Fossil SCM
Pass argv arguments to Tcl
Commit
3709b1eaa212e0b1c5b014db4080c15bc508d967
Parent
c9bb3200658911d…
2 files changed
+12
-15
+11
-3
+12
-15
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -411,16 +411,10 @@ | ||
| 411 | 411 | const char *zCmdName = "unknown"; |
| 412 | 412 | int idx; |
| 413 | 413 | int rc; |
| 414 | 414 | int i; |
| 415 | 415 | |
| 416 | -#ifdef FOSSIL_ENABLE_TCL | |
| 417 | - g.tcl.argc = argc; | |
| 418 | - g.tcl.argv = argv; | |
| 419 | - g.tcl.interp = 0; | |
| 420 | -#endif | |
| 421 | - | |
| 422 | 416 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 423 | 417 | memset(&g, 0, sizeof(g)); |
| 424 | 418 | g.now = time(0); |
| 425 | 419 | g.argc = argc; |
| 426 | 420 | g.argv = argv; |
| @@ -436,22 +430,25 @@ | ||
| 436 | 430 | g.json.outOpt = cson_output_opt_empty; |
| 437 | 431 | g.json.outOpt.addNewline = 1; |
| 438 | 432 | g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */; |
| 439 | 433 | #endif /* FOSSIL_ENABLE_JSON */ |
| 440 | 434 | expand_args_option(); |
| 441 | - argc = g.argc; | |
| 442 | - argv = g.argv; | |
| 443 | - for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); | |
| 435 | + for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]); | |
| 436 | +#ifdef FOSSIL_ENABLE_TCL | |
| 437 | + g.tcl.argc = g.argc; | |
| 438 | + g.tcl.argv = g.argv; | |
| 439 | + g.tcl.interp = 0; | |
| 440 | +#endif | |
| 444 | 441 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 445 | 442 | zCmdName = "cgi"; |
| 446 | 443 | g.isHTTP = 1; |
| 447 | - }else if( argc<2 ){ | |
| 444 | + }else if( g.argc<2 ){ | |
| 448 | 445 | fossil_print( |
| 449 | 446 | "Usage: %s COMMAND ...\n" |
| 450 | 447 | " or: %s help -- for a list of common commands\n" |
| 451 | 448 | " or: %s help COMMMAND -- for help with the named command\n", |
| 452 | - argv[0], argv[0], argv[0]); | |
| 449 | + g.argv[0], g.argv[0], g.argv[0]); | |
| 453 | 450 | fossil_exit(1); |
| 454 | 451 | }else{ |
| 455 | 452 | const char *zChdir = find_option("chdir",0,1); |
| 456 | 453 | g.isHTTP = 0; |
| 457 | 454 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| @@ -469,13 +466,13 @@ | ||
| 469 | 466 | if( find_option("help",0,0)!=0 ){ |
| 470 | 467 | /* --help anywhere on the command line is translated into |
| 471 | 468 | ** "fossil help argv[1] argv[2]..." */ |
| 472 | 469 | int i; |
| 473 | 470 | char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) ); |
| 474 | - for(i=1; i<g.argc; i++) zNewArgv[i+1] = argv[i]; | |
| 471 | + for(i=1; i<g.argc; i++) zNewArgv[i+1] = g.argv[i]; | |
| 475 | 472 | zNewArgv[i+1] = 0; |
| 476 | - zNewArgv[0] = argv[0]; | |
| 473 | + zNewArgv[0] = g.argv[0]; | |
| 477 | 474 | zNewArgv[1] = "help"; |
| 478 | 475 | g.argc++; |
| 479 | 476 | g.argv = zNewArgv; |
| 480 | 477 | } |
| 481 | 478 | zCmdName = g.argv[1]; |
| @@ -482,11 +479,11 @@ | ||
| 482 | 479 | } |
| 483 | 480 | rc = name_search(zCmdName, aCommand, count(aCommand), &idx); |
| 484 | 481 | if( rc==1 ){ |
| 485 | 482 | fossil_fatal("%s: unknown command: %s\n" |
| 486 | 483 | "%s: use \"help\" for more information\n", |
| 487 | - argv[0], zCmdName, argv[0]); | |
| 484 | + g.argv[0], zCmdName, g.argv[0]); | |
| 488 | 485 | }else if( rc==2 ){ |
| 489 | 486 | int i, n; |
| 490 | 487 | Blob couldbe; |
| 491 | 488 | blob_zero(&couldbe); |
| 492 | 489 | n = strlen(zCmdName); |
| @@ -496,11 +493,11 @@ | ||
| 496 | 493 | } |
| 497 | 494 | } |
| 498 | 495 | fossil_print("%s: ambiguous command prefix: %s\n" |
| 499 | 496 | "%s: could be any of:%s\n" |
| 500 | 497 | "%s: use \"help\" for more information\n", |
| 501 | - argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); | |
| 498 | + g.argv[0], zCmdName, g.argv[0], blob_str(&couldbe), g.argv[0]); | |
| 502 | 499 | fossil_exit(1); |
| 503 | 500 | } |
| 504 | 501 | atexit( fossil_atexit ); |
| 505 | 502 | aCommand[idx].xFunc(); |
| 506 | 503 | fossil_exit(0); |
| 507 | 504 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -411,16 +411,10 @@ | |
| 411 | const char *zCmdName = "unknown"; |
| 412 | int idx; |
| 413 | int rc; |
| 414 | int i; |
| 415 | |
| 416 | #ifdef FOSSIL_ENABLE_TCL |
| 417 | g.tcl.argc = argc; |
| 418 | g.tcl.argv = argv; |
| 419 | g.tcl.interp = 0; |
| 420 | #endif |
| 421 | |
| 422 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 423 | memset(&g, 0, sizeof(g)); |
| 424 | g.now = time(0); |
| 425 | g.argc = argc; |
| 426 | g.argv = argv; |
| @@ -436,22 +430,25 @@ | |
| 436 | g.json.outOpt = cson_output_opt_empty; |
| 437 | g.json.outOpt.addNewline = 1; |
| 438 | g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */; |
| 439 | #endif /* FOSSIL_ENABLE_JSON */ |
| 440 | expand_args_option(); |
| 441 | argc = g.argc; |
| 442 | argv = g.argv; |
| 443 | for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); |
| 444 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 445 | zCmdName = "cgi"; |
| 446 | g.isHTTP = 1; |
| 447 | }else if( argc<2 ){ |
| 448 | fossil_print( |
| 449 | "Usage: %s COMMAND ...\n" |
| 450 | " or: %s help -- for a list of common commands\n" |
| 451 | " or: %s help COMMMAND -- for help with the named command\n", |
| 452 | argv[0], argv[0], argv[0]); |
| 453 | fossil_exit(1); |
| 454 | }else{ |
| 455 | const char *zChdir = find_option("chdir",0,1); |
| 456 | g.isHTTP = 0; |
| 457 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| @@ -469,13 +466,13 @@ | |
| 469 | if( find_option("help",0,0)!=0 ){ |
| 470 | /* --help anywhere on the command line is translated into |
| 471 | ** "fossil help argv[1] argv[2]..." */ |
| 472 | int i; |
| 473 | char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) ); |
| 474 | for(i=1; i<g.argc; i++) zNewArgv[i+1] = argv[i]; |
| 475 | zNewArgv[i+1] = 0; |
| 476 | zNewArgv[0] = argv[0]; |
| 477 | zNewArgv[1] = "help"; |
| 478 | g.argc++; |
| 479 | g.argv = zNewArgv; |
| 480 | } |
| 481 | zCmdName = g.argv[1]; |
| @@ -482,11 +479,11 @@ | |
| 482 | } |
| 483 | rc = name_search(zCmdName, aCommand, count(aCommand), &idx); |
| 484 | if( rc==1 ){ |
| 485 | fossil_fatal("%s: unknown command: %s\n" |
| 486 | "%s: use \"help\" for more information\n", |
| 487 | argv[0], zCmdName, argv[0]); |
| 488 | }else if( rc==2 ){ |
| 489 | int i, n; |
| 490 | Blob couldbe; |
| 491 | blob_zero(&couldbe); |
| 492 | n = strlen(zCmdName); |
| @@ -496,11 +493,11 @@ | |
| 496 | } |
| 497 | } |
| 498 | fossil_print("%s: ambiguous command prefix: %s\n" |
| 499 | "%s: could be any of:%s\n" |
| 500 | "%s: use \"help\" for more information\n", |
| 501 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 502 | fossil_exit(1); |
| 503 | } |
| 504 | atexit( fossil_atexit ); |
| 505 | aCommand[idx].xFunc(); |
| 506 | fossil_exit(0); |
| 507 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -411,16 +411,10 @@ | |
| 411 | const char *zCmdName = "unknown"; |
| 412 | int idx; |
| 413 | int rc; |
| 414 | int i; |
| 415 | |
| 416 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 417 | memset(&g, 0, sizeof(g)); |
| 418 | g.now = time(0); |
| 419 | g.argc = argc; |
| 420 | g.argv = argv; |
| @@ -436,22 +430,25 @@ | |
| 430 | g.json.outOpt = cson_output_opt_empty; |
| 431 | g.json.outOpt.addNewline = 1; |
| 432 | g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */; |
| 433 | #endif /* FOSSIL_ENABLE_JSON */ |
| 434 | expand_args_option(); |
| 435 | for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]); |
| 436 | #ifdef FOSSIL_ENABLE_TCL |
| 437 | g.tcl.argc = g.argc; |
| 438 | g.tcl.argv = g.argv; |
| 439 | g.tcl.interp = 0; |
| 440 | #endif |
| 441 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 442 | zCmdName = "cgi"; |
| 443 | g.isHTTP = 1; |
| 444 | }else if( g.argc<2 ){ |
| 445 | fossil_print( |
| 446 | "Usage: %s COMMAND ...\n" |
| 447 | " or: %s help -- for a list of common commands\n" |
| 448 | " or: %s help COMMMAND -- for help with the named command\n", |
| 449 | g.argv[0], g.argv[0], g.argv[0]); |
| 450 | fossil_exit(1); |
| 451 | }else{ |
| 452 | const char *zChdir = find_option("chdir",0,1); |
| 453 | g.isHTTP = 0; |
| 454 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| @@ -469,13 +466,13 @@ | |
| 466 | if( find_option("help",0,0)!=0 ){ |
| 467 | /* --help anywhere on the command line is translated into |
| 468 | ** "fossil help argv[1] argv[2]..." */ |
| 469 | int i; |
| 470 | char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) ); |
| 471 | for(i=1; i<g.argc; i++) zNewArgv[i+1] = g.argv[i]; |
| 472 | zNewArgv[i+1] = 0; |
| 473 | zNewArgv[0] = g.argv[0]; |
| 474 | zNewArgv[1] = "help"; |
| 475 | g.argc++; |
| 476 | g.argv = zNewArgv; |
| 477 | } |
| 478 | zCmdName = g.argv[1]; |
| @@ -482,11 +479,11 @@ | |
| 479 | } |
| 480 | rc = name_search(zCmdName, aCommand, count(aCommand), &idx); |
| 481 | if( rc==1 ){ |
| 482 | fossil_fatal("%s: unknown command: %s\n" |
| 483 | "%s: use \"help\" for more information\n", |
| 484 | g.argv[0], zCmdName, g.argv[0]); |
| 485 | }else if( rc==2 ){ |
| 486 | int i, n; |
| 487 | Blob couldbe; |
| 488 | blob_zero(&couldbe); |
| 489 | n = strlen(zCmdName); |
| @@ -496,11 +493,11 @@ | |
| 493 | } |
| 494 | } |
| 495 | fossil_print("%s: ambiguous command prefix: %s\n" |
| 496 | "%s: could be any of:%s\n" |
| 497 | "%s: use \"help\" for more information\n", |
| 498 | g.argv[0], zCmdName, g.argv[0], blob_str(&couldbe), g.argv[0]); |
| 499 | fossil_exit(1); |
| 500 | } |
| 501 | atexit( fossil_atexit ); |
| 502 | aCommand[idx].xFunc(); |
| 503 | fossil_exit(0); |
| 504 |
+11
-3
| --- src/th_tcl.c | ||
| +++ src/th_tcl.c | ||
| @@ -389,13 +389,11 @@ | ||
| 389 | 389 | return TH_ERROR; |
| 390 | 390 | } |
| 391 | 391 | if ( tclContext->interp ){ |
| 392 | 392 | return TH_OK; |
| 393 | 393 | } |
| 394 | - if ( tclContext->argc>0 && tclContext->argv ) { | |
| 395 | - Tcl_FindExecutable(tclContext->argv[0]); | |
| 396 | - } | |
| 394 | + Tcl_FindExecutable(tclContext->argv[0]); | |
| 397 | 395 | tclInterp = tclContext->interp = Tcl_CreateInterp(); |
| 398 | 396 | if( !tclInterp || Tcl_InterpDeleted(tclInterp) ){ |
| 399 | 397 | Th_ErrorMessage(interp, |
| 400 | 398 | "Could not create Tcl interpreter", (const char *)"", 0); |
| 401 | 399 | return TH_ERROR; |
| @@ -405,10 +403,20 @@ | ||
| 405 | 403 | "Tcl initialization error:", Tcl_GetStringResult(tclInterp), -1); |
| 406 | 404 | Tcl_DeleteInterp(tclInterp); |
| 407 | 405 | tclContext->interp = tclInterp = 0; |
| 408 | 406 | return TH_ERROR; |
| 409 | 407 | } |
| 408 | + if (tclContext->argc > 0) { | |
| 409 | + int argc = tclContext->argc - 1; | |
| 410 | + char **argv = tclContext->argv + 1; | |
| 411 | + Tcl_Obj *argvPtr = Tcl_NewListObj(0, NULL); | |
| 412 | + while (argc--) { | |
| 413 | + Tcl_ListObjAppendElement(NULL, argvPtr, Tcl_NewStringObj(*argv++, -1)); | |
| 414 | + } | |
| 415 | + Tcl_SetVar2Ex(tclContext->interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY); | |
| 416 | + } | |
| 417 | + | |
| 410 | 418 | /* Add the TH1 integration commands to Tcl. */ |
| 411 | 419 | Tcl_CallWhenDeleted(tclInterp, Th1DeleteProc, interp); |
| 412 | 420 | Tcl_CreateObjCommand(tclInterp, "th1Eval", Th1EvalObjCmd, interp, NULL); |
| 413 | 421 | Tcl_CreateObjCommand(tclInterp, "th1Expr", Th1ExprObjCmd, interp, NULL); |
| 414 | 422 | return TH_OK; |
| 415 | 423 |
| --- src/th_tcl.c | |
| +++ src/th_tcl.c | |
| @@ -389,13 +389,11 @@ | |
| 389 | return TH_ERROR; |
| 390 | } |
| 391 | if ( tclContext->interp ){ |
| 392 | return TH_OK; |
| 393 | } |
| 394 | if ( tclContext->argc>0 && tclContext->argv ) { |
| 395 | Tcl_FindExecutable(tclContext->argv[0]); |
| 396 | } |
| 397 | tclInterp = tclContext->interp = Tcl_CreateInterp(); |
| 398 | if( !tclInterp || Tcl_InterpDeleted(tclInterp) ){ |
| 399 | Th_ErrorMessage(interp, |
| 400 | "Could not create Tcl interpreter", (const char *)"", 0); |
| 401 | return TH_ERROR; |
| @@ -405,10 +403,20 @@ | |
| 405 | "Tcl initialization error:", Tcl_GetStringResult(tclInterp), -1); |
| 406 | Tcl_DeleteInterp(tclInterp); |
| 407 | tclContext->interp = tclInterp = 0; |
| 408 | return TH_ERROR; |
| 409 | } |
| 410 | /* Add the TH1 integration commands to Tcl. */ |
| 411 | Tcl_CallWhenDeleted(tclInterp, Th1DeleteProc, interp); |
| 412 | Tcl_CreateObjCommand(tclInterp, "th1Eval", Th1EvalObjCmd, interp, NULL); |
| 413 | Tcl_CreateObjCommand(tclInterp, "th1Expr", Th1ExprObjCmd, interp, NULL); |
| 414 | return TH_OK; |
| 415 |
| --- src/th_tcl.c | |
| +++ src/th_tcl.c | |
| @@ -389,13 +389,11 @@ | |
| 389 | return TH_ERROR; |
| 390 | } |
| 391 | if ( tclContext->interp ){ |
| 392 | return TH_OK; |
| 393 | } |
| 394 | Tcl_FindExecutable(tclContext->argv[0]); |
| 395 | tclInterp = tclContext->interp = Tcl_CreateInterp(); |
| 396 | if( !tclInterp || Tcl_InterpDeleted(tclInterp) ){ |
| 397 | Th_ErrorMessage(interp, |
| 398 | "Could not create Tcl interpreter", (const char *)"", 0); |
| 399 | return TH_ERROR; |
| @@ -405,10 +403,20 @@ | |
| 403 | "Tcl initialization error:", Tcl_GetStringResult(tclInterp), -1); |
| 404 | Tcl_DeleteInterp(tclInterp); |
| 405 | tclContext->interp = tclInterp = 0; |
| 406 | return TH_ERROR; |
| 407 | } |
| 408 | if (tclContext->argc > 0) { |
| 409 | int argc = tclContext->argc - 1; |
| 410 | char **argv = tclContext->argv + 1; |
| 411 | Tcl_Obj *argvPtr = Tcl_NewListObj(0, NULL); |
| 412 | while (argc--) { |
| 413 | Tcl_ListObjAppendElement(NULL, argvPtr, Tcl_NewStringObj(*argv++, -1)); |
| 414 | } |
| 415 | Tcl_SetVar2Ex(tclContext->interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY); |
| 416 | } |
| 417 | |
| 418 | /* Add the TH1 integration commands to Tcl. */ |
| 419 | Tcl_CallWhenDeleted(tclInterp, Th1DeleteProc, interp); |
| 420 | Tcl_CreateObjCommand(tclInterp, "th1Eval", Th1EvalObjCmd, interp, NULL); |
| 421 | Tcl_CreateObjCommand(tclInterp, "th1Expr", Th1ExprObjCmd, interp, NULL); |
| 422 | return TH_OK; |
| 423 |