SQLite

Check-in [e2c8c88b4b]
Login

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

Overview
Comment:Move shell extension load functionality into its own .shxload command for usage and code simplicity.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | cli_extension
Files: files | file ages | folders
SHA3-256: e2c8c88b4b4f2c23c42fb1fdb86c0ade2992ce2e5d7f23b06af0e9ea3eb6a4f9
User & Date: larrybr 2022-04-17 19:22:42.509
Context
2022-04-17
21:03
Get docs caught up with the .shxload change. (check-in: e21964480f user: larrybr tags: cli_extension)
19:22
Move shell extension load functionality into its own .shxload command for usage and code simplicity. (check-in: e2c8c88b4b user: larrybr tags: cli_extension)
00:48
For sqlite3x, rudimentary testing in place as make target shellxtest . More to come. (check-in: b73928befb user: larrybr tags: cli_extension)
Changes
Unified Diff Ignore Whitespace Patch
Changes to Makefile.in.
1377
1378
1379
1380
1381
1382
1383




1384
1385
1386
1387
1388
1389
1390
1391
1392
# A very fast test that checks basic sanity.  The name comes from
# the 60s-era electronics testing:  "Turn it on and see if smoke
# comes out."
#
smoketest:	$(TESTPROGS) fuzzcheck$(TEXE)
	./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)





shellxtest: $(TESTPROGS_SHX)
	./testfixture$(TEXE) $(TOP)/test/shell_x/shell*.test

shelltest: $(TESTPROGS)
	./testfixture$(TEXE) $(TOP)/test/permutations.test shell

sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in
	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c








>
>
>
>

|







1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
# A very fast test that checks basic sanity.  The name comes from
# the 60s-era electronics testing:  "Turn it on and see if smoke
# comes out."
#
smoketest:	$(TESTPROGS) fuzzcheck$(TEXE)
	./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)

TESTRUNS_SHX = \
 $(TOP)/test/shell_x/shell9.test \
 $(TOP)/test/shell_x/shell10.test

shellxtest: $(TESTPROGS_SHX)
	./testfixture$(TEXE) $(TESTRUNS_SHX)

shelltest: $(TESTPROGS)
	./testfixture$(TEXE) $(TOP)/test/permutations.test shell

sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in
	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c

Changes to src/shell.c.in.
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
*/
#define NOT_IFDEF_BIT(x,bitnum) (x? (!(x & (1<<bitnum))) : !(x+0))

/* Whether build will include extended input parsing option */
#define SHEXT_PARSING_BIT 0
#define SHELL_EXTENDED_PARSING \
  NOT_IFDEF_BIT(SHELL_OMIT_EXTENSIONS, SHEXT_PARSING_BIT)
/* Whether build will include runtime extension via .load -extension */
#define SHEXT_DYNEXT_BIT 1
#define SHELL_DYNAMIC_EXTENSION ( !SHELL_OMIT_LOAD_EXTENSION \
  && NOT_IFDEF_BIT(SHELL_OMIT_EXTENSIONS, SHEXT_DYNEXT_BIT) )
/* Whether build will include expansion of variables in dot-commands */
#define SHEXT_VAREXP_BIT 2
#define SHELL_VARIABLE_EXPANSION \
  NOT_IFDEF_BIT(SHELL_OMIT_EXTENSIONS, SHEXT_VAREXP_BIT)







|







1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
*/
#define NOT_IFDEF_BIT(x,bitnum) (x? (!(x & (1<<bitnum))) : !(x+0))

/* Whether build will include extended input parsing option */
#define SHEXT_PARSING_BIT 0
#define SHELL_EXTENDED_PARSING \
  NOT_IFDEF_BIT(SHELL_OMIT_EXTENSIONS, SHEXT_PARSING_BIT)
/* Whether build will include runtime extension via .shxload */
#define SHEXT_DYNEXT_BIT 1
#define SHELL_DYNAMIC_EXTENSION ( !SHELL_OMIT_LOAD_EXTENSION \
  && NOT_IFDEF_BIT(SHELL_OMIT_EXTENSIONS, SHEXT_DYNEXT_BIT) )
/* Whether build will include expansion of variables in dot-commands */
#define SHEXT_VAREXP_BIT 2
#define SHELL_VARIABLE_EXPANSION \
  NOT_IFDEF_BIT(SHELL_OMIT_EXTENSIONS, SHEXT_VAREXP_BIT)
