Fossil SCM
Reformat the windows command-line parser to following the Fossil style. Use the alternative command-line parser on all windows builds, not just for MinGW builds, to simplify the logic and so that the alternative parser code is testing more heavily.
Commit
f575af97b2221e9e822cab27b8e153c70bcd01f8
Parent
047dd6260411595…
1 file changed
+116
-129
+116
-129
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -330,131 +330,125 @@ | ||
| 330 | 330 | if(g.db){ |
| 331 | 331 | db_close(0); |
| 332 | 332 | } |
| 333 | 333 | } |
| 334 | 334 | |
| 335 | +#if defined(_WIN32) | |
| 335 | 336 | /* |
| 336 | - *------------------------------------------------------------------------- | |
| 337 | - * | |
| 338 | - * setargv -- | |
| 339 | - * | |
| 340 | - * Parse the Windows command line string into argc/argv. Done here | |
| 341 | - * because we don't trust the builtin argument parser in crt0. Windows | |
| 342 | - * applications are responsible for breaking their command line into | |
| 343 | - * arguments. | |
| 344 | - * | |
| 345 | - * 2N backslashes + quote -> N backslashes + begin quoted string | |
| 346 | - * 2N + 1 backslashes + quote -> literal | |
| 347 | - * N backslashes + non-quote -> literal | |
| 348 | - * quote + quote in a quoted string -> single quote | |
| 349 | - * quote + quote not in quoted string -> empty string | |
| 350 | - * quote -> begin quoted string | |
| 351 | - * | |
| 352 | - * Results: | |
| 353 | - * Fills argcPtr with the number of arguments and argvPtr with the array | |
| 354 | - * of arguments. | |
| 355 | - * | |
| 356 | - * Side effects: | |
| 357 | - * Memory allocated. | |
| 358 | - * | |
| 359 | - *-------------------------------------------------------------------------- | |
| 360 | - */ | |
| 361 | - | |
| 362 | -#ifdef MINGW_BROKEN_MAINARGS | |
| 337 | +** Parse the command-line arguments passed to windows. We do this | |
| 338 | +** ourselves to work around bugs in the command-line parsing of MinGW. | |
| 339 | +** It is possible (in theory) to only use this routine when compiling | |
| 340 | +** with MinGW and to use built-in command-line parsing for MSVC and | |
| 341 | +** MinGW-64. However, the code is here, it is efficient, and works, and | |
| 342 | +** by using it in all cases we do a better job of testing it. If you suspect | |
| 343 | +** a bug in this code, test your theory by invoking "fossil test-echo". | |
| 344 | +** | |
| 345 | +** This routine is copied from TCL with some reformatting. | |
| 346 | +** The original comment text follows: | |
| 347 | +** | |
| 348 | +** Parse the Windows command line string into argc/argv. Done here | |
| 349 | +** because we don't trust the builtin argument parser in crt0. Windows | |
| 350 | +** applications are responsible for breaking their command line into | |
| 351 | +** arguments. | |
| 352 | +** | |
| 353 | +** 2N backslashes + quote -> N backslashes + begin quoted string | |
| 354 | +** 2N + 1 backslashes + quote -> literal | |
| 355 | +** N backslashes + non-quote -> literal | |
| 356 | +** quote + quote in a quoted string -> single quote | |
| 357 | +** quote + quote not in quoted string -> empty string | |
| 358 | +** quote -> begin quoted string | |
| 359 | +** | |
| 360 | +** Results: | |
| 361 | +** Fills argcPtr with the number of arguments and argvPtr with the array | |
| 362 | +** of arguments. | |
| 363 | +*/ | |
| 363 | 364 | #include <tchar.h> |
| 364 | - | |
| 365 | -static void | |
| 366 | -setargv( | |
| 367 | - int *argcPtr, /* Filled with number of argument strings. */ | |
| 368 | - void *argvPtr) /* Filled with argument strings (malloc'd). */ | |
| 369 | -{ | |
| 370 | - TCHAR *cmdLine, *p, *arg, *argSpace; | |
| 371 | - TCHAR **argv; | |
| 372 | - int argc, size, inquote, copy, slashes; | |
| 373 | - | |
| 374 | - cmdLine = GetCommandLine(); | |
| 375 | - | |
| 376 | - /* | |
| 377 | - * Precompute an overly pessimistic guess at the number of arguments in | |
| 378 | - * the command line by counting non-space spans. | |
| 379 | - */ | |
| 380 | - | |
| 381 | - size = 2; | |
| 382 | - for (p = cmdLine; *p != TEXT('\0'); p++) { | |
| 383 | - if ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ | |
| 384 | - size++; | |
| 385 | - while ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ | |
| 386 | - p++; | |
| 387 | - } | |
| 388 | - if (*p == TEXT('\0')) { | |
| 389 | - break; | |
| 390 | - } | |
| 391 | - } | |
| 392 | - } | |
| 393 | - | |
| 394 | - argSpace = fossil_malloc(size * sizeof(char *) | |
| 395 | - + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); | |
| 396 | - argv = (TCHAR **) argSpace; | |
| 397 | - argSpace += size * (sizeof(char *)/sizeof(TCHAR)); | |
| 398 | - size--; | |
| 399 | - | |
| 400 | - p = cmdLine; | |
| 401 | - for (argc = 0; argc < size; argc++) { | |
| 402 | - argv[argc] = arg = argSpace; | |
| 403 | - while ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ | |
| 404 | - p++; | |
| 405 | - } | |
| 406 | - if (*p == TEXT('\0')) { | |
| 407 | - break; | |
| 408 | - } | |
| 409 | - | |
| 410 | - inquote = 0; | |
| 411 | - slashes = 0; | |
| 412 | - while (1) { | |
| 413 | - copy = 1; | |
| 414 | - while (*p == TEXT('\\')) { | |
| 415 | - slashes++; | |
| 416 | - p++; | |
| 417 | - } | |
| 418 | - if (*p == TEXT('"')) { | |
| 419 | - if ((slashes & 1) == 0) { | |
| 420 | - copy = 0; | |
| 421 | - if ((inquote) && (p[1] == TEXT('"'))) { | |
| 422 | - p++; | |
| 423 | - copy = 1; | |
| 424 | - } else { | |
| 425 | - inquote = !inquote; | |
| 426 | - } | |
| 427 | - } | |
| 428 | - slashes >>= 1; | |
| 429 | - } | |
| 430 | - | |
| 431 | - while (slashes) { | |
| 432 | - *arg = TEXT('\\'); | |
| 433 | - arg++; | |
| 434 | - slashes--; | |
| 435 | - } | |
| 436 | - | |
| 437 | - if ((*p == TEXT('\0')) || (!inquote && | |
| 438 | - ((*p == TEXT(' ')) || (*p == TEXT('\t'))))) { /* INTL: ISO space. */ | |
| 439 | - break; | |
| 440 | - } | |
| 441 | - if (copy != 0) { | |
| 442 | - *arg = *p; | |
| 443 | - arg++; | |
| 444 | - } | |
| 445 | - p++; | |
| 446 | - } | |
| 447 | - *arg = '\0'; | |
| 448 | - argSpace = arg + 1; | |
| 449 | - } | |
| 450 | - argv[argc] = NULL; | |
| 451 | - | |
| 452 | - *argcPtr = argc; | |
| 453 | - *((TCHAR ***)argvPtr) = argv; | |
| 454 | -} | |
| 455 | -#endif /* MINGW_BROKEN_MAINARGS */ | |
| 365 | +#define tchar_isspace(X) ((X)==TEXT(' ') || (X)==TEXT('\t')) | |
| 366 | +static void parse_windows_command_line( | |
| 367 | + int *argcPtr, /* Filled with number of argument strings. */ | |
| 368 | + void *argvPtr /* Filled with argument strings (malloc'd). */ | |
| 369 | +){ | |
| 370 | + TCHAR *cmdLine, *p, *arg, *argSpace; | |
| 371 | + TCHAR **argv; | |
| 372 | + int argc, size, inquote, copy, slashes; | |
| 373 | + | |
| 374 | + cmdLine = GetCommandLine(); | |
| 375 | + | |
| 376 | + /* | |
| 377 | + ** Precompute an overly pessimistic guess at the number of arguments in | |
| 378 | + ** the command line by counting non-space spans. | |
| 379 | + */ | |
| 380 | + size = 2; | |
| 381 | + for(p=cmdLine; *p!=TEXT('\0'); p++){ | |
| 382 | + if( tchar_isspace(*p) ){ | |
| 383 | + size++; | |
| 384 | + while( tchar_isspace(*p) ){ | |
| 385 | + p++; | |
| 386 | + } | |
| 387 | + if( *p==TEXT('\0') ){ | |
| 388 | + break; | |
| 389 | + } | |
| 390 | + } | |
| 391 | + } | |
| 392 | + | |
| 393 | + argSpace = fossil_malloc(size * sizeof(char*) | |
| 394 | + + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); | |
| 395 | + argv = (TCHAR**)argSpace; | |
| 396 | + argSpace += size*(sizeof(char*)/sizeof(TCHAR)); | |
| 397 | + size--; | |
| 398 | + | |
| 399 | + p = cmdLine; | |
| 400 | + for(argc=0; argc<size; argc++){ | |
| 401 | + argv[argc] = arg = argSpace; | |
| 402 | + while( tchar_isspace(*p) ){ | |
| 403 | + p++; | |
| 404 | + } | |
| 405 | + if (*p == TEXT('\0')) { | |
| 406 | + break; | |
| 407 | + } | |
| 408 | + inquote = 0; | |
| 409 | + slashes = 0; | |
| 410 | + while(1){ | |
| 411 | + copy = 1; | |
| 412 | + while( *p==TEXT('\\') ){ | |
| 413 | + slashes++; | |
| 414 | + p++; | |
| 415 | + } | |
| 416 | + if( *p==TEXT('"') ){ | |
| 417 | + if( (slashes&1)==0 ){ | |
| 418 | + copy = 0; | |
| 419 | + if( inquote && p[1]==TEXT('"') ){ | |
| 420 | + p++; | |
| 421 | + copy = 1; | |
| 422 | + }else{ | |
| 423 | + inquote = !inquote; | |
| 424 | + } | |
| 425 | + } | |
| 426 | + slashes >>= 1; | |
| 427 | + } | |
| 428 | + while( slashes ){ | |
| 429 | + *arg = TEXT('\\'); | |
| 430 | + arg++; | |
| 431 | + slashes--; | |
| 432 | + } | |
| 433 | + if( *p==TEXT('\0') || (!inquote && tchar_isspace(*p)) ){ | |
| 434 | + break; | |
| 435 | + } | |
| 436 | + if( copy!=0 ){ | |
| 437 | + *arg = *p; | |
| 438 | + arg++; | |
| 439 | + } | |
| 440 | + p++; | |
| 441 | + } | |
| 442 | + *arg = '\0'; | |
| 443 | + argSpace = arg + 1; | |
| 444 | + } | |
| 445 | + argv[argc] = NULL; | |
| 446 | + *argcPtr = argc; | |
| 447 | + *((TCHAR ***)argvPtr) = argv; | |
| 448 | +} | |
| 449 | +#endif /* defined(_WIN32) */ | |
| 456 | 450 | |
| 457 | 451 | |
| 458 | 452 | /* |
| 459 | 453 | ** Convert all arguments from mbcs (or unicode) to UTF-8. Then |
| 460 | 454 | ** search g.argv for arguments "--args FILENAME". If found, then |
| @@ -482,13 +476,11 @@ | ||
| 482 | 476 | #endif |
| 483 | 477 | |
| 484 | 478 | g.argc = argc; |
| 485 | 479 | g.argv = argv; |
| 486 | 480 | #ifdef _WIN32 |
| 487 | -#ifdef MINGW_BROKEN_MAINARGS | |
| 488 | - setargv(&g.argc, &g.argv); | |
| 489 | -#endif | |
| 481 | + parse_windows_command_line(&g.argc, &g.argv); | |
| 490 | 482 | GetModuleFileNameW(NULL, buf, MAX_PATH); |
| 491 | 483 | g.argv[0] = fossil_unicode_to_utf8(buf); |
| 492 | 484 | #ifdef UNICODE |
| 493 | 485 | for(i=1; i<g.argc; i++) g.argv[i] = fossil_unicode_to_utf8(g.argv[i]); |
| 494 | 486 | #else |
| @@ -530,11 +522,11 @@ | ||
| 530 | 522 | z[n-1] = 0; |
| 531 | 523 | if (foundBom == -1) { |
| 532 | 524 | static const char bom[] = { 0xEF, 0xBB, 0xBF }; |
| 533 | 525 | foundBom = memcmp(z, bom, 3)==0; |
| 534 | 526 | if( foundBom ) { |
| 535 | - z += 3; n -= 3; | |
| 527 | + z += 3; n -= 3; | |
| 536 | 528 | } |
| 537 | 529 | } |
| 538 | 530 | if((n>1) && ('\r'==z[n-2])){ |
| 539 | 531 | if(n==2) continue /*empty line*/; |
| 540 | 532 | z[n-2] = 0; |
| @@ -560,16 +552,11 @@ | ||
| 560 | 552 | } |
| 561 | 553 | |
| 562 | 554 | /* |
| 563 | 555 | ** This procedure runs first. |
| 564 | 556 | */ |
| 565 | -#if defined(_WIN32) && defined(UNICODE) && !defined(MINGW_BROKEN_MAINARGS) | |
| 566 | -int wmain(int argc, wchar_t **argv) | |
| 567 | -#else | |
| 568 | -int main(int argc, char **argv) | |
| 569 | -#endif | |
| 570 | -{ | |
| 557 | +int main(int argc, char **argv){ | |
| 571 | 558 | const char *zCmdName = "unknown"; |
| 572 | 559 | int idx; |
| 573 | 560 | int rc; |
| 574 | 561 | |
| 575 | 562 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 576 | 563 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -330,131 +330,125 @@ | |
| 330 | if(g.db){ |
| 331 | db_close(0); |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | /* |
| 336 | *------------------------------------------------------------------------- |
| 337 | * |
| 338 | * setargv -- |
| 339 | * |
| 340 | * Parse the Windows command line string into argc/argv. Done here |
| 341 | * because we don't trust the builtin argument parser in crt0. Windows |
| 342 | * applications are responsible for breaking their command line into |
| 343 | * arguments. |
| 344 | * |
| 345 | * 2N backslashes + quote -> N backslashes + begin quoted string |
| 346 | * 2N + 1 backslashes + quote -> literal |
| 347 | * N backslashes + non-quote -> literal |
| 348 | * quote + quote in a quoted string -> single quote |
| 349 | * quote + quote not in quoted string -> empty string |
| 350 | * quote -> begin quoted string |
| 351 | * |
| 352 | * Results: |
| 353 | * Fills argcPtr with the number of arguments and argvPtr with the array |
| 354 | * of arguments. |
| 355 | * |
| 356 | * Side effects: |
| 357 | * Memory allocated. |
| 358 | * |
| 359 | *-------------------------------------------------------------------------- |
| 360 | */ |
| 361 | |
| 362 | #ifdef MINGW_BROKEN_MAINARGS |
| 363 | #include <tchar.h> |
| 364 | |
| 365 | static void |
| 366 | setargv( |
| 367 | int *argcPtr, /* Filled with number of argument strings. */ |
| 368 | void *argvPtr) /* Filled with argument strings (malloc'd). */ |
| 369 | { |
| 370 | TCHAR *cmdLine, *p, *arg, *argSpace; |
| 371 | TCHAR **argv; |
| 372 | int argc, size, inquote, copy, slashes; |
| 373 | |
| 374 | cmdLine = GetCommandLine(); |
| 375 | |
| 376 | /* |
| 377 | * Precompute an overly pessimistic guess at the number of arguments in |
| 378 | * the command line by counting non-space spans. |
| 379 | */ |
| 380 | |
| 381 | size = 2; |
| 382 | for (p = cmdLine; *p != TEXT('\0'); p++) { |
| 383 | if ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ |
| 384 | size++; |
| 385 | while ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ |
| 386 | p++; |
| 387 | } |
| 388 | if (*p == TEXT('\0')) { |
| 389 | break; |
| 390 | } |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | argSpace = fossil_malloc(size * sizeof(char *) |
| 395 | + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); |
| 396 | argv = (TCHAR **) argSpace; |
| 397 | argSpace += size * (sizeof(char *)/sizeof(TCHAR)); |
| 398 | size--; |
| 399 | |
| 400 | p = cmdLine; |
| 401 | for (argc = 0; argc < size; argc++) { |
| 402 | argv[argc] = arg = argSpace; |
| 403 | while ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */ |
| 404 | p++; |
| 405 | } |
| 406 | if (*p == TEXT('\0')) { |
| 407 | break; |
| 408 | } |
| 409 | |
| 410 | inquote = 0; |
| 411 | slashes = 0; |
| 412 | while (1) { |
| 413 | copy = 1; |
| 414 | while (*p == TEXT('\\')) { |
| 415 | slashes++; |
| 416 | p++; |
| 417 | } |
| 418 | if (*p == TEXT('"')) { |
| 419 | if ((slashes & 1) == 0) { |
| 420 | copy = 0; |
| 421 | if ((inquote) && (p[1] == TEXT('"'))) { |
| 422 | p++; |
| 423 | copy = 1; |
| 424 | } else { |
| 425 | inquote = !inquote; |
| 426 | } |
| 427 | } |
| 428 | slashes >>= 1; |
| 429 | } |
| 430 | |
| 431 | while (slashes) { |
| 432 | *arg = TEXT('\\'); |
| 433 | arg++; |
| 434 | slashes--; |
| 435 | } |
| 436 | |
| 437 | if ((*p == TEXT('\0')) || (!inquote && |
| 438 | ((*p == TEXT(' ')) || (*p == TEXT('\t'))))) { /* INTL: ISO space. */ |
| 439 | break; |
| 440 | } |
| 441 | if (copy != 0) { |
| 442 | *arg = *p; |
| 443 | arg++; |
| 444 | } |
| 445 | p++; |
| 446 | } |
| 447 | *arg = '\0'; |
| 448 | argSpace = arg + 1; |
| 449 | } |
| 450 | argv[argc] = NULL; |
| 451 | |
| 452 | *argcPtr = argc; |
| 453 | *((TCHAR ***)argvPtr) = argv; |
| 454 | } |
| 455 | #endif /* MINGW_BROKEN_MAINARGS */ |
| 456 | |
| 457 | |
| 458 | /* |
| 459 | ** Convert all arguments from mbcs (or unicode) to UTF-8. Then |
| 460 | ** search g.argv for arguments "--args FILENAME". If found, then |
| @@ -482,13 +476,11 @@ | |
| 482 | #endif |
| 483 | |
| 484 | g.argc = argc; |
| 485 | g.argv = argv; |
| 486 | #ifdef _WIN32 |
| 487 | #ifdef MINGW_BROKEN_MAINARGS |
| 488 | setargv(&g.argc, &g.argv); |
| 489 | #endif |
| 490 | GetModuleFileNameW(NULL, buf, MAX_PATH); |
| 491 | g.argv[0] = fossil_unicode_to_utf8(buf); |
| 492 | #ifdef UNICODE |
| 493 | for(i=1; i<g.argc; i++) g.argv[i] = fossil_unicode_to_utf8(g.argv[i]); |
| 494 | #else |
| @@ -530,11 +522,11 @@ | |
| 530 | z[n-1] = 0; |
| 531 | if (foundBom == -1) { |
| 532 | static const char bom[] = { 0xEF, 0xBB, 0xBF }; |
| 533 | foundBom = memcmp(z, bom, 3)==0; |
| 534 | if( foundBom ) { |
| 535 | z += 3; n -= 3; |
| 536 | } |
| 537 | } |
| 538 | if((n>1) && ('\r'==z[n-2])){ |
| 539 | if(n==2) continue /*empty line*/; |
| 540 | z[n-2] = 0; |
| @@ -560,16 +552,11 @@ | |
| 560 | } |
| 561 | |
| 562 | /* |
| 563 | ** This procedure runs first. |
| 564 | */ |
| 565 | #if defined(_WIN32) && defined(UNICODE) && !defined(MINGW_BROKEN_MAINARGS) |
| 566 | int wmain(int argc, wchar_t **argv) |
| 567 | #else |
| 568 | int main(int argc, char **argv) |
| 569 | #endif |
| 570 | { |
| 571 | const char *zCmdName = "unknown"; |
| 572 | int idx; |
| 573 | int rc; |
| 574 | |
| 575 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 576 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -330,131 +330,125 @@ | |
| 330 | if(g.db){ |
| 331 | db_close(0); |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | #if defined(_WIN32) |
| 336 | /* |
| 337 | ** Parse the command-line arguments passed to windows. We do this |
| 338 | ** ourselves to work around bugs in the command-line parsing of MinGW. |
| 339 | ** It is possible (in theory) to only use this routine when compiling |
| 340 | ** with MinGW and to use built-in command-line parsing for MSVC and |
| 341 | ** MinGW-64. However, the code is here, it is efficient, and works, and |
| 342 | ** by using it in all cases we do a better job of testing it. If you suspect |
| 343 | ** a bug in this code, test your theory by invoking "fossil test-echo". |
| 344 | ** |
| 345 | ** This routine is copied from TCL with some reformatting. |
| 346 | ** The original comment text follows: |
| 347 | ** |
| 348 | ** Parse the Windows command line string into argc/argv. Done here |
| 349 | ** because we don't trust the builtin argument parser in crt0. Windows |
| 350 | ** applications are responsible for breaking their command line into |
| 351 | ** arguments. |
| 352 | ** |
| 353 | ** 2N backslashes + quote -> N backslashes + begin quoted string |
| 354 | ** 2N + 1 backslashes + quote -> literal |
| 355 | ** N backslashes + non-quote -> literal |
| 356 | ** quote + quote in a quoted string -> single quote |
| 357 | ** quote + quote not in quoted string -> empty string |
| 358 | ** quote -> begin quoted string |
| 359 | ** |
| 360 | ** Results: |
| 361 | ** Fills argcPtr with the number of arguments and argvPtr with the array |
| 362 | ** of arguments. |
| 363 | */ |
| 364 | #include <tchar.h> |
| 365 | #define tchar_isspace(X) ((X)==TEXT(' ') || (X)==TEXT('\t')) |
| 366 | static void parse_windows_command_line( |
| 367 | int *argcPtr, /* Filled with number of argument strings. */ |
| 368 | void *argvPtr /* Filled with argument strings (malloc'd). */ |
| 369 | ){ |
| 370 | TCHAR *cmdLine, *p, *arg, *argSpace; |
| 371 | TCHAR **argv; |
| 372 | int argc, size, inquote, copy, slashes; |
| 373 | |
| 374 | cmdLine = GetCommandLine(); |
| 375 | |
| 376 | /* |
| 377 | ** Precompute an overly pessimistic guess at the number of arguments in |
| 378 | ** the command line by counting non-space spans. |
| 379 | */ |
| 380 | size = 2; |
| 381 | for(p=cmdLine; *p!=TEXT('\0'); p++){ |
| 382 | if( tchar_isspace(*p) ){ |
| 383 | size++; |
| 384 | while( tchar_isspace(*p) ){ |
| 385 | p++; |
| 386 | } |
| 387 | if( *p==TEXT('\0') ){ |
| 388 | break; |
| 389 | } |
| 390 | } |
| 391 | } |
| 392 | |
| 393 | argSpace = fossil_malloc(size * sizeof(char*) |
| 394 | + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); |
| 395 | argv = (TCHAR**)argSpace; |
| 396 | argSpace += size*(sizeof(char*)/sizeof(TCHAR)); |
| 397 | size--; |
| 398 | |
| 399 | p = cmdLine; |
| 400 | for(argc=0; argc<size; argc++){ |
| 401 | argv[argc] = arg = argSpace; |
| 402 | while( tchar_isspace(*p) ){ |
| 403 | p++; |
| 404 | } |
| 405 | if (*p == TEXT('\0')) { |
| 406 | break; |
| 407 | } |
| 408 | inquote = 0; |
| 409 | slashes = 0; |
| 410 | while(1){ |
| 411 | copy = 1; |
| 412 | while( *p==TEXT('\\') ){ |
| 413 | slashes++; |
| 414 | p++; |
| 415 | } |
| 416 | if( *p==TEXT('"') ){ |
| 417 | if( (slashes&1)==0 ){ |
| 418 | copy = 0; |
| 419 | if( inquote && p[1]==TEXT('"') ){ |
| 420 | p++; |
| 421 | copy = 1; |
| 422 | }else{ |
| 423 | inquote = !inquote; |
| 424 | } |
| 425 | } |
| 426 | slashes >>= 1; |
| 427 | } |
| 428 | while( slashes ){ |
| 429 | *arg = TEXT('\\'); |
| 430 | arg++; |
| 431 | slashes--; |
| 432 | } |
| 433 | if( *p==TEXT('\0') || (!inquote && tchar_isspace(*p)) ){ |
| 434 | break; |
| 435 | } |
| 436 | if( copy!=0 ){ |
| 437 | *arg = *p; |
| 438 | arg++; |
| 439 | } |
| 440 | p++; |
| 441 | } |
| 442 | *arg = '\0'; |
| 443 | argSpace = arg + 1; |
| 444 | } |
| 445 | argv[argc] = NULL; |
| 446 | *argcPtr = argc; |
| 447 | *((TCHAR ***)argvPtr) = argv; |
| 448 | } |
| 449 | #endif /* defined(_WIN32) */ |
| 450 | |
| 451 | |
| 452 | /* |
| 453 | ** Convert all arguments from mbcs (or unicode) to UTF-8. Then |
| 454 | ** search g.argv for arguments "--args FILENAME". If found, then |
| @@ -482,13 +476,11 @@ | |
| 476 | #endif |
| 477 | |
| 478 | g.argc = argc; |
| 479 | g.argv = argv; |
| 480 | #ifdef _WIN32 |
| 481 | parse_windows_command_line(&g.argc, &g.argv); |
| 482 | GetModuleFileNameW(NULL, buf, MAX_PATH); |
| 483 | g.argv[0] = fossil_unicode_to_utf8(buf); |
| 484 | #ifdef UNICODE |
| 485 | for(i=1; i<g.argc; i++) g.argv[i] = fossil_unicode_to_utf8(g.argv[i]); |
| 486 | #else |
| @@ -530,11 +522,11 @@ | |
| 522 | z[n-1] = 0; |
| 523 | if (foundBom == -1) { |
| 524 | static const char bom[] = { 0xEF, 0xBB, 0xBF }; |
| 525 | foundBom = memcmp(z, bom, 3)==0; |
| 526 | if( foundBom ) { |
| 527 | z += 3; n -= 3; |
| 528 | } |
| 529 | } |
| 530 | if((n>1) && ('\r'==z[n-2])){ |
| 531 | if(n==2) continue /*empty line*/; |
| 532 | z[n-2] = 0; |
| @@ -560,16 +552,11 @@ | |
| 552 | } |
| 553 | |
| 554 | /* |
| 555 | ** This procedure runs first. |
| 556 | */ |
| 557 | int main(int argc, char **argv){ |
| 558 | const char *zCmdName = "unknown"; |
| 559 | int idx; |
| 560 | int rc; |
| 561 | |
| 562 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 563 |