Changes On Branch tcl-argv-handling
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch tcl-argv-handling Excluding Merge-Ins

This is equivalent to a diff from c9bb320065 to 3709b1eaa2

2012-08-22
11:51
Merge the TCL argument handling patches into trunk. check-in: b6a7e52c93 user: drh tags: trunk
11:15
Modify the Tcl argument handling to deal with object reference counts and errors. check-in: 46864ac9cc user: mistachkin tags: tcl-argv-handling-v2
07:45
Pass argv arguments to Tcl Closed-Leaf check-in: 3709b1eaa2 user: jan.nijtmans tags: tcl-argv-handling
2012-08-21
23:45
Restore the previous Tcl argc/argv handling as all the arguments will be used for the Tcl argv script variable. check-in: c9bb320065 user: mistachkin tags: trunk
14:25
Tcl only uses argv0 so it is enough to transfer only that one argument. check-in: 7f96a71599 user: drh tags: trunk

Changes to src/main.c.

   409    409   */
   410    410   int main(int argc, char **argv){
   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;
   427    421   #ifdef FOSSIL_ENABLE_JSON
   428    422   #if defined(NDEBUG)
................................................................................
   434    428     g.json.errorDetailParanoia = 0;
   435    429   #endif
   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;
   458    455       g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
   459    456       g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
................................................................................
   467    464         fossil_fatal("unable to change directories to %s", zChdir);
   468    465       }
   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    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);
   493    490       for(i=0; i<count(aCommand); i++){
   494    491         if( memcmp(zCmdName, aCommand[i].zName, n)==0 ){
   495    492           blob_appendf(&couldbe, " %s", aCommand[i].zName);
   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     /*NOT_REACHED*/
   508    505     return 0;

Changes to src/th_tcl.c.

   387    387       Th_ErrorMessage(interp,
   388    388           "Invalid Tcl context", (const char *)"", 0);
   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;
   402    400     }
   403    401     if( Tcl_Init(tclInterp)!=TCL_OK ){
   404    402       Th_ErrorMessage(interp,
   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   }
   416    424