9946
9947
9948
9949
9950
9951
9952











9953
9954
9955
9956
9957
9958
9959
      return DCR_Error;
    }else{
      sqlite3IoTrace = iotracePrintf;
    }
  }
  return DCR_Ok;
}











DISPATCHABLE_COMMAND( limits 5 1 3 ){
  static const struct {
    const char *zLimitName;   /* Name of a limit */
    int limitCode;            /* Integer code for that limit */
  } aLimit[] = {
    { "length",                SQLITE_LIMIT_LENGTH                    },
    { "sql_length",            SQLITE_LIMIT_SQL_LENGTH                },







>
>
>
>
>
>
>
>
>
>
>







9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
      return DCR_Error;
    }else{
      sqlite3IoTrace = iotracePrintf;
    }
  }
  return DCR_Ok;
}

/*****************
 * The .limits and .load commands
 */
COLLECT_HELP_TEXT[
  ",limits ?LIMIT_NAME?     Display limit selected by its name, or all limits",
  ".load FILE ?ENTRY?       Load a SQLite extension library",
  "   If ENTRY is provided, the entry point \"sqlite_ENTRY_init\" is called.",
  "   Otherwise, the entry point name is derived from the FILE's name.",
];

DISPATCHABLE_COMMAND( limits 5 1 3 ){
  static const struct {
    const char *zLimitName;   /* Name of a limit */
    int limitCode;            /* Integer code for that limit */
  } aLimit[] = {
    { "length",                SQLITE_LIMIT_LENGTH                    },
    { "sql_length",            SQLITE_LIMIT_SQL_LENGTH                },
10178
10179
10180
10181
10182
10183
10184















10185
10186
10187
10188
10189
10190
10191
    }
  }else{
    *pzErr = smprintf("%s\n", sqlite3_errmsg(db));
  }

  return DCR_Ok|(rc!=0);
}
















DISPATCHABLE_COMMAND( log ? 2 2 ){
  const char *zFile = azArg[1];
  if( ISS(p)->bSafeMode ) return DCR_AbortError;
  output_file_close(ISS(p)->pLog);
  ISS(p)->pLog = output_file_open(zFile, 0);
  return DCR_Ok;







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







10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
    }
  }else{
    *pzErr = smprintf("%s\n", sqlite3_errmsg(db));
  }

  return DCR_Ok|(rc!=0);
}

DISPATCHABLE_COMMAND( load ? 2 3 ){
  const char *zFile = 0, *zProc = 0;
  int ai = 1, rc;
  if( ISS(p)->bSafeMode ) return DCR_AbortError;
  while( ai<nArg ){
    const char *zA = azArg[ai++];
    if( zFile==0 ) zFile = zA;
    else if( zProc==0 ) zProc = zA;
    else return DCR_TooMany|ai;
  }
  open_db(p, 0);
  rc = sqlite3_load_extension(DBX(p), zFile, zProc, pzErr);
  return DCR_Ok|(rc!=SQLITE_OK);
}

DISPATCHABLE_COMMAND( log ? 2 2 ){
  const char *zFile = azArg[1];
  if( ISS(p)->bSafeMode ) return DCR_AbortError;
  output_file_close(ISS(p)->pLog);
  ISS(p)->pLog = output_file_open(zFile, 0);
  return DCR_Ok;
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
  }
  if( zColSep!=0 ){
    sqlite3_snprintf(sizeof(psi->colSeparator), psi->colSeparator, zColSep);
  }
  psi->mode = modeNominal;
}

/*****************
 * The .load command
 * This is out of order to alleviate code clarity concerns.
 */
#if SHELL_DYNAMIC_EXTENSION  /* Avoid confusing users or mkshellc.tcl here. */
# define LDEXT_OPTS "?ENTRY? ?..?"
# define LDEXT_MAXARGS 0
#else
# define LDEXT_OPTS "?ENTRY?     "
# define LDEXT_MAXARGS 3
#endif
COLLECT_HELP_TEXT[
  ".load FILE "LDEXT_OPTS"  Load an extension library",
#if SHELL_DYNAMIC_EXTENSION
  "   If option -shext follows the first 1 or 2 arguments, then the library",
  "   will be loaded as a shell extension, and any subsequent arguments will",
  "   be passed to the extension's init function. That function is named per",
  "   the docs for sqlite3_load_extension(), with ENTRY taking zProc's role.",
#else
  "   If ENTRY is provided, the entry point \"sqlite_ENTRY_init\" is called.",
  "   Otherwise, the entry point name is derived from the FILE's name.",
#endif
];
DISPATCHABLE_COMMAND( load ? 2 LDEXT_MAXARGS ){
  const char *zFile = 0, *zProc = 0;
  char *zErrMsg = 0;
  int ai = 1, rc;
#if SHELL_DYNAMIC_EXTENSION
  char **pzShext = 0;
#else
  if( nArg>3 ) return DCR_TooMany|3;
#endif
  if( ISS(p)->bSafeMode ) return DCR_AbortError;
  while( ai<nArg ){
    const char *zA = azArg[ai++];
#if SHELL_DYNAMIC_EXTENSION
    if( optionMatch(zA, "shext") ){
      if( zFile==0 ) return DCR_Missing;
      pzShext = azArg + ai;
      break;
    }else if( zFile==0 ) zFile = zA;
    else if( zProc==0 ) zProc = zA;
#else
    if( zFile==0 ) zFile = zA;
    else if( zProc==0 ) zProc = zA;
    else return DCR_TooMany|ai;
#endif
  }
  open_db(p, 0);
#if SHELL_DYNAMIC_EXTENSION
  if( pzShext ){
    rc = load_shell_extension(p, zFile, zProc, pzErr, nArg-ai, pzShext);
  }else
#endif
    {
      rc = sqlite3_load_extension(DBX(p), zFile, zProc, pzErr);
    }
  return DCR_Ok|(rc!=SQLITE_OK);
}

/*****************
 * The .mode command
 */
COLLECT_HELP_TEXT[
  ".mode MODE ?OPTIONS?     Set output mode",
  "   MODE is one of:",
  "     ascii       Columns/rows delimited by 0x1F and 0x1E",







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







10279
10280
10281
10282
10283
10284
10285




























































10286
10287
10288
10289
10290
10291
10292
  }
  if( zColSep!=0 ){
    sqlite3_snprintf(sizeof(psi->colSeparator), psi->colSeparator, zColSep);
  }
  psi->mode = modeNominal;
}





























































/*****************
 * The .mode command
 */
COLLECT_HELP_TEXT[
  ".mode MODE ?OPTIONS?     Set output mode",
  "   MODE is one of:",
  "     ascii       Columns/rows delimited by 0x1F and 0x1E",
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
    shell_exec(p, zSql, 0);
  }
  sqlite3_free(zSql);
  return DCR_Ok;
}

/*****************
 * The .selftest*, .shell, .show, .shxopts, .stats and .system commands
 */
CONDITION_COMMAND( selftest_bool defined(SQLITE_DEBUG) );
CONDITION_COMMAND( selftest_int defined(SQLITE_DEBUG) );
CONDITION_COMMAND( shell !defined(SQLITE_NOHAVE_SYSTEM) );
CONDITION_COMMAND( shxopts (SHELL_EXTENSIONS)!=0 );
CONDITION_COMMAND( system !defined(SQLITE_NOHAVE_SYSTEM) );
COLLECT_HELP_TEXT[
  ",selftest ?OPTIONS?      Run tests defined in the SELFTEST table",
  "    Options:",
  "       --init               Create a new SELFTEST table",
  "       -v                   Verbose output",
  ",selftest_bool ?ARGS?    Show boolean values of ARGS as flag tokens",
  ",selftest_int ?ARGS?     Show integer values of ARGS as integer tokens",
  ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
  ".show                    Show the current values for various settings",
  ".shxopts ?SIGNED_OPTS?   Show or alter shell extension options",
  "   Run without arguments to see their self-descriptive names",
  ".stats ?ARG?             Show stats or turn stats on or off",
  "   off                      Turn off automatic stat display",
  "   on                       Turn on automatic stat display",
  "   stmt                     Show statement stats",
  "   vmstep                   Show the virtual machine step count only",
  ".system CMD ARGS...      Run CMD ARGS... in a system shell",
];

