diff --git a/manifest b/manifest index f50d302e4f..1346fe76ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".auth\sON|OFF"\scommand\sto\sthe\scommand-line\sshell. -D 2016-04-04T17:23:10.395 +C Improved\shandling\sof\sUTF8\sby\sthe\scommand-line\sshell. +D 2016-04-04T17:34:54.498 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -360,7 +360,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec -F src/os_win.c ff870d89f4cb088a04cbf5ea0cbd9ff1b089ff4a +F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -376,7 +376,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 -F src/shell.c e0996a0be612c8d2630fdf8bcedf4c4260a29734 +F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/sqlite.h.in c46a7b85d3f37371cacea8f98ec825f5e52c420c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1051,7 +1051,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test dff5b20ad989770aface6d714491121172dfe8b0 +F test/shell1.test a216486c6aeae4d3e75e37d64e4b6c8974108750 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1482,7 +1482,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8627a4cd6d64bd076b56c1e8ccc3b1dfc1b4c07d -R 327fee759e5533f8bd09762659f3f70b +P 65c7bcc42786a254966c531ba9062abb8fc8c5bf f4cbd18db47af4af990d7891dcc831e92b3f17e0 +R 6a3470f790b8def5155325c3cfdf4cee +T +closed f4cbd18db47af4af990d7891dcc831e92b3f17e0 U drh -Z ff39f0b57606b297cab9fa07bc83cd18 +Z cd8719efec0532e424e0fef6159fe981 diff --git a/manifest.uuid b/manifest.uuid index 8a44ee2cd4..cf9bd49e8e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65c7bcc42786a254966c531ba9062abb8fc8c5bf \ No newline at end of file +4534ebf15fbcd6fe2028957b7aa591b6cd5da95f \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index f64a7d43a7..4aca70b6c9 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1306,6 +1306,12 @@ void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */ if( nMin<-1 ) nMin = -1; /* all negative values become -1. */ assert( nMin==-1 || nMin==0 || nMin0 ){ memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); @@ -1631,147 +1637,244 @@ void sqlite3MemSetDefault(void){ #endif /* SQLITE_WIN32_MALLOC */ /* -** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). +** Convert a UTF-8 string to Microsoft Unicode. ** -** Space to hold the returned string is obtained from malloc. +** Space to hold the returned string is obtained from sqlite3_malloc(). */ -static LPWSTR winUtf8ToUnicode(const char *zFilename){ +static LPWSTR winUtf8ToUnicode(const char *zText){ int nChar; - LPWSTR zWideFilename; + LPWSTR zWideText; - nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0); if( nChar==0 ){ return 0; } - zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) ); - if( zWideFilename==0 ){ + zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) ); + if( zWideText==0 ){ return 0; } - nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, + nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText, nChar); if( nChar==0 ){ - sqlite3_free(zWideFilename); - zWideFilename = 0; + sqlite3_free(zWideText); + zWideText = 0; } - return zWideFilename; + return zWideText; } /* -** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is -** obtained from sqlite3_malloc(). +** Convert a Microsoft Unicode string to UTF-8. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). */ -static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ +static char *winUnicodeToUtf8(LPCWSTR zWideText){ int nByte; - char *zFilename; + char *zText; - nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0); if( nByte == 0 ){ return 0; } - zFilename = sqlite3MallocZero( nByte ); - if( zFilename==0 ){ + zText = sqlite3MallocZero( nByte ); + if( zText==0 ){ return 0; } - nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte, 0, 0); if( nByte == 0 ){ - sqlite3_free(zFilename); - zFilename = 0; + sqlite3_free(zText); + zText = 0; } - return zFilename; + return zText; } /* -** Convert an ANSI string to Microsoft Unicode, based on the -** current codepage settings for file apis. +** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM +** code page. ** -** Space to hold the returned string is obtained -** from sqlite3_malloc. +** Space to hold the returned string is obtained from sqlite3_malloc(). */ -static LPWSTR winMbcsToUnicode(const char *zFilename){ +static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ int nByte; - LPWSTR zMbcsFilename; - int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; + LPWSTR zMbcsText; + int codepage = useAnsi ? CP_ACP : CP_OEMCP; - nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, 0)*sizeof(WCHAR); if( nByte==0 ){ return 0; } - zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) ); - if( zMbcsFilename==0 ){ + zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) ); + if( zMbcsText==0 ){ return 0; } - nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, nByte); if( nByte==0 ){ - sqlite3_free(zMbcsFilename); - zMbcsFilename = 0; + sqlite3_free(zMbcsText); + zMbcsText = 0; } - return zMbcsFilename; + return zMbcsText; } /* -** Convert Microsoft Unicode to multi-byte character string, based on the -** user's ANSI codepage. +** Convert a Microsoft Unicode string to a multi-byte character string, +** using the ANSI or OEM code page. ** -** Space to hold the returned string is obtained from -** sqlite3_malloc(). +** Space to hold the returned string is obtained from sqlite3_malloc(). */ -static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ +static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ int nByte; - char *zFilename; - int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; + char *zText; + int codepage = useAnsi ? CP_ACP : CP_OEMCP; - nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); + nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0); if( nByte == 0 ){ return 0; } - zFilename = sqlite3MallocZero( nByte ); - if( zFilename==0 ){ + zText = sqlite3MallocZero( nByte ); + if( zText==0 ){ return 0; } - nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, + nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText, nByte, 0, 0); if( nByte == 0 ){ - sqlite3_free(zFilename); - zFilename = 0; + sqlite3_free(zText); + zText = 0; } - return zFilename; + return zText; } /* -** Convert multibyte character string to UTF-8. Space to hold the -** returned string is obtained from sqlite3_malloc(). +** Convert a multi-byte character string to UTF-8. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). */ -char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ - char *zFilenameUtf8; +static char *winMbcsToUtf8(const char *zText, int useAnsi){ + char *zTextUtf8; LPWSTR zTmpWide; - zTmpWide = winMbcsToUnicode(zFilename); + zTmpWide = winMbcsToUnicode(zText, useAnsi); if( zTmpWide==0 ){ return 0; } - zFilenameUtf8 = winUnicodeToUtf8(zTmpWide); + zTextUtf8 = winUnicodeToUtf8(zTmpWide); sqlite3_free(zTmpWide); - return zFilenameUtf8; + return zTextUtf8; } /* -** Convert UTF-8 to multibyte character string. Space to hold the -** returned string is obtained from sqlite3_malloc(). +** Convert a UTF-8 string to a multi-byte character string. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). */ -char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ - char *zFilenameMbcs; +static char *winUtf8ToMbcs(const char *zText, int useAnsi){ + char *zTextMbcs; LPWSTR zTmpWide; - zTmpWide = winUtf8ToUnicode(zFilename); + zTmpWide = winUtf8ToUnicode(zText); if( zTmpWide==0 ){ return 0; } - zFilenameMbcs = winUnicodeToMbcs(zTmpWide); + zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi); sqlite3_free(zTmpWide); - return zFilenameMbcs; + return zTextMbcs; +} + +/* +** This is a public wrapper for the winUtf8ToUnicode() function. +*/ +LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToUnicode(zText); +} + +/* +** This is a public wrapper for the winUnicodeToUtf8() function. +*/ +char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zWideText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUnicodeToUtf8(zWideText); +} + +/* +** This is a public wrapper for the winMbcsToUtf8() function. +*/ +char *sqlite3_win32_mbcs_to_utf8(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winMbcsToUtf8(zText, osAreFileApisANSI()); +} + +/* +** This is a public wrapper for the winMbcsToUtf8() function. +*/ +char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winMbcsToUtf8(zText, useAnsi); +} + +/* +** This is a public wrapper for the winUtf8ToMbcs() function. +*/ +char *sqlite3_win32_utf8_to_mbcs(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToMbcs(zText, osAreFileApisANSI()); +} + +/* +** This is a public wrapper for the winUtf8ToMbcs() function. +*/ +char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToMbcs(zText, useAnsi); } /* @@ -1873,7 +1976,7 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ sqlite3BeginBenignMalloc(); - zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); sqlite3EndBenignMalloc(); /* free the system buffer allocated by FormatMessage */ osLocalFree(zTemp); @@ -4318,7 +4421,7 @@ static char *winConvertToUtf8Filename(const void *zFilename){ } #ifdef SQLITE_WIN32_HAS_ANSI else{ - zConverted = sqlite3_win32_mbcs_to_utf8(zFilename); + zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); } #endif /* caller will handle out of memory */ @@ -4339,7 +4442,7 @@ static void *winConvertFromUtf8Filename(const char *zFilename){ } #ifdef SQLITE_WIN32_HAS_ANSI else{ - zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); + zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); } #endif /* caller will handle out of memory */ @@ -4540,7 +4643,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), "winGetTempname3", 0); } - zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); + zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI()); if( zUtf8 ){ sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); sqlite3_free(zUtf8); @@ -5318,7 +5421,7 @@ static int winFullPathname( "winFullPathname4", zRelative); } sqlite3_free(zConverted); - zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); sqlite3_free(zTemp); } #endif diff --git a/src/shell.c b/src/shell.c index 809d9d0459..001dd6d465 100644 --- a/src/shell.c +++ b/src/shell.c @@ -90,7 +90,7 @@ #else -# define shell_read_history(X) +# define shell_read_history(X) # define shell_write_history(X) # define shell_stifle_history(X) @@ -136,6 +136,15 @@ #define IsDigit(X) isdigit((unsigned char)X) #define ToLower(X) (char)tolower((unsigned char)X) +#if defined(_WIN32) || defined(WIN32) +#include + +/* string conversion routines only needed on Win32 */ +extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); +extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); +extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); +#endif + /* 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 @@ -143,17 +152,17 @@ ** routines take care of that. */ #if defined(_WIN32) || defined(WIN32) -static void setBinaryMode(FILE *out){ - fflush(out); - _setmode(_fileno(out), _O_BINARY); +static void setBinaryMode(FILE *file, int isOutput){ + if( isOutput ) fflush(file); + _setmode(_fileno(file), _O_BINARY); } -static void setTextMode(FILE *out){ - fflush(out); - _setmode(_fileno(out), _O_TEXT); +static void setTextMode(FILE *file, int isOutput){ + if( isOutput ) fflush(file); + _setmode(_fileno(file), _O_TEXT); } #else -# define setBinaryMode(X) -# define setTextMode(X) +# define setBinaryMode(X,Y) +# define setTextMode(X,Y) #endif @@ -204,7 +213,7 @@ static void beginTimer(void){ /* Return the difference of two time_structs in seconds */ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ - return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + + return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + (double)(pEnd->tv_sec - pStart->tv_sec); } @@ -229,8 +238,6 @@ static void endTimer(void){ #elif (defined(_WIN32) || defined(WIN32)) -#include - /* Saved resource information for the beginning of an operation */ static HANDLE hProcess; static FILETIME ftKernelBegin; @@ -261,7 +268,7 @@ static int hasTimer(void){ if( NULL != getProcessTimesAddr ){ return 1; } - FreeLibrary(hinstLib); + FreeLibrary(hinstLib); } } } @@ -307,7 +314,7 @@ static void endTimer(void){ #define HAS_TIMER hasTimer() #else -#define BEGIN_TIMER +#define BEGIN_TIMER #define END_TIMER #define HAS_TIMER 0 #endif @@ -361,6 +368,38 @@ static char *Argv0; static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ +/* +** Render output like fprintf(). Except, if the output is going to the +** console and if this is running on a Windows machine, translate the +** output from UTF-8 into MBCS. +*/ +#if defined(_WIN32) || defined(WIN32) +void utf8_printf(FILE *out, const char *zFormat, ...){ + va_list ap; + va_start(ap, zFormat); + if( stdout_is_console && (out==stdout || out==stderr) ){ + char *z1 = sqlite3_vmprintf(zFormat, ap); + char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); + sqlite3_free(z1); + fputs(z2, out); + sqlite3_free(z2); + }else{ + vfprintf(out, zFormat, ap); + } + va_end(ap); +} +#elif !defined(utf8_printf) +# define utf8_printf fprintf +#endif + +/* +** Render output like fprintf(). This should not be used on anything that +** includes string formatting (e.g. "%s"). +*/ +#if !defined(raw_printf) +# define raw_printf fprintf +#endif + /* ** Write I/O traces to the following stream. */ @@ -382,7 +421,7 @@ static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); va_end(ap); - fprintf(iotrace, "%s", z); + utf8_printf(iotrace, "%s", z); sqlite3_free(z); } #endif @@ -416,8 +455,8 @@ static int isNumber(const char *z, int *realnum){ } /* -** A global char* and an SQL function to access its current value -** from within an SQL statement. This program used to use the +** A global char* and an SQL function to access its current value +** from within an SQL statement. This program used to use the ** sqlite_exec_printf() API to substitue a string into an SQL statement. ** The correct way to do this with sqlite3 is to use the bind API, but ** since the shell is built around the callback paradigm it would be a lot @@ -483,11 +522,10 @@ static char *local_getline(char *zLine, FILE *in){ } } #if defined(_WIN32) || defined(WIN32) - /* For interactive input on Windows systems, translate the + /* For interactive input on Windows systems, translate the ** multi-byte characterset characters into UTF-8. */ if( stdin_is_interactive ){ - extern char *sqlite3_win32_mbcs_to_utf8(const char*); - char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine); + char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); if( zTrans ){ int nTrans = strlen30(zTrans)+1; if( nTrans>nLine ){ @@ -553,40 +591,7 @@ struct OpenSession { #endif /* -** Render output like fprintf(). Except, if the output is going to the -** console and if this is running on a Windows machine, translate the -** output from UTF-8 into MBCS. -*/ -#if defined(_WIN32) || defined(WIN32) -void utf8_printf(FILE *out, const char *zFormat, ...){ - va_list ap; - va_start(ap, zFormat); - if( stdout_is_console && (out==stdout || out==stderr) ){ - extern char *sqlite3_win32_utf8_to_mbcs(const char*); - char *z1 = sqlite3_vmprintf(zFormat, ap); - char *z2 = sqlite3_win32_utf8_to_mbcs(z1); - sqlite3_free(z1); - fputs(z2, out); - sqlite3_free(z2); - }else{ - vfprintf(out, zFormat, ap); - } - va_end(ap); -} -#elif !defined(utf8_printf) -# define utf8_printf fprintf -#endif - -/* -** Render output like fprintf(). This should not be used on anything that -** includes string formatting (e.g. "%s"). -*/ -#if !defined(raw_printf) -# define raw_printf fprintf -#endif - -/* -** Shell output mode information from before ".explain on", +** Shell output mode information from before ".explain on", ** saved so that it can be restored by ".explain off" */ typedef struct SavedModeInfo SavedModeInfo; @@ -723,7 +728,7 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ static void output_quoted_string(FILE *out, const char *z){ int i; int nSingle = 0; - setBinaryMode(out); + setBinaryMode(out, 1); for(i=0; z[i]; i++){ if( z[i]=='\'' ) nSingle++; } @@ -746,7 +751,7 @@ static void output_quoted_string(FILE *out, const char *z){ } raw_printf(out,"'"); } - setTextMode(out); + setTextMode(out, 1); } /* @@ -788,11 +793,11 @@ static void output_html_string(FILE *out, const char *z){ int i; if( z==0 ) z = ""; while( *z ){ - for(i=0; z[i] - && z[i]!='<' - && z[i]!='&' - && z[i]!='>' - && z[i]!='\"' + for(i=0; z[i] + && z[i]!='<' + && z[i]!='&' + && z[i]!='>' + && z[i]!='\"' && z[i]!='\''; i++){} if( i>0 ){ @@ -820,22 +825,22 @@ static void output_html_string(FILE *out, const char *z){ ** array, then the string must be quoted for CSV. */ static const char needCsvQuote[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; /* @@ -852,8 +857,8 @@ static void output_csv(ShellState *p, const char *z, int bSep){ int i; int nSep = strlen30(p->colSeparator); for(i=0; z[i]; i++){ - if( needCsvQuote[((unsigned char*)z)[i]] - || (z[i]==p->colSeparator[0] && + if( needCsvQuote[((unsigned char*)z)[i]] + || (z[i]==p->colSeparator[0] && (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){ i = 0; break; @@ -1109,7 +1114,7 @@ static int shell_callback( break; } case MODE_Csv: { - setBinaryMode(p->out); + setBinaryMode(p->out, 1); if( p->cnt++==0 && p->showHeader ){ for(i=0; iout, "%s", p->rowSeparator); } - setTextMode(p->out); + setTextMode(p->out, 1); break; } case MODE_Insert: { @@ -1235,7 +1240,7 @@ static void set_table_name(ShellState *p, const char *zName){ ** added to zIn, and the result returned in memory obtained from malloc(). ** zIn, if it was not NULL, is freed. ** -** If the third argument, quote, is not '\0', then it is used as a +** If the third argument, quote, is not '\0', then it is used as a ** quote character for zAppend. */ static char *appendText(char *zIn, char const *zAppend, char quote){ @@ -1282,7 +1287,7 @@ static char *appendText(char *zIn, char const *zAppend, char quote){ ** semicolon terminator to the end of that line. ** ** If the number of columns is 1 and that column contains text "--" -** then write the semicolon on a separate line. That way, if a +** then write the semicolon on a separate line. That way, if a ** "--" comment occurs at the end of the statement, the comment ** won't consume the semicolon terminator. */ @@ -1312,7 +1317,7 @@ static int run_table_dump_query( } z = (const char*)sqlite3_column_text(pSelect, 0); utf8_printf(p->out, "%s", z); - for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); } if( z==0 ) z = ""; @@ -1321,7 +1326,7 @@ static int run_table_dump_query( raw_printf(p->out, "\n;\n"); }else{ raw_printf(p->out, ";\n"); - } + } rc = sqlite3_step(pSelect); } rc = sqlite3_finalize(pSelect); @@ -1380,7 +1385,7 @@ static void displayLinuxIoStats(FILE *out){ } } fclose(in); -} +} #endif @@ -1396,7 +1401,7 @@ static int display_stats( int iHiwtr; if( pArg && pArg->out ){ - + iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset); raw_printf(pArg->out, @@ -1480,18 +1485,18 @@ static int display_stats( raw_printf(pArg->out, "Page cache hits: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache misses: %d\n", iCur); + raw_printf(pArg->out, "Page cache misses: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache writes: %d\n", iCur); + raw_printf(pArg->out, "Page cache writes: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", - iCur); + iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", - iCur); + iCur); } if( pArg && pArg->out && db && pArg->pStmt ){ @@ -1553,7 +1558,7 @@ static void display_scanstats( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain); rEstLoop *= rEst; - raw_printf(pArg->out, + raw_printf(pArg->out, " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n", nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst ); @@ -1580,7 +1585,7 @@ static int str_in_array(const char *zStr, const char **azArray){ /* ** If compiled statement pSql appears to be an EXPLAIN statement, allocate ** and populate the ShellState.aiIndent[] array with the number of -** spaces each opcode should be indented before it is output. +** spaces each opcode should be indented before it is output. ** ** The indenting rules are: ** @@ -1685,12 +1690,12 @@ static void explain_data_delete(ShellState *p){ } /* -** Execute a statement or set of statements. Print -** any result rows/columns depending on the current mode +** Execute a statement or set of statements. Print +** any result rows/columns depending on the current mode ** set via the supplied callback. ** -** This is very similar to SQLite's built-in sqlite3_exec() -** function except it takes a slightly different callback +** This is very similar to SQLite's built-in sqlite3_exec() +** function except it takes a slightly different callback ** and callback data argument. */ static int shell_exec( @@ -1762,7 +1767,7 @@ static int shell_exec( ){ pArg->cMode = MODE_Explain; } - + /* If the shell is currently in ".explain" mode, gather the extra ** data required to add indents to the output.*/ if( pArg->cMode==MODE_Explain ){ @@ -1788,7 +1793,7 @@ static int shell_exec( char **azVals = &azCols[nCol]; /* Results */ int *aiTypes = (int *)&azVals[nCol]; /* Result types */ int i, x; - assert(sizeof(int) <= sizeof(char *)); + assert(sizeof(int) <= sizeof(char *)); /* save off ptrs to column names */ for(i=0; iout, + raw_printf(p->out, ".session ?NAME? SUBCOMMAND ?ARGS...?\n" "If ?NAME? is omitted, the first defined session is used.\n" "Subcommands:\n" @@ -2093,7 +2098,7 @@ void session_help(ShellState *p){ " changeset FILE Write a changeset into FILE\n" " close Close one session\n" " enable ?BOOLEAN? Set or query the enable bit\n" - " filter GLOB... Reject tables matching GLOBs\n" + " filter GLOB... Reject tables matching GLOBs\n" " indirect ?BOOLEAN? Mark or query the indirect status\n" " isempty Query whether the session is empty\n" " list List currently open session names\n" @@ -2230,7 +2235,7 @@ static void open_db(ShellState *p, int keepAlive){ shellstaticFunc, 0, 0); } if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ - utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", + utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", p->zDbFilename, sqlite3_errmsg(p->db)); if( keepAlive ) return; exit(1); @@ -2394,7 +2399,7 @@ static void output_file_close(FILE *f){ /* ** Try to open an output file. The names "stdout" and "stderr" are -** recognized and do the right thing. NULL is returned if the output +** recognized and do the right thing. NULL is returned if the output ** filename is "off". */ static FILE *output_file_open(const char *zFile){ @@ -2583,7 +2588,7 @@ static void tryToCloneData( sqlite3 *newDb, const char *zTable ){ - sqlite3_stmt *pQuery = 0; + sqlite3_stmt *pQuery = 0; sqlite3_stmt *pInsert = 0; char *zQuery = 0; char *zInsert = 0; @@ -2887,9 +2892,9 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ utf8_printf(p->out, "%-20s %u", aField[i].zName, val); switch( ofst ){ case 56: { - if( val==1 ) raw_printf(p->out, " (utf8)"); - if( val==2 ) raw_printf(p->out, " (utf16le)"); - if( val==3 ) raw_printf(p->out, " (utf16be)"); + if( val==1 ) raw_printf(p->out, " (utf8)"); + if( val==2 ) raw_printf(p->out, " (utf16le)"); + if( val==3 ) raw_printf(p->out, " (utf16be)"); } } raw_printf(p->out, "\n"); @@ -2949,9 +2954,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zLine[h]=='\'' || zLine[h]=='"' ){ int delim = zLine[h++]; azArg[nArg++] = &zLine[h]; - while( zLine[h] && zLine[h]!=delim ){ + while( zLine[h] && zLine[h]!=delim ){ if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++; - h++; + h++; } if( zLine[h]==delim ){ zLine[h++] = 0; @@ -3053,9 +3058,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){ if( nArg==2 ){ if( booleanValue(azArg[1]) ){ - setBinaryMode(p->out); + setBinaryMode(p->out, 1); }else{ - setTextMode(p->out); + setTextMode(p->out, 1); } }else{ raw_printf(stderr, "Usage: .binary on|off\n"); @@ -3127,11 +3132,11 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); p->nErr = 0; if( nArg==1 ){ - run_schema_dump_query(p, + run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" ); - run_schema_dump_query(p, + run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE name=='sqlite_sequence'" ); @@ -3180,7 +3185,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ raw_printf(stderr, "Usage: .eqp on|off\n"); rc = 1; - } + } }else if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ @@ -3562,7 +3567,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 ){ @@ -3966,11 +3971,11 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCmd!=2 ) goto session_syntax_error; if( pSession->p==0 ){ session_not_open: - fprintf(stderr, "ERROR: No sessions are open\n"); + raw_printf(stderr, "ERROR: No sessions are open\n"); }else{ rc = sqlite3session_attach(pSession->p, azCmd[1]); if( rc ){ - fprintf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); + raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); rc = 0; } } @@ -3986,7 +3991,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( pSession->p==0 ) goto session_not_open; out = fopen(azCmd[1], "wb"); if( out==0 ){ - fprintf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); + utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); }else{ int szChng; void *pChng; @@ -3999,9 +4004,9 @@ static int do_meta_command(char *zLine, ShellState *p){ printf("Error: error code %d\n", rc); rc = 0; } - if( pChng + if( pChng && fwrite(pChng, szChng, 1, out)!=1 ){ - fprintf(stderr, "ERROR: Failed to write entire %d-byte output\n", + raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n", szChng); } sqlite3_free(pChng); @@ -4029,7 +4034,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( p->nSession ){ ii = sqlite3session_enable(pSession->p, ii); - fprintf(p->out, "session %s enable flag = %d\n", pSession->zName, ii); + utf8_printf(p->out, "session %s enable flag = %d\n", + pSession->zName, ii); } }else @@ -4047,11 +4053,11 @@ static int do_meta_command(char *zLine, ShellState *p){ nByte = sizeof(pSession->azFilter[0])*(nCmd-1); pSession->azFilter = sqlite3_malloc( nByte ); if( pSession->azFilter==0 ){ - fprintf(stderr, "Error: out or memory\n"); + raw_printf(stderr, "Error: out or memory\n"); exit(1); } for(ii=1; iiazFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); + pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); } pSession->nFilter = ii-1; } @@ -4066,7 +4072,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( p->nSession ){ ii = sqlite3session_indirect(pSession->p, ii); - fprintf(p->out, "session %s indirect flag = %d\n", pSession->zName,ii); + utf8_printf(p->out, "session %s indirect flag = %d\n", + pSession->zName, ii); } }else @@ -4078,7 +4085,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCmd!=1 ) goto session_syntax_error; if( p->nSession ){ ii = sqlite3session_isempty(pSession->p); - fprintf(p->out, "session %s isempty flag = %d\n", pSession->zName, ii); + utf8_printf(p->out, "session %s isempty flag = %d\n", + pSession->zName, ii); } }else @@ -4087,7 +4095,7 @@ static int do_meta_command(char *zLine, ShellState *p){ */ if( strcmp(azCmd[0],"list")==0 ){ for(i=0; inSession; i++){ - fprintf(p->out, "%d %s\n", i, p->aSession[i].zName); + utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName); } }else @@ -4102,18 +4110,18 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zName[0]==0 ) goto session_syntax_error; for(i=0; inSession; i++){ if( strcmp(p->aSession[i].zName,zName)==0 ){ - fprintf(stderr, "Session \"%s\" already exists\n", zName); + utf8_printf(stderr, "Session \"%s\" already exists\n", zName); goto meta_command_exit; } } if( p->nSession>=ArraySize(p->aSession) ){ - fprintf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); + raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); goto meta_command_exit; } pSession = &p->aSession[p->nSession]; rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); if( rc ){ - fprintf(stderr, "Cannot open session: error code=%d\n", rc); + raw_printf(stderr, "Cannot open session: error code=%d\n", rc); rc = 0; goto meta_command_exit; } @@ -4382,9 +4390,9 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, db, int) */ case SQLITE_TESTCTRL_OPTIMIZATIONS: - case SQLITE_TESTCTRL_RESERVE: + case SQLITE_TESTCTRL_RESERVE: if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); + int opt = (int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { @@ -4408,7 +4416,7 @@ static int do_meta_command(char *zLine, ShellState *p){ break; /* sqlite3_test_control(int, uint) */ - case SQLITE_TESTCTRL_PENDING_BYTE: + case SQLITE_TESTCTRL_PENDING_BYTE: if( nArg==3 ){ unsigned int opt = (unsigned int)integerValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); @@ -4418,13 +4426,13 @@ static int do_meta_command(char *zLine, ShellState *p){ " int option\n", azArg[1]); } break; - + /* sqlite3_test_control(int, int) */ - case SQLITE_TESTCTRL_ASSERT: - case SQLITE_TESTCTRL_ALWAYS: - case SQLITE_TESTCTRL_NEVER_CORRUPT: + case SQLITE_TESTCTRL_ASSERT: + case SQLITE_TESTCTRL_ALWAYS: + case SQLITE_TESTCTRL_NEVER_CORRUPT: if( nArg==3 ){ - int opt = booleanValue(azArg[2]); + int opt = booleanValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { @@ -4435,9 +4443,9 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, char *) */ #ifdef SQLITE_N_KEYWORD - case SQLITE_TESTCTRL_ISKEYWORD: + case SQLITE_TESTCTRL_ISKEYWORD: if( nArg==3 ){ - const char *opt = azArg[2]; + const char *opt = azArg[2]; rc2 = sqlite3_test_control(testctrl, opt); raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { @@ -4450,7 +4458,7 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_IMPOSTER: if( nArg==5 ){ - rc2 = sqlite3_test_control(testctrl, p->db, + rc2 = sqlite3_test_control(testctrl, p->db, azArg[2], integerValue(azArg[3]), integerValue(azArg[4])); @@ -4460,10 +4468,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } break; - case SQLITE_TESTCTRL_BITVEC_TEST: - case SQLITE_TESTCTRL_FAULT_INSTALL: - case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: - case SQLITE_TESTCTRL_SCRATCHMALLOC: + case SQLITE_TESTCTRL_BITVEC_TEST: + case SQLITE_TESTCTRL_FAULT_INSTALL: + case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: + case SQLITE_TESTCTRL_SCRATCHMALLOC: default: utf8_printf(stderr, "Error: CLI support for testctrl %s not implemented\n", @@ -4477,7 +4485,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); }else - + if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){ if( nArg==2 ){ enableTimer = booleanValue(azArg[1]); @@ -4490,7 +4498,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; } }else - + if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ open_db(p, 0); if( nArg!=2 ){ @@ -4570,7 +4578,7 @@ static int do_meta_command(char *zLine, ShellState *p){ raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n"); rc = 1; goto meta_command_exit; - } + } }else #endif /* SQLITE_USER_AUTHENTICATION */ @@ -4802,7 +4810,7 @@ static int process_input(ShellState *p, FILE *in){ if( rc || zErrMsg ){ char zPrefix[100]; if( in!=0 || !stdin_is_interactive ){ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, + sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error: near line %d:", startline); }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); @@ -4944,7 +4952,7 @@ static void process_sqliterc( /* ** Show available command line options */ -static const char zOptions[] = +static const char zOptions[] = " -ascii set output mode to 'ascii'\n" " -bail stop after hitting an error\n" " -batch force batch I/O\n" @@ -4981,7 +4989,7 @@ static const char zOptions[] = ; static void usage(int showDetail){ utf8_printf(stderr, - "Usage: %s [OPTIONS] FILENAME [SQL]\n" + "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.\n", Argv0); if( showDetail ){ @@ -5043,7 +5051,20 @@ static char *cmdline_option_value(int argc, char **argv, int i){ return argv[i]; } +#ifndef SQLITE_SHELL_IS_UTF8 +# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) +# define SQLITE_SHELL_IS_UTF8 (0) +# else +# define SQLITE_SHELL_IS_UTF8 (1) +# endif +#endif + +#if SQLITE_SHELL_IS_UTF8 int SQLITE_CDECL main(int argc, char **argv){ +#else +int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ + char **argv; +#endif char *zErrMsg = 0; ShellState data; const char *zInitFile = 0; @@ -5054,6 +5075,11 @@ int SQLITE_CDECL main(int argc, char **argv){ int nCmd = 0; char **azCmd = 0; + setBinaryMode(stdin, 0); + setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ + stdin_is_interactive = isatty(0); + stdout_is_console = isatty(1); + #if USE_SYSTEM_SQLITE+0!=1 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", @@ -5061,12 +5087,24 @@ int SQLITE_CDECL main(int argc, char **argv){ exit(1); } #endif - setBinaryMode(stdin); - setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ - Argv0 = argv[0]; main_init(&data); - stdin_is_interactive = isatty(0); - stdout_is_console = isatty(1); +#if !SQLITE_SHELL_IS_UTF8 + sqlite3_initialize(); + argv = sqlite3_malloc64(sizeof(argv[0])*argc); + if( argv==0 ){ + raw_printf(stderr, "out of memory\n"); + exit(1); + } + for(i=0; i=1 && argv && argv[0] ); + Argv0 = argv[0]; /* Make sure we have a valid signal handler early, before anything ** else is done. @@ -5122,7 +5160,7 @@ int SQLITE_CDECL main(int argc, char **argv){ zInitFile = cmdline_option_value(argc, argv, ++i); }else if( strcmp(z,"-batch")==0 ){ /* Need to check for batch mode here to so we can avoid printing - ** informational messages (like from process_sqliterc) before + ** informational messages (like from process_sqliterc) before ** we do the actual processing of arguments later in a second pass. */ stdin_is_interactive = 0; @@ -5397,6 +5435,10 @@ int SQLITE_CDECL main(int argc, char **argv){ session_close_all(&data); sqlite3_close(data.db); } - sqlite3_free(data.zFreeOnClose); + sqlite3_free(data.zFreeOnClose); +#if !SQLITE_SHELL_IS_UTF8 + for(i=0; i