@@ -65,6 +65,72 @@ string[] tokenizeArgs(string text, bool semi_is_seperator = true, bool space_is_
6565 return args;
6666}
6767
68+ // Microsoft like quoting
69+ string [] splitCmdLine (string cmdline, bool removeSlashes = true )
70+ {
71+ string [] args;
72+ for (size_t p = 0 ; p < cmdline.length; p++ )
73+ {
74+ if (cmdline[p] == ' ' || cmdline[p] == ' \t ' )
75+ continue ;
76+ size_t q = p;
77+ size_t quotes = 0 ;
78+ while (q < cmdline.length)
79+ {
80+ auto c = cmdline[q];
81+ if ((quotes & 1 ) == 0 && (c == ' ' || c == ' \t ' ))
82+ break ;
83+ q++ ;
84+ if (c == ' \\ ' )
85+ {
86+ size_t slash = q - 1 ;
87+ while (q < cmdline.length && cmdline[q] == ' \\ ' )
88+ q++ ;
89+ if (q < cmdline.length && cmdline[q] == ' "' )
90+ {
91+ size_t slashes = q - slash;
92+ if (removeSlashes)
93+ {
94+ // strip half the slashes, if odd, escape the '"'
95+ size_t nq = slash + (slashes >> 1 );
96+ cmdline = cmdline[0 .. nq] ~ cmdline[q .. $];
97+ q = nq + 1 ;
98+ }
99+ if (slashes & 1 )
100+ q++ ;
101+ else
102+ quotes++ ;
103+ }
104+ }
105+ else if (c == ' "' )
106+ {
107+ quotes++ ;
108+ }
109+ }
110+ auto arg = cmdline[p.. q];
111+ if (quotes == 2 && arg[0 ] == ' "' && arg[$- 1 ] == ' "' )
112+ arg = arg[1 .. $- 1 ];
113+ args ~= arg;
114+ p = q;
115+ }
116+ return args;
117+ }
118+
119+ unittest
120+ {
121+ string [] args = splitCmdLine(" a b c" );
122+ assert (args[0 ] == " a" && args[1 ] == " b" && args[2 ] == " c" );
123+
124+ args = splitCmdLine(q" (a " b b" c)" );
125+ assert (args[0 ] == " a" && args[1 ] == " b b" && args[2 ] == " c" );
126+
127+ args = splitCmdLine(q" (a " b\ b\\ " c)" );
128+ assert (args[0 ] == " a" && args[1 ] == q" (b\ b\) " && args[2 ] == " c" );
129+
130+ args = splitCmdLine(q" (a " b\" b\\ " c)" );
131+ assert (args[0 ] == " a" && args[1 ] == q" (b" b\) " && args[2] == " c" );
132+ }
133+
68134string unquoteArgument(string arg)
69135{
70136 if(arg.length <= 0 || arg[0] != '\" ')
@@ -76,6 +142,14 @@ string unquoteArgument(string arg)
76142 return arg[1..$-1];
77143}
78144
145+ string quoteArgument(string arg)
146+ {
147+ if(arg.indexOf(' ') < 0 && arg.indexOf('\t ') < 0)
148+ return arg;
149+
150+ return " \" " ~ arg ~ " \" " ;
151+ }
152+
79153string replaceCrLfSemi(string s)
80154{
81155 return replace(replace(s, " \n " , " ;" ), " \r " , " " );
0 commit comments