DISPATCHABLE_COMMAND( selftest_bool 10 0 0 ){
  int i, v;
  for(i=1; i<nArg; i++){
    v = booleanValue(azArg[i]);
    utf8_printf(ISS(p)->out, "%s: %d 0x%x\n", azArg[i], v, v);







|



<
<
<







<

<
<
<
<
<
<
<
<







12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194



12195
12196
12197
12198
12199
12200
12201

12202








12203
12204
12205
12206
12207
12208
12209
    shell_exec(p, zSql, 0);
  }
  sqlite3_free(zSql);
  return DCR_Ok;
}

/*****************
 * The .selftest*, .shell, and .show commands
 */
CONDITION_COMMAND( selftest_bool defined(SQLITE_DEBUG) );
CONDITION_COMMAND( selftest_int defined(SQLITE_DEBUG) );



COLLECT_HELP_TEXT[
  ",selftest ?OPTIONS?      Run tests defined in the SELFTEST table",
  "    Options:",
  "       --init               Create a new SELFTEST table",
  "       -v                   Verbose output",
  ",selftest_bool ?ARGS?    Show boolean values of ARGS as flag tokens",
  ",selftest_int ?ARGS?     Show integer values of ARGS as integer tokens",

  ".show                    Show the current values for various settings",








];

DISPATCHABLE_COMMAND( selftest_bool 10 0 0 ){
  int i, v;
  for(i=1; i<nArg; i++){
    v = booleanValue(azArg[i]);
    utf8_printf(ISS(p)->out, "%s: %d 0x%x\n", azArg[i], v, v);
12368
12369
12370
12371
12372
12373
12374



12375














12376
12377
12378
12379
12380
12381
12382
12383
12384
12385

12386
12387
12388
12389
12390












































12391
12392
12393
12394
12395
12396
12397
    sqlite3_finalize(pStmt);
  } /* End loop over k */
  freeText(&str);
  utf8_printf(psi->out, "%d errors out of %d tests\n", nErr, nTest);
  return rc > 0;
}




DISPATCHABLE_COMMAND( shell ? 2 0 ){














  char *zCmd;
  int i, x;
  if( ISS(p)->bSafeMode ) return DCR_AbortError;
  zCmd = smprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
  shell_check_oom(zCmd);
  for(i=2; i<nArg; i++){
    zCmd = smprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
                    zCmd, azArg[i]);
    shell_check_oom(zCmd);
  }

  x = system(zCmd);
  sqlite3_free(zCmd);
  if( x ) raw_printf(STD_ERR, "%s command returns %d\n", azArg[0], x);
  return DCR_Ok;
}












































DISPATCHABLE_COMMAND( shxopts 3 0 0 ){
  static struct { const char *name; u8 mask; } shopts[] = {
#if SHELL_DYNAMIC_COMMANDS
    {"dyn_cmds", 1<<SHEXT_DYNCMDS_BIT},
#endif
#if SHELL_EXTENDED_PARSING
    {"parsing", 1<<SHEXT_PARSING_BIT},







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


|

<



<

>





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







12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350

12351
12352
12353

12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
    sqlite3_finalize(pStmt);
  } /* End loop over k */
  freeText(&str);
  utf8_printf(psi->out, "%d errors out of %d tests\n", nErr, nTest);
  return rc > 0;
}

/*****************
 * The .shell, .stats and .system commands
 */
CONDITION_COMMAND( shell !defined(SQLITE_NOHAVE_SYSTEM) );
CONDITION_COMMAND( system !defined(SQLITE_NOHAVE_SYSTEM) );
COLLECT_HELP_TEXT[
  ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
  ".stats ?ARG?             Show stats or turn stats on or off",
  "   off                      Turn off automatic stat display",
  "   on                       Turn on automatic stat display",
  "   stmt                     Show statement stats",
  "   vmstep                   Show the virtual machine step count only",
  ".system CMD ARGS...      Run CMD ARGS... in a system shell",
];

#ifndef SQLITE_NOHAVE_SYSTEM
static DotCmdRC shellOut(char *azArg[], int nArg,
                         ShellExState *psx, char **pzErr){
  char *zCmd;
  int i, x;
  if( ISS(psx)->bSafeMode ) return DCR_AbortError;
  zCmd = smprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);

  for(i=2; i<nArg; i++){
    zCmd = smprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
                    zCmd, azArg[i]);

  }
  shell_check_oom(zCmd);
  x = system(zCmd);
  sqlite3_free(zCmd);
  if( x ) raw_printf(STD_ERR, "%s command returns %d\n", azArg[0], x);
  return DCR_Ok;
}
#endif
DISPATCHABLE_COMMAND( shell ? 2 0 ){
  return shellOut(azArg, nArg, p, pzErr);
}

