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