| 804 | | * vlc_parse_cmdline: Command line parsing into elements. |
|---|
| 805 | | * |
|---|
| 806 | | * The command line is composed of space/tab separated arguments. |
|---|
| 807 | | * Quotes can be used as argument delimiters and a backslash can be used to |
|---|
| 808 | | * escape a quote. |
|---|
| 809 | | *************************************************************************/ |
|---|
| 810 | | static void find_end_quote( char **s, char **ppsz_parser, int i_quote ) |
|---|
| 811 | | { |
|---|
| 812 | | int i_bcount = 0; |
|---|
| 813 | | |
|---|
| 814 | | while( **s ) |
|---|
| 815 | | { |
|---|
| 816 | | if( **s == '\\' ) |
|---|
| 817 | | { |
|---|
| 818 | | **ppsz_parser = **s; |
|---|
| 819 | | (*ppsz_parser)++; (*s)++; |
|---|
| 820 | | i_bcount++; |
|---|
| 821 | | } |
|---|
| 822 | | else if( **s == '"' || **s == '\'' ) |
|---|
| 823 | | { |
|---|
| 824 | | /* Preceeded by a number of '\' which we erase. */ |
|---|
| 825 | | *ppsz_parser -= i_bcount / 2; |
|---|
| 826 | | if( i_bcount & 1 ) |
|---|
| 827 | | { |
|---|
| 828 | | /* '\\' followed by a '"' or '\'' */ |
|---|
| 829 | | *ppsz_parser -= 1; |
|---|
| 830 | | **ppsz_parser = **s; |
|---|
| 831 | | (*ppsz_parser)++; (*s)++; |
|---|
| 832 | | i_bcount = 0; |
|---|
| 833 | | continue; |
|---|
| 834 | | } |
|---|
| 835 | | |
|---|
| 836 | | if( **s == i_quote ) |
|---|
| 837 | | { |
|---|
| 838 | | /* End */ |
|---|
| 839 | | return; |
|---|
| 840 | | } |
|---|
| 841 | | else |
|---|
| 842 | | { |
|---|
| 843 | | /* Different quoting */ |
|---|
| 844 | | int i_quote = **s; |
|---|
| 845 | | **ppsz_parser = **s; |
|---|
| 846 | | (*ppsz_parser)++; (*s)++; |
|---|
| 847 | | find_end_quote( s, ppsz_parser, i_quote ); |
|---|
| 848 | | **ppsz_parser = **s; |
|---|
| 849 | | (*ppsz_parser)++; (*s)++; |
|---|
| 850 | | } |
|---|
| 851 | | |
|---|
| 852 | | i_bcount = 0; |
|---|
| 853 | | } |
|---|
| 854 | | else |
|---|
| 855 | | { |
|---|
| 856 | | /* A regular character */ |
|---|
| 857 | | **ppsz_parser = **s; |
|---|
| 858 | | (*ppsz_parser)++; (*s)++; |
|---|
| 859 | | i_bcount = 0; |
|---|
| 860 | | } |
|---|
| 861 | | } |
|---|
| 862 | | } |
|---|
| 863 | | |
|---|
| 864 | | char **vlc_parse_cmdline( const char *psz_cmdline, int *i_args ) |
|---|
| 865 | | { |
|---|
| 866 | | int argc = 0; |
|---|
| 867 | | char **argv = 0; |
|---|
| 868 | | char *s, *psz_parser, *psz_arg, *psz_orig; |
|---|
| 869 | | int i_bcount = 0; |
|---|
| 870 | | |
|---|
| 871 | | if( !psz_cmdline ) return 0; |
|---|
| 872 | | psz_orig = strdup( psz_cmdline ); |
|---|
| 873 | | psz_arg = psz_parser = s = psz_orig; |
|---|
| 874 | | |
|---|
| 875 | | while( *s ) |
|---|
| 876 | | { |
|---|
| 877 | | if( *s == '\t' || *s == ' ' ) |
|---|
| 878 | | { |
|---|
| 879 | | /* We have a complete argument */ |
|---|
| 880 | | *psz_parser = 0; |
|---|
| 881 | | TAB_APPEND( argc, argv, strdup(psz_arg) ); |
|---|
| 882 | | |
|---|
| 883 | | /* Skip trailing spaces/tabs */ |
|---|
| 884 | | do{ s++; } while( *s == '\t' || *s == ' ' ); |
|---|
| 885 | | |
|---|
| 886 | | /* New argument */ |
|---|
| 887 | | psz_arg = psz_parser = s; |
|---|
| 888 | | i_bcount = 0; |
|---|
| 889 | | } |
|---|
| 890 | | else if( *s == '\\' ) |
|---|
| 891 | | { |
|---|
| 892 | | *psz_parser++ = *s++; |
|---|
| 893 | | i_bcount++; |
|---|
| 894 | | } |
|---|
| 895 | | else if( *s == '"' || *s == '\'' ) |
|---|
| 896 | | { |
|---|
| 897 | | if( ( i_bcount & 1 ) == 0 ) |
|---|
| 898 | | { |
|---|
| 899 | | /* Preceeded by an even number of '\', this is half that |
|---|
| 900 | | * number of '\', plus a quote which we erase. */ |
|---|
| 901 | | int i_quote = *s; |
|---|
| 902 | | psz_parser -= i_bcount / 2; |
|---|
| 903 | | s++; |
|---|
| 904 | | find_end_quote( &s, &psz_parser, i_quote ); |
|---|
| 905 | | s++; |
|---|
| 906 | | } |
|---|
| 907 | | else |
|---|
| 908 | | { |
|---|
| 909 | | /* Preceeded by an odd number of '\', this is half that |
|---|
| 910 | | * number of '\' followed by a '"' */ |
|---|
| 911 | | psz_parser = psz_parser - i_bcount/2 - 1; |
|---|
| 912 | | *psz_parser++ = '"'; |
|---|
| 913 | | s++; |
|---|
| 914 | | } |
|---|
| 915 | | i_bcount = 0; |
|---|
| 916 | | } |
|---|
| 917 | | else |
|---|
| 918 | | { |
|---|
| 919 | | /* A regular character */ |
|---|
| 920 | | *psz_parser++ = *s++; |
|---|
| 921 | | i_bcount = 0; |
|---|
| 922 | | } |
|---|
| 923 | | } |
|---|
| 924 | | |
|---|
| 925 | | /* Take care of the last arg */ |
|---|
| 926 | | if( *psz_arg ) |
|---|
| 927 | | { |
|---|
| 928 | | *psz_parser = '\0'; |
|---|
| 929 | | TAB_APPEND( argc, argv, strdup(psz_arg) ); |
|---|
| 930 | | } |
|---|
| 931 | | |
|---|
| 932 | | if( i_args ) *i_args = argc; |
|---|
| 933 | | free( psz_orig ); |
|---|
| 934 | | return argv; |
|---|
| 935 | | } |
|---|
| 936 | | |
|---|
| 937 | | /************************************************************************* |
|---|