Fossil SCM

(experimental) command-line expansion for MinGW-w64. Should work on MSVC as well. Doesn't work with MinGW.

jan.nijtmans 2012-11-30 13:27 trunk
Commit b1036fe5bfafbac69421cba308464233388274b3
+9 -123
--- src/main.c
+++ src/main.c
@@ -344,126 +344,10 @@
344344
free(g.zErrMsg);
345345
if(g.db){
346346
db_close(0);
347347
}
348348
}
349
-
350
-#if defined(_WIN32) && !defined(__MINGW32__)
351
-/*
352
-** Parse the command-line arguments passed to windows. We do this
353
-** ourselves to work around bugs in the command-line parsing of MinGW.
354
-** It is possible (in theory) to only use this routine when compiling
355
-** with MinGW and to use built-in command-line parsing for MSVC and
356
-** MinGW-64. However, the code is here, it is efficient, and works, and
357
-** by using it in all cases we do a better job of testing it. If you suspect
358
-** a bug in this code, test your theory by invoking "fossil test-echo".
359
-**
360
-** This routine is copied from TCL with some reformatting.
361
-** The original comment text follows:
362
-**
363
-** Parse the Windows command line string into argc/argv. Done here
364
-** because we don't trust the builtin argument parser in crt0. Windows
365
-** applications are responsible for breaking their command line into
366
-** arguments.
367
-**
368
-** 2N backslashes + quote -> N backslashes + begin quoted string
369
-** 2N + 1 backslashes + quote -> literal
370
-** N backslashes + non-quote -> literal
371
-** quote + quote in a quoted string -> single quote
372
-** quote + quote not in quoted string -> empty string
373
-** quote -> begin quoted string
374
-**
375
-** Results:
376
-** Fills argcPtr with the number of arguments and argvPtr with the array
377
-** of arguments.
378
-*/
379
-#define wchar_isspace(X) ((X)==' ' || (X)=='\t')
380
-static void parse_windows_command_line(
381
- int *argcPtr, /* Filled with number of argument strings. */
382
- void *argvPtr /* Filled with argument strings (malloc'd). */
383
-){
384
- WCHAR *cmdLine, *p, *arg, *argSpace;
385
- WCHAR **argv;
386
- int argc, size, inquote, copy, slashes;
387
-
388
- cmdLine = GetCommandLineW();
389
-
390
- /*
391
- ** Precompute an overly pessimistic guess at the number of arguments in
392
- ** the command line by counting non-space spans.
393
- */
394
- size = 2;
395
- for(p=cmdLine; *p!='\0'; p++){
396
- if( wchar_isspace(*p) ){
397
- size++;
398
- while( wchar_isspace(*p) ){
399
- p++;
400
- }
401
- if( *p=='\0' ){
402
- break;
403
- }
404
- }
405
- }
406
-
407
- argSpace = fossil_malloc(size * sizeof(char*)
408
- + (wcslen(cmdLine) * sizeof(WCHAR)) + sizeof(WCHAR));
409
- argv = (WCHAR**)argSpace;
410
- argSpace += size*(sizeof(char*)/sizeof(WCHAR));
411
- size--;
412
-
413
- p = cmdLine;
414
- for(argc=0; argc<size; argc++){
415
- argv[argc] = arg = argSpace;
416
- while( wchar_isspace(*p) ){
417
- p++;
418
- }
419
- if (*p == '\0') {
420
- break;
421
- }
422
- inquote = 0;
423
- slashes = 0;
424
- while(1){
425
- copy = 1;
426
- while( *p=='\\' ){
427
- slashes++;
428
- p++;
429
- }
430
- if( *p=='"' ){
431
- if( (slashes&1)==0 ){
432
- copy = 0;
433
- if( inquote && p[1]=='"' ){
434
- p++;
435
- copy = 1;
436
- }else{
437
- inquote = !inquote;
438
- }
439
- }
440
- slashes >>= 1;
441
- }
442
- while( slashes ){
443
- *arg = '\\';
444
- arg++;
445
- slashes--;
446
- }
447
- if( *p=='\0' || (!inquote && wchar_isspace(*p)) ){
448
- break;
449
- }
450
- if( copy!=0 ){
451
- *arg = *p;
452
- arg++;
453
- }
454
- p++;
455
- }
456
- *arg = '\0';
457
- argSpace = arg + 1;
458
- }
459
- argv[argc] = NULL;
460
- *argcPtr = argc;
461
- *((WCHAR ***)argvPtr) = argv;
462
-}
463
-#endif /* defined(_WIN32) && !defined(__MINGW32__) */
464
-
465349
466350
/*
467351
** Convert all arguments from mbcs (or unicode) to UTF-8. Then
468352
** search g.argv for arguments "--args FILENAME". If found, then
469353
** (1) remove the two arguments from g.argv
@@ -482,27 +366,23 @@
482366
int n; /* Number of bytes in one line */
483367
char *z; /* General use string pointer */
484368
char **newArgv; /* New expanded g.argv under construction */
485369
char const * zFileName; /* input file name */
486370
FILE * zInFile; /* input FILE */
487
-#if defined(_WIN32) && !defined(__MINGW32__)
371
+#if defined(_WIN32)
488372
WCHAR buf[MAX_PATH];
489373
#endif
490374
491375
g.argc = argc;
492376
g.argv = argv;
493
-#if defined(_WIN32) && !defined(__MINGW32__)
494
- parse_windows_command_line(&g.argc, &g.argv);
377
+#if defined(_WIN32)
495378
GetModuleFileNameW(NULL, buf, MAX_PATH);
496379
g.nameOfExe = fossil_filename_to_utf8(buf);
497
- for(i=0; i<g.argc; i++) g.argv[i] = fossil_filename_to_utf8(g.argv[i]);
498
-#elif defined(__APPLE__)
499
- for(i=0; i<g.argc; i++) g.argv[i] = fossil_filename_to_utf8(g.argv[i]);
500
- g.nameOfExe = g.argv[0];
501380
#else
502381
g.nameOfExe = g.argv[0];
503382
#endif
383
+ for(i=0; i<g.argc; i++) g.argv[i] = fossil_filename_to_utf8(g.argv[i]);
504384
for(i=1; i<g.argc-1; i++){
505385
z = g.argv[i];
506386
if( z[0]!='-' ) continue;
507387
z++;
508388
if( z[0]=='-' ) z++;
@@ -569,15 +449,21 @@
569449
zNewArgv[i] = fossil_strdup(argv[i]);
570450
}
571451
return zNewArgv;
572452
}
573453
#endif
454
+
574455
575456
/*
576457
** This procedure runs first.
577458
*/
459
+#ifdef _WIN32
460
+int _dowildcard = -1; /* This turns on command-line globbing in MinGW-w64 */
461
+int wmain(int argc, wchar_t **argv)
462
+#else
578463
int main(int argc, char **argv)
464
+#endif
579465
{
580466
const char *zCmdName = "unknown";
581467
int idx;
582468
int rc;
583469
584470
--- src/main.c
+++ src/main.c
@@ -344,126 +344,10 @@
344 free(g.zErrMsg);
345 if(g.db){
346 db_close(0);
347 }
348 }
349
350 #if defined(_WIN32) && !defined(__MINGW32__)
351 /*
352 ** Parse the command-line arguments passed to windows. We do this
353 ** ourselves to work around bugs in the command-line parsing of MinGW.
354 ** It is possible (in theory) to only use this routine when compiling
355 ** with MinGW and to use built-in command-line parsing for MSVC and
356 ** MinGW-64. However, the code is here, it is efficient, and works, and
357 ** by using it in all cases we do a better job of testing it. If you suspect
358 ** a bug in this code, test your theory by invoking "fossil test-echo".
359 **
360 ** This routine is copied from TCL with some reformatting.
361 ** The original comment text follows:
362 **
363 ** Parse the Windows command line string into argc/argv. Done here
364 ** because we don't trust the builtin argument parser in crt0. Windows
365 ** applications are responsible for breaking their command line into
366 ** arguments.
367 **
368 ** 2N backslashes + quote -> N backslashes + begin quoted string
369 ** 2N + 1 backslashes + quote -> literal
370 ** N backslashes + non-quote -> literal
371 ** quote + quote in a quoted string -> single quote
372 ** quote + quote not in quoted string -> empty string
373 ** quote -> begin quoted string
374 **
375 ** Results:
376 ** Fills argcPtr with the number of arguments and argvPtr with the array
377 ** of arguments.
378 */
379 #define wchar_isspace(X) ((X)==' ' || (X)=='\t')
380 static void parse_windows_command_line(
381 int *argcPtr, /* Filled with number of argument strings. */
382 void *argvPtr /* Filled with argument strings (malloc'd). */
383 ){
384 WCHAR *cmdLine, *p, *arg, *argSpace;
385 WCHAR **argv;
386 int argc, size, inquote, copy, slashes;
387
388 cmdLine = GetCommandLineW();
389
390 /*
391 ** Precompute an overly pessimistic guess at the number of arguments in
392 ** the command line by counting non-space spans.
393 */
394 size = 2;
395 for(p=cmdLine; *p!='\0'; p++){
396 if( wchar_isspace(*p) ){
397 size++;
398 while( wchar_isspace(*p) ){
399 p++;
400 }
401 if( *p=='\0' ){
402 break;
403 }
404 }
405 }
406
407 argSpace = fossil_malloc(size * sizeof(char*)
408 + (wcslen(cmdLine) * sizeof(WCHAR)) + sizeof(WCHAR));
409 argv = (WCHAR**)argSpace;
410 argSpace += size*(sizeof(char*)/sizeof(WCHAR));
411 size--;
412
413 p = cmdLine;
414 for(argc=0; argc<size; argc++){
415 argv[argc] = arg = argSpace;
416 while( wchar_isspace(*p) ){
417 p++;
418 }
419 if (*p == '\0') {
420 break;
421 }
422 inquote = 0;
423 slashes = 0;
424 while(1){
425 copy = 1;
426 while( *p=='\\' ){
427 slashes++;
428 p++;
429 }
430 if( *p=='"' ){
431 if( (slashes&1)==0 ){
432 copy = 0;
433 if( inquote && p[1]=='"' ){
434 p++;
435 copy = 1;
436 }else{
437 inquote = !inquote;
438 }
439 }
440 slashes >>= 1;
441 }
442 while( slashes ){
443 *arg = '\\';
444 arg++;
445 slashes--;
446 }
447 if( *p=='\0' || (!inquote && wchar_isspace(*p)) ){
448 break;
449 }
450 if( copy!=0 ){
451 *arg = *p;
452 arg++;
453 }
454 p++;
455 }
456 *arg = '\0';
457 argSpace = arg + 1;
458 }
459 argv[argc] = NULL;
460 *argcPtr = argc;
461 *((WCHAR ***)argvPtr) = argv;
462 }
463 #endif /* defined(_WIN32) && !defined(__MINGW32__) */
464
465
466 /*
467 ** Convert all arguments from mbcs (or unicode) to UTF-8. Then
468 ** search g.argv for arguments "--args FILENAME". If found, then
469 ** (1) remove the two arguments from g.argv
@@ -482,27 +366,23 @@
482 int n; /* Number of bytes in one line */
483 char *z; /* General use string pointer */
484 char **newArgv; /* New expanded g.argv under construction */
485 char const * zFileName; /* input file name */
486 FILE * zInFile; /* input FILE */
487 #if defined(_WIN32) && !defined(__MINGW32__)
488 WCHAR buf[MAX_PATH];
489 #endif
490
491 g.argc = argc;
492 g.argv = argv;
493 #if defined(_WIN32) && !defined(__MINGW32__)
494 parse_windows_command_line(&g.argc, &g.argv);
495 GetModuleFileNameW(NULL, buf, MAX_PATH);
496 g.nameOfExe = fossil_filename_to_utf8(buf);
497 for(i=0; i<g.argc; i++) g.argv[i] = fossil_filename_to_utf8(g.argv[i]);
498 #elif defined(__APPLE__)
499 for(i=0; i<g.argc; i++) g.argv[i] = fossil_filename_to_utf8(g.argv[i]);
500 g.nameOfExe = g.argv[0];
501 #else
502 g.nameOfExe = g.argv[0];
503 #endif
 
