int n = 0;
int k;
int aw;
+ (void)p;
if( w<-mxW ){
w = -mxW;
}else if( w>mxW ){
-C Fix\svarious\sbugs\sand\scompiler\swarnings.\s\sAll\stests\snow\spassing\son\slinux,\smac,\nand\swindows.\s\sMore\stesting\sneeded,\sthough.
-D 2025-11-14T13:07:45.192
+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
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c
F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee
F ext/qrf/README.md db3710552dfdacfc600e4c9772f84dccdf84ceb9983837a86269d4f6cb67219a
-F ext/qrf/qrf.c 7175ce8274b1566672cf26e29be06b39547cf6761bf75bdda4d8355f6b5837a9
+F ext/qrf/qrf.c a8cb5b2ecc9fc57ed79668002fbb5c54c6af03de7e20fc15aca5c85978f6b070
F ext/qrf/qrf.h b4b3489b3b3683523fd248d15cf5945830643b036943efacdb772a3e00367aa2
F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a
-F src/shell.c.in 4f034dea340795f025160a81b0ea26d27729376df23b0a9bc784cc328e8aefd2
+F src/shell.c.in a1c46ccb2e2eb8ffe489ee8fed03d42f386c9bd5ffa74b9fbf0fcc330c5cf18f
F src/sqlite.h.in 684c19c3b093cca7a38e3f6405d067777464285f17a58a78f7f89d6763e011e7
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl 3801ce32f8c55fe63a3b279f231fb26c2c1a2ea9a09d2dd599239d87a609acec
-F tool/mkshellc.tcl bab0a72a68384181a5706712dfdf6815f6526446d4e8aacace2de5e80cda91b2
+F tool/mkshellc.tcl 1c9197524174237b580dc1a6d1552541c5f5b78162949b4b8e640a7aef688d40
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
F tool/mksqlite3c-noext.tcl 351c55256213154cabb051a3c870ef9f4487de905015141ae50dc7578a901b84
F tool/mksqlite3c.tcl 7a268139158e5deef27a370bc2f8db6ccf100c1ad7ac5e5b23743c0fd354f609
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 6ffab43ca32230975e79d91080dfa2e80a4c21deef31ab86455581af18a399cd 5252a2e629e1adb61169d32ca6458c6decd1ec562f358bb9d0b448a2f0243c56
-R 55001368278a1a9bd00f0d0045e947e0
+P 2220cb70c2f1ee30dcdf917a20feacdfcb3789433d0645fea626fd4c5cf0d099
+R 502efdf1aafac3b4fa047f717c227b57
U drh
-Z 4eb8cd588f9e324fca2d92f8eebd5607
+Z 84e7db1443d1d78445106107a04c9aa2
# Remove this line to create a well-formed Fossil manifest.
-2220cb70c2f1ee30dcdf917a20feacdfcb3789433d0645fea626fd4c5cf0d099
+046bfab4a01e8a7cc58d1bdf0756c90ba354562d79e5453c08202daf648e76a6
*/
static void modeChange(Mode *p, unsigned char eMode){
const ModeInfo *pI;
- assert( eMode>=0 && eMode<ArraySize(aModeInfo) );
+ assert( eMode<ArraySize(aModeInfo) );
pI = &aModeInfo[eMode];
p->eMode = eMode;
if( pI->eCSep ) modeSetStr(&p->spec.zColumnSep, aModeStr[pI->eCSep]);
#endif
};
+INSERT-USAGE-TEXT-HERE
+
+/*
+** Return a pointer to usage text for zCmd, or NULL if none exists.
+*/
+static const char *findUsage(const char *zCmd){
+ int i;
+ for(i=0; i<ArraySize(aUsage); i++){
+ if( sqlite3_strglob(zCmd, aUsage[i].zCmd)==0 ) return aUsage[i].zUsage;
+ }
+ return 0;
+}
+
/*
** Output help text for commands that match zPattern.
**
}
/* Seek documented commands for which zPattern is an exact prefix */
- zPat = sqlite3_mprintf(".%s*", zPattern);
+ zPat = sqlite3_mprintf(".%s*", zPattern[0]=='.' ? &zPattern[1] : zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( sqlite3_strglob(zPat, azHelp[i])==0 ){
n++;
}
}
- sqlite3_free(zPat);
if( 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]==' ' ){
- cli_printf(out, "%s\n", azHelp[j]);
- j++;
+ const char *zUsage = findUsage(zPat);
+ if( zUsage ){
+ cli_puts(zUsage, out);
+ }else{
+ /* 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]==' ' ){
+ cli_printf(out, "%s\n", azHelp[j]);
+ j++;
+ }
}
}
- return n;
}
+ sqlite3_free(zPat);
+ if( n ) return n;
/* Look for documented commands that contain zPattern anywhere.
** Show complete text of all documented commands that match. */
}
/*
-** DOT-COMMAND: .output [OPTIONS] [FILE]
-** ONELINER: Redirect output
+** DOT-COMMAND: .output
+** USAGE: .output [OPTIONS] [FILE]
**
** Begin redirecting output to FILE. Or if FILE is omitted, revert
** to sending output to the console. If FILE begins with "|" then
** written to a temp file as CSV then the spreadsheet
** is launched when
**
-** DOT-COMMAND: .once [OPTIONS] FILE ...
-** ONELINER: Redirect output for the next SQL statement or dot-command
+** DOT-COMMAND: .once
+** USAGE: .once [OPTIONS] FILE ...
**
** Write the output for the next line of SQL or the next dot-command into
** FILE. If FILE begins with "|" then it is a program into which output
** is launched when
**
** DOT-COMMAND: .excel
-** ONELINER: Display results of the next SQL statement in a spreadsheet
-**
** Shorthand for ".once -x"
**
** DOT-COMMAND: .www [--plain]
-** ONELINER: Display result of the next SQL statement in a web browser
-**
** Shorthand for ".once -w" or ".once --plain -w"
*/
static int dotCmdOutput(ShellState *p){
set out stdout
fconfigure stdout -translation binary
if {[lindex $argv 0]!=""} {
- set out [open [lindex $argv 0] wb]
+ set output_file [lindex $argv 0]
+ file delete -force $output_file
+ set out [open $output_file wb]
+} else {
+ set output_file {}
}
-puts $out {/* DO NOT EDIT!
-** This file is automatically generated by the script in the canonical
-** SQLite source tree at tool/mkshellc.tcl. That script combines source
-** code from various constituent source files of SQLite into this single
-** "shell.c" file used to implement the SQLite command-line shell.
-**
-** Most of the code found below comes from the "src/shell.c.in" file in
-** the canonical SQLite source tree. That main file contains "INCLUDE"
-** lines that specify other files in the canonical source tree that are
-** inserted to getnerate this complete program source file.
-**
-** The code from multiple files is combined into this single "shell.c"
-** source file to help make the command-line program easier to compile.
-**
-** To modify this program, get a copy of the canonical SQLite source tree,
-** edit the src/shell.c.in" and/or some of the other files that are included
-** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
-*/}
+
+############################## FIRST PASS ################################
+# Read through the shell.c.in source file to gather information. Do not
+# yet generate any code
+#
set in [open $topdir/src/shell.c.in]
fconfigure $in -translation binary
+set allSource(src/shell.c.in) 1
+set inUsage 0
+set dotcmd {}
+while {1} {
+ set lx [gets $in]
+ if {[eof $in]} break;
+ if {[regexp {^INCLUDE } $lx]} {
+ set cfile [lindex $lx 1]
+ if {[string match ../* $cfile]} {
+ set xfile [string range $cfile 3 end]
+ } else {
+ set xfile "src/$cfile"
+ }
+ set allSource($xfile) 1
+ } elseif {[regexp {^\*\* USAGE:\s+([^\s]+)} $lx all dotcmd]} {
+ set inUsage 1
+ set details [string trim [string range $lx 2 end]]
+ } elseif {$inUsage} {
+ if {![regexp {^\*\*} $lx] || [regexp { DOT-COMMAND: } $lx]} {
+ set inUsage 0
+ set Usage($dotcmd) [string trim $details]
+ } else {
+ append details \n
+ append details [string range [string trimright $lx] 3 end]
+ }
+ }
+}
+
+# Generate dot-command usage text based on the data accumulated in
+# the Usage() array.
+#
+proc generate_usage {out} {
+ global Usage
+ puts $out "/**************************************************************"
+ puts $out "** \"Usage\" help text automatically generated from comments */"
+ puts $out "static const struct \173"
+ puts $out " const char *zCmd; /* Name of the dot-command */"
+ puts $out " const char *zUsage; /* Documentation */"
+ puts $out "\175 aUsage\[\] = \173"
+ foreach dotcmd [array names Usage] {
+ puts $out " \173 \"$dotcmd\","
+ foreach line [split $Usage($dotcmd) \n] {
+ set x [string map [list \\ \\\\ \" \\\"] $line]
+ puts $out "\"$x\\n\""
+ }
+ puts $out " \175,"
+ }
+ puts $out "\175;"
+}
+# generate_usage stderr
+
+###### SECOND PASS #######
+# Make a second pass through shell.c.in to generate the the final
+# output, based on data gathered during the first pass.
+#
+
+puts $out {/*
+** This is the amalgamated source code to the "sqlite3" or "sqlite3.exe"
+** command-line shell (CLI) for SQLite. This file is automatically
+** generated by the tool/mkshellc.tcl script from the following sources:
+**}
+foreach fn [lsort [array names allSource]] {
+ puts $out "** $fn"
+}
+puts $out {**
+** To modify this program, get a copy of the canonical SQLite source tree,
+** edit the src/shell.c.in file and/or some of the other files that are
+** listed above, then rerun the rerun "make shell.c".
+*/}
+seek $in 0 start
+puts $out "/************************* Begin src/shell.c.in ******************/"
proc omit_redundant_typedefs {line} {
global typedef_seen
if {[regexp {^typedef .* ([a-zA-Z0-9_]+);} $line all typename]} {
incr iLine
if {[regexp {^INCLUDE } $lx]} {
set cfile [lindex $lx 1]
- puts $out "/************************* Begin $cfile ******************/"
-# puts $out "#line 1 \"$cfile\""
- set in2 [open $topdir/src/$cfile]
+ if {[string match ../* $cfile]} {
+ set xfile [string range $cfile 3 end]
+ } else {
+ set xfile "src/$cfile"
+ }
+ puts $out "/************************* Begin $xfile ******************/"
+# puts $out "#line 1 \"$xfile\""
+ set in2 [open $topdir/$xfile]
fconfigure $in2 -translation binary
while {![eof $in2]} {
set lx [omit_redundant_typedefs [gets $in2]]
puts $out $lx
}
close $in2
- puts $out "/************************* End $cfile ********************/"
+ puts $out "/************************* End $xfile ********************/"
# puts $out "#line [expr $iLine+1] \"shell.c.in\""
- continue
+ } elseif {[regexp {^INSERT-USAGE-TEXT-HERE} $lx]} {
+ generate_usage $out
+ } else {
+ puts $out $lx
}
- puts $out $lx
}
+puts $out "/************************* End src/shell.c.in ******************/"
close $in
close $out
+
+# Try to disable write permissions on the generate file, to prevent
+# accidentally editing the generated file rather than source files.
+#
+if {$output_file ne ""} {
+ catch {file attributes $output_file -readonly 1}
+ catch {file attributes $output_file -permissions -w}
+ catch {exec chmod -w $output_file}
+}