From 57b32ef924850824ce120987e7d9e2306bf254f1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 24 Sep 2024 13:46:32 +0000 Subject: [PATCH] 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);