504 for(i=1; i<g.argc-1; i++){
505 z = g.argv[i];
506 if( z[0]!='-' ) continue;
507 z++;
508 if( z[0]=='-' ) z++;
@@ -569,15 +449,21 @@
569 zNewArgv[i] = fossil_strdup(argv[i]);
570 }
571 return zNewArgv;
572 }
573 #endif
 
574
575 /*
576 ** This procedure runs first.
577 */
 
 
 
 
578 int main(int argc, char **argv)
 
579 {
580 const char *zCmdName = "unknown";
581 int idx;
582 int rc;
583
584
--- src/main.c
+++ src/main.c
@@ -344,126 +344,10 @@
344 free(g.zErrMsg);
345 if(g.db){
346 db_close(0);
347 }
348 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
350 /*
351 ** Convert all arguments from mbcs (or unicode) to UTF-8. Then
352 ** search g.argv for arguments "--args FILENAME". If found, then
353 ** (1) remove the two arguments from g.argv
@@ -482,27 +366,23 @@
366 int n; /* Number of bytes in one line */
367 char *z; /* General use string pointer */
368 char **newArgv; /* New expanded g.argv under construction */
369 char const * zFileName; /* input file name */
370 FILE * zInFile; /* input FILE */
371 #if defined(_WIN32)
372 WCHAR buf[MAX_PATH];
373 #endif
374
375 g.argc = argc;
376 g.argv = argv;
377 #if defined(_WIN32)
 
378 GetModuleFileNameW(NULL, buf, MAX_PATH);
379 g.nameOfExe = fossil_filename_to_utf8(buf);
 
 
 
 
380 #else
381 g.nameOfExe = g.argv[0];
382 #endif
383 for(i=0; i<g.argc; i++) g.argv[i] = fossil_filename_to_utf8(g.argv[i]);
384 for(i=1; i<g.argc-1; i++){
385 z = g.argv[i];
386 if( z[0]!='-' ) continue;
387 z++;
388 if( z[0]=='-' ) z++;
@@ -569,15 +449,21 @@
449 zNewArgv[i] = fossil_strdup(argv[i]);
450 }
451 return zNewArgv;
452 }
453 #endif
454
455
456 /*
457 ** This procedure runs first.
458 */
459 #ifdef _WIN32
460 int _dowildcard = -1; /* This turns on command-line globbing in MinGW-w64 */
461 int wmain(int argc, wchar_t **argv)
462 #else
463 int main(int argc, char **argv)
464 #endif
465 {
466 const char *zCmdName = "unknown";
467 int idx;
468 int rc;
469
470
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -503,11 +503,11 @@
503503
endif
504504
505505
#### We add the -static option here so that we can build a static
506506
# executable that will run in a chroot jail.
507507
#
508
-LIB = -static
508
+LIB = -static -municode
509509
510510
# OpenSSL: Add the necessary libraries required, if enabled.
511511
ifdef FOSSIL_ENABLE_SSL
512512
LIB += -lssl -lcrypto -lgdi32
513513
endif
@@ -971,11 +971,11 @@
971971
@echo Building zlib from "$(ZLIBDIR)"...
972972
@pushd "$(ZLIBDIR)" && nmake /f win32\Makefile.msc $(ZLIB) && popd
973973
974974
$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OX)\linkopts zlib
975975
cd $(OX)
976
- link /NODEFAULTLIB:msvcrt -OUT:$@ $(LIBDIR) @linkopts
976
+ link /NODEFAULTLIB:msvcrt -OUT:$@ $(LIBDIR) Wsetargv.obj @linkopts
977977
978978
$(OX)\linkopts: $B\win\Makefile.msc}
979979
set redir {>}
980980
foreach s [lsort [concat $src {shell sqlite3 th th_lang}]] {
981981
writeln "\techo \$(OX)\\$s.obj $redir \$@"
982982
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -503,11 +503,11 @@
503 endif
504
505 #### We add the -static option here so that we can build a static
506 # executable that will run in a chroot jail.
507 #
508 LIB = -static
509
510 # OpenSSL: Add the necessary libraries required, if enabled.
511 ifdef FOSSIL_ENABLE_SSL
512 LIB += -lssl -lcrypto -lgdi32
513 endif
@@ -971,11 +971,11 @@
971 @echo Building zlib from "$(ZLIBDIR)"...
972 @pushd "$(ZLIBDIR)" && nmake /f win32\Makefile.msc $(ZLIB) && popd
973
974 $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OX)\linkopts zlib
975 cd $(OX)
976 link /NODEFAULTLIB:msvcrt -OUT:$@ $(LIBDIR) @linkopts
977
978 $(OX)\linkopts: $B\win\Makefile.msc}
979 set redir {>}
980 foreach s [lsort [concat $src {shell sqlite3 th th_lang}]] {
981 writeln "\techo \$(OX)\\$s.obj $redir \$@"
982
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -503,11 +503,11 @@
503 endif
504
505 #### We add the -static option here so that we can build a static
506 # executable that will run in a chroot jail.
507 #
508 LIB = -static -municode
509
510 # OpenSSL: Add the necessary libraries required, if enabled.
511 ifdef FOSSIL_ENABLE_SSL
512 LIB += -lssl -lcrypto -lgdi32
513 endif
@@ -971,11 +971,11 @@
971 @echo Building zlib from "$(ZLIBDIR)"...
972 @pushd "$(ZLIBDIR)" && nmake /f win32\Makefile.msc $(ZLIB) && popd
973
974 $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OX)\linkopts zlib
975 cd $(OX)
976 link /NODEFAULTLIB:msvcrt -OUT:$@ $(LIBDIR) Wsetargv.obj @linkopts
977
978 $(OX)\linkopts: $B\win\Makefile.msc}
979 set redir {>}
980 foreach s [lsort [concat $src {shell sqlite3 th th_lang}]] {
981 writeln "\techo \$(OX)\\$s.obj $redir \$@"
982
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -173,11 +173,11 @@
173173
endif
174174
175175
#### We add the -static option here so that we can build a static
176176
# executable that will run in a chroot jail.
177177
#
178
-LIB = -static
178
+LIB = -static -municode
179179
180180
# OpenSSL: Add the necessary libraries required, if enabled.
181181
ifdef FOSSIL_ENABLE_SSL
182182
LIB += -lssl -lcrypto -lgdi32
183183
endif
184184
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -173,11 +173,11 @@
173 endif
174
175 #### We add the -static option here so that we can build a static
176 # executable that will run in a chroot jail.
177 #
178 LIB = -static
179
180 # OpenSSL: Add the necessary libraries required, if enabled.
181 ifdef FOSSIL_ENABLE_SSL
182 LIB += -lssl -lcrypto -lgdi32
183 endif
184
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -173,11 +173,11 @@
173 endif
174
175 #### We add the -static option here so that we can build a static
176 # executable that will run in a chroot jail.
177 #
178 LIB = -static -municode
179
180 # OpenSSL: Add the necessary libraries required, if enabled.
181 ifdef FOSSIL_ENABLE_SSL
182 LIB += -lssl -lcrypto -lgdi32
183 endif
184
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -173,11 +173,11 @@
173173
endif
174174
175175
#### We add the -static option here so that we can build a static
176176
# executable that will run in a chroot jail.
177177
#
178
-LIB = -static
178
+LIB = -static -municode
179179
180180
# OpenSSL: Add the necessary libraries required, if enabled.
181181
ifdef FOSSIL_ENABLE_SSL
182182
LIB += -lssl -lcrypto -lgdi32
183183
endif
184184
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -173,11 +173,11 @@
173 endif
174
175 #### We add the -static option here so that we can build a static
176 # executable that will run in a chroot jail.
177 #
178 LIB = -static
179
180 # OpenSSL: Add the necessary libraries required, if enabled.
181 ifdef FOSSIL_ENABLE_SSL
182 LIB += -lssl -lcrypto -lgdi32
183 endif
184
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -173,11 +173,11 @@
173 endif
174
175 #### We add the -static option here so that we can build a static
176 # executable that will run in a chroot jail.
177 #
178 LIB = -static -municode
179
180 # OpenSSL: Add the necessary libraries required, if enabled.
181 ifdef FOSSIL_ENABLE_SSL
182 LIB += -lssl -lcrypto -lgdi32
183 endif
184
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -254,11 +254,11 @@
254254
@echo Building zlib from "$(ZLIBDIR)"...
255255
@pushd "$(ZLIBDIR)" && nmake /f win32\Makefile.msc $(ZLIB) && popd
256256
257257
$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OX)\linkopts zlib
258258
cd $(OX)
259
- link /NODEFAULTLIB:msvcrt -OUT:$@ $(LIBDIR) @linkopts
259
+ link /NODEFAULTLIB:msvcrt -OUT:$@ $(LIBDIR) Wsetargv.obj @linkopts
260260
261261
$(OX)\linkopts: $B\win\Makefile.msc
262262
echo $(OX)\add.obj > $@
263263
echo $(OX)\allrepo.obj >> $@
264264
echo $(OX)\attach.obj >> $@
265265
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -254,11 +254,11 @@
254 @echo Building zlib from "$(ZLIBDIR)"...
255 @pushd "$(ZLIBDIR)" && nmake /f win32\Makefile.msc $(ZLIB) && popd
256
257 $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OX)\linkopts zlib
258 cd $(OX)
259 link /NODEFAULTLIB:msvcrt -OUT:$@ $(LIBDIR) @linkopts
260
261 $(OX)\linkopts: $B\win\Makefile.msc
262 echo $(OX)\add.obj > $@
263 echo $(OX)\allrepo.obj >> $@
264 echo $(OX)\attach.obj >> $@
265
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -254,11 +254,11 @@
254 @echo Building zlib from "$(ZLIBDIR)"...
255 @pushd "$(ZLIBDIR)" && nmake /f win32\Makefile.msc $(ZLIB) && popd
256
257 $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OX)\linkopts zlib
258 cd $(OX)
259 link /NODEFAULTLIB:msvcrt -OUT:$@ $(LIBDIR) Wsetargv.obj @linkopts
260
261 $(OX)\linkopts: $B\win\Makefile.msc
262 echo $(OX)\add.obj > $@
263 echo $(OX)\allrepo.obj >> $@
264 echo $(OX)\attach.obj >> $@
265

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button