--- origsrc/sqlite-autoconf-3080300/Makefile.am 2014-02-03 15:04:55.000000000 +0100 +++ src/sqlite-autoconf-3080300/Makefile.am 2014-02-04 12:53:52.195918100 +0100 @@ -1,13 +1,13 @@ AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE - + lib_LTLIBRARIES = libsqlite3.la libsqlite3_la_SOURCES = sqlite3.c libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8 bin_PROGRAMS = sqlite3 sqlite3_SOURCES = shell.c sqlite3.h -sqlite3_LDADD = $(top_builddir)/libsqlite3.la @READLINE_LIBS@ +sqlite3_LDADD = $(top_builddir)/libsqlite3.la @READLINE_LIBS@ -licui18n -licuuc -lz sqlite3_DEPENDENCIES = $(top_builddir)/libsqlite3.la include_HEADERS = sqlite3.h sqlite3ext.h --- origsrc/sqlite-autoconf-3080300/icu.c 1970-01-01 01:00:00.000000000 +0100 +++ src/sqlite-autoconf-3080300/icu.c 2014-02-04 12:53:52.204918600 +0100 @@ -0,0 +1,504 @@ +/* +** 2007 May 6 +** +** 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. +** +************************************************************************* +** $Id: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $ +** +** This file implements an integration between the ICU library +** ("International Components for Unicode", an open-source library +** for handling unicode data) and SQLite. The integration uses +** ICU to provide the following to SQLite: +** +** * An implementation of the SQL regexp() function (and hence REGEXP +** operator) using the ICU uregex_XX() APIs. +** +** * Implementations of the SQL scalar upper() and lower() functions +** for case mapping. +** +** * Integration of ICU and SQLite collation sequences. +** +** * An implementation of the LIKE operator that uses ICU to +** provide case-independent matching. +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) + +/* Include ICU headers */ +#include +#include +#include +#include + +#include + +#ifndef SQLITE_CORE + #include "sqlite3ext.h" + SQLITE_EXTENSION_INIT1 +#else + #include "sqlite3.h" +#endif + +/* +** Maximum length (in bytes) of the pattern in a LIKE or GLOB +** operator. +*/ +#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH +# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 +#endif + +/* +** Version of sqlite3_free() that is always a function, never a macro. +*/ +static void xFree(void *p){ + sqlite3_free(p); +} + +/* +** Compare two UTF-8 strings for equality where the first string is +** a "LIKE" expression. Return true (1) if they are the same and +** false (0) if they are different. +*/ +static int icuLikeCompare( + const uint8_t *zPattern, /* LIKE pattern */ + const uint8_t *zString, /* The UTF-8 string to compare against */ + const UChar32 uEsc /* The escape character */ +){ + static const int MATCH_ONE = (UChar32)'_'; + static const int MATCH_ALL = (UChar32)'%'; + + int iPattern = 0; /* Current byte index in zPattern */ + int iString = 0; /* Current byte index in zString */ + + int prevEscape = 0; /* True if the previous character was uEsc */ + + while( zPattern[iPattern]!=0 ){ + + /* Read (and consume) the next character from the input pattern. */ + UChar32 uPattern; + U8_NEXT_UNSAFE(zPattern, iPattern, uPattern); + assert(uPattern!=0); + + /* There are now 4 possibilities: + ** + ** 1. uPattern is an unescaped match-all character "%", + ** 2. uPattern is an unescaped match-one character "_", + ** 3. uPattern is an unescaped escape character, or + ** 4. uPattern is to be handled as an ordinary character + */ + if( !prevEscape && uPattern==MATCH_ALL ){ + /* Case 1. */ + uint8_t c; + + /* Skip any MATCH_ALL or MATCH_ONE characters that follow a + ** MATCH_ALL. For each MATCH_ONE, skip one character in the + ** test string. + */ + while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){ + if( c==MATCH_ONE ){ + if( zString[iString]==0 ) return 0; + U8_FWD_1_UNSAFE(zString, iString); + } + iPattern++; + } + + if( zPattern[iPattern]==0 ) return 1; + + while( zString[iString] ){ + if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){ + return 1; + } + U8_FWD_1_UNSAFE(zString, iString); + } + return 0; + + }else if( !prevEscape && uPattern==MATCH_ONE ){ + /* Case 2. */ + if( zString[iString]==0 ) return 0; + U8_FWD_1_UNSAFE(zString, iString); + + }else if( !prevEscape && uPattern==uEsc){ + /* Case 3. */ + prevEscape = 1; + + }else{ + /* Case 4. */ + UChar32 uString; + U8_NEXT_UNSAFE(zString, iString, uString); + uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT); + uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT); + if( uString!=uPattern ){ + return 0; + } + prevEscape = 0; + } + } + + return zString[iString]==0; +} + +/* +** Implementation of the like() SQL function. This function implements +** the build-in LIKE operator. The first argument to the function is the +** pattern and the second argument is the string. So, the SQL statements: +** +** A LIKE B +** +** is implemented as like(B, A). If there is an escape character E, +** +** A LIKE B ESCAPE E +** +** is mapped to like(B, A, E). +*/ +static void icuLikeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zA = sqlite3_value_text(argv[0]); + const unsigned char *zB = sqlite3_value_text(argv[1]); + UChar32 uEsc = 0; + + /* Limit the length of the LIKE or GLOB pattern to avoid problems + ** of deep recursion and N*N behavior in patternCompare(). + */ + if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + return; + } + + + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + int nE= sqlite3_value_bytes(argv[2]); + const unsigned char *zE = sqlite3_value_text(argv[2]); + int i = 0; + if( zE==0 ) return; + U8_NEXT(zE, i, nE, uEsc); + if( i!=nE){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + } + + if( zA && zB ){ + sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc)); + } +} + +/* +** This function is called when an ICU function called from within +** the implementation of an SQL scalar function returns an error. +** +** The scalar function context passed as the first argument is +** loaded with an error message based on the following two args. +*/ +static void icuFunctionError( + sqlite3_context *pCtx, /* SQLite scalar function context */ + const char *zName, /* Name of ICU function that failed */ + UErrorCode e /* Error code returned by ICU function */ +){ + char zBuf[128]; + sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); + zBuf[127] = '\0'; + sqlite3_result_error(pCtx, zBuf, -1); +} + +/* +** Function to delete compiled regexp objects. Registered as +** a destructor function with sqlite3_set_auxdata(). +*/ +static void icuRegexpDelete(void *p){ + URegularExpression *pExpr = (URegularExpression *)p; + uregex_close(pExpr); +} + +/* +** Implementation of SQLite REGEXP operator. This scalar function takes +** two arguments. The first is a regular expression pattern to compile +** the second is a string to match against that pattern. If either +** argument is an SQL NULL, then NULL Is returned. Otherwise, the result +** is 1 if the string matches the pattern, or 0 otherwise. +** +** SQLite maps the regexp() function to the regexp() operator such +** that the following two are equivalent: +** +** zString REGEXP zPattern +** regexp(zPattern, zString) +** +** Uses the following ICU regexp APIs: +** +** uregex_open() +** uregex_matches() +** uregex_close() +*/ +static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + UErrorCode status = U_ZERO_ERROR; + URegularExpression *pExpr; + UBool res; + const UChar *zString = sqlite3_value_text16(apArg[1]); + + (void)nArg; /* Unused parameter */ + + /* If the left hand side of the regexp operator is NULL, + ** then the result is also NULL. + */ + if( !zString ){ + return; + } + + pExpr = sqlite3_get_auxdata(p, 0); + if( !pExpr ){ + const UChar *zPattern = sqlite3_value_text16(apArg[0]); + if( !zPattern ){ + return; + } + pExpr = uregex_open(zPattern, -1, 0, 0, &status); + + if( U_SUCCESS(status) ){ + sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); + }else{ + assert(!pExpr); + icuFunctionError(p, "uregex_open", status); + return; + } + } + + /* Configure the text that the regular expression operates on. */ + uregex_setText(pExpr, zString, -1, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "uregex_setText", status); + return; + } + + /* Attempt the match */ + res = uregex_matches(pExpr, 0, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "uregex_matches", status); + return; + } + + /* Set the text that the regular expression operates on to a NULL + ** pointer. This is not really necessary, but it is tidier than + ** leaving the regular expression object configured with an invalid + ** pointer after this function returns. + */ + uregex_setText(pExpr, 0, 0, &status); + + /* Return 1 or 0. */ + sqlite3_result_int(p, res ? 1 : 0); +} + +/* +** Implementations of scalar functions for case mapping - upper() and +** lower(). Function upper() converts its input to upper-case (ABC). +** Function lower() converts to lower-case (abc). +** +** ICU provides two types of case mapping, "general" case mapping and +** "language specific". Refer to ICU documentation for the differences +** between the two. +** +** To utilise "general" case mapping, the upper() or lower() scalar +** functions are invoked with one argument: +** +** upper('ABC') -> 'abc' +** lower('abc') -> 'ABC' +** +** To access ICU "language specific" case mapping, upper() or lower() +** should be invoked with two arguments. The second argument is the name +** of the locale to use. Passing an empty string ("") or SQL NULL value +** as the second argument is the same as invoking the 1 argument version +** of upper() or lower(). +** +** lower('I', 'en_us') -> 'i' +** lower('I', 'tr_tr') -> 'ı' (small dotless i) +** +** http://www.icu-project.org/userguide/posix.html#case_mappings +*/ +static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + const UChar *zInput; + UChar *zOutput; + int nInput; + int nOutput; + + UErrorCode status = U_ZERO_ERROR; + const char *zLocale = 0; + + assert(nArg==1 || nArg==2); + if( nArg==2 ){ + zLocale = (const char *)sqlite3_value_text(apArg[1]); + } + + zInput = sqlite3_value_text16(apArg[0]); + if( !zInput ){ + return; + } + nInput = sqlite3_value_bytes16(apArg[0]); + + nOutput = nInput * 2 + 2; + zOutput = sqlite3_malloc(nOutput); + if( !zOutput ){ + return; + } + + if( sqlite3_user_data(p) ){ + u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); + }else{ + u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); + } + + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "u_strToLower()/u_strToUpper", status); + return; + } + + sqlite3_result_text16(p, zOutput, -1, xFree); +} + +/* +** Collation sequence destructor function. The pCtx argument points to +** a UCollator structure previously allocated using ucol_open(). +*/ +static void icuCollationDel(void *pCtx){ + UCollator *p = (UCollator *)pCtx; + ucol_close(p); +} + +/* +** Collation sequence comparison function. The pCtx argument points to +** a UCollator structure previously allocated using ucol_open(). +*/ +static int icuCollationColl( + void *pCtx, + int nLeft, + const void *zLeft, + int nRight, + const void *zRight +){ + UCollationResult res; + UCollator *p = (UCollator *)pCtx; + res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2); + switch( res ){ + case UCOL_LESS: return -1; + case UCOL_GREATER: return +1; + case UCOL_EQUAL: return 0; + } + assert(!"Unexpected return value from ucol_strcoll()"); + return 0; +} + +/* +** Implementation of the scalar function icu_load_collation(). +** +** This scalar function is used to add ICU collation based collation +** types to an SQLite database connection. It is intended to be called +** as follows: +** +** SELECT icu_load_collation(, ); +** +** Where is a string containing an ICU locale identifier (i.e. +** "en_AU", "tr_TR" etc.) and is the name of the +** collation sequence to create. +*/ +static void icuLoadCollation( + sqlite3_context *p, + int nArg, + sqlite3_value **apArg +){ + sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); + UErrorCode status = U_ZERO_ERROR; + const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ + const char *zName; /* SQL Collation sequence name (eg. "japanese") */ + UCollator *pUCollator; /* ICU library collation object */ + int rc; /* Return code from sqlite3_create_collation_x() */ + + assert(nArg==2); + zLocale = (const char *)sqlite3_value_text(apArg[0]); + zName = (const char *)sqlite3_value_text(apArg[1]); + + if( !zLocale || !zName ){ + return; + } + + pUCollator = ucol_open(zLocale, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "ucol_open", status); + return; + } + assert(p); + + rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, + icuCollationColl, icuCollationDel + ); + if( rc!=SQLITE_OK ){ + ucol_close(pUCollator); + sqlite3_result_error(p, "Error registering collation function", -1); + } +} + +/* +** Register the ICU extension functions with database db. +*/ +int sqlite3IcuInit(sqlite3 *db){ + struct IcuScalar { + const char *zName; /* Function name */ + int nArg; /* Number of arguments */ + int enc; /* Optimal text encoding */ + void *pContext; /* sqlite3_user_data() context */ + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } scalars[] = { + {"regexp", 2, SQLITE_ANY, 0, icuRegexpFunc}, + + {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16}, + + {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16}, + + {"like", 2, SQLITE_UTF8, 0, icuLikeFunc}, + {"like", 3, SQLITE_UTF8, 0, icuLikeFunc}, + + {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation}, + }; + + int rc = SQLITE_OK; + int i; + + for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ + struct IcuScalar *p = &scalars[i]; + rc = sqlite3_create_function( + db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0 + ); + } + + return rc; +} + +#if !SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_icu_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3IcuInit(db); +} +#endif + +#endif --- origsrc/sqlite-autoconf-3080300/shell.c 2014-02-03 15:04:55.000000000 +0100 +++ src/sqlite-autoconf-3080300/shell.c 2014-02-04 12:53:52.214919200 +0100 @@ -28,11 +28,24 @@ # define _LARGEFILE_SOURCE 1 #endif +#define SQLITE_CORE 1 +#define SQLITE_ENABLE_ICU 1 +#define SQLITE_ENABLE_ZLIB 1 + #include #include #include #include #include "sqlite3.h" +#ifndef SQLITE_CORE +# define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ +#endif +#ifdef SQLITE_ENABLE_ICU +#include "icu.c" +#endif +#ifdef SQLITE_ENABLE_ZLIB +#include "zlib.c" +#endif #include #include @@ -482,7 +495,7 @@ struct callback_data { #define MODE_Csv 7 /* Quote strings, numbers are plain */ #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ -static const char *modeDescr[] = { +static const char *const modeDescr[] = { "line", "column", "list", @@ -1156,7 +1169,7 @@ static int display_stats( ** is equal, according to strcmp(), to any of the strings in the array. ** Otherwise, return zero. */ -static int str_in_array(const char *zStr, const char **azArray){ +static int str_in_array(const char *zStr, const char *const *azArray){ int i; for(i=0; azArray[i]; i++){ if( 0==strcmp(zStr, azArray[i]) ) return 1; @@ -1188,9 +1201,9 @@ static void explain_data_prepare(struct int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ int iOp; /* Index of operation in p->aiIndent[] */ - const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; - const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 }; - const char *azGoto[] = { "Goto", 0 }; + const char *const azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; + const char *const azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 }; + const char *const azGoto[] = { "Goto", 0 }; /* Try to figure out if this is really an EXPLAIN statement. If this ** cannot be verified, return early. */ @@ -2772,6 +2785,9 @@ static int do_meta_command(char *zLine, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, + { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT }, + { "explain_stmt", SQLITE_TESTCTRL_EXPLAIN_STMT }, + { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT } }; int testctrl = -1; int rc = 0; @@ -2866,6 +2882,9 @@ static int do_meta_command(char *zLine, case SQLITE_TESTCTRL_FAULT_INSTALL: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: case SQLITE_TESTCTRL_SCRATCHMALLOC: + case SQLITE_TESTCTRL_LOCALTIME_FAULT: + case SQLITE_TESTCTRL_EXPLAIN_STMT: + case SQLITE_TESTCTRL_NEVER_CORRUPT: default: fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", azArg[1]); @@ -3271,6 +3290,9 @@ static void usage(int showDetail){ ** Initialize the state information in data */ static void main_init(struct callback_data *data) { +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SQLITE_WIN32_NO_WIDE) + sqlite3_vfs *pVfs; +#endif memset(data, 0, sizeof(*data)); data->mode = MODE_List; memcpy(data->separator,"|", 2); @@ -3280,6 +3302,18 @@ static void main_init(struct callback_da sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SQLITE_WIN32_NO_WIDE) + pVfs = sqlite3_vfs_find("win32-longpath"); + if( pVfs ){ + sqlite3_vfs_register(pVfs, 1); + } +#endif +#ifdef SQLITE_ENABLE_ICU + sqlite3_auto_extension((void *)sqlite3IcuInit); +#endif +#ifdef SQLITE_ENABLE_ZLIB + sqlite3_auto_extension((void *)sqlite3ZlibInit); +#endif } /* @@ -3303,9 +3337,9 @@ int main(int argc, char **argv){ int i; int rc = 0; - if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ - fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", - sqlite3_sourceid(), SQLITE_SOURCE_ID); + if( sqlite3_libversion_number()<3008000 ){ + fprintf(stderr, "Unsuitable SQLite version %s, must be at least 3.8.0", + sqlite3_libversion()); exit(1); } Argv0 = argv[0]; --- origsrc/sqlite-autoconf-3080300/sqlite3.c 2014-02-03 15:04:55.000000000 +0100 +++ src/sqlite-autoconf-3080300/sqlite3.c 2014-02-04 12:53:52.284923200 +0100 @@ -137,7 +137,7 @@ extern "C" { */ #define SQLITE_VERSION "3.8.3" #define SQLITE_VERSION_NUMBER 3008003 -#define SQLITE_SOURCE_ID "2014-02-03 14:04:11 6c643e45c274e755dc5a1a65673df79261c774be" +#define SQLITE_SOURCE_ID "2014-02-03 13:52:03 e816dd924619db5f766de6df74ea2194f3e3b538" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -9779,7 +9779,10 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefa #if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) # define SQLITE_OS_OTHER 0 # ifndef SQLITE_OS_WIN -# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) +# if defined(__CYGWIN__) +# define SQLITE_OS_WIN 1 +# define SQLITE_OS_UNIX 1 +# elif defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) # define SQLITE_OS_WIN 1 # define SQLITE_OS_UNIX 0 # else @@ -9795,7 +9798,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefa # endif #endif -#if SQLITE_OS_WIN +#if SQLITE_OS_WIN && !defined(__CYGWIN__) # include #endif @@ -10067,10 +10070,10 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sq # define SQLITE_MUTEX_OMIT #endif #if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) -# if SQLITE_OS_UNIX -# define SQLITE_MUTEX_PTHREADS -# elif SQLITE_OS_WIN +# if SQLITE_OS_WIN # define SQLITE_MUTEX_W32 +# elif SQLITE_OS_UNIX +# define SQLITE_MUTEX_PTHREADS # else # define SQLITE_MUTEX_NOOP # endif @@ -12743,6 +12746,8 @@ SQLITE_PRIVATE void sqlite3WithPush(Pa #else #define sqlite3WithPush(x,y,z) #define sqlite3WithDelete(x,y) +#define sqlite3WithAdd(p,w,t,x,y) (sqlite3ErrorMsg((p), \ + "near \"%T\": syntax error", (t)),(With*)(w)) #endif /* Declarations for functions in fkey.c. All of these are replaced by @@ -18789,6 +18794,10 @@ SQLITE_PRIVATE sqlite3_mutex_methods con ** This file contains the C functions that implement mutexes for win32 */ +#ifdef __CYGWIN__ +# include /* amalgamator: keep */ +#endif + /* ** The code in this file is only used if we are compiling multithreaded ** on a win32 system. @@ -18885,6 +18894,9 @@ static int winMutex_isInit = 0; */ static LONG winMutex_lock = 0; +#if defined(__CYGWIN__) && defined(SQLITE_AMALGAMATION) +static +#endif SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ static int winMutexInit(void){ @@ -23413,7 +23425,7 @@ SQLITE_PRIVATE const char *sqlite3Opcode ** where the database is located. */ #if !defined(SQLITE_ENABLE_LOCKING_STYLE) -# if defined(__APPLE__) +# if defined(__APPLE__) || defined(__CYGWIN__) # define SQLITE_ENABLE_LOCKING_STYLE 1 # else # define SQLITE_ENABLE_LOCKING_STYLE 0 @@ -23472,13 +23484,17 @@ SQLITE_PRIVATE const char *sqlite3Opcode #include #endif +#ifdef __CYGWIN__ +# include +#endif -#if SQLITE_ENABLE_LOCKING_STYLE +#if SQLITE_ENABLE_LOCKING_STYLE || defined(__CYGWIN__) # include -# if OS_VXWORKS +# if OS_VXWORKS || defined(__CYGWIN__) # include # include -# else +# endif +# if !OS_VXWORKS # include # include # endif @@ -23523,7 +23539,15 @@ SQLITE_PRIVATE const char *sqlite3Opcode /* ** Maximum supported path-length. */ -#define MAX_PATHNAME 512 +#ifndef MAX_PATHNAME +# if defined(PATH_MAX) +# define MAX_PATHNAME PATH_MAX +# elif defined(MAXPATHLEN) +# define MAX_PATHNAME MAXPATHLEN +# else +# define MAX_PATHNAME 512 +# endif +#endif /* ** Only set the lastErrno if the error code is a real error and not @@ -23581,7 +23605,7 @@ struct unixFile { #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif -#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) +#if SQLITE_ENABLE_LOCKING_STYLE && !defined(__CYGWIN__) || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS @@ -23913,6 +23937,7 @@ static int openDirectory(const char*, in ** testing and sandboxing. The following array holds the names and pointers ** to all overrideable system calls. */ +#define aSyscall aUnixSyscall static struct unix_syscall { const char *zName; /* Name of the system call */ sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ @@ -24409,7 +24434,9 @@ struct vxworksFileId { ** variable: */ static struct vxworksFileId *vxworksFileList = 0; +#endif /* OS_VXWORKS */ +#if OS_VXWORKS || defined(__CYGWIN__) /* ** Simplify a filename into its canonical form ** by making the following changes: @@ -24428,7 +24455,13 @@ static int vxworksSimplifyName(char *z, while( n>1 && z[n-1]=='/' ){ n--; } for(i=j=0; ictrlFlags |= UNIXFILE_EXCL; + ioMethods = &posixIoMethods; + }else if( sqlite3_stricmp(strategy, "posix") == 0 ){ + ioMethods = &posixIoMethods; + }else if( sqlite3_stricmp(strategy, "bsd") == 0 + || sqlite3_stricmp(strategy, "flock") == 0 ){ + ioMethods = &flockIoMethods; + }else if( sqlite3_stricmp(strategy, "dotfile") == 0 ){ + ioMethods = &dotlockIoMethods; + }else if( sqlite3_stricmp(strategy, "nfs") == 0 ){ + ioMethods = &nfsIoMethods; + }else if( sqlite3_stricmp(strategy, "none") == 0 ){ + ioMethods = &nolockIoMethods; + }else if( sqlite3_strnicmp(strategy, "win", 3) == 0 + || sqlite3_strnicmp(strategy, "cyg", 3) == 0 + || sqlite3_stricmp(strategy, "proxy") == 0 ){ + /* Fall back to original default */ + ioMethods = &cygwinIoMethods; + } + } + } + return ioMethods; +} +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; + +#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ + /* ** An abstract type for a pointer to a IO method finder function: */ @@ -28745,7 +28851,7 @@ static int fillInUnixFile( ** exception is when opening the proxy "conch" file in builds that ** include the special Apple locking styles. */ -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +#if (defined(__APPLE__) || defined(__CYGWIN__)) && SQLITE_ENABLE_LOCKING_STYLE assert( zFilename==0 || zFilename[0]=='/' || pVfs->pAppData==(void*)&autolockIoFinder ); #else @@ -28792,7 +28898,7 @@ static int fillInUnixFile( } if( pLockingStyle == &posixIoMethods -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +#if (defined(__APPLE__) || defined(__CYGWIN__)) && SQLITE_ENABLE_LOCKING_STYLE || pLockingStyle == &nfsIoMethods #endif ){ @@ -28868,7 +28974,7 @@ static int fillInUnixFile( pNew->lockingContext = zLockFile; } -#if OS_VXWORKS +#if OS_VXWORKS || defined(__CYGWIN__) else if( pLockingStyle == &semIoMethods ){ /* Named semaphore locking uses the file path so it needs to be ** included in the semLockingContext @@ -28878,8 +28984,14 @@ static int fillInUnixFile( if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){ char *zSemName = pNew->pInode->aSemName; int n; +#if OS_VXWORKS sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", pNew->pId->zCanonicalName); +#else + sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", + zFilename); + vxworksSimplifyName(zSemName, MAX_PATHNAME); +#endif for( n=1; zSemName[n]; n++ ) if( zSemName[n]=='/' ) zSemName[n] = '_'; pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); @@ -28891,6 +29003,15 @@ static int fillInUnixFile( unixLeaveMutex(); } #endif + +#if defined(__CYGWIN__) + else if( pLockingStyle == &cygwinIoMethods ){ + if ((osFcntl(h, F_LCK_MANDATORY, 1) != 0) && (errno != EINVAL)) { + /* The API exists but it refused to enable mandatory locking! */ + rc = SQLITE_IOERR_ACCESS; + } + } +#endif pNew->lastErrno = 0; #if OS_VXWORKS @@ -28920,6 +29041,8 @@ static const char *unixTempFileDir(void) 0, 0, 0, + 0, + 0, "/var/tmp", "/usr/tmp", "/tmp", @@ -28932,6 +29055,8 @@ static const char *unixTempFileDir(void) azDirs[0] = sqlite3_temp_directory; if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR"); if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR"); + if( !azDirs[3] ) azDirs[2] = getenv("TMP"); + if( !azDirs[4] ) azDirs[3] = getenv("TEMP"); for(i=0; iopenFlags = openFlags; } @@ -29332,7 +29457,7 @@ static int unixOpen( noLock = eType!=SQLITE_OPEN_MAIN_DB; -#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE && !defined(__CYGWIN__) if( fstatfs(fd, &fsInfo) == -1 ){ ((unixFile*)pFile)->lastErrno = errno; robust_close(p, fd, __LINE__); @@ -29350,7 +29475,7 @@ static int unixOpen( if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; -#if SQLITE_ENABLE_LOCKING_STYLE +#if SQLITE_ENABLE_LOCKING_STYLE && !defined(__CYGWIN__) #if SQLITE_PREFER_PROXY_LOCKING isAutoProxy = 1; #endif @@ -29492,6 +29617,13 @@ static int unixAccess( } +#if SQLITE_OS_WIN +# if defined(SQLITE_AMALGAMATION) + static +# endif + void winSimplifyName(char *z); +#endif + /* ** Turn a relative pathname into a full pathname. The relative path ** is stored as a nul-terminated string in the buffer pointed to by @@ -29507,6 +29639,9 @@ static int unixFullPathname( int nOut, /* Size of output buffer in bytes */ char *zOut /* Output buffer */ ){ +#ifdef __CYGWIN__ + int i; +#endif /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this @@ -29519,6 +29654,35 @@ static int unixFullPathname( UNUSED_PARAMETER(pVfs); zOut[nOut-1] = '\0'; +#ifdef __CYGWIN__ + if( sqlite3Isalpha(zPath[0]) && (zPath[1]==':') + && ((zPath[2]=='\\') || (zPath[2]=='/')) ){ + int nDrive; + char temp[4]; + temp[0] = zPath[0]; + memcpy(&temp[1], ":\\", 3); + cygwin_conv_path(CCP_WIN_A_TO_POSIX, temp, zOut, nOut); + nDrive = (int)strlen(zOut); + sqlite3_snprintf(nOut-nDrive, &zOut[nDrive], "%s", zPath+2); + }else if( ((zPath[0]=='\\') || (zPath[0]=='/')) && ((zPath[1]=='\\') || (zPath[1]=='/')) + && (zPath[2]=='?') && ((zPath[3]=='\\') || (zPath[3]=='/')) && sqlite3Isalpha(zPath[4]) + && (zPath[5]==':') && ((zPath[6]=='\\') || (zPath[6]=='/')) ){ + int nDrive; + char temp[4]; + temp[0] = zPath[4]; + memcpy(&temp[1], ":\\", 3); + cygwin_conv_path(CCP_WIN_A_TO_POSIX, temp, zOut, nOut); + nDrive = (int)strlen(zOut); + sqlite3_snprintf(nOut-nDrive, &zOut[nDrive], "%s", zPath+6); + }else if( ((zPath[0]=='\\') || (zPath[0]=='/')) && ((zPath[1]=='\\') || (zPath[1]=='/')) + && (zPath[2]=='?') && ((zPath[3]=='\\') || (zPath[3]=='/')) && sqlite3_strnicmp(zPath+4, "UNC", 3)==0 + && ((zPath[7]=='\\') || (zPath[7]=='/')) ){ + /* UNC paths in Cygwin start with "//" */ + sqlite3_snprintf(nOut, zOut, "//%s", zPath+8); + }else if( zPath[0]=='\\' ){ + sqlite3_snprintf(nOut, zOut, "%s", zPath); + }else +#endif if( zPath[0]=='/' ){ sqlite3_snprintf(nOut, zOut, "%s", zPath); }else{ @@ -29529,6 +29693,9 @@ static int unixFullPathname( nCwd = (int)strlen(zOut); sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath); } +#if SQLITE_OS_WIN && defined(__CYGWIN__) + winSimplifyName(zOut); +#endif return SQLITE_OK; } @@ -29672,7 +29839,7 @@ static int unixSleep(sqlite3_vfs *NotUse ** sqlite3OsCurrentTime() during testing. */ #ifdef SQLITE_TEST -SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +SQLITE_API extern int sqlite3_current_time; /* Fake system time in seconds since 1970. */ #endif /* @@ -29897,9 +30064,9 @@ static int unixGetLastError(sqlite3_vfs */ /* -** Proxy locking is only available on MacOSX +** Proxy locking is only available on MacOSX/Cygwin */ -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +#if (defined(__APPLE__) || defined(__CYGWIN__)) && SQLITE_ENABLE_LOCKING_STYLE /* ** The proxyLockingContext has the path and file structures for the remote @@ -29965,7 +30132,7 @@ static int proxyGetLockPath(const char * */ static int proxyCreateLockPath(const char *lockPath){ int i, len; - char buf[MAXPATHLEN]; + char buf[MAX_PATHNAME]; int start = 0; assert(lockPath!=NULL); @@ -30090,6 +30257,12 @@ end_create_proxy: SQLITE_API int sqlite3_hostid_num = 0; #endif +#ifdef __CYGWIN__ +# define st_mtimespec st_mtim +# undef uuid_t +# define uuid_t void * +#endif + #define PROXY_HOSTIDLEN 16 /* conch file host id length */ /* Not always defined in the headers as it ought to be */ @@ -30131,7 +30304,7 @@ static int proxyGetHostID(unsigned char #define PROXY_CONCHVERSION 2 /* 1-byte header, 16-byte host id, path */ #define PROXY_HEADERLEN 1 /* conch file header length */ #define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN) -#define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN) +#define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAX_PATHNAME) /* ** Takes an open conch file, copies the contents to a new path and then moves @@ -30142,7 +30315,7 @@ static int proxyGetHostID(unsigned char static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; unixFile *conchFile = pCtx->conchFile; - char tPath[MAXPATHLEN]; + char tPath[MAX_PATHNAME]; char buf[PROXY_MAXCONCHLEN]; char *cPath = pCtx->conchFilePath; size_t readLen = 0; @@ -30153,8 +30326,8 @@ static int proxyBreakConchLock(unixFile UNUSED_PARAMETER(myHostID); /* create a new path by replace the trailing '-conch' with '-break' */ - pathLen = strlcpy(tPath, cPath, MAXPATHLEN); - if( pathLen>MAXPATHLEN || pathLen<6 || + pathLen = strlcpy(tPath, cPath, MAX_PATHNAME); + if( pathLen>MAX_PATHNAME || pathLen<6 || (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); goto end_breaklock; @@ -30287,7 +30460,7 @@ static int proxyTakeConch(unixFile *pFil uuid_t myHostID; int pError = 0; char readBuf[PROXY_MAXCONCHLEN]; - char lockPath[MAXPATHLEN]; + char lockPath[MAX_PATHNAME]; char *tempLockPath = NULL; int rc = SQLITE_OK; int createConch = 0; @@ -30339,8 +30512,8 @@ static int proxyTakeConch(unixFile *pFil if( hostIdMatch ){ size_t pathLen = (readLen - PROXY_PATHINDEX); - if( pathLen>=MAXPATHLEN ){ - pathLen=MAXPATHLEN-1; + if( pathLen>=MAX_PATHNAME ){ + pathLen=MAX_PATHNAME-1; } memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen); lockPath[pathLen] = 0; @@ -30366,7 +30539,7 @@ static int proxyTakeConch(unixFile *pFil /* either the conch didn't match or we need to create a new one */ if( !pCtx->lockProxyPath ){ - proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN); + proxyGetLockPath(pCtx->dbPath, lockPath, MAX_PATHNAME); tempLockPath = lockPath; /* create a copy of the lock path _only_ if the conch is taken */ } @@ -30394,9 +30567,9 @@ static int proxyTakeConch(unixFile *pFil writeBuffer[0] = (char)PROXY_CONCHVERSION; memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); if( pCtx->lockProxyPath!=NULL ){ - strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN); + strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAX_PATHNAME); }else{ - strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); + strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAX_PATHNAME); } writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); robust_ftruncate(conchFile->h, writeSize); @@ -30478,11 +30651,13 @@ static int proxyTakeConch(unixFile *pFil if( rc==SQLITE_OK ){ pCtx->conchHeld = 1; +#if defined(__APPLE__) if( pCtx->lockProxy->pMethod == &afpIoMethods ){ afpLockingContext *afpCtx; afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext; afpCtx->dbPath = pCtx->lockProxyPath; } +#endif } else { conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); } @@ -30575,7 +30750,7 @@ static int switchLockProxyPath(unixFile /* nothing to do if the path is NULL, :auto: or matches the existing path */ if( !path || path[0]=='\0' || !strcmp(path, ":auto:") || - (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){ + (oldPath && !strncmp(oldPath, path, MAX_PATHNAME)) ){ return SQLITE_OK; }else{ unixFile *lockProxy = pCtx->lockProxy; @@ -30595,7 +30770,7 @@ static int switchLockProxyPath(unixFile /* ** pFile is a file that has been opened by a prior xOpen call. dbPath -** is a string buffer at least MAXPATHLEN+1 characters in size. +** is a string buffer at least MAX_PATHNAME+1 characters in size. ** ** This routine find the filename associated with pFile and writes it ** int dbPath. @@ -30605,8 +30780,8 @@ static int proxyGetDbPathForUnixFile(uni if( pFile->pMethod == &afpIoMethods ){ /* afp style keeps a reference to the db path in the filePath field ** of the struct */ - assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); - strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN); + assert( (int)strlen((char*)pFile->lockingContext)<=MAX_PATHNAME ); + strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAX_PATHNAME); } else #endif if( pFile->pMethod == &dotlockIoMethods ){ @@ -30616,8 +30791,8 @@ static int proxyGetDbPathForUnixFile(uni memcpy(dbPath, (char *)pFile->lockingContext, len + 1); }else{ /* all other styles use the locking context to store the db file path */ - assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); - strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN); + assert( strlen((char*)pFile->lockingContext)<=MAX_PATHNAME ); + strlcpy(dbPath, (char *)pFile->lockingContext, MAX_PATHNAME); } return SQLITE_OK; } @@ -30632,7 +30807,7 @@ static int proxyGetDbPathForUnixFile(uni */ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { proxyLockingContext *pCtx; - char dbPath[MAXPATHLEN+1]; /* Name of the database file */ + char dbPath[MAX_PATHNAME+1]; /* Name of the database file */ char *lockPath=NULL; int rc = SQLITE_OK; @@ -30664,15 +30839,19 @@ static int proxyTransformUnixFile(unixFi ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts ** that openFlags will have only one of O_RDONLY or O_RDWR. */ +#if defined(__APPLE__) struct statfs fsInfo; +#endif struct stat conchInfo; int goLockless = 0; if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { int err = errno; +#if defined(__APPLE__) if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; } +#endif } if( goLockless ){ pCtx->conchHeld = -1; /* read only FS/ lockless */ @@ -30753,7 +30932,7 @@ static int proxyFileControl(sqlite3_file (proxyLockingContext*)pFile->lockingContext; if( !strcmp(pArg, ":auto:") || (pCtx->lockProxyPath && - !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) + !strncmp(pCtx->lockProxyPath, proxyPath, MAX_PATHNAME)) ){ rc = SQLITE_OK; }else{ @@ -30931,7 +31110,15 @@ static int proxyClose(sqlite3_file *id) ** necessarily been initialized when this routine is called, and so they ** should not be used. */ -SQLITE_API int sqlite3_os_init(void){ +#if SQLITE_OS_WIN +#if defined(SQLITE_AMALGAMATION) +static +#endif +SQLITE_API int sqlite3_os_unix_init(void){ +#else +SQLITE_API int sqlite3_os_init(void){ +#endif + /* ** The following macro defines an initializer for an sqlite3_vfs object. ** The name of the VFS is NAME. The pAppData is a pointer to a pointer @@ -30985,25 +31172,33 @@ SQLITE_API int sqlite3_os_init(void){ ** array cannot be const. */ static sqlite3_vfs aVfs[] = { -#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__)) +#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__) || defined(__CYGWIN__)) UNIXVFS("unix", autolockIoFinder ), #else UNIXVFS("unix", posixIoFinder ), #endif +#ifdef __CYGWIN__ + UNIXVFS("unix-cygwin", cygwinIoFinder ), +#if !SQLITE_OS_WIN + UNIXVFS("win32-longpath", cygwinIoFinder ), +#endif +#endif UNIXVFS("unix-none", nolockIoFinder ), UNIXVFS("unix-dotfile", dotlockIoFinder ), UNIXVFS("unix-excl", posixIoFinder ), -#if OS_VXWORKS +#if OS_VXWORKS || defined(__CYGWIN__) UNIXVFS("unix-namedsem", semIoFinder ), #endif #if SQLITE_ENABLE_LOCKING_STYLE UNIXVFS("unix-posix", posixIoFinder ), -#if !OS_VXWORKS - UNIXVFS("unix-flock", flockIoFinder ), #endif +#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS || defined(__CYGWIN__) + UNIXVFS("unix-flock", flockIoFinder ), #endif -#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +#if SQLITE_ENABLE_LOCKING_STYLE && (defined(__APPLE__) || defined(__CYGWIN__)) +#if defined(__APPLE__) UNIXVFS("unix-afp", afpIoFinder ), +#endif UNIXVFS("unix-nfs", nfsIoFinder ), UNIXVFS("unix-proxy", proxyIoFinder ), #endif @@ -31021,6 +31216,8 @@ SQLITE_API int sqlite3_os_init(void){ return SQLITE_OK; } +#undef aSyscall +#if !SQLITE_OS_WIN /* ** Shutdown the operating system interface. ** @@ -31031,6 +31228,7 @@ SQLITE_API int sqlite3_os_init(void){ SQLITE_API int sqlite3_os_end(void){ return SQLITE_OK; } +#endif /* !SQLITE_OS_WIN */ #endif /* SQLITE_OS_UNIX */ @@ -31053,8 +31251,16 @@ SQLITE_API int sqlite3_os_end(void){ #if SQLITE_OS_WIN /* This file is used for Windows only */ #ifdef __CYGWIN__ -# include +/* # include */ +# include /* amalgamator: keep */ +# include /* amalgamator: keep */ # include /* amalgamator: keep */ +# include /* amalgamator: keep */ +#else +enum { + CCP_POSIX_TO_WIN_W=1, + CCP_WIN_A_TO_POSIX +}; #endif /* @@ -31283,7 +31489,8 @@ SQLITE_API int sqlite3_open_file_count = ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions ** based on the sub-platform)? */ -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(_WIN64) \ + && !defined(__CYGWIN__) && !defined(SQLITE_WIN32_NO_ANSI) # define SQLITE_WIN32_HAS_ANSI #endif @@ -31359,7 +31566,11 @@ SQLITE_API int sqlite3_open_file_count = ** UNICODE_STRING_MAX_CHARS. */ #ifndef SQLITE_WINNT_MAX_PATH_CHARS -# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS) +# ifdef __CYGWIN__ +# define SQLITE_WINNT_MAX_PATH_CHARS (PATH_MAX) +# else +# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS) +# endif #endif /* @@ -31906,7 +32117,7 @@ static struct win_syscall { #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) -#if !defined(SQLITE_OMIT_LOAD_EXTENSION) +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) || !defined(__CYGWIN__) #if SQLITE_OS_WINCE /* The GetProcAddressA() routine is only available on Windows CE. */ { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, @@ -32293,6 +32504,65 @@ static struct win_syscall { #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) +#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(__CYGWIN__) + { "GetModuleHandleA", (SYSCALL)GetModuleHandleA, 0 }, +#else + { "GetModuleHandleA", (SYSCALL)0, 0 }, +#endif + +#define osGetModuleHandleA ((HMODULE(*)(LPCSTR))aSyscall[76].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) && !defined(__CYGWIN__) + { "GetModuleHandleW", (SYSCALL)GetModuleHandleW, 0 }, +#else + { "GetModuleHandleW", (SYSCALL)0, 0 }, +#endif + +#define osGetModuleHandleW ((HMODULE(*)(LPCWSTR))aSyscall[77].pCurrent) + +#if defined(__CYGWIN__) + { "getenv", (SYSCALL)getenv, 0 }, +#else + { "getenv", (SYSCALL)0, 0 }, +#endif + +#define getenv ((const char *(*)(const char *))aSyscall[78].pCurrent) + +#if defined(__CYGWIN__) + { "getcwd", (SYSCALL)getcwd, 0 }, +#else + { "getcwd", (SYSCALL)0, 0 }, +#endif + +#define getcwd ((char*(*)(char*,size_t))aSyscall[79].pCurrent) + +#if defined(__CYGWIN__) + { "__errno", (SYSCALL)__errno, 0 }, +#else + { "__errno", (SYSCALL)0, 0 }, +#endif + +#define osErrno (*((int*(*)(void))aSyscall[80].pCurrent)()) + +#if defined(__CYGWIN__) && defined(SQLITE_WIN32_HAS_WIDE) + { "cygwin_conv_path", (SYSCALL)cygwin_conv_path, 0 }, +#else + { "cygwin_conv_path", (SYSCALL)0, 0 }, +#endif + +#define cygwin_conv_path ((ssize_t(*)(unsigned int, \ + const void *, void *, size_t))aSyscall[81].pCurrent) + + { "cygwin_conv_to_full_win32_path", (SYSCALL)0, 0 }, + +#define cygwin_conv_to_full_win32_path ((void(*)(const char *, \ + char *))aSyscall[82].pCurrent) + + { "cygwin_conv_to_full_posix_path", (SYSCALL)0, 0 }, + +#define cygwin_conv_to_full_posix_path ((void(*)(const char *, \ + char *))aSyscall[83].pCurrent) + }; /* End of the overrideable system calls */ /* @@ -32466,6 +32736,7 @@ SQLITE_API int sqlite3_win32_reset_heap( } #endif /* SQLITE_WIN32_MALLOC */ +#ifndef __CYGWIN__ /* ** This function outputs the specified (ANSI) string to the Win32 debugger ** (if available). @@ -32502,6 +32773,7 @@ SQLITE_API void sqlite3_win32_write_debu } #endif } +#endif /* !__CYGWIN__ */ /* ** The following routine suspends the current thread for at least ms @@ -32511,6 +32783,9 @@ SQLITE_API void sqlite3_win32_write_debu static HANDLE sleepObj = NULL; #endif +#if defined(__CYGWIN__) && defined(SQLITE_AMALGAMATION) +static +#endif SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){ #if SQLITE_OS_WINRT if ( sleepObj==NULL ){ @@ -32768,9 +33043,11 @@ SQLITE_PRIVATE void sqlite3MemSetDefault /* ** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). ** -** Space to hold the returned string is obtained from malloc. +** Space to hold the returned string is obtained from malloc, +** unless buf is not NULL and the needed size is less than +** SQLITE_WIN32_MAX_PATH_CHARS bytes. */ -static LPWSTR winUtf8ToUnicode(const char *zFilename){ +static LPWSTR winUtf8ToUnicode(const char *zFilename, WCHAR *buf){ int nChar; LPWSTR zWideFilename; @@ -32778,9 +33055,13 @@ static LPWSTR winUtf8ToUnicode(const cha if( nChar==0 ){ return 0; } - zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) ); - if( zWideFilename==0 ){ - return 0; + if( buf && (nChar<=SQLITE_WIN32_MAX_PATH_CHARS/sizeof(WCHAR)) ){ + zWideFilename = buf; + }else{ + zWideFilename = sqlite3Malloc( nChar*sizeof(WCHAR) ); + if( zWideFilename==0 ){ + return 0; + } } nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); @@ -32833,7 +33114,7 @@ static LPWSTR winMbcsToUnicode(const cha if( nByte==0 ){ return 0; } - zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) ); + zMbcsFilename = sqlite3Malloc( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; } @@ -32862,7 +33143,7 @@ static char *winUnicodeToMbcs(LPCWSTR zW if( nByte == 0 ){ return 0; } - zFilename = sqlite3MallocZero( nByte ); + zFilename = sqlite3Malloc( nByte ); if( zFilename==0 ){ return 0; } @@ -32875,6 +33156,7 @@ static char *winUnicodeToMbcs(LPCWSTR zW return zFilename; } +#if !defined(__CYGWIN__) /* ** Convert multibyte character string to UTF-8. Space to hold the ** returned string is obtained from sqlite3_malloc(). @@ -32894,18 +33176,22 @@ SQLITE_API char *sqlite3_win32_mbcs_to_u /* ** Convert UTF-8 to multibyte character string. Space to hold the -** returned string is obtained from sqlite3_malloc(). +** returned string is obtained from sqlite3_malloc(). If 'buf' is +** non-zero, it points to scratch area to be used internally, +** saving a 'malloc' call. */ -SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ +SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename, WCHAR *buf){ char *zFilenameMbcs; LPWSTR zTmpWide; - zTmpWide = winUtf8ToUnicode(zFilename); + zTmpWide = winUtf8ToUnicode(zFilename, buf); if( zTmpWide==0 ){ return 0; } zFilenameMbcs = winUnicodeToMbcs(zTmpWide); - sqlite3_free(zTmpWide); + if( zTmpWide != buf ){ + sqlite3_free(zTmpWide); + } return zFilenameMbcs; } @@ -32931,7 +33217,7 @@ SQLITE_API int sqlite3_win32_set_directo || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ); assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); - if( ppDirectory ){ + if( !getenv && ppDirectory ){ char *zValueUtf8 = 0; if( zValue && zValue[0] ){ zValueUtf8 = winUnicodeToUtf8(zValue); @@ -32945,6 +33231,7 @@ SQLITE_API int sqlite3_win32_set_directo } return SQLITE_ERROR; } +#endif /* !__CYGWIN__*/ /* ** The return value of winGetLastErrorMsg @@ -33178,8 +33465,9 @@ static int winceCreateLock(const char *z DWORD lastErrno; BOOL bLogged = FALSE; BOOL bInit = TRUE; + WCHAR buf[SQLITE_WIN32_MAX_PATH_CHARS/sizeof(WCHAR)]; - zName = winUtf8ToUnicode(zFilename); + zName = winUtf8ToUnicode(zFilename, buf); if( zName==0 ){ /* out of memory */ return SQLITE_IOERR_NOMEM; @@ -33199,7 +33487,9 @@ static int winceCreateLock(const char *z pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ pFile->lastErrno = osGetLastError(); - sqlite3_free(zName); + if( zName!=buf ){ + sqlite3_free(zName); + } return winLogError(SQLITE_IOERR, pFile->lastErrno, "winceCreateLock1", zFilename); } @@ -33223,7 +33513,9 @@ static int winceCreateLock(const char *z bInit = FALSE; } - sqlite3_free(zName); + if( zName!=buf ){ + sqlite3_free(zName); + } /* If we succeeded in making the shared memory handle, map it. */ if( pFile->hShared ){ @@ -33861,8 +34153,7 @@ static int winTruncate(sqlite3_file *id, ** Count the number of fullsyncs and normal syncs. This is used to test ** that syncs and fullsyncs are occuring at the right times. */ -SQLITE_API int sqlite3_sync_count = 0; -SQLITE_API int sqlite3_fullsync_count = 0; +extern int sqlite3_sync_count, sqlite3_fullsync_count; #endif /* @@ -34446,7 +34737,7 @@ static int winDeviceCharacteristics(sqli ** During sqlite3_os_init() we do a GetSystemInfo() ** to get the granularity size. */ -SYSTEM_INFO winSysInfo; +static SYSTEM_INFO winSysInfo; #ifndef SQLITE_OMIT_WAL @@ -35348,7 +35639,7 @@ static const sqlite3_io_methods winIoMet ** sqlite3_vfs object. */ -#if defined(__CYGWIN__) +#if 0 /* ** Convert a filename from whatever the underlying operating system ** supports for filenames into UTF-8. Space to hold the result is @@ -35373,16 +35664,77 @@ static char *winConvertToUtf8Filename(co ** Convert a UTF-8 filename into whatever form the underlying ** operating system wants filenames in. Space to hold the result ** is obtained from malloc and must be freed by the calling -** function. +** function, unless buf is not NULL and the needed size is less +** than SQLITE_WIN32_MAX_PATH_CHARS bytes. */ -static void *winConvertFromUtf8Filename(const char *zFilename){ +static void *winConvertFromUtf8Filename(const char *zFilename, WCHAR *buf){ void *zConverted = 0; if( osIsNT() ){ - zConverted = winUtf8ToUnicode(zFilename); + int nChar; + LPWSTR zWideFilename; + + if( (cygwin_conv_path!=NULL) && !(winIsDriveLetterAndColon(zFilename) + && winIsDirSep(zFilename[2]))){ + int nByte = cygwin_conv_path(CCP_POSIX_TO_WIN_W, zFilename, 0, 0); + if( nByte>0 ){ + if( buf && (nBytemxPathname @@ -36204,7 +36620,73 @@ static int winFullPathname( char *zFull /* Output buffer */ ){ -#if defined(__CYGWIN__) +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) + DWORD nByte; + void *zConverted; + char *zOut; + WCHAR buf[SQLITE_WIN32_MAX_PATH_CHARS/sizeof(WCHAR)]; +#endif + + if( cygwin_conv_path || cygwin_conv_to_full_posix_path ){ + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + UNUSED_PARAMETER(pVfs); + + zFull[nFull-1] = '\0'; + if( winIsDirSep(zRelative[0]) && winIsDirSep(zRelative[1]) + && zRelative[2]=='?' && winIsDirSep(zRelative[3])){ + /* This is an extended path. Convert to non-extended form. */ + if( winIsDriveLetterAndColon(&zRelative[4]) && winIsDirSep(zRelative[6]) ){ + int nDrive; + char temp[4]; + temp[0] = zRelative[4]; + memcpy(&temp[1], ":\\", 3); + if( cygwin_conv_path ){ + cygwin_conv_path(CCP_WIN_A_TO_POSIX, temp, zFull, nFull); + }else{ + cygwin_conv_to_full_posix_path(temp, zFull); + } + nDrive = (int)strlen(zFull); + sqlite3_snprintf(nFull-nDrive, &zFull[nDrive], "%s", zRelative+4); + }else if( sqlite3_strnicmp(zRelative+4, "UNC", 3)==0 && winIsDirSep(zRelative[7]) ){ + /* UNC paths in Cygwin start with "//" */ + sqlite3_snprintf(nFull, zFull, "//%s", zRelative+8); + }else{ + /* Something wrong, no conversion */ + sqlite3_snprintf(nFull, zFull, "%s", zRelative); + } + }else if( winIsDriveLetterAndColon(zRelative) && winIsDirSep(zRelative[2]) ){ + int nDrive; + char temp[4]; + temp[0] = zRelative[0]; + memcpy(&temp[1], ":\\", 3); + if( cygwin_conv_path ){ + cygwin_conv_path(CCP_WIN_A_TO_POSIX, temp, zFull, nFull); + }else{ + cygwin_conv_to_full_posix_path(temp, zFull); + } + nDrive = (int)strlen(zFull); + sqlite3_snprintf(nFull-nDrive, &zFull[nDrive], "%s", zRelative+2); + }else if( getcwd && !winIsDirSep(zRelative[0]) ){ + int nCwd; + if( getcwd(zFull, nFull-1)==0 ){ + return winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "getcwd", zRelative); + } + nCwd = (int)strlen(zFull); + sqlite3_snprintf(nFull-nCwd, &zFull[nCwd], "/%s", zRelative); + }else{ + sqlite3_snprintf(nFull, zFull, "%s", zRelative); + } +#if defined(_WIN32) || defined(__CYGWIN__) + winSimplifyName(zFull); +#endif + return SQLITE_OK; + } +#if 0 SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); assert( nFull>=pVfs->mxPathname ); @@ -36281,9 +36763,11 @@ static int winFullPathname( #endif #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) +#if 0 DWORD nByte; void *zConverted; char *zOut; +#endif /* If this path name begins with "/X:", where "X" is any alphabetic ** character, discard the initial "/" from the pathname. @@ -36309,32 +36793,131 @@ static int winFullPathname( sqlite3_data_directory, winGetDirSep(), zRelative); return SQLITE_OK; } - zConverted = winConvertFromUtf8Filename(zRelative); - if( zConverted==0 ){ - return SQLITE_IOERR_NOMEM; + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, NULL, 0); + if( nByte==0 ){ + return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)osGetLastError(), + "winFullPathname", zRelative); + } + if( osIsNT() ){ + LPWSTR zWideFilename; + int i, j; + + if( nByte>SQLITE_WIN32_MAX_PATH_CHARS ){ + /* No Win32 API functions can handle such long paths. Let's see if + * we can do something about it. If not, just leave it as is. */ + if( winIsDirSep(zRelative[0]) && winIsDirSep(zRelative[1]) + && zRelative[2]!='?' ){ + /* It's an UNC path, convert it to an extended UNC path. */ + zWideFilename = sqlite3MallocZero( (nByte+6)*sizeof(WCHAR) ); + if( zWideFilename==0 ){ + return SQLITE_IOERR_NOMEM; + } + memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative+2, -1, + zWideFilename+8, nByte); + goto finished; + }else if( winIsDriveLetterAndColon(zRelative) + && winIsDirSep(zRelative[2]) ){ + /* It has a correct drive prefix, convert to extended form. */ + zWideFilename = sqlite3MallocZero( (nByte+4)*sizeof(WCHAR) ); + if( zWideFilename==0 ){ + return SQLITE_IOERR_NOMEM; + } + memcpy(zWideFilename, L"\\\\?\\", 8); + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, + zWideFilename+4, nByte); + zWideFilename[6] = '\\'; + goto finished; + } + /* Another form, e.g. relative path or maybe it already + * has the '\\?\' prefix. Just leave it as-is. */ + } + if( nByte<=SQLITE_WIN32_MAX_PATH_CHARS/sizeof(WCHAR) ){ + zWideFilename = buf; + }else{ + zWideFilename = sqlite3Malloc( nByte*sizeof(WCHAR) ); + if( zWideFilename==0 ){ + return SQLITE_IOERR_NOMEM; + } + } + /* Check whether it has the '\\?\' prefix and can be shortened. */ + if( nByte<=(SQLITE_WIN32_MAX_PATH_CHARS+6) + && winIsDirSep(zRelative[0]) && winIsDirSep(zRelative[1]) + && (zRelative[2]=='?') && winIsDirSep(zRelative[3]) ){ + if( sqlite3_strnicmp(&zRelative[4], "UNC", 3) + && winIsDirSep(zRelative[7]) ){ + memcpy(zWideFilename, L"\\\\", 4); + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative+8, -1, + zWideFilename+2, nByte-8); + }else if( nByte<=(SQLITE_WIN32_MAX_PATH_CHARS+4) ){ + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative+4, -1, + zWideFilename, nByte-4); + }else{ + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, + zWideFilename, nByte); + } + }else{ + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, + zWideFilename, nByte); + } + if( nByte==0 ){ + sqlite3_free(zWideFilename); + return SQLITE_IOERR_NOMEM; + } + finished: + zConverted = zWideFilename; + for(i=j=0; zWideFilename[i]; ++i){ + if( winIsDirSep(zWideFilename[i]) ){ + if( zWideFilename[i+1]=='.' && winIsDirSep(zWideFilename[i+2]) ){ + ++i; + continue; + } + if( !zWideFilename[i+1] || (winIsDirSep(zWideFilename[i+1]) && (i!=0)) ){ + continue; + } + zWideFilename[j++] = '\\'; + }else{ + zWideFilename[j++] = zWideFilename[i]; + } + } + while(j0 ); assert( winSysInfo.dwPageSize>0 ); +#if !defined(__CYGWIN__) + if( osIsNT() ){ + module = osGetModuleHandleW(L"CYGWIN1.DLL"); + if( !module){ + module = osGetModuleHandleW(L"MSYS-1.0.DLL"); + } +#ifdef SQLITE_WIN32_HAS_ANSI + }else{ + module = osGetModuleHandleA("CYGWIN1.DLL"); + if( !module){ + module = osGetModuleHandleA("MSYS-1.0.DLL"); + } +#endif + } + if( module ){ + for( i=78; iskipNext==0 || pCur->eState!=CURSOR_VALID ); if( pCur->eState!=CURSOR_VALID ){ rc = restoreCursorPosition(pCur); @@ -55546,15 +56200,6 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCu ** successful then set *pRes=0. If the cursor ** was already pointing to the first entry in the database before ** this routine was called, then set *pRes=1. -** -** The calling function will set *pRes to 0 or 1. The initial *pRes value -** will be 1 if the cursor being stepped corresponds to an SQL index and -** if this routine could have been skipped if that SQL index had been -** a unique index. Otherwise the caller will have set *pRes to zero. -** Zero is the common case. The btree implementation is free to use the -** initial *pRes value as a hint to improve performance, but the current -** SQLite btree implementation does not. (Note that the comdb2 btree -** implementation does use this hint, however.) */ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ int rc; @@ -55562,7 +56207,6 @@ SQLITE_PRIVATE int sqlite3BtreePrevious( assert( cursorHoldsMutex(pCur) ); assert( pRes!=0 ); - assert( *pRes==0 || *pRes==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); pCur->atLast = 0; if( pCur->eState!=CURSOR_VALID ){ @@ -57789,7 +58433,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(Bt ** sub-tree headed by the child page of the cell being deleted. This makes ** balancing the tree following the delete operation easier. */ if( !pPage->leaf ){ - int notUsed = 0; + int notUsed; rc = sqlite3BtreePrevious(pCur, ¬Used); if( rc ) return rc; } @@ -70054,7 +70698,6 @@ case OP_SeekGt: { /* jump, in3 */ #endif if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt ); if( res<0 || (res==0 && oc==OP_SeekGt) ){ - res = 0; rc = sqlite3BtreeNext(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; pC->rowidIsValid = 0; @@ -70064,7 +70707,6 @@ case OP_SeekGt: { /* jump, in3 */ }else{ assert( oc==OP_SeekLt || oc==OP_SeekLe ); if( res>0 || (res==0 && oc==OP_SeekLt) ){ - res = 0; rc = sqlite3BtreePrevious(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; pC->rowidIsValid = 0; @@ -70917,7 +71559,7 @@ case OP_Rewind: { /* jump */ break; } -/* Opcode: Next P1 P2 P3 * P5 +/* Opcode: Next P1 P2 * * P5 ** ** Advance cursor P1 so that it points to the next key/data pair in its ** table or index. If there are no more key/value pairs then fall through @@ -70927,11 +71569,6 @@ case OP_Rewind: { /* jump */ ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have ** been opened prior to this opcode or the program will segfault. ** -** The P3 value is a hint to the btree implementation. If P3==1, that -** means P1 is an SQL index and that this instruction could have been -** omitted if that index had been unique. P3 is usually 0. P3 is -** always either 0 or 1. -** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreeNext(). ** @@ -70940,12 +71577,12 @@ case OP_Rewind: { /* jump */ ** ** See also: Prev, NextIfOpen */ -/* Opcode: NextIfOpen P1 P2 P3 * P5 +/* Opcode: NextIfOpen P1 P2 * * P5 ** ** This opcode works just like OP_Next except that if cursor P1 is not ** open it behaves a no-op. */ -/* Opcode: Prev P1 P2 P3 * P5 +/* Opcode: Prev P1 P2 * * P5 ** ** Back up cursor P1 so that it points to the previous key/data pair in its ** table or index. If there is no previous key/value pairs then fall through @@ -70955,18 +71592,13 @@ case OP_Rewind: { /* jump */ ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is ** not open then the behavior is undefined. ** -** The P3 value is a hint to the btree implementation. If P3==1, that -** means P1 is an SQL index and that this instruction could have been -** omitted if that index had been unique. P3 is usually 0. P3 is -** always either 0 or 1. -** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreePrevious(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ -/* Opcode: PrevIfOpen P1 P2 P3 * P5 +/* Opcode: PrevIfOpen P1 P2 * * P5 ** ** This opcode works just like OP_Prev except that if cursor P1 is not ** open it behaves a no-op. @@ -70988,12 +71620,9 @@ case OP_Next: /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pOp->p5aCounter) ); pC = p->apCsr[pOp->p1]; - res = pOp->p3; assert( pC!=0 ); assert( pC->deferredMoveto==0 ); assert( pC->pCursor ); - assert( res==0 || (res==1 && pC->isTable==0) ); - testcase( res==1 ); assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); @@ -96034,6 +96663,9 @@ static int sqlite3LoadExtension( for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){} iFile++; if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; +#ifdef __CYGWIN__ + if( sqlite3_strnicmp(zFile+iFile, "cyg", 3)==0 ) iFile += 3; +#endif for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ if( sqlite3Isalpha(c) ){ zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; @@ -96312,7 +96944,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExten */ #if !defined(SQLITE_ENABLE_LOCKING_STYLE) -# if defined(__APPLE__) +# if defined(__APPLE__) || defined(__CYGWIN__) # define SQLITE_ENABLE_LOCKING_STYLE 1 # else # define SQLITE_ENABLE_LOCKING_STYLE 0 @@ -96444,7 +97076,7 @@ static const struct sPragmaNames { /* ePragFlag: */ 0, /* iArg: */ SQLITE_CountRows }, #endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN +#if SQLITE_OS_WIN && !defined(__CYGWIN__) { /* zName: */ "data_store_directory", /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, /* ePragFlag: */ 0, @@ -97562,7 +98194,7 @@ SQLITE_PRIVATE void sqlite3Pragma( break; } -#if SQLITE_OS_WIN +#if SQLITE_OS_WIN && !defined(__CYGWIN__) /* ** PRAGMA data_store_directory ** PRAGMA data_store_directory = ""|"directory_name" @@ -108490,7 +109122,7 @@ struct WhereLevel { int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ u8 iFrom; /* Which entry in the FROM clause */ - u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ + u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to ends the loop */ union { /* Information that depends on pWLoop->wsFlags */ struct { @@ -108877,7 +109509,6 @@ struct WhereInfo { #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ -#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ /************** End of whereInt.h ********************************************/ /************** Continuing where we left off in where.c **********************/ @@ -112047,8 +112678,6 @@ static Bitmask codeOneLoopStart( pLevel->op = OP_Next; } pLevel->p1 = iIdxCur; - assert( (WHERE_UNQ_WANTED>>16)==1 ); - pLevel->p3 = (pLoop->wsFlags>>16)&1; if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; }else{ @@ -112851,13 +113480,12 @@ static int whereLoopAddBtreeIndex( || nInMul==0 ); pNew->wsFlags |= WHERE_COLUMN_EQ; - if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1)){ + if( iCol<0 + || (pProbe->onError!=OE_None && nInMul==0 + && pNew->u.btree.nEq==pProbe->nKeyCol-1) + ){ assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 ); - if( iCol>=0 && pProbe->onError==OE_None ){ - pNew->wsFlags |= WHERE_UNQ_WANTED; - }else{ - pNew->wsFlags |= WHERE_ONEROW; - } + pNew->wsFlags |= WHERE_ONEROW; } pNew->u.btree.nEq++; pNew->nOut = nRowEst + nInMul; @@ -114651,7 +115279,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(Wher pLoop = pLevel->pWLoop; sqlite3VdbeResolveLabel(v, pLevel->addrCont); if( pLevel->op!=OP_Noop ){ - sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); + sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2); sqlite3VdbeChangeP5(v, pLevel->p5); } if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ @@ -117970,12 +118598,20 @@ static void yy_reduce( break; case 325: /* wqlist ::= nm idxlist_opt AS LP select RP */ { +#ifdef SQLITE_OMIT_CTE + assert(0); +#else yygotominor.yy59 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy3); +#endif } break; case 326: /* wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP */ { +#ifdef SQLITE_OMIT_CTE + assert(0); +#else yygotominor.yy59 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy59, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy3); +#endif } break; default: @@ -119468,6 +120104,39 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite /************** End of sqliteicu.h *******************************************/ /************** Continuing where we left off in main.c ***********************/ #endif +#ifdef SQLITE_ENABLE_ZLIB +/************** Include sqlitezlib.h in the middle of main.c *****************/ +/************** Begin file sqlitezlib.h **************************************/ +/* +** 2008 May 26 +** +** 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 is used by programs that want to link against the +** zlib extension. All it does is declare the sqlite3ZlibInit() interface. +*/ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3ZlibInit(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + + +/************** End of sqlitezlib.h ******************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif #ifndef SQLITE_AMALGAMATION /* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant @@ -122060,6 +122729,12 @@ static int openDatabase( } #endif +#ifdef SQLITE_ENABLE_ZLIB + if( !db->mallocFailed && rc==SQLITE_OK ){ + rc = sqlite3ZlibInit(db); + } +#endif + #ifdef SQLITE_ENABLE_RTREE if( !db->mallocFailed && rc==SQLITE_OK){ rc = sqlite3RtreeInit(db); @@ -145515,6 +146190,137 @@ SQLITE_API int sqlite3_icu_init( #endif /************** End of icu.c *************************************************/ +/************** Begin file zlib.c ********************************************/ +/* +** 2014 January 6 +** +** 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. +** +************************************************************************* +** $Id: zlib.c,v 1.0 2013/01/06 11:13:11 jan.nijtmans Exp $ +** +** This file implements an integration between the zlib library , +** an open-source compression library and SQLite. The integration uses +** zlib to provide the following to SQLite: +** +** * An implementation of the SQL compress() and decompress() +** functions. +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ZLIB) + +/* Include zlib headers */ +#include + +#ifndef SQLITE_CORE + SQLITE_EXTENSION_INIT1 +#else +#endif + + /* + ** Implementation of the "compress(X)" SQL function. The input X is + ** compressed using zLib and the output is returned. + */ + static void zlibCompressFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv + ){ + const unsigned char *pIn; + unsigned char *pOut; + unsigned int nIn; + unsigned long int nOut; + + pIn = sqlite3_value_blob(argv[0]); + nIn = sqlite3_value_bytes(argv[0]); + nOut = 13 + nIn + (nIn+999)/1000; + pOut = sqlite3_malloc( nOut+4 ); + pOut[0] = nIn>>24 & 0xff; + pOut[1] = nIn>>16 & 0xff; + pOut[2] = nIn>>8 & 0xff; + pOut[3] = nIn & 0xff; + compress(&pOut[4], &nOut, pIn, nIn); + sqlite3_result_blob(context, pOut, nOut+4, sqlite3_free); + } + + /* + ** Implementation of the "decompress(X)" SQL function. The argument X + ** is a blob which was obtained from compress(Y). The output will be + ** the value Y. + */ + static void zlibDecompressFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv + ){ + const unsigned char *pIn; + unsigned char *pOut; + unsigned int nIn; + unsigned long int nOut; + int rc; + + pIn = sqlite3_value_blob(argv[0]); + nIn = sqlite3_value_bytes(argv[0]); + nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3]; + pOut = sqlite3_malloc( nOut+1 ); + rc = uncompress(pOut, &nOut, &pIn[4], nIn-4); + if( rc==Z_OK ){ + sqlite3_result_blob(context, pOut, nOut, sqlite3_free); + }else{ + sqlite3_result_error(context, "input is not zlib compressed", -1); + } + } + +/* +** Register the zlib extension functions with database db. +*/ +SQLITE_PRIVATE int sqlite3ZlibInit(sqlite3 *db){ + struct ZlibScalar { + const char *zName; /* Function name */ + int nArg; /* Number of arguments */ + int enc; /* Optimal text encoding */ + void *pContext; /* sqlite3_user_data() context */ + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } scalars[] = { + {"compress", 1, SQLITE_ANY, 0, zlibCompressFunc}, + {"decompress", 1, SQLITE_ANY, 0, zlibDecompressFunc}, + }; + + int rc = SQLITE_OK; + int i; + + for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ + struct ZlibScalar *p = &scalars[i]; + rc = sqlite3_create_function( + db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0 + ); + } + + return rc; +} + +#if !SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int sqlite3_zlib_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3ZlibInit(db); +} +#endif + +#endif + +/************** End of zlib.c ************************************************/ /************** Begin file fts3_icu.c ****************************************/ /* ** 2007 June 22 --- origsrc/sqlite-autoconf-3080300/sqlite3.h 2014-02-03 15:04:55.000000000 +0100 +++ src/sqlite-autoconf-3080300/sqlite3.h 2014-02-04 12:53:52.297923900 +0100 @@ -108,8 +108,8 @@ extern "C" { ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.3" -#define SQLITE_VERSION_NUMBER 3008003 -#define SQLITE_SOURCE_ID "2014-02-03 14:04:11 6c643e45c274e755dc5a1a65673df79261c774be" +#define SQLITE_VERSION_NUMBER 3008002 +#define SQLITE_SOURCE_ID "2014-02-03 13:52:03 e816dd924619db5f766de6df74ea2194f3e3b538" /* ** CAPI3REF: Run-Time Library Version Numbers --- origsrc/sqlite-autoconf-3080300/sqliteicu.h 1970-01-01 01:00:00.000000000 +0100 +++ src/sqlite-autoconf-3080300/sqliteicu.h 2014-02-04 12:53:52.307924500 +0100 @@ -0,0 +1,27 @@ +/* +** 2008 May 26 +** +** 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 is used by programs that want to link against the +** ICU extension. All it does is declare the sqlite3IcuInit() interface. +*/ +#include "sqlite3.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int sqlite3IcuInit(sqlite3 *db); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + --- origsrc/sqlite-autoconf-3080300/sqlitezlib.h 1970-01-01 01:00:00.000000000 +0100 +++ src/sqlite-autoconf-3080300/sqlitezlib.h 2014-02-04 12:53:52.313924800 +0100 @@ -0,0 +1,27 @@ +/* +** 2008 May 26 +** +** 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 is used by programs that want to link against the +** zlib extension. All it does is declare the sqlite3ZlibInit() interface. +*/ +#include "sqlite3.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int sqlite3ZlibInit(sqlite3 *db); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + --- origsrc/sqlite-autoconf-3080300/tea/generic/tclsqlite3.c 2014-02-03 15:04:57.000000000 +0100 +++ src/sqlite-autoconf-3080300/tea/generic/tclsqlite3.c 2014-02-04 12:53:52.321925300 +0100 @@ -174,6 +174,10 @@ static int strlen30(const char *z){ return 0x3fffffff & (int)(z2 - z); } +#ifdef USE_TCL_STUBS +# define tclStubsPtr staticTclStubsPtr +static const TclStubs *tclStubsPtr = NULL; +#endif #ifndef SQLITE_OMIT_INCRBLOB /* @@ -3028,6 +3032,11 @@ static int DbMain(void *cd, Tcl_Interp * memset(p, 0, sizeof(*p)); zFile = Tcl_GetStringFromObj(objv[2], 0); zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SQLITE_WIN32_NO_WIDE) + if( !zVfs ){ + zVfs = "win32-longpath"; + } +#endif rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); Tcl_DStringFree(&translatedFilename); if( p->db ){ @@ -3069,6 +3078,18 @@ static int DbMain(void *cd, Tcl_Interp * #ifndef USE_TCL_STUBS # undef Tcl_InitStubs # define Tcl_InitStubs(a,b,c) TCL_VERSION +#else +# define Tcl_InitStubs staticTclInitStubs +typedef struct { + char *result; + Tcl_FreeProc *freeProc; + int errorLine; + const struct TclStubs *stubTable; +} PrivateTclInterp; +static const char *Tcl_InitStubs(Tcl_Interp *interp, const char *version, int exact) { + tclStubsPtr = ((PrivateTclInterp *)interp)->stubTable; + return Tcl_PkgRequireEx(interp, "Tcl", version, 0, (void *)&tclStubsPtr); +} #endif /* --- origsrc/sqlite-autoconf-3080300/tea/tclconfig/tcl.m4 2014-02-03 15:04:55.000000000 +0100 +++ src/sqlite-autoconf-3080300/tea/tclconfig/tcl.m4 2014-02-04 12:53:52.332925900 +0100 @@ -1410,6 +1410,9 @@ dnl AC_CHECK_TOOL(AR, ar) SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".dll" EXE_SUFFIX=".exe" + EXEEXT=".exe" + do64bit_ok=yes + SHARED_LIB_SUFFIX='3.dll' CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; @@ -3184,13 +3187,19 @@ AC_DEFUN([TEA_MAKE_LIB], [ if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. - SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\"" fi + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" + if test "$GCC" = "yes"; then + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc" + fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" + if test "$GCC" = "yes"; then + PKG_LIB_FILE=lib${PKG_LIB_FILE} + fi fi # Some packages build their own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" @@ -3207,7 +3216,7 @@ AC_DEFUN([TEA_MAKE_LIB], [ if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}" fi - eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" + eval eval "PKG_LIB_FILE=tcl${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" --- origsrc/sqlite-autoconf-3080300/zlib.c 1970-01-01 01:00:00.000000000 +0100 +++ src/sqlite-autoconf-3080300/zlib.c 2014-02-04 12:53:52.341926400 +0100 @@ -0,0 +1,130 @@ +/* +** 2014 January 6 +** +** 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. +** +************************************************************************* +** $Id: zlib.c,v 1.0 2013/01/06 11:13:11 jan.nijtmans Exp $ +** +** This file implements an integration between the zlib library , +** an open-source compression library and SQLite. The integration uses +** zlib to provide the following to SQLite: +** +** * An implementation of the SQL compress() and decompress() +** functions. +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ZLIB) + +/* Include zlib headers */ +#include + +#ifndef SQLITE_CORE + #include "sqlite3ext.h" + SQLITE_EXTENSION_INIT1 +#else + #include "sqlite3.h" +#endif + + /* + ** Implementation of the "compress(X)" SQL function. The input X is + ** compressed using zLib and the output is returned. + */ + static void zlibCompressFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv + ){ + const unsigned char *pIn; + unsigned char *pOut; + unsigned int nIn; + unsigned long int nOut; + + pIn = sqlite3_value_blob(argv[0]); + nIn = sqlite3_value_bytes(argv[0]); + nOut = 13 + nIn + (nIn+999)/1000; + pOut = sqlite3_malloc( nOut+4 ); + pOut[0] = nIn>>24 & 0xff; + pOut[1] = nIn>>16 & 0xff; + pOut[2] = nIn>>8 & 0xff; + pOut[3] = nIn & 0xff; + compress(&pOut[4], &nOut, pIn, nIn); + sqlite3_result_blob(context, pOut, nOut+4, sqlite3_free); + } + + /* + ** Implementation of the "decompress(X)" SQL function. The argument X + ** is a blob which was obtained from compress(Y). The output will be + ** the value Y. + */ + static void zlibDecompressFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv + ){ + const unsigned char *pIn; + unsigned char *pOut; + unsigned int nIn; + unsigned long int nOut; + int rc; + + pIn = sqlite3_value_blob(argv[0]); + nIn = sqlite3_value_bytes(argv[0]); + nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3]; + pOut = sqlite3_malloc( nOut+1 ); + rc = uncompress(pOut, &nOut, &pIn[4], nIn-4); + if( rc==Z_OK ){ + sqlite3_result_blob(context, pOut, nOut, sqlite3_free); + }else{ + sqlite3_result_error(context, "input is not zlib compressed", -1); + } + } + +/* +** Register the zlib extension functions with database db. +*/ +int sqlite3ZlibInit(sqlite3 *db){ + struct ZlibScalar { + const char *zName; /* Function name */ + int nArg; /* Number of arguments */ + int enc; /* Optimal text encoding */ + void *pContext; /* sqlite3_user_data() context */ + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } scalars[] = { + {"compress", 1, SQLITE_ANY, 0, zlibCompressFunc}, + {"decompress", 1, SQLITE_ANY, 0, zlibDecompressFunc}, + }; + + int rc = SQLITE_OK; + int i; + + for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ + struct ZlibScalar *p = &scalars[i]; + rc = sqlite3_create_function( + db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0 + ); + } + + return rc; +} + +#if !SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_zlib_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3ZlibInit(db); +} +#endif + +#endif