Fossil

Check-in [e923b4a6]
Login

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

Overview
Comment:Refactored th1 function registration code to be reusable across modules.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | th1-query-api
Files: files | file ages | folders
SHA1:e923b4a64dd2d0b0c9d5df5a364feb225ad6746f
User & Date: stephan 2012-07-14 13:43:04
Context
2012-07-14
13:51
moved th1 argv funcs into their own registration unit. Renamed argv_getat to argv_at. check-in: 3b25f80e user: stephan tags: th1-query-api
13:43
Refactored th1 function registration code to be reusable across modules. check-in: e923b4a6 user: stephan tags: th1-query-api
13:20
minor generic cleanups in th1 before continuing on to real work... check-in: 1767603f user: stephan tags: th1-query-api
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/th.h.

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
...
236
237
238
239
240
241
242


















243
244
245
246
247
248
249
int th_isspecial(char);
char *th_strdup(Th_Interp *interp, const char *z, int n);

/*
** Interfaces to register the language extensions.
*/
int th_register_language(Th_Interp *interp);            /* th_lang.c */
int th_register_sqlite(Th_Interp *interp);              /* th_sqlite.c */
int th_register_vfs(Th_Interp *interp);                 /* th_vfs.c */
int th_register_testvfs(Th_Interp *interp);             /* th_testvfs.c */
int th_register_tcl(Th_Interp *interp, void *pContext); /* th_tcl.c */

/*
** General purpose hash table from th_lang.c.
*/
................................................................................
/*
** Th_output_f() implementation which sends its output to either
** pState (which must be NULL or a (FILE*)) or stdout (if pState is
** NULL).
*/
int Th_output_f_FILE( char const * zData, int len, void * pState );




















#ifdef TH_USE_SQLITE
#include "stddef.h" /* size_t */
extern void *fossil_realloc(void *p, size_t n);

/*
** Adds the given prepared statement to the interpreter. Returns the







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
...
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
int th_isspecial(char);
char *th_strdup(Th_Interp *interp, const char *z, int n);

/*
** Interfaces to register the language extensions.
*/
int th_register_language(Th_Interp *interp);            /* th_lang.c */
int th_register_sqlite(Th_Interp *interp);              /* th_main.c */
int th_register_vfs(Th_Interp *interp);                 /* th_vfs.c */
int th_register_testvfs(Th_Interp *interp);             /* th_testvfs.c */
int th_register_tcl(Th_Interp *interp, void *pContext); /* th_tcl.c */

/*
** General purpose hash table from th_lang.c.
*/
................................................................................
/*
** Th_output_f() implementation which sends its output to either
** pState (which must be NULL or a (FILE*)) or stdout (if pState is
** NULL).
*/
int Th_output_f_FILE( char const * zData, int len, void * pState );

typedef struct Th_Command_Reg Th_Command_Reg;
/*
** A helper type for holding lists of function registration information.
** For use with Th_register_commands().
*/
struct Th_Command_Reg {
  const char *zName;     /* Function name. */
  Th_CommandProc xProc;  /* Callback function */
  void *pContext;        /* Arbitrary data for the callback. */
};

/*
** Registers a list of commands with the interpreter. pList must be a non-NULL
** pointer to an array of Th_Command_Reg objects, the last one of which MUST
** have a NULL zName field (that is the end-of-list marker).
** Returns TH_OK on success, "something else" on error.
*/
int Th_register_commands( Th_Interp * interp, Th_Command_Reg const * pList );

#ifdef TH_USE_SQLITE
#include "stddef.h" /* size_t */
extern void *fossil_realloc(void *p, size_t n);

/*
** Adds the given prepared statement to the interpreter. Returns the

Changes to src/th_lang.c.

1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
....
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084

/*
** Register the built-in th1 language commands with interpreter interp.
** Usually this is called soon after interpreter creation.
*/
int th_register_language(Th_Interp *interp){
  /* Array of built-in commands. */
  struct _Command {
    const char *zName;
    Th_CommandProc xProc;
    void *pContext;
  } aCommand[] = {
    {"catch",    catch_command,   0},
    {"expr",     expr_command,    0},
    {"for",      for_command,     0},
    {"if",       if_command,      0},
    {"info",     info_command,    0},
    {"lindex",   lindex_command,  0},
    {"list",     list_command,    0},
................................................................................
    {"return",   return_command, 0},
    {"break",    simple_command, (void *)TH_BREAK}, 
    {"continue", simple_command, (void *)TH_CONTINUE}, 
    {"error",    simple_command, (void *)TH_ERROR}, 

    {0, 0, 0}
  };
  int i;

  /* Add the language commands. */
  for(i=0; i<(sizeof(aCommand)/sizeof(aCommand[0])); i++){
    void *ctx;
    if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
    ctx = aCommand[i].pContext;
    Th_CreateCommand(interp, aCommand[i].zName, aCommand[i].xProc, ctx, 0);
  }

  return TH_OK;
}