DISPATCHABLE_COMMAND( system ? 2 0 ){
  return shellOut(azArg, nArg, p, pzErr);
}

/*****************
 * The .shxload and .shxopts commands
 */
CONDITION_COMMAND( shxload (SHELL_DYNAMIC_EXTENSION)!=0 );
CONDITION_COMMAND( shxopts (SHELL_EXTENSIONS)!=0 );
COLLECT_HELP_TEXT[
  ".shxload FILE ?OPTIONS?  Load a CLI shell extension library",
  "   The first option may name the init function to be called upon load.",
  "   Otherwise, its name is derived from FILE. Either way, the entry point"
  "   \"sqlite_NAME_init\" is called. All options after \"--\" are passed to",
  "   the extension's init function in the ShellExtensionLink struct.",
  ".shxopts ?SIGNED_OPTS?   Show or alter shell extension options",
  "   Run without arguments to see their self-descriptive names",
];

DISPATCHABLE_COMMAND( shxload 4 2 0 ){
  const char *zFile = 0, *zProc = 0;
  int ai = 1, rc;
  char **pzExtArgs = 0;
  if( ISS(p)->bSafeMode ) return DCR_AbortError;
  while( ai<nArg ){
    const char *zA = azArg[ai++];
    if( strcmp(zA, "--")==0 ){
      pzExtArgs = azArg + ai;
      break;
    }
    if( zFile==0 ) zFile = zA;
    else if( zProc==0 ) zProc = zA;
  }
  if( zFile==0 ) return DCR_Missing;
  if( pzExtArgs==0 ) pzExtArgs = azArg + ai;
  rc = load_shell_extension(p, zFile, zProc, pzErr, nArg-ai, pzExtArgs);
  return DCR_Ok|(rc!=SQLITE_OK);
}

DISPATCHABLE_COMMAND( shxopts 3 0 0 ){
  static struct { const char *name; u8 mask; } shopts[] = {
#if SHELL_DYNAMIC_COMMANDS
    {"dyn_cmds", 1<<SHEXT_DYNCMDS_BIT},
#endif
#if SHELL_EXTENDED_PARSING
    {"parsing", 1<<SHEXT_PARSING_BIT},
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
    }
  }
  return DCR_Ok;
 moan_error:
  raw_printf(STD_ERR, "Error: %s %s\n", zAbout, zMoan);
  return DCR_CmdErred;
}
DISPATCHABLE_COMMAND( system ? 2 0 ){
  return shellCommand(azArg, nArg, p, pzErr);
}
DISPATCHABLE_COMMAND( show ? 1 1 ){
  static const char *azBool[] = { "off", "on", "trigger", "full"};
  const char *zOut;
  ShellInState *psi = ISS(p);
  FILE *out = psi->out;
  int i;
  utf8_printf(out, "%12.12s: %s\n","echo",







<
<
<







12452
12453
12454
12455
12456
12457
12458



12459
12460
12461
12462
12463
12464
12465
    }
  }
  return DCR_Ok;
 moan_error:
  raw_printf(STD_ERR, "Error: %s %s\n", zAbout, zMoan);
  return DCR_CmdErred;
}



