| Index: third_party/sqlite/src/src/util.c
|
| diff --git a/third_party/sqlite/src/src/util.c b/third_party/sqlite/src/src/util.c
|
| index 7640f1d8d0a82b91322f5cce943b789c86352162..0a76ddec683de97bec6b9fa6c1fc03057549db87 100644
|
| --- a/third_party/sqlite/src/src/util.c
|
| +++ b/third_party/sqlite/src/src/util.c
|
| @@ -42,7 +42,7 @@ void sqlite3Coverage(int x){
|
| ** Return whatever integer value the test callback returns, or return
|
| ** SQLITE_OK if no test callback is installed.
|
| */
|
| -#ifndef SQLITE_OMIT_BUILTIN_TEST
|
| +#ifndef SQLITE_UNTESTABLE
|
| int sqlite3FaultSim(int iTest){
|
| int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback;
|
| return xCallback ? xCallback(iTest) : SQLITE_OK;
|
| @@ -110,12 +110,48 @@ int sqlite3Strlen30(const char *z){
|
| }
|
|
|
| /*
|
| +** Return the declared type of a column. Or return zDflt if the column
|
| +** has no declared type.
|
| +**
|
| +** The column type is an extra string stored after the zero-terminator on
|
| +** the column name if and only if the COLFLAG_HASTYPE flag is set.
|
| +*/
|
| +char *sqlite3ColumnType(Column *pCol, char *zDflt){
|
| + if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt;
|
| + return pCol->zName + strlen(pCol->zName) + 1;
|
| +}
|
| +
|
| +/*
|
| +** Helper function for sqlite3Error() - called rarely. Broken out into
|
| +** a separate routine to avoid unnecessary register saves on entry to
|
| +** sqlite3Error().
|
| +*/
|
| +static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){
|
| + if( db->pErr ) sqlite3ValueSetNull(db->pErr);
|
| + sqlite3SystemError(db, err_code);
|
| +}
|
| +
|
| +/*
|
| ** Set the current error code to err_code and clear any prior error message.
|
| +** Also set iSysErrno (by calling sqlite3System) if the err_code indicates
|
| +** that would be appropriate.
|
| */
|
| void sqlite3Error(sqlite3 *db, int err_code){
|
| assert( db!=0 );
|
| db->errCode = err_code;
|
| - if( db->pErr ) sqlite3ValueSetNull(db->pErr);
|
| + if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code);
|
| +}
|
| +
|
| +/*
|
| +** Load the sqlite3.iSysErrno field if that is an appropriate thing
|
| +** to do based on the SQLite error code in rc.
|
| +*/
|
| +void sqlite3SystemError(sqlite3 *db, int rc){
|
| + if( rc==SQLITE_IOERR_NOMEM ) return;
|
| + rc &= 0xff;
|
| + if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){
|
| + db->iSysErrno = sqlite3OsGetLastError(db->pVfs);
|
| + }
|
| }
|
|
|
| /*
|
| @@ -142,6 +178,7 @@ void sqlite3Error(sqlite3 *db, int err_code){
|
| void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
|
| assert( db!=0 );
|
| db->errCode = err_code;
|
| + sqlite3SystemError(db, err_code);
|
| if( zFormat==0 ){
|
| sqlite3Error(db, err_code);
|
| }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){
|
| @@ -205,18 +242,13 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
|
| ** brackets from around identifiers. For example: "[a-b-c]" becomes
|
| ** "a-b-c".
|
| */
|
| -int sqlite3Dequote(char *z){
|
| +void sqlite3Dequote(char *z){
|
| char quote;
|
| int i, j;
|
| - if( z==0 ) return -1;
|
| + if( z==0 ) return;
|
| quote = z[0];
|
| - switch( quote ){
|
| - case '\'': break;
|
| - case '"': break;
|
| - case '`': break; /* For MySQL compatibility */
|
| - case '[': quote = ']'; break; /* For MS SqlServer compatibility */
|
| - default: return -1;
|
| - }
|
| + if( !sqlite3Isquote(quote) ) return;
|
| + if( quote=='[' ) quote = ']';
|
| for(i=1, j=0;; i++){
|
| assert( z[i] );
|
| if( z[i]==quote ){
|
| @@ -231,7 +263,14 @@ int sqlite3Dequote(char *z){
|
| }
|
| }
|
| z[j] = 0;
|
| - return j;
|
| +}
|
| +
|
| +/*
|
| +** Generate a Token object from a string
|
| +*/
|
| +void sqlite3TokenInit(Token *p, char *z){
|
| + p->z = z;
|
| + p->n = sqlite3Strlen30(z);
|
| }
|
|
|
| /* Convenient short-hand */
|
| @@ -248,16 +287,25 @@ int sqlite3Dequote(char *z){
|
| ** independence" that SQLite uses internally when comparing identifiers.
|
| */
|
| int sqlite3_stricmp(const char *zLeft, const char *zRight){
|
| - register unsigned char *a, *b;
|
| if( zLeft==0 ){
|
| return zRight ? -1 : 0;
|
| }else if( zRight==0 ){
|
| return 1;
|
| }
|
| + return sqlite3StrICmp(zLeft, zRight);
|
| +}
|
| +int sqlite3StrICmp(const char *zLeft, const char *zRight){
|
| + unsigned char *a, *b;
|
| + int c;
|
| a = (unsigned char *)zLeft;
|
| b = (unsigned char *)zRight;
|
| - while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
| - return UpperToLower[*a] - UpperToLower[*b];
|
| + for(;;){
|
| + c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
|
| + if( c || *a==0 ) break;
|
| + a++;
|
| + b++;
|
| + }
|
| + return c;
|
| }
|
| int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
|
| register unsigned char *a, *b;
|
| @@ -307,7 +355,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
| int eValid = 1; /* True exponent is either not used or is well-formed */
|
| double result;
|
| int nDigits = 0;
|
| - int nonNum = 0;
|
| + int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
|
|
|
| assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
| *pResult = 0.0; /* Default return value, in case of an error */
|
| @@ -320,7 +368,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
| assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
| for(i=3-enc; i<length && z[i]==0; i+=2){}
|
| nonNum = i<length;
|
| - zEnd = z+i+enc-3;
|
| + zEnd = &z[i^1];
|
| z += (enc&1);
|
| }
|
|
|
| @@ -336,9 +384,6 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
| z+=incr;
|
| }
|
|
|
| - /* skip leading zeroes */
|
| - while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
|
| -
|
| /* copy max significant digits to significand */
|
| while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
|
| s = s*10 + (*z - '0');
|
| @@ -355,12 +400,13 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
| z+=incr;
|
| /* copy digits from after decimal to significand
|
| ** (decrease exponent by d to shift decimal right) */
|
| - while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
|
| - s = s*10 + (*z - '0');
|
| - z+=incr, nDigits++, d--;
|
| + while( z<zEnd && sqlite3Isdigit(*z) ){
|
| + if( s<((LARGEST_INT64-9)/10) ){
|
| + s = s*10 + (*z - '0');
|
| + d--;
|
| + }
|
| + z+=incr, nDigits++;
|
| }
|
| - /* skip non-significant digits */
|
| - while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
|
| }
|
| if( z>=zEnd ) goto do_atof_calc;
|
|
|
| @@ -368,7 +414,12 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
| if( *z=='e' || *z=='E' ){
|
| z+=incr;
|
| eValid = 0;
|
| - if( z>=zEnd ) goto do_atof_calc;
|
| +
|
| + /* This branch is needed to avoid a (harmless) buffer overread. The
|
| + ** special comment alerts the mutation tester that the correct answer
|
| + ** is obtained even if the branch is omitted */
|
| + if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/
|
| +
|
| /* get sign of exponent */
|
| if( *z=='-' ){
|
| esign = -1;
|
| @@ -385,9 +436,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
| }
|
|
|
| /* skip trailing spaces */
|
| - if( nDigits && eValid ){
|
| - while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
|
| - }
|
| + while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
|
|
|
| do_atof_calc:
|
| /* adjust exponent by d, and update sign */
|
| @@ -399,41 +448,51 @@ do_atof_calc:
|
| esign = 1;
|
| }
|
|
|
| - /* if 0 significand */
|
| - if( !s ) {
|
| - /* In the IEEE 754 standard, zero is signed.
|
| - ** Add the sign if we've seen at least one digit */
|
| - result = (sign<0 && nDigits) ? -(double)0 : (double)0;
|
| + if( s==0 ) {
|
| + /* In the IEEE 754 standard, zero is signed. */
|
| + result = sign<0 ? -(double)0 : (double)0;
|
| } else {
|
| - /* attempt to reduce exponent */
|
| - if( esign>0 ){
|
| - while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
|
| - }else{
|
| - while( !(s%10) && e>0 ) e--,s/=10;
|
| + /* Attempt to reduce exponent.
|
| + **
|
| + ** Branches that are not required for the correct answer but which only
|
| + ** help to obtain the correct answer faster are marked with special
|
| + ** comments, as a hint to the mutation tester.
|
| + */
|
| + while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/
|
| + if( esign>0 ){
|
| + if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/
|
| + s *= 10;
|
| + }else{
|
| + if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/
|
| + s /= 10;
|
| + }
|
| + e--;
|
| }
|
|
|
| /* adjust the sign of significand */
|
| s = sign<0 ? -s : s;
|
|
|
| - /* if exponent, scale significand as appropriate
|
| - ** and store in result. */
|
| - if( e ){
|
| + if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
|
| + result = (double)s;
|
| + }else{
|
| LONGDOUBLE_TYPE scale = 1.0;
|
| /* attempt to handle extremely small/large numbers better */
|
| - if( e>307 && e<342 ){
|
| - while( e%308 ) { scale *= 1.0e+1; e -= 1; }
|
| - if( esign<0 ){
|
| - result = s / scale;
|
| - result /= 1.0e+308;
|
| - }else{
|
| - result = s * scale;
|
| - result *= 1.0e+308;
|
| - }
|
| - }else if( e>=342 ){
|
| - if( esign<0 ){
|
| - result = 0.0*s;
|
| - }else{
|
| - result = 1e308*1e308*s; /* Infinity */
|
| + if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
|
| + if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
|
| + while( e%308 ) { scale *= 1.0e+1; e -= 1; }
|
| + if( esign<0 ){
|
| + result = s / scale;
|
| + result /= 1.0e+308;
|
| + }else{
|
| + result = s * scale;
|
| + result *= 1.0e+308;
|
| + }
|
| + }else{ assert( e>=342 );
|
| + if( esign<0 ){
|
| + result = 0.0*s;
|
| + }else{
|
| + result = 1e308*1e308*s; /* Infinity */
|
| + }
|
| }
|
| }else{
|
| /* 1.0e+22 is the largest power of 10 than can be
|
| @@ -446,8 +505,6 @@ do_atof_calc:
|
| result = s * scale;
|
| }
|
| }
|
| - } else {
|
| - result = (double)s;
|
| }
|
| }
|
|
|
| @@ -455,7 +512,7 @@ do_atof_calc:
|
| *pResult = result;
|
|
|
| /* return true if number and no extra non-whitespace chracters after */
|
| - return z>=zEnd && nDigits>0 && eValid && nonNum==0;
|
| + return z==zEnd && nDigits>0 && eValid && nonNum==0;
|
| #else
|
| return !sqlite3Atoi64(z, pResult, length, enc);
|
| #endif /* SQLITE_OMIT_FLOATING_POINT */
|
| @@ -517,7 +574,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
| int neg = 0; /* assume positive */
|
| int i;
|
| int c = 0;
|
| - int nonNum = 0;
|
| + int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
|
| const char *zStart;
|
| const char *zEnd = zNum + length;
|
| assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
| @@ -528,7 +585,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
| assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
| for(i=3-enc; i<length && zNum[i]==0; i+=2){}
|
| nonNum = i<length;
|
| - zEnd = zNum+i+enc-3;
|
| + zEnd = &zNum[i^1];
|
| zNum += (enc&1);
|
| }
|
| while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
|
| @@ -555,8 +612,11 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
| testcase( i==18 );
|
| testcase( i==19 );
|
| testcase( i==20 );
|
| - if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum)
|
| - || i>19*incr || nonNum ){
|
| + if( &zNum[i]<zEnd /* Extra bytes at the end */
|
| + || (i==0 && zStart==zNum) /* No digits */
|
| + || i>19*incr /* Too many digits */
|
| + || nonNum /* UTF16 with high-order bytes non-zero */
|
| + ){
|
| /* zNum is empty or contains non-numeric text or is longer
|
| ** than 19 digits (thus guaranteeing that it is too large) */
|
| return 1;
|
| @@ -598,7 +658,6 @@ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
|
| #ifndef SQLITE_OMIT_HEX_INTEGER
|
| if( z[0]=='0'
|
| && (z[1]=='x' || z[1]=='X')
|
| - && sqlite3Isxdigit(z[2])
|
| ){
|
| u64 u = 0;
|
| int i, k;
|
| @@ -1068,7 +1127,7 @@ u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
|
| */
|
| int sqlite3VarintLen(u64 v){
|
| int i;
|
| - for(i=1; (v >>= 7)!=0; i++){ assert( i<9 ); }
|
| + for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); }
|
| return i;
|
| }
|
|
|
| @@ -1081,13 +1140,11 @@ u32 sqlite3Get4byte(const u8 *p){
|
| u32 x;
|
| memcpy(&x,p,4);
|
| return x;
|
| -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
| - && defined(__GNUC__) && GCC_VERSION>=4003000
|
| +#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
| u32 x;
|
| memcpy(&x,p,4);
|
| return __builtin_bswap32(x);
|
| -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
| - && defined(_MSC_VER) && _MSC_VER>=1300
|
| +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
| u32 x;
|
| memcpy(&x,p,4);
|
| return _byteswap_ulong(x);
|
| @@ -1099,10 +1156,10 @@ u32 sqlite3Get4byte(const u8 *p){
|
| void sqlite3Put4byte(unsigned char *p, u32 v){
|
| #if SQLITE_BYTEORDER==4321
|
| memcpy(p,&v,4);
|
| -#elif SQLITE_BYTEORDER==1234 && defined(__GNUC__) && GCC_VERSION>=4003000
|
| +#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
| u32 x = __builtin_bswap32(v);
|
| memcpy(p,&x,4);
|
| -#elif SQLITE_BYTEORDER==1234 && defined(_MSC_VER) && _MSC_VER>=1300
|
| +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
| u32 x = _byteswap_ulong(v);
|
| memcpy(p,&x,4);
|
| #else
|
| @@ -1142,7 +1199,7 @@ void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
|
| char *zBlob;
|
| int i;
|
|
|
| - zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1);
|
| + zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1);
|
| n--;
|
| if( zBlob ){
|
| for(i=0; i<n; i+=2){
|
| @@ -1218,6 +1275,9 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
|
| ** overflow, leave *pA unchanged and return 1.
|
| */
|
| int sqlite3AddInt64(i64 *pA, i64 iB){
|
| +#if GCC_VERSION>=5004000 || CLANG_VERSION>=4000000
|
| + return __builtin_add_overflow(*pA, iB, pA);
|
| +#else
|
| i64 iA = *pA;
|
| testcase( iA==0 ); testcase( iA==1 );
|
| testcase( iB==-1 ); testcase( iB==0 );
|
| @@ -1232,8 +1292,12 @@ int sqlite3AddInt64(i64 *pA, i64 iB){
|
| }
|
| *pA += iB;
|
| return 0;
|
| +#endif
|
| }
|
| int sqlite3SubInt64(i64 *pA, i64 iB){
|
| +#if GCC_VERSION>=5004000 || CLANG_VERSION>=4000000
|
| + return __builtin_sub_overflow(*pA, iB, pA);
|
| +#else
|
| testcase( iB==SMALLEST_INT64+1 );
|
| if( iB==SMALLEST_INT64 ){
|
| testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
|
| @@ -1243,8 +1307,18 @@ int sqlite3SubInt64(i64 *pA, i64 iB){
|
| }else{
|
| return sqlite3AddInt64(pA, -iB);
|
| }
|
| +#endif
|
| }
|
| int sqlite3MulInt64(i64 *pA, i64 iB){
|
| +/* TODO(shess): Chromium Android clang generates a link error:
|
| +** undefined reference to '__mulodi4'
|
| +** UPDATE(shess): Also, apparently, 32-bit Linux clang.
|
| +*/
|
| +#if GCC_VERSION>=5004000 || \
|
| + (CLANG_VERSION>=4000000 && !defined(__ANDROID__) && \
|
| + (!defined(__linux__) || !defined(__i386__)))
|
| + return __builtin_mul_overflow(*pA, iB, pA);
|
| +#else
|
| i64 iA = *pA;
|
| if( iB>0 ){
|
| if( iA>LARGEST_INT64/iB ) return 1;
|
| @@ -1260,6 +1334,7 @@ int sqlite3MulInt64(i64 *pA, i64 iB){
|
| }
|
| *pA = iA*iB;
|
| return 0;
|
| +#endif
|
| }
|
|
|
| /*
|
| @@ -1343,7 +1418,7 @@ LogEst sqlite3LogEst(u64 x){
|
| if( x<2 ) return 0;
|
| while( x<8 ){ y -= 10; x <<= 1; }
|
| }else{
|
| - while( x>255 ){ y += 40; x >>= 4; }
|
| + while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/
|
| while( x>15 ){ y += 10; x >>= 1; }
|
| }
|
| return a[x&7] + y - 10;
|
| @@ -1366,18 +1441,132 @@ LogEst sqlite3LogEstFromDouble(double x){
|
| }
|
| #endif /* SQLITE_OMIT_VIRTUALTABLE */
|
|
|
| +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
|
| + defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
|
| + defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
|
| /*
|
| ** Convert a LogEst into an integer.
|
| +**
|
| +** Note that this routine is only used when one or more of various
|
| +** non-standard compile-time options is enabled.
|
| */
|
| u64 sqlite3LogEstToInt(LogEst x){
|
| u64 n;
|
| - if( x<10 ) return 1;
|
| n = x%10;
|
| x /= 10;
|
| if( n>=5 ) n -= 2;
|
| else if( n>=1 ) n -= 1;
|
| - if( x>=3 ){
|
| - return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3);
|
| +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
|
| + defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
|
| + if( x>60 ) return (u64)LARGEST_INT64;
|
| +#else
|
| + /* If only SQLITE_ENABLE_STAT3_OR_STAT4 is on, then the largest input
|
| + ** possible to this routine is 310, resulting in a maximum x of 31 */
|
| + assert( x<=60 );
|
| +#endif
|
| + return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
|
| +}
|
| +#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
|
| +
|
| +/*
|
| +** Add a new name/number pair to a VList. This might require that the
|
| +** VList object be reallocated, so return the new VList. If an OOM
|
| +** error occurs, the original VList returned and the
|
| +** db->mallocFailed flag is set.
|
| +**
|
| +** A VList is really just an array of integers. To destroy a VList,
|
| +** simply pass it to sqlite3DbFree().
|
| +**
|
| +** The first integer is the number of integers allocated for the whole
|
| +** VList. The second integer is the number of integers actually used.
|
| +** Each name/number pair is encoded by subsequent groups of 3 or more
|
| +** integers.
|
| +**
|
| +** Each name/number pair starts with two integers which are the numeric
|
| +** value for the pair and the size of the name/number pair, respectively.
|
| +** The text name overlays one or more following integers. The text name
|
| +** is always zero-terminated.
|
| +**
|
| +** Conceptually:
|
| +**
|
| +** struct VList {
|
| +** int nAlloc; // Number of allocated slots
|
| +** int nUsed; // Number of used slots
|
| +** struct VListEntry {
|
| +** int iValue; // Value for this entry
|
| +** int nSlot; // Slots used by this entry
|
| +** // ... variable name goes here
|
| +** } a[0];
|
| +** }
|
| +**
|
| +** During code generation, pointers to the variable names within the
|
| +** VList are taken. When that happens, nAlloc is set to zero as an
|
| +** indication that the VList may never again be enlarged, since the
|
| +** accompanying realloc() would invalidate the pointers.
|
| +*/
|
| +VList *sqlite3VListAdd(
|
| + sqlite3 *db, /* The database connection used for malloc() */
|
| + VList *pIn, /* The input VList. Might be NULL */
|
| + const char *zName, /* Name of symbol to add */
|
| + int nName, /* Bytes of text in zName */
|
| + int iVal /* Value to associate with zName */
|
| +){
|
| + int nInt; /* number of sizeof(int) objects needed for zName */
|
| + char *z; /* Pointer to where zName will be stored */
|
| + int i; /* Index in pIn[] where zName is stored */
|
| +
|
| + nInt = nName/4 + 3;
|
| + assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */
|
| + if( pIn==0 || pIn[1]+nInt > pIn[0] ){
|
| + /* Enlarge the allocation */
|
| + int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt;
|
| + VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
|
| + if( pOut==0 ) return pIn;
|
| + if( pIn==0 ) pOut[1] = 2;
|
| + pIn = pOut;
|
| + pIn[0] = nAlloc;
|
| }
|
| - return (n+8)>>(3-x);
|
| + i = pIn[1];
|
| + pIn[i] = iVal;
|
| + pIn[i+1] = nInt;
|
| + z = (char*)&pIn[i+2];
|
| + pIn[1] = i+nInt;
|
| + assert( pIn[1]<=pIn[0] );
|
| + memcpy(z, zName, nName);
|
| + z[nName] = 0;
|
| + return pIn;
|
| +}
|
| +
|
| +/*
|
| +** Return a pointer to the name of a variable in the given VList that
|
| +** has the value iVal. Or return a NULL if there is no such variable in
|
| +** the list
|
| +*/
|
| +const char *sqlite3VListNumToName(VList *pIn, int iVal){
|
| + int i, mx;
|
| + if( pIn==0 ) return 0;
|
| + mx = pIn[1];
|
| + i = 2;
|
| + do{
|
| + if( pIn[i]==iVal ) return (char*)&pIn[i+2];
|
| + i += pIn[i+1];
|
| + }while( i<mx );
|
| + return 0;
|
| +}
|
| +
|
| +/*
|
| +** Return the number of the variable named zName, if it is in VList.
|
| +** or return 0 if there is no such variable.
|
| +*/
|
| +int sqlite3VListNameToNum(VList *pIn, const char *zName, int nName){
|
| + int i, mx;
|
| + if( pIn==0 ) return 0;
|
| + mx = pIn[1];
|
| + i = 2;
|
| + do{
|
| + const char *z = (const char*)&pIn[i+2];
|
| + if( strncmp(z,zName,nName)==0 && z[nName]==0 ) return pIn[i];
|
| + i += pIn[i+1];
|
| + }while( i<mx );
|
| + return 0;
|
| }
|
|
|