⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 sqlite源码wince移植版
💻 C
📖 第 1 页 / 共 3 页
字号:
  if( pz==0 ) return;  nByte = 0;  va_start(ap, pz);  while( (z = va_arg(ap, const char*))!=0 ){    n = va_arg(ap, int);    if( n<=0 ) n = strlen(z);    nByte += n;  }  va_end(ap);  sqliteFree(*pz);  *pz = zResult = sqliteMallocRaw( nByte + 1 );  if( zResult==0 ) return;  va_start(ap, pz);  while( (z = va_arg(ap, const char*))!=0 ){    n = va_arg(ap, int);    if( n<=0 ) n = strlen(z);    strncpy(zResult, z, n);    zResult += n;  }  *zResult = 0;#ifdef MEMORY_DEBUG#if MEMORY_DEBUG>1  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);#endif#endif  va_end(ap);}/*** Add an error message to pParse->zErrMsg and increment pParse->nErr.** The following formatting characters are allowed:****      %s      Insert a string**      %z      A string that should be freed after use**      %d      Insert an integer**      %T      Insert a token**      %S      Insert the first element of a SrcList*/void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){  va_list ap;  pParse->nErr++;  sqliteFree(pParse->zErrMsg);  va_start(ap, zFormat);  pParse->zErrMsg = sqliteVMPrintf(zFormat, ap);  va_end(ap);}/*** Convert an SQL-style quoted string into a normal string by removing** the quote characters.  The conversion is done in-place.  If the** input does not begin with a quote character, then this routine** is a no-op.**** 2002-Feb-14: This routine is extended to remove MS-Access style** brackets from around identifers.  For example:  "[a-b-c]" becomes** "a-b-c".*/void sqliteDequote(char *z){  int quote;  int i, j;  if( z==0 ) return;  quote = z[0];  switch( quote ){    case '\'':  break;    case '"':   break;    case '[':   quote = ']';  break;    default:    return;  }  for(i=1, j=0; z[i]; i++){    if( z[i]==quote ){      if( z[i+1]==quote ){        z[j++] = quote;        i++;      }else{        z[j++] = 0;        break;      }    }else{      z[j++] = z[i];    }  }}/* An array to map all upper-case characters into their corresponding** lower-case character. */static unsigned char UpperToLower[] = {      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,    104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,    122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,    108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,    126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,    162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,    180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,    198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,    216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,    234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,    252,253,254,255};/*** This function computes a hash on the name of a keyword.** Case is not significant.*/int sqliteHashNoCase(const char *z, int n){  int h = 0;  if( n<=0 ) n = strlen(z);  while( n > 0  ){    h = (h<<3) ^ h ^ UpperToLower[(unsigned char)*z++];    n--;  }  return h & 0x7fffffff;}/*** Some systems have stricmp().  Others have strcasecmp().  Because** there is no consistency, we will define our own.*/int sqliteStrICmp(const char *zLeft, const char *zRight){  register unsigned char *a, *b;  a = (unsigned char *)zLeft;  b = (unsigned char *)zRight;  while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }  return UpperToLower[*a] - UpperToLower[*b];}int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){  register unsigned char *a, *b;  a = (unsigned char *)zLeft;  b = (unsigned char *)zRight;  while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];}/*** Return TRUE if z is a pure numeric string.  Return FALSE if the** string contains any character which is not part of a number.**** Am empty string is considered non-numeric.*/int sqliteIsNumber(const char *z){  if( *z=='-' || *z=='+' ) z++;  if( !isdigit(*z) ){    return 0;  }  z++;  while( isdigit(*z) ){ z++; }  if( *z=='.' ){    z++;    if( !isdigit(*z) ) return 0;    while( isdigit(*z) ){ z++; }  }  if( *z=='e' || *z=='E' ){    z++;    if( *z=='+' || *z=='-' ) z++;    if( !isdigit(*z) ) return 0;    while( isdigit(*z) ){ z++; }  }  return *z==0;}/*** The string z[] is an ascii representation of a real number.** Convert this string to a double.**** This routine assumes that z[] really is a valid number.  If it** is not, the result is undefined.**** This routine is used instead of the library atof() function because** the library atof() might want to use "," as the decimal point instead** of "." depending on how locale is set.  But that would cause problems** for SQL.  So this routine always uses "." regardless of locale.*/double sqliteAtoF(const char *z, const char **pzEnd){  int sign = 1;  LONGDOUBLE_TYPE v1 = 0.0;  if( *z=='-' ){    sign = -1;    z++;  }else if( *z=='+' ){    z++;  }  while( isdigit(*z) ){    v1 = v1*10.0 + (*z - '0');    z++;  }  if( *z=='.' ){    LONGDOUBLE_TYPE divisor = 1.0;    z++;    while( isdigit(*z) ){      v1 = v1*10.0 + (*z - '0');      divisor *= 10.0;      z++;    }    v1 /= divisor;  }  if( *z=='e' || *z=='E' ){    int esign = 1;    int eval = 0;    LONGDOUBLE_TYPE scale = 1.0;    z++;    if( *z=='-' ){      esign = -1;      z++;    }else if( *z=='+' ){      z++;    }    while( isdigit(*z) ){      eval = eval*10 + *z - '0';      z++;    }    while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }    while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }    while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }    if( esign<0 ){      v1 /= scale;    }else{      v1 *= scale;    }  }  if( pzEnd ) *pzEnd = z;  return sign<0 ? -v1 : v1;}/*** The string zNum represents an integer.  There might be some other** information following the integer too, but that part is ignored.** If the integer that the prefix of zNum represents will fit in a** 32-bit signed integer, return TRUE.  Otherwise return FALSE.**** This routine returns FALSE for the string -2147483648 even that** that number will, in theory fit in a 32-bit integer.  But positive** 2147483648 will not fit in 32 bits.  So it seems safer to return** false.*/int sqliteFitsIn32Bits(const char *zNum){  int i, c;  if( *zNum=='-' || *zNum=='+' ) zNum++;  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}  return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);}/* This comparison routine is what we use for comparison operations** between numeric values in an SQL expression.  "Numeric" is a little** bit misleading here.  What we mean is that the strings have a** type of "numeric" from the point of view of SQL.  The strings** do not necessarily contain numbers.  They could contain text.**** If the input strings both look like actual numbers then they** compare in numerical order.  Numerical strings are always less ** than non-numeric strings so if one input string looks like a** number and the other does not, then the one that looks like** a number is the smaller.  Non-numeric strings compare in ** lexigraphical order (the same order as strcmp()).*/int sqliteCompare(const char *atext, const char *btext){  int result;  int isNumA, isNumB;  if( atext==0 ){    return -1;  }else if( btext==0 ){    return 1;  }  isNumA = sqliteIsNumber(atext);  isNumB = sqliteIsNumber(btext);  if( isNumA ){    if( !isNumB ){      result = -1;    }else{      double rA, rB;      rA = sqliteAtoF(atext, 0);      rB = sqliteAtoF(btext, 0);      if( rA<rB ){        result = -1;      }else if( rA>rB ){        result = +1;      }else{        result = 0;      }    }  }else if( isNumB ){    result = +1;  }else {    result = strcmp(atext, btext);  }  return result; }/*** This routine is used for sorting.  Each key is a list of one or more** null-terminated elements.  The list is terminated by two nulls in** a row.  For example, the following text is a key with three elements****            Aone\000Dtwo\000Athree\000\000**** All elements begin with one of the characters "+-AD" and end with "\000"** with zero or more text elements in between.  Except, NULL elements** consist of the special two-character sequence "N\000".**** Both arguments will have the same number of elements.  This routine** returns negative, zero, or positive if the first argument is less** than, equal to, or greater than the first.  (Result is a-b).**** Each element begins with one of the characters "+", "-", "A", "D".** This character determines the sort order and collating sequence:****     +      Sort numerically in ascending order**     -      Sort numerically in descending order**     A      Sort as strings in ascending order**     D      Sort as strings in descending order.**** For the "+" and "-" sorting, pure numeric strings (strings for which the** isNum() function above returns TRUE) always compare less than strings** that are not pure numerics.  Non-numeric strings compare in memcmp()** order.  This is the same sort order as the sqliteCompare() function** above generates.**** The last point is a change from version 2.6.3 to version 2.7.0.  In** version 2.6.3 and earlier, substrings of digits compare in numerical ** and case was used only to break a tie.**** Elements that begin with 'A' or 'D' compare in memcmp() order regardless** of whether or not they look like a number.**** Note that the sort order imposed by the rules above is the same** from the ordering defined by the "<", "<=", ">", and ">=" operators** of expressions and for indices.  This was not the case for version** 2.6.3 and earlier.*/int sqliteSortCompare(const char *a, const char *b){  int res = 0;  int isNumA, isNumB;  int dir = 0;  while( res==0 && *a && *b ){    if( a[0]=='N' || b[0]=='N' ){      if( a[0]==b[0] ){        a += 2;        b += 2;        continue;      }      if( a[0]=='N' ){        dir = b[0];        res = -1;      }else{        dir = a[0];        res = +1;      }      break;    }    assert( a[0]==b[0] );    if( (dir=a[0])=='A' || a[0]=='D' ){      res = strcmp(&a[1],&b[1]);      if( res ) break;    }else{      isNumA = sqliteIsNumber(&a[1]);      isNumB = sqliteIsNumber(&b[1]);      if( isNumA ){        double rA, rB;        if( !isNumB ){          res = -1;          break;        }        rA = sqliteAtoF(&a[1], 0);        rB = sqliteAtoF(&b[1], 0);        if( rA<rB ){          res = -1;          break;        }        if( rA>rB ){          res = +1;          break;        }      }else if( isNumB ){        res = +1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -