| Index: third_party/sqlite/src/src/tclsqlite.c | 
| diff --git a/third_party/sqlite/src/src/tclsqlite.c b/third_party/sqlite/src/src/tclsqlite.c | 
| index 575651d7e561d11c8e54280377b72ff6bddd75ec..756d0daa5a914287f55b0faeb431caf6d0a40b03 100644 | 
| --- a/third_party/sqlite/src/src/tclsqlite.c | 
| +++ b/third_party/sqlite/src/src/tclsqlite.c | 
| @@ -41,6 +41,18 @@ | 
| #endif | 
| #include <ctype.h> | 
|  | 
| +/* Used to get the current process ID */ | 
| +#if !defined(_WIN32) | 
| +# include <unistd.h> | 
| +# define GETPID getpid | 
| +#elif !defined(_WIN32_WCE) | 
| +# ifndef SQLITE_AMALGAMATION | 
| +#  define WIN32_LEAN_AND_MEAN | 
| +#  include <windows.h> | 
| +# endif | 
| +# define GETPID (int)GetCurrentProcessId | 
| +#endif | 
| + | 
| /* | 
| * Windows needs to know which symbols to export.  Unix does not. | 
| * BUILD_sqlite should be undefined for Unix. | 
| @@ -53,15 +65,8 @@ | 
| #define NUM_PREPARED_STMTS 10 | 
| #define MAX_PREPARED_STMTS 100 | 
|  | 
| -/* | 
| -** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we | 
| -** have to do a translation when going between the two.  Set the | 
| -** UTF_TRANSLATION_NEEDED macro to indicate that we need to do | 
| -** this translation. | 
| -*/ | 
| -#if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8) | 
| -# define UTF_TRANSLATION_NEEDED 1 | 
| -#endif | 
| +/* Forward declaration */ | 
| +typedef struct SqliteDb SqliteDb; | 
|  | 
| /* | 
| ** New SQL functions can be created as TCL scripts.  Each such function | 
| @@ -71,6 +76,7 @@ typedef struct SqlFunc SqlFunc; | 
| struct SqlFunc { | 
| Tcl_Interp *interp;   /* The TCL interpret to execute the function */ | 
| Tcl_Obj *pScript;     /* The Tcl_Obj representation of the script */ | 
| +  SqliteDb *pDb;        /* Database connection that owns this function */ | 
| int useEvalObjv;      /* True if it is safe to use Tcl_EvalObjv */ | 
| char *zName;          /* Name of this function */ | 
| SqlFunc *pNext;       /* Next function on the list of them all */ | 
| @@ -107,8 +113,12 @@ typedef struct IncrblobChannel IncrblobChannel; | 
| /* | 
| ** There is one instance of this structure for each SQLite database | 
| ** that has been opened by the SQLite TCL interface. | 
| +** | 
| +** If this module is built with SQLITE_TEST defined (to create the SQLite | 
| +** testfixture executable), then it may be configured to use either | 
| +** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements. | 
| +** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used. | 
| */ | 
| -typedef struct SqliteDb SqliteDb; | 
| struct SqliteDb { | 
| sqlite3 *db;               /* The "real" database structure. MUST BE FIRST */ | 
| Tcl_Interp *interp;        /* The interpreter used for this database */ | 
| @@ -135,6 +145,9 @@ struct SqliteDb { | 
| IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ | 
| int nStep, nSort, nIndex;  /* Statistics for most recent operation */ | 
| int nTransaction;          /* Number of nested [transaction] methods */ | 
| +#ifdef SQLITE_TEST | 
| +  int bLegacyPrepare;        /* True to use sqlite3_prepare() */ | 
| +#endif | 
| }; | 
|  | 
| struct IncrblobChannel { | 
| @@ -411,18 +424,18 @@ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ | 
| */ | 
| static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ | 
| SqlFunc *p, *pNew; | 
| -  int i; | 
| -  pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen30(zName) + 1 ); | 
| +  int nName = strlen30(zName); | 
| +  pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); | 
| pNew->zName = (char*)&pNew[1]; | 
| -  for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); } | 
| -  pNew->zName[i] = 0; | 
| +  memcpy(pNew->zName, zName, nName+1); | 
| for(p=pDb->pFunc; p; p=p->pNext){ | 
| -    if( strcmp(p->zName, pNew->zName)==0 ){ | 
| +    if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){ | 
| Tcl_Free((char*)pNew); | 
| return p; | 
| } | 
| } | 
| pNew->interp = pDb->interp; | 
| +  pNew->pDb = pDb; | 
| pNew->pScript = 0; | 
| pNew->pNext = pDb->pFunc; | 
| pDb->pFunc = pNew; | 
| @@ -430,19 +443,32 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ | 
| } | 
|  | 
| /* | 
| +** Free a single SqlPreparedStmt object. | 
| +*/ | 
| +static void dbFreeStmt(SqlPreparedStmt *pStmt){ | 
| +#ifdef SQLITE_TEST | 
| +  if( sqlite3_sql(pStmt->pStmt)==0 ){ | 
| +    Tcl_Free((char *)pStmt->zSql); | 
| +  } | 
| +#endif | 
| +  sqlite3_finalize(pStmt->pStmt); | 
| +  Tcl_Free((char *)pStmt); | 
| +} | 
| + | 
| +/* | 
| ** Finalize and free a list of prepared statements | 
| */ | 
| -static void flushStmtCache( SqliteDb *pDb ){ | 
| +static void flushStmtCache(SqliteDb *pDb){ | 
| SqlPreparedStmt *pPreStmt; | 
| +  SqlPreparedStmt *pNext; | 
|  | 
| -  while(  pDb->stmtList ){ | 
| -    sqlite3_finalize( pDb->stmtList->pStmt ); | 
| -    pPreStmt = pDb->stmtList; | 
| -    pDb->stmtList = pDb->stmtList->pNext; | 
| -    Tcl_Free( (char*)pPreStmt ); | 
| +  for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){ | 
| +    pNext = pPreStmt->pNext; | 
| +    dbFreeStmt(pPreStmt); | 
| } | 
| pDb->nStmt = 0; | 
| pDb->stmtLast = 0; | 
| +  pDb->stmtList = 0; | 
| } | 
|  | 
| /* | 
| @@ -457,6 +483,7 @@ static void DbDeleteCmd(void *db){ | 
| while( pDb->pFunc ){ | 
| SqlFunc *pFunc = pDb->pFunc; | 
| pDb->pFunc = pFunc->pNext; | 
| +    assert( pFunc->pDb==pDb ); | 
| Tcl_DecrRefCount(pFunc->pScript); | 
| Tcl_Free((char*)pFunc); | 
| } | 
| @@ -733,7 +760,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ | 
| /* If there are arguments to the function, make a shallow copy of the | 
| ** script object, lappend the arguments, then evaluate the copy. | 
| ** | 
| -    ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated. | 
| +    ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. | 
| ** The new Tcl_Obj contains pointers to the original list elements. | 
| ** That way, when Tcl_EvalObjv() is run and shimmers the first element | 
| ** of the list to tclCmdNameType, that alternate representation will | 
| @@ -761,7 +788,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ | 
| case SQLITE_INTEGER: { | 
| sqlite_int64 v = sqlite3_value_int64(pIn); | 
| if( v>=-2147483647 && v<=2147483647 ){ | 
| -            pVal = Tcl_NewIntObj(v); | 
| +            pVal = Tcl_NewIntObj((int)v); | 
| }else{ | 
| pVal = Tcl_NewWideIntObj(v); | 
| } | 
| @@ -773,7 +800,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ | 
| break; | 
| } | 
| case SQLITE_NULL: { | 
| -          pVal = Tcl_NewStringObj("", 0); | 
| +          pVal = Tcl_NewStringObj(p->pDb->zNull, -1); | 
| break; | 
| } | 
| default: { | 
| @@ -845,8 +872,11 @@ static int auth_callback( | 
| const char *zArg2, | 
| const char *zArg3, | 
| const char *zArg4 | 
| +#ifdef SQLITE_USER_AUTHENTICATION | 
| +  ,const char *zArg5 | 
| +#endif | 
| ){ | 
| -  char *zCode; | 
| +  const char *zCode; | 
| Tcl_DString str; | 
| int rc; | 
| const char *zReply; | 
| @@ -887,6 +917,7 @@ static int auth_callback( | 
| case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break; | 
| case SQLITE_FUNCTION          : zCode="SQLITE_FUNCTION"; break; | 
| case SQLITE_SAVEPOINT         : zCode="SQLITE_SAVEPOINT"; break; | 
| +    case SQLITE_RECURSIVE         : zCode="SQLITE_RECURSIVE"; break; | 
| default                       : zCode="????"; break; | 
| } | 
| Tcl_DStringInit(&str); | 
| @@ -896,9 +927,12 @@ static int auth_callback( | 
| Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); | 
| Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); | 
| Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); | 
| +#ifdef SQLITE_USER_AUTHENTICATION | 
| +  Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); | 
| +#endif | 
| rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); | 
| Tcl_DStringFree(&str); | 
| -  zReply = Tcl_GetStringResult(pDb->interp); | 
| +  zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; | 
| if( strcmp(zReply,"SQLITE_OK")==0 ){ | 
| rc = SQLITE_OK; | 
| }else if( strcmp(zReply,"SQLITE_DENY")==0 ){ | 
| @@ -913,26 +947,6 @@ static int auth_callback( | 
| #endif /* SQLITE_OMIT_AUTHORIZATION */ | 
|  | 
| /* | 
| -** zText is a pointer to text obtained via an sqlite3_result_text() | 
| -** or similar interface. This routine returns a Tcl string object, | 
| -** reference count set to 0, containing the text. If a translation | 
| -** between iso8859 and UTF-8 is required, it is preformed. | 
| -*/ | 
| -static Tcl_Obj *dbTextToObj(char const *zText){ | 
| -  Tcl_Obj *pVal; | 
| -#ifdef UTF_TRANSLATION_NEEDED | 
| -  Tcl_DString dCol; | 
| -  Tcl_DStringInit(&dCol); | 
| -  Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol); | 
| -  pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1); | 
| -  Tcl_DStringFree(&dCol); | 
| -#else | 
| -  pVal = Tcl_NewStringObj(zText, -1); | 
| -#endif | 
| -  return pVal; | 
| -} | 
| - | 
| -/* | 
| ** This routine reads a line of text from FILE in, stores | 
| ** the text in memory obtained from malloc() and returns a pointer | 
| ** to the text.  NULL is returned at end of file, or if malloc() | 
| @@ -947,14 +961,12 @@ static char *local_getline(char *zPrompt, FILE *in){ | 
| char *zLine; | 
| int nLine; | 
| int n; | 
| -  int eol; | 
|  | 
| nLine = 100; | 
| zLine = malloc( nLine ); | 
| if( zLine==0 ) return 0; | 
| n = 0; | 
| -  eol = 0; | 
| -  while( !eol ){ | 
| +  while( 1 ){ | 
| if( n+100>nLine ){ | 
| nLine = nLine*2 + 100; | 
| zLine = realloc(zLine, nLine); | 
| @@ -966,14 +978,13 @@ static char *local_getline(char *zPrompt, FILE *in){ | 
| return 0; | 
| } | 
| zLine[n] = 0; | 
| -      eol = 1; | 
| break; | 
| } | 
| while( zLine[n] ){ n++; } | 
| if( n>0 && zLine[n-1]=='\n' ){ | 
| n--; | 
| zLine[n] = 0; | 
| -      eol = 1; | 
| +      break; | 
| } | 
| } | 
| zLine = realloc( zLine, n+1 ); | 
| @@ -994,7 +1005,7 @@ static int DbTransPostCmd( | 
| Tcl_Interp *interp,                  /* Tcl interpreter */ | 
| int result                           /* Result of evaluating SCRIPT */ | 
| ){ | 
| -  static const char *azEnd[] = { | 
| +  static const char *const azEnd[] = { | 
| "RELEASE _tcl_transaction",        /* rc==TCL_ERROR, nTransaction!=0 */ | 
| "COMMIT",                          /* rc!=TCL_ERROR, nTransaction==0 */ | 
| "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction", | 
| @@ -1012,7 +1023,7 @@ static int DbTransPostCmd( | 
| /* This is a tricky scenario to handle. The most likely cause of an | 
| ** error is that the exec() above was an attempt to commit the | 
| ** top-level transaction that returned SQLITE_BUSY. Or, less likely, | 
| -      ** that an IO-error has occured. In either case, throw a Tcl exception | 
| +      ** that an IO-error has occurred. In either case, throw a Tcl exception | 
| ** and try to rollback the transaction. | 
| ** | 
| ** But it could also be that the user executed one or more BEGIN, | 
| @@ -1020,7 +1031,7 @@ static int DbTransPostCmd( | 
| ** this method's logic. Not clear how this would be best handled. | 
| */ | 
| if( rc!=TCL_ERROR ){ | 
| -      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); | 
| +      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); | 
| rc = TCL_ERROR; | 
| } | 
| sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0); | 
| @@ -1031,6 +1042,27 @@ static int DbTransPostCmd( | 
| } | 
|  | 
| /* | 
| +** Unless SQLITE_TEST is defined, this function is a simple wrapper around | 
| +** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either | 
| +** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending | 
| +** on whether or not the [db_use_legacy_prepare] command has been used to | 
| +** configure the connection. | 
| +*/ | 
| +static int dbPrepare( | 
| +  SqliteDb *pDb,                  /* Database object */ | 
| +  const char *zSql,               /* SQL to compile */ | 
| +  sqlite3_stmt **ppStmt,          /* OUT: Prepared statement */ | 
| +  const char **pzOut              /* OUT: Pointer to next SQL statement */ | 
| +){ | 
| +#ifdef SQLITE_TEST | 
| +  if( pDb->bLegacyPrepare ){ | 
| +    return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut); | 
| +  } | 
| +#endif | 
| +  return sqlite3_prepare_v2(pDb->db, zSql, -1, ppStmt, pzOut); | 
| +} | 
| + | 
| +/* | 
| ** Search the cache for a prepared-statement object that implements the | 
| ** first SQL statement in the buffer pointed to by parameter zIn. If | 
| ** no such prepared-statement can be found, allocate and prepare a new | 
| @@ -1057,13 +1089,14 @@ static int dbPrepareAndBind( | 
| int nSql;                       /* Length of zSql in bytes */ | 
| int nVar;                       /* Number of variables in statement */ | 
| int iParm = 0;                  /* Next free entry in apParm */ | 
| +  char c; | 
| int i; | 
| Tcl_Interp *interp = pDb->interp; | 
|  | 
| *ppPreStmt = 0; | 
|  | 
| /* Trim spaces from the start of zSql and calculate the remaining length. */ | 
| -  while( isspace(zSql[0]) ){ zSql++; } | 
| +  while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; } | 
| nSql = strlen30(zSql); | 
|  | 
| for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ | 
| @@ -1100,14 +1133,14 @@ static int dbPrepareAndBind( | 
| if( pPreStmt==0 ){ | 
| int nByte; | 
|  | 
| -    if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, pzOut) ){ | 
| -      Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); | 
| +    if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){ | 
| +      Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); | 
| return TCL_ERROR; | 
| } | 
| if( pStmt==0 ){ | 
| if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ | 
| /* A compile-time error in the statement. */ | 
| -        Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); | 
| +        Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); | 
| return TCL_ERROR; | 
| }else{ | 
| /* The statement was a no-op.  Continue to the next statement | 
| @@ -1124,9 +1157,17 @@ static int dbPrepareAndBind( | 
| memset(pPreStmt, 0, nByte); | 
|  | 
| pPreStmt->pStmt = pStmt; | 
| -    pPreStmt->nSql = (*pzOut - zSql); | 
| +    pPreStmt->nSql = (int)(*pzOut - zSql); | 
| pPreStmt->zSql = sqlite3_sql(pStmt); | 
| pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1]; | 
| +#ifdef SQLITE_TEST | 
| +    if( pPreStmt->zSql==0 ){ | 
| +      char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1); | 
| +      memcpy(zCopy, zSql, pPreStmt->nSql); | 
| +      zCopy[pPreStmt->nSql] = '\0'; | 
| +      pPreStmt->zSql = zCopy; | 
| +    } | 
| +#endif | 
| } | 
| assert( pPreStmt ); | 
| assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql ); | 
| @@ -1180,7 +1221,6 @@ static int dbPrepareAndBind( | 
| return TCL_OK; | 
| } | 
|  | 
| - | 
| /* | 
| ** Release a statement reference obtained by calling dbPrepareAndBind(). | 
| ** There should be exactly one call to this function for each call to | 
| @@ -1205,8 +1245,7 @@ static void dbReleaseStmt( | 
|  | 
| if( pDb->maxStmt<=0 || discard ){ | 
| /* If the cache is turned off, deallocated the statement */ | 
| -    sqlite3_finalize(pPreStmt->pStmt); | 
| -    Tcl_Free((char *)pPreStmt); | 
| +    dbFreeStmt(pPreStmt); | 
| }else{ | 
| /* Add the prepared statement to the beginning of the cache list. */ | 
| pPreStmt->pNext = pDb->stmtList; | 
| @@ -1226,11 +1265,11 @@ static void dbReleaseStmt( | 
| /* If we have too many statement in cache, remove the surplus from | 
| ** the end of the cache list.  */ | 
| while( pDb->nStmt>pDb->maxStmt ){ | 
| -      sqlite3_finalize(pDb->stmtLast->pStmt); | 
| -      pDb->stmtLast = pDb->stmtLast->pPrev; | 
| -      Tcl_Free((char*)pDb->stmtLast->pNext); | 
| +      SqlPreparedStmt *pLast = pDb->stmtLast; | 
| +      pDb->stmtLast = pLast->pPrev; | 
| pDb->stmtLast->pNext = 0; | 
| pDb->nStmt--; | 
| +      dbFreeStmt(pLast); | 
| } | 
| } | 
| } | 
| @@ -1320,7 +1359,7 @@ static void dbEvalRowInfo( | 
| if( nCol>0 && (papColName || p->pArray) ){ | 
| apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol ); | 
| for(i=0; i<nCol; i++){ | 
| -        apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i)); | 
| +        apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1); | 
| Tcl_IncrRefCount(apColName[i]); | 
| } | 
| p->apColName = apColName; | 
| @@ -1363,9 +1402,12 @@ static void dbEvalRowInfo( | 
| ** no further rows available. This is similar to SQLITE_DONE. | 
| */ | 
| static int dbEvalStep(DbEvalContext *p){ | 
| +  const char *zPrevSql = 0;       /* Previous value of p->zSql */ | 
| + | 
| while( p->zSql[0] || p->pPreStmt ){ | 
| int rc; | 
| if( p->pPreStmt==0 ){ | 
| +      zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql); | 
| rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt); | 
| if( rc!=TCL_OK ) return rc; | 
| }else{ | 
| @@ -1392,8 +1434,20 @@ static int dbEvalStep(DbEvalContext *p){ | 
| if( rcs!=SQLITE_OK ){ | 
| /* If a run-time error occurs, report the error and stop reading | 
| ** the SQL.  */ | 
| -        Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db))); | 
| dbReleaseStmt(pDb, pPreStmt, 1); | 
| +#if SQLITE_TEST | 
| +        if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){ | 
| +          /* If the runtime error was an SQLITE_SCHEMA, and the database | 
| +          ** handle is configured to use the legacy sqlite3_prepare() | 
| +          ** interface, retry prepare()/step() on the same SQL statement. | 
| +          ** This only happens once. If there is a second SQLITE_SCHEMA | 
| +          ** error, the error will be returned to the caller. */ | 
| +          p->zSql = zPrevSql; | 
| +          continue; | 
| +        } | 
| +#endif | 
| +        Tcl_SetObjResult(pDb->interp, | 
| +                         Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); | 
| return TCL_ERROR; | 
| }else{ | 
| dbReleaseStmt(pDb, pPreStmt, 0); | 
| @@ -1441,7 +1495,7 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){ | 
| case SQLITE_INTEGER: { | 
| sqlite_int64 v = sqlite3_column_int64(pStmt, iCol); | 
| if( v>=-2147483647 && v<=2147483647 ){ | 
| -        return Tcl_NewIntObj(v); | 
| +        return Tcl_NewIntObj((int)v); | 
| }else{ | 
| return Tcl_NewWideIntObj(v); | 
| } | 
| @@ -1450,11 +1504,11 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){ | 
| return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol)); | 
| } | 
| case SQLITE_NULL: { | 
| -      return dbTextToObj(p->pDb->zNull); | 
| +      return Tcl_NewStringObj(p->pDb->zNull, -1); | 
| } | 
| } | 
|  | 
| -  return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol)); | 
| +  return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1); | 
| } | 
|  | 
| /* | 
| @@ -1483,9 +1537,9 @@ static int DbUseNre(void){ | 
| */ | 
| # define SQLITE_TCL_NRE 0 | 
| # define DbUseNre() 0 | 
| -# define Tcl_NRAddCallback(a,b,c,d,e,f) 0 | 
| +# define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0 | 
| # define Tcl_NREvalObj(a,b,c) 0 | 
| -# define Tcl_NRCreateCommand(a,b,c,d,e,f) 0 | 
| +# define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0 | 
| #endif | 
|  | 
| /* | 
| @@ -1627,7 +1681,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| */ | 
| case DB_AUTHORIZER: { | 
| #ifdef SQLITE_OMIT_AUTHORIZATION | 
| -    Tcl_AppendResult(interp, "authorization not available in this build", 0); | 
| +    Tcl_AppendResult(interp, "authorization not available in this build", | 
| +                     (char*)0); | 
| return TCL_ERROR; | 
| #else | 
| if( objc>3 ){ | 
| @@ -1635,7 +1690,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| return TCL_ERROR; | 
| }else if( objc==2 ){ | 
| if( pDb->zAuth ){ | 
| -        Tcl_AppendResult(interp, pDb->zAuth, 0); | 
| +        Tcl_AppendResult(interp, pDb->zAuth, (char*)0); | 
| } | 
| }else{ | 
| char *zAuth; | 
| @@ -1651,8 +1706,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| pDb->zAuth = 0; | 
| } | 
| if( pDb->zAuth ){ | 
| +        typedef int (*sqlite3_auth_cb)( | 
| +           void*,int,const char*,const char*, | 
| +           const char*,const char*); | 
| pDb->interp = interp; | 
| -        sqlite3_set_authorizer(pDb->db, auth_callback, pDb); | 
| +        sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb); | 
| }else{ | 
| sqlite3_set_authorizer(pDb->db, 0, 0); | 
| } | 
| @@ -1721,7 +1779,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| return TCL_ERROR; | 
| }else if( objc==2 ){ | 
| if( pDb->zBusy ){ | 
| -        Tcl_AppendResult(interp, pDb->zBusy, 0); | 
| +        Tcl_AppendResult(interp, pDb->zBusy, (char*)0); | 
| } | 
| }else{ | 
| char *zBusy; | 
| @@ -1775,7 +1833,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| }else{ | 
| if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ | 
| Tcl_AppendResult( interp, "cannot convert \"", | 
| -               Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0); | 
| +               Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0); | 
| return TCL_ERROR; | 
| }else{ | 
| if( n<0 ){ | 
| @@ -1789,7 +1847,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| } | 
| }else{ | 
| Tcl_AppendResult( interp, "bad option \"", | 
| -          Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 0); | 
| +          Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", | 
| +          (char*)0); | 
| return TCL_ERROR; | 
| } | 
| break; | 
| @@ -1886,10 +1945,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| return TCL_ERROR; | 
| }else if( objc==2 ){ | 
| if( pDb->zCommit ){ | 
| -        Tcl_AppendResult(interp, pDb->zCommit, 0); | 
| +        Tcl_AppendResult(interp, pDb->zCommit, (char*)0); | 
| } | 
| }else{ | 
| -      char *zCommit; | 
| +      const char *zCommit; | 
| int len; | 
| if( pDb->zCommit ){ | 
| Tcl_Free(pDb->zCommit); | 
| @@ -1962,14 +2021,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| char *zSql;                 /* An SQL statement */ | 
| char *zLine;                /* A single line of input from the file */ | 
| char **azCol;               /* zLine[] broken up into columns */ | 
| -    char *zCommit;              /* How to commit changes */ | 
| +    const char *zCommit;        /* How to commit changes */ | 
| FILE *in;                   /* The input file */ | 
| int lineno = 0;             /* Line number of input file */ | 
| char zLineNum[80];          /* Line number print buffer */ | 
| Tcl_Obj *pResult;           /* interp result */ | 
|  | 
| -    char *zSep; | 
| -    char *zNull; | 
| +    const char *zSep; | 
| +    const char *zNull; | 
| if( objc<5 || objc>7 ){ | 
| Tcl_WrongNumArgs(interp, 2, objv, | 
| "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); | 
| @@ -1991,7 +2050,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| nSep = strlen30(zSep); | 
| nNull = strlen30(zNull); | 
| if( nSep==0 ){ | 
| -      Tcl_AppendResult(interp,"Error: non-null separator required for copy",0); | 
| +      Tcl_AppendResult(interp,"Error: non-null separator required for copy", | 
| +                       (char*)0); | 
| return TCL_ERROR; | 
| } | 
| if(strcmp(zConflict, "rollback") != 0 && | 
| @@ -2001,19 +2061,19 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| strcmp(zConflict, "replace" ) != 0 ) { | 
| Tcl_AppendResult(interp, "Error: \"", zConflict, | 
| "\", conflict-algorithm must be one of: rollback, " | 
| -            "abort, fail, ignore, or replace", 0); | 
| +            "abort, fail, ignore, or replace", (char*)0); | 
| return TCL_ERROR; | 
| } | 
| zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); | 
| if( zSql==0 ){ | 
| -      Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0); | 
| +      Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0); | 
| return TCL_ERROR; | 
| } | 
| nByte = strlen30(zSql); | 
| rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); | 
| sqlite3_free(zSql); | 
| if( rc ){ | 
| -      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); | 
| +      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); | 
| nCol = 0; | 
| }else{ | 
| nCol = sqlite3_column_count(pStmt); | 
| @@ -2024,7 +2084,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| } | 
| zSql = malloc( nByte + 50 + nCol*2 ); | 
| if( zSql==0 ) { | 
| -      Tcl_AppendResult(interp, "Error: can't malloc()", 0); | 
| +      Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); | 
| return TCL_ERROR; | 
| } | 
| sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?", | 
| @@ -2039,7 +2099,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); | 
| free(zSql); | 
| if( rc ){ | 
| -      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); | 
| +      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); | 
| sqlite3_finalize(pStmt); | 
| return TCL_ERROR; | 
| } | 
| @@ -2051,7 +2111,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| } | 
| azCol = malloc( sizeof(azCol[0])*(nCol+1) ); | 
| if( azCol==0 ) { | 
| -      Tcl_AppendResult(interp, "Error: can't malloc()", 0); | 
| +      Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); | 
| fclose(in); | 
| return TCL_ERROR; | 
| } | 
| @@ -2059,7 +2119,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| zCommit = "COMMIT"; | 
| while( (zLine = local_getline(0, in))!=0 ){ | 
| char *z; | 
| -      i = 0; | 
| lineno++; | 
| azCol[0] = zLine; | 
| for(i=0, z=zLine; *z; z++){ | 
| @@ -2080,7 +2139,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| sqlite3_snprintf(nErr, zErr, | 
| "Error: %s line %d: expected %d columns of data but found %d", | 
| zFile, lineno, nCol, i+1); | 
| -          Tcl_AppendResult(interp, zErr, 0); | 
| +          Tcl_AppendResult(interp, zErr, (char*)0); | 
| free(zErr); | 
| } | 
| zCommit = "ROLLBACK"; | 
| @@ -2100,7 +2159,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| rc = sqlite3_reset(pStmt); | 
| free(zLine); | 
| if( rc!=SQLITE_OK ){ | 
| -        Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0); | 
| +        Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0); | 
| zCommit = "ROLLBACK"; | 
| break; | 
| } | 
| @@ -2118,7 +2177,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| }else{ | 
| /* failure, append lineno where failed */ | 
| sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno); | 
| -      Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0); | 
| +      Tcl_AppendResult(interp,", failed while processing line: ",zLineNum, | 
| +                       (char*)0); | 
| rc = TCL_ERROR; | 
| } | 
| break; | 
| @@ -2144,7 +2204,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| break; | 
| #else | 
| Tcl_AppendResult(interp, "extension loading is turned off at compile-time", | 
| -                     0); | 
| +                     (char*)0); | 
| return TCL_ERROR; | 
| #endif | 
| } | 
| @@ -2180,6 +2240,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| if( choice==DB_ONECOLUMN ){ | 
| if( rc==TCL_OK ){ | 
| Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0)); | 
| +      }else if( rc==TCL_BREAK ){ | 
| +        Tcl_ResetResult(interp); | 
| } | 
| }else if( rc==TCL_BREAK || rc==TCL_OK ){ | 
| Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK)); | 
| @@ -2300,14 +2362,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| */ | 
| case DB_INCRBLOB: { | 
| #ifdef SQLITE_OMIT_INCRBLOB | 
| -    Tcl_AppendResult(interp, "incrblob not available in this build", 0); | 
| +    Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0); | 
| return TCL_ERROR; | 
| #else | 
| int isReadonly = 0; | 
| const char *zDb = "main"; | 
| const char *zTable; | 
| const char *zColumn; | 
| -    sqlite_int64 iRow; | 
| +    Tcl_WideInt iRow; | 
|  | 
| /* Check for the -readonly option */ | 
| if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){ | 
| @@ -2328,7 +2390,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
|  | 
| if( rc==TCL_OK ){ | 
| rc = createIncrblobChannel( | 
| -          interp, pDb, zDb, zTable, zColumn, iRow, isReadonly | 
| +          interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly | 
| ); | 
| } | 
| #endif | 
| @@ -2367,13 +2429,13 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| } | 
| if( zNull && len>0 ){ | 
| pDb->zNull = Tcl_Alloc( len + 1 ); | 
| -        strncpy(pDb->zNull, zNull, len); | 
| +        memcpy(pDb->zNull, zNull, len); | 
| pDb->zNull[len] = '\0'; | 
| }else{ | 
| pDb->zNull = 0; | 
| } | 
| } | 
| -    Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull)); | 
| +    Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1)); | 
| break; | 
| } | 
|  | 
| @@ -2407,7 +2469,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| case DB_PROGRESS: { | 
| if( objc==2 ){ | 
| if( pDb->zProgress ){ | 
| -        Tcl_AppendResult(interp, pDb->zProgress, 0); | 
| +        Tcl_AppendResult(interp, pDb->zProgress, (char*)0); | 
| } | 
| }else if( objc==4 ){ | 
| char *zProgress; | 
| @@ -2453,7 +2515,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| return TCL_ERROR; | 
| }else if( objc==2 ){ | 
| if( pDb->zProfile ){ | 
| -        Tcl_AppendResult(interp, pDb->zProfile, 0); | 
| +        Tcl_AppendResult(interp, pDb->zProfile, (char*)0); | 
| } | 
| }else{ | 
| char *zProfile; | 
| @@ -2486,17 +2548,19 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| ** Change the encryption key on the currently open database. | 
| */ | 
| case DB_REKEY: { | 
| +#ifdef SQLITE_HAS_CODEC | 
| int nKey; | 
| void *pKey; | 
| +#endif | 
| if( objc!=3 ){ | 
| Tcl_WrongNumArgs(interp, 2, objv, "KEY"); | 
| return TCL_ERROR; | 
| } | 
| -    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); | 
| #ifdef SQLITE_HAS_CODEC | 
| +    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); | 
| rc = sqlite3_rekey(pDb->db, pKey, nKey); | 
| if( rc ){ | 
| -      Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); | 
| +      Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0); | 
| rc = TCL_ERROR; | 
| } | 
| #endif | 
| @@ -2637,7 +2701,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| return TCL_ERROR; | 
| }else if( objc==2 ){ | 
| if( pDb->zTrace ){ | 
| -        Tcl_AppendResult(interp, pDb->zTrace, 0); | 
| +        Tcl_AppendResult(interp, pDb->zTrace, (char*)0); | 
| } | 
| }else{ | 
| char *zTrace; | 
| @@ -2708,7 +2772,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0); | 
| pDb->disableAuth--; | 
| if( rc!=SQLITE_OK ){ | 
| -      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); | 
| +      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); | 
| return TCL_ERROR; | 
| } | 
| pDb->nTransaction++; | 
| @@ -2720,7 +2784,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| ** or savepoint.  */ | 
| if( DbUseNre() ){ | 
| Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); | 
| -      Tcl_NREvalObj(interp, pScript, 0); | 
| +      (void)Tcl_NREvalObj(interp, pScript, 0); | 
| }else{ | 
| rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0)); | 
| } | 
| @@ -2732,7 +2796,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| */ | 
| case DB_UNLOCK_NOTIFY: { | 
| #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY | 
| -    Tcl_AppendResult(interp, "unlock_notify not available in this build", 0); | 
| +    Tcl_AppendResult(interp, "unlock_notify not available in this build", | 
| +                     (char*)0); | 
| rc = TCL_ERROR; | 
| #else | 
| if( objc!=2 && objc!=3 ){ | 
| @@ -2755,7 +2820,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| } | 
|  | 
| if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ | 
| -        Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); | 
| +        Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); | 
| rc = TCL_ERROR; | 
| } | 
| } | 
| @@ -2856,8 +2921,6 @@ static int DbObjCmdAdaptor( | 
| */ | 
| static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| SqliteDb *p; | 
| -  void *pKey = 0; | 
| -  int nKey = 0; | 
| const char *zArg; | 
| char *zErrMsg; | 
| int i; | 
| @@ -2865,6 +2928,11 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| const char *zVfs = 0; | 
| int flags; | 
| Tcl_DString translatedFilename; | 
| +#ifdef SQLITE_HAS_CODEC | 
| +  void *pKey = 0; | 
| +  int nKey = 0; | 
| +#endif | 
| +  int rc; | 
|  | 
| /* In normal use, each TCL interpreter runs in a single thread.  So | 
| ** by default, we can turn of mutexing on SQLite database connections. | 
| @@ -2881,14 +2949,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| if( objc==2 ){ | 
| zArg = Tcl_GetStringFromObj(objv[1], 0); | 
| if( strcmp(zArg,"-version")==0 ){ | 
| -      Tcl_AppendResult(interp,sqlite3_version,0); | 
| +      Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0); | 
| return TCL_OK; | 
| } | 
| if( strcmp(zArg,"-has-codec")==0 ){ | 
| #ifdef SQLITE_HAS_CODEC | 
| -      Tcl_AppendResult(interp,"1",0); | 
| +      Tcl_AppendResult(interp,"1",(char*)0); | 
| #else | 
| -      Tcl_AppendResult(interp,"0",0); | 
| +      Tcl_AppendResult(interp,"0",(char*)0); | 
| #endif | 
| return TCL_OK; | 
| } | 
| @@ -2896,7 +2964,9 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| for(i=3; i+1<objc; i+=2){ | 
| zArg = Tcl_GetString(objv[i]); | 
| if( strcmp(zArg,"-key")==0 ){ | 
| +#ifdef SQLITE_HAS_CODEC | 
| pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey); | 
| +#endif | 
| }else if( strcmp(zArg, "-vfs")==0 ){ | 
| zVfs = Tcl_GetString(objv[i+1]); | 
| }else if( strcmp(zArg, "-readonly")==0 ){ | 
| @@ -2926,7 +2996,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| }else{ | 
| flags &= ~SQLITE_OPEN_NOMUTEX; | 
| } | 
| -   }else if( strcmp(zArg, "-fullmutex")==0 ){ | 
| +    }else if( strcmp(zArg, "-fullmutex")==0 ){ | 
| int b; | 
| if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; | 
| if( b ){ | 
| @@ -2935,6 +3005,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| }else{ | 
| flags &= ~SQLITE_OPEN_FULLMUTEX; | 
| } | 
| +    }else if( strcmp(zArg, "-uri")==0 ){ | 
| +      int b; | 
| +      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; | 
| +      if( b ){ | 
| +        flags |= SQLITE_OPEN_URI; | 
| +      }else{ | 
| +        flags &= ~SQLITE_OPEN_URI; | 
| +      } | 
| }else{ | 
| Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); | 
| return TCL_ERROR; | 
| @@ -2943,7 +3021,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| if( objc<3 || (objc&1)!=1 ){ | 
| Tcl_WrongNumArgs(interp, 1, objv, | 
| "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" | 
| -      " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?" | 
| +      " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" | 
| #ifdef SQLITE_HAS_CODEC | 
| " ?-key CODECKEY?" | 
| #endif | 
| @@ -2953,18 +3031,22 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| zErrMsg = 0; | 
| p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); | 
| if( p==0 ){ | 
| -    Tcl_SetResult(interp, "malloc failed", TCL_STATIC); | 
| +    Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC); | 
| return TCL_ERROR; | 
| } | 
| memset(p, 0, sizeof(*p)); | 
| zFile = Tcl_GetStringFromObj(objv[2], 0); | 
| zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); | 
| -  sqlite3_open_v2(zFile, &p->db, flags, zVfs); | 
| +  rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); | 
| Tcl_DStringFree(&translatedFilename); | 
| -  if( SQLITE_OK!=sqlite3_errcode(p->db) ){ | 
| -    zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); | 
| -    sqlite3_close(p->db); | 
| -    p->db = 0; | 
| +  if( p->db ){ | 
| +    if( SQLITE_OK!=sqlite3_errcode(p->db) ){ | 
| +      zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); | 
| +      sqlite3_close(p->db); | 
| +      p->db = 0; | 
| +    } | 
| +  }else{ | 
| +    zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc)); | 
| } | 
| #ifdef SQLITE_HAS_CODEC | 
| if( p->db ){ | 
| @@ -2995,7 +3077,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| */ | 
| #ifndef USE_TCL_STUBS | 
| # undef  Tcl_InitStubs | 
| -# define Tcl_InitStubs(a,b,c) | 
| +# define Tcl_InitStubs(a,b,c) TCL_VERSION | 
| #endif | 
|  | 
| /* | 
| @@ -3019,38 +3101,33 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 
| ** The EXTERN macros are required by TCL in order to work on windows. | 
| */ | 
| EXTERN int Sqlite3_Init(Tcl_Interp *interp){ | 
| -  Tcl_InitStubs(interp, "8.4", 0); | 
| -  Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); | 
| -  Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); | 
| - | 
| +  int rc = Tcl_InitStubs(interp, "8.4", 0)==0 ? TCL_ERROR : TCL_OK; | 
| +  if( rc==TCL_OK ){ | 
| +    Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); | 
| #ifndef SQLITE_3_SUFFIX_ONLY | 
| -  /* The "sqlite" alias is undocumented.  It is here only to support | 
| -  ** legacy scripts.  All new scripts should use only the "sqlite3" | 
| -  ** command. | 
| -  */ | 
| -  Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); | 
| +    /* The "sqlite" alias is undocumented.  It is here only to support | 
| +    ** legacy scripts.  All new scripts should use only the "sqlite3" | 
| +    ** command. */ | 
| +    Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); | 
| #endif | 
| - | 
| -  return TCL_OK; | 
| +    rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); | 
| +  } | 
| +  return rc; | 
| } | 
| EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } | 
| -EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } | 
| -EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } | 
| EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 
| EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 
| -EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 
| -EXTERN int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;} | 
|  | 
| +/* Because it accesses the file-system and uses persistent state, SQLite | 
| +** is not considered appropriate for safe interpreters.  Hence, we deliberately | 
| +** omit the _SafeInit() interfaces. | 
| +*/ | 
|  | 
| #ifndef SQLITE_3_SUFFIX_ONLY | 
| int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } | 
| int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } | 
| -int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } | 
| -int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } | 
| int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 
| int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 
| -int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 
| -int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;} | 
| #endif | 
|  | 
| #ifdef TCLSH | 
| @@ -3309,13 +3386,11 @@ static void MD5Final(unsigned char digest[16], MD5Context *ctx){ | 
| byteReverse(ctx->in, 14); | 
|  | 
| /* Append length in bits and transform */ | 
| -        ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0]; | 
| -        ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1]; | 
| +        memcpy(ctx->in + 14*4, ctx->bits, 8); | 
|  | 
| MD5Transform(ctx->buf, (uint32 *)ctx->in); | 
| byteReverse((unsigned char *)ctx->buf, 4); | 
| memcpy(digest, ctx->buf, 16); | 
| -        memset(ctx, 0, sizeof(ctx));    /* In case it is sensitive */ | 
| } | 
|  | 
| /* | 
| @@ -3363,7 +3438,7 @@ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ | 
|  | 
| if( argc!=2 ){ | 
| Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], | 
| -        " TEXT\"", 0); | 
| +        " TEXT\"", (char*)0); | 
| return TCL_ERROR; | 
| } | 
| MD5Init(&ctx); | 
| @@ -3388,19 +3463,19 @@ static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){ | 
|  | 
| if( argc!=2 ){ | 
| Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], | 
| -        " FILENAME\"", 0); | 
| +        " FILENAME\"", (char*)0); | 
| return TCL_ERROR; | 
| } | 
| in = fopen(argv[1],"rb"); | 
| if( in==0 ){ | 
| Tcl_AppendResult(interp,"unable to open file \"", argv[1], | 
| -         "\" for reading", 0); | 
| +         "\" for reading", (char*)0); | 
| return TCL_ERROR; | 
| } | 
| MD5Init(&ctx); | 
| for(;;){ | 
| int n; | 
| -    n = fread(zBuf, 1, sizeof(zBuf), in); | 
| +    n = (int)fread(zBuf, 1, sizeof(zBuf), in); | 
| if( n<=0 ) break; | 
| MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n); | 
| } | 
| @@ -3446,7 +3521,7 @@ static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){ | 
| for(i=0; i<argc; i++){ | 
| const char *zData = (char*)sqlite3_value_text(argv[i]); | 
| if( zData ){ | 
| -      MD5Update(p, (unsigned char*)zData, strlen(zData)); | 
| +      MD5Update(p, (unsigned char*)zData, (int)strlen(zData)); | 
| } | 
| } | 
| } | 
| @@ -3475,33 +3550,34 @@ int Md5_Register(sqlite3 *db){ | 
| ** the TCL interpreter reads and evaluates that file. | 
| */ | 
| #if TCLSH==1 | 
| -static char zMainloop[] = | 
| -  "set line {}\n" | 
| -  "while {![eof stdin]} {\n" | 
| -    "if {$line!=\"\"} {\n" | 
| -      "puts -nonewline \"> \"\n" | 
| -    "} else {\n" | 
| -      "puts -nonewline \"% \"\n" | 
| -    "}\n" | 
| -    "flush stdout\n" | 
| -    "append line [gets stdin]\n" | 
| -    "if {[info complete $line]} {\n" | 
| -      "if {[catch {uplevel #0 $line} result]} {\n" | 
| -        "puts stderr \"Error: $result\"\n" | 
| -      "} elseif {$result!=\"\"} {\n" | 
| -        "puts $result\n" | 
| +static const char *tclsh_main_loop(void){ | 
| +  static const char zMainloop[] = | 
| +    "set line {}\n" | 
| +    "while {![eof stdin]} {\n" | 
| +      "if {$line!=\"\"} {\n" | 
| +        "puts -nonewline \"> \"\n" | 
| +      "} else {\n" | 
| +        "puts -nonewline \"% \"\n" | 
| +      "}\n" | 
| +      "flush stdout\n" | 
| +      "append line [gets stdin]\n" | 
| +      "if {[info complete $line]} {\n" | 
| +        "if {[catch {uplevel #0 $line} result]} {\n" | 
| +          "puts stderr \"Error: $result\"\n" | 
| +        "} elseif {$result!=\"\"} {\n" | 
| +          "puts $result\n" | 
| +        "}\n" | 
| +        "set line {}\n" | 
| +      "} else {\n" | 
| +        "append line \\n\n" | 
| "}\n" | 
| -      "set line {}\n" | 
| -    "} else {\n" | 
| -      "append line \\n\n" | 
| "}\n" | 
| -  "}\n" | 
| -; | 
| +  ; | 
| +  return zMainloop; | 
| +} | 
| #endif | 
| #if TCLSH==2 | 
| -static char zMainloop[] = | 
| -#include "spaceanal_tcl.h" | 
| -; | 
| +static const char *tclsh_main_loop(void); | 
| #endif | 
|  | 
| #ifdef SQLITE_TEST | 
| @@ -3527,6 +3603,44 @@ static int init_all_cmd( | 
| init_all(slave); | 
| return TCL_OK; | 
| } | 
| + | 
| +/* | 
| +** Tclcmd: db_use_legacy_prepare DB BOOLEAN | 
| +** | 
| +**   The first argument to this command must be a database command created by | 
| +**   [sqlite3]. If the second argument is true, then the handle is configured | 
| +**   to use the sqlite3_prepare_v2() function to prepare statements. If it | 
| +**   is false, sqlite3_prepare(). | 
| +*/ | 
| +static int db_use_legacy_prepare_cmd( | 
| +  ClientData cd, | 
| +  Tcl_Interp *interp, | 
| +  int objc, | 
| +  Tcl_Obj *CONST objv[] | 
| +){ | 
| +  Tcl_CmdInfo cmdInfo; | 
| +  SqliteDb *pDb; | 
| +  int bPrepare; | 
| + | 
| +  if( objc!=3 ){ | 
| +    Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN"); | 
| +    return TCL_ERROR; | 
| +  } | 
| + | 
| +  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){ | 
| +    Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0); | 
| +    return TCL_ERROR; | 
| +  } | 
| +  pDb = (SqliteDb*)cmdInfo.objClientData; | 
| +  if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){ | 
| +    return TCL_ERROR; | 
| +  } | 
| + | 
| +  pDb->bLegacyPrepare = bPrepare; | 
| + | 
| +  Tcl_ResetResult(interp); | 
| +  return TCL_OK; | 
| +} | 
| #endif | 
|  | 
| /* | 
| @@ -3547,6 +3661,17 @@ static void init_all(Tcl_Interp *interp){ | 
| Md5_Init(interp); | 
| #endif | 
|  | 
| +  /* Install the [register_dbstat_vtab] command to access the implementation | 
| +  ** of virtual table dbstat (source file test_stat.c). This command is | 
| +  ** required for testfixture and sqlite3_analyzer, but not by the production | 
| +  ** Tcl extension.  */ | 
| +#if defined(SQLITE_TEST) || TCLSH==2 | 
| +  { | 
| +    extern int SqlitetestStat_Init(Tcl_Interp*); | 
| +    SqlitetestStat_Init(interp); | 
| +  } | 
| +#endif | 
| + | 
| #ifdef SQLITE_TEST | 
| { | 
| extern int Sqliteconfig_Init(Tcl_Interp*); | 
| @@ -3570,20 +3695,22 @@ static void init_all(Tcl_Interp *interp){ | 
| extern int Sqlitetestschema_Init(Tcl_Interp*); | 
| extern int Sqlitetestsse_Init(Tcl_Interp*); | 
| extern int Sqlitetesttclvar_Init(Tcl_Interp*); | 
| +    extern int Sqlitetestfs_Init(Tcl_Interp*); | 
| extern int SqlitetestThread_Init(Tcl_Interp*); | 
| extern int SqlitetestOnefile_Init(); | 
| extern int SqlitetestOsinst_Init(Tcl_Interp*); | 
| extern int Sqlitetestbackup_Init(Tcl_Interp*); | 
| extern int Sqlitetestintarray_Init(Tcl_Interp*); | 
| extern int Sqlitetestvfs_Init(Tcl_Interp *); | 
| -    extern int SqlitetestStat_Init(Tcl_Interp*); | 
| extern int Sqlitetestrtree_Init(Tcl_Interp*); | 
| extern int Sqlitequota_Init(Tcl_Interp*); | 
| extern int Sqlitemultiplex_Init(Tcl_Interp*); | 
| extern int SqliteSuperlock_Init(Tcl_Interp*); | 
| extern int SqlitetestSyscall_Init(Tcl_Interp*); | 
| -    extern int Sqlitetestfuzzer_Init(Tcl_Interp*); | 
| -    extern int Sqlitetestwholenumber_Init(Tcl_Interp*); | 
| + | 
| +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) | 
| +    extern int Sqlitetestfts3_Init(Tcl_Interp *interp); | 
| +#endif | 
|  | 
| #ifdef SQLITE_ENABLE_ZIPVFS | 
| extern int Zipvfs_Init(Tcl_Interp*); | 
| @@ -3610,22 +3737,29 @@ static void init_all(Tcl_Interp *interp){ | 
| Sqlitetest_mutex_Init(interp); | 
| Sqlitetestschema_Init(interp); | 
| Sqlitetesttclvar_Init(interp); | 
| +    Sqlitetestfs_Init(interp); | 
| SqlitetestThread_Init(interp); | 
| SqlitetestOnefile_Init(interp); | 
| SqlitetestOsinst_Init(interp); | 
| Sqlitetestbackup_Init(interp); | 
| Sqlitetestintarray_Init(interp); | 
| Sqlitetestvfs_Init(interp); | 
| -    SqlitetestStat_Init(interp); | 
| Sqlitetestrtree_Init(interp); | 
| Sqlitequota_Init(interp); | 
| Sqlitemultiplex_Init(interp); | 
| SqliteSuperlock_Init(interp); | 
| SqlitetestSyscall_Init(interp); | 
| -    Sqlitetestfuzzer_Init(interp); | 
| -    Sqlitetestwholenumber_Init(interp); | 
|  | 
| -    Tcl_CreateObjCommand(interp,"load_testfixture_extensions",init_all_cmd,0,0); | 
| +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) | 
| +    Sqlitetestfts3_Init(interp); | 
| +#endif | 
| + | 
| +    Tcl_CreateObjCommand( | 
| +        interp, "load_testfixture_extensions", init_all_cmd, 0, 0 | 
| +    ); | 
| +    Tcl_CreateObjCommand( | 
| +        interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0 | 
| +    ); | 
|  | 
| #ifdef SQLITE_SSE | 
| Sqlitetestsse_Init(interp); | 
| @@ -3637,18 +3771,29 @@ static void init_all(Tcl_Interp *interp){ | 
| #define TCLSH_MAIN main   /* Needed to fake out mktclapp */ | 
| int TCLSH_MAIN(int argc, char **argv){ | 
| Tcl_Interp *interp; | 
| - | 
| + | 
| +#if !defined(_WIN32_WCE) | 
| +  if( getenv("BREAK") ){ | 
| +    fprintf(stderr, | 
| +        "attach debugger to process %d and press any key to continue.\n", | 
| +        GETPID()); | 
| +    fgetc(stdin); | 
| +  } | 
| +#endif | 
| + | 
| /* Call sqlite3_shutdown() once before doing anything else. This is to | 
| ** test that sqlite3_shutdown() can be safely called by a process before | 
| ** sqlite3_initialize() is. */ | 
| sqlite3_shutdown(); | 
|  | 
| +  Tcl_FindExecutable(argv[0]); | 
| +  Tcl_SetSystemEncoding(NULL, "utf-8"); | 
| +  interp = Tcl_CreateInterp(); | 
| + | 
| #if TCLSH==2 | 
| sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); | 
| #endif | 
| -  Tcl_FindExecutable(argv[0]); | 
|  | 
| -  interp = Tcl_CreateInterp(); | 
| init_all(interp); | 
| if( argc>=2 ){ | 
| int i; | 
| @@ -3669,7 +3814,7 @@ int TCLSH_MAIN(int argc, char **argv){ | 
| } | 
| } | 
| if( TCLSH==2 || argc<=1 ){ | 
| -    Tcl_GlobalEval(interp, zMainloop); | 
| +    Tcl_GlobalEval(interp, tclsh_main_loop()); | 
| } | 
| return 0; | 
| } | 
|  |