<
<
<
<
|







 







|
|
<
<
<
<
<
<
<
<
<
<
1036
1037
1038
1039
1040
1041
1042




1043
1044
1045
1046
1047
1048
1049
1050
....
1062
1063
1064
1065
1066
1067
1068
1069
1070











/*
** Register the built-in th1 language commands with interpreter interp.
** Usually this is called soon after interpreter creation.
*/
int th_register_language(Th_Interp *interp){
  /* Array of built-in commands. */




  struct Th_Command_Reg aCommand[] = {
    {"catch",    catch_command,   0},
    {"expr",     expr_command,    0},
    {"for",      for_command,     0},
    {"if",       if_command,      0},
    {"info",     info_command,    0},
    {"lindex",   lindex_command,  0},
    {"list",     list_command,    0},
................................................................................
    {"return",   return_command, 0},
    {"break",    simple_command, (void *)TH_BREAK}, 
    {"continue", simple_command, (void *)TH_CONTINUE}, 
    {"error",    simple_command, (void *)TH_ERROR}, 

    {0, 0, 0}
  };
  return Th_register_commands(interp, aCommand);
}










Changes to src/th_main.c.

1294
1295
1296
1297
1298
1299
1300
1301




































1302
1303
1304










1305



1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
....
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
....
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399

1400

1401
1402
1403
1404
1405
1406
1407
  rc = sqlite3_bind_double( pStmt, index, val );
  if(rc){
    return queryReportDbErr( interp );
  }
  Th_SetResultInt( interp, 0 );
  return TH_OK;
}





































#endif
/* end TH_USE_SQLITE */
















/*
** Make sure the interpreter has been initialized.  Initialize it if
** it has not been already.
**
** The interpreter is stored in the g.interp global variable.
*/
void Th_FossilInit(void){
  static PutsCmdData puts_Html = {0, 0, 0};
  static PutsCmdData puts_Normal = {1, 0, 0};
  static struct _Command {
    const char *zName;
    Th_CommandProc xProc;
    void *pContext;
  } aCommand[] = {
    {"anycap",        anycapCmd,            0},
    {"combobox",      comboboxCmd,          0},
    {"enable_output", enableOutputCmd,      0},
    {"linecount",     linecntCmd,           0},
    {"hascap",        hascapCmd,            0},
    {"hasfeature",    hasfeatureCmd,        0},
    {"htmlize",       htmlizeCmd,           0},
................................................................................
    {"argv_len",      argvArgcCmd,             0},
    {"argv_getat",    argvGetAtCmd,            0},
    {"argv_getstr",   argvFindOptionStringCmd, 0},
    {"argv_getbool",  argvFindOptionBoolCmd,   0},
    {"argv_getint",   argvFindOptionIntCmd,    0},
#endif

#ifdef TH_USE_SQLITE
    {"query_bind_int",    queryBindIntCmd,   0},
    {"query_bind_double", queryBindDoubleCmd,0},
    {"query_bind_null",   queryBindNullCmd,  0},
    {"query_bind_string", queryBindStringCmd,0},
    {"query_col_count",   queryColCountCmd,  0},
    {"query_col_double",  queryColDoubleCmd, 0},
    {"query_col_int",     queryColIntCmd,    0},
    {"query_col_is_null", queryColIsNullCmd, 0},
    {"query_col_name",    queryColNameCmd,   0},
    {"query_col_string",  queryColStringCmd, 0},
    {"query_col_type",    queryColTypeCmd,   0},
    {"query_finalize",    queryFinalizeCmd,  0},
    {"query_prepare",     queryPrepareCmd,   0},
    {"query_step",        queryStepCmd,      0},
#endif

    {0, 0, 0}
  };
  if( g.interp==0 ){
    int i;
    if(g.cgiOutput){
      vtab.out.f = Th_output_f_cgi_content;
    }else{
................................................................................
    g.interp = Th_CreateInterp(&vtab);
    th_register_language(g.interp);       /* Basic scripting commands. */
#ifdef FOSSIL_ENABLE_TCL
    if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
      th_register_tcl(g.interp, &g.tcl);  /* Tcl integration commands. */
    }
#endif
    for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
      if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
      Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
                       aCommand[i].pContext, 0);
    }
#ifdef TH_USE_SQLITE
    {
      enum { BufLen = 100 };
      char buf[BufLen];
      int i, l;
#define SET(K) l = snprintf(buf, BufLen, "%d", K); \
      Th_SetVar( g.interp, #K, strlen(#K), buf, l );
      SET(SQLITE_BLOB);
      SET(SQLITE_DONE);
      SET(SQLITE_ERROR);
      SET(SQLITE_FLOAT);
      SET(SQLITE_INTEGER);
      SET(SQLITE_NULL);
      SET(SQLITE_OK);
      SET(SQLITE_ROW);
      SET(SQLITE_TEXT);
#undef SET
    }

#endif

  }
}

