".binary on|off Turn binary output on or off. Default OFF",
".cd DIRECTORY Change the working directory to DIRECTORY",
".changes on|off Show number of rows changed by SQL",
- ".check GLOB Fail if output since .testcase does not match",
".clone NEWDB Clone data into NEWDB from the existing database",
".connection [close] [#] Open or close an auxiliary database connection",
".databases List names and files of attached databases",
" --help Show CMD details",
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
".headers on|off Turn display of headers on or off",
- ".help ?-all? ?PATTERN? Show help text for PATTERN",
+ ".help ?PATTERN?|?-all? Show help for PATTERN or everything, or summarize",
+ " Repeat -all to see undocumented commands",
".import FILE TABLE Import data from FILE into TABLE",
" Options:",
" --ascii Use \\037 and \\036 as column and row separators",
".system CMD ARGS... Run CMD ARGS... in a system shell",
#endif
".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
- ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
- ".testctrl CMD ... Run various sqlite3_test_control() operations",
- " Run \".testctrl\" with no arguments for details",
".timeout MS Try opening locked tables for MS milliseconds",
".timer on|off Turn SQL timer on or off",
#ifndef SQLITE_OMIT_TRACE
" Negative values right-justify",
};
+/* Like azHelp[], but for undocumented commands. */
+static const char *(azHelpUndoc[]) = {
+ "These undocumented commands are for internal testing.\n"
+ "They are subject to change without notice.\n"
+ ".check GLOB Fail if output since .testcase does not match",
+ ".seeargs Echo arguments separated or terminated by |",
+ ".selftest-boolean Check boolean translation",
+ ".selftest-integer Check integer conversion",
+ ".testcase NAME Begin output redirect to 'testcase-out.txt'",
+ ".testctrl CMD ... Run various sqlite3_test_control() operations",
+ " Run \".testctrl\" with no arguments for details",
+};
+
+/* This literal's value and address is used for help's workings. */
+static const char *zHelpAll = "-all";
+
/*
** Output help text.
**
int i = 0;
int j = 0;
int n = 0;
+ int nHelp = ArraySize(azHelp);
+ const char **azHelpText = azHelp;
char *zPat;
+ if( zPattern==zHelpAll ){
+ /* It's zHelpAll, show help for the undocumented commands. */
+ nHelp = ArraySize(azHelpUndoc);
+ azHelpText = azHelpUndoc;
+ }
if( zPattern==0
|| zPattern[0]=='0'
|| strcmp(zPattern,"-a")==0
|| strcmp(zPattern,"-all")==0
|| strcmp(zPattern,"--all")==0
){
- /* Show all commands, but only one line per command */
+ /* Show all commands.
+ * If no pattern, only one line per command.
+ * If any --all-like pattern, show all help.
+ */
if( zPattern==0 ) zPattern = "";
- for(i=0; i<ArraySize(azHelp); i++){
- if( azHelp[i][0]=='.' || zPattern[0] ){
- utf8_printf(out, "%s\n", azHelp[i]);
+ for(i=0; i<nHelp; i++){
+ if( azHelpText[i][0]=='.' || zPattern[0] ){
+ utf8_printf(out, "%s\n", azHelpText[i]);
n++;
}
}
/* Look for commands that for which zPattern is an exact prefix */
zPat = sqlite3_mprintf(".%s*", zPattern);
shell_check_oom(zPat);
- for(i=0; i<ArraySize(azHelp); i++){
- if( sqlite3_strglob(zPat, azHelp[i])==0 ){
- utf8_printf(out, "%s\n", azHelp[i]);
+ for(i=0; i<nHelp; i++){
+ if( sqlite3_strglob(zPat, azHelpText[i])==0 ){
+ utf8_printf(out, "%s\n", azHelpText[i]);
j = i+1;
n++;
}
if( n==1 ){
/* when zPattern is a prefix of exactly one command, then include the
** details of that command, which should begin at offset j */
- while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
- utf8_printf(out, "%s\n", azHelp[j]);
+ while( j<nHelp-1 && azHelpText[j][0]!='.' ){
+ utf8_printf(out, "%s\n", azHelpText[j]);
j++;
}
}
** text of all commands that match. */
zPat = sqlite3_mprintf("%%%s%%", zPattern);
shell_check_oom(zPat);
- for(i=0; i<ArraySize(azHelp); i++){
- if( azHelp[i][0]=='.' ) j = i;
- if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
- utf8_printf(out, "%s\n", azHelp[j]);
- while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
+ for(i=0; i<nHelp; i++){
+ if( azHelpText[i][0]=='.' ) j = i;
+ if( sqlite3_strlike(zPat, azHelpText[i], 0)==0 ){
+ utf8_printf(out, "%s\n", azHelpText[j]);
+ while( j<nHelp-1 && azHelpText[j+1][0]=='.' ){
j++;
- utf8_printf(out, "%s\n", azHelp[j]);
+ utf8_printf(out, "%s\n", azHelpText[j]);
}
i = j;
n++;
** for TRUE and FALSE. Return the integer value if appropriate.
*/
static int booleanValue(const char *zArg){
+ static const char *zBoolNames[] = {
+ "no","yes", "off","on",
+#ifdef BOOLNAMES_ARE_BOOLEAN
+ "false","true",
+#endif
+ 0
+ };
int i;
if( zArg[0]=='0' && zArg[1]=='x' ){
for(i=2; hexDigitValue(zArg[i])>=0; i++){}
for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
}
if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
- if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
- return 1;
- }
- if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
- return 0;
+ for( i=0; zBoolNames[i]!=0; ++i ){
+ if( sqlite3_stricmp(zArg, zBoolNames[i])==0 ) return i&1;
}
utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
zArg);
if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
if( nArg>=2 ){
- n = showHelp(p->out, azArg[1]);
+ if( nArg==3
+ && strcmp(azArg[1], zHelpAll)==0 && strcmp(azArg[2], zHelpAll)==0 ){
+ /* Show the undocumented command help */
+ n = showHelp(p->out, zHelpAll);
+ }else{
+ /* Show such help as the pattern selects */
+ n = showHelp(p->out, azArg[1]);
+ }
if( n==0 ){
utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
}
}else{
+ /* Show one-line summaries */
showHelp(p->out, 0);
}
}else
}
}else
+ if( c=='s' && n==7 && strncmp(azArg[0], "seeargs", n)==0 ){
+ for( n=1; n<nArg; ++n ){
+ raw_printf(p->out, "%s%s", azArg[n], (n==nArg-1)? "|\n" : "|");
+ }
+ }else
+
if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);