From 02751a7162efcaa1021a345cd5d4e05408905c22 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 14 Nov 2025 17:11:06 +0000 Subject: [PATCH] Add the --once option to the .mode command. Improvements to help text. FossilOrigin-Name: 253980122a35f787423aaeedbec12ec94b31768f245fe1c1fcc7e08911855c60 --- manifest | 12 +++--- manifest.uuid | 2 +- src/shell.c.in | 110 +++++++++++++++++++++---------------------------- 3 files changed, 54 insertions(+), 70 deletions(-) diff --git a/manifest b/manifest index daafd458ca..ab709ab434 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings.\s\sIncorporate\s"USAGE:"\scomments\son\sdot-command\nimplementations\sinto\sthe\sCLI\s".help"\scommand\soutput. -D 2025-11-14T14:59:43.895 +C Add\sthe\s--once\soption\sto\sthe\s.mode\scommand.\s\sImprovements\sto\shelp\stext. +D 2025-11-14T17:11:06.215 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -735,7 +735,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a -F src/shell.c.in a1c46ccb2e2eb8ffe489ee8fed03d42f386c9bd5ffa74b9fbf0fcc330c5cf18f +F src/shell.c.in 80cddc5b2c3b9a2317ba673566b3a4091948ee640cf9e80daa432556418e61aa F src/sqlite.h.in 684c19c3b093cca7a38e3f6405d067777464285f17a58a78f7f89d6763e011e7 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52 @@ -2175,8 +2175,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2220cb70c2f1ee30dcdf917a20feacdfcb3789433d0645fea626fd4c5cf0d099 -R 502efdf1aafac3b4fa047f717c227b57 +P 046bfab4a01e8a7cc58d1bdf0756c90ba354562d79e5453c08202daf648e76a6 +R 617f8c7d32295d372a6a7a285c1648b3 U drh -Z 84e7db1443d1d78445106107a04c9aa2 +Z 8d9d41d539e868e42ddb8706f8074151 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bef4e23e54..8aacf80ba6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -046bfab4a01e8a7cc58d1bdf0756c90ba354562d79e5453c08202daf648e76a6 +253980122a35f787423aaeedbec12ec94b31768f245fe1c1fcc7e08911855c60 diff --git a/src/shell.c.in b/src/shell.c.in index f8d3bb8eab..bb79a75681 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1273,9 +1273,9 @@ struct ShellState { u8 eRestoreState; /* See comments above doAutoDetectRestore() */ unsigned statsOn; /* True to display memory stats before each finalize */ unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */ + u8 nPopOutput; /* Revert .output settings when reaching zero */ + u8 nPopMode; /* Revert .mode settings when reaching zero */ int inputNesting; /* Track nesting level of .read and other redirects */ - int outCount; /* Revert to stdout when reaching zero */ - int cnt; /* Number of records displayed so far */ i64 lineno; /* Line number of last line read from in */ const char *zInFile; /* Name of the input file */ int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */ @@ -1617,6 +1617,23 @@ static int modeFind(const char *zName){ return -1; } +/* +** Save or restore the current output mode +*/ +static void modePush(ShellState *p){ + if( p->nPopMode==0 ){ + modeFree(&p->modePrior); + modeDup(&p->modePrior,&p->mode); + } +} +static void modePop(ShellState *p){ + if( p->modePrior.spec.iVersion>0 ){ + modeFree(&p->mode); + p->mode = p->modePrior; + memset(&p->modePrior, 0, sizeof(p->modePrior)); + } +} + /* ** A callback for the sqlite3_log() interface. @@ -1861,21 +1878,6 @@ edit_func_end: } #endif /* SQLITE_NOHAVE_SYSTEM */ -/* -** Save or restore the current output mode -*/ -static void outputModePush(ShellState *p){ - modeFree(&p->modePrior); - modeDup(&p->modePrior,&p->mode); - p->priorShFlgs = p->shellFlgs; -} -static void outputModePop(ShellState *p){ - modeFree(&p->mode); - p->mode = p->modePrior; - modeInit(&p->modePrior); - p->shellFlgs = p->priorShFlgs; -} - /* ** Set output mode to text or binary for Windows. */ @@ -3150,10 +3152,9 @@ static int shell_exec( if( zStmtSql==0 ) zStmtSql = ""; while( IsSpace(zStmtSql[0]) ) zStmtSql++; - /* save off the prepared statement handle and reset row count */ + /* save off the prepared statement handle */ if( pArg ){ pArg->pStmt = pStmt; - pArg->cnt = 0; } /* Show the EXPLAIN QUERY PLAN if .eqp is on */ @@ -3908,6 +3909,7 @@ static int showHelp(FILE *out, const char *zPattern){ int j = 0; int n = 0; char *zPat; + const char *zHit = 0; if( zPattern==0 ){ /* Show just the first line for all help topics */ zPattern = "[a-z]"; @@ -3939,7 +3941,8 @@ static int showHelp(FILE *out, const char *zPattern){ shell_check_oom(zPat); for(i=0; idoXdgOpen = 0; } #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ @@ -7283,73 +7289,57 @@ static int modeTitleDsply(ShellState *p, int bAll){ /* ** DOT-COMMAND: .mode ** -** USAGE: .mode [MODE] [OPTIONS] +** USAGE: .mode [MODE] [OPTIONS] ** ** Change the output mode to MODE and/or apply OPTIONS to the ** output mode. If no arguments, show the current output mode ** and relevant options. ** ** Options: -** ** --align STRING Set the alignment of text in columnar modes ** String consists of characters 'L', 'C', 'R' ** meaning "left", "centered", and "right", with ** one letter per column starting from the left. ** Unspecified alignment defaults to 'L'. -** ** --charlimit N Set the maximum number of output characters to ** show for any single SQL value to N. Longer values ** truncated. Zero means "no limit". -** ** --colsep STRING Use STRING as the column separator -** ** --escape ESC Enable/disable escaping of control characters ** in output. ESC can be "off", "ascii", or ** "symbol". -** ** --linelimit N Set the maximum number of output lines to show for ** any single SQL value to N. Longer values are ** truncated. Zero means "no limit". Only works ** in "line" mode and in columnar modes. -** ** --null STRING Render SQL NULL values as the given string -** +** --once Setting changes to the left are reverted after +** the next SQL command. ** --quote ARG Enable/disable quoting of text. ARG can be ** "off", "on", "sql", "csv", "html", "tcl", ** or "json". "off" means show the text as-is. ** "on and "sql" are synonyms. -** ** --reset Changes all mode settings back to their default. -** ** --rowsep STRING Use STRING as the row separator -** ** --screenwidth N Declare the screen width of the output device ** to be N characters. An attempt may be made to ** wrap output text to fit within this limit. Zero ** means "no limit". Or N can be "auto" to set the ** width automatically. -** ** --tablename NAME Set the name of the table for "insert" mode. -** ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON. -** ** --title ARG Whether or not to show column headers, and if so ** how to encode them. ARG can be "off", "on", ** "sql", "csv", "html", "tcl", or "json". -** ** -v|--verbose Verbose output -** ** --widths LIST Set the columns widths for columnar modes. The ** argument is a list of integers, one for each ** column. A "0" width means use a dynamic width ** based on the actual width of data. If there are ** fewer entries in LIST than columns, "0" is used ** for the unspecified widths. -** ** --wordwrap BOOLEAN Enable/disable word wrapping -** ** --wrap N Wrap columns wider than N characters -** ** --ww Shorthand for "--wordwrap on" */ static int dotCmdMode(ShellState *p){ @@ -7512,6 +7502,10 @@ static int dotCmdMode(ShellState *p){ p->mode.spec.eText = QRF_TEXT_Plain; p->mode.spec.eBlob = QRF_BLOB_Text; chng = 1; + }else if( optionMatch(z,"once") ){ + p->nPopMode = 0; + modePush(p); + p->nPopMode = 1; }else if( optionMatch(z,"reset") ){ int saved_eMode = p->mode.eMode; modeFree(&p->mode); @@ -7634,6 +7628,7 @@ static int dotCmdMode(ShellState *p){ char *zDesc; const char *zSetting; + if( p->nPopMode ) sqlite3_str_appendall(pDesc, "--once "); sqlite3_str_appendall(pDesc,pI->zName); if( bAll || (p->mode.spec.nAlign && pI->eCx==2) ){ int ii; @@ -7741,40 +7736,29 @@ static int dotCmdMode(ShellState *p){ ** into /dev/null or the equivalent. ** ** Options: -** ** --bom Prepend a byte-order mark to the output -** ** -e Accumulate output in a temporary text file then ** launch a text editor when the redirection ends. -** ** --error-prefix X Use X as the left-margin prefix for error messages. ** Set to an empty string to restore the default. -** ** --glob GLOB Raise an error if the memory buffer does not match ** the GLOB pattern. -** ** --keep Continue using the same "memory" buffer. Do not ** reset it or delete it. Useful in combination with ** --glob, --not-glob, and/or --verify. -** ** ---notglob GLOB Raise an error if the memory buffer does not match ** the GLOB pattern. -** ** --plain Use plain text rather than HTML tables with -w -** ** --show Write the memory buffer to the screen, for debugging. -** ** --verify ENDMARK Read subsequent lines of text until the first line ** that matches ENDMARK. Discard the ENDMARK. Compare ** the text against the accumulated output in memory and ** raise an error if there are any differences. -** ** -w Show the output in a web browser. Output is ** written into a temporary HTML file until the ** redirect ends, then the web browser is launched. ** Query results are shown as HTML tables, unless ** the --plain is used too. -** ** -x Show the output in a spreadsheet. Output is ** written to a temp file as CSV then the spreadsheet ** is launched when @@ -7788,15 +7772,11 @@ static int dotCmdMode(ShellState *p){ ** or -x options is used. ** ** Options: -** ** -e Capture output into a temporary file then bring up ** a text editor on that temporary file. -** ** --plain Use plain text rather than HTML tables with -w -** ** -w Capture output into an HTML file then bring up that ** file in a web browser -** ** -x Show the output in a spreadsheet. Output is ** written to a temp file as CSV then the spreadsheet ** is launched when @@ -7915,9 +7895,9 @@ static int dotCmdOutput(ShellState *p){ shell_check_oom(zFile); } if( bOnce ){ - p->outCount = 2; + p->nPopOutput = 2; }else{ - p->outCount = 0; + p->nPopOutput = 0; } if( eCheck ){ char *zTest; @@ -7966,7 +7946,7 @@ static int dotCmdOutput(ShellState *p){ #ifndef SQLITE_NOHAVE_SYSTEM if( eMode=='e' || eMode=='x' || eMode=='w' ){ p->doXdgOpen = 1; - outputModePush(p); + modePush(p); if( eMode=='x' ){ /* spreadsheet mode. Output as CSV. */ newTempFile(p, "csv"); @@ -11467,9 +11447,9 @@ static int do_meta_command(const char *zLine, ShellState *p){ } meta_command_exit: - if( p->outCount ){ - p->outCount--; - if( p->outCount==0 ) output_reset(p); + if( p->nPopOutput ){ + p->nPopOutput--; + if( p->nPopOutput==0 ) output_reset(p); } p->bSafeMode = p->bSafeModePersist; return rc; @@ -11896,12 +11876,16 @@ static int process_input(ShellState *p, const char *zSrc){ errCnt += runOneSqlLine(p, zSql, p->in, startline); CONTINUE_PROMPT_RESET; nSql = 0; - if( p->outCount ){ + if( p->nPopOutput ){ output_reset(p); - p->outCount = 0; + p->nPopOutput = 0; }else{ clearTempFile(p); } + if( p->nPopMode ){ + modePop(p); + p->nPopMode = 0; + } p->bSafeMode = p->bSafeModePersist; qss = QSS_Start; }else if( nSql && QSS_PLAINWHITE(qss) ){ -- 2.47.3