@@ -184,16 +184,95 @@ static int strip_prefix(LPWSTR str, int *len, LPCWSTR prefix)
184
184
return 0 ;
185
185
}
186
186
187
+ static void extract_first_arg (LPWSTR command_line , LPWSTR exepath , LPWSTR buf )
188
+ {
189
+ LPWSTR * wargv ;
190
+ int wargc ;
191
+
192
+ wargv = CommandLineToArgvW (command_line , & wargc );
193
+ if (wargc < 1 ) {
194
+ fwprintf (stderr , L"Invalid command-line: '%s'\n" , command_line );
195
+ exit (1 );
196
+ }
197
+ if (* wargv [0 ] == L'\\' ||
198
+ (isalpha (* wargv [0 ]) && wargv [0 ][1 ] == L':' ))
199
+ wcscpy (buf , wargv [0 ]);
200
+ else {
201
+ wcscpy (buf , exepath );
202
+ PathAppend (buf , wargv [0 ]);
203
+ }
204
+ LocalFree (wargv );
205
+ }
206
+
207
+ #define alloc_nr (x ) (((x)+16)*3/2)
208
+
209
+ static LPWSTR expand_variables (LPWSTR buffer , size_t alloc )
210
+ {
211
+ LPWSTR buf = buffer ;
212
+ size_t len = wcslen (buf );
213
+
214
+ for (;;) {
215
+ LPWSTR atat = wcsstr (buf , L"@@" ), atat2 ;
216
+ WCHAR save ;
217
+ int env_len , delta ;
218
+
219
+ if (!atat )
220
+ break ;
221
+
222
+ atat2 = wcsstr (atat + 2 , L"@@" );
223
+ if (!atat2 )
224
+ break ;
225
+
226
+ * atat2 = L'\0' ;
227
+ env_len = GetEnvironmentVariable (atat + 2 , NULL , 0 );
228
+ delta = env_len - 1 - (atat2 + 2 - atat );
229
+ if (len + delta >= alloc ) {
230
+ LPWSTR buf2 ;
231
+ alloc = alloc_nr (alloc );
232
+ if (alloc <= len + delta )
233
+ alloc = len + delta + 1 ;
234
+ if (buf != buffer )
235
+ buf2 = realloc (buf , sizeof (WCHAR ) * alloc );
236
+ else {
237
+ buf2 = malloc (sizeof (WCHAR ) * alloc );
238
+ if (buf2 )
239
+ memcpy (buf2 , buf , sizeof (WCHAR )
240
+ * (len + 1 ));
241
+ }
242
+ if (!buf2 ) {
243
+ fwprintf (stderr ,
244
+ L"Substituting '%s' results in too "
245
+ L"large a command-line\n" , atat + 2 );
246
+ exit (1 );
247
+ }
248
+ atat += buf2 - buf ;
249
+ atat2 += buf2 - buf ;
250
+ buf = buf2 ;
251
+ }
252
+ if (delta )
253
+ memmove (atat2 + 2 + delta , atat2 + 2 ,
254
+ sizeof (WCHAR ) * (len + 1
255
+ - (atat2 + 2 - buf )));
256
+ len += delta ;
257
+ save = atat [env_len - 1 ];
258
+ GetEnvironmentVariable (atat + 2 , atat , env_len );
259
+ atat [env_len - 1 ] = save ;
260
+ }
261
+
262
+ return buf ;
263
+ }
264
+
187
265
static int configure_via_resource (LPWSTR basename , LPWSTR exepath , LPWSTR exep ,
188
266
LPWSTR * prefix_args , int * prefix_args_len ,
189
267
int * is_git_command , LPWSTR * working_directory , int * full_path ,
190
268
int * skip_arguments , int * allocate_console , int * show_console )
191
269
{
192
- int id , minimal_search_path , needs_a_console , no_hide , wargc ;
270
+ int i , id , minimal_search_path , needs_a_console , no_hide , wargc ;
193
271
LPWSTR * wargv ;
194
272
195
273
#define BUFSIZE 65536
196
274
static WCHAR buf [BUFSIZE ];
275
+ LPWSTR buf2 = buf ;
197
276
int len ;
198
277
199
278
for (id = 0 ; ; id ++ ) {
@@ -233,74 +312,58 @@ static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
233
312
if (!id )
234
313
SetEnvironmentVariable (L"EXEPATH" , exepath );
235
314
236
- for (;;) {
237
- LPWSTR atat = wcsstr (buf , L"@@" ), atat2 ;
238
- WCHAR save ;
239
- int env_len , delta ;
240
-
241
- if (!atat )
242
- break ;
243
-
244
- atat2 = wcsstr (atat + 2 , L"@@" );
245
- if (!atat2 )
246
- break ;
247
-
248
- * atat2 = L'\0' ;
249
- env_len = GetEnvironmentVariable (atat + 2 , NULL , 0 );
250
- delta = env_len - 1 - (atat2 + 2 - atat );
251
- if (len + delta >= BUFSIZE ) {
252
- fwprintf (stderr ,
253
- L"Substituting '%s' results in too "
254
- L"large a command-line\n" , atat + 2 );
255
- exit (1 );
256
- }
257
- if (delta )
258
- memmove (atat2 + 2 + delta , atat2 + 2 ,
259
- sizeof (WCHAR ) * (len + 1
260
- - (atat2 + 2 - buf )));
261
- len += delta ;
262
- save = atat [env_len - 1 ];
263
- GetEnvironmentVariable (atat + 2 , atat , env_len );
264
- atat [env_len - 1 ] = save ;
265
- }
315
+ buf2 = expand_variables (buf , BUFSIZE );
266
316
267
- /* parse first argument */
268
- wargv = CommandLineToArgvW (buf , & wargc );
269
- if (wargc < 1 ) {
270
- fwprintf (stderr , L"Invalid command-line: '%s'\n" , buf );
271
- exit (1 );
272
- }
273
- if (* wargv [0 ] == L'\\' ||
274
- (isalpha (* wargv [0 ]) && wargv [0 ][1 ] == L':' ))
275
- wcscpy (exep , wargv [0 ]);
276
- else {
277
- wcscpy (exep , exepath );
278
- PathAppend (exep , wargv [0 ]);
279
- }
280
- LocalFree (wargv );
317
+ extract_first_arg (buf2 , exepath , exep );
281
318
282
319
if (_waccess (exep , 0 ) != -1 )
283
320
break ;
284
321
fwprintf (stderr ,
285
322
L"Skipping command-line '%s'\n('%s' not found)\n" ,
286
- buf , exep );
323
+ buf2 , exep );
287
324
}
288
325
289
- * prefix_args = buf ;
290
- * prefix_args_len = wcslen (buf );
326
+ * prefix_args = buf2 ;
327
+ * prefix_args_len = wcslen (buf2 );
291
328
292
329
* is_git_command = 0 ;
293
330
* working_directory = (LPWSTR ) 1 ;
294
331
wargv = CommandLineToArgvW (GetCommandLine (), & wargc );
295
- if ( wargc > 1 ) {
296
- if (!wcscmp (L"--no-cd" , wargv [1 ])) {
332
+ for ( i = 1 ; i < wargc ; i ++ ) {
333
+ if (!wcscmp (L"--no-cd" , wargv [i ]))
297
334
* working_directory = NULL ;
298
- * skip_arguments = 1 ;
299
- }
300
- else if (!wcsncmp (L"--cd=" , wargv [1 ], 5 )) {
301
- * working_directory = wcsdup (wargv [1 ] + 5 );
302
- * skip_arguments = 1 ;
335
+ else if (!wcsncmp (L"--cd=" , wargv [i ], 5 ))
336
+ * working_directory = wcsdup (wargv [i ] + 5 );
337
+ else if (!wcscmp (L"--minimal-search-path" , wargv [i ]))
338
+ minimal_search_path = 1 ;
339
+ else if (!wcscmp (L"--no-minimal-search-path" , wargv [i ]))
340
+ minimal_search_path = 0 ;
341
+ else if (!wcscmp (L"--needs-console" , wargv [i ]))
342
+ needs_a_console = 1 ;
343
+ else if (!wcscmp (L"--no-needs-console" , wargv [i ]))
344
+ needs_a_console = 0 ;
345
+ else if (!wcscmp (L"--hide" , wargv [i ]))
346
+ no_hide = 0 ;
347
+ else if (!wcscmp (L"--no-hide" , wargv [i ]))
348
+ no_hide = 1 ;
349
+ else if (!wcsncmp (L"--command=" , wargv [i ], 10 )) {
350
+ LPWSTR expanded ;
351
+
352
+ wargv [i ] += 10 ;
353
+ expanded = expand_variables (wargv [i ], wcslen (wargv [i ]));
354
+ if (expanded == wargv [i ])
355
+ expanded = wcsdup (expanded );
356
+
357
+ extract_first_arg (expanded , exepath , exep );
358
+
359
+ * prefix_args = expanded ;
360
+ * prefix_args_len = wcslen (* prefix_args );
361
+ * skip_arguments = i ;
362
+ break ;
303
363
}
364
+ else
365
+ break ;
366
+ * skip_arguments = i ;
304
367
}
305
368
if (minimal_search_path )
306
369
* full_path = 0 ;
0 commit comments