DISPATCHABLE_COMMAND( show ? 1 1 ){
  static const char *azBool[] = { "off", "on", "trigger", "full"};
  const char *zOut;
  ShellInState *psi = ISS(p);
  FILE *out = psi->out;
  int i;
  utf8_printf(out, "%12.12s: %s\n","echo",
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
  enum {
    HO_Tbd, HO_AllP, HO_AllX, HO_LikeP, HO_OneX, HO_LikeT, HO_Undoc
  } hoKind = bShowUndoc? HO_Undoc : HO_Tbd;

  if( hoKind==HO_Undoc ){
    int ixct = 0;
    utf8_printf(out, "%s\n%s\n",
                "The following commands are used for internal SQLite testing.",
                "They are undocumented and subject to change without notice.");
    /* Bypass command lookup/resolution. This is just for internal commands. */
    while( ixct<numCommands ){
      struct CommandInfo *pci = &command_table[ixct];
      const char *zH = pci->azHelp[0];
      if( zH && *zH==cLead ){
        utf8_printf(out, HELP_TEXT_FMTP, zH+1);
        zH = pci->azHelp[1];







|
|







14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
  enum {
    HO_Tbd, HO_AllP, HO_AllX, HO_LikeP, HO_OneX, HO_LikeT, HO_Undoc
  } hoKind = bShowUndoc? HO_Undoc : HO_Tbd;

  if( hoKind==HO_Undoc ){
    int ixct = 0;
    utf8_printf(out, "%s\n%s\n",
      "The following commands are for SQLite diagnosis and internal testing.",
      "They are undocumented and subject to change without notice.");
    /* Bypass command lookup/resolution. This is just for internal commands. */
    while( ixct<numCommands ){
      struct CommandInfo *pci = &command_table[ixct];
      const char *zH = pci->azHelp[0];
      if( zH && *zH==cLead ){
        utf8_printf(out, HELP_TEXT_FMTP, zH+1);
        zH = pci->azHelp[1];
Changes to test/shell_x/shell10.test.
38
39
40
41
42
43
44
45


46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  set rc [catch { exec $CLI :memory: << $cmd } msg]
  list $rc $msg
}

#----------------------------------------------------------------------------
# Test cases shell10-1.*: loading/running the {C,C++}-written test extensions
set cmds ".
 .load $blddir/test_shellext_cpp -shext C++


"
do_test shell10-1.1 {
  catch_mdb_cmd $cmds
} {0 {BatBeing lives.
Load arguments: C++

dbUser closing
dbShell closing
BatBeing incommunicado.
BatBeing unbecoming.
BatBeing RIP.}}

set cmds ".
 .load $blddir/test_shellext_c -shext C
 .bat 10 20 30
 .load $blddir/test_shellext_cpp -shext C++
 .bat 10 20 30

"
do_test shell10-1.2 {
  catch_mdb_cmd $cmds
} {0 {Load arguments: C
Column widths: 10 20 30
This execute has been called 1 times.
BatBeing lives.
Load arguments: C++
Column widths: 20 30 10
This execute has been called 2 times.


dbUser closing
dbUser closing
dbShell closing
dbShell closing
BatBeing incommunicado.
BatBeing incommunicado.
BatBeing unbecoming.
BatBeing unbecoming.
BatBeing RIP.}}


#----------------------------------------------------------------------------
# Test cases shell10-2.*: Tcl extension load and execution environment switching

set ldtce ".load $blddir/tclshext -shext"

set cmds {
 ..
 puts Putsing
 for {set i 0} {$i<2} {incr i} {.print $i}
 puts [info commands ..]
 .







|
>
>





>







|

|

>










>
>














|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  set rc [catch { exec $CLI :memory: << $cmd } msg]
  list $rc $msg
}

#----------------------------------------------------------------------------
# Test cases shell10-1.*: loading/running the {C,C++}-written test extensions
set cmds ".
 .shxload $blddir/test_shellext_cpp -- C++
 .tables
 .quit
"
do_test shell10-1.1 {
  catch_mdb_cmd $cmds
} {0 {BatBeing lives.
Load arguments: C++
dbUser appeared
dbUser closing
dbShell closing
BatBeing incommunicado.
BatBeing unbecoming.
BatBeing RIP.}}

set cmds ".
 .shxload $blddir/test_shellext_c -- C
 .bat 10 20 30
 .shxload $blddir/test_shellext_cpp -- C++
 .bat 10 20 30
 .tables
"
do_test shell10-1.2 {
  catch_mdb_cmd $cmds
} {0 {Load arguments: C
Column widths: 10 20 30
This execute has been called 1 times.
BatBeing lives.
Load arguments: C++
Column widths: 20 30 10
This execute has been called 2 times.
dbUser appeared
dbUser appeared
dbUser closing
dbUser closing
dbShell closing
dbShell closing
BatBeing incommunicado.
BatBeing incommunicado.
BatBeing unbecoming.
BatBeing unbecoming.
BatBeing RIP.}}


#----------------------------------------------------------------------------
# Test cases shell10-2.*: Tcl extension load and execution environment switching

set ldtce ".shxload $blddir/tclshext"

set cmds {
 ..
 puts Putsing
 for {set i 0} {$i<2} {incr i} {.print $i}
 puts [info commands ..]
 .