/*
** Store a string value in a variable in the interpreter.
*/
void Th_Store(const char *zName, const char *zValue){








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>
|
>
>
>










<
<
<
<
|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>

>







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364




1365
1366
1367
1368
1369
1370
1371
1372
....
1380
1381
1382
1383
1384
1385
1386

















1387
1388
1389
1390
1391
1392
1393
....
1398
1399
1400
1401
1402
1403
1404





1405

















1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
  rc = sqlite3_bind_double( pStmt, index, val );
  if(rc){
    return queryReportDbErr( interp );
  }
  Th_SetResultInt( interp, 0 );
  return TH_OK;
}

int th_register_sqlite(Th_Interp *interp){
  enum { BufLen = 100 };
  char buf[BufLen];
  int i, l;
#define SET(K) l = snprintf(buf, BufLen, "%d", K);      \
  Th_SetVar( interp, #K, strlen(#K), buf, l );
  SET(SQLITE_BLOB);
  SET(SQLITE_DONE);
  SET(SQLITE_ERROR);
  SET(SQLITE_FLOAT);
  SET(SQLITE_INTEGER);
  SET(SQLITE_NULL);
  SET(SQLITE_OK);
  SET(SQLITE_ROW);
  SET(SQLITE_TEXT);
#undef SET
  static Th_Command_Reg aCommand[] = {
    {"query_bind_int",    queryBindIntCmd,   0},
    {"query_bind_double", queryBindDoubleCmd,0},
    {"query_bind_null",   queryBindNullCmd,  0},
    {"query_bind_string", queryBindStringCmd,0},
    {"query_col_count",   queryColCountCmd,  0},
    {"query_col_double",  queryColDoubleCmd, 0},
    {"query_col_int",     queryColIntCmd,    0},
    {"query_col_is_null", queryColIsNullCmd, 0},
    {"query_col_name",    queryColNameCmd,   0},
    {"query_col_string",  queryColStringCmd, 0},
    {"query_col_type",    queryColTypeCmd,   0},
    {"query_finalize",    queryFinalizeCmd,  0},
    {"query_prepare",     queryPrepareCmd,   0},
    {"query_step",        queryStepCmd,      0},
    {0, 0, 0}
  };
  Th_register_commands( interp, aCommand );
}

#endif
/* end TH_USE_SQLITE */

int Th_register_commands( Th_Interp * interp,
                           Th_Command_Reg const * aCommand ){
  int i;
  int rc = TH_OK;
  for(i=0; (TH_OK==rc) && aCommand[i].zName; ++i){
    if ( !aCommand[i].zName ) break;
    else if( !aCommand[i].xProc ) continue;
    else{
      rc = Th_CreateCommand(interp, aCommand[i].zName, aCommand[i].xProc,
                            aCommand[i].pContext, 0);
    }
  }
  return rc;
}

/*
** Make sure the interpreter has been initialized.  Initialize it if
** it has not been already.
**
** The interpreter is stored in the g.interp global variable.
*/
void Th_FossilInit(void){
  static PutsCmdData puts_Html = {0, 0, 0};
  static PutsCmdData puts_Normal = {1, 0, 0};




  static Th_Command_Reg aCommand[] = {
    {"anycap",        anycapCmd,            0},
    {"combobox",      comboboxCmd,          0},
    {"enable_output", enableOutputCmd,      0},
    {"linecount",     linecntCmd,           0},
    {"hascap",        hascapCmd,            0},
    {"hasfeature",    hasfeatureCmd,        0},
    {"htmlize",       htmlizeCmd,           0},
................................................................................
    {"argv_len",      argvArgcCmd,             0},
    {"argv_getat",    argvGetAtCmd,            0},
    {"argv_getstr",   argvFindOptionStringCmd, 0},
    {"argv_getbool",  argvFindOptionBoolCmd,   0},
    {"argv_getint",   argvFindOptionIntCmd,    0},
#endif


















    {0, 0, 0}
  };
  if( g.interp==0 ){
    int i;
    if(g.cgiOutput){
      vtab.out.f = Th_output_f_cgi_content;
    }else{
................................................................................
    g.interp = Th_CreateInterp(&vtab);
    th_register_language(g.interp);       /* Basic scripting commands. */
#ifdef FOSSIL_ENABLE_TCL
    if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
      th_register_tcl(g.interp, &g.tcl);  /* Tcl integration commands. */
    }
#endif





#ifdef TH_USE_SQLITE

















    th_register_sqlite(g.interp);
#endif
    Th_register_commands( g.interp, aCommand );
  }
}

/*
** Store a string value in a variable in the interpreter.
*/
void Th_Store(const char *zName, const char *zValue){