diff options
author | drh <> | 2025-02-24 00:18:12 +0000 |
---|---|---|
committer | drh <> | 2025-02-24 00:18:12 +0000 |
commit | 96a65cc4747cd79cf7966d03a876230c7c9ddcde (patch) | |
tree | d74d6e89df0896941359eeffabc4c66a1a237a76 /src | |
parent | 9ba963f03530b2d0817d5b89c8e35e8b36430290 (diff) | |
download | sqlite-96a65cc4747cd79cf7966d03a876230c7c9ddcde.tar.gz sqlite-96a65cc4747cd79cf7966d03a876230c7c9ddcde.zip |
Three different --escape modes: symbol, ascii, off.
FossilOrigin-Name: b5adb52fc0dc1838cb9c66cff422f2b8ec147e546cf909dd3c48731fa1edfe50
Diffstat (limited to 'src')
-rw-r--r-- | src/shell.c.in | 94 |
1 files changed, 73 insertions, 21 deletions
diff --git a/src/shell.c.in b/src/shell.c.in index 515da6ada..3bc8d2717 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1549,8 +1549,11 @@ static ShellState shellState; /* Allowed values for ShellState.eEscMode */ -#define SHELL_ESC_GRAPHIC 0 /* Substitute U+2400 graphics */ -#define SHELL_ESC_OFF 1 /* Send characters verbatim */ +#define SHELL_ESC_SYMBOL 0 /* Substitute U+2400 graphics */ +#define SHELL_ESC_ASCII 1 /* Substitute ^Y for X where Y=X+0x40 */ +#define SHELL_ESC_OFF 2 /* Send characters verbatim */ + +static const char *shell_EscModeNames[] = { "symbol", "ascii", "off" }; /* ** These are the allowed shellFlgs values @@ -2160,7 +2163,8 @@ static const char *escapeOutput( *ppFree = 0; return zInX; } - zOut = sqlite3_malloc64( i + 2*nCtrl + 1 ); + if( p->eEscMode==SHELL_ESC_SYMBOL ) nCtrl *= 2; + zOut = sqlite3_malloc64( i + nCtrl + 1 ); shell_check_oom(zOut); for(i=j=0; (c = zIn[i])!=0; i++){ if( c>0x1f @@ -2176,9 +2180,17 @@ static const char *escapeOutput( } zIn += i+1; i = -1; - zOut[j++] = 0xe2; - zOut[j++] = 0x90; - zOut[j++] = 0x80+c; + switch( p->eEscMode ){ + case SHELL_ESC_SYMBOL: + zOut[j++] = 0xe2; + zOut[j++] = 0x90; + zOut[j++] = 0x80+c; + break; + case SHELL_ESC_ASCII: + zOut[j++] = '^'; + zOut[j++] = 0x40+c; + break; + } } if( i>0 ){ memcpy(&zOut[j], zIn, i); @@ -9833,28 +9845,50 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zMode = 0; const char *zTabname = 0; int i, n2; + int chng = 0; ColModeOpts cmOpts = ColModeOpts_default; for(i=1; i<nArg; i++){ const char *z = azArg[i]; if( optionMatch(z,"wrap") && i+1<nArg ){ cmOpts.iWrap = integerValue(azArg[++i]); + chng = 1; }else if( optionMatch(z,"ww") ){ cmOpts.bWordWrap = 1; + chng = 1; }else if( optionMatch(z,"wordwrap") && i+1<nArg ){ cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]); + chng = 1; }else if( optionMatch(z,"quote") ){ cmOpts.bQuote = 1; + chng = 1; }else if( optionMatch(z,"noquote") ){ cmOpts.bQuote = 0; - }else if( optionMatch(z,"escape") ){ - p->eEscMode = SHELL_ESC_GRAPHIC; - }else if( optionMatch(z,"noescape") ){ - p->eEscMode = SHELL_ESC_OFF; + chng = 1; + }else if( optionMatch(z,"escape") && i+1<nArg ){ + const char *zEsc = azArg[++i]; + int k; + for(k=0; k<ArraySize(shell_EscModeNames); k++){ + if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){ + p->eEscMode = k; + chng = 1; + break; + } + } + if( k>=ArraySize(shell_EscModeNames) ){ + sqlite3_fprintf(stderr, "unknown escape mod \"%s\" - choices:", zEsc); + for(k=0; k<ArraySize(shell_EscModeNames); k++){ + sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]); + } + sqlite3_fprintf(stderr, "\n"); + rc = 1; + goto meta_command_exit; + } }else if( zMode==0 ){ zMode = z; /* Apply defaults for qbox pseudo-mode. If that * overwrites already-set values, user was informed of this. */ + chng = 1; if( cli_strcmp(z, "qbox")==0 ){ ColModeOpts cmo = ColModeOpts_default_qbox; zMode = "box"; @@ -9865,6 +9899,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( z[0]=='-' ){ sqlite3_fprintf(stderr,"unknown option: %s\n", z); eputz("options:\n" + " --escape MODE\n" " --noquote\n" " --quote\n" " --wordwrap on/off\n" @@ -9878,25 +9913,27 @@ static int do_meta_command(char *zLine, ShellState *p){ goto meta_command_exit; } } - if( zMode==0 ){ + if( !chng ){ if( p->mode==MODE_Column || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) ){ sqlite3_fprintf(p->out, "current output mode: %s --wrap %d --wordwrap %s " - "--%squote --%sescape\n", + "--%squote --escape %s\n", modeDescr[p->mode], p->cmOpts.iWrap, p->cmOpts.bWordWrap ? "on" : "off", p->cmOpts.bQuote ? "" : "no", - p->eEscMode ? "no" : "" + shell_EscModeNames[p->eEscMode] ); }else{ sqlite3_fprintf(p->out, - "current output mode: %s --%sescape\n", + "current output mode: %s --escape %s\n", modeDescr[p->mode], - p->eEscMode ? "no" : "" + shell_EscModeNames[p->eEscMode] ); } + } + if( zMode==0 ){ zMode = modeDescr[p->mode]; } n2 = strlen30(zMode); @@ -12650,7 +12687,7 @@ static const char zOptions[] = " -deserialize open the database using sqlite3_deserialize()\n" #endif " -echo print inputs before execution\n" - " -escape print control character XX as U+24XX\n" + " -escape MODE ctrl-char escape mode, one of: symbol, ascii, off\n" " -init FILENAME read/process named file\n" " -[no]header turn headers on or off\n" #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) @@ -12673,7 +12710,6 @@ static const char zOptions[] = " -multiplex enable the multiplexor VFS\n" #endif " -newline SEP set output row separator. Default: '\\n'\n" - " -noescape output control characters unmodified\n" " -nofollow refuse to open symbolic links to database files\n" " -nonce STRING set the safe-mode escape nonce\n" " -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n" @@ -13085,6 +13121,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ ShellSetFlag(&data,SHFLG_TestingMode); }else if( cli_strcmp(z,"-safe")==0 ){ /* no-op - catch this on the second pass */ + }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){ + /* skip over the argument */ + i++; } } #ifndef SQLITE_SHELL_FIDDLE @@ -13184,10 +13223,23 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( cli_strcmp(z,"-csv")==0 ){ data.mode = MODE_Csv; memcpy(data.colSeparator,",",2); - }else if( cli_strcmp(z,"-noescape")==0 ){ - data.eEscMode = SHELL_ESC_OFF; - }else if( cli_strcmp(z,"-escape")==0 ){ - data.eEscMode = SHELL_ESC_GRAPHIC; + }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){ + const char *zEsc = argv[++i]; + int k; + for(k=0; k<ArraySize(shell_EscModeNames); k++){ + if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){ + data.eEscMode = k; + break; + } + } + if( k>=ArraySize(shell_EscModeNames) ){ + sqlite3_fprintf(stderr, "unknown escape mode \"%s\" - choices:", zEsc); + for(k=0; k<ArraySize(shell_EscModeNames); k++){ + sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]); + } + sqlite3_fprintf(stderr, "\n"); + exit(1); + } #ifdef SQLITE_HAVE_ZLIB }else if( cli_strcmp(z,"-zip")==0 ){ data.openMode = SHELL_OPEN_ZIPFILE; |