From 1d9db01065d3d855d33c257711ef40486b122885 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 23 Sep 2024 20:23:43 +0000 Subject: [PATCH 01/25] CLI uses only lib-c for I/O on Windows. No calls to Win32. Works on Win11, at least. Reads and writes unicode to/from the console and UTF-8 to/from files. Prototype code only - must testing and additional work required. FossilOrigin-Name: 5c54530d5a0a4125a1ba44f22537c4f63d5e5708f347c43cbac3e1832c4335da --- Makefile.in | 2 - Makefile.msc | 2 - main.mk | 2 - manifest | 21 +++--- manifest.uuid | 2 +- src/shell.c.in | 190 ++++++++++++++++++++++++++++--------------------- 6 files changed, 122 insertions(+), 97 deletions(-) diff --git a/Makefile.in b/Makefile.in index dba80d38fb..7b693b5225 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1187,8 +1187,6 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c # Source and header files that shell.c depends on SHELL_DEP = \ $(TOP)/src/shell.c.in \ - $(TOP)/ext/consio/console_io.c \ - $(TOP)/ext/consio/console_io.h \ $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/sqlite3expert.h \ $(TOP)/ext/intck/sqlite3intck.c \ diff --git a/Makefile.msc b/Makefile.msc index 434c996608..bb63601518 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2316,8 +2316,6 @@ keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe # Source and header files that shell.c depends on SHELL_DEP = \ $(TOP)\src\shell.c.in \ - $(TOP)\ext\consio\console_io.c \ - $(TOP)\ext\consio\console_io.h \ $(TOP)\ext\expert\sqlite3expert.c \ $(TOP)\ext\expert\sqlite3expert.h \ $(TOP)\ext\intck\sqlite3intck.c \ diff --git a/main.mk b/main.mk index 79e345d1b8..8aaa7e7d06 100644 --- a/main.mk +++ b/main.mk @@ -763,8 +763,6 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c # Source and header files that shell.c depends on SHELL_DEP = \ $(TOP)/src/shell.c.in \ - $(TOP)/ext/consio/console_io.c \ - $(TOP)/ext/consio/console_io.h \ $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/sqlite3expert.h \ $(TOP)/ext/intck/sqlite3intck.c \ diff --git a/manifest b/manifest index ca881335f6..8b26ee7843 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Add\sthe\srun-fuzzcheck\starget\sto\sthe\sMSVC\smakefile. -D 2024-09-21T17:27:47.017 +C CLI\suses\sonly\slib-c\sfor\sI/O\son\sWindows.\s\sNo\scalls\sto\sWin32.\s\sWorks\son\sWin11,\nat\sleast.\s\sReads\sand\swrites\sunicode\sto/from\sthe\sconsole\sand\sUTF-8\sto/from\sfiles.\nPrototype\scode\sonly\s-\smust\stesting\sand\sadditional\swork\srequired. +D 2024-09-23T20:23:43.341 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in fa448c4c0567623fd140efebecb570ab58d955d766a5ea0fd8a94e9b5697007c +F Makefile.in aa594119c3c7f699e87a767fca6598452f77d4c32c41a6486c40d4f156d4efc1 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 -F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 +F Makefile.msc add7e29bae33ad5b8c464daf6de84a1a01e31e6337d79fb0c1062e53fa7657da F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -687,7 +687,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 67e622f31d10fee8f0f62655b4f9b47cd97fe70a125674ca6754b3549d69cc0e +F main.mk b897586c0c7b77b7e39f0a0e9ed79fed7346b09af1ed35a08da745e02b795772 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -768,7 +768,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c b2cd748488012312824508639b6af908461e45403037d5c4e19d9b0e8195507f F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 375f8a183126be96ec73db4e42c57917ff10a0900846b1b722dd4f8cef537812 +F src/shell.c.in 265c877932142ee8ef05a6aa5a0a5bff92905ffef97dc6f566062a27814274a1 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2213,8 +2213,11 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 62e11a3a78edf9853b74d6495ccd8ae9ac1966c7d78eb3682cf2d5885e3740ec -R 44ce456c4e740a869984e636809287df +P 2e5194407a1b34dd0659c350ea8098bfef7b3f11aa5b2a07ecd2bce5582655a2 +R 7c20c2fd1880ef1b062b32c88da2e8e4 +T *branch * cli-stdlib +T *sym-cli-stdlib * +T -sym-trunk * U drh -Z fb345da7ed81e5875e018c3667e473a3 +Z cdf0bc25a30881c9fe4f62b1ff96af22 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c7adf060ec..7417271d4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e5194407a1b34dd0659c350ea8098bfef7b3f11aa5b2a07ecd2bce5582655a2 +5c54530d5a0a4125a1ba44f22537c4f63d5e5708f347c43cbac3e1832c4335da diff --git a/src/shell.c.in b/src/shell.c.in index 2b0e506ed8..a2b22845d6 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -237,6 +237,57 @@ extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); #endif +#ifdef _WIN32 +/* On Windows, we normally run with output mode of TEXT so that \n characters +** are automatically translated into \r\n. However, this behavior needs +** to be disabled in some cases (ex: when generating CSV output and when +** rendering quoted strings that contain \n characters). The following +** routines take care of that. +*/ +static void setBinaryMode(FILE *file, int isOutput){ + if( isOutput ) fflush(file); + _setmode(_fileno(file), _O_BINARY); +} +static void setTextMode(FILE *file, int isOutput){ + if( isOutput ) fflush(file); + _setmode(_fileno(file), _O_TEXT); +} +#else + /* Unix equivalents to set*Mode() */ +# define setBinaryMode(X,Y) +# define setTextMode(X,Y) +#endif + +#ifdef _WIN32 +/* fgets() for windows */ +static char *cli_fgets(char *buf, int sz, FILE *in){ + if( isatty(_fileno(in)) ){ + /* When reading from the command-prompt in Windows, it is necessary + ** to use _O_WTEXT input mode to read UTF-16 characters, then translate + ** that into UTF-8. Otherwise, non-ASCII characters all get translated + ** into '?'. + */ + wchar_t *b1 = malloc( sz*sizeof(wchar_t) ); + if( b1==0 ) return 0; + _setmode(_fileno(in), _O_WTEXT); + if( fgetws(b1, sz/4, in)==0 ){ + sqlite3_free(b1); + return 0; + } + WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0); + sqlite3_free(b1); + return buf; + }else{ + /* Reading from a file or other input source, just read bytes without + ** any translation. */ + return fgets(buf, sz, in); + } +} +#else +/* library version works for everybody else */ +# define cli_fgets fgets +#endif + /* Use console I/O package as a direct INCLUDE. */ #define SQLITE_INTERNAL_LINKAGE static @@ -248,57 +299,15 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); # define SQLITE_CIO_NO_SETMODE # define SQLITE_CIO_NO_FLUSH #endif -INCLUDE ../ext/consio/console_io.h -INCLUDE ../ext/consio/console_io.c -#ifndef SQLITE_SHELL_FIDDLE - -/* From here onward, fgets() is redirected to the console_io library. */ -# define fgets(b,n,f) fGetsUtf8(b,n,f) -/* - * Define macros for emitting output text in various ways: - * sputz(s, z) => emit 0-terminated string z to given stream s - * sputf(s, f, ...) => emit varargs per format f to given stream s - * oputz(z) => emit 0-terminated string z to default stream - * oputf(f, ...) => emit varargs per format f to default stream - * eputz(z) => emit 0-terminated string z to error stream - * eputf(f, ...) => emit varargs per format f to error stream - * oputb(b, n) => emit char buffer b[0..n-1] to default stream - * - * Note that the default stream is whatever has been last set via: - * setOutputStream(FILE *pf) - * This is normally the stream that CLI normal output goes to. - * For the stand-alone CLI, it is stdout with no .output redirect. - * - * The ?putz(z) forms are required for the Fiddle builds for string literal - * output, in aid of enforcing format string to argument correspondence. - */ -# define sputz(s,z) fPutsUtf8(z,s) -# define sputf fPrintfUtf8 -# define oputz(z) oPutsUtf8(z) -# define oputf oPrintfUtf8 -# define eputz(z) ePutsUtf8(z) -# define eputf ePrintfUtf8 -# define oputb(buf,na) oPutbUtf8(buf,na) -# define fflush(s) fFlushBuffer(s); - -#else -/* For Fiddle, all console handling and emit redirection is omitted. */ -/* These next 3 macros are for emitting formatted output. When complaints - * from the WASM build are issued for non-formatted output, when a mere - * string literal is to be emitted, the ?putz(z) forms should be used. - * (This permits compile-time checking of format string / argument mismatch.) - */ -# define oputf(fmt, ...) printf(fmt,__VA_ARGS__) -# define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__) -# define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__) +#define oputf(fmt, ...) printf(fmt,__VA_ARGS__) +#define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__) +#define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__) /* These next 3 macros are for emitting simple string literals. */ -# define oputz(z) fputs(z,stdout) -# define eputz(z) fputs(z,stderr) -# define sputz(fp,z) fputs(z,fp) -# define oputb(buf,na) fwrite(buf,1,na,stdout) -# undef fflush -#endif +#define oputz(z) fputs(z,stdout) +#define eputz(z) fputs(z,stderr) +#define sputz(fp,z) fputs(z,fp) +#define oputb(buf,na) fwrite(buf,1,na,stdout) /* True if the timer is enabled */ static int enableTimer = 0; @@ -344,6 +353,7 @@ struct rusage { #define getrusage(A,B) memset(B,0,sizeof(*B)) #endif + /* Saved resource information for the beginning of an operation */ static struct rusage sBegin; /* CPU time at start */ static sqlite3_int64 iBegin; /* Wall-clock time at start */ @@ -802,7 +812,7 @@ static char *local_getline(char *zLine, FILE *in){ zLine = realloc(zLine, nLine); shell_check_oom(zLine); } - if( fgets(&zLine[n], nLine - n, in)==0 ){ + if( cli_fgets(&zLine[n], nLine - n, in)==0 ){ if( n==0 ){ free(zLine); return 0; @@ -1766,10 +1776,7 @@ static const char *unused_string( static void output_quoted_string(const char *z){ int i; char c; -#ifndef SQLITE_SHELL_FIDDLE - FILE *pfO = setOutputStream(invalidFileStream); - setBinaryMode(pfO, 1); -#endif + setBinaryMode(stdout, 1); if( z==0 ) return; for(i=0; (c = z[i])!=0 && c!='\''; i++){} if( c==0 ){ @@ -1794,11 +1801,7 @@ static void output_quoted_string(const char *z){ } oputz("'"); } -#ifndef SQLITE_SHELL_FIDDLE - setTextMode(pfO, 1); -#else setTextMode(stdout, 1); -#endif } /* @@ -1813,10 +1816,7 @@ static void output_quoted_string(const char *z){ static void output_quoted_escaped_string(const char *z){ int i; char c; -#ifndef SQLITE_SHELL_FIDDLE - FILE *pfO = setOutputStream(invalidFileStream); - setBinaryMode(pfO, 1); -#endif + setBinaryMode(stdout, 1); for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} if( c==0 ){ oputf("'%s'",z); @@ -1868,11 +1868,7 @@ static void output_quoted_escaped_string(const char *z){ oputf(",'%s',char(10))", zNL); } } -#ifndef SQLITE_SHELL_FIDDLE - setTextMode(pfO, 1); -#else setTextMode(stdout, 1); -#endif } /* @@ -1892,6 +1888,42 @@ static const char *anyOfInStr(const char *s, const char *zAny, size_t ns){ } return pcFirst; } + +/* Skip over as much z[] input char sequence as is valid UTF-8, +** limited per nAccept char's or whole characters and containing +** no char cn such that ((1<=0 => char count, nAccept<0 => character + */ +const char *zSkipValidUtf8(const char *z, int nAccept, long ccm){ + int ng = (nAccept<0)? -nAccept : 0; + const char *pcLimit = (nAccept>=0)? z+nAccept : 0; + assert(z!=0); + while( (pcLimit)? (z= pcLimit ) return z; + else{ + char ct = *zt++; + if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){ + /* Trailing bytes are too few, too many, or invalid. */ + return z; + } + } + } while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */ + z = zt; + } + } + return z; +} + + /* ** Output the given string as a quoted according to C or TCL quoting rules. */ @@ -3027,7 +3059,7 @@ static void displayLinuxIoStats(void){ sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); in = fopen(z, "rb"); if( in==0 ) return; - while( fgets(z, sizeof(z), in)!=0 ){ + while( cli_fgets(z, sizeof(z), in)!=0 ){ static const struct { const char *zPattern; const char *zDesc; @@ -5238,7 +5270,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ } *pnData = 0; nLine++; - if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; + if( cli_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) goto readHexDb_error; if( n<0 ) goto readHexDb_error; @@ -5251,7 +5283,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ eputz("invalid pagesize\n"); goto readHexDb_error; } - for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){ + for(nLine++; cli_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ rc = sscanf(zLine, "| page %d offset %d", &j, &k); if( rc==2 ){ iOffset = k; @@ -5283,7 +5315,7 @@ readHexDb_error: if( in!=p->in ){ fclose(in); }else{ - while( fgets(zLine, sizeof(zLine), p->in)!=0 ){ + while( cli_fgets(zLine, sizeof(zLine), p->in)!=0 ){ nLine++; if(cli_strncmp(zLine, "| end ", 6)==0 ) break; } @@ -6177,10 +6209,10 @@ static void tryToClone(ShellState *p, const char *zNewDb){ ** Change the output stream (file or pipe or console) to something else. */ static void output_redir(ShellState *p, FILE *pfNew){ - if( p->out != stdout ) eputz("Output already redirected.\n"); - else{ + if( p->out != stdout ){ + eputz("Output already redirected.\n"); + }else{ p->out = pfNew; - setOutputStream(pfNew); } } @@ -6226,7 +6258,6 @@ static void output_reset(ShellState *p){ } p->outfile[0] = 0; p->out = stdout; - setOutputStream(stdout); } #else # define output_redir(SS,pfO) @@ -10719,9 +10750,9 @@ static int do_meta_command(char *zLine, ShellState *p){ zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"", zCmd, azArg[i]); } - consoleRestore(); + /*consoleRestore();*/ x = zCmd!=0 ? system(zCmd) : 1; - consoleRenewSetup(); + /*consoleRenewSetup();*/ sqlite3_free(zCmd); if( x ) eputf("System command returns %d\n", x); }else @@ -12374,7 +12405,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ # define data shellState #else ShellState data; - StreamsAreConsole consStreams = SAC_NoConsole; #endif const char *zInitFile = 0; int i; @@ -12397,10 +12427,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ stdout_is_console = 1; data.wasm.zDefaultDbName = "/fiddle.sqlite3"; #else - consStreams = consoleClassifySetup(stdin, stdout, stderr); - stdin_is_interactive = (consStreams & SAC_InConsole)!=0; - stdout_is_console = (consStreams & SAC_OutConsole)!=0; - atexit(consoleRestore); + stdin_is_interactive = isatty(0); + stdout_is_console = isatty(1); #endif atexit(sayAbnormalExit); #ifdef SQLITE_DEBUG From 118ac6a7ad50378a18be2c8ba76a01ed2c696922 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 09:51:53 +0000 Subject: [PATCH 02/25] Always use fputws() for output to a Windows command-line prompt. FossilOrigin-Name: 33950a8c3f3e48e5107fe56647da05147aa84f9c3eccbe7c8671f5b502ebb70b --- manifest | 15 +++++------ manifest.uuid | 2 +- src/shell.c.in | 68 +++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 8b26ee7843..f90dfa8f25 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C CLI\suses\sonly\slib-c\sfor\sI/O\son\sWindows.\s\sNo\scalls\sto\sWin32.\s\sWorks\son\sWin11,\nat\sleast.\s\sReads\sand\swrites\sunicode\sto/from\sthe\sconsole\sand\sUTF-8\sto/from\sfiles.\nPrototype\scode\sonly\s-\smust\stesting\sand\sadditional\swork\srequired. -D 2024-09-23T20:23:43.341 +C Always\suse\sfputws()\sfor\soutput\sto\sa\sWindows\scommand-line\sprompt. +D 2024-09-24T09:51:53.618 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -768,7 +768,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c b2cd748488012312824508639b6af908461e45403037d5c4e19d9b0e8195507f F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 265c877932142ee8ef05a6aa5a0a5bff92905ffef97dc6f566062a27814274a1 +F src/shell.c.in 6054892954e926a30a5b3d2994805477d38154692b5bb571d81db86791d0e58b F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2213,11 +2213,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2e5194407a1b34dd0659c350ea8098bfef7b3f11aa5b2a07ecd2bce5582655a2 -R 7c20c2fd1880ef1b062b32c88da2e8e4 -T *branch * cli-stdlib -T *sym-cli-stdlib * -T -sym-trunk * +P 5c54530d5a0a4125a1ba44f22537c4f63d5e5708f347c43cbac3e1832c4335da +R 39e94947c12065fc6ead20518785128b U drh -Z cdf0bc25a30881c9fe4f62b1ff96af22 +Z 9f7cd507ccaf6f6343bd8b5a2d5f1672 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7417271d4a..d6a1143c67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c54530d5a0a4125a1ba44f22537c4f63d5e5708f347c43cbac3e1832c4335da +33950a8c3f3e48e5107fe56647da05147aa84f9c3eccbe7c8671f5b502ebb70b diff --git a/src/shell.c.in b/src/shell.c.in index a2b22845d6..c400073872 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -288,6 +288,62 @@ static char *cli_fgets(char *buf, int sz, FILE *in){ # define cli_fgets fgets #endif +#ifdef _WIN32 +/* fputs() for windows */ +static int cli_fputs(const char *z, FILE *out){ + if( isatty(_fileno(out)) ){ + /* When writing to the command-prompt in Windows, it is necessary + ** to use _O_WTEXT input mode and write UTF-16 characters. + */ + int sz = (int)strlen(z); + wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) ); + if( b1==0 ) return 0; + sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); + b1[sz] = 0; + _setmode(_fileno(out), _O_WTEXT); + fputws(b1, out); + sqlite3_free(b1); + return 0; + }else{ + /* Writing to a file or other destination, just write bytes without + ** any translation. */ + return fputs(z, out); + } +} +#else +/* library version works for everybody else */ +# define cli_fputs fputs +#endif + +#ifdef _WIN32 +/* fprintf() for windows */ +static void cli_fprintf(FILE *out, const char *zFormat, ...){ + if( isatty(fileno(out)) ){ + /* When writing to the command-prompt in Windows, it is necessary + ** to use _O_WTEXT input mode and write UTF-16 characters. + */ + char *z; + va_list ap; + + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + cli_fputs(z, out); + sqlite3_free(z); + }else{ + /* Writing to a file or other destination, just write bytes without + ** any translation. */ + va_list ap; + va_start(ap, zFormat); + vfprintf(out, zFormat, ap); + va_end(ap); + } +} +#else +/* library version works for everybody else */ +# define cli_fprintf fprintf +#endif + /* Use console I/O package as a direct INCLUDE. */ #define SQLITE_INTERNAL_LINKAGE static @@ -300,13 +356,13 @@ static char *cli_fgets(char *buf, int sz, FILE *in){ # define SQLITE_CIO_NO_FLUSH #endif -#define oputf(fmt, ...) printf(fmt,__VA_ARGS__) -#define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__) -#define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__) +#define oputf(fmt, ...) cli_fprintf(stdout,fmt,__VA_ARGS__) +#define eputf(fmt, ...) cli_fprintf(stderr,fmt,__VA_ARGS__) +#define sputf(fp,fmt, ...) cli_fprintf(fp,fmt,__VA_ARGS__) /* These next 3 macros are for emitting simple string literals. */ -#define oputz(z) fputs(z,stdout) -#define eputz(z) fputs(z,stderr) -#define sputz(fp,z) fputs(z,fp) +#define oputz(z) cli_fputs(z,stdout) +#define eputz(z) cli_fputs(z,stderr) +#define sputz(fp,z) cli_fputs(z,fp) #define oputb(buf,na) fwrite(buf,1,na,stdout) /* True if the timer is enabled */ From 4e34558f1baf40bf628f8872f9bddf52f05c8c4f Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 10:30:07 +0000 Subject: [PATCH 03/25] Use _wfopen() instead of fopen() on Windows in the CLI. FossilOrigin-Name: 21a8cac5e9a0d5ead29ca1114be7520d182348f7e2e2e2416852b827d7e09f21 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 53 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index f90dfa8f25..6c38834512 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\suse\sfputws()\sfor\soutput\sto\sa\sWindows\scommand-line\sprompt. -D 2024-09-24T09:51:53.618 +C Use\s_wfopen()\sinstead\sof\sfopen()\son\sWindows\sin\sthe\sCLI. +D 2024-09-24T10:30:07.376 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -768,7 +768,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c b2cd748488012312824508639b6af908461e45403037d5c4e19d9b0e8195507f F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 6054892954e926a30a5b3d2994805477d38154692b5bb571d81db86791d0e58b +F src/shell.c.in 95f1bdfb9b1d513c7d82ab04fbca746a9668fb02d3eb984cd1cfb3b4ffc413e0 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2213,8 +2213,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5c54530d5a0a4125a1ba44f22537c4f63d5e5708f347c43cbac3e1832c4335da -R 39e94947c12065fc6ead20518785128b +P 33950a8c3f3e48e5107fe56647da05147aa84f9c3eccbe7c8671f5b502ebb70b +R 563de058a2a6970ab738b542c7a8c099 U drh -Z 9f7cd507ccaf6f6343bd8b5a2d5f1672 +Z 3b9fb03668dcca40431939db5346d2bc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d6a1143c67..a3d44399a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33950a8c3f3e48e5107fe56647da05147aa84f9c3eccbe7c8671f5b502ebb70b +21a8cac5e9a0d5ead29ca1114be7520d182348f7e2e2e2416852b827d7e09f21 diff --git a/src/shell.c.in b/src/shell.c.in index c400073872..5677e060f7 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -344,6 +344,33 @@ static void cli_fprintf(FILE *out, const char *zFormat, ...){ # define cli_fprintf fprintf #endif +#ifdef _WIN32 +/* fopen() for windows */ +static FILE *cli_fopen(const char *zFilename, const char *zMode){ + FILE *fp = 0; + wchar_t *b1, *b2; + int sz1, sz2; + + sz1 = (int)strlen(zFilename); + sz2 = (int)strlen(zMode); + b1 = malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + if( b1 && b2 ){ + sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); + b1[sz1] = 0; + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); + b2[sz2] = 0; + fp = _wfopen(b1, b2); + } + free(b1); + free(b2); + return fp; +} +#else +/* library version works for everybody else */ +# define cli_fopen fopen +#endif + /* Use console I/O package as a direct INCLUDE. */ #define SQLITE_INTERNAL_LINKAGE static @@ -827,7 +854,7 @@ static FILE * openChrSource(const char *zFile){ /* On Windows, open first, then check the stream nature. This order ** is necessary because _stat() and sibs, when checking a named pipe, ** effectively break the pipe as its supplier sees it. */ - FILE *rv = fopen(zFile, "rb"); + FILE *rv = cli_fopen(zFile, "rb"); if( rv==0 ) return 0; if( _fstat64(_fileno(rv), &x) != 0 || !STAT_CHR_SRC(x.st_mode)){ @@ -841,7 +868,7 @@ static FILE * openChrSource(const char *zFile){ # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) if( rc!=0 ) return 0; if( STAT_CHR_SRC(x.st_mode) ){ - return fopen(zFile, "rb"); + return cli_fopen(zFile, "rb"); }else{ return 0; } @@ -1681,7 +1708,7 @@ static void editFunc( bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; /* When writing the file to be edited, do \n to \r\n conversions on systems ** that want \r\n line endings */ - f = fopen(zTempFile, bBin ? "wb" : "w"); + f = cli_fopen(zTempFile, bBin ? "wb" : "w"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot open temp file", -1); goto edit_func_end; @@ -1712,7 +1739,7 @@ static void editFunc( sqlite3_result_error(context, "EDITOR returned non-zero", -1); goto edit_func_end; } - f = fopen(zTempFile, "rb"); + f = cli_fopen(zTempFile, "rb"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot reopen temp file after edit", -1); @@ -3113,7 +3140,7 @@ static void displayLinuxIoStats(void){ FILE *in; char z[200]; sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); - in = fopen(z, "rb"); + in = cli_fopen(z, "rb"); if( in==0 ) return; while( cli_fgets(z, sizeof(z), in)!=0 ){ static const struct { @@ -5170,7 +5197,7 @@ static int process_input(ShellState *p); ** is undefined in this case. */ static char *readFile(const char *zName, int *pnByte){ - FILE *in = fopen(zName, "rb"); + FILE *in = cli_fopen(zName, "rb"); long nIn; size_t nRead; char *pBuf; @@ -5260,7 +5287,7 @@ static int session_filter(void *pCtx, const char *zTab){ ** the type cannot be determined from content. */ int deduceDatabaseType(const char *zName, int dfltZip){ - FILE *f = fopen(zName, "rb"); + FILE *f = cli_fopen(zName, "rb"); size_t n; int rc = SHELL_OPEN_UNSPEC; char zBuf[100]; @@ -5313,7 +5340,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ unsigned int x[16]; char zLine[1000]; if( zDbFilename ){ - in = fopen(zDbFilename, "r"); + in = cli_fopen(zDbFilename, "r"); if( in==0 ){ eputf("cannot open \"%s\" for reading\n", zDbFilename); return 0; @@ -5800,7 +5827,7 @@ static FILE *output_file_open(const char *zFile, int bTextMode){ }else if( cli_strcmp(zFile, "off")==0 ){ f = 0; }else{ - f = fopen(zFile, bTextMode ? "w" : "wb"); + f = cli_fopen(zFile, bTextMode ? "w" : "wb"); if( f==0 ){ eputf("Error: cannot open \"%s\"\n", zFile); } @@ -9029,7 +9056,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sCtx.xCloser = pclose; #endif }else{ - sCtx.in = fopen(sCtx.zFile, "rb"); + sCtx.in = cli_fopen(sCtx.zFile, "rb"); sCtx.xCloser = fclose; } if( sCtx.in==0 ){ @@ -9358,7 +9385,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3IoTrace = iotracePrintf; iotrace = stdout; }else{ - iotrace = fopen(azArg[1], "w"); + iotrace = cli_fopen(azArg[1], "w"); if( iotrace==0 ){ eputf("Error: cannot open \"%s\"\n", azArg[1]); sqlite3IoTrace = 0; @@ -10327,7 +10354,7 @@ static int do_meta_command(char *zLine, ShellState *p){ failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]); if( nCmd!=2 ) goto session_syntax_error; if( pSession->p==0 ) goto session_not_open; - out = fopen(azCmd[1], "wb"); + out = cli_fopen(azCmd[1], "wb"); if( out==0 ){ eputf("ERROR: cannot open \"%s\" for writing\n", azCmd[1]); @@ -12267,7 +12294,7 @@ static void process_sqliterc( shell_check_oom(zBuf); sqliterc = zBuf; } - p->in = fopen(sqliterc,"rb"); + p->in = cli_fopen(sqliterc,"rb"); if( p->in ){ if( stdin_is_interactive ){ eputf("-- Loading resources from %s\n", sqliterc); From 57b32ef924850824ce120987e7d9e2306bf254f1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 13:46:32 +0000 Subject: [PATCH 04/25] Add the sqlite3_stdio.h library for Windows console I/O. FossilOrigin-Name: fcd0ecffc9889f8c855ea340f075ec42cdca482df82d6e67dc9c32613e8d5846 --- Makefile.in | 2 + Makefile.msc | 2 + ext/misc/sqlite3_stdio.c | 157 +++++++++++++++++++++++++++++ ext/misc/sqlite3_stdio.h | 52 ++++++++++ main.mk | 2 + manifest | 20 ++-- manifest.uuid | 2 +- src/shell.c.in | 211 ++++++++------------------------------- 8 files changed, 266 insertions(+), 182 deletions(-) create mode 100644 ext/misc/sqlite3_stdio.c create mode 100644 ext/misc/sqlite3_stdio.h diff --git a/Makefile.in b/Makefile.in index 7b693b5225..5abe3bf6d3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1206,6 +1206,8 @@ SHELL_DEP = \ $(TOP)/ext/misc/sha1.c \ $(TOP)/ext/misc/shathree.c \ $(TOP)/ext/misc/sqlar.c \ + $(TOP)/ext/misc/sqlite3_stdio.c \ + $(TOP)/ext/misc/sqlite3_stdio.h \ $(TOP)/ext/misc/uint.c \ $(TOP)/ext/misc/vfstrace.c \ $(TOP)/ext/misc/zipfile.c \ diff --git a/Makefile.msc b/Makefile.msc index bb63601518..be6a771639 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2335,6 +2335,8 @@ SHELL_DEP = \ $(TOP)\ext\misc\sha1.c \ $(TOP)\ext\misc\shathree.c \ $(TOP)\ext\misc\sqlar.c \ + $(TOP)\ext\misc\sqlite3_stdio.c \ + $(TOP)\ext\misc\sqlite3_stdio.h \ $(TOP)\ext\misc\uint.c \ $(TOP)\ext\misc\vfstrace.c \ $(TOP)\ext\misc\zipfile.c \ diff --git a/ext/misc/sqlite3_stdio.c b/ext/misc/sqlite3_stdio.c new file mode 100644 index 0000000000..0cfa26673a --- /dev/null +++ b/ext/misc/sqlite3_stdio.c @@ -0,0 +1,157 @@ +/* +** 2024-09-24 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** Implementation of standard I/O interfaces for UTF-8 that are missing +** on Windows. +*/ +#ifdef _WIN32 /* This file is a no-op on all platforms except Windows */ + +/* +** Work-alike for the fopen() routine from the standard C library. +*/ +FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ + FILE *fp = 0; + wchar_t *b1, *b2; + int sz1, sz2; + + sz1 = (int)strlen(zFilename); + sz2 = (int)strlen(zMode); + b1 = malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + if( b1 && b2 ){ + sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); + b1[sz1] = 0; + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); + b2[sz2] = 0; + fp = _wfopen(b1, b2); + } + free(b1); + free(b2); + return fp; +} + + +/* +** Work-alike for the popen() routine from the standard C library. +*/ +FILE *sqlite3_popen(const char *zCommand, const char *zMode){ + FILE *fp = 0; + wchar_t *b1, *b2; + int sz1, sz2; + + sz1 = (int)strlen(zCommand); + sz2 = (int)strlen(zMode); + b1 = malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + if( b1 && b2 ){ + sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1); + b1[sz1] = 0; + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); + b2[sz2] = 0; + fp = _wpopen(b1, b2); + } + free(b1); + free(b2); + return fp; +} + +/* +** Work-alike for fgets() from the standard C library. +*/ +char *sqlite3_fgets(char *buf, int sz, FILE *in){ + if( isatty(_fileno(in)) ){ + /* When reading from the command-prompt in Windows, it is necessary + ** to use _O_WTEXT input mode to read UTF-16 characters, then translate + ** that into UTF-8. Otherwise, non-ASCII characters all get translated + ** into '?'. + */ + wchar_t *b1 = malloc( sz*sizeof(wchar_t) ); + if( b1==0 ) return 0; + _setmode(_fileno(in), _O_WTEXT); + if( fgetws(b1, sz/4, in)==0 ){ + sqlite3_free(b1); + return 0; + } + WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0); + sqlite3_free(b1); + return buf; + }else{ + /* Reading from a file or other input source, just read bytes without + ** any translation. */ + return fgets(buf, sz, in); + } +} + +/* +** Work-alike for fputs() from the standard C library. +*/ +int sqlite3_fputs(const char *z, FILE *out){ + if( isatty(_fileno(out)) ){ + /* When writing to the command-prompt in Windows, it is necessary + ** to use _O_WTEXT input mode and write UTF-16 characters. + */ + int sz = (int)strlen(z); + wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) ); + if( b1==0 ) return 0; + sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); + b1[sz] = 0; + _setmode(_fileno(out), _O_WTEXT); + fputws(b1, out); + sqlite3_free(b1); + return 0; + }else{ + /* Writing to a file or other destination, just write bytes without + ** any translation. */ + return fputs(z, out); + } +} + + +/* +** Work-alike for fprintf() from the standard C library. +*/ +int sqlite3_fprintf(FILE *out, const char *zFormat, ...){ + int rc; + if( isatty(fileno(out)) ){ + /* When writing to the command-prompt in Windows, it is necessary + ** to use _O_WTEXT input mode and write UTF-16 characters. + */ + char *z; + va_list ap; + + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + sqlite3_fputs(z, out); + rc = (int)strlen(z); + sqlite3_free(z); + }else{ + /* Writing to a file or other destination, just write bytes without + ** any translation. */ + va_list ap; + va_start(ap, zFormat); + rc = vfprintf(out, zFormat, ap); + va_end(ap); + } + return rc; +} + +/* +** Set the mode for a stream. mode argument is typically _O_BINARY or +** _O_TEXT. +*/ +void sqlite3_fsetmode(FILE *fp, int mode){ + fflush(fp); + _setmode(_fileno(fp), mode); +} + +#endif /* defined(_WIN32) */ diff --git a/ext/misc/sqlite3_stdio.h b/ext/misc/sqlite3_stdio.h new file mode 100644 index 0000000000..3014c1b287 --- /dev/null +++ b/ext/misc/sqlite3_stdio.h @@ -0,0 +1,52 @@ +/* +** 2024-09-24 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This header file contains definitions of interfaces that provide +** cross-platform I/O for UTF-8 content. +** +** On most platforms, the interfaces definitions in this file are +** just #defines. For example sqlite3_fopen() is a macro that resolves +** to the standard fopen() in the C-library. +** +** But Windows does not have a standard C-library, at least not one that +** can handle UTF-8. So for windows build, the interfaces resolve to new +** C-language routines contained in the separate sqlite3_stdio.c source file. +** +** So on all non-Windows platforms, simply #include this header file and +** use the interfaces defined herein. Then to run your application on Windows, +** also link in the accompanying sqlite3_stdio.c source file when compiling +** to get compatible interfaces. +*/ +#ifdef _WIN32 +/**** Definitions For Windows ****/ +#include +#include + +FILE *sqlite3_fopen(const char *zFilename, const char *zMode); +FILE *sqlite3_popen(const char *zCommand, const char *type); +char *sqlite3_fgets(char *s, int size, FILE *stream); +int sqlite3_fputs(const char *s, FILE *stream); +int sqlite3_fprintf(FILE *stream, const char *format, ...); +void sqlite3_fsetmode(FILE *stream, int mode); + + +#else +/**** Definitions For All Other Platforms ****/ +#include +#define sqlite3_fopen fopen +#define sqlite3_popen popen +#define sqlite3_fgets fgets +#define sqlite3_fputs fputs +#define sqlite3_fprintf fprintf +#define sqlite3_fsetmode(F,X) /*no-op*/ + +#endif diff --git a/main.mk b/main.mk index 8aaa7e7d06..2d616a6167 100644 --- a/main.mk +++ b/main.mk @@ -782,6 +782,8 @@ SHELL_DEP = \ $(TOP)/ext/misc/sha1.c \ $(TOP)/ext/misc/shathree.c \ $(TOP)/ext/misc/sqlar.c \ + $(TOP)/ext/misc/sqlite3_stdio.c \ + $(TOP)/ext/misc/sqlite3_stdio.h \ $(TOP)/ext/misc/uint.c \ $(TOP)/ext/misc/vfstrace.c \ $(TOP)/ext/misc/zipfile.c \ diff --git a/manifest b/manifest index 6c38834512..b88e6beea1 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Use\s_wfopen()\sinstead\sof\sfopen()\son\sWindows\sin\sthe\sCLI. -D 2024-09-24T10:30:07.376 +C Add\sthe\ssqlite3_stdio.h\slibrary\sfor\sWindows\sconsole\sI/O. +D 2024-09-24T13:46:32.112 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in aa594119c3c7f699e87a767fca6598452f77d4c32c41a6486c40d4f156d4efc1 +F Makefile.in a8e1d44a1166b6fb368effb19edc9adf7fede9225e9563352b9bb1989cd0150d F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 -F Makefile.msc add7e29bae33ad5b8c464daf6de84a1a01e31e6337d79fb0c1062e53fa7657da +F Makefile.msc 1a5234794c9a5a71ba13fb47bcf031814d45b3ed6a56b4cb8e9f63fd32b4febe F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -425,6 +425,8 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 +F ext/misc/sqlite3_stdio.c 4d4190eac193a8ea8fc3f8259e0996cf8e54254b4f4925d71e456e88165401d8 +F ext/misc/sqlite3_stdio.h ddefddeb448eee7fe2d41a828356a0019f813a4ced4ea2e97faa1d6c3e803742 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc F ext/misc/templatevtab.c 10f15b165b95423ddef593bc5dcb915ec4eb5e0f1066d585e5435a368b8bc22b @@ -687,7 +689,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk b897586c0c7b77b7e39f0a0e9ed79fed7346b09af1ed35a08da745e02b795772 +F main.mk dcb5cbba0ad64bd639b3e05d73d92e27c144a55bab9fca3460699602f4e9f4c2 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -768,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c b2cd748488012312824508639b6af908461e45403037d5c4e19d9b0e8195507f F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 95f1bdfb9b1d513c7d82ab04fbca746a9668fb02d3eb984cd1cfb3b4ffc413e0 +F src/shell.c.in a4dd977ee3c5a80793121979ec0adf5332a63c4b5314cf1816720b228389bc99 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2213,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 33950a8c3f3e48e5107fe56647da05147aa84f9c3eccbe7c8671f5b502ebb70b -R 563de058a2a6970ab738b542c7a8c099 +P 21a8cac5e9a0d5ead29ca1114be7520d182348f7e2e2e2416852b827d7e09f21 +R 5d809f396de7819d09230f46e082352b U drh -Z 3b9fb03668dcca40431939db5346d2bc +Z 615e3829254cd5f44a2bd3c1963a47dc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a3d44399a6..11300e9220 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -21a8cac5e9a0d5ead29ca1114be7520d182348f7e2e2e2416852b827d7e09f21 +fcd0ecffc9889f8c855ea340f075ec42cdca482df82d6e67dc9c32613e8d5846 diff --git a/src/shell.c.in b/src/shell.c.in index 5677e060f7..e28bb4910f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -192,8 +192,6 @@ typedef unsigned char u8; # ifndef strdup # define strdup _strdup # endif -# undef popen -# define popen _popen # undef pclose # define pclose _pclose # endif @@ -237,139 +235,8 @@ extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); #endif -#ifdef _WIN32 -/* On Windows, we normally run with output mode of TEXT so that \n characters -** are automatically translated into \r\n. However, this behavior needs -** to be disabled in some cases (ex: when generating CSV output and when -** rendering quoted strings that contain \n characters). The following -** routines take care of that. -*/ -static void setBinaryMode(FILE *file, int isOutput){ - if( isOutput ) fflush(file); - _setmode(_fileno(file), _O_BINARY); -} -static void setTextMode(FILE *file, int isOutput){ - if( isOutput ) fflush(file); - _setmode(_fileno(file), _O_TEXT); -} -#else - /* Unix equivalents to set*Mode() */ -# define setBinaryMode(X,Y) -# define setTextMode(X,Y) -#endif - -#ifdef _WIN32 -/* fgets() for windows */ -static char *cli_fgets(char *buf, int sz, FILE *in){ - if( isatty(_fileno(in)) ){ - /* When reading from the command-prompt in Windows, it is necessary - ** to use _O_WTEXT input mode to read UTF-16 characters, then translate - ** that into UTF-8. Otherwise, non-ASCII characters all get translated - ** into '?'. - */ - wchar_t *b1 = malloc( sz*sizeof(wchar_t) ); - if( b1==0 ) return 0; - _setmode(_fileno(in), _O_WTEXT); - if( fgetws(b1, sz/4, in)==0 ){ - sqlite3_free(b1); - return 0; - } - WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0); - sqlite3_free(b1); - return buf; - }else{ - /* Reading from a file or other input source, just read bytes without - ** any translation. */ - return fgets(buf, sz, in); - } -} -#else -/* library version works for everybody else */ -# define cli_fgets fgets -#endif - -#ifdef _WIN32 -/* fputs() for windows */ -static int cli_fputs(const char *z, FILE *out){ - if( isatty(_fileno(out)) ){ - /* When writing to the command-prompt in Windows, it is necessary - ** to use _O_WTEXT input mode and write UTF-16 characters. - */ - int sz = (int)strlen(z); - wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) ); - if( b1==0 ) return 0; - sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); - b1[sz] = 0; - _setmode(_fileno(out), _O_WTEXT); - fputws(b1, out); - sqlite3_free(b1); - return 0; - }else{ - /* Writing to a file or other destination, just write bytes without - ** any translation. */ - return fputs(z, out); - } -} -#else -/* library version works for everybody else */ -# define cli_fputs fputs -#endif - -#ifdef _WIN32 -/* fprintf() for windows */ -static void cli_fprintf(FILE *out, const char *zFormat, ...){ - if( isatty(fileno(out)) ){ - /* When writing to the command-prompt in Windows, it is necessary - ** to use _O_WTEXT input mode and write UTF-16 characters. - */ - char *z; - va_list ap; - - va_start(ap, zFormat); - z = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - cli_fputs(z, out); - sqlite3_free(z); - }else{ - /* Writing to a file or other destination, just write bytes without - ** any translation. */ - va_list ap; - va_start(ap, zFormat); - vfprintf(out, zFormat, ap); - va_end(ap); - } -} -#else -/* library version works for everybody else */ -# define cli_fprintf fprintf -#endif - -#ifdef _WIN32 -/* fopen() for windows */ -static FILE *cli_fopen(const char *zFilename, const char *zMode){ - FILE *fp = 0; - wchar_t *b1, *b2; - int sz1, sz2; - - sz1 = (int)strlen(zFilename); - sz2 = (int)strlen(zMode); - b1 = malloc( (sz1+1)*sizeof(b1[0]) ); - b2 = malloc( (sz2+1)*sizeof(b1[0]) ); - if( b1 && b2 ){ - sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); - b1[sz1] = 0; - sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); - b2[sz2] = 0; - fp = _wfopen(b1, b2); - } - free(b1); - free(b2); - return fp; -} -#else -/* library version works for everybody else */ -# define cli_fopen fopen -#endif +INCLUDE ../ext/misc/sqlite3_stdio.h +INCLUDE ../ext/misc/sqlite3_stdio.c /* Use console I/O package as a direct INCLUDE. */ #define SQLITE_INTERNAL_LINKAGE static @@ -383,13 +250,13 @@ static FILE *cli_fopen(const char *zFilename, const char *zMode){ # define SQLITE_CIO_NO_FLUSH #endif -#define oputf(fmt, ...) cli_fprintf(stdout,fmt,__VA_ARGS__) -#define eputf(fmt, ...) cli_fprintf(stderr,fmt,__VA_ARGS__) -#define sputf(fp,fmt, ...) cli_fprintf(fp,fmt,__VA_ARGS__) +#define oputf(fmt, ...) sqlite3_fprintf(stdout,fmt,__VA_ARGS__) +#define eputf(fmt, ...) sqlite3_fprintf(stderr,fmt,__VA_ARGS__) +#define sputf(fp,fmt, ...) sqlite3_fprintf(fp,fmt,__VA_ARGS__) /* These next 3 macros are for emitting simple string literals. */ -#define oputz(z) cli_fputs(z,stdout) -#define eputz(z) cli_fputs(z,stderr) -#define sputz(fp,z) cli_fputs(z,fp) +#define oputz(z) sqlite3_fputs(z,stdout) +#define eputz(z) sqlite3_fputs(z,stderr) +#define sputz(fp,z) sqlite3_fputs(z,fp) #define oputb(buf,na) fwrite(buf,1,na,stdout) /* True if the timer is enabled */ @@ -854,7 +721,7 @@ static FILE * openChrSource(const char *zFile){ /* On Windows, open first, then check the stream nature. This order ** is necessary because _stat() and sibs, when checking a named pipe, ** effectively break the pipe as its supplier sees it. */ - FILE *rv = cli_fopen(zFile, "rb"); + FILE *rv = sqlite3_fopen(zFile, "rb"); if( rv==0 ) return 0; if( _fstat64(_fileno(rv), &x) != 0 || !STAT_CHR_SRC(x.st_mode)){ @@ -868,7 +735,7 @@ static FILE * openChrSource(const char *zFile){ # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) if( rc!=0 ) return 0; if( STAT_CHR_SRC(x.st_mode) ){ - return cli_fopen(zFile, "rb"); + return sqlite3_fopen(zFile, "rb"); }else{ return 0; } @@ -895,7 +762,7 @@ static char *local_getline(char *zLine, FILE *in){ zLine = realloc(zLine, nLine); shell_check_oom(zLine); } - if( cli_fgets(&zLine[n], nLine - n, in)==0 ){ + if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){ if( n==0 ){ free(zLine); return 0; @@ -1708,7 +1575,7 @@ static void editFunc( bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; /* When writing the file to be edited, do \n to \r\n conversions on systems ** that want \r\n line endings */ - f = cli_fopen(zTempFile, bBin ? "wb" : "w"); + f = sqlite3_fopen(zTempFile, bBin ? "wb" : "w"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot open temp file", -1); goto edit_func_end; @@ -1739,7 +1606,7 @@ static void editFunc( sqlite3_result_error(context, "EDITOR returned non-zero", -1); goto edit_func_end; } - f = cli_fopen(zTempFile, "rb"); + f = sqlite3_fopen(zTempFile, "rb"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot reopen temp file after edit", -1); @@ -1859,7 +1726,7 @@ static const char *unused_string( static void output_quoted_string(const char *z){ int i; char c; - setBinaryMode(stdout, 1); + sqlite3_fsetmode(stdout, _O_BINARY); if( z==0 ) return; for(i=0; (c = z[i])!=0 && c!='\''; i++){} if( c==0 ){ @@ -1884,7 +1751,7 @@ static void output_quoted_string(const char *z){ } oputz("'"); } - setTextMode(stdout, 1); + sqlite3_fsetmode(stdout, _O_TEXT); } /* @@ -1899,7 +1766,7 @@ static void output_quoted_string(const char *z){ static void output_quoted_escaped_string(const char *z){ int i; char c; - setBinaryMode(stdout, 1); + sqlite3_fsetmode(stdout, _O_BINARY); for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} if( c==0 ){ oputf("'%s'",z); @@ -1951,7 +1818,7 @@ static void output_quoted_escaped_string(const char *z){ oputf(",'%s',char(10))", zNL); } } - setTextMode(stdout, 1); + sqlite3_fsetmode(stdout, _O_TEXT); } /* @@ -2722,7 +2589,7 @@ static int shell_callback( break; } case MODE_Csv: { - setBinaryMode(p->out, 1); + sqlite3_fsetmode(p->out, _O_BINARY); if( p->cnt++==0 && p->showHeader ){ for(i=0; irowSeparator); } - setTextMode(p->out, 1); + sqlite3_fsetmode(p->out, _O_TEXT); break; } case MODE_Insert: { @@ -3140,9 +3007,9 @@ static void displayLinuxIoStats(void){ FILE *in; char z[200]; sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); - in = cli_fopen(z, "rb"); + in = sqlite3_fopen(z, "rb"); if( in==0 ) return; - while( cli_fgets(z, sizeof(z), in)!=0 ){ + while( sqlite3_fgets(z, sizeof(z), in)!=0 ){ static const struct { const char *zPattern; const char *zDesc; @@ -5197,7 +5064,7 @@ static int process_input(ShellState *p); ** is undefined in this case. */ static char *readFile(const char *zName, int *pnByte){ - FILE *in = cli_fopen(zName, "rb"); + FILE *in = sqlite3_fopen(zName, "rb"); long nIn; size_t nRead; char *pBuf; @@ -5287,7 +5154,7 @@ static int session_filter(void *pCtx, const char *zTab){ ** the type cannot be determined from content. */ int deduceDatabaseType(const char *zName, int dfltZip){ - FILE *f = cli_fopen(zName, "rb"); + FILE *f = sqlite3_fopen(zName, "rb"); size_t n; int rc = SHELL_OPEN_UNSPEC; char zBuf[100]; @@ -5340,7 +5207,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ unsigned int x[16]; char zLine[1000]; if( zDbFilename ){ - in = cli_fopen(zDbFilename, "r"); + in = sqlite3_fopen(zDbFilename, "r"); if( in==0 ){ eputf("cannot open \"%s\" for reading\n", zDbFilename); return 0; @@ -5353,7 +5220,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ } *pnData = 0; nLine++; - if( cli_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; + if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) goto readHexDb_error; if( n<0 ) goto readHexDb_error; @@ -5366,7 +5233,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ eputz("invalid pagesize\n"); goto readHexDb_error; } - for(nLine++; cli_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ + for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ rc = sscanf(zLine, "| page %d offset %d", &j, &k); if( rc==2 ){ iOffset = k; @@ -5398,7 +5265,7 @@ readHexDb_error: if( in!=p->in ){ fclose(in); }else{ - while( cli_fgets(zLine, sizeof(zLine), p->in)!=0 ){ + while( sqlite3_fgets(zLine, sizeof(zLine), p->in)!=0 ){ nLine++; if(cli_strncmp(zLine, "| end ", 6)==0 ) break; } @@ -5827,7 +5694,7 @@ static FILE *output_file_open(const char *zFile, int bTextMode){ }else if( cli_strcmp(zFile, "off")==0 ){ f = 0; }else{ - f = cli_fopen(zFile, bTextMode ? "w" : "wb"); + f = sqlite3_fopen(zFile, bTextMode ? "w" : "wb"); if( f==0 ){ eputf("Error: cannot open \"%s\"\n", zFile); } @@ -8287,9 +8154,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){ if( nArg==2 ){ if( booleanValue(azArg[1]) ){ - setBinaryMode(p->out, 1); + sqlite3_fsetmode(p->out, _O_BINARY); }else{ - setTextMode(p->out, 1); + sqlite3_fsetmode(p->out, _O_TEXT); } }else{ eputz("The \".binary\" command is deprecated. Use \".crnl\" instead.\n" @@ -8422,9 +8289,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='c' && n==4 && cli_strncmp(azArg[0], "crnl", n)==0 ){ if( nArg==2 ){ if( booleanValue(azArg[1]) ){ - setTextMode(p->out, 1); + sqlite3_fsetmode(p->out, _O_TEXT); }else{ - setBinaryMode(p->out, 1); + sqlite3_fsetmode(p->out, _O_BINARY); } }else{ #if !defined(_WIN32) && !defined(WIN32) @@ -9051,12 +8918,12 @@ static int do_meta_command(char *zLine, ShellState *p){ eputz("Error: pipes are not supported in this OS\n"); goto meta_command_exit; #else - sCtx.in = popen(sCtx.zFile+1, "r"); + sCtx.in = sqlite3_popen(sCtx.zFile+1, "r"); sCtx.zFile = ""; sCtx.xCloser = pclose; #endif }else{ - sCtx.in = cli_fopen(sCtx.zFile, "rb"); + sCtx.in = sqlite3_fopen(sCtx.zFile, "rb"); sCtx.xCloser = fclose; } if( sCtx.in==0 ){ @@ -9385,7 +9252,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3IoTrace = iotracePrintf; iotrace = stdout; }else{ - iotrace = cli_fopen(azArg[1], "w"); + iotrace = sqlite3_fopen(azArg[1], "w"); if( iotrace==0 ){ eputf("Error: cannot open \"%s\"\n", azArg[1]); sqlite3IoTrace = 0; @@ -9832,7 +9699,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; output_redir(p, stdout); #else - FILE *pfPipe = popen(zFile + 1, "w"); + FILE *pfPipe = sqlite3_popen(zFile + 1, "w"); if( pfPipe==0 ){ eputf("Error: cannot open pipe \"%s\"\n", zFile + 1); rc = 1; @@ -10049,7 +9916,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; p->out = stdout; #else - p->in = popen(azArg[1]+1, "r"); + p->in = sqlite3_popen(azArg[1]+1, "r"); if( p->in==0 ){ eputf("Error: cannot open \"%s\"\n", azArg[1]); rc = 1; @@ -10354,7 +10221,7 @@ static int do_meta_command(char *zLine, ShellState *p){ failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]); if( nCmd!=2 ) goto session_syntax_error; if( pSession->p==0 ) goto session_not_open; - out = cli_fopen(azCmd[1], "wb"); + out = sqlite3_fopen(azCmd[1], "wb"); if( out==0 ){ eputf("ERROR: cannot open \"%s\" for writing\n", azCmd[1]); @@ -12294,7 +12161,7 @@ static void process_sqliterc( shell_check_oom(zBuf); sqliterc = zBuf; } - p->in = cli_fopen(sqliterc,"rb"); + p->in = sqlite3_fopen(sqliterc,"rb"); if( p->in ){ if( stdin_is_interactive ){ eputf("-- Loading resources from %s\n", sqliterc); From 0be2dd9a1bb0615661f8d7ef98805b52955e32de Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 16:09:50 +0000 Subject: [PATCH 05/25] Get output redirection working again in the CLI. FossilOrigin-Name: 086034c3508d95e4f620c5e0580fae770e85410b0c8bd94f600fc0fd25088947 --- manifest | 12 +- manifest.uuid | 2 +- src/shell.c.in | 934 ++++++++++++++++++++++++++----------------------- 3 files changed, 498 insertions(+), 450 deletions(-) diff --git a/manifest b/manifest index b88e6beea1..5e7518fc0c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_stdio.h\slibrary\sfor\sWindows\sconsole\sI/O. -D 2024-09-24T13:46:32.112 +C Get\soutput\sredirection\sworking\sagain\sin\sthe\sCLI. +D 2024-09-24T16:09:50.466 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c b2cd748488012312824508639b6af908461e45403037d5c4e19d9b0e8195507f F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in a4dd977ee3c5a80793121979ec0adf5332a63c4b5314cf1816720b228389bc99 +F src/shell.c.in b3b0aed1b1050da8d70734b1a4bdc4a4679a73f37b2593f276e5a5f71a6fca2a F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 21a8cac5e9a0d5ead29ca1114be7520d182348f7e2e2e2416852b827d7e09f21 -R 5d809f396de7819d09230f46e082352b +P fcd0ecffc9889f8c855ea340f075ec42cdca482df82d6e67dc9c32613e8d5846 +R bfd2b7dbaf4f82e5e4b17d1ed0ea1a8f U drh -Z 615e3829254cd5f44a2bd3c1963a47dc +Z 5097f278634497c50b8747316810c634 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 11300e9220..ad785fcbcd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fcd0ecffc9889f8c855ea340f075ec42cdca482df82d6e67dc9c32613e8d5846 +086034c3508d95e4f620c5e0580fae770e85410b0c8bd94f600fc0fd25088947 diff --git a/src/shell.c.in b/src/shell.c.in index e28bb4910f..4c2ca65d83 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -250,14 +250,9 @@ INCLUDE ../ext/misc/sqlite3_stdio.c # define SQLITE_CIO_NO_FLUSH #endif -#define oputf(fmt, ...) sqlite3_fprintf(stdout,fmt,__VA_ARGS__) #define eputf(fmt, ...) sqlite3_fprintf(stderr,fmt,__VA_ARGS__) -#define sputf(fp,fmt, ...) sqlite3_fprintf(fp,fmt,__VA_ARGS__) -/* These next 3 macros are for emitting simple string literals. */ -#define oputz(z) sqlite3_fputs(z,stdout) #define eputz(z) sqlite3_fputs(z,stderr) #define sputz(fp,z) sqlite3_fputs(z,fp) -#define oputb(buf,na) fwrite(buf,1,na,stdout) /* True if the timer is enabled */ static int enableTimer = 0; @@ -332,7 +327,7 @@ static void endTimer(void){ sqlite3_int64 iEnd = timeOfDay(); struct rusage sEnd; getrusage(RUSAGE_SELF, &sEnd); - sputf(stdout, "Run Time: real %.3f user %f sys %f\n", + sqlite3_fprintf(stdout, "Run Time: real %.3f user %f sys %f\n", (iEnd - iBegin)*0.001, timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); @@ -411,7 +406,7 @@ static void endTimer(void){ FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; sqlite3_int64 ftWallEnd = timeOfDay(); getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); - sputf(stdout, "Run Time: real %.3f user %f sys %f\n", + sqlite3_fprintf(stdout, "Run Time: real %.3f user %f sys %f\n", (ftWallEnd - ftWallBegin)*0.001, timeDiff(&ftUserBegin, &ftUserEnd), timeDiff(&ftKernelBegin, &ftKernelEnd)); @@ -625,7 +620,7 @@ static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); va_end(ap); - sputf(iotrace, "%s", z); + sqlite3_fprintf(iotrace, "%s", z); sqlite3_free(z); } #endif @@ -636,7 +631,7 @@ static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ ** in bytes. This is different from the %*.*s specification in printf ** since with %*.*s the width is measured in bytes, not characters. */ -static void utf8_width_print(int w, const char *zUtf){ +static void utf8_width_print(FILE *out, int w, const char *zUtf){ int i; int n; int aw = w<0 ? -w : w; @@ -651,11 +646,11 @@ static void utf8_width_print(int w, const char *zUtf){ } } if( n>=aw ){ - oputf("%.*s", i, zUtf); + sqlite3_fprintf(out, "%.*s", i, zUtf); }else if( w<0 ){ - oputf("%*s%s", aw-n, "", zUtf); + sqlite3_fprintf(out, "%*s%s", aw-n, "", zUtf); }else{ - oputf("%s%*s", zUtf, aw-n, ""); + sqlite3_fprintf(out, "%s%*s", zUtf, aw-n, ""); } } @@ -1472,7 +1467,7 @@ static const char *modeDescr[] = { static void shellLog(void *pArg, int iErrCode, const char *zMsg){ ShellState *p = (ShellState*)pArg; if( p->pLog==0 ) return; - sputf(p->pLog, "(%d) %s\n", iErrCode, zMsg); + sqlite3_fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); fflush(p->pLog); } @@ -1487,9 +1482,9 @@ static void shellPutsFunc( int nVal, sqlite3_value **apVal ){ - /* Unused: (ShellState*)sqlite3_user_data(pCtx); */ + ShellState *p = (ShellState*)sqlite3_user_data(pCtx); (void)nVal; - oputf("%s\n", sqlite3_value_text(apVal[0])); + sqlite3_fprintf(p->out, "%s\n", sqlite3_value_text(apVal[0])); sqlite3_result_value(pCtx, apVal[0]); } @@ -1676,7 +1671,7 @@ static void outputModePop(ShellState *p){ /* ** Output the given string as a hex-encoded blob (eg. X'1234' ) */ -static void output_hex_blob(const void *pBlob, int nBlob){ +static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ int i; unsigned char *aBlob = (unsigned char*)pBlob; @@ -1693,7 +1688,7 @@ static void output_hex_blob(const void *pBlob, int nBlob){ } zStr[i*2] = '\0'; - oputf("X'%s'", zStr); + sqlite3_fprintf(out, "X'%s'", zStr); sqlite3_free(zStr); } @@ -1723,25 +1718,25 @@ static const char *unused_string( ** ** See also: output_quoted_escaped_string() */ -static void output_quoted_string(const char *z){ +static void output_quoted_string(FILE *out, const char *z){ int i; char c; - sqlite3_fsetmode(stdout, _O_BINARY); + sqlite3_fsetmode(out, _O_BINARY); if( z==0 ) return; for(i=0; (c = z[i])!=0 && c!='\''; i++){} if( c==0 ){ - oputf("'%s'",z); + sqlite3_fprintf(out, "'%s'",z); }else{ - oputz("'"); + sqlite3_fputs("'", out); while( *z ){ for(i=0; (c = z[i])!=0 && c!='\''; i++){} if( c=='\'' ) i++; if( i ){ - oputf("%.*s", i, z); + sqlite3_fprintf(out, "%.*s", i, z); z += i; } if( c=='\'' ){ - oputz("'"); + sqlite3_fputs("'", out); continue; } if( c==0 ){ @@ -1749,9 +1744,9 @@ static void output_quoted_string(const char *z){ } z++; } - oputz("'"); + sqlite3_fputs("'", out); } - sqlite3_fsetmode(stdout, _O_TEXT); + sqlite3_fsetmode(out, _O_TEXT); } /* @@ -1763,13 +1758,13 @@ static void output_quoted_string(const char *z){ ** This is like output_quoted_string() but with the addition of the \r\n ** escape mechanism. */ -static void output_quoted_escaped_string(const char *z){ +static void output_quoted_escaped_string(FILE *out, const char *z){ int i; char c; - sqlite3_fsetmode(stdout, _O_BINARY); + sqlite3_fsetmode(out, _O_BINARY); for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} if( c==0 ){ - oputf("'%s'",z); + sqlite3_fprintf(out, "'%s'",z); }else{ const char *zNL = 0; const char *zCR = 0; @@ -1781,23 +1776,23 @@ static void output_quoted_escaped_string(const char *z){ if( z[i]=='\r' ) nCR++; } if( nNL ){ - oputz("replace("); + sqlite3_fputs("replace(", out); zNL = unused_string(z, "\\n", "\\012", zBuf1); } if( nCR ){ - oputz("replace("); + sqlite3_fputs("replace(", out); zCR = unused_string(z, "\\r", "\\015", zBuf2); } - oputz("'"); + sqlite3_fputs("'", out); while( *z ){ for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} if( c=='\'' ) i++; if( i ){ - oputf("%.*s", i, z); + sqlite3_fprintf(out, "%.*s", i, z); z += i; } if( c=='\'' ){ - oputz("'"); + sqlite3_fputs("'", out); continue; } if( c==0 ){ @@ -1805,17 +1800,17 @@ static void output_quoted_escaped_string(const char *z){ } z++; if( c=='\n' ){ - oputz(zNL); + sqlite3_fputs(zNL, out); continue; } - oputz(zCR); + sqlite3_fputs(zCR, out); } - oputz("'"); + sqlite3_fputs("'", out); if( nCR ){ - oputf(",'%s',char(13))", zCR); + sqlite3_fprintf(out, ",'%s',char(13))", zCR); } if( nNL ){ - oputf(",'%s',char(10))", zNL); + sqlite3_fprintf(out, ",'%s',char(10))", zNL); } } sqlite3_fsetmode(stdout, _O_TEXT); @@ -1877,19 +1872,21 @@ const char *zSkipValidUtf8(const char *z, int nAccept, long ccm){ /* ** Output the given string as a quoted according to C or TCL quoting rules. */ -static void output_c_string(const char *z){ +static void output_c_string(FILE *out, const char *z){ char c; static const char *zq = "\""; static long ctrlMask = ~0L; static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */ char ace[3] = "\\?"; char cbsSay; - oputz(zq); + sqlite3_fputs(zq, out); while( *z!=0 ){ const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0); const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask); const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast; - if( pcEnd > z ) oputb(z, (int)(pcEnd-z)); + if( pcEnd > z ){ + sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z); + } if( (c = *pcEnd)==0 ) break; ++pcEnd; switch( c ){ @@ -1904,22 +1901,22 @@ static void output_c_string(const char *z){ } if( cbsSay ){ ace[1] = cbsSay; - oputz(ace); + sqlite3_fputs(ace, out); }else if( !isprint(c&0xff) ){ - oputf("\\%03o", c&0xff); + sqlite3_fprintf(out, "\\%03o", c&0xff); }else{ ace[1] = (char)c; - oputz(ace+1); + sqlite3_fputs(ace+1, out); } z = pcEnd; } - oputz(zq); + sqlite3_fputs(zq, out); } /* ** Output the given string as a quoted according to JSON quoting rules. */ -static void output_json_string(const char *z, i64 n){ +static void output_json_string(FILE *out, const char *z, i64 n){ char c; static const char *zq = "\""; static long ctrlMask = ~0L; @@ -1930,13 +1927,13 @@ static void output_json_string(const char *z, i64 n){ if( z==0 ) z = ""; pcLimit = z + ((n<0)? strlen(z) : (size_t)n); - oputz(zq); + sqlite3_fputs(zq, out); while( z < pcLimit ){ const char *pcDQBS = anyOfInStr(z, zDQBS, pcLimit-z); const char *pcPast = zSkipValidUtf8(z, (int)(pcLimit-z), ctrlMask); const char *pcEnd = (pcDQBS && pcDQBS < pcPast)? pcDQBS : pcPast; if( pcEnd > z ){ - oputb(z, (int)(pcEnd-z)); + sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z); z = pcEnd; } if( z >= pcLimit ) break; @@ -1954,22 +1951,22 @@ static void output_json_string(const char *z, i64 n){ } if( cbsSay ){ ace[1] = cbsSay; - oputz(ace); + sqlite3_fputs(ace, out); }else if( c<=0x1f ){ - oputf("u%04x", c); + sqlite3_fprintf(out, "u%04x", c); }else{ ace[1] = (char)c; - oputz(ace+1); + sqlite3_fputs(ace+1, out); } } - oputz(zq); + sqlite3_fputs(zq, out); } /* ** Output the given string with characters that are special to ** HTML escaped. */ -static void output_html_string(const char *z){ +static void output_html_string(FILE *out, const char *z){ int i; if( z==0 ) z = ""; while( *z ){ @@ -1981,18 +1978,18 @@ static void output_html_string(const char *z){ && z[i]!='\''; i++){} if( i>0 ){ - oputf("%.*s",i,z); + sqlite3_fprintf(out, "%.*s",i,z); } if( z[i]=='<' ){ - oputz("<"); + sqlite3_fputs("<", out); }else if( z[i]=='&' ){ - oputz("&"); + sqlite3_fputs("&", out); }else if( z[i]=='>' ){ - oputz(">"); + sqlite3_fputs(">", out); }else if( z[i]=='\"' ){ - oputz("""); + sqlite3_fputs(""", out); }else if( z[i]=='\'' ){ - oputz("'"); + sqlite3_fputs("'", out); }else{ break; } @@ -2031,7 +2028,7 @@ static const char needCsvQuote[] = { */ static void output_csv(ShellState *p, const char *z, int bSep){ if( z==0 ){ - oputf("%s",p->nullValue); + sqlite3_fprintf(p->out, "%s",p->nullValue); }else{ unsigned i; for(i=0; z[i]; i++){ @@ -2043,14 +2040,14 @@ static void output_csv(ShellState *p, const char *z, int bSep){ if( i==0 || strstr(z, p->colSeparator)!=0 ){ char *zQuoted = sqlite3_mprintf("\"%w\"", z); shell_check_oom(zQuoted); - oputz(zQuoted); + sqlite3_fputs(zQuoted, p->out); sqlite3_free(zQuoted); }else{ - oputz(z); + sqlite3_fputs(z, p->out); } } if( bSep ){ - oputz(p->colSeparator); + sqlite3_fputs(p->colSeparator, p->out); } } @@ -2158,16 +2155,16 @@ static int shellAuth( az[1] = zA2; az[2] = zA3; az[3] = zA4; - oputf("authorizer: %s", azAction[op]); + sqlite3_fprintf(p->out, "authorizer: %s", azAction[op]); for(i=0; i<4; i++){ - oputz(" "); + sqlite3_fputs(" ", p->out); if( az[i] ){ - output_c_string(az[i]); + output_c_string(p->out, az[i]); }else{ - oputz("NULL"); + sqlite3_fputs("NULL", p->out); } } - oputz("\n"); + sqlite3_fputs("\n", p->out); if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4); return SQLITE_OK; } @@ -2183,7 +2180,7 @@ static int shellAuth( ** sqlite3_complete() returns false, try to terminate the comment before ** printing the result. https://sqlite.org/forum/forumpost/d7be961c5c */ -static void printSchemaLine(const char *z, const char *zTail){ +static void printSchemaLine(FILE *out, const char *z, const char *zTail){ char *zToFree = 0; if( z==0 ) return; if( zTail==0 ) return; @@ -2205,16 +2202,16 @@ static void printSchemaLine(const char *z, const char *zTail){ } } if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ - oputf("CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); + sqlite3_fprintf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); }else{ - oputf("%s%s", z, zTail); + sqlite3_fprintf(out, "%s%s", z, zTail); } sqlite3_free(zToFree); } -static void printSchemaLineN(char *z, int n, const char *zTail){ +static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ char c = z[n]; z[n] = 0; - printSchemaLine(z, zTail); + printSchemaLine(out, z, zTail); z[n] = c; } @@ -2242,7 +2239,7 @@ static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){ if( zText==0 ) return; nText = strlen(zText); if( p->autoEQPtest ){ - oputf("%d,%d,%s\n", iEqpId, p2, zText); + sqlite3_fprintf(p->out, "%d,%d,%s\n", iEqpId, p2, zText); } pNew = sqlite3_malloc64( sizeof(*pNew) + nText ); shell_check_oom(pNew); @@ -2290,7 +2287,8 @@ static void eqp_render_level(ShellState *p, int iEqpId){ for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ pNext = eqp_next_row(p, iEqpId, pRow); z = pRow->zText; - oputf("%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z); + sqlite3_fprintf(p->out, "%s%s%s\n", p->sGraph.zPrefix, + pNext ? "|--" : "`--", z); if( n<(i64)sizeof(p->sGraph.zPrefix)-7 ){ memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4); eqp_render_level(p, pRow->iEqpId); @@ -2310,13 +2308,13 @@ static void eqp_render(ShellState *p, i64 nCycle){ eqp_reset(p); return; } - oputf("%s\n", pRow->zText+3); + sqlite3_fprintf(p->out, "%s\n", pRow->zText+3); p->sGraph.pRow = pRow->pNext; sqlite3_free(pRow); }else if( nCycle>0 ){ - oputf("QUERY PLAN (cycles=%lld [100%%])\n", nCycle); + sqlite3_fprintf(p->out, "QUERY PLAN (cycles=%lld [100%%])\n", nCycle); }else{ - oputz("QUERY PLAN\n"); + sqlite3_fputs("QUERY PLAN\n", p->out); } p->sGraph.zPrefix[0] = 0; eqp_render_level(p, 0); @@ -2332,13 +2330,13 @@ static int progress_handler(void *pClientData) { ShellState *p = (ShellState*)pClientData; p->nProgress++; if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){ - oputf("Progress limit reached (%u)\n", p->nProgress); + sqlite3_fprintf(p->out, "Progress limit reached (%u)\n", p->nProgress); if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0; return 1; } if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){ - oputf("Progress %u\n", p->nProgress); + sqlite3_fprintf(p->out, "Progress %u\n", p->nProgress); } return 0; } @@ -2347,14 +2345,14 @@ static int progress_handler(void *pClientData) { /* ** Print N dashes */ -static void print_dashes(int N){ +static void print_dashes(FILE *out, int N){ const char zDash[] = "--------------------------------------------------"; const int nDash = sizeof(zDash) - 1; while( N>nDash ){ - oputz(zDash); + sqlite3_fputs(zDash, out); N -= nDash; } - oputf("%.*s", N, zDash); + sqlite3_fprintf(out, "%.*s", N, zDash); } /* @@ -2367,15 +2365,15 @@ static void print_row_separator( ){ int i; if( nArg>0 ){ - oputz(zSep); - print_dashes(p->actualWidth[0]+2); + sqlite3_fputs(zSep, p->out); + print_dashes(p->out, p->actualWidth[0]+2); for(i=1; iactualWidth[i]+2); + sqlite3_fputs(zSep, p->out); + print_dashes(p->out, p->actualWidth[i]+2); } - oputz(zSep); + sqlite3_fputs(zSep, p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); } /* @@ -2405,9 +2403,9 @@ static int shell_callback( int len = strlen30(azCol[i] ? azCol[i] : ""); if( len>w ) w = len; } - if( p->cnt++>0 ) oputz(p->rowSeparator); + if( p->cnt++>0 ) sqlite3_fputs(p->rowSeparator, p->out); for(i=0; iout, "%*s = %s%s", w, azCol[i], azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); } break; @@ -2435,12 +2433,12 @@ static int shell_callback( /* If this is the first row seen, print out the headers */ if( p->cnt++==0 ){ for(i=0; iout, aWidth[i], azCol[ aMap[i] ]); + sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out); } for(i=0; iout, aWidth[i]); + sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out); } } @@ -2458,17 +2456,17 @@ static int shell_callback( } if( i==iIndent && p->aiIndent && p->pStmt ){ if( p->iIndentnIndent ){ - oputf("%*.s", p->aiIndent[p->iIndent], ""); + sqlite3_fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); } p->iIndent++; } - utf8_width_print(w, zVal ? zVal : p->nullValue); - oputz(i==nArg-1 ? "\n" : zSep); + utf8_width_print(p->out, w, zVal ? zVal : p->nullValue); + sqlite3_fputs(i==nArg-1 ? "\n" : zSep, p->out); } break; } case MODE_Semi: { /* .schema and .fullschema output */ - printSchemaLine(azArg[0], ";\n"); + printSchemaLine(p->out, azArg[0], ";\n"); break; } case MODE_Pretty: { /* .schema and .fullschema with --indent */ @@ -2483,7 +2481,7 @@ static int shell_callback( if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 ){ - oputf("%s;\n", azArg[0]); + sqlite3_fprintf(p->out, "%s;\n", azArg[0]); break; } z = sqlite3_mprintf("%s", azArg[0]); @@ -2516,7 +2514,7 @@ static int shell_callback( }else if( c==')' ){ nParen--; if( nLine>0 && nParen==0 && j>0 ){ - printSchemaLineN(z, j, "\n"); + printSchemaLineN(p->out, z, j, "\n"); j = 0; } } @@ -2525,7 +2523,7 @@ static int shell_callback( && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1))) ){ if( c=='\n' ) j--; - printSchemaLineN(z, j, "\n "); + printSchemaLineN(p->out, z, j, "\n "); j = 0; nLine++; while( IsSpace(z[i+1]) ){ i++; } @@ -2533,59 +2531,60 @@ static int shell_callback( } z[j] = 0; } - printSchemaLine(z, ";\n"); + printSchemaLine(p->out, z, ";\n"); sqlite3_free(z); break; } case MODE_List: { if( p->cnt++==0 && p->showHeader ){ for(i=0; irowSeparator : p->colSeparator); + sqlite3_fprintf(p->out, "%s%s", azCol[i], + i==nArg-1 ? p->rowSeparator : p->colSeparator); } } if( azArg==0 ) break; for(i=0; inullValue; - oputz(z); - oputz((icolSeparator : p->rowSeparator); + sqlite3_fputs(z, p->out); + sqlite3_fputs((icolSeparator : p->rowSeparator, p->out); } break; } case MODE_Html: { if( p->cnt++==0 && p->showHeader ){ - oputz(""); + sqlite3_fputs("", p->out); for(i=0; i"); - output_html_string(azCol[i]); - oputz("\n"); + sqlite3_fputs("", p->out); + output_html_string(p->out, azCol[i]); + sqlite3_fputs("\n", p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); } if( azArg==0 ) break; - oputz(""); + sqlite3_fputs("", p->out); for(i=0; i"); - output_html_string(azArg[i] ? azArg[i] : p->nullValue); - oputz("\n"); + sqlite3_fputs("", p->out); + output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); + sqlite3_fputs("\n", p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); break; } case MODE_Tcl: { if( p->cnt++==0 && p->showHeader ){ for(i=0; icolSeparator); + output_c_string(p->out, azCol[i] ? azCol[i] : ""); + if(icolSeparator, p->out); } - oputz(p->rowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); } if( azArg==0 ) break; for(i=0; inullValue); - if(icolSeparator); + output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); + if(icolSeparator, p->out); } - oputz(p->rowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); break; } case MODE_Csv: { @@ -2594,57 +2593,57 @@ static int shell_callback( for(i=0; irowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); } if( nArg>0 ){ for(i=0; irowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); } sqlite3_fsetmode(p->out, _O_TEXT); break; } case MODE_Insert: { if( azArg==0 ) break; - oputf("INSERT INTO %s",p->zDestTable); + sqlite3_fprintf(p->out, "INSERT INTO %s",p->zDestTable); if( p->showHeader ){ - oputz("("); + sqlite3_fputs("(", p->out); for(i=0; i0 ) oputz(","); + if( i>0 ) sqlite3_fputs(",", p->out); if( quoteChar(azCol[i]) ){ char *z = sqlite3_mprintf("\"%w\"", azCol[i]); shell_check_oom(z); - oputz(z); + sqlite3_fputs(z, p->out); sqlite3_free(z); }else{ - oputf("%s", azCol[i]); + sqlite3_fprintf(p->out, "%s", azCol[i]); } } - oputz(")"); + sqlite3_fputs(")", p->out); } p->cnt++; for(i=0; i0 ? "," : " VALUES("); + sqlite3_fputs(i>0 ? "," : " VALUES(", p->out); if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - oputz("NULL"); + sqlite3_fputs("NULL", p->out); }else if( aiType && aiType[i]==SQLITE_TEXT ){ if( ShellHasFlag(p, SHFLG_Newlines) ){ - output_quoted_string(azArg[i]); + output_quoted_string(p->out, azArg[i]); }else{ - output_quoted_escaped_string(azArg[i]); + output_quoted_escaped_string(p->out, azArg[i]); } }else if( aiType && aiType[i]==SQLITE_INTEGER ){ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); }else if( aiType && aiType[i]==SQLITE_FLOAT ){ char z[50]; double r = sqlite3_column_double(p->pStmt, i); sqlite3_uint64 ur; memcpy(&ur,&r,sizeof(r)); if( ur==0x7ff0000000000000LL ){ - oputz("9.0e+999"); + sqlite3_fputs("9.0e+999", p->out); }else if( ur==0xfff0000000000000LL ){ - oputz("-9.0e+999"); + sqlite3_fputs("-9.0e+999", p->out); }else{ sqlite3_int64 ir = (sqlite3_int64)r; if( r==(double)ir ){ @@ -2652,63 +2651,63 @@ static int shell_callback( }else{ sqlite3_snprintf(50,z,"%!.20g", r); } - oputz(z); + sqlite3_fputs(z, p->out); } }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); - output_hex_blob(pBlob, nBlob); + output_hex_blob(p->out, pBlob, nBlob); }else if( isNumber(azArg[i], 0) ){ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); }else if( ShellHasFlag(p, SHFLG_Newlines) ){ - output_quoted_string(azArg[i]); + output_quoted_string(p->out, azArg[i]); }else{ - output_quoted_escaped_string(azArg[i]); + output_quoted_escaped_string(p->out, azArg[i]); } } - oputz(");\n"); + sqlite3_fputs(");\n", p->out); break; } case MODE_Json: { if( azArg==0 ) break; if( p->cnt==0 ){ - fputs("[{", p->out); + sqlite3_fputs("[{", p->out); }else{ - fputs(",\n{", p->out); + sqlite3_fputs(",\n{", p->out); } p->cnt++; for(i=0; iout, azCol[i], -1); + sqlite3_fputs(":", p->out); if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - oputz("null"); + sqlite3_fputs("null", p->out); }else if( aiType && aiType[i]==SQLITE_FLOAT ){ char z[50]; double r = sqlite3_column_double(p->pStmt, i); sqlite3_uint64 ur; memcpy(&ur,&r,sizeof(r)); if( ur==0x7ff0000000000000LL ){ - oputz("9.0e+999"); + sqlite3_fputs("9.0e+999", p->out); }else if( ur==0xfff0000000000000LL ){ - oputz("-9.0e+999"); + sqlite3_fputs("-9.0e+999", p->out); }else{ sqlite3_snprintf(50,z,"%!.20g", r); - oputz(z); + sqlite3_fputs(z, p->out); } }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); - output_json_string(pBlob, nBlob); + output_json_string(p->out, pBlob, nBlob); }else if( aiType && aiType[i]==SQLITE_TEXT ){ - output_json_string(azArg[i], -1); + output_json_string(p->out, azArg[i], -1); }else{ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); } if( iout); } } - oputz("}"); + sqlite3_fputs("}", p->out); break; } case MODE_Quote: { @@ -2716,7 +2715,7 @@ static int shell_callback( if( p->cnt==0 && p->showHeader ){ for(i=0; i0 ) fputs(p->colSeparator, p->out); - output_quoted_string(azCol[i]); + output_quoted_string(p->out, azCol[i]); } fputs(p->rowSeparator, p->out); } @@ -2724,24 +2723,24 @@ static int shell_callback( for(i=0; i0 ) fputs(p->colSeparator, p->out); if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - oputz("NULL"); + sqlite3_fputs("NULL", p->out); }else if( aiType && aiType[i]==SQLITE_TEXT ){ - output_quoted_string(azArg[i]); + output_quoted_string(p->out, azArg[i]); }else if( aiType && aiType[i]==SQLITE_INTEGER ){ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); }else if( aiType && aiType[i]==SQLITE_FLOAT ){ char z[50]; double r = sqlite3_column_double(p->pStmt, i); sqlite3_snprintf(50,z,"%!.20g", r); - oputz(z); + sqlite3_fputs(z, p->out); }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); - output_hex_blob(pBlob, nBlob); + output_hex_blob(p->out, pBlob, nBlob); }else if( isNumber(azArg[i], 0) ){ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); }else{ - output_quoted_string(azArg[i]); + output_quoted_string(p->out, azArg[i]); } } fputs(p->rowSeparator, p->out); @@ -2750,17 +2749,17 @@ static int shell_callback( case MODE_Ascii: { if( p->cnt++==0 && p->showHeader ){ for(i=0; i0 ) oputz(p->colSeparator); - oputz(azCol[i] ? azCol[i] : ""); + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); + sqlite3_fputs(azCol[i] ? azCol[i] : "", p->out); } - oputz(p->rowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); } if( azArg==0 ) break; for(i=0; i0 ) oputz(p->colSeparator); - oputz(azArg[i] ? azArg[i] : p->nullValue); + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); + sqlite3_fputs(azArg[i] ? azArg[i] : p->nullValue, p->out); } - oputz(p->rowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); break; } case MODE_EQP: { @@ -2942,7 +2941,7 @@ static int run_table_dump_query( rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); if( rc!=SQLITE_OK || !pSelect ){ char *zContext = shell_error_context(zSelect, p->db); - oputf("/**** ERROR: (%d) %s *****/\n%s", + sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n%s", rc, sqlite3_errmsg(p->db), zContext); sqlite3_free(zContext); if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; @@ -2952,22 +2951,23 @@ static int run_table_dump_query( nResult = sqlite3_column_count(pSelect); while( rc==SQLITE_ROW ){ z = (const char*)sqlite3_column_text(pSelect, 0); - oputf("%s", z); + sqlite3_fprintf(p->out, "%s", z); for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); } if( z==0 ) z = ""; while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; if( z[0] ){ - oputz("\n;\n"); + sqlite3_fputs("\n;\n", p->out); }else{ - oputz(";\n"); + sqlite3_fputs(";\n", p->out); } rc = sqlite3_step(pSelect); } rc = sqlite3_finalize(pSelect); if( rc!=SQLITE_OK ){ - oputf("/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); + sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", + rc, sqlite3_errmsg(p->db)); if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; } return rc; @@ -3003,7 +3003,7 @@ static char *save_err_msg( /* ** Attempt to display I/O stats on Linux using /proc/PID/io */ -static void displayLinuxIoStats(void){ +static void displayLinuxIoStats(FILE *out){ FILE *in; char z[200]; sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); @@ -3026,7 +3026,7 @@ static void displayLinuxIoStats(void){ for(i=0; iout==0 ) return 0; + out = pArg->out; if( pArg->pStmt && pArg->statsOn==2 ){ int nCol, i, x; sqlite3_stmt *pStmt = pArg->pStmt; char z[100]; nCol = sqlite3_column_count(pStmt); - oputf("%-36s %d\n", "Number of output columns:", nCol); + sqlite3_fprintf(out, "%-36s %d\n", "Number of output columns:", nCol); for(i=0; istatsOn==3 ){ if( pArg->pStmt ){ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset); - oputf("VM-steps: %d\n", iCur); + sqlite3_fprintf(out, "VM-steps: %d\n", iCur); } return 0; } - displayStatLine("Memory Used:", + displayStatLine(out, "Memory Used:", "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); - displayStatLine("Number of Outstanding Allocations:", + displayStatLine(out, "Number of Outstanding Allocations:", "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); if( pArg->shellFlgs & SHFLG_Pagecache ){ - displayStatLine("Number of Pcache Pages Used:", + displayStatLine(out, "Number of Pcache Pages Used:", "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); } - displayStatLine("Number of Pcache Overflow Bytes:", + displayStatLine(out, "Number of Pcache Overflow Bytes:", "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); - displayStatLine("Largest Allocation:", + displayStatLine(out, "Largest Allocation:", "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); - displayStatLine("Largest Pcache Allocation:", + displayStatLine(out, "Largest Pcache Allocation:", "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); #ifdef YYTRACKMAXSTACKDEPTH - displayStatLine("Deepest Parser Stack:", + displayStatLine(out, "Deepest Parser Stack:", "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); #endif @@ -3128,68 +3132,87 @@ static int display_stats( iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset); - oputf("Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); + sqlite3_fprintf(out, + "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset); - oputf("Successful lookaside attempts: %d\n", iHiwtr); + sqlite3_fprintf(out, + "Successful lookaside attempts: %d\n", iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset); - oputf("Lookaside failures due to size: %d\n", iHiwtr); + sqlite3_fprintf(out, + "Lookaside failures due to size: %d\n", iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset); - oputf("Lookaside failures due to OOM: %d\n", iHiwtr); + sqlite3_fprintf(out, + "Lookaside failures due to OOM: %d\n", iHiwtr); } iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); - oputf("Pager Heap Usage: %d bytes\n", iCur); + sqlite3_fprintf(out, + "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); - oputf("Page cache hits: %d\n", iCur); + sqlite3_fprintf(out, + "Page cache hits: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); - oputf("Page cache misses: %d\n", iCur); + sqlite3_fprintf(out, + "Page cache misses: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - oputf("Page cache writes: %d\n", iCur); + sqlite3_fprintf(out, + "Page cache writes: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); - oputf("Page cache spills: %d\n", iCur); + sqlite3_fprintf(out, + "Page cache spills: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); - oputf("Schema Heap Usage: %d bytes\n", iCur); + sqlite3_fprintf(out, + "Schema Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); - oputf("Statement Heap/Lookaside Usage: %d bytes\n", iCur); + sqlite3_fprintf(out, + "Statement Heap/Lookaside Usage: %d bytes\n", iCur); } if( pArg->pStmt ){ int iHit, iMiss; iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset); - oputf("Fullscan Steps: %d\n", iCur); + sqlite3_fprintf(out, + "Fullscan Steps: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); - oputf("Sort Operations: %d\n", iCur); + sqlite3_fprintf(out, + "Sort Operations: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); - oputf("Autoindex Inserts: %d\n", iCur); + sqlite3_fprintf(out, + "Autoindex Inserts: %d\n", iCur); iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, bReset); iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, bReset); if( iHit || iMiss ){ - oputf("Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss); + sqlite3_fprintf(out, + "Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss); } iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); - oputf("Virtual Machine Steps: %d\n", iCur); + sqlite3_fprintf(out, + "Virtual Machine Steps: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset); - oputf("Reprepare operations: %d\n", iCur); + sqlite3_fprintf(out, + "Reprepare operations: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); - oputf("Number of times run: %d\n", iCur); + sqlite3_fprintf(out, + "Number of times run: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset); - oputf("Memory used by prepared stmt: %d\n", iCur); + sqlite3_fprintf(out, + "Memory used by prepared stmt: %d\n", iCur); } #ifdef __linux__ - displayLinuxIoStats(); + displayLinuxIoStats(pArg->out); #endif /* Do not remove this machine readable comment: extra-stats-output-here */ @@ -3585,17 +3608,17 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){ /* Draw horizontal line N characters long using unicode box ** characters */ -static void print_box_line(int N){ +static void print_box_line(FILE *out, int N){ const char zDash[] = BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24; const int nDash = sizeof(zDash) - 1; N *= 3; while( N>nDash ){ - oputz(zDash); + sqlite3_fputs(zDash, out); N -= nDash; } - oputf("%.*s", N, zDash); + sqlite3_fprintf(out, "%.*s", N, zDash); } /* @@ -3610,15 +3633,15 @@ static void print_box_row_separator( ){ int i; if( nArg>0 ){ - oputz(zSep1); - print_box_line(p->actualWidth[0]+2); + sqlite3_fputs(zSep1, p->out); + print_box_line(p->out, p->actualWidth[0]+2); for(i=1; iactualWidth[i]+2); + sqlite3_fputs(zSep2, p->out); + print_box_line(p->out, p->actualWidth[i]+2); } - oputz(zSep3); + sqlite3_fputs(zSep3, p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); } /* @@ -3881,11 +3904,11 @@ static void exec_prepared_stmt_columnar( for(i=0; iactualWidth[i]; if( p->colWidth[i]<0 ) w = -w; - utf8_width_print(w, azData[i]); - fputs(i==nColumn-1?"\n":" ", p->out); + utf8_width_print(p->out, w, azData[i]); + sqlite3_fputs(i==nColumn-1?"\n":" ", p->out); } for(i=0; iactualWidth[i]); + print_dashes(p->out, p->actualWidth[i]); fputs(i==nColumn-1?"\n":" ", p->out); } } @@ -3899,8 +3922,9 @@ static void exec_prepared_stmt_columnar( for(i=0; iactualWidth[i]; n = strlenChar(azData[i]); - oputf("%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, ""); - oputz(i==nColumn-1?" |\n":" | "); + sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "", + azData[i], (w-n+1)/2, ""); + sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out); } print_row_separator(p, nColumn, "+"); break; @@ -3912,8 +3936,9 @@ static void exec_prepared_stmt_columnar( for(i=0; iactualWidth[i]; n = strlenChar(azData[i]); - oputf("%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, ""); - oputz(i==nColumn-1?" |\n":" | "); + sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "", + azData[i], (w-n+1)/2, ""); + sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out); } print_row_separator(p, nColumn, "|"); break; @@ -3922,11 +3947,11 @@ static void exec_prepared_stmt_columnar( colSep = " " BOX_13 " "; rowSep = " " BOX_13 "\n"; print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34); - oputz(BOX_13 " "); + sqlite3_fputs(BOX_13 " ", p->out); for(i=0; iactualWidth[i]; n = strlenChar(azData[i]); - oputf("%*s%s%*s%s", + sqlite3_fprintf(p->out, "%*s%s%*s%s", (w-n)/2, "", azData[i], (w-n+1)/2, "", i==nColumn-1?" "BOX_13"\n":" "BOX_13" "); } @@ -3936,28 +3961,28 @@ static void exec_prepared_stmt_columnar( } for(i=nColumn, j=0; icMode!=MODE_Column ){ - oputz(p->cMode==MODE_Box?BOX_13" ":"| "); + sqlite3_fputs(p->cMode==MODE_Box?BOX_13" ":"| ", p->out); } z = azData[i]; if( z==0 ) z = p->nullValue; w = p->actualWidth[j]; if( p->colWidth[j]<0 ) w = -w; - utf8_width_print(w, z); + utf8_width_print(p->out, w, z); if( j==nColumn-1 ){ - oputz(rowSep); + sqlite3_fputs(rowSep, p->out); if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1cMode==MODE_Table ){ print_row_separator(p, nColumn, "+"); }else if( p->cMode==MODE_Box ){ print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134); }else if( p->cMode==MODE_Column ){ - oputz("\n"); + sqlite3_fputs("\n", p->out); } } j = -1; if( seenInterrupt ) goto columnar_end; }else{ - oputz(colSep); + sqlite3_fputs(colSep, p->out); } } if( p->cMode==MODE_Table ){ @@ -3967,7 +3992,7 @@ static void exec_prepared_stmt_columnar( } columnar_end: if( seenInterrupt ){ - oputz("Interrupt\n"); + sqlite3_fputs("Interrupt\n", p->out); } nData = (nRow+1)*nColumn; for(i=0; iexpert.pExpert; + FILE *out = pState->out; assert( p ); assert( bCancel || pzErr==0 || *pzErr==0 ); if( bCancel==0 ){ @@ -4115,8 +4141,8 @@ static int expertFinish( if( bVerbose ){ const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES); - oputz("-- Candidates -----------------------------\n"); - oputf("%s\n", zCand); + sqlite3_fputs("-- Candidates -----------------------------\n", out); + sqlite3_fprintf(out, "%s\n", zCand); } for(i=0; ishellFlgs & SHFLG_DumpNoSys)!=0; if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){ - if( !dataOnly ) oputz("DELETE FROM sqlite_sequence;\n"); + if( !dataOnly ) sqlite3_fputs("DELETE FROM sqlite_sequence;\n", p->out); }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){ - if( !dataOnly ) oputz("ANALYZE sqlite_schema;\n"); + if( !dataOnly ) sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); }else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){ return 0; }else if( dataOnly ){ @@ -4521,7 +4548,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ }else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ char *zIns; if( !p->writableSchema ){ - oputz("PRAGMA writable_schema=ON;\n"); + sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out); p->writableSchema = 1; } zIns = sqlite3_mprintf( @@ -4529,11 +4556,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ "VALUES('table','%q','%q',0,'%q');", zTable, zTable, zSql); shell_check_oom(zIns); - oputf("%s\n", zIns); + sqlite3_fprintf(p->out, "%s\n", zIns); sqlite3_free(zIns); return 0; }else{ - printSchemaLine(zSql, ";\n"); + printSchemaLine(p->out, zSql, ";\n"); } if( cli_strcmp(zType, "table")==0 ){ @@ -4591,7 +4618,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ p->mode = p->cMode = MODE_Insert; rc = shell_exec(p, sSelect.z, 0); if( (rc&0xff)==SQLITE_CORRUPT ){ - oputz("/****** CORRUPTION ERROR *******/\n"); + sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); toggleSelectOrder(p->db); shell_exec(p, sSelect.z, 0); toggleSelectOrder(p->db); @@ -4622,9 +4649,9 @@ static int run_schema_dump_query( if( rc==SQLITE_CORRUPT ){ char *zQ2; int len = strlen30(zQuery); - oputz("/****** CORRUPTION ERROR *******/\n"); + sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); if( zErr ){ - oputf("/****** %s ******/\n", zErr); + sqlite3_fprintf(p->out, "/****** %s ******/\n", zErr); sqlite3_free(zErr); zErr = 0; } @@ -4633,7 +4660,7 @@ static int run_schema_dump_query( sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); if( rc ){ - oputf("/****** ERROR: %s ******/\n", zErr); + sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr); }else{ rc = SQLITE_CORRUPT; } @@ -4990,10 +5017,10 @@ static int showHelp(FILE *out, const char *zPattern){ } if( ((hw^hh)&HH_Undoc)==0 ){ if( (hh&HH_Summary)!=0 ){ - sputf(out, ".%s\n", azHelp[i]+1); + sqlite3_fprintf(out, ".%s\n", azHelp[i]+1); ++n; }else if( (hw&HW_SummaryOnly)==0 ){ - sputf(out, "%s\n", azHelp[i]); + sqlite3_fprintf(out, "%s\n", azHelp[i]); } } } @@ -5003,7 +5030,7 @@ static int showHelp(FILE *out, const char *zPattern){ shell_check_oom(zPat); for(i=0; i65536 || (pgsz & (pgsz-1))!=0 ){ - eputz("invalid pagesize\n"); + sqlite3_fputs("invalid pagesize\n", stderr); goto readHexDb_error; } for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ @@ -5355,7 +5382,8 @@ static void open_db(ShellState *p, int openFlags){ sqlite3_close(p->db); sqlite3_open(":memory:", &p->db); if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ - eputz("Also: unable to open substitute in-memory database.\n"); + sqlite3_fputs("Also: unable to open substitute in-memory database.\n", + stderr); exit(1); }else{ eputf("Notice: using substitute in-memory database instead of \"%s\"\n", @@ -5749,12 +5777,12 @@ static int sql_trace_callback( switch( mType ){ case SQLITE_TRACE_ROW: case SQLITE_TRACE_STMT: { - sputf(p->traceOut, "%.*s;\n", (int)nSql, zSql); + sqlite3_fprintf(p->traceOut, "%.*s;\n", (int)nSql, zSql); break; } case SQLITE_TRACE_PROFILE: { sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0; - sputf(p->traceOut, "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec); + sqlite3_fprintf(p->traceOut, "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec); break; } } @@ -6080,7 +6108,7 @@ static void tryToCloneSchema( zSql = sqlite3_column_text(pQuery, 1); if( zName==0 || zSql==0 ) continue; if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){ - sputf(stdout, "%s... ", zName); fflush(stdout); + sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout); sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); if( zErrMsg ){ eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql); @@ -6110,7 +6138,7 @@ static void tryToCloneSchema( zSql = sqlite3_column_text(pQuery, 1); if( zName==0 || zSql==0 ) continue; if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue; - sputf(stdout, "%s... ", zName); fflush(stdout); + sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout); sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); if( zErrMsg ){ eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql); @@ -6160,7 +6188,7 @@ static void tryToClone(ShellState *p, const char *zNewDb){ */ static void output_redir(ShellState *p, FILE *pfNew){ if( p->out != stdout ){ - eputz("Output already redirected.\n"); + sqlite3_fputs("Output already redirected.\n", stderr); }else{ p->out = pfNew; } @@ -6296,28 +6324,28 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ memcpy(aHdr, pb, 100); sqlite3_finalize(pStmt); }else{ - eputz("unable to read database header\n"); + sqlite3_fputs("unable to read database header\n", stderr); sqlite3_finalize(pStmt); return 1; } i = get2byteInt(aHdr+16); if( i==1 ) i = 65536; - oputf("%-20s %d\n", "database page size:", i); - oputf("%-20s %d\n", "write format:", aHdr[18]); - oputf("%-20s %d\n", "read format:", aHdr[19]); - oputf("%-20s %d\n", "reserved bytes:", aHdr[20]); + sqlite3_fprintf(p->out, "%-20s %d\n", "database page size:", i); + sqlite3_fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); + sqlite3_fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); + sqlite3_fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); for(i=0; iout, "%-20s %u", aField[i].zName, val); switch( ofst ){ case 56: { - if( val==1 ) oputz(" (utf8)"); - if( val==2 ) oputz(" (utf16le)"); - if( val==3 ) oputz(" (utf16be)"); + if( val==1 ) sqlite3_fputs(" (utf8)", p->out); + if( val==2 ) sqlite3_fputs(" (utf16le)", p->out); + if( val==3 ) sqlite3_fputs(" (utf16be)", p->out); } } - oputz("\n"); + sqlite3_fputs("\n", p->out); } if( zDb==0 ){ zSchemaTab = sqlite3_mprintf("main.sqlite_schema"); @@ -6330,11 +6358,11 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); int val = db_int(p->db, zSql); sqlite3_free(zSql); - oputf("%-20s %d\n", aQuery[i].zName, val); + sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); } sqlite3_free(zSchemaTab); sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion); - oputf("%-20s %u\n", "data version", iDataVersion); + sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion); return 0; } #endif /* SQLITE_SHELL_HAVE_RECOVER */ @@ -6590,6 +6618,7 @@ static int lintFkeyIndexes( const char *zIndent = ""; /* How much to indent CREATE INDEX by */ int rc; /* Return code */ sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ + FILE *out = pState->out; /* Send output here */ /* ** This SELECT statement returns one row for each foreign key constraint @@ -6709,22 +6738,22 @@ static int lintFkeyIndexes( if( rc!=SQLITE_OK ) break; if( res<0 ){ - eputz("Error: internal error"); + sqlite3_fputs("Error: internal error", stderr); break; }else{ if( bGroupByParent && (bVerbose || res==0) && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) ){ - oputf("-- Parent table %s\n", zParent); + sqlite3_fprintf(out, "-- Parent table %s\n", zParent); sqlite3_free(zPrev); zPrev = sqlite3_mprintf("%s", zParent); } if( res==0 ){ - oputf("%s%s --> %s\n", zIndent, zCI, zTarget); + sqlite3_fprintf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); }else if( bVerbose ){ - oputf("%s/* no extra indexes required for %s -> %s */\n", + sqlite3_fprintf(out, "%s/* no extra indexes required for %s -> %s */\n", zIndent, zFrom, zTarget ); } @@ -6762,9 +6791,9 @@ static int lintDotCommand( return lintFkeyIndexes(pState, azArg, nArg); usage: - eputf("Usage %s sub-command ?switches...?\n", azArg[0]); - eputz("Where sub-commands are:\n"); - eputz(" fkey-indexes\n"); + sqlite3_fprintf(stderr,"Usage %s sub-command ?switches...?\n", azArg[0]); + sqlite3_fprintf(stderr, "Where sub-commands are:\n"); + sqlite3_fprintf(stderr, " fkey-indexes\n"); return SQLITE_ERROR; } @@ -6873,6 +6902,7 @@ struct ArCommand { const char *zDir; /* --directory argument, or NULL */ char **azArg; /* Array of command arguments */ ShellState *p; /* Shell state */ + FILE *out; /* Output to this stream */ sqlite3 *db; /* Database containing the archive */ }; @@ -6896,9 +6926,9 @@ static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){ va_end(ap); shellEmitError(z); if( pAr->fromCmdLine ){ - eputz("Use \"-A\" for more help\n"); + sqlite3_fputs("Use \"-A\" for more help\n", stderr); }else{ - eputz("Use \".archive --help\" for more help\n"); + sqlite3_fputs("Use \".archive --help\" for more help\n", stderr); } sqlite3_free(z); return SQLITE_ERROR; @@ -6998,7 +7028,7 @@ static int arParseCommand( struct ArSwitch *pEnd = &aSwitch[nSwitch]; if( nArg<=1 ){ - eputz("Wrong number of arguments. Usage:\n"); + sqlite3_fprintf(stderr, "Wrong number of arguments. Usage:\n"); return arUsage(stderr); }else{ char *z = azArg[1]; @@ -7104,7 +7134,7 @@ static int arParseCommand( } } if( pAr->eCmd==0 ){ - eputz("Required argument missing. Usage:\n"); + sqlite3_fprintf(stderr, "Required argument missing. Usage:\n"); return arUsage(stderr); } return SQLITE_OK; @@ -7214,15 +7244,15 @@ static int arListCommand(ArCommand *pAr){ shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose], pAr->zSrcTable, zWhere); if( pAr->bDryRun ){ - oputf("%s\n", sqlite3_sql(pSql)); + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql)); }else{ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ if( pAr->bVerbose ){ - oputf("%s % 10d %s %s\n", + sqlite3_fprintf(pAr->out, "%s % 10d %s %s\n", sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1), sqlite3_column_text(pSql, 2),sqlite3_column_text(pSql, 3)); }else{ - oputf("%s\n", sqlite3_column_text(pSql, 0)); + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0)); } } } @@ -7249,7 +7279,7 @@ static int arRemoveCommand(ArCommand *pAr){ zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;", pAr->zSrcTable, zWhere); if( pAr->bDryRun ){ - oputf("%s\n", zSql); + sqlite3_fprintf(pAr->out, "%s\n", zSql); }else{ char *zErr = 0; rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0); @@ -7262,7 +7292,7 @@ static int arRemoveCommand(ArCommand *pAr){ } } if( zErr ){ - sputf(stdout, "ERROR: %s\n", zErr); /* stdout? */ + sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); /* stdout? */ sqlite3_free(zErr); } } @@ -7326,11 +7356,11 @@ static int arExtractCommand(ArCommand *pAr){ j = sqlite3_bind_parameter_index(pSql, "$dirOnly"); sqlite3_bind_int(pSql, j, i); if( pAr->bDryRun ){ - oputf("%s\n", sqlite3_sql(pSql)); + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql)); }else{ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ if( i==0 && pAr->bVerbose ){ - oputf("%s\n", sqlite3_column_text(pSql, 0)); + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0)); } } } @@ -7350,13 +7380,13 @@ static int arExtractCommand(ArCommand *pAr){ static int arExecSql(ArCommand *pAr, const char *zSql){ int rc; if( pAr->bDryRun ){ - oputf("%s\n", zSql); + sqlite3_fprintf(pAr->out, "%s\n", zSql); rc = SQLITE_OK; }else{ char *zErr = 0; rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); if( zErr ){ - sputf(stdout, "ERROR: %s\n", zErr); + sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); sqlite3_free(zErr); } } @@ -7505,6 +7535,7 @@ static int arDotCommand( if( rc==SQLITE_OK ){ int eDbType = SHELL_OPEN_UNSPEC; cmd.p = pState; + cmd.out = pState->out; cmd.db = pState->db; if( cmd.zFile ){ eDbType = deduceDatabaseType(cmd.zFile, 1); @@ -7531,13 +7562,14 @@ static int arDotCommand( } cmd.db = 0; if( cmd.bDryRun ){ - oputf("-- open database '%s'%s\n", cmd.zFile, + sqlite3_fprintf(cmd.out, "-- open database '%s'%s\n", cmd.zFile, eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : ""); } rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); if( rc!=SQLITE_OK ){ - eputf("cannot open file: %s (%s)\n", cmd.zFile, sqlite3_errmsg(cmd.db)); + sqlite3_fprintf(stderr, "cannot open file: %s (%s)\n", + cmd.zFile, sqlite3_errmsg(cmd.db)); goto end_ar_command; } sqlite3_fileio_init(cmd.db, 0, 0); @@ -7550,7 +7582,7 @@ static int arDotCommand( if( cmd.eCmd!=AR_CMD_CREATE && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0) ){ - eputz("database does not contain an 'sqlar' table\n"); + sqlite3_fprintf(stderr, "database does not contain an 'sqlar' table\n"); rc = SQLITE_ERROR; goto end_ar_command; } @@ -7608,7 +7640,7 @@ end_ar_command: */ static int recoverSqlCb(void *pCtx, const char *zSql){ ShellState *pState = (ShellState*)pCtx; - sputf(pState->out, "%s;\n", zSql); + sqlite3_fprintf(pState->out, "%s;\n", zSql); return SQLITE_OK; } @@ -7692,7 +7724,7 @@ static int intckDatabaseCmd(ShellState *pState, i64 nStepPerUnlock){ while( SQLITE_OK==sqlite3_intck_step(p) ){ const char *zMsg = sqlite3_intck_message(p); if( zMsg ){ - oputf("%s\n", zMsg); + sqlite3_fprintf(pState->out, "%s\n", zMsg); nError++; } nStep++; @@ -7706,7 +7738,7 @@ static int intckDatabaseCmd(ShellState *pState, i64 nStepPerUnlock){ } sqlite3_intck_close(p); - oputf("%lld steps, %lld errors\n", nStep, nError); + sqlite3_fprintf(pState->out, "%lld steps, %lld errors\n", nStep, nError); } return rc; @@ -7946,8 +7978,9 @@ static int outputDumpWarning(ShellState *p, const char *zLike){ "sql LIKE 'CREATE VIRTUAL TABLE%%' AND %s", zLike ? zLike : "true" ); if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ - oputz("/* WARNING: " - "Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n" + sqlite3_fputs("/* WARNING: " + "Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n", + p->out ); } shellFinalize(&rc, pStmt); @@ -7978,12 +8011,14 @@ static int faultsim_callback(int iArg){ if( faultsim_state.iCnt ){ if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--; if( faultsim_state.eVerbose>=2 ){ - oputf("FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt); + sqlite3_fprintf(stdout, + "FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt); } return SQLITE_OK; } if( faultsim_state.eVerbose>=1 ){ - oputf("FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr); + sqlite3_fprintf(stdout, + "FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr); } faultsim_state.iCnt = faultsim_state.iInterval; faultsim_state.nHit++; @@ -8046,7 +8081,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifndef SQLITE_OMIT_AUTHORIZATION if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){ if( nArg!=2 ){ - eputz("Usage: .auth ON|OFF\n"); + sqlite3_fprintf(stderr, "Usage: .auth ON|OFF\n"); rc = 1; goto meta_command_exit; } @@ -8102,12 +8137,12 @@ static int do_meta_command(char *zLine, ShellState *p){ zDb = zDestFile; zDestFile = azArg[j]; }else{ - eputz("Usage: .backup ?DB? ?OPTIONS? FILENAME\n"); + sqlite3_fprintf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n"); return 1; } } if( zDestFile==0 ){ - eputz("missing FILENAME argument on .backup\n"); + sqlite3_fprintf(stderr, "missing FILENAME argument on .backup\n"); return 1; } if( zDb==0 ) zDb = "main"; @@ -8221,7 +8256,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->zTestcase, azArg[1], zRes); rc = 1; }else{ - oputf("testcase-%s ok\n", p->zTestcase); + sqlite3_fprintf(p->out, "testcase-%s ok\n", p->zTestcase); p->nCheck++; } sqlite3_free(zRes); @@ -8254,9 +8289,9 @@ static int do_meta_command(char *zLine, ShellState *p){ zFile = "(temporary-file)"; } if( p->pAuxDb == &p->aAuxDb[i] ){ - sputf(stdout, "ACTIVE %d: %s\n", i, zFile); + sqlite3_fprintf(stdout, "ACTIVE %d: %s\n", i, zFile); }else if( p->aAuxDb[i].db!=0 ){ - sputf(stdout, " %d: %s\n", i, zFile); + sqlite3_fprintf(stdout, " %d: %s\n", i, zFile); } } }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){ @@ -8329,7 +8364,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int eTxn = sqlite3_txn_state(p->db, azName[i*2]); int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]); const char *z = azName[i*2+1]; - oputf("%s: %s %s%s\n", + sqlite3_fprintf(p->out, "%s: %s %s%s\n", azName[i*2], z && z[0] ? z : "\"\"", bRdonly ? "r/o" : "r/w", eTxn==SQLITE_TXN_NONE ? "" : eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn"); @@ -8371,7 +8406,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); } sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); - oputf("%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); + sqlite3_fprintf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); if( nArg>1 ) break; } if( nArg>1 && ii==ArraySize(aDbConfig) ){ @@ -8460,8 +8495,8 @@ static int do_meta_command(char *zLine, ShellState *p){ /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ - oputz("PRAGMA foreign_keys=OFF;\n"); - oputz("BEGIN TRANSACTION;\n"); + sqlite3_fputs("PRAGMA foreign_keys=OFF;\n", p->out); + sqlite3_fputs("BEGIN TRANSACTION;\n", p->out); } p->writableSchema = 0; p->showHeader = 0; @@ -8493,13 +8528,13 @@ static int do_meta_command(char *zLine, ShellState *p){ } sqlite3_free(zLike); if( p->writableSchema ){ - oputz("PRAGMA writable_schema=OFF;\n"); + sqlite3_fputs("PRAGMA writable_schema=OFF;\n", p->out); p->writableSchema = 0; } sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ - oputz(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n"); + sqlite3_fputs(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n", p->out); } p->showHeader = savedShowHeader; p->shellFlgs = savedShellFlags; @@ -8636,9 +8671,9 @@ static int do_meta_command(char *zLine, ShellState *p){ /* --help lists all file-controls */ if( cli_strcmp(zCmd,"help")==0 ){ - oputz("Available file-controls:\n"); + sqlite3_fputs("Available file-controls:\n", p->out); for(i=0; iout, " .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); } rc = 1; goto meta_command_exit; @@ -8705,7 +8740,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg!=2 ) break; sqlite3_file_control(p->db, zSchema, filectrl, &z); if( z ){ - oputf("%s\n", z); + sqlite3_fprintf(p->out, "%s\n", z); sqlite3_free(z); } isOk = 2; @@ -8719,19 +8754,20 @@ static int do_meta_command(char *zLine, ShellState *p){ } x = -1; sqlite3_file_control(p->db, zSchema, filectrl, &x); - oputf("%d\n", x); + sqlite3_fprintf(p->out, "%d\n", x); isOk = 2; break; } } } if( isOk==0 && iCtrl>=0 ){ - oputf("Usage: .filectrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); + sqlite3_fprintf(p->out, "Usage: .filectrl %s %s\n", + zCmd, aCtrl[iCtrl].zUsage); rc = 1; }else if( isOk==1 ){ char zBuf[100]; sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes); - oputf("%s\n", zBuf); + sqlite3_fprintf(p->out, "%s\n", zBuf); } }else @@ -8772,15 +8808,15 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( doStats==0 ){ - oputz("/* No STAT tables available */\n"); + sqlite3_fputs("/* No STAT tables available */\n", p->out); }else{ - oputz("ANALYZE sqlite_schema;\n"); + sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); data.cMode = data.mode = MODE_Insert; data.zDestTable = "sqlite_stat1"; shell_exec(&data, "SELECT * FROM sqlite_stat1", 0); data.zDestTable = "sqlite_stat4"; shell_exec(&data, "SELECT * FROM sqlite_stat4", 0); - oputz("ANALYZE sqlite_schema;\n"); + sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); } }else @@ -8798,7 +8834,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg>=2 ){ n = showHelp(p->out, azArg[1]); if( n==0 ){ - oputf("Nothing matches '%s'\n", azArg[1]); + sqlite3_fprintf(p->out, "Nothing matches '%s'\n", azArg[1]); } }else{ showHelp(p->out, 0); @@ -8841,7 +8877,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( zTable==0 ){ zTable = z; }else{ - oputf("ERROR: extra argument: \"%s\". Usage:\n", z); + sqlite3_fprintf(p->out, "ERROR: extra argument: \"%s\". Usage:\n",z); showHelp(p->out, "import"); goto meta_command_exit; } @@ -8862,13 +8898,13 @@ static int do_meta_command(char *zLine, ShellState *p){ xRead = csv_read_one_field; useOutputMode = 0; }else{ - oputf("ERROR: unknown option: \"%s\". Usage:\n", z); + sqlite3_fprintf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z); showHelp(p->out, "import"); goto meta_command_exit; } } if( zTable==0 ){ - oputf("ERROR: missing %s argument. Usage:\n", + sqlite3_fprintf(p->out, "ERROR: missing %s argument. Usage:\n", zFile==0 ? "FILE" : "TABLE"); showHelp(p->out, "import"); goto meta_command_exit; @@ -8934,12 +8970,12 @@ static int do_meta_command(char *zLine, ShellState *p){ char zSep[2]; zSep[1] = 0; zSep[0] = sCtx.cColSep; - oputz("Column separator "); - output_c_string(zSep); - oputz(", row separator "); + sqlite3_fputs("Column separator ", p->out); + output_c_string(p->out, zSep); + sqlite3_fputs(", row separator ", p->out); zSep[0] = sCtx.cRowSep; - output_c_string(zSep); - oputz("\n"); + output_c_string(p->out, zSep); + sqlite3_fputs("\n", p->out); } sCtx.z = sqlite3_malloc64(120); if( sCtx.z==0 ){ @@ -8964,7 +9000,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } zColDefs = zAutoColumn(0, &dbCols, &zRenames); if( zRenames!=0 ){ - sputf((stdin_is_interactive && p->in==stdin)? p->out : stderr, + sqlite3_fprintf((stdin_is_interactive && p->in==stdin)? p->out : stderr, "Columns renamed during .import %s due to duplicates:\n" "%s\n", sCtx.zFile, zRenames); sqlite3_free(zRenames); @@ -8983,7 +9019,7 @@ static int do_meta_command(char *zLine, ShellState *p){ shell_out_of_memory(); } if( eVerbose>=1 ){ - oputf("%s\n", zCreate); + sqlite3_fprintf(p->out, "%s\n", zCreate); } rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); sqlite3_free(zCreate); @@ -9044,7 +9080,7 @@ static int do_meta_command(char *zLine, ShellState *p){ zSql[j] = 0; assert( j=2 ){ - oputf("Insert using: %s\n", zSql); + sqlite3_fprintf(p->out, "Insert using: %s\n", zSql); } rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); @@ -9115,7 +9151,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_finalize(pStmt); if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); if( eVerbose>0 ){ - oputf("Added %d rows with %d errors using %d lines of input\n", + sqlite3_fprintf(p->out, "Added %d rows with %d errors using %d lines of input\n", sCtx.nRow, sCtx.nErr, sCtx.nLine-1); } }else @@ -9214,8 +9250,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( rc ){ eputf("Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); }else{ - sputf(stdout, "%s;\n", zSql); - sputf(stdout, "WARNING: writing to an imposter table will corrupt" + sqlite3_fprintf(stdout, "%s;\n", zSql); + sqlite3_fprintf(stdout, "WARNING: writing to an imposter table will corrupt" " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index"); } }else{ @@ -9286,7 +9322,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); if( nArg==1 ){ for(i=0; idb, aLimit[i].limitCode, -1)); } }else if( nArg>3 ){ @@ -9318,7 +9354,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_limit(p->db, aLimit[iLimit].limitCode, (int)integerValue(azArg[2])); } - sputf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName, + sqlite3_fprintf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName, sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); } }else @@ -9420,12 +9456,13 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->mode==MODE_Column || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) ){ - oputf("current output mode: %s --wrap %d --wordwrap %s --%squote\n", + sqlite3_fprintf(p->out, + "current output mode: %s --wrap %d --wordwrap %s --%squote\n", modeDescr[p->mode], p->cmOpts.iWrap, p->cmOpts.bWordWrap ? "on" : "off", p->cmOpts.bQuote ? "" : "no"); }else{ - oputf("current output mode: %s\n", modeDescr[p->mode]); + sqlite3_fprintf(p->out, "current output mode: %s\n", modeDescr[p->mode]); } zMode = modeDescr[p->mode]; } @@ -9644,7 +9681,8 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c!='e' && cli_strcmp(z,"-e")==0 ){ eMode = 'e'; /* text editor */ }else{ - oputf("ERROR: unknown option: \"%s\". Usage:\n", azArg[i]); + sqlite3_fprintf(p->out, + "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; goto meta_command_exit; @@ -9656,7 +9694,7 @@ static int do_meta_command(char *zLine, ShellState *p){ break; } }else{ - oputf("ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); + sqlite3_fprintf(p->out, "ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; sqlite3_free(zFile); @@ -9705,7 +9743,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; }else{ output_redir(p, pfPipe); - if( zBom ) oputz(zBom); + if( zBom ) sqlite3_fputs(zBom, pfPipe); sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } #endif @@ -9718,7 +9756,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; } else { output_redir(p, pfFile); - if( zBom ) oputz(zBom); + if( zBom ) sqlite3_fputs(zBom, pfFile); sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } @@ -9759,7 +9797,7 @@ static int do_meta_command(char *zLine, ShellState *p){ "SELECT key, quote(value) " "FROM temp.sqlite_parameters;", -1, &pStmt, 0); while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ - oputf("%-*s %s\n", len, sqlite3_column_text(pStmt,0), + sqlite3_fprintf(p->out, "%-*s %s\n", len, sqlite3_column_text(pStmt,0), sqlite3_column_text(pStmt,1)); } sqlite3_finalize(pStmt); @@ -9804,7 +9842,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rx!=SQLITE_OK ){ - oputf("Error: %s\n", sqlite3_errmsg(p->db)); + sqlite3_fprintf(p->out, "Error: %s\n", sqlite3_errmsg(p->db)); sqlite3_finalize(pStmt); pStmt = 0; rc = 1; @@ -9833,10 +9871,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){ int i; for(i=1; i1 ) oputz(" "); - oputz(azArg[i]); + if( i>1 ) sqlite3_fputs(" ", p->out); + sqlite3_fputs(azArg[i], p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); }else #ifndef SQLITE_OMIT_PROGRESS_CALLBACK @@ -10143,7 +10181,7 @@ static int do_meta_command(char *zLine, ShellState *p){ appendText(&sSelect, "sql IS NOT NULL" " ORDER BY snum, rowid", 0); if( bDebug ){ - oputf("SQL: %s;\n", sSelect.z); + sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z); }else{ rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); } @@ -10234,7 +10272,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); } if( rc ){ - sputf(stdout, "Error: error code %d\n", rc); + sqlite3_fprintf(stdout, "Error: error code %d\n", rc); rc = 0; } if( pChng @@ -10266,7 +10304,7 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( pAuxDb->nSession ){ ii = sqlite3session_enable(pSession->p, ii); - oputf("session %s enable flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, "session %s enable flag = %d\n", pSession->zName, ii); } }else @@ -10301,7 +10339,7 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( pAuxDb->nSession ){ ii = sqlite3session_indirect(pSession->p, ii); - oputf("session %s indirect flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, "session %s indirect flag = %d\n", pSession->zName, ii); } }else @@ -10313,7 +10351,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCmd!=1 ) goto session_syntax_error; if( pAuxDb->nSession ){ ii = sqlite3session_isempty(pSession->p); - oputf("session %s isempty flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, "session %s isempty flag = %d\n", pSession->zName, ii); } }else @@ -10322,7 +10360,7 @@ static int do_meta_command(char *zLine, ShellState *p){ */ if( cli_strcmp(azCmd[0],"list")==0 ){ for(i=0; inSession; i++){ - oputf("%d %s\n", i, pAuxDb->aSession[i].zName); + sqlite3_fprintf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName); } }else @@ -10372,7 +10410,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int i, v; for(i=1; iout, "%s: %d 0x%x\n", azArg[i], v, v); } } if( cli_strncmp(azArg[0]+9, "integer", n-9)==0 ){ @@ -10381,7 +10419,7 @@ static int do_meta_command(char *zLine, ShellState *p){ char zBuf[200]; v = integerValue(azArg[i]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v); - oputz(zBuf); + sqlite3_fputs(zBuf, p->out); } } }else @@ -10454,10 +10492,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zAns==0 ) continue; k = 0; if( bVerbose>0 ){ - sputf(stdout, "%d: %s %s\n", tno, zOp, zSql); + sqlite3_fprintf(stdout, "%d: %s %s\n", tno, zOp, zSql); } if( cli_strcmp(zOp,"memo")==0 ){ - oputf("%s\n", zSql); + sqlite3_fprintf(p->out, "%s\n", zSql); }else if( cli_strcmp(zOp,"run")==0 ){ char *zErrMsg = 0; @@ -10466,18 +10504,18 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); nTest++; if( bVerbose ){ - oputf("Result: %s\n", str.z); + sqlite3_fprintf(p->out, "Result: %s\n", str.z); } if( rc || zErrMsg ){ nErr++; rc = 1; - oputf("%d: error-code-%d: %s\n", tno, rc, zErrMsg); + sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg); sqlite3_free(zErrMsg); }else if( cli_strcmp(zAns,str.z)!=0 ){ nErr++; rc = 1; - oputf("%d: Expected: [%s]\n", tno, zAns); - oputf("%d: Got: [%s]\n", tno, str.z); + sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns); + sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.z); } } else{ @@ -10489,7 +10527,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_finalize(pStmt); } /* End loop over k */ freeText(&str); - oputf("%d errors out of %d tests\n", nErr, nTest); + sqlite3_fprintf(p->out, "%d errors out of %d tests\n", nErr, nTest); }else if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){ @@ -10615,7 +10653,7 @@ static int do_meta_command(char *zLine, ShellState *p){ freeText(&sQuery); freeText(&sSql); if( bDebug ){ - oputf("%s\n", zSql); + sqlite3_fprintf(p->out, "%s\n", zSql); }else{ shell_exec(p, zSql, 0); } @@ -10645,7 +10683,7 @@ static int do_meta_command(char *zLine, ShellState *p){ "' OR ') as query, tname from tabcols group by tname)" , zRevText); shell_check_oom(zRevText); - if( bDebug ) oputf("%s\n", zRevText); + if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zRevText); lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0); if( lrc!=SQLITE_OK ){ /* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the @@ -10658,7 +10696,7 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0); sqlite3_stmt *pCheckStmt; lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0); - if( bDebug ) oputf("%s\n", zGenQuery); + if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zGenQuery); if( lrc!=SQLITE_OK ){ rc = 1; }else{ @@ -10717,46 +10755,46 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - oputf("%12.12s: %s\n","echo", + sqlite3_fprintf(p->out, "%12.12s: %s\n","echo", azBool[ShellHasFlag(p, SHFLG_Echo)]); - oputf("%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); - oputf("%12.12s: %s\n","explain", + sqlite3_fprintf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); + sqlite3_fprintf(p->out, "%12.12s: %s\n","explain", p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); - oputf("%12.12s: %s\n","headers", azBool[p->showHeader!=0]); + sqlite3_fprintf(p->out, "%12.12s: %s\n","headers", azBool[p->showHeader!=0]); if( p->mode==MODE_Column || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) ){ - oputf("%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", + sqlite3_fprintf(p->out, "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", modeDescr[p->mode], p->cmOpts.iWrap, p->cmOpts.bWordWrap ? "on" : "off", p->cmOpts.bQuote ? "" : "no"); }else{ - oputf("%12.12s: %s\n","mode", modeDescr[p->mode]); + sqlite3_fprintf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); } - oputf("%12.12s: ", "nullvalue"); - output_c_string(p->nullValue); - oputz("\n"); - oputf("%12.12s: %s\n","output", + sqlite3_fprintf(p->out, "%12.12s: ", "nullvalue"); + output_c_string(p->out, p->nullValue); + sqlite3_fputs("\n", p->out); + sqlite3_fprintf(p->out, "%12.12s: %s\n","output", strlen30(p->outfile) ? p->outfile : "stdout"); - oputf("%12.12s: ", "colseparator"); - output_c_string(p->colSeparator); - oputz("\n"); - oputf("%12.12s: ", "rowseparator"); - output_c_string(p->rowSeparator); - oputz("\n"); + sqlite3_fprintf(p->out, "%12.12s: ", "colseparator"); + output_c_string(p->out, p->colSeparator); + sqlite3_fputs("\n", p->out); + sqlite3_fprintf(p->out, "%12.12s: ", "rowseparator"); + output_c_string(p->out, p->rowSeparator); + sqlite3_fputs("\n", p->out); switch( p->statsOn ){ case 0: zOut = "off"; break; default: zOut = "on"; break; case 2: zOut = "stmt"; break; case 3: zOut = "vmstep"; break; } - oputf("%12.12s: %s\n","stats", zOut); - oputf("%12.12s: ", "width"); + sqlite3_fprintf(p->out, "%12.12s: %s\n","stats", zOut); + sqlite3_fprintf(p->out, "%12.12s: ", "width"); for (i=0;inWidth;i++) { - oputf("%d ", p->colWidth[i]); + sqlite3_fprintf(p->out, "%d ", p->colWidth[i]); } - oputz("\n"); - oputf("%12.12s: %s\n", "filename", + sqlite3_fputs("\n", p->out); + sqlite3_fprintf(p->out, "%12.12s: %s\n", "filename", p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : ""); }else @@ -10874,9 +10912,9 @@ static int do_meta_command(char *zLine, ShellState *p){ for(i=0; iout, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); } - oputz("\n"); + sqlite3_fputs("\n", p->out); } } @@ -10952,10 +10990,10 @@ static int do_meta_command(char *zLine, ShellState *p){ /* --help lists all test-controls */ if( cli_strcmp(zCmd,"help")==0 ){ - oputz("Available test-controls:\n"); + sqlite3_fputs("Available test-controls:\n", p->out); for(i=0; iout, " .testctrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); } rc = 1; @@ -11078,16 +11116,16 @@ static int do_meta_command(char *zLine, ShellState *p){ curOpt = ~newOpt; } if( newOpt==0 ){ - oputz("+All\n"); + sqlite3_fputs("+All\n", p->out); }else if( newOpt==0xffffffff ){ - oputz("-All\n"); + sqlite3_fputs("-All\n", p->out); }else{ int jj; for(jj=0; jjout, "%c%s\n", (newOpt & m)==0 ? '+' : '-', aLabel[jj].zLabel); } } @@ -11131,7 +11169,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3 *db; if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){ sqlite3_randomness(sizeof(ii),&ii); - sputf(stdout, "-- random seed: %d\n", ii); + sqlite3_fprintf(stdout, "-- random seed: %d\n", ii); } if( nArg==3 ){ db = 0; @@ -11199,7 +11237,7 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_SEEK_COUNT: { u64 x = 0; rc2 = sqlite3_test_control(testctrl, p->db, &x); - oputf("%llu\n", x); + sqlite3_fprintf(p->out, "%llu\n", x); isOk = 3; break; } @@ -11230,11 +11268,11 @@ static int do_meta_command(char *zLine, ShellState *p){ int val = 0; rc2 = sqlite3_test_control(testctrl, -id, &val); if( rc2!=SQLITE_OK ) break; - if( id>1 ) oputz(" "); - oputf("%d: %d", id, val); + if( id>1 ) sqlite3_fputs(" ", p->out); + sqlite3_fprintf(p->out, "%d: %d", id, val); id++; } - if( id>1 ) oputz("\n"); + if( id>1 ) sqlite3_fputs("\n", p->out); isOk = 3; } break; @@ -11276,14 +11314,22 @@ static int do_meta_command(char *zLine, ShellState *p){ faultsim_state.nHit = 0; sqlite3_test_control(testctrl, faultsim_callback); }else if( cli_strcmp(z,"status")==0 ){ - oputf("faultsim.iId: %d\n", faultsim_state.iId); - oputf("faultsim.iErr: %d\n", faultsim_state.iErr); - oputf("faultsim.iCnt: %d\n", faultsim_state.iCnt); - oputf("faultsim.nHit: %d\n", faultsim_state.nHit); - oputf("faultsim.iInterval: %d\n", faultsim_state.iInterval); - oputf("faultsim.eVerbose: %d\n", faultsim_state.eVerbose); - oputf("faultsim.nRepeat: %d\n", faultsim_state.nRepeat); - oputf("faultsim.nSkip: %d\n", faultsim_state.nSkip); + sqlite3_fprintf(p->out, "faultsim.iId: %d\n", + faultsim_state.iId); + sqlite3_fprintf(p->out, "faultsim.iErr: %d\n", + faultsim_state.iErr); + sqlite3_fprintf(p->out, "faultsim.iCnt: %d\n", + faultsim_state.iCnt); + sqlite3_fprintf(p->out, "faultsim.nHit: %d\n", + faultsim_state.nHit); + sqlite3_fprintf(p->out, "faultsim.iInterval: %d\n", + faultsim_state.iInterval); + sqlite3_fprintf(p->out, "faultsim.eVerbose: %d\n", + faultsim_state.eVerbose); + sqlite3_fprintf(p->out, "faultsim.nRepeat: %d\n", + faultsim_state.nRepeat); + sqlite3_fprintf(p->out, "faultsim.nSkip: %d\n", + faultsim_state.nSkip); }else if( cli_strcmp(z,"-v")==0 ){ if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++; }else if( cli_strcmp(z,"-q")==0 ){ @@ -11309,7 +11355,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( bShowHelp ){ - oputz( + sqlite3_fputs( "Usage: .testctrl fault_install ARGS\n" "Possible arguments:\n" " off Disable faultsim\n" @@ -11323,6 +11369,7 @@ static int do_meta_command(char *zLine, ShellState *p){ " --interval N Trigger only after every N-th call\n" " --repeat N Turn off after N hits. 0 means never\n" " --skip N Skip the first N encounters\n" + ,p->out ); } break; @@ -11330,12 +11377,13 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( isOk==0 && iCtrl>=0 ){ - oputf("Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); + sqlite3_fprintf(p->out, + "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); rc = 1; }else if( isOk==1 ){ - oputf("%d\n", rc2); + sqlite3_fprintf(p->out, "%d\n", rc2); }else if( isOk==2 ){ - oputf("0x%08x\n", rc2); + sqlite3_fprintf(p->out, "0x%08x\n", rc2); } }else #endif /* !defined(SQLITE_UNTESTABLE) */ @@ -11498,21 +11546,21 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){ char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit"; - oputf("SQLite %s %s\n" /*extra-version-info*/, + sqlite3_fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); #if SQLITE_HAVE_ZLIB - oputf("zlib version %s\n", zlibVersion()); + sqlite3_fprintf(p->out, "zlib version %s\n", zlibVersion()); #endif #define CTIMEOPT_VAL_(opt) #opt #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) #if defined(__clang__) && defined(__clang_major__) - oputf("clang-" CTIMEOPT_VAL(__clang_major__) "." + sqlite3_fprintf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." CTIMEOPT_VAL(__clang_minor__) "." CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz); #elif defined(_MSC_VER) - oputf("msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz); + sqlite3_fprintf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz); #elif defined(__GNUC__) && defined(__VERSION__) - oputf("gcc-" __VERSION__ " (%s)\n", zPtrSz); + sqlite3_fprintf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz); #endif }else @@ -11522,10 +11570,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->db ){ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); if( pVfs ){ - oputf("vfs.zName = \"%s\"\n", pVfs->zName); - oputf("vfs.iVersion = %d\n", pVfs->iVersion); - oputf("vfs.szOsFile = %d\n", pVfs->szOsFile); - oputf("vfs.mxPathname = %d\n", pVfs->mxPathname); + sqlite3_fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); + sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); + sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); + sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); } } }else @@ -11537,13 +11585,13 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent); } for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ - oputf("vfs.zName = \"%s\"%s\n", pVfs->zName, + sqlite3_fprintf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName, pVfs==pCurrent ? " <--- CURRENT" : ""); - oputf("vfs.iVersion = %d\n", pVfs->iVersion); - oputf("vfs.szOsFile = %d\n", pVfs->szOsFile); - oputf("vfs.mxPathname = %d\n", pVfs->mxPathname); + sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); + sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); + sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); if( pVfs->pNext ){ - oputz("-----------------------------------\n"); + sqlite3_fputs("-----------------------------------\n", p->out); } } }else @@ -11554,7 +11602,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->db ){ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); if( zVfsName ){ - oputf("%s\n", zVfsName); + sqlite3_fprintf(p->out, "%s\n", zVfsName); sqlite3_free(zVfsName); } } @@ -11863,7 +11911,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ sqlite3_snprintf(sizeof(zLineBuf), zLineBuf, "changes: %lld total_changes: %lld", sqlite3_changes64(p->db), sqlite3_total_changes64(p->db)); - oputf("%s\n", zLineBuf); + sqlite3_fprintf(p->out, "%s\n", zLineBuf); } if( doAutoDetectRestore(p, zSql) ) return 1; @@ -11871,7 +11919,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ } static void echo_group_input(ShellState *p, const char *zDo){ - if( ShellHasFlag(p, SHFLG_Echo) ) oputf("%s\n", zDo); + if( ShellHasFlag(p, SHFLG_Echo) ) sqlite3_fprintf(p->out, "%s\n", zDo); } #ifdef SQLITE_SHELL_FIDDLE @@ -11941,7 +11989,7 @@ static int process_input(ShellState *p){ zLine = one_input_line(p->in, zLine, nSql>0); if( zLine==0 ){ /* End of input */ - if( p->in==0 && stdin_is_interactive ) oputz("\n"); + if( p->in==0 && stdin_is_interactive ) sqlite3_fputs("\n", p->out); break; } if( seenInterrupt ){ @@ -12308,7 +12356,7 @@ static void printBold(const char *zText){ } #else static void printBold(const char *zText){ - sputf(stdout, "\033[1m%s\033[0m", zText); + sqlite3_fprintf(stdout, "\033[1m%s\033[0m", zText); } #endif @@ -12765,7 +12813,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( cli_strcmp(z,"-bail")==0 ){ /* No-op. The bail_on_error flag should already be set. */ }else if( cli_strcmp(z,"-version")==0 ){ - sputf(stdout, "%s %s (%d-bit)\n", + sqlite3_fprintf(stdout, "%s %s (%d-bit)\n", sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*)); return 0; }else if( cli_strcmp(z,"-interactive")==0 ){ @@ -12901,7 +12949,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #else # define SHELL_CIO_CHAR_SET "" #endif - sputf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/ + sqlite3_fprintf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/ "Enter \".help\" for usage hints.\n", sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET); if( warnInmemoryDb ){ @@ -13017,7 +13065,7 @@ sqlite3_vfs * fiddle_db_vfs(const char *zDbName){ /* Only for emcc experimentation purposes. */ sqlite3 * fiddle_db_arg(sqlite3 *arg){ - oputf("fiddle_db_arg(%p)\n", (const void*)arg); + sqlite3_fprintf(p->out, "fiddle_db_arg(%p)\n", (const void*)arg); return arg; } @@ -13054,7 +13102,7 @@ void fiddle_reset_db(void){ ** Resolve problem reported in ** https://sqlite.org/forum/forumpost/0b41a25d65 */ - oputz("Rolling back in-progress transaction.\n"); + sqlite3_fputs("Rolling back in-progress transaction.\n", stdout); sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0); } rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); From a55901a27cf3de084c906466f0e126e76be0de64 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 17:40:54 +0000 Subject: [PATCH 06/25] Port sqldiff over to use sqlite3_stdio. FossilOrigin-Name: 18f784c47d4252bc3696a7e084a1afb9f51f006cf2021292f2103531b8235226 --- Makefile.in | 4 +- Makefile.msc | 4 +- ext/misc/sqlite3_stdio.c | 19 ++++- ext/misc/sqlite3_stdio.h | 3 + main.mk | 4 +- manifest | 22 +++--- manifest.uuid | 2 +- tool/sqldiff.c | 150 ++++++++++++++++++--------------------- 8 files changed, 106 insertions(+), 102 deletions(-) diff --git a/Makefile.in b/Makefile.in index 5abe3bf6d3..6fc821da23 100644 --- a/Makefile.in +++ b/Makefile.in @@ -694,8 +694,8 @@ sqlite3$(TEXE): shell.c sqlite3.c shell.c sqlite3.c \ $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" -sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h - $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) +sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.lo sqlite3.h + $(LTLINK) -I$(TOP)/ext/misc -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h $(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS) diff --git a/Makefile.msc b/Makefile.msc index be6a771639..cc0285bb2c 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1861,8 +1861,8 @@ $(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLIT /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) # <> -sqldiff.exe: $(TOP)\tool\sqldiff.c $(TOP)\ext\consio\console_io.h $(TOP)\ext\consio\console_io.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) - $(LTLINK) $(NO_WARN) -I$(TOP)\ext\consio $(TOP)\tool\sqldiff.c $(TOP)\ext\consio\console_io.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS) +sqldiff.exe: $(TOP)\tool\sqldiff.c $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) + $(LTLINK) $(NO_WARN) -I$(TOP)\ext\misc $(TOP)\tool\sqldiff.c $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS) dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) diff --git a/ext/misc/sqlite3_stdio.c b/ext/misc/sqlite3_stdio.c index 0cfa26673a..6b7beff4e6 100644 --- a/ext/misc/sqlite3_stdio.c +++ b/ext/misc/sqlite3_stdio.c @@ -14,6 +14,19 @@ ** on Windows. */ #ifdef _WIN32 /* This file is a no-op on all platforms except Windows */ +#include "sqlite3_stdio.h" +#undef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include "sqlite3.h" +#include +#include +#include +#include /* ** Work-alike for the fopen() routine from the standard C library. @@ -68,7 +81,7 @@ FILE *sqlite3_popen(const char *zCommand, const char *zMode){ ** Work-alike for fgets() from the standard C library. */ char *sqlite3_fgets(char *buf, int sz, FILE *in){ - if( isatty(_fileno(in)) ){ + if( _isatty(_fileno(in)) ){ /* When reading from the command-prompt in Windows, it is necessary ** to use _O_WTEXT input mode to read UTF-16 characters, then translate ** that into UTF-8. Otherwise, non-ASCII characters all get translated @@ -95,7 +108,7 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){ ** Work-alike for fputs() from the standard C library. */ int sqlite3_fputs(const char *z, FILE *out){ - if( isatty(_fileno(out)) ){ + if( _isatty(_fileno(out)) ){ /* When writing to the command-prompt in Windows, it is necessary ** to use _O_WTEXT input mode and write UTF-16 characters. */ @@ -121,7 +134,7 @@ int sqlite3_fputs(const char *z, FILE *out){ */ int sqlite3_fprintf(FILE *out, const char *zFormat, ...){ int rc; - if( isatty(fileno(out)) ){ + if( _isatty(fileno(out)) ){ /* When writing to the command-prompt in Windows, it is necessary ** to use _O_WTEXT input mode and write UTF-16 characters. */ diff --git a/ext/misc/sqlite3_stdio.h b/ext/misc/sqlite3_stdio.h index 3014c1b287..dd0eefad04 100644 --- a/ext/misc/sqlite3_stdio.h +++ b/ext/misc/sqlite3_stdio.h @@ -26,6 +26,8 @@ ** also link in the accompanying sqlite3_stdio.c source file when compiling ** to get compatible interfaces. */ +#ifndef _SQLITE3_STDIO_H_ +#define _SQLITE3_STDIO_H_ 1 #ifdef _WIN32 /**** Definitions For Windows ****/ #include @@ -50,3 +52,4 @@ void sqlite3_fsetmode(FILE *stream, int mode); #define sqlite3_fsetmode(F,X) /*no-op*/ #endif +#endif /* _SQLITE3_STDIO_H_ */ diff --git a/main.mk b/main.mk index 2d616a6167..f0f41736d1 100644 --- a/main.mk +++ b/main.mk @@ -560,8 +560,8 @@ sqlite3$(EXE): sqlite3.h libsqlite3.a shell.c $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \ shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) -sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h - $(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ +sqldiff$(EXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.c sqlite3.h + $(TCCX) -I$(TOP)/ext/misc -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB) dbhash$(EXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h diff --git a/manifest b/manifest index 5e7518fc0c..728db2c94e 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Get\soutput\sredirection\sworking\sagain\sin\sthe\sCLI. -D 2024-09-24T16:09:50.466 +C Port\ssqldiff\sover\sto\suse\ssqlite3_stdio. +D 2024-09-24T17:40:54.086 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in a8e1d44a1166b6fb368effb19edc9adf7fede9225e9563352b9bb1989cd0150d +F Makefile.in 6a826facc78c3c8ad38bf00ed588f6aa3665ccd7a9749b891d20582fc290c77e F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 -F Makefile.msc 1a5234794c9a5a71ba13fb47bcf031814d45b3ed6a56b4cb8e9f63fd32b4febe +F Makefile.msc 10fcf3b1eff1859846878469ffad1ebcd168fa0bd9e8a81f76ce65465b79e35d F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -425,8 +425,8 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 -F ext/misc/sqlite3_stdio.c 4d4190eac193a8ea8fc3f8259e0996cf8e54254b4f4925d71e456e88165401d8 -F ext/misc/sqlite3_stdio.h ddefddeb448eee7fe2d41a828356a0019f813a4ced4ea2e97faa1d6c3e803742 +F ext/misc/sqlite3_stdio.c d9c7b3883788ef6e15134323783d6a3c69d2b453545a2aa60d8a3503bfeadcb7 +F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc F ext/misc/templatevtab.c 10f15b165b95423ddef593bc5dcb915ec4eb5e0f1066d585e5435a368b8bc22b @@ -689,7 +689,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk dcb5cbba0ad64bd639b3e05d73d92e27c144a55bab9fca3460699602f4e9f4c2 +F main.mk 0a55ebec3508ca1bdb593d86f3aa19d7fa42a2ddd3220703e6dc0a65f1338a43 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2175,7 +2175,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 -F tool/sqldiff.c 847fc8fcfddf5ce4797b7394cad6372f2f5dc17d8186e2ef8fb44d50fae4f44a +F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b F tool/sqlite3-rsync.c 187b262035c1159b047dbfa1959c168b87b5a153b63465e8c8bd1b54fabf4460 F tool/sqlite3_analyzer.c.in 8da2b08f56eeac331a715036cf707cc20f879f231362be0c22efd682e2b89b4f F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fcd0ecffc9889f8c855ea340f075ec42cdca482df82d6e67dc9c32613e8d5846 -R bfd2b7dbaf4f82e5e4b17d1ed0ea1a8f +P 086034c3508d95e4f620c5e0580fae770e85410b0c8bd94f600fc0fd25088947 +R d688762d4b1334b98cdf41bc1c1c4c96 U drh -Z 5097f278634497c50b8747316810c634 +Z 9855069890c5f74ec21934036ad0fa9f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ad785fcbcd..f7119b107e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -086034c3508d95e4f620c5e0580fae770e85410b0c8bd94f600fc0fd25088947 +18f784c47d4252bc3696a7e084a1afb9f51f006cf2021292f2103531b8235226 diff --git a/tool/sqldiff.c b/tool/sqldiff.c index 8b2293cafd..bb26daf139 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -14,7 +14,7 @@ ** between two SQLite databases. ** ** To compile, simply link against SQLite. (Windows builds must also link -** against ext/consio/console_io.c.) +** against ext/misc/sqlite3_stdio.c.) ** ** See the showHelp() routine below for a brief description of how to ** run the utility. @@ -26,19 +26,7 @@ #include #include #include "sqlite3.h" - -/* Output function substitutions that cause UTF8 characters to be rendered -** correctly on Windows: -** -** fprintf() -> Wfprintf() -** -*/ -#if defined(_WIN32) -# include "console_io.h" -# define Wfprintf fPrintfUtf8 -#else -# define Wfprintf fprintf -#endif +#include "sqlite3_stdio.h" /* ** All global variables are gathered into the "g" singleton. @@ -76,9 +64,9 @@ static void cmdlineError(const char *zFormat, ...){ va_start(ap, zFormat); sqlite3_str_vappendf(pOut, zFormat, ap); va_end(ap); - Wfprintf(stderr, "%s: %s\n", g.zArgv0, sqlite3_str_value(pOut)); + sqlite3_fprintf(stderr, "%s: %s\n", g.zArgv0, sqlite3_str_value(pOut)); strFree(pOut); - Wfprintf(stderr, "\"%s --help\" for more help\n", g.zArgv0); + sqlite3_fprintf(stderr, "\"%s --help\" for more help\n", g.zArgv0); exit(1); } @@ -92,7 +80,7 @@ static void runtimeError(const char *zFormat, ...){ va_start(ap, zFormat); sqlite3_str_vappendf(pOut, zFormat, ap); va_end(ap); - Wfprintf(stderr, "%s: %s\n", g.zArgv0, sqlite3_str_value(pOut)); + sqlite3_fprintf(stderr, "%s: %s\n", g.zArgv0, sqlite3_str_value(pOut)); strFree(pOut); exit(1); } @@ -349,11 +337,11 @@ static void printQuoted(FILE *out, sqlite3_value *X){ char zBuf[50]; r1 = sqlite3_value_double(X); sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); - fprintf(out, "%s", zBuf); + sqlite3_fprintf(out, "%s", zBuf); break; } case SQLITE_INTEGER: { - fprintf(out, "%lld", sqlite3_value_int64(X)); + sqlite3_fprintf(out, "%lld", sqlite3_value_int64(X)); break; } case SQLITE_BLOB: { @@ -361,14 +349,14 @@ static void printQuoted(FILE *out, sqlite3_value *X){ int nBlob = sqlite3_value_bytes(X); if( zBlob ){ int i; - fprintf(out, "x'"); + sqlite3_fprintf(out, "x'"); for(i=0; iinctl ){ inctl = ctl; - fprintf(out, "%.*s'||X'%02x", i-j, &zArg[j], c); + sqlite3_fprintf(out, "%.*s'||X'%02x", i-j, &zArg[j], c); j = i+1; }else if( ctl ){ - fprintf(out, "%02x", c); + sqlite3_fprintf(out, "%02x", c); j = i+1; }else{ if( inctl ){ inctl = 0; - fprintf(out, "'\n||'"); + sqlite3_fprintf(out, "'\n||'"); } if( c=='\'' ){ - fprintf(out, "%.*s'", i-j+1, &zArg[j]); + sqlite3_fprintf(out, "%.*s'", i-j+1, &zArg[j]); j = i+1; } } } - fprintf(out, "%s'", &zArg[j]); + sqlite3_fprintf(out, "%s'", &zArg[j]); } break; } case SQLITE_NULL: { - fprintf(out, "NULL"); + sqlite3_fprintf(out, "NULL"); break; } } @@ -428,7 +416,7 @@ static void dump_table(const char *zTab, FILE *out){ pStmt = db_prepare("SELECT sql FROM aux.sqlite_schema WHERE name=%Q", zTab); if( SQLITE_ROW==sqlite3_step(pStmt) ){ - fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0)); + sqlite3_fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0)); } sqlite3_finalize(pStmt); if( !g.bSchemaOnly ){ @@ -463,14 +451,14 @@ static void dump_table(const char *zTab, FILE *out){ } nCol = sqlite3_column_count(pStmt); while( SQLITE_ROW==sqlite3_step(pStmt) ){ - Wfprintf(out, "%s",sqlite3_str_value(pIns)); + sqlite3_fprintf(out, "%s",sqlite3_str_value(pIns)); zSep = "("; for(i=0; i0 ) fprintf(out, ", "); + if( i>0 ) sqlite3_fprintf(out, ", "); printQuoted(out, sqlite3_column_value(pStmt, i)); } }else{ @@ -1320,9 +1308,9 @@ static void rbudiff_one_table(const char *zTab, FILE *out){ nDelta = rbuDeltaCreate(aSrc, nSrc, aFinal, nFinal, aDelta); if( nDelta Date: Tue, 24 Sep 2024 17:49:06 +0000 Subject: [PATCH 07/25] Port sqlite3_analyzer.exe to use sqlite3_stdio. FossilOrigin-Name: 7c1c1226d803dbaf8e75085b1cc2aad88aef4c3168288e587c8c736633d09054 --- Makefile.msc | 2 +- ext/misc/sqlite3_stdio.c | 2 ++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/sqlite3_analyzer.c.in | 8 ++++---- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index cc0285bb2c..60669993c1 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2624,7 +2624,7 @@ smoketest: $(TESTPROGS) shelltest: $(TESTPROGS) .\testfixture.exe $(TOP)\test\permutations.test shell -sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(TOP)\ext\consio\console_io.h $(TOP)\ext\consio\console_io.c $(SQLITE_TCL_DEP) +sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(TOP)\ext\misc\sqlite3_stdio.h $(TOP)\ext\misc\sqlite3_stdio.c $(SQLITE_TCL_DEP) $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS) diff --git a/ext/misc/sqlite3_stdio.c b/ext/misc/sqlite3_stdio.c index 6b7beff4e6..5447faadf7 100644 --- a/ext/misc/sqlite3_stdio.c +++ b/ext/misc/sqlite3_stdio.c @@ -14,7 +14,9 @@ ** on Windows. */ #ifdef _WIN32 /* This file is a no-op on all platforms except Windows */ +#ifndef _SQLITE3_STDIO_H_ #include "sqlite3_stdio.h" +#endif #undef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #include diff --git a/manifest b/manifest index 728db2c94e..4679c11a96 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Port\ssqldiff\sover\sto\suse\ssqlite3_stdio. -D 2024-09-24T17:40:54.086 +C Port\ssqlite3_analyzer.exe\sto\suse\ssqlite3_stdio. +D 2024-09-24T17:49:06.245 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 6a826facc78c3c8ad38bf00ed588f6aa3665ccd7a9749b891d20582fc290c77e F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 -F Makefile.msc 10fcf3b1eff1859846878469ffad1ebcd168fa0bd9e8a81f76ce65465b79e35d +F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -425,7 +425,7 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 -F ext/misc/sqlite3_stdio.c d9c7b3883788ef6e15134323783d6a3c69d2b453545a2aa60d8a3503bfeadcb7 +F ext/misc/sqlite3_stdio.c aefcfaeefdee26eae2c0d94e41d3720d86b1dc5c96e70132366ab1e204f9ef92 F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc @@ -2177,7 +2177,7 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b F tool/sqlite3-rsync.c 187b262035c1159b047dbfa1959c168b87b5a153b63465e8c8bd1b54fabf4460 -F tool/sqlite3_analyzer.c.in 8da2b08f56eeac331a715036cf707cc20f879f231362be0c22efd682e2b89b4f +F tool/sqlite3_analyzer.c.in 348ba349bbdc93c9866439f9f935d7284866a2a4e6898bc906ae1204ade56918 F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c 41c586dee84d0b190ad13e0282ed83d4a65ec9fefde9adf4943efdf6558eea7f @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 086034c3508d95e4f620c5e0580fae770e85410b0c8bd94f600fc0fd25088947 -R d688762d4b1334b98cdf41bc1c1c4c96 +P 18f784c47d4252bc3696a7e084a1afb9f51f006cf2021292f2103531b8235226 +R f37703682204a6532c10f65be42e5cd4 U drh -Z 9855069890c5f74ec21934036ad0fa9f +Z 64787aa4f9a8932f50b4106ef4d8ed62 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f7119b107e..c8fe7fce57 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18f784c47d4252bc3696a7e084a1afb9f51f006cf2021292f2103531b8235226 +7c1c1226d803dbaf8e75085b1cc2aad88aef4c3168288e587c8c736633d09054 diff --git a/tool/sqlite3_analyzer.c.in b/tool/sqlite3_analyzer.c.in index 2d799ed250..1c9fc836a1 100644 --- a/tool/sqlite3_analyzer.c.in +++ b/tool/sqlite3_analyzer.c.in @@ -20,8 +20,8 @@ INCLUDE sqlite3.c INCLUDE $ROOT/src/tclsqlite.c #if defined(_WIN32) -INCLUDE $ROOT/ext/consio/console_io.h -INCLUDE $ROOT/ext/consio/console_io.c +INCLUDE $ROOT/ext/misc/sqlite3_stdio.h +INCLUDE $ROOT/ext/misc/sqlite3_stdio.c /* Substitute "puts" command. Only these forms recognized: ** @@ -56,8 +56,8 @@ static int subst_puts( return TCL_ERROR; } } - fPutsUtf8(zOut, pOut); - if( addNewLine ) fPutsUtf8("\n", pOut); + sqlite3_fputs(zOut, pOut); + if( addNewLine ) sqlite3_fputs("\n", pOut); return TCL_OK; } #endif /* defined(_WIN32) */ From 63558eae548343ad9990b48f4f0874404dc7d101 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 18:01:50 +0000 Subject: [PATCH 08/25] Get fiddle working again on this branch. FossilOrigin-Name: 0f228317c6ea1388d82df46f44c166b2aa9be63361ff9b81569ebee63c930f2e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4679c11a96..47bc7a854d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Port\ssqlite3_analyzer.exe\sto\suse\ssqlite3_stdio. -D 2024-09-24T17:49:06.245 +C Get\sfiddle\sworking\sagain\son\sthis\sbranch. +D 2024-09-24T18:01:50.659 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c b2cd748488012312824508639b6af908461e45403037d5c4e19d9b0e8195507f F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in b3b0aed1b1050da8d70734b1a4bdc4a4679a73f37b2593f276e5a5f71a6fca2a +F src/shell.c.in 2774f5af2edc468b272a14b3aec7f3c3c63bfe977f4db8c69a900433ec2b1e4f F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 18f784c47d4252bc3696a7e084a1afb9f51f006cf2021292f2103531b8235226 -R f37703682204a6532c10f65be42e5cd4 +P 7c1c1226d803dbaf8e75085b1cc2aad88aef4c3168288e587c8c736633d09054 +R c097c41ad97afac2d584ca3114783cc7 U drh -Z 64787aa4f9a8932f50b4106ef4d8ed62 +Z de72510160f83f54a6026486570e81b8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c8fe7fce57..a6d9dfda23 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c1c1226d803dbaf8e75085b1cc2aad88aef4c3168288e587c8c736633d09054 +0f228317c6ea1388d82df46f44c166b2aa9be63361ff9b81569ebee63c930f2e diff --git a/src/shell.c.in b/src/shell.c.in index 4c2ca65d83..4b799838da 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -13065,7 +13065,7 @@ sqlite3_vfs * fiddle_db_vfs(const char *zDbName){ /* Only for emcc experimentation purposes. */ sqlite3 * fiddle_db_arg(sqlite3 *arg){ - sqlite3_fprintf(p->out, "fiddle_db_arg(%p)\n", (const void*)arg); + sqlite3_fprintf(stdout, "fiddle_db_arg(%p)\n", (const void*)arg); return arg; } From 697c3fb25b521dd3b57de253b98cd17ca4dd4351 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 19:19:53 +0000 Subject: [PATCH 09/25] Fix error messages in the shell. FossilOrigin-Name: aeef82e974c24071e3211588001a92c7f122fbaf02d9dcf7fa5aaf30d2729f64 --- manifest | 12 +-- manifest.uuid | 2 +- src/shell.c.in | 238 +++++++++++++++++++++++++------------------------ 3 files changed, 127 insertions(+), 125 deletions(-) diff --git a/manifest b/manifest index 47bc7a854d..f7a7dc5ef4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sfiddle\sworking\sagain\son\sthis\sbranch. -D 2024-09-24T18:01:50.659 +C Fix\serror\smessages\sin\sthe\sshell. +D 2024-09-24T19:19:53.992 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c b2cd748488012312824508639b6af908461e45403037d5c4e19d9b0e8195507f F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 2774f5af2edc468b272a14b3aec7f3c3c63bfe977f4db8c69a900433ec2b1e4f +F src/shell.c.in 38a38100356134f962b3f72e1e3a44da014dee4f044b81438273aa5b0b5e7469 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7c1c1226d803dbaf8e75085b1cc2aad88aef4c3168288e587c8c736633d09054 -R c097c41ad97afac2d584ca3114783cc7 +P 0f228317c6ea1388d82df46f44c166b2aa9be63361ff9b81569ebee63c930f2e +R d40ea38d7142da3f67c791f2921da224 U drh -Z de72510160f83f54a6026486570e81b8 +Z 6cd8755ee2455e78de1e4ba9f17c392f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a6d9dfda23..66bec0a036 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f228317c6ea1388d82df46f44c166b2aa9be63361ff9b81569ebee63c930f2e +aeef82e974c24071e3211588001a92c7f122fbaf02d9dcf7fa5aaf30d2729f64 diff --git a/src/shell.c.in b/src/shell.c.in index 4b799838da..48234b7d31 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -250,7 +250,6 @@ INCLUDE ../ext/misc/sqlite3_stdio.c # define SQLITE_CIO_NO_FLUSH #endif -#define eputf(fmt, ...) sqlite3_fprintf(stderr,fmt,__VA_ARGS__) #define eputz(z) sqlite3_fputs(z,stderr) #define sputz(fp,z) sqlite3_fputs(z,fp) @@ -1503,7 +1502,7 @@ static void failIfSafeMode( va_start(ap, zErrMsg); zMsg = sqlite3_vmprintf(zErrMsg, ap); va_end(ap); - eputf("line %d: %s\n", p->lineno, zMsg); + sqlite3_fprintf(stderr, "line %d: %s\n", p->lineno, zMsg); exit(1); } } @@ -2838,7 +2837,7 @@ static void createSelftestTable(ShellState *p){ "DROP TABLE [_shell$self];" ,0,0,&zErrMsg); if( zErrMsg ){ - eputf("SELFTEST initialization failure: %s\n", zErrMsg); + sqlite3_fprintf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg); sqlite3_free(zErrMsg); } sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0); @@ -4190,18 +4189,18 @@ static int expertDotCommand( } else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){ if( i==(nArg-1) ){ - eputf("option requires an argument: %s\n", z); + sqlite3_fprintf(stderr, "option requires an argument: %s\n", z); rc = SQLITE_ERROR; }else{ iSample = (int)integerValue(azArg[++i]); if( iSample<0 || iSample>100 ){ - eputf("value out of range: %s\n", azArg[i]); + sqlite3_fprintf(stderr,"value out of range: %s\n", azArg[i]); rc = SQLITE_ERROR; } } } else{ - eputf("unknown option: %s\n", z); + sqlite3_fprintf(stderr,"unknown option: %s\n", z); rc = SQLITE_ERROR; } } @@ -4209,7 +4208,7 @@ static int expertDotCommand( if( rc==SQLITE_OK ){ pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); if( pState->expert.pExpert==0 ){ - eputf("sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory"); + sqlite3_fprintf(stderr,"sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory"); rc = SQLITE_ERROR; }else{ sqlite3_expert_config( @@ -5099,7 +5098,7 @@ static char *readFile(const char *zName, int *pnByte){ if( in==0 ) return 0; rc = fseek(in, 0, SEEK_END); if( rc!=0 ){ - eputf("Error: '%s' not seekable\n", zName); + sqlite3_fprintf(stderr,"Error: '%s' not seekable\n", zName); fclose(in); return 0; } @@ -5115,7 +5114,7 @@ static char *readFile(const char *zName, int *pnByte){ fclose(in); if( nRead!=1 ){ sqlite3_free(pBuf); - eputf("Error: cannot read '%s'\n", zName); + sqlite3_fprintf(stderr,"Error: cannot read '%s'\n", zName); return 0; } pBuf[nIn] = 0; @@ -5236,7 +5235,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ if( zDbFilename ){ in = sqlite3_fopen(zDbFilename, "r"); if( in==0 ){ - eputf("cannot open \"%s\" for reading\n", zDbFilename); + sqlite3_fprintf(stderr,"cannot open \"%s\" for reading\n", zDbFilename); return 0; } nLine = 0; @@ -5299,7 +5298,7 @@ readHexDb_error: p->lineno = nLine; } sqlite3_free(a); - eputf("Error on line %d of --hexdb input\n", nLine); + sqlite3_fprintf(stderr,"Error on line %d of --hexdb input\n", nLine); return 0; } #endif /* SQLITE_OMIT_DESERIALIZE */ @@ -5374,7 +5373,7 @@ static void open_db(ShellState *p, int openFlags){ } } if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ - eputf("Error: unable to open database \"%s\": %s\n", + sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n", zDbFilename, sqlite3_errmsg(p->db)); if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){ exit(1); @@ -5386,7 +5385,7 @@ static void open_db(ShellState *p, int openFlags){ stderr); exit(1); }else{ - eputf("Notice: using substitute in-memory database instead of \"%s\"\n", + sqlite3_fprintf(stderr,"Notice: using substitute in-memory database instead of \"%s\"\n", zDbFilename); } } @@ -5498,7 +5497,7 @@ static void open_db(ShellState *p, int openFlags){ SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE); if( rc ){ - eputf("Error: sqlite3_deserialize() returns %d\n", rc); + sqlite3_fprintf(stderr,"Error: sqlite3_deserialize() returns %d\n", rc); } if( p->szMax>0 ){ sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax); @@ -5522,7 +5521,7 @@ static void open_db(ShellState *p, int openFlags){ void close_db(sqlite3 *db){ int rc = sqlite3_close(db); if( rc ){ - eputf("Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); } } @@ -5686,7 +5685,7 @@ static int booleanValue(const char *zArg){ if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ return 0; } - eputf("ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg); + sqlite3_fprintf(stderr,"ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg); return 0; } @@ -5724,7 +5723,7 @@ static FILE *output_file_open(const char *zFile, int bTextMode){ }else{ f = sqlite3_fopen(zFile, bTextMode ? "w" : "wb"); if( f==0 ){ - eputf("Error: cannot open \"%s\"\n", zFile); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile); } } return f; @@ -5889,10 +5888,11 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ break; } if( pc==cQuote && c!='\r' ){ - eputf("%s:%d: unescaped %c character\n", p->zFile, p->nLine, cQuote); + sqlite3_fprintf(stderr,"%s:%d: unescaped %c character\n", + p->zFile, p->nLine, cQuote); } if( c==EOF ){ - eputf("%s:%d: unterminated %c-quoted field\n", + sqlite3_fprintf(stderr,"%s:%d: unterminated %c-quoted field\n", p->zFile, startLine, cQuote); p->cTerm = c; break; @@ -5991,7 +5991,7 @@ static void tryToCloneData( shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - eputf("Error %d: %s on [%s]\n", + sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n", sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); goto end_data_xfer; } @@ -6008,7 +6008,7 @@ static void tryToCloneData( memcpy(zInsert+i, ");", 3); rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); if( rc ){ - eputf("Error %d: %s on [%s]\n", + sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n", sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zInsert); goto end_data_xfer; } @@ -6044,7 +6044,7 @@ static void tryToCloneData( } /* End for */ rc = sqlite3_step(pInsert); if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ - eputf("Error %d: %s\n", + sqlite3_fprintf(stderr,"Error %d: %s\n", sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb)); } sqlite3_reset(pInsert); @@ -6062,7 +6062,7 @@ static void tryToCloneData( shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - eputf("Warning: cannot step \"%s\" backwards", zTable); + sqlite3_fprintf(stderr,"Warning: cannot step \"%s\" backwards", zTable); break; } } /* End for(k=0...) */ @@ -6099,7 +6099,7 @@ static void tryToCloneSchema( shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - eputf("Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), + sqlite3_fprintf(stderr,"Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); goto end_schema_xfer; } @@ -6111,7 +6111,7 @@ static void tryToCloneSchema( sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout); sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); if( zErrMsg ){ - eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql); + sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql); sqlite3_free(zErrMsg); zErrMsg = 0; } @@ -6129,7 +6129,7 @@ static void tryToCloneSchema( shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - eputf("Error: (%d) %s on [%s]\n", + sqlite3_fprintf(stderr,"Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); goto end_schema_xfer; } @@ -6141,7 +6141,7 @@ static void tryToCloneSchema( sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout); sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); if( zErrMsg ){ - eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql); + sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql); sqlite3_free(zErrMsg); zErrMsg = 0; } @@ -6165,12 +6165,12 @@ static void tryToClone(ShellState *p, const char *zNewDb){ int rc; sqlite3 *newDb = 0; if( access(zNewDb,0)==0 ){ - eputf("File \"%s\" already exists.\n", zNewDb); + sqlite3_fprintf(stderr,"File \"%s\" already exists.\n", zNewDb); return; } rc = sqlite3_open(zNewDb, &newDb); if( rc ){ - eputf("Cannot create output database: %s\n", sqlite3_errmsg(newDb)); + sqlite3_fprintf(stderr,"Cannot create output database: %s\n", sqlite3_errmsg(newDb)); }else{ sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); @@ -6221,7 +6221,7 @@ static void output_reset(ShellState *p){ char *zCmd; zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile); if( system(zCmd) ){ - eputf("Failed: [%s]\n", zCmd); + sqlite3_fprintf(stderr,"Failed: [%s]\n", zCmd); }else{ /* Give the start/open/xdg-open command some time to get ** going before we continue, and potential delete the @@ -6311,7 +6311,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1", -1, &pStmt, 0); if( rc ){ - eputf("error: %s\n", sqlite3_errmsg(p->db)); + sqlite3_fprintf(stderr,"error: %s\n", sqlite3_errmsg(p->db)); sqlite3_finalize(pStmt); return 1; } @@ -6371,7 +6371,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ ** Print the given string as an error message. */ static void shellEmitError(const char *zErr){ - eputf("Error: %s\n", zErr); + sqlite3_fprintf(stderr,"Error: %s\n", zErr); } /* ** Print the current sqlite3_errmsg() value to stderr and return 1. @@ -6694,7 +6694,7 @@ static int lintFkeyIndexes( zIndent = " "; } else{ - eputf("Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); + sqlite3_fprintf(stderr,"Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); return SQLITE_ERROR; } } @@ -6762,16 +6762,16 @@ static int lintFkeyIndexes( sqlite3_free(zPrev); if( rc!=SQLITE_OK ){ - eputf("%s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); } rc2 = sqlite3_finalize(pSql); if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ rc = rc2; - eputf("%s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); } }else{ - eputf("%s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); } return rc; @@ -6807,7 +6807,7 @@ static void shellPrepare( if( *pRc==SQLITE_OK ){ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); if( rc!=SQLITE_OK ){ - eputf("sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); + sqlite3_fprintf(stderr,"sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); *pRc = rc; } } @@ -6851,7 +6851,7 @@ static void shellFinalize( int rc = sqlite3_finalize(pStmt); if( *pRc==SQLITE_OK ){ if( rc!=SQLITE_OK ){ - eputf("SQL error: %s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db)); } *pRc = rc; } @@ -6873,7 +6873,7 @@ void shellReset( if( *pRc==SQLITE_OK ){ if( rc!=SQLITE_OK ){ sqlite3 *db = sqlite3_db_handle(pStmt); - eputf("SQL error: %s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db)); } *pRc = rc; } @@ -7177,7 +7177,7 @@ static int arCheckEntries(ArCommand *pAr){ } shellReset(&rc, pTest); if( rc==SQLITE_OK && bOk==0 ){ - eputf("not found in archive: %s\n", z); + sqlite3_fprintf(stderr,"not found in archive: %s\n", z); rc = SQLITE_ERROR; } } @@ -7683,7 +7683,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ bRowids = 0; } else{ - eputf("unexpected option: %s\n", azArg[i]); + sqlite3_fprintf(stderr,"unexpected option: %s\n", azArg[i]); showHelp(pState->out, azArg[0]); return 1; } @@ -7702,7 +7702,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ if( sqlite3_recover_errcode(p)!=SQLITE_OK ){ const char *zErr = sqlite3_recover_errmsg(p); int errCode = sqlite3_recover_errcode(p); - eputf("sql error: %s (%d)\n", zErr, errCode); + sqlite3_fprintf(stderr,"sql error: %s (%d)\n", zErr, errCode); } rc = sqlite3_recover_finish(p); return rc; @@ -7734,7 +7734,7 @@ static int intckDatabaseCmd(ShellState *pState, i64 nStepPerUnlock){ } rc = sqlite3_intck_error(p, &zErr); if( zErr ){ - eputf("%s\n", zErr); + sqlite3_fprintf(stderr,"%s\n", zErr); } sqlite3_intck_close(p); @@ -7761,7 +7761,7 @@ static int intckDatabaseCmd(ShellState *pState, i64 nStepPerUnlock){ #define rc_err_oom_die(rc) \ if( rc==SQLITE_NOMEM ) shell_check_oom(0); \ else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \ - eputf("E:%d\n",rc), assert(0) + sqlite3_fprintf(stderr,"E:%d\n",rc), assert(0) #else static void rc_err_oom_die(int rc){ if( rc==SQLITE_NOMEM ) shell_check_oom(0); @@ -8128,7 +8128,7 @@ static int do_meta_command(char *zLine, ShellState *p){ bAsync = 1; }else { - eputf("unknown option: %s\n", azArg[j]); + sqlite3_fprintf(stderr,"unknown option: %s\n", azArg[j]); return 1; } }else if( zDestFile==0 ){ @@ -8149,7 +8149,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_open_v2(zDestFile, &pDest, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs); if( rc!=SQLITE_OK ){ - eputf("Error: cannot open \"%s\"\n", zDestFile); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zDestFile); close_db(pDest); return 1; } @@ -8219,7 +8219,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = chdir(azArg[1]); #endif if( rc ){ - eputf("Cannot change to directory \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Cannot change to directory \"%s\"\n", azArg[1]); rc = 1; } }else{ @@ -8252,7 +8252,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ rc = 2; }else if( testcase_glob(azArg[1],zRes)==0 ){ - eputf("testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", + sqlite3_fprintf(stderr,"testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", p->zTestcase, azArg[1], zRes); rc = 1; }else{ @@ -8410,7 +8410,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg>1 ) break; } if( nArg>1 && ii==ArraySize(aDbConfig) ){ - eputf("Error: unknown dbconfig \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Error: unknown dbconfig \"%s\"\n", azArg[1]); eputz("Enter \".dbconfig\" with no arguments for a list\n"); } }else @@ -8460,7 +8460,7 @@ static int do_meta_command(char *zLine, ShellState *p){ ShellSetFlag(p, SHFLG_DumpNoSys); }else { - eputf("Unknown option \"%s\" on \".dump\"\n", azArg[i]); + sqlite3_fprintf(stderr,"Unknown option \"%s\" on \".dump\"\n", azArg[i]); rc = 1; sqlite3_free(zLike); goto meta_command_exit; @@ -8614,7 +8614,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifndef SQLITE_OMIT_VIRTUALTABLE if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ if( p->bSafeMode ){ - eputf("Cannot run experimental commands such as \"%s\" in safe mode\n", + sqlite3_fprintf(stderr,"Cannot run experimental commands such as \"%s\" in safe mode\n", azArg[0]); rc = 1; }else{ @@ -8688,7 +8688,7 @@ static int do_meta_command(char *zLine, ShellState *p){ filectrl = aCtrl[i].ctrlCode; iCtrl = i; }else{ - eputf("Error: ambiguous file-control: \"%s\"\n" + sqlite3_fprintf(stderr,"Error: ambiguous file-control: \"%s\"\n" "Use \".filectrl --help\" for help\n", zCmd); rc = 1; goto meta_command_exit; @@ -8696,7 +8696,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( filectrl<0 ){ - eputf("Error: unknown file-control: %s\n" + sqlite3_fprintf(stderr,"Error: unknown file-control: %s\n" "Use \".filectrl --help\" for help\n", zCmd); }else{ switch(filectrl){ @@ -8963,7 +8963,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sCtx.xCloser = fclose; } if( sCtx.in==0 ){ - eputf("Error: cannot open \"%s\"\n", zFile); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile); goto meta_command_exit; } if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){ @@ -9007,7 +9007,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } assert(dbCols==0); if( zColDefs==0 ){ - eputf("%s: empty file\n", sCtx.zFile); + sqlite3_fprintf(stderr,"%s: empty file\n", sCtx.zFile); import_cleanup(&sCtx); rc = 1; sqlite3_free(zCreate); @@ -9022,10 +9022,12 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_fprintf(p->out, "%s\n", zCreate); } rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); + if( rc ){ + sqlite3_fprintf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); + } sqlite3_free(zCreate); zCreate = 0; if( rc ){ - eputf("%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); import_cleanup(&sCtx); rc = 1; goto meta_command_exit; @@ -9119,7 +9121,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); if( i=nCol ){ sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); if( rc!=SQLITE_OK ){ - eputf("%s:%d: INSERT failed: %s\n", + sqlite3_fprintf(stderr,"%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, sqlite3_errmsg(p->db)); sCtx.nErr++; }else{ @@ -9167,7 +9169,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ int i; if( !ShellHasFlag(p,SHFLG_TestingMode) ){ - eputf(".%s unavailable without --unsafe-testing\n", + sqlite3_fprintf(stderr,".%s unavailable without --unsafe-testing\n", "imposter"); rc = 1; goto meta_command_exit; @@ -9233,7 +9235,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } sqlite3_finalize(pStmt); if( i==0 || tnum==0 ){ - eputf("no such index: \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"no such index: \"%s\"\n", azArg[1]); rc = 1; sqlite3_free(zCollist); goto meta_command_exit; @@ -9248,14 +9250,14 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); if( rc ){ - eputf("Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); + sqlite3_fprintf(stderr,"Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); }else{ sqlite3_fprintf(stdout, "%s;\n", zSql); sqlite3_fprintf(stdout, "WARNING: writing to an imposter table will corrupt" " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index"); } }else{ - eputf("SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); + sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); rc = 1; } sqlite3_free(zSql); @@ -9269,7 +9271,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( iArg==0 ) iArg = -1; } if( (nArg!=1 && nArg!=2) || iArg<0 ){ - eputf("%s","Usage: .intck STEPS_PER_UNLOCK\n"); + sqlite3_fprintf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n"); rc = 1; goto meta_command_exit; } @@ -9290,7 +9292,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ iotrace = sqlite3_fopen(azArg[1], "w"); if( iotrace==0 ){ - eputf("Error: cannot open \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); sqlite3IoTrace = 0; rc = 1; }else{ @@ -9337,14 +9339,14 @@ static int do_meta_command(char *zLine, ShellState *p){ if( iLimit<0 ){ iLimit = i; }else{ - eputf("ambiguous limit: \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"ambiguous limit: \"%s\"\n", azArg[1]); rc = 1; goto meta_command_exit; } } } if( iLimit<0 ){ - eputf("unknown limit: \"%s\"\n" + sqlite3_fprintf(stderr,"unknown limit: \"%s\"\n" "enter \".limits\" with no arguments for a list.\n", azArg[1]); rc = 1; @@ -9437,7 +9439,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( zTabname==0 ){ zTabname = z; }else if( z[0]=='-' ){ - eputf("unknown option: %s\n", z); + sqlite3_fprintf(stderr,"unknown option: %s\n", z); eputz("options:\n" " --noquote\n" " --quote\n" @@ -9447,7 +9449,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; }else{ - eputf("extra argument: \"%s\"\n", z); + sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z); rc = 1; goto meta_command_exit; } @@ -9535,7 +9537,7 @@ static int do_meta_command(char *zLine, ShellState *p){ eputz("Usage: .nonce NONCE\n"); rc = 1; }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){ - eputf("line %d: incorrect nonce: \"%s\"\n", + sqlite3_fprintf(stderr,"line %d: incorrect nonce: \"%s\"\n", p->lineno, azArg[1]); exit(1); }else{ @@ -9590,11 +9592,11 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif /* !SQLITE_SHELL_FIDDLE */ if( z[0]=='-' ){ - eputf("unknown option: %s\n", z); + sqlite3_fprintf(stderr,"unknown option: %s\n", z); rc = 1; goto meta_command_exit; }else if( zFN ){ - eputf("extra argument: \"%s\"\n", z); + sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z); rc = 1; goto meta_command_exit; }else{ @@ -9636,7 +9638,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->pAuxDb->zDbFilename = zNewFilename; open_db(p, OPEN_DB_KEEPALIVE); if( p->db==0 ){ - eputf("Error: cannot open '%s'\n", zNewFilename); + sqlite3_fprintf(stderr,"Error: cannot open '%s'\n", zNewFilename); sqlite3_free(zNewFilename); }else{ p->pAuxDb->zFreeOnClose = zNewFilename; @@ -9739,7 +9741,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #else FILE *pfPipe = sqlite3_popen(zFile + 1, "w"); if( pfPipe==0 ){ - eputf("Error: cannot open pipe \"%s\"\n", zFile + 1); + sqlite3_fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); rc = 1; }else{ output_redir(p, pfPipe); @@ -9751,7 +9753,7 @@ static int do_meta_command(char *zLine, ShellState *p){ FILE *pfFile = output_file_open(zFile, bTxtMode); if( pfFile==0 ){ if( cli_strcmp(zFile,"off")!=0 ){ - eputf("Error: cannot write to \"%s\"\n", zFile); + sqlite3_fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile); } rc = 1; } else { @@ -9911,7 +9913,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } continue; } - eputf("Error: unknown option: \"%s\"\n", azArg[i]); + sqlite3_fprintf(stderr,"Error: unknown option: \"%s\"\n", azArg[i]); rc = 1; goto meta_command_exit; }else{ @@ -9956,7 +9958,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #else p->in = sqlite3_popen(azArg[1]+1, "r"); if( p->in==0 ){ - eputf("Error: cannot open \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; }else{ rc = process_input(p); @@ -9964,7 +9966,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } #endif }else if( (p->in = openChrSource(azArg[1]))==0 ){ - eputf("Error: cannot open \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; }else{ rc = process_input(p); @@ -9997,7 +9999,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } rc = sqlite3_open(zSrcFile, &pSrc); if( rc!=SQLITE_OK ){ - eputf("Error: cannot open \"%s\"\n", zSrcFile); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zSrcFile); close_db(pSrc); return 1; } @@ -10080,7 +10082,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( optionMatch(azArg[ii],"nosys") ){ bNoSystemTabs = 1; }else if( azArg[ii][0]=='-' ){ - eputf("Unknown option: \"%s\"\n", azArg[ii]); + sqlite3_fprintf(stderr,"Unknown option: \"%s\"\n", azArg[ii]); rc = 1; goto meta_command_exit; }else if( zName==0 ){ @@ -10242,7 +10244,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ rc = sqlite3session_attach(pSession->p, azCmd[1]); if( rc ){ - eputf("ERROR: sqlite3session_attach() returns %d\n",rc); + sqlite3_fprintf(stderr,"ERROR: sqlite3session_attach() returns %d\n",rc); rc = 0; } } @@ -10261,7 +10263,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( pSession->p==0 ) goto session_not_open; out = sqlite3_fopen(azCmd[1], "wb"); if( out==0 ){ - eputf("ERROR: cannot open \"%s\" for writing\n", + sqlite3_fprintf(stderr,"ERROR: cannot open \"%s\" for writing\n", azCmd[1]); }else{ int szChng; @@ -10277,7 +10279,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } if( pChng && fwrite(pChng, szChng, 1, out)!=1 ){ - eputf("ERROR: Failed to write entire %d-byte output\n", szChng); + sqlite3_fprintf(stderr,"ERROR: Failed to write entire %d-byte output\n", szChng); } sqlite3_free(pChng); fclose(out); @@ -10375,18 +10377,18 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zName[0]==0 ) goto session_syntax_error; for(i=0; inSession; i++){ if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){ - eputf("Session \"%s\" already exists\n", zName); + sqlite3_fprintf(stderr,"Session \"%s\" already exists\n", zName); goto meta_command_exit; } } if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){ - eputf("Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); + sqlite3_fprintf(stderr,"Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); goto meta_command_exit; } pSession = &pAuxDb->aSession[pAuxDb->nSession]; rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); if( rc ){ - eputf("Cannot open session: error code=%d\n", rc); + sqlite3_fprintf(stderr,"Cannot open session: error code=%d\n", rc); rc = 0; goto meta_command_exit; } @@ -10446,7 +10448,7 @@ static int do_meta_command(char *zLine, ShellState *p){ bVerbose++; }else { - eputf("Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); + sqlite3_fprintf(stderr,"Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); eputz("Should be one of: --init -v\n"); rc = 1; goto meta_command_exit; @@ -10519,7 +10521,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } } else{ - eputf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno); + sqlite3_fprintf(stderr,"Unknown operation \"%s\" on selftest line %d\n", zOp, tno); rc = 1; break; } @@ -10575,7 +10577,7 @@ static int do_meta_command(char *zLine, ShellState *p){ bDebug = 1; }else { - eputf("Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); + sqlite3_fprintf(stderr,"Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); showHelp(p->out, azArg[0]); rc = 1; goto meta_command_exit; @@ -10704,7 +10706,7 @@ static int do_meta_command(char *zLine, ShellState *p){ double countIrreversible = sqlite3_column_double(pCheckStmt, 0); if( countIrreversible>0 ){ int sz = (int)(countIrreversible + 0.5); - eputf("Digest includes %d invalidly encoded text field%s.\n", + sqlite3_fprintf(stderr,"Digest includes %d invalidly encoded text field%s.\n", sz, (sz>1)? "s": ""); } } @@ -10742,7 +10744,7 @@ static int do_meta_command(char *zLine, ShellState *p){ x = zCmd!=0 ? system(zCmd) : 1; /*consoleRenewSetup();*/ sqlite3_free(zCmd); - if( x ) eputf("System command returns %d\n", x); + if( x ) sqlite3_fprintf(stderr,"System command returns %d\n", x); }else #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */ @@ -11010,7 +11012,7 @@ static int do_meta_command(char *zLine, ShellState *p){ testctrl = aCtrl[i].ctrlCode; iCtrl = i; }else{ - eputf("Error: ambiguous test-control: \"%s\"\n" + sqlite3_fprintf(stderr,"Error: ambiguous test-control: \"%s\"\n" "Use \".testctrl --help\" for help\n", zCmd); rc = 1; goto meta_command_exit; @@ -11018,7 +11020,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( testctrl<0 ){ - eputf("Error: unknown test-control: %s\n" + sqlite3_fprintf(stderr,"Error: unknown test-control: %s\n" "Use \".testctrl --help\" for help\n", zCmd); }else{ switch(testctrl){ @@ -11094,10 +11096,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break; } if( jj>=ArraySize(aLabel) ){ - eputf("Error: no such optimization: \"%s\"\n", zLabel); + sqlite3_fprintf(stderr,"Error: no such optimization: \"%s\"\n", zLabel); eputz("Should be one of:"); for(jj=0; jjdb, azArg[2], azArg[3], strlen30(azArg[3])); if( rc ){ - eputf("Authentication failed for user %s\n", azArg[2]); + sqlite3_fprintf(stderr,"Authentication failed for user %s\n", azArg[2]); rc = 1; } }else if( cli_strcmp(azArg[1],"add")==0 ){ @@ -11510,7 +11512,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]), booleanValue(azArg[4])); if( rc ){ - eputf("User-Add failed: %d\n", rc); + sqlite3_fprintf(stderr,"User-Add failed: %d\n", rc); rc = 1; } }else if( cli_strcmp(azArg[1],"edit")==0 ){ @@ -11522,7 +11524,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]), booleanValue(azArg[4])); if( rc ){ - eputf("User-Edit failed: %d\n", rc); + sqlite3_fprintf(stderr,"User-Edit failed: %d\n", rc); rc = 1; } }else if( cli_strcmp(azArg[1],"delete")==0 ){ @@ -11533,7 +11535,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } rc = sqlite3_user_delete(p->db, azArg[2]); if( rc ){ - eputf("User-Delete failed: %d\n", rc); + sqlite3_fprintf(stderr,"User-Delete failed: %d\n", rc); rc = 1; } }else{ @@ -11626,7 +11628,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else { - eputf("Error: unknown command or invalid arguments: " + sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: " " \"%s\". Enter \".help\" for help\n", azArg[0]); rc = 1; } @@ -11902,7 +11904,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType); } - eputf("%s %s\n", zPrefix, zErrorTail); + sqlite3_fprintf(stderr,"%s %s\n", zPrefix, zErrorTail); sqlite3_free(zErrMsg); zErrMsg = 0; return 1; @@ -11977,7 +11979,7 @@ static int process_input(ShellState *p){ if( p->inputNesting==MAX_INPUT_NESTING ){ /* This will be more informative in a later version. */ - eputf("Input nesting limit (%d) reached at line %d." + sqlite3_fprintf(stderr,"Input nesting limit (%d) reached at line %d." " Check recursion.\n", MAX_INPUT_NESTING, p->lineno); return 1; } @@ -12212,12 +12214,12 @@ static void process_sqliterc( p->in = sqlite3_fopen(sqliterc,"rb"); if( p->in ){ if( stdin_is_interactive ){ - eputf("-- Loading resources from %s\n", sqliterc); + sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc); } if( process_input(p) && bail_on_error ) exit(1); fclose(p->in); }else if( sqliterc_override!=0 ){ - eputf("cannot open: \"%s\"\n", sqliterc); + sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc); if( bail_on_error ) exit(1); } p->in = inSaved; @@ -12292,11 +12294,11 @@ static const char zOptions[] = #endif ; static void usage(int showDetail){ - eputf("Usage: %s [OPTIONS] [FILENAME [SQL]]\n" + sqlite3_fprintf(stderr,"Usage: %s [OPTIONS] [FILENAME [SQL]]\n" "FILENAME is the name of an SQLite database. A new database is created\n" "if the file does not previously exist. Defaults to :memory:.\n", Argv0); if( showDetail ){ - eputf("OPTIONS include:\n%s", zOptions); + sqlite3_fprintf(stderr,"OPTIONS include:\n%s", zOptions); }else{ eputz("Use the -help option for additional information\n"); } @@ -12366,7 +12368,7 @@ static void printBold(const char *zText){ */ static char *cmdline_option_value(int argc, char **argv, int i){ if( i==argc ){ - eputf("%s: Error: missing argument to %s\n", argv[0], argv[argc-1]); + sqlite3_fprintf(stderr,"%s: Error: missing argument to %s\n", argv[0], argv[argc-1]); exit(1); } return argv[i]; @@ -12435,7 +12437,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #if !defined(_WIN32_WCE) if( getenv("SQLITE_DEBUG_BREAK") ){ if( isatty(0) && isatty(2) ){ - eputf("attach debugger to process %d and press any key to continue.\n", + sqlite3_fprintf(stderr,"attach debugger to process %d and press any key to continue.\n", GETPID()); fgetc(stdin); }else{ @@ -12462,7 +12464,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #if USE_SYSTEM_SQLITE+0!=1 if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ - eputf("SQLite header and source version mismatch\n%s\n%s\n", + sqlite3_fprintf(stderr,"SQLite header and source version mismatch\n%s\n%s\n", sqlite3_sourceid(), SQLITE_SOURCE_ID); exit(1); } @@ -12686,7 +12688,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( pVfs ){ sqlite3_vfs_register(pVfs, 1); }else{ - eputf("no such VFS: \"%s\"\n", zVfs); + sqlite3_fprintf(stderr,"no such VFS: \"%s\"\n", zVfs); exit(1); } } @@ -12696,7 +12698,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ data.pAuxDb->zDbFilename = ":memory:"; warnInmemoryDb = argc==1; #else - eputf("%s: Error: no database filename specified\n", Argv0); + sqlite3_fprintf(stderr,"%s: Error: no database filename specified\n", Argv0); return 1; #endif } @@ -12876,14 +12878,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ shellEmitError(zErrMsg); if( bail_on_error ) return rc!=0 ? rc : 1; }else if( rc!=0 ){ - eputf("Error: unable to process SQL \"%s\"\n", z); + sqlite3_fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z); if( bail_on_error ) return rc; } } #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) }else if( cli_strncmp(z, "-A", 2)==0 ){ if( nCmd>0 ){ - eputf("Error: cannot mix regular SQL or dot-commands" + sqlite3_fprintf(stderr,"Error: cannot mix regular SQL or dot-commands" " with \"%s\"\n", z); return 1; } @@ -12902,7 +12904,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( cli_strcmp(z,"-unsafe-testing")==0 ){ /* Acted upon in first pass. */ }else{ - eputf("%s: Error: unknown option: %s\n", Argv0, z); + sqlite3_fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); eputz("Use -help for a list of options.\n"); return 1; } @@ -12929,7 +12931,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( zErrMsg!=0 ){ shellEmitError(zErrMsg); }else{ - eputf("Error: unable to process SQL: %s\n", azCmd[i]); + sqlite3_fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]); } sqlite3_free(zErrMsg); if( rc==0 ) rc = 1; @@ -13025,7 +13027,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } #ifdef SQLITE_DEBUG if( sqlite3_memory_used()>mem_main_enter ){ - eputf("Memory leaked: %u bytes\n", + sqlite3_fprintf(stderr,"Memory leaked: %u bytes\n", (unsigned int)(sqlite3_memory_used()-mem_main_enter)); } #endif From 18e2ace4681c6b1d4950811a6123c014ba0fbab0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 19:47:12 +0000 Subject: [PATCH 10/25] Fix over-length lines in the shell source code. FossilOrigin-Name: f3fdf76a0d3abeb5202f2b6f26318815396da7df680073955bde60b13f84e797 --- manifest | 12 ++--- manifest.uuid | 2 +- src/shell.c.in | 140 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 99 insertions(+), 55 deletions(-) diff --git a/manifest b/manifest index f7a7dc5ef4..42bba29152 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\serror\smessages\sin\sthe\sshell. -D 2024-09-24T19:19:53.992 +C Fix\sover-length\slines\sin\sthe\sshell\ssource\scode. +D 2024-09-24T19:47:12.272 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c b2cd748488012312824508639b6af908461e45403037d5c4e19d9b0e8195507f F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 38a38100356134f962b3f72e1e3a44da014dee4f044b81438273aa5b0b5e7469 +F src/shell.c.in 59d96ef5df9ba2f1f1982267385486b0a3fe5d9c04bcf00db8341064a6aaf72f F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0f228317c6ea1388d82df46f44c166b2aa9be63361ff9b81569ebee63c930f2e -R d40ea38d7142da3f67c791f2921da224 +P aeef82e974c24071e3211588001a92c7f122fbaf02d9dcf7fa5aaf30d2729f64 +R e0249c26fc1dbc90ee636c7d58ded95a U drh -Z 6cd8755ee2455e78de1e4ba9f17c392f +Z d330d508deb5561f036eaedfc6533764 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 66bec0a036..fd858c80cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aeef82e974c24071e3211588001a92c7f122fbaf02d9dcf7fa5aaf30d2729f64 +f3fdf76a0d3abeb5202f2b6f26318815396da7df680073955bde60b13f84e797 diff --git a/src/shell.c.in b/src/shell.c.in index 48234b7d31..6454c2d935 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -4208,7 +4208,8 @@ static int expertDotCommand( if( rc==SQLITE_OK ){ pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); if( pState->expert.pExpert==0 ){ - sqlite3_fprintf(stderr,"sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory"); + sqlite3_fprintf(stderr, + "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory"); rc = SQLITE_ERROR; }else{ sqlite3_expert_config( @@ -5385,7 +5386,8 @@ static void open_db(ShellState *p, int openFlags){ stderr); exit(1); }else{ - sqlite3_fprintf(stderr,"Notice: using substitute in-memory database instead of \"%s\"\n", + sqlite3_fprintf(stderr, + "Notice: using substitute in-memory database instead of \"%s\"\n", zDbFilename); } } @@ -5521,7 +5523,8 @@ static void open_db(ShellState *p, int openFlags){ void close_db(sqlite3 *db){ int rc = sqlite3_close(db); if( rc ){ - sqlite3_fprintf(stderr,"Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); + sqlite3_fprintf(stderr, + "Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); } } @@ -5685,7 +5688,8 @@ static int booleanValue(const char *zArg){ if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ return 0; } - sqlite3_fprintf(stderr,"ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg); + sqlite3_fprintf(stderr, + "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg); return 0; } @@ -5781,7 +5785,8 @@ static int sql_trace_callback( } case SQLITE_TRACE_PROFILE: { sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0; - sqlite3_fprintf(p->traceOut, "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec); + sqlite3_fprintf(p->traceOut, + "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec); break; } } @@ -6099,7 +6104,8 @@ static void tryToCloneSchema( shell_check_oom(zQuery); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - sqlite3_fprintf(stderr,"Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), + sqlite3_fprintf(stderr, + "Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); goto end_schema_xfer; } @@ -6170,7 +6176,8 @@ static void tryToClone(ShellState *p, const char *zNewDb){ } rc = sqlite3_open(zNewDb, &newDb); if( rc ){ - sqlite3_fprintf(stderr,"Cannot create output database: %s\n", sqlite3_errmsg(newDb)); + sqlite3_fprintf(stderr, + "Cannot create output database: %s\n", sqlite3_errmsg(newDb)); }else{ sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); @@ -6694,7 +6701,8 @@ static int lintFkeyIndexes( zIndent = " "; } else{ - sqlite3_fprintf(stderr,"Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); + sqlite3_fprintf(stderr, + "Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); return SQLITE_ERROR; } } @@ -6753,7 +6761,8 @@ static int lintFkeyIndexes( if( res==0 ){ sqlite3_fprintf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); }else if( bVerbose ){ - sqlite3_fprintf(out, "%s/* no extra indexes required for %s -> %s */\n", + sqlite3_fprintf(out, + "%s/* no extra indexes required for %s -> %s */\n", zIndent, zFrom, zTarget ); } @@ -6807,7 +6816,8 @@ static void shellPrepare( if( *pRc==SQLITE_OK ){ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); if( rc!=SQLITE_OK ){ - sqlite3_fprintf(stderr,"sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); + sqlite3_fprintf(stderr, + "sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); *pRc = rc; } } @@ -8252,7 +8262,8 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ rc = 2; }else if( testcase_glob(azArg[1],zRes)==0 ){ - sqlite3_fprintf(stderr,"testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", + sqlite3_fprintf(stderr, + "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", p->zTestcase, azArg[1], zRes); rc = 1; }else{ @@ -8406,7 +8417,8 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); } sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); - sqlite3_fprintf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); + sqlite3_fprintf(p->out, "%19s %s\n", + aDbConfig[ii].zName, v ? "on" : "off"); if( nArg>1 ) break; } if( nArg>1 && ii==ArraySize(aDbConfig) ){ @@ -8460,7 +8472,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ShellSetFlag(p, SHFLG_DumpNoSys); }else { - sqlite3_fprintf(stderr,"Unknown option \"%s\" on \".dump\"\n", azArg[i]); + sqlite3_fprintf(stderr, + "Unknown option \"%s\" on \".dump\"\n", azArg[i]); rc = 1; sqlite3_free(zLike); goto meta_command_exit; @@ -8614,7 +8627,8 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifndef SQLITE_OMIT_VIRTUALTABLE if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ if( p->bSafeMode ){ - sqlite3_fprintf(stderr,"Cannot run experimental commands such as \"%s\" in safe mode\n", + sqlite3_fprintf(stderr, + "Cannot run experimental commands such as \"%s\" in safe mode\n", azArg[0]); rc = 1; }else{ @@ -8673,7 +8687,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( cli_strcmp(zCmd,"help")==0 ){ sqlite3_fputs("Available file-controls:\n", p->out); for(i=0; iout, " .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); + sqlite3_fprintf(p->out, + " .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); } rc = 1; goto meta_command_exit; @@ -9023,7 +9038,8 @@ static int do_meta_command(char *zLine, ShellState *p){ } rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); if( rc ){ - sqlite3_fprintf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); + sqlite3_fprintf(stderr, + "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); } sqlite3_free(zCreate); zCreate = 0; @@ -9133,7 +9149,8 @@ static int do_meta_command(char *zLine, ShellState *p){ xRead(&sCtx); i++; }while( sCtx.cTerm==sCtx.cColSep ); - sqlite3_fprintf(stderr,"%s:%d: expected %d columns but found %d - extras ignored\n", + sqlite3_fprintf(stderr, + "%s:%d: expected %d columns but found %d - extras ignored\n", sCtx.zFile, startLine, nCol, i); } if( i>=nCol ){ @@ -9153,7 +9170,8 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_finalize(pStmt); if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); if( eVerbose>0 ){ - sqlite3_fprintf(p->out, "Added %d rows with %d errors using %d lines of input\n", + sqlite3_fprintf(p->out, + "Added %d rows with %d errors using %d lines of input\n", sCtx.nRow, sCtx.nErr, sCtx.nLine-1); } }else @@ -9250,10 +9268,12 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); if( rc ){ - sqlite3_fprintf(stderr,"Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); + sqlite3_fprintf(stderr, + "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); }else{ sqlite3_fprintf(stdout, "%s;\n", zSql); - sqlite3_fprintf(stdout, "WARNING: writing to an imposter table will corrupt" + sqlite3_fprintf(stdout, + "WARNING: writing to an imposter table will corrupt" " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index"); } }else{ @@ -9464,7 +9484,8 @@ static int do_meta_command(char *zLine, ShellState *p){ p->cmOpts.bWordWrap ? "on" : "off", p->cmOpts.bQuote ? "" : "no"); }else{ - sqlite3_fprintf(p->out, "current output mode: %s\n", modeDescr[p->mode]); + sqlite3_fprintf(p->out, + "current output mode: %s\n", modeDescr[p->mode]); } zMode = modeDescr[p->mode]; } @@ -9696,7 +9717,8 @@ static int do_meta_command(char *zLine, ShellState *p){ break; } }else{ - sqlite3_fprintf(p->out, "ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); + sqlite3_fprintf(p->out, + "ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; sqlite3_free(zFile); @@ -9799,7 +9821,8 @@ static int do_meta_command(char *zLine, ShellState *p){ "SELECT key, quote(value) " "FROM temp.sqlite_parameters;", -1, &pStmt, 0); while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ - sqlite3_fprintf(p->out, "%-*s %s\n", len, sqlite3_column_text(pStmt,0), + sqlite3_fprintf(p->out, + "%-*s %s\n", len, sqlite3_column_text(pStmt,0), sqlite3_column_text(pStmt,1)); } sqlite3_finalize(pStmt); @@ -10244,7 +10267,8 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ rc = sqlite3session_attach(pSession->p, azCmd[1]); if( rc ){ - sqlite3_fprintf(stderr,"ERROR: sqlite3session_attach() returns %d\n",rc); + sqlite3_fprintf(stderr, + "ERROR: sqlite3session_attach() returns %d\n",rc); rc = 0; } } @@ -10279,7 +10303,8 @@ static int do_meta_command(char *zLine, ShellState *p){ } if( pChng && fwrite(pChng, szChng, 1, out)!=1 ){ - sqlite3_fprintf(stderr,"ERROR: Failed to write entire %d-byte output\n", szChng); + sqlite3_fprintf(stderr, + "ERROR: Failed to write entire %d-byte output\n", szChng); } sqlite3_free(pChng); fclose(out); @@ -10306,7 +10331,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( pAuxDb->nSession ){ ii = sqlite3session_enable(pSession->p, ii); - sqlite3_fprintf(p->out, "session %s enable flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, + "session %s enable flag = %d\n", pSession->zName, ii); } }else @@ -10341,7 +10367,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( pAuxDb->nSession ){ ii = sqlite3session_indirect(pSession->p, ii); - sqlite3_fprintf(p->out, "session %s indirect flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, + "session %s indirect flag = %d\n", pSession->zName, ii); } }else @@ -10353,7 +10380,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCmd!=1 ) goto session_syntax_error; if( pAuxDb->nSession ){ ii = sqlite3session_isempty(pSession->p); - sqlite3_fprintf(p->out, "session %s isempty flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, + "session %s isempty flag = %d\n", pSession->zName, ii); } }else @@ -10382,7 +10410,8 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){ - sqlite3_fprintf(stderr,"Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); + sqlite3_fprintf(stderr, + "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); goto meta_command_exit; } pSession = &pAuxDb->aSession[pAuxDb->nSession]; @@ -10448,8 +10477,9 @@ static int do_meta_command(char *zLine, ShellState *p){ bVerbose++; }else { - sqlite3_fprintf(stderr,"Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); - eputz("Should be one of: --init -v\n"); + sqlite3_fprintf(stderr, + "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); + sqlite3_fputs("Should be one of: --init -v\n", stderr); rc = 1; goto meta_command_exit; } @@ -10511,7 +10541,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( rc || zErrMsg ){ nErr++; rc = 1; - sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg); + sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg); sqlite3_free(zErrMsg); }else if( cli_strcmp(zAns,str.z)!=0 ){ nErr++; @@ -10521,7 +10551,8 @@ static int do_meta_command(char *zLine, ShellState *p){ } } else{ - sqlite3_fprintf(stderr,"Unknown operation \"%s\" on selftest line %d\n", zOp, tno); + sqlite3_fprintf(stderr, + "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); rc = 1; break; } @@ -10577,7 +10608,8 @@ static int do_meta_command(char *zLine, ShellState *p){ bDebug = 1; }else { - sqlite3_fprintf(stderr,"Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); + sqlite3_fprintf(stderr, + "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); showHelp(p->out, azArg[0]); rc = 1; goto meta_command_exit; @@ -10706,7 +10738,8 @@ static int do_meta_command(char *zLine, ShellState *p){ double countIrreversible = sqlite3_column_double(pCheckStmt, 0); if( countIrreversible>0 ){ int sz = (int)(countIrreversible + 0.5); - sqlite3_fprintf(stderr,"Digest includes %d invalidly encoded text field%s.\n", + sqlite3_fprintf(stderr, + "Digest includes %d invalidly encoded text field%s.\n", sz, (sz>1)? "s": ""); } } @@ -10762,11 +10795,13 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_fprintf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); sqlite3_fprintf(p->out, "%12.12s: %s\n","explain", p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); - sqlite3_fprintf(p->out, "%12.12s: %s\n","headers", azBool[p->showHeader!=0]); + sqlite3_fprintf(p->out, "%12.12s: %s\n","headers", + azBool[p->showHeader!=0]); if( p->mode==MODE_Column || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) ){ - sqlite3_fprintf(p->out, "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", + sqlite3_fprintf(p->out, + "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", modeDescr[p->mode], p->cmOpts.iWrap, p->cmOpts.bWordWrap ? "on" : "off", p->cmOpts.bQuote ? "" : "no"); @@ -10914,7 +10949,8 @@ static int do_meta_command(char *zLine, ShellState *p){ for(i=0; iout, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); + sqlite3_fprintf(p->out, + "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); } sqlite3_fputs("\n", p->out); } @@ -11096,12 +11132,13 @@ static int do_meta_command(char *zLine, ShellState *p){ if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break; } if( jj>=ArraySize(aLabel) ){ - sqlite3_fprintf(stderr,"Error: no such optimization: \"%s\"\n", zLabel); - eputz("Should be one of:"); + sqlite3_fprintf(stderr, + "Error: no such optimization: \"%s\"\n", zLabel); + sqlite3_fputs("Should be one of:", stderr); for(jj=0; jjzDbFilename = ":memory:"; warnInmemoryDb = argc==1; #else - sqlite3_fprintf(stderr,"%s: Error: no database filename specified\n", Argv0); + sqlite3_fprintf(stderr, + "%s: Error: no database filename specified\n", Argv0); return 1; #endif } @@ -12931,7 +12973,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( zErrMsg!=0 ){ shellEmitError(zErrMsg); }else{ - sqlite3_fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]); + sqlite3_fprintf(stderr, + "Error: unable to process SQL: %s\n", azCmd[i]); } sqlite3_free(zErrMsg); if( rc==0 ) rc = 1; @@ -12951,7 +12994,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #else # define SHELL_CIO_CHAR_SET "" #endif - sqlite3_fprintf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/ + sqlite3_fprintf(stdout, + "SQLite version %s %.19s%s\n" /*extra-version-info*/ "Enter \".help\" for usage hints.\n", sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET); if( warnInmemoryDb ){ From 38b4158abae426f2efc610e4c7916931d8e03da1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 11:27:59 +0000 Subject: [PATCH 11/25] Use sqlite3_fgets() instead of fgetc() to end the startup debugging pause in the CLI. FossilOrigin-Name: 869b3c05e852a797b5801a81d30a1f7955c31afad0274327f7af2284b555f23a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 97936fe65a..590b028e17 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\senhancements,\sand\sespecially\sthe\szero-\sand\sdouble-width\scharacter\nprocessing\sfor\scolumnar\soutputs\sinto\sthe\scli-stdlib\sbranch. -D 2024-09-25T09:43:05.208 +C Use\ssqlite3_fgets()\sinstead\sof\sfgetc()\sto\send\sthe\sstartup\sdebugging\spause\nin\sthe\sCLI. +D 2024-09-25T11:27:59.291 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 3eb4e28de9e629adba14f2314c0051ea462770fdc04972f15a3922810fec5959 +F src/shell.c.in 4ff7790dc89c0ca7f7a0f1921b34ed01d78c70e1c8d080659ebaecdca298411f F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f3fdf76a0d3abeb5202f2b6f26318815396da7df680073955bde60b13f84e797 9592b9ba3ad7a842cdd4c4010da278485a6fdec7e811bda01ebe640162a8c3b6 -R cb8cb8b7debcfd75af761c484fdbc0a1 +P d6262a4bcd7b0334b23ae4d194ca2bce7c6554ee6c678666b24c830e4c14a467 +R d977d49e5dea1a4e01fec0c001abe012 U drh -Z e3c77b1ca9fc0efcd7f2507f7b7e048d +Z 0a28ca13fa93e1f632f49b48601d4127 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8afc0d5af4..1375b7c7d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6262a4bcd7b0334b23ae4d194ca2bce7c6554ee6c678666b24c830e4c14a467 +869b3c05e852a797b5801a81d30a1f7955c31afad0274327f7af2284b555f23a diff --git a/src/shell.c.in b/src/shell.c.in index cdcba084da..667f3e2d1f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -12672,10 +12672,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #if !defined(_WIN32_WCE) if( getenv("SQLITE_DEBUG_BREAK") ){ if( isatty(0) && isatty(2) ){ + char zLine[100]; sqlite3_fprintf(stderr, - "attach debugger to process %d and press any key to continue.\n", + "attach debugger to process %d and press ENTER to continue...", GETPID()); - fgetc(stdin); + sqlite3_fgets(zLine, sizeof(zLine), stdin); }else{ #if defined(_WIN32) || defined(WIN32) #if SQLITE_OS_WINRT From 853520ddbf85b29db418cc283648e4eac0f62a83 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 11:38:00 +0000 Subject: [PATCH 12/25] Fix stray fputs() calls in the CLI. FossilOrigin-Name: 1ee3fa0f0e87a61b5700abd56547c4acefe999317b0d53d66d890d9e09d8b7d9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 19 ++++++++++--------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 590b028e17..9b7a96878f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssqlite3_fgets()\sinstead\sof\sfgetc()\sto\send\sthe\sstartup\sdebugging\spause\nin\sthe\sCLI. -D 2024-09-25T11:27:59.291 +C Fix\sstray\sfputs()\scalls\sin\sthe\sCLI. +D 2024-09-25T11:38:00.160 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 4ff7790dc89c0ca7f7a0f1921b34ed01d78c70e1c8d080659ebaecdca298411f +F src/shell.c.in d91ad1c7b7c00cfe2d5f0577016fa31411b238b0a8eba232087265c89ed134e2 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d6262a4bcd7b0334b23ae4d194ca2bce7c6554ee6c678666b24c830e4c14a467 -R d977d49e5dea1a4e01fec0c001abe012 +P 869b3c05e852a797b5801a81d30a1f7955c31afad0274327f7af2284b555f23a +R 65de7bdaddb9c81ab30a8bc4f548eed2 U drh -Z 0a28ca13fa93e1f632f49b48601d4127 +Z fec9edb9be260bf1b825cec9b6314a72 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1375b7c7d3..19e0615510 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -869b3c05e852a797b5801a81d30a1f7955c31afad0274327f7af2284b555f23a +1ee3fa0f0e87a61b5700abd56547c4acefe999317b0d53d66d890d9e09d8b7d9 diff --git a/src/shell.c.in b/src/shell.c.in index 667f3e2d1f..6dba6e8c33 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2891,14 +2891,14 @@ static int shell_callback( if( azArg==0 ) break; if( p->cnt==0 && p->showHeader ){ for(i=0; i0 ) fputs(p->colSeparator, p->out); + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); output_quoted_string(p->out, azCol[i]); } - fputs(p->rowSeparator, p->out); + sqlite3_fputs(p->rowSeparator, p->out); } p->cnt++; for(i=0; i0 ) fputs(p->colSeparator, p->out); + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ sqlite3_fputs("NULL", p->out); }else if( aiType && aiType[i]==SQLITE_TEXT ){ @@ -2920,7 +2920,7 @@ static int shell_callback( output_quoted_string(p->out, azArg[i]); } } - fputs(p->rowSeparator, p->out); + sqlite3_fputs(p->rowSeparator, p->out); break; } case MODE_Ascii: { @@ -4104,7 +4104,7 @@ static void exec_prepared_stmt_columnar( } for(i=0; iout, p->actualWidth[i]); - fputs(i==nColumn-1?"\n":" ", p->out); + sqlite3_fputs(i==nColumn-1?"\n":" ", p->out); } } break; @@ -4113,7 +4113,7 @@ static void exec_prepared_stmt_columnar( colSep = " | "; rowSep = " |\n"; print_row_separator(p, nColumn, "+"); - fputs("| ", p->out); + sqlite3_fputs("| ", p->out); for(i=0; iactualWidth[i]; n = strlenChar(azData[i]); @@ -4127,7 +4127,7 @@ static void exec_prepared_stmt_columnar( case MODE_Markdown: { colSep = " | "; rowSep = " |\n"; - fputs("| ", p->out); + sqlite3_fputs("| ", p->out); for(i=0; iactualWidth[i]; n = strlenChar(azData[i]); @@ -4274,7 +4274,7 @@ static void exec_prepared_stmt( } while( SQLITE_ROW == rc ); sqlite3_free(pData); if( pArg->cMode==MODE_Json ){ - fputs("]\n", pArg->out); + sqlite3_fputs("]\n", pArg->out); }else if( pArg->cMode==MODE_Count ){ char zBuf[200]; sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n", @@ -12845,7 +12845,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break; } }else if( cli_strcmp(z,"-vfstrace")==0 ){ - vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); + vfstrace_register("trace",0,(int(*)(const char*,void*))sqlite3_fputs, + stderr,1); bEnableVfstrace = 1; #ifdef SQLITE_ENABLE_MULTIPLEX }else if( cli_strcmp(z,"-multiplex")==0 ){ From 9e59c06fb1644fed1499b65cbe547b1eb07bc6ea Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 12:56:44 +0000 Subject: [PATCH 13/25] Always include a UTF-8 BOM at the beginning of the output CSV when using the ".excel" command on Windows, as the actual Excel program requires the BOM in order to work correctly. FossilOrigin-Name: 04727fc00207325a76a5d5f20549c00232810ac727dedb70bc9e8112e60b3f56 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9b7a96878f..1494e6c021 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sstray\sfputs()\scalls\sin\sthe\sCLI. -D 2024-09-25T11:38:00.160 +C Always\sinclude\sa\sUTF-8\sBOM\sat\sthe\sbeginning\sof\sthe\soutput\sCSV\swhen\susing\nthe\s".excel"\scommand\son\sWindows,\sas\sthe\sactual\sExcel\sprogram\srequires\sthe\nBOM\sin\sorder\sto\swork\scorrectly. +D 2024-09-25T12:56:44.564 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in d91ad1c7b7c00cfe2d5f0577016fa31411b238b0a8eba232087265c89ed134e2 +F src/shell.c.in be499bb6bcd951a7fa9480588a824a03cef863c334f1843a2f4b76bcf31bd616 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 869b3c05e852a797b5801a81d30a1f7955c31afad0274327f7af2284b555f23a -R 65de7bdaddb9c81ab30a8bc4f548eed2 +P 1ee3fa0f0e87a61b5700abd56547c4acefe999317b0d53d66d890d9e09d8b7d9 +R aa31813957ce0d0538591043958b4e17 U drh -Z fec9edb9be260bf1b825cec9b6314a72 +Z 487c96328e404c2d5a7c68c4fa573337 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 19e0615510..31a0367380 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ee3fa0f0e87a61b5700abd56547c4acefe999317b0d53d66d890d9e09d8b7d9 +04727fc00207325a76a5d5f20549c00232810ac727dedb70bc9e8112e60b3f56 diff --git a/src/shell.c.in b/src/shell.c.in index 6dba6e8c33..c6beeee0da 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -9941,6 +9941,10 @@ static int do_meta_command(char *zLine, ShellState *p){ p->mode = MODE_Csv; sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); +#ifdef _WIN32 + zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does + ** not work without it. */ +#endif }else{ /* text editor mode */ newTempFile(p, "txt"); From 2a9254cf2c9412da3994d6e11f556ba507dd66c2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 13:29:03 +0000 Subject: [PATCH 14/25] Add the "www" output mode that include <table> in the HTML output. Add the ".www" command and the "-w" option to ".once". FossilOrigin-Name: b06fd9e6bcce09f12c994dc34f329a8d267ea0601bb07c9b00903c5017d55d42 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 44 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1494e6c021..c421c9dd6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\sinclude\sa\sUTF-8\sBOM\sat\sthe\sbeginning\sof\sthe\soutput\sCSV\swhen\susing\nthe\s".excel"\scommand\son\sWindows,\sas\sthe\sactual\sExcel\sprogram\srequires\sthe\nBOM\sin\sorder\sto\swork\scorrectly. -D 2024-09-25T12:56:44.564 +C Add\sthe\s"www"\soutput\smode\sthat\sinclude\s<table>\sin\sthe\sHTML\soutput.\nAdd\sthe\s".www"\scommand\sand\sthe\s"-w"\soption\sto\s".once". +D 2024-09-25T13:29:03.338 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in be499bb6bcd951a7fa9480588a824a03cef863c334f1843a2f4b76bcf31bd616 +F src/shell.c.in 9781ab726a108a10f8722d0d5e10c548d6f797ceef8d1a257a4e2cdc107bffc0 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1ee3fa0f0e87a61b5700abd56547c4acefe999317b0d53d66d890d9e09d8b7d9 -R aa31813957ce0d0538591043958b4e17 +P 04727fc00207325a76a5d5f20549c00232810ac727dedb70bc9e8112e60b3f56 +R a9ce986cea2b862753a371f08d91ab92 U drh -Z 487c96328e404c2d5a7c68c4fa573337 +Z cd53dd6e20071a9c7b2de3e7e318715b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 31a0367380..2fedfa4050 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04727fc00207325a76a5d5f20549c00232810ac727dedb70bc9e8112e60b3f56 +b06fd9e6bcce09f12c994dc34f329a8d267ea0601bb07c9b00903c5017d55d42 diff --git a/src/shell.c.in b/src/shell.c.in index c6beeee0da..9581c5c3cb 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1596,6 +1596,7 @@ static ShellState shellState; #define MODE_Count 17 /* Output only a count of the rows of output */ #define MODE_Off 18 /* No query output shown */ #define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */ +#define MODE_Www 20 /* Full web-page output */ static const char *modeDescr[] = { "line", @@ -1616,7 +1617,9 @@ static const char *modeDescr[] = { "table", "box", "count", - "off" + "off", + "scanexp", + "www", }; /* @@ -2728,8 +2731,13 @@ static int shell_callback( } break; } + case MODE_Www: case MODE_Html: { - if( p->cnt++==0 && p->showHeader ){ + if( p->cnt==0 && p->cMode==MODE_Www ){ + sqlite3_fputs( + "\n",p->out); + } + if( p->cnt==0 && p->showHeader ){ sqlite3_fputs("", p->out); for(i=0; i", p->out); @@ -2738,6 +2746,7 @@ static int shell_callback( } sqlite3_fputs("\n", p->out); } + p->cnt++; if( azArg==0 ) break; sqlite3_fputs("", p->out); for(i=0; icMode==MODE_Json ){ sqlite3_fputs("]\n", pArg->out); + }else if( pArg->cMode==MODE_Www ){ + sqlite3_fputs("
\n", pArg->out); }else if( pArg->cMode==MODE_Count ){ char zBuf[200]; sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n", @@ -5029,6 +5040,7 @@ static const char *(azHelp[]) = { " If FILE begins with '|' then open as a pipe", " --bom Put a UTF8 byte-order mark at the beginning", " -e Send output to the system text editor", + " -w Send output as HTML to a web browser (same as \".www\")", " -x Send output as CSV to a spreadsheet (same as \".excel\")", /* Note that .open is (partially) available in WASM builds but is ** currently only intended to be used by the fiddle tool, not @@ -5165,6 +5177,9 @@ static const char *(azHelp[]) = { ".vfsname ?AUX? Print the name of the VFS stack", ".width NUM1 NUM2 ... Set minimum column widths for columnar output", " Negative values right-justify", +#ifndef SQLITE_SHELL_FIDDLE + ".www Display output of the next command in web browser", +#endif }; /* @@ -9702,6 +9717,8 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); }else if( cli_strncmp(zMode,"html",n2)==0 ){ p->mode = MODE_Html; + }else if( cli_strncmp(zMode,"www",n2)==0 ){ + p->mode = MODE_Www; }else if( cli_strncmp(zMode,"tcl",n2)==0 ){ p->mode = MODE_Tcl; sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); @@ -9873,12 +9890,13 @@ static int do_meta_command(char *zLine, ShellState *p){ && (cli_strncmp(azArg[0], "output", n)==0 || cli_strncmp(azArg[0], "once", n)==0)) || (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0) + || (c=='w' && n==3 && cli_strcmp(azArg[0],"www")==0) ){ char *zFile = 0; int bTxtMode = 0; int i; int eMode = 0; - int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */ + int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */ static const char *zBomUtf8 = "\xef\xbb\xbf"; const char *zBom = 0; @@ -9886,6 +9904,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='e' ){ eMode = 'x'; bOnce = 2; + }else if( c=='w' ){ + eMode = 'w'; + bOnce = 2; }else if( cli_strncmp(azArg[0],"once",n)==0 ){ bOnce = 1; } @@ -9895,10 +9916,12 @@ static int do_meta_command(char *zLine, ShellState *p){ if( z[1]=='-' ) z++; if( cli_strcmp(z,"-bom")==0 ){ zBom = zBomUtf8; - }else if( c!='e' && cli_strcmp(z,"-x")==0 ){ + }else if( c=='o' && cli_strcmp(z,"-x")==0 ){ eMode = 'x'; /* spreadsheet */ - }else if( c!='e' && cli_strcmp(z,"-e")==0 ){ + }else if( c=='o' && cli_strcmp(z,"-e")==0 ){ eMode = 'e'; /* text editor */ + }else if( c=='o' && cli_strcmp(z,"-w")==0 ){ + eMode = 'w'; /* Web browser */ }else{ sqlite3_fprintf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]); @@ -9906,7 +9929,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - }else if( zFile==0 && eMode!='e' && eMode!='x' ){ + }else if( zFile==0 && eMode==0 ){ zFile = sqlite3_mprintf("%s", z); if( zFile && zFile[0]=='|' ){ while( i+1doXdgOpen = 1; outputModePush(p); if( eMode=='x' ){ @@ -9945,6 +9968,11 @@ static int do_meta_command(char *zLine, ShellState *p){ zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does ** not work without it. */ #endif + }else if( eMode=='w' ){ + /* web-browser mode. */ + newTempFile(p, "html"); + p->mode = MODE_Www; + bTxtMode = 1; }else{ /* text editor mode */ newTempFile(p, "txt"); @@ -12979,6 +13007,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ i++; }else if( cli_strcmp(z,"-html")==0 ){ data.mode = MODE_Html; + }else if( cli_strcmp(z,"-www")==0 ){ + data.mode = MODE_Www; }else if( cli_strcmp(z,"-list")==0 ){ data.mode = MODE_List; }else if( cli_strcmp(z,"-quote")==0 ){ From 62d96919f6dfc42f441311b000d2726e5077f8c1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 13:56:05 +0000 Subject: [PATCH 15/25] Improvements to ".www" and ".output -w" so that text that is not part of query output is shown using <pre>. FossilOrigin-Name: f8ef65c52305b2180ec56760f5762ac5638584cd504c79d57e86f61736901aa4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 21 +++++++++++++++------ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index c421c9dd6a..e7cdcc4770 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"www"\soutput\smode\sthat\sinclude\s<table>\sin\sthe\sHTML\soutput.\nAdd\sthe\s".www"\scommand\sand\sthe\s"-w"\soption\sto\s".once". -D 2024-09-25T13:29:03.338 +C Improvements\sto\s".www"\sand\s".output\s-w"\sso\sthat\stext\sthat\sis\snot\spart\sof\nquery\soutput\sis\sshown\susing\s<pre>. +D 2024-09-25T13:56:05.407 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 9781ab726a108a10f8722d0d5e10c548d6f797ceef8d1a257a4e2cdc107bffc0 +F src/shell.c.in 053df097aad75a1ecdff3f71c8452efffc889cc3b88907c93325360340d8b977 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 04727fc00207325a76a5d5f20549c00232810ac727dedb70bc9e8112e60b3f56 -R a9ce986cea2b862753a371f08d91ab92 +P b06fd9e6bcce09f12c994dc34f329a8d267ea0601bb07c9b00903c5017d55d42 +R 322d10259a92b6303d31355dabde0d96 U drh -Z cd53dd6e20071a9c7b2de3e7e318715b +Z 8156bb15fa45205c46d5412fa2ec3c8c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2fedfa4050..07c5b4e27c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b06fd9e6bcce09f12c994dc34f329a8d267ea0601bb07c9b00903c5017d55d42 +f8ef65c52305b2180ec56760f5762ac5638584cd504c79d57e86f61736901aa4 diff --git a/src/shell.c.in b/src/shell.c.in index 9581c5c3cb..3bba26c7dd 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2735,7 +2735,10 @@ static int shell_callback( case MODE_Html: { if( p->cnt==0 && p->cMode==MODE_Www ){ sqlite3_fputs( - "\n",p->out); + "\n" + "
\n" + ,p->out + ); } if( p->cnt==0 && p->showHeader ){ sqlite3_fputs("", p->out); @@ -4285,7 +4288,7 @@ static void exec_prepared_stmt( if( pArg->cMode==MODE_Json ){ sqlite3_fputs("]\n", pArg->out); }else if( pArg->cMode==MODE_Www ){ - sqlite3_fputs("
\n", pArg->out); + sqlite3_fputs("\n
\n", pArg->out);
       }else if( pArg->cMode==MODE_Count ){
         char zBuf[200];
         sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n",
@@ -6409,6 +6412,13 @@ static void output_redir(ShellState *p, FILE *pfNew){
     sqlite3_fputs("Output already redirected.\n", stderr);
   }else{
     p->out = pfNew;
+    if( p->mode==MODE_Www ){
+      sqlite3_fputs(
+        "\n"
+        "
\n",
+        p->out
+      );
+    }
   }
 }
 
@@ -6425,6 +6435,9 @@ static void output_reset(ShellState *p){
     pclose(p->out);
 #endif
   }else{
+    if( p->mode==MODE_Www ){
+      sqlite3_fputs("
\n", p->out); + } output_file_close(p->out); #ifndef SQLITE_NOHAVE_SYSTEM if( p->doXdgOpen ){ @@ -9717,8 +9730,6 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); }else if( cli_strncmp(zMode,"html",n2)==0 ){ p->mode = MODE_Html; - }else if( cli_strncmp(zMode,"www",n2)==0 ){ - p->mode = MODE_Www; }else if( cli_strncmp(zMode,"tcl",n2)==0 ){ p->mode = MODE_Tcl; sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); @@ -13007,8 +13018,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ i++; }else if( cli_strcmp(z,"-html")==0 ){ data.mode = MODE_Html; - }else if( cli_strcmp(z,"-www")==0 ){ - data.mode = MODE_Www; }else if( cli_strcmp(z,"-list")==0 ){ data.mode = MODE_List; }else if( cli_strcmp(z,"-quote")==0 ){ From 95f35b64da4e4507c3fd117f91f7ee2069c65723 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 14:09:47 +0000 Subject: [PATCH 16/25] Redirect timer output just like any other text. FossilOrigin-Name: 3b5ae21074958788b23ccf449e52fbbad1f81779e07a6ca62ad8395f88a37286 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index e7cdcc4770..affcaf289a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\s".www"\sand\s".output\s-w"\sso\sthat\stext\sthat\sis\snot\spart\sof\nquery\soutput\sis\sshown\susing\s<pre>. -D 2024-09-25T13:56:05.407 +C Redirect\stimer\soutput\sjust\slike\sany\sother\stext. +D 2024-09-25T14:09:47.920 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 053df097aad75a1ecdff3f71c8452efffc889cc3b88907c93325360340d8b977 +F src/shell.c.in 9e32f35af780b0369cac93730d6c7e4440c7ec8a7382525da913e406491a1e46 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b06fd9e6bcce09f12c994dc34f329a8d267ea0601bb07c9b00903c5017d55d42 -R 322d10259a92b6303d31355dabde0d96 +P f8ef65c52305b2180ec56760f5762ac5638584cd504c79d57e86f61736901aa4 +R ac074bfeea03930c231c06a9d210f518 U drh -Z 8156bb15fa45205c46d5412fa2ec3c8c +Z 51901a5607650ec168b6e659dbb210c8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 07c5b4e27c..464094fc1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f8ef65c52305b2180ec56760f5762ac5638584cd504c79d57e86f61736901aa4 +3b5ae21074958788b23ccf449e52fbbad1f81779e07a6ca62ad8395f88a37286 diff --git a/src/shell.c.in b/src/shell.c.in index 3bba26c7dd..1c81a0bbab 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -321,12 +321,12 @@ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ /* ** Print the timing results. */ -static void endTimer(void){ +static void endTimer(FILE *out){ if( enableTimer ){ sqlite3_int64 iEnd = timeOfDay(); struct rusage sEnd; getrusage(RUSAGE_SELF, &sEnd); - sqlite3_fprintf(stdout, "Run Time: real %.3f user %f sys %f\n", + sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", (iEnd - iBegin)*0.001, timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); @@ -334,7 +334,7 @@ static void endTimer(void){ } #define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() +#define END_TIMER(X) endTimer(X) #define HAS_TIMER 1 #elif (defined(_WIN32) || defined(WIN32)) @@ -400,12 +400,12 @@ static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ /* ** Print the timing results. */ -static void endTimer(void){ +static void endTimer(FILE *out){ if( enableTimer && getProcessTimesAddr){ FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; sqlite3_int64 ftWallEnd = timeOfDay(); getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); - sqlite3_fprintf(stdout, "Run Time: real %.3f user %f sys %f\n", + sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", (ftWallEnd - ftWallBegin)*0.001, timeDiff(&ftUserBegin, &ftUserEnd), timeDiff(&ftKernelBegin, &ftKernelEnd)); @@ -413,12 +413,12 @@ static void endTimer(void){ } #define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() +#define END_TIMER(X) endTimer(X) #define HAS_TIMER hasTimer() #else #define BEGIN_TIMER -#define END_TIMER +#define END_TIMER(X) /*no-op*/ #define HAS_TIMER 0 #endif @@ -12157,7 +12157,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; BEGIN_TIMER; rc = shell_exec(p, zSql, &zErrMsg); - END_TIMER; + END_TIMER(p->out); if( rc || zErrMsg ){ char zPrefix[100]; const char *zErrorTail; From 7119a6c16b046a35b690fc8c56c8ee26a35cbad9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 15:26:37 +0000 Subject: [PATCH 17/25] Have the zipfile and fileio extensions use sqlite3_stdio.c when it is available - such as when those extensions are preloaded into the CLI. FossilOrigin-Name: 74bbb2b2b4507d9acbd91209a2ce341968e9ff64f3aebe9e817bfe488d39ae03 --- ext/misc/fileio.c | 11 +++++++++-- ext/misc/zipfile.c | 12 ++++++++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/ext/misc/fileio.c b/ext/misc/fileio.c index c2ecab0b25..483ef0187f 100644 --- a/ext/misc/fileio.c +++ b/ext/misc/fileio.c @@ -110,6 +110,13 @@ SQLITE_EXTENSION_INIT1 #include #include +/* When used as part of the CLI, the sqlite3_stdio.h module will have +** been included before this one. In that case use the sqlite3_stdio.h +** #defines. If not, create our own for fopen(). +*/ +#ifndef _SQLITE3_STDIO_H_ +# define sqlite3_fopen fopen +#endif /* ** Structure of the fsdir() table-valued function @@ -142,7 +149,7 @@ static void readFileContents(sqlite3_context *ctx, const char *zName){ sqlite3 *db; int mxBlob; - in = fopen(zName, "rb"); + in = sqlite3_fopen(zName, "rb"); if( in==0 ){ /* File does not exist or is unreadable. Leave the result set to NULL. */ return; @@ -397,7 +404,7 @@ static int writeFile( sqlite3_int64 nWrite = 0; const char *z; int rc = 0; - FILE *out = fopen(zFile, "wb"); + FILE *out = sqlite3_fopen(zFile, "wb"); if( out==0 ) return 1; z = (const char*)sqlite3_value_blob(pData); if( z ){ diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index fd6d13bc38..2377457dfb 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -35,6 +35,14 @@ SQLITE_EXTENSION_INIT1 #include +/* When used as part of the CLI, the sqlite3_stdio.h module will have +** been included before this one. In that case use the sqlite3_stdio.h +** #defines. If not, create our own for fopen(). +*/ +#ifndef _SQLITE3_STDIO_H_ +# define sqlite3_fopen fopen +#endif + #ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_AMALGAMATION @@ -1291,7 +1299,7 @@ static int zipfileFilter( } if( 0==pTab->pWriteFd && 0==bInMemory ){ - pCsr->pFile = zFile ? fopen(zFile, "rb") : 0; + pCsr->pFile = zFile ? sqlite3_fopen(zFile, "rb") : 0; if( pCsr->pFile==0 ){ zipfileCursorErr(pCsr, "cannot open file: %s", zFile); rc = SQLITE_ERROR; @@ -1481,7 +1489,7 @@ static int zipfileBegin(sqlite3_vtab *pVtab){ ** structure into memory. During the transaction any new file data is ** appended to the archive file, but the central directory is accumulated ** in main-memory until the transaction is committed. */ - pTab->pWriteFd = fopen(pTab->zFile, "ab+"); + pTab->pWriteFd = sqlite3_fopen(pTab->zFile, "ab+"); if( pTab->pWriteFd==0 ){ pTab->base.zErrMsg = sqlite3_mprintf( "zipfile: failed to open file %s for writing", pTab->zFile diff --git a/manifest b/manifest index affcaf289a..76054939a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Redirect\stimer\soutput\sjust\slike\sany\sother\stext. -D 2024-09-25T14:09:47.920 +C Have\sthe\szipfile\sand\sfileio\sextensions\suse\ssqlite3_stdio.c\swhen\sit\sis\navailable\s-\ssuch\sas\swhen\sthose\sextensions\sare\spreloaded\sinto\sthe\sCLI. +D 2024-09-25T15:26:37.435 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -399,7 +399,7 @@ F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f82 F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b -F ext/misc/fileio.c 001179b29735639c607586c9e9398c92505c0833de06eefc27e13acf60dd1577 +F ext/misc/fileio.c e6b34db4df4b55b96265086c0010264e257b6eab1644e665697a6da587659403 F ext/misc/fossildelta.c 8c026e086e406e2b69947f1856fa3b848fff5379962276430d10085b8756b05a F ext/misc/fuzzer.c 8b28acf1a7e95d50e332bdd47e792ff27054ad99d3f9bc2e91273814d4b31a5a F ext/misc/ieee754.c 62a90978204d2c956d5036eb89e548e736ca5fac0e965912867ddd7bb833256d @@ -441,7 +441,7 @@ F ext/misc/vfstrace.c ac76a4ac4d907774fd423cc2b61410c756f9d0782e27cf6032e058594a F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 -F ext/misc/zipfile.c 5a3bf1b9cccb8e0da2389fe9e39e9c7f2b1351474b7e5090635f817d495eee3f +F ext/misc/zipfile.c b62147ac4985eaac4e368d529b1f4f43ad6bc9ac13d6805d907fff3afdac64d3 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f8ef65c52305b2180ec56760f5762ac5638584cd504c79d57e86f61736901aa4 -R ac074bfeea03930c231c06a9d210f518 +P 3b5ae21074958788b23ccf449e52fbbad1f81779e07a6ca62ad8395f88a37286 +R 5afd3bdce6fbcc9f56c686c2625824c5 U drh -Z 51901a5607650ec168b6e659dbb210c8 +Z a729cfecd90e8d587c0a925f42031223 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 464094fc1b..9f435ff8f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b5ae21074958788b23ccf449e52fbbad1f81779e07a6ca62ad8395f88a37286 +74bbb2b2b4507d9acbd91209a2ce341968e9ff64f3aebe9e817bfe488d39ae03 From 878db7b099ed8928ec18a584a2efa7d9d3ff4f45 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 15:55:52 +0000 Subject: [PATCH 18/25] Add the --plain option to the ".www" dot-command. FossilOrigin-Name: a9209519f612e66cfe11c89e70efd8285a0185ac0d3e5795846aafbd05d7a21f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 23 ++++++++++++++++++----- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 76054939a5..85c44e231b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\szipfile\sand\sfileio\sextensions\suse\ssqlite3_stdio.c\swhen\sit\sis\navailable\s-\ssuch\sas\swhen\sthose\sextensions\sare\spreloaded\sinto\sthe\sCLI. -D 2024-09-25T15:26:37.435 +C Add\sthe\s--plain\soption\sto\sthe\s".www"\sdot-command. +D 2024-09-25T15:55:52.425 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 9e32f35af780b0369cac93730d6c7e4440c7ec8a7382525da913e406491a1e46 +F src/shell.c.in 405e15e6a57a224af0f6ff014cb45cbb8123178fa1a6e5cfb39d3540389d9207 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3b5ae21074958788b23ccf449e52fbbad1f81779e07a6ca62ad8395f88a37286 -R 5afd3bdce6fbcc9f56c686c2625824c5 +P 74bbb2b2b4507d9acbd91209a2ce341968e9ff64f3aebe9e817bfe488d39ae03 +R 9584e7093ca35da79a25d5e2b514ac01 U drh -Z a729cfecd90e8d587c0a925f42031223 +Z 9a391f06b77de429a8a012b5954b01a2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9f435ff8f9..24a6899959 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74bbb2b2b4507d9acbd91209a2ce341968e9ff64f3aebe9e817bfe488d39ae03 +a9209519f612e66cfe11c89e70efd8285a0185ac0d3e5795846aafbd05d7a21f diff --git a/src/shell.c.in b/src/shell.c.in index 1c81a0bbab..25e3aad519 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -5041,10 +5041,11 @@ static const char *(azHelp[]) = { #ifndef SQLITE_SHELL_FIDDLE ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE", " If FILE begins with '|' then open as a pipe", - " --bom Put a UTF8 byte-order mark at the beginning", - " -e Send output to the system text editor", - " -w Send output as HTML to a web browser (same as \".www\")", - " -x Send output as CSV to a spreadsheet (same as \".excel\")", + " --bom Put a UTF8 byte-order mark at the beginning", + " -e Send output to the system text editor", + " --plain Use text/plain output instead of HTML for -w option", + " -w Send output as HTML to a web browser (same as \".www\")", + " -x Send output as CSV to a spreadsheet (same as \".excel\")", /* Note that .open is (partially) available in WASM builds but is ** currently only intended to be used by the fiddle tool, not ** end users, so is "undocumented." */ @@ -5067,6 +5068,8 @@ static const char *(azHelp[]) = { " Options:", " --bom Prefix output with a UTF8 byte-order mark", " -e Send output to the system text editor", + " --plain Use text/plain for -w option", + " -w Send output to a web browser", " -x Send output as CSV to a spreadsheet", #endif ".parameter CMD ... Manage SQL parameter bindings", @@ -5182,6 +5185,7 @@ static const char *(azHelp[]) = { " Negative values right-justify", #ifndef SQLITE_SHELL_FIDDLE ".www Display output of the next command in web browser", + " --plain Show results as text/plain, not as HTML", #endif }; @@ -9908,6 +9912,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int i; int eMode = 0; int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */ + int bPlain = 0; /* --plain option */ static const char *zBomUtf8 = "\xef\xbb\xbf"; const char *zBom = 0; @@ -9927,6 +9932,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( z[1]=='-' ) z++; if( cli_strcmp(z,"-bom")==0 ){ zBom = zBomUtf8; + }else if( cli_strcmp(z,"-plain")==0 ){ + bPlain = 1; }else if( c=='o' && cli_strcmp(z,"-x")==0 ){ eMode = 'x'; /* spreadsheet */ }else if( c=='o' && cli_strcmp(z,"-e")==0 ){ @@ -9982,7 +9989,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( eMode=='w' ){ /* web-browser mode. */ newTempFile(p, "html"); - p->mode = MODE_Www; + if( !bPlain ) p->mode = MODE_Www; bTxtMode = 1; }else{ /* text editor mode */ @@ -10019,6 +10026,12 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; } else { output_redir(p, pfFile); + if( bPlain && eMode=='w' ){ + sqlite3_fputs( + "\n\n\n", + pfFile + ); + } if( zBom ) sqlite3_fputs(zBom, pfFile); sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } From 66b3ed318b89d41a3484eb38bad43ccc255034a1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 25 Sep 2024 16:11:27 +0000 Subject: [PATCH 19/25] Always show HTML table headers in ".www" output mode. FossilOrigin-Name: 660ca5ce6600d897cc2b00b9d39e5d993c1c0e71ec0d5dc706246c053a163281 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 85c44e231b..1e84cd981f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--plain\soption\sto\sthe\s".www"\sdot-command. -D 2024-09-25T15:55:52.425 +C Always\sshow\sHTML\stable\sheaders\sin\s".www"\soutput\smode. +D 2024-09-25T16:11:27.958 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 405e15e6a57a224af0f6ff014cb45cbb8123178fa1a6e5cfb39d3540389d9207 +F src/shell.c.in 5a5881cbe128962b431bfd466ff408db6bf05b971db67200615be38745f0ceef F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 74bbb2b2b4507d9acbd91209a2ce341968e9ff64f3aebe9e817bfe488d39ae03 -R 9584e7093ca35da79a25d5e2b514ac01 +P a9209519f612e66cfe11c89e70efd8285a0185ac0d3e5795846aafbd05d7a21f +R 5a9e599155b273bd1e8c309df5248f6e U drh -Z 9a391f06b77de429a8a012b5954b01a2 +Z 4b89dbbffeeb17eaffa0b5d5ca63c4c0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 24a6899959..53d2b13f11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9209519f612e66cfe11c89e70efd8285a0185ac0d3e5795846aafbd05d7a21f +660ca5ce6600d897cc2b00b9d39e5d993c1c0e71ec0d5dc706246c053a163281 diff --git a/src/shell.c.in b/src/shell.c.in index 25e3aad519..c848c4c235 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2740,7 +2740,7 @@ static int shell_callback( ,p->out ); } - if( p->cnt==0 && p->showHeader ){ + if( p->cnt==0 && (p->showHeader || p->cMode==MODE_Www) ){ sqlite3_fputs("<TR>", p->out); for(i=0; i<nArg; i++){ sqlite3_fputs("<TH>", p->out); From b7ceffdadff6826711e2bbaba866821afcd99a22 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 26 Sep 2024 01:29:22 +0000 Subject: [PATCH 20/25] Fix shell test cases to account for recent additions to the ".help" output. FossilOrigin-Name: 54c22bc6165affbea0d1166a0912d19939300ccc4ae33a6b2ed8c510ab61c574 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/shell1.test | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 1e84cd981f..ea40af4ac6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\sshow\sHTML\stable\sheaders\sin\s".www"\soutput\smode. -D 2024-09-25T16:11:27.958 +C Fix\sshell\stest\scases\sto\saccount\sfor\srecent\sadditions\sto\sthe\s".help"\soutput. +D 2024-09-26T01:29:22.012 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1628,7 +1628,7 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21 F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 490bf9d0c7c9564fea318c46d49369f4690b825b584c9a544dbdccf61bc0babc +F test/shell1.test b02d628494fa284cdb2b7b2fecdadea96913796afd623f340a79d68f055dcb7e F test/shell2.test 01a01f76ed98088ce598794fbf5b359e148271541a8ddbf79d21cc353cc67a24 F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8 F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a9209519f612e66cfe11c89e70efd8285a0185ac0d3e5795846aafbd05d7a21f -R 5a9e599155b273bd1e8c309df5248f6e +P 660ca5ce6600d897cc2b00b9d39e5d993c1c0e71ec0d5dc706246c053a163281 +R 3b1b1ac1efd2caefa25e8d6c9bf0ff2f U drh -Z 4b89dbbffeeb17eaffa0b5d5ca63c4c0 +Z 1e00c19e9c0388401e635e4bb988cbfe # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 53d2b13f11..fac43782cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -660ca5ce6600d897cc2b00b9d39e5d993c1c0e71ec0d5dc706246c053a163281 +54c22bc6165affbea0d1166a0912d19939300ccc4ae33a6b2ed8c510ab61c574 diff --git a/test/shell1.test b/test/shell1.test index f355989c31..b4883e3521 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -516,6 +516,8 @@ do_test shell1-3.15.3 { Options: --bom Prefix output with a UTF8 byte-order mark -e Send output to the system text editor + --plain Use text/plain for -w option + -w Send output to a web browser -x Send output as CSV to a spreadsheet child process exited abnormally}} @@ -532,6 +534,8 @@ do_test shell1-3.16.2 { Options: --bom Prefix output with a UTF8 byte-order mark -e Send output to the system text editor + --plain Use text/plain for -w option + -w Send output to a web browser -x Send output as CSV to a spreadsheet child process exited abnormally}} From 2fb055366dfb68b20d313f628f180fe52801c20d Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 26 Sep 2024 13:12:19 +0000 Subject: [PATCH 21/25] Clarification of the meaning of the nByte parameter to sqlite3_prepare(). Comment and documentation change only - no changes to the code. FossilOrigin-Name: 92d71eee4f3a5edb3877c108d14972d80654982b0de3e635d9d008e9d3b6591f --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 8 ++++++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e74bcacf3c..04cb434a6f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sCLI,\sfor\scolumnar\soutput\sformats,\stry\sto\saccount\sfor\sthe\spresence\sof\nzero-width\sand\sdouble-width\scharacters\sin\sthe\soutput\sand\sadjust\scolumn\swidths\naccordingly. -D 2024-09-25T09:39:11.501 +C Clarification\sof\sthe\smeaning\sof\sthe\snByte\sparameter\sto\ssqlite3_prepare().\nComment\sand\sdocumentation\schange\sonly\s-\sno\schanges\sto\sthe\scode. +D 2024-09-26T13:12:19.952 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -769,7 +769,7 @@ F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe F src/shell.c.in 9b68a945f3aafc78eac1a256a4a588a9310dbc61a0cd60378c5b7a78f789af50 -F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c +F src/sqlite.h.in b20547021d20ba016c2fd0500f14f08a21ff23e64a0ed93e72ca0fecb9e1d0a0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqliteInt.h 5978cbb11becc3ce6471015d770d95f694ece06336c496f691df1b02460e9cd5 @@ -2213,9 +2213,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 42bb941584a1ac922ee6b0b6ecadce71c9259555563cf49913a6f820f3f9b887 b217e3004b58af0e777726bdd652b999ad41815261299ef4ce8f8d2f6b0afe8d -R 5fcf6775e686fdd76943c66cce860cb0 -T +closed b217e3004b58af0e777726bdd652b999ad41815261299ef4ce8f8d2f6b0afe8d +P 9592b9ba3ad7a842cdd4c4010da278485a6fdec7e811bda01ebe640162a8c3b6 +R 0bed48c612190c1339a39e58e27e8cbd U drh -Z af457fc67e3efab459ef7260d9a5da46 +Z 38a364760cd51d772a2b987e6988323a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5d05a8c7ec..e3d4847c8a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9592b9ba3ad7a842cdd4c4010da278485a6fdec7e811bda01ebe640162a8c3b6 +92d71eee4f3a5edb3877c108d14972d80654982b0de3e635d9d008e9d3b6591f diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 5546793c94..72190beec5 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4222,13 +4222,17 @@ int sqlite3_limit(sqlite3*, int id, int newVal); ** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the -** first zero terminator. ^If nByte is positive, then it is the -** number of bytes read from zSql. ^If nByte is zero, then no prepared +** first zero terminator. ^If nByte is positive, then it is the maximum +** number of bytes read from zSql. When nByte is positive, zSql is read +** up to the first zero terminator or until the nByte bytes have been read, +** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string <i>including</i> ** the nul-terminator. +** Note that nByte measure the length of the input in bytes, not +** characters, even for the UTF-16 inferfaces. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only From 2c77d51dfe206fad8caf39a9788482cd96875e5b Mon Sep 17 00:00:00 2001 From: stephan <stephan@noemail.net> Date: Thu, 26 Sep 2024 18:13:10 +0000 Subject: [PATCH 22/25] Resolve a harmless compiler warning in QNX builds. FossilOrigin-Name: 2916460179c6089375188c6e4e3cff1fca5bbbbb7280a10c919e09e75d1f11f8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 04cb434a6f..bb39343c96 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarification\sof\sthe\smeaning\sof\sthe\snByte\sparameter\sto\ssqlite3_prepare().\nComment\sand\sdocumentation\schange\sonly\s-\sno\schanges\sto\sthe\scode. -D 2024-09-26T13:12:19.952 +C Resolve\sa\sharmless\scompiler\swarning\sin\sQNX\sbuilds. +D 2024-09-26T18:13:10.425 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -751,7 +751,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 6e3e4fc75904ff85184091dbab996e6e35c1799e771788961cc3b4fcbe8f852c +F src/os_unix.c 779e83666ecd535f6725497ba6da069c1d15138ff6a4ee123edad1ae0cdfbe83 F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3 @@ -2213,8 +2213,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9592b9ba3ad7a842cdd4c4010da278485a6fdec7e811bda01ebe640162a8c3b6 -R 0bed48c612190c1339a39e58e27e8cbd -U drh -Z 38a364760cd51d772a2b987e6988323a +P 92d71eee4f3a5edb3877c108d14972d80654982b0de3e635d9d008e9d3b6591f +R 695a2a8c9ed9206bd31e5393e29d1395 +U stephan +Z 46b5546a8d1e43d063c19803f97215ff # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e3d4847c8a..24900fc1d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -92d71eee4f3a5edb3877c108d14972d80654982b0de3e635d9d008e9d3b6591f +2916460179c6089375188c6e4e3cff1fca5bbbbb7280a10c919e09e75d1f11f8 diff --git a/src/os_unix.c b/src/os_unix.c index 5d1dc9ac6b..92ad9d8607 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4159,7 +4159,7 @@ static void setDeviceCharacteristics(unixFile *pFd){ static void setDeviceCharacteristics(unixFile *pFile){ if( pFile->sectorSize == 0 ){ struct statvfs fsInfo; - + /* Set defaults for non-supported filesystems */ pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; pFile->deviceCharacteristics = 0; @@ -4199,7 +4199,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; @@ -4207,7 +4207,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; From 2b041fb97a8a821d15e5d40184a0a724cce549e0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 26 Sep 2024 19:16:20 +0000 Subject: [PATCH 23/25] Provide SQLITE_U8TEXT_ONLY and SQLITE_U8TEXT_STDIO compile-time options to the sqlite3_stdio.c module. FossilOrigin-Name: f31588520e3f45b50dcaa9eecab17f52ebb56bb53d0f9bdb88cc596d1a156353 --- ext/misc/sqlite3_stdio.c | 55 ++++++++++++++++++++++++++++++++++------ manifest | 14 +++++----- manifest.uuid | 2 +- src/shell.c.in | 34 ++++++++++++------------- 4 files changed, 72 insertions(+), 33 deletions(-) diff --git a/ext/misc/sqlite3_stdio.c b/ext/misc/sqlite3_stdio.c index 5447faadf7..46f12dff36 100644 --- a/ext/misc/sqlite3_stdio.c +++ b/ext/misc/sqlite3_stdio.c @@ -30,6 +30,43 @@ #include <io.h> #include <fcntl.h> +/* +** If the SQLITE_U8TEXT_ONLY option is defined, then only use +** _O_U8TEXT, _O_WTEXT, and similar together with the UTF-16 +** interfaces to the Windows CRT. The use of ANSI-only routines +** like fputs() and ANSI modes like _O_TEXT and _O_BINARY is +** avoided. +** +** The downside of using SQLITE_U8TEXT_ONLY is that it becomes +** impossible to output a bare newline character (0x0a) - that is, +** a newline that is not preceded by a carriage return (0x0d). +** And without that capability, sometimes the output will be slightly +** incorrect, as extra 0x0d characters will have been inserted where +** they do not belong. +** +** The SQLITE_U8TEXT_STDIO compile-time option is a compromise. +** It always enables _O_WTEXT or similar for stdin, stdout, stderr, +** but allows other streams to be _O_TEXT and/or O_BINARY. The +** SQLITE_U8TEXT_STDIO option has the same downside as SQLITE_U8TEXT_ONLY +** in that stray 0x0d characters might appear where they ought not, but +** at least with this option those characters only appear on standard +** I/O streams, and not on new streams that might be created by the +** application using sqlite3_fopen() or sqlite3_popen(). +*/ +#if defined(SQLITE_U8TEXT_ONLY) +# define UseWtextForOutput(fd) 1 +# define UseWtextForInput(fd) 1 +# define IsConsole(fd) _isatty(_fileno(fd)) +#elif defined(SQLITE_U8TEXT_STDIO) +# define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) +# define UseWtextForInput(fd) ((fd)==stdin) +# define IsConsole(fd) _isatty(_fileno(fd)) +#else +# define UseWtextForOutput(fd) _isatty(_fileno(fd)) +# define UseWtextForInput(fd) _isatty(_fileno(fd)) +# define IsConsole(fd) 1 +#endif + /* ** Work-alike for the fopen() routine from the standard C library. */ @@ -83,7 +120,7 @@ FILE *sqlite3_popen(const char *zCommand, const char *zMode){ ** Work-alike for fgets() from the standard C library. */ char *sqlite3_fgets(char *buf, int sz, FILE *in){ - if( _isatty(_fileno(in)) ){ + if( UseWtextForInput(in) ){ /* When reading from the command-prompt in Windows, it is necessary ** to use _O_WTEXT input mode to read UTF-16 characters, then translate ** that into UTF-8. Otherwise, non-ASCII characters all get translated @@ -91,7 +128,7 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){ */ wchar_t *b1 = malloc( sz*sizeof(wchar_t) ); if( b1==0 ) return 0; - _setmode(_fileno(in), _O_WTEXT); + _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); if( fgetws(b1, sz/4, in)==0 ){ sqlite3_free(b1); return 0; @@ -110,7 +147,7 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){ ** Work-alike for fputs() from the standard C library. */ int sqlite3_fputs(const char *z, FILE *out){ - if( _isatty(_fileno(out)) ){ + if( UseWtextForOutput(out) ){ /* When writing to the command-prompt in Windows, it is necessary ** to use _O_WTEXT input mode and write UTF-16 characters. */ @@ -119,7 +156,7 @@ int sqlite3_fputs(const char *z, FILE *out){ if( b1==0 ) return 0; sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); b1[sz] = 0; - _setmode(_fileno(out), _O_WTEXT); + _setmode(_fileno(out), _O_U8TEXT); fputws(b1, out); sqlite3_free(b1); return 0; @@ -136,7 +173,7 @@ int sqlite3_fputs(const char *z, FILE *out){ */ int sqlite3_fprintf(FILE *out, const char *zFormat, ...){ int rc; - if( _isatty(fileno(out)) ){ + if( UseWtextForOutput(out) ){ /* When writing to the command-prompt in Windows, it is necessary ** to use _O_WTEXT input mode and write UTF-16 characters. */ @@ -161,12 +198,14 @@ int sqlite3_fprintf(FILE *out, const char *zFormat, ...){ } /* -** Set the mode for a stream. mode argument is typically _O_BINARY or +** Set the mode for an output stream. mode argument is typically _O_BINARY or ** _O_TEXT. */ void sqlite3_fsetmode(FILE *fp, int mode){ - fflush(fp); - _setmode(_fileno(fp), mode); + if( !UseWtextForOutput(fp) ){ + fflush(fp); + _setmode(_fileno(fp), mode); + } } #endif /* defined(_WIN32) */ diff --git a/manifest b/manifest index ea40af4ac6..7cdc9f8b96 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sshell\stest\scases\sto\saccount\sfor\srecent\sadditions\sto\sthe\s".help"\soutput. -D 2024-09-26T01:29:22.012 +C Provide\sSQLITE_U8TEXT_ONLY\sand\sSQLITE_U8TEXT_STDIO\scompile-time\soptions\nto\sthe\ssqlite3_stdio.c\smodule. +D 2024-09-26T19:16:20.290 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -425,7 +425,7 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 -F ext/misc/sqlite3_stdio.c aefcfaeefdee26eae2c0d94e41d3720d86b1dc5c96e70132366ab1e204f9ef92 +F ext/misc/sqlite3_stdio.c f110e6f2dc97c67e89f941f82af7dbd221193fa44d1e3ef38a691454a2cbccda F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 5a5881cbe128962b431bfd466ff408db6bf05b971db67200615be38745f0ceef +F src/shell.c.in f82c16f090496e61d4b67500522dbbf8f1b37c77415aafc24a7c84bc9d0c8709 F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 660ca5ce6600d897cc2b00b9d39e5d993c1c0e71ec0d5dc706246c053a163281 -R 3b1b1ac1efd2caefa25e8d6c9bf0ff2f +P 54c22bc6165affbea0d1166a0912d19939300ccc4ae33a6b2ed8c510ab61c574 +R 2b2b12aba8675f6b1c9a607cabf2b89d U drh -Z 1e00c19e9c0388401e635e4bb988cbfe +Z a76d82025e5362f7f888a23f868f0cc8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fac43782cc..04b6c8d8cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54c22bc6165affbea0d1166a0912d19939300ccc4ae33a6b2ed8c510ab61c574 +f31588520e3f45b50dcaa9eecab17f52ebb56bb53d0f9bdb88cc596d1a156353 diff --git a/src/shell.c.in b/src/shell.c.in index c848c4c235..b8c247cc2a 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1631,7 +1631,13 @@ static const char *modeDescr[] = { #define SEP_Tab "\t" #define SEP_Space " " #define SEP_Comma "," -#define SEP_CrLf "\r\n" +#ifdef SQLITE_U8TEXT_ONLY + /* With the SQLITE_U8TEXT_ONLY option, the output will always be in + ** text mode. The \r will be inserted automatically. */ +# define SEP_CrLf "\n" +#else +# define SEP_CrLf "\r\n" +#endif #define SEP_Unit "\x1F" #define SEP_Record "\x1E" @@ -4933,9 +4939,10 @@ static const char *(azHelp[]) = { ".clone NEWDB Clone data into NEWDB from the existing database", #endif ".connection [close] [#] Open or close an auxiliary database connection", -#if defined(_WIN32) || defined(WIN32) +#if defined(_WIN32) && !defined(SQLITE_U8TEXT_ONLY) \ + && !defined(SQLITE_U8TEXT_STDIO) ".crnl on|off Translate \\n to \\r\\n. Default ON", -#endif +#endif /* _WIN32 && U8TEXT_ONLY && U8TEXT_STDIO */ ".databases List names and files of attached databases", ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", #if SQLITE_SHELL_HAVE_RECOVER @@ -8425,17 +8432,8 @@ static int do_meta_command(char *zLine, ShellState *p){ /* Undocumented. Legacy only. See "crnl" below */ if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){ - if( nArg==2 ){ - if( booleanValue(azArg[1]) ){ - sqlite3_fsetmode(p->out, _O_BINARY); - }else{ - sqlite3_fsetmode(p->out, _O_TEXT); - } - }else{ - eputz("The \".binary\" command is deprecated. Use \".crnl\" instead.\n" - "Usage: .binary on|off\n"); - rc = 1; - } + eputz("The \".binary\" command is deprecated. Use \".crnl\" instead.\n"); + rc = 1; }else /* The undocumented ".breakpoint" command causes a call to the no-op @@ -8561,6 +8559,10 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c=='c' && n==4 && cli_strncmp(azArg[0], "crnl", n)==0 ){ +#if !defined(_WIN32) || defined(SQLITE_U8TEXT_ONLY) \ + || defined(SQLITE_U8TEXT_STDIO) + sqlite3_fputs("The \".crnl\" command is disable in this build.\n", p->out); +#else if( nArg==2 ){ if( booleanValue(azArg[1]) ){ sqlite3_fsetmode(p->out, _O_TEXT); @@ -8568,12 +8570,10 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_fsetmode(p->out, _O_BINARY); } }else{ -#if !defined(_WIN32) && !defined(WIN32) - eputz("The \".crnl\" is a no-op on non-Windows machines.\n"); -#endif eputz("Usage: .crnl on|off\n"); rc = 1; } +#endif }else if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){ From c94e4a7b2fb1686ef78a518fc6b3ad13e27eecf5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 26 Sep 2024 22:25:13 +0000 Subject: [PATCH 24/25] Fix a harmless compiler warning in the CLI. FossilOrigin-Name: 27ef1909bb0c4d9470c6074b40500632c68341127a079a3eb3b6a19dbfb2aeac --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/shell.c.in | 6 +++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c147b4354a..68ea64dcf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sext/misc/sqlite3_stdio.c\sportability\sinterface\sand\sincorporate\sit\ninto\sthe\sCLI,\ssqldiff,\sand\ssqlite3_analyzer.\s\sEnhance\sthe\sCLI\swith\sthe\snew\n".www"\sdot-command\sand\srelated\soptions\son\s.once\sand\s.output. -D 2024-09-26T19:38:34.453 +C Fix\sa\sharmless\scompiler\swarning\sin\sthe\sCLI. +D 2024-09-26T22:25:13.188 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -770,7 +770,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in f82c16f090496e61d4b67500522dbbf8f1b37c77415aafc24a7c84bc9d0c8709 +F src/shell.c.in 857c60ed21ae2c58d7740d790e8b22e167136ad1930af50527ec0e584a8cc8aa F src/sqlite.h.in b20547021d20ba016c2fd0500f14f08a21ff23e64a0ed93e72ca0fecb9e1d0a0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2215,9 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2916460179c6089375188c6e4e3cff1fca5bbbbb7280a10c919e09e75d1f11f8 f31588520e3f45b50dcaa9eecab17f52ebb56bb53d0f9bdb88cc596d1a156353 -R f87c6f9c6a8b13e5a36fdc8ca3678f8e -T +closed f31588520e3f45b50dcaa9eecab17f52ebb56bb53d0f9bdb88cc596d1a156353 +P f97f9944b829a49da12786f934da0a5ad51591afd6d8a19a4a0835f51bbdbff2 +R a6968f0fc463c15c807b790b3704b8a0 U drh -Z ae14ce22d9ca5329be6ced79481d3b29 +Z 47d3a59057a462e974fa3c72ad894820 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a71365e258..edb083fd58 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f97f9944b829a49da12786f934da0a5ad51591afd6d8a19a4a0835f51bbdbff2 +27ef1909bb0c4d9470c6074b40500632c68341127a079a3eb3b6a19dbfb2aeac diff --git a/src/shell.c.in b/src/shell.c.in index b8c247cc2a..56f63fb190 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -12732,7 +12732,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ sqlite3_fprintf(stderr, "attach debugger to process %d and press ENTER to continue...", GETPID()); - sqlite3_fgets(zLine, sizeof(zLine), stdin); + if( sqlite3_fgets(zLine, sizeof(zLine), stdin)!=0 + && cli_strcmp(zLine,"stop")==0 + ){ + exit(1); + } }else{ #if defined(_WIN32) || defined(WIN32) #if SQLITE_OS_WINRT From c707b2eb6d8456f682574a10b718e48bf07c7d99 Mon Sep 17 00:00:00 2001 From: stephan <stephan@noemail.net> Date: Fri, 27 Sep 2024 16:20:03 +0000 Subject: [PATCH 25/25] Squash sign-comparison warnings reported in [forum:5e605a763a65c3f8 | forum post 5e605a763a65c3f8]. FossilOrigin-Name: e74fce93c518296bdb0a4273cd5fd3f785d37d27750ca456b61a3502135775f9 --- ext/misc/spellfix.c | 8 ++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index a0c5aafd10..6debdf5dbd 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -351,7 +351,7 @@ static int substituteCost(char cPrev, char cFrom, char cTo){ ** Negative values indicate an error: ** -1 One of the inputs is NULL ** -2 Non-ASCII characters on input -** -3 Unable to allocate memory +** -3 Unable to allocate memory ** ** If pnMatch is not NULL, then *pnMatch is set to the number of bytes ** of zB that matched the pattern in zA. If zA does not end with a '*', @@ -360,8 +360,8 @@ static int substituteCost(char cPrev, char cFrom, char cTo){ ** of zB that was deemed to match zA. */ static int editdist1(const char *zA, const char *zB, int *pnMatch){ - int nA, nB; /* Number of characters in zA[] and zB[] */ - int xA, xB; /* Loop counters for zA[] and zB[] */ + unsigned int nA, nB; /* Number of characters in zA[] and zB[] */ + unsigned int xA, xB; /* Loop counters for zA[] and zB[] */ char cA = 0, cB; /* Current character of zA and zB */ char cAprev, cBprev; /* Previous character of zA and zB */ char cAnext, cBnext; /* Next character in zA and zB */ @@ -3021,7 +3021,7 @@ static sqlite3_module spellfix1Module = { */ static int spellfix1Register(sqlite3 *db){ int rc = SQLITE_OK; - int i; + unsigned int i; rc = sqlite3_create_function(db, "spellfix1_translit", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, transliterateSqlFunc, 0, 0); diff --git a/manifest b/manifest index 68ea64dcf2..00d8d3f66e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\sin\sthe\sCLI. -D 2024-09-26T22:25:13.188 +C Squash\ssign-comparison\swarnings\sreported\sin\s[forum:5e605a763a65c3f8\s|\sforum\spost\s5e605a763a65c3f8]. +D 2024-09-27T16:20:03.346 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -423,7 +423,7 @@ F ext/misc/series.c a6089b5e8e3002bd1e5d9877cee6aead0b9a6426e406c09a399817db9e9a F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9 F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea +F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 F ext/misc/sqlite3_stdio.c f110e6f2dc97c67e89f941f82af7dbd221193fa44d1e3ef38a691454a2cbccda F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176 @@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f97f9944b829a49da12786f934da0a5ad51591afd6d8a19a4a0835f51bbdbff2 -R a6968f0fc463c15c807b790b3704b8a0 -U drh -Z 47d3a59057a462e974fa3c72ad894820 +P 27ef1909bb0c4d9470c6074b40500632c68341127a079a3eb3b6a19dbfb2aeac +R 81a4d040bd5425cfeac10fd5ca0ed96b +U stephan +Z 6359f322b683086f026c8375d9816233 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index edb083fd58..40b51b8191 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27ef1909bb0c4d9470c6074b40500632c68341127a079a3eb3b6a19dbfb2aeac +e74fce93c518296bdb0a4273cd5fd3f785d37d27750ca456b61a3502135775f9