-C Better\sdetection\sand\shandling\sof\scorrupt\sdatabase\sfiles.\s(CVS\s1922)
-D 2004-08-30T16:52:18
+C Combine\sthe\simplementation\sof\sLIKE\sand\sGLOB\sinto\sa\ssingle\sparameterized\nfunction.\s(CVS\s1923)
+D 2004-08-31T00:52:37
F Makefile.in 65a7c43fcaf9a710d62f120b11b6e435eeb4a450
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/delete.c 0ccc3424d72e5aaded165a8861b9d958c9d0afe6
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
F src/expr.c 3694386726ca140dddb839837ba24b58563d10af
-F src/func.c 7e2eeebe219aa612ce7a04c74ae6d57379c6656b
+F src/func.c ab1d6436edea1333f2a9398800a6404942661724
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c fc1ce65a0fe68f226143de9b43c3582164a92aff
F src/select.c 400b2dcc8e05c0101a65a370f7ebb33c9c85f0b3
F src/shell.c 64932b37d79baffd34544172c14c99b2e08a11bb
F src/sqlite.h.in b89ced1acc705bc9c79a2a4e725ac0eb64bd0614
-F src/sqliteInt.h c7ed161ecc40f9fd0f080fbcc00e34bd7d6735ee
+F src/sqliteInt.h 89c1555ceba68d460ee13530eb8a51944e57fad2
F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
F src/tclsqlite.c b7dd8b3531b70188d03354db530de0f2ffcac697
F src/test1.c 3670f318c473b5a81cae548d9cc42da3f6a6efee
F src/tokenize.c 32171c3d576c7ec6acd6cf15e55c00ac0b314769
F src/trigger.c 8b147c6b8ae0bab3a13463a4ca9ab6ad61f1361d
F src/update.c 151f1869ce532ed883f1ce26306f0b0fa7b2589a
-F src/utf.c 3d8f7bffcbefcced69a436c9e0a1c7eb9e0bb4fa
-F src/util.c e2c631849cc9e035f6fd387f507ad8886f77cedd
+F src/utf.c 328890099db492dda5620ee5f924e244c6e57ff7
+F src/util.c d5aaf211543fb6e285654fada50252c857ac78aa
F src/vacuum.c 9978a5760c2c430bc5b5e66505a02dad76f25813
F src/vdbe.c bc7717be599d23c463c029d13eb2eb46c94a5e6e
F src/vdbe.h e081c72cd0f7c19d49b1927460aeefcf0fbc85ac
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 9322c439c5727f0d65548efdf4de4d7b89b4be66
-R 78b9eb3fdca60240e1b2bb671f0502fe
+P 8f5b199e845fa7ae3444ef69bd840716d305cf73
+R 616cb374fb9c8575e09ed1273dacb01d
U drh
-Z b8b12d29336c5de9dba049e2bc96808c
+Z 33bccfa82a63e9342b9c97917948d9a3
-8f5b199e845fa7ae3444ef69bd840716d305cf73
\ No newline at end of file
+0a47c8f86d1649e9ae7edd4c49a6fe5f5272351e
\ No newline at end of file
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.80 2004/08/08 20:22:18 drh Exp $
+** $Id: func.c,v 1.81 2004/08/31 00:52:37 drh Exp $
*/
#include <ctype.h>
#include <math.h>
sqlite3_result_int(context, sqlite3_total_changes(db));
}
-#if 0
-
/*
-** A LIKE pattern compiles to an instance of the following structure. Refer
-** to the comment for compileLike() function for details.
+** A structure defining how to do GLOB-style comparisons.
*/
-struct LikePattern {
- int nState;
- struct LikeState {
- int val; /* Unicode codepoint or -1 for any char i.e. '_' */
- int failstate; /* State to jump to if next char is not val */
- } aState[1];
+struct compareInfo {
+ u8 matchAll;
+ u8 matchOne;
+ u8 matchSet;
+ u8 noCase;
};
-typedef struct LikePattern LikePattern;
+static const struct compareInfo globInfo = { '*', '?', '[', 0 };
+static const struct compareInfo likeInfo = { '%', '_', 0, 1 };
+
+/*
+** X is a pointer to the first byte of a UTF-8 character. Increment
+** X so that it points to the next character. This only works right
+** if X points to a well-formed UTF-8 string.
+*/
+#define sqliteNextChar(X) while( (0xc0&*++(X))==0x80 ){}
+#define sqliteCharVal(X) sqlite3ReadUtf8(X)
-void deleteLike(void *pLike){
- sqliteFree(pLike);
-}
-/* #define TRACE_LIKE */
-#if defined(TRACE_LIKE) && !defined(NDEBUG)
-char *dumpLike(LikePattern *pLike){
- int i;
- int k = 0;
- char *zBuf = (char *)sqliteMalloc(pLike->nState*40);
-
- k += sprintf(&zBuf[k], "%d states - ", pLike->nState);
- for(i=0; i<pLike->nState; i++){
- k += sprintf(&zBuf[k], " %d:(%d, %d)", i, pLike->aState[i].val,
- pLike->aState[i].failstate);
- }
- return zBuf;
-}
-#endif
/*
-** This function compiles an SQL 'LIKE' pattern into a state machine,
-** represented by a LikePattern structure.
+** Compare two UTF-8 strings for equality where the first string can
+** potentially be a "glob" expression. Return true (1) if they
+** are the same and false (0) if they are different.
**
-** Each state of the state-machine has two attributes, 'val' and
-** 'failstate'. The val attribute is either the value of a unicode
-** codepoint, or -1, indicating a '_' wildcard (match any single
-** character). The failstate is either the number of another state
-** or -1, indicating jump to 'no match'.
+** Globbing rules:
**
-** To see if a string matches a pattern the pattern is
-** compiled to a state machine that is executed according to the algorithm
-** below. The string is assumed to be terminated by a 'NUL' character
-** (unicode codepoint 0).
+** '*' Matches any sequence of zero or more characters.
**
-** 1 S = 0
-** 2 DO
-** 3 C = <Next character from input string>
-** 4 IF( C matches <State S val> )
-** 5 S = S+1
-** 6 ELSE IF( S != <State S failstate> )
-** 7 S = <State S failstate>
-** 8 <Rewind Input string 1 character>
-** 9 WHILE( (C != NUL) AND (S != FAILED) )
-** 10
-** 11 IF( S == <number of states> )
-** 12 RETURN MATCH
-** 13 ELSE
-** 14 RETURN NO-MATCH
-**
-** In practice there is a small optimization to avoid the <Rewind>
-** operation in line 8 of the description above.
+** '?' Matches exactly one character.
**
-** For example, the following pattern, 'X%ABabc%_Y' is compiled to
-** the state machine below.
+** [...] Matches one character from the enclosed list of
+** characters.
**
-** State Val FailState
-** -------------------------------
-** 0 120 (x) -1 (NO MATCH)
-** 1 97 (a) 1
-** 2 98 (b) 1
-** 3 97 (a) 1
-** 4 98 (b) 2
-** 5 99 (c) 3
-** 6 -1 (_) 6
-** 7 121 (y) 7
-** 8 0 (NUL) 7
+** [^...] Matches one character not in the enclosed list.
**
-** The algorithms implemented to compile and execute the state machine were
-** first presented in "Fast pattern matching in strings", Knuth, Morris and
-** Pratt, 1977.
-**
-*/
-LikePattern *compileLike(sqlite3_value *pPattern, u8 enc){
- LikePattern *pLike;
- struct LikeState *aState;
- int pc_state = -1; /* State number of previous '%' wild card */
- int n = 0;
- int c;
-
- int offset = 0;
- const char *zLike;
-
- if( enc==SQLITE_UTF8 ){
- zLike = sqlite3_value_text(pPattern);
- n = sqlite3_value_bytes(pPattern) + 1;
- }else{
- zLike = sqlite3_value_text16(pPattern);
- n = sqlite3_value_bytes16(pPattern)/2 + 1;
- }
-
- pLike = (LikePattern *)
- sqliteMalloc(sizeof(LikePattern)+n*sizeof(struct LikeState));
- aState = pLike->aState;
-
- n = 0;
- do {
- c = sqlite3ReadUniChar(zLike, &offset, &enc, 1);
- if( c==95 ){ /* A '_' wildcard */
- aState[n].val = -1;
- n++;
- }else if( c==37 ){ /* A '%' wildcard */
- aState[n].failstate = n;
- pc_state = n;
- }else{ /* A regular character */
- aState[n].val = c;
-
- assert( pc_state<=n );
- if( pc_state<0 ){
- aState[n].failstate = -1;
- }else if( pc_state==n ){
- if( c ){
- aState[n].failstate = pc_state;
- }else{
- aState[n].failstate = -2;
- }
- }else{
- int k = pLike->aState[n-1].failstate;
- while( k>pc_state && aState[k+1].val!=-1 && aState[k+1].val!=c ){
- k = aState[k].failstate;
- }
- if( k!=pc_state && aState[k+1].val==c ){
- assert( k==pc_state );
- k++;
- }
- aState[n].failstate = k;
- }
- n++;
- }
- }while( c );
- pLike->nState = n;
-#if defined(TRACE_LIKE) && !defined(NDEBUG)
- {
- char *zCompiled = dumpLike(pLike);
- printf("Pattern=\"%s\" Compiled=\"%s\"\n", zPattern, zCompiled);
- sqliteFree(zCompiled);
- }
-#endif
- return pLike;
-}
-
-/*
-** 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:
+** With the [...] and [^...] matching, a ']' character can be included
+** in the list by making it the first character after '[' or '^'. A
+** range of characters can be specified using '-'. Example:
+** "[a-z]" matches any single lower-case letter. To match a '-', make
+** it the last character in the list.
**
-** A LIKE B
+** This routine is usually quick, but can be N**2 in the worst case.
**
-** is implemented as like(B,A).
+** Hints: to match '*' or '?', put them in "[]". Like this:
**
-** If the pointer retrieved by via a call to sqlite3_user_data() is
-** not NULL, then this function uses UTF-16. Otherwise UTF-8.
+** abc[*]xyz Matches "abc*xyz" only
*/
-static void likeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
+int patternCompare(
+ const u8 *zPattern, /* The glob pattern */
+ const u8 *zString, /* The string to compare against the glob */
+ const struct compareInfo *pInfo /* Information about how to do the compare */
){
register int c;
- u8 enc;
- int offset = 0;
- const unsigned char *zString;
- LikePattern *pLike = sqlite3_get_auxdata(context, 0);
- struct LikeState *aState;
- register struct LikeState *pState;
-
- /* If either argument is NULL, the result is NULL */
- if( sqlite3_value_type(argv[1])==SQLITE_NULL ||
- sqlite3_value_type(argv[0])==SQLITE_NULL ){
- return;
- }
-
- /* If the user-data pointer is NULL, use UTF-8. Otherwise UTF-16. */
- if( sqlite3_user_data(context) ){
- enc = SQLITE_UTF16NATIVE;
- zString = (const unsigned char *)sqlite3_value_text16(argv[1]);
- assert(0);
- }else{
- enc = SQLITE_UTF8;
- zString = sqlite3_value_text(argv[1]);
- }
-
- /* If the LIKE pattern has not been compiled, compile it now. */
- if( !pLike ){
- pLike = compileLike(argv[0], enc);
- if( !pLike ){
- sqlite3_result_error(context, "out of memory", -1);
- return;
- }
- sqlite3_set_auxdata(context, 0, pLike, deleteLike);
- }
- aState = pLike->aState;
- pState = aState;
-
- do {
- if( enc==SQLITE_UTF8 ){
- c = zString[offset++];
- if( c&0x80 ){
- offset--;
- c = sqlite3ReadUniChar(zString, &offset, &enc, 1);
+ int invert;
+ int seen;
+ int c2;
+ u8 matchOne = pInfo->matchOne;
+ u8 matchAll = pInfo->matchAll;
+ u8 matchSet = pInfo->matchSet;
+ u8 noCase = pInfo->noCase;
+
+ while( (c = *zPattern)!=0 ){
+ if( c==matchAll ){
+ while( (c=zPattern[1]) == matchAll || c == matchOne ){
+ if( c==matchOne ){
+ if( *zString==0 ) return 0;
+ sqliteNextChar(zString);
+ }
+ zPattern++;
}
+ if( c==0 ) return 1;
+ if( c==matchSet ){
+ while( *zString && patternCompare(&zPattern[1],zString,pInfo)==0 ){
+ sqliteNextChar(zString);
+ }
+ return *zString!=0;
+ }else{
+ while( (c2 = *zString)!=0 ){
+ if( noCase ){
+ c2 = sqlite3UpperToLower[c2];
+ c = sqlite3UpperToLower[c];
+ while( c2 != 0 && c2 != c ){ c2 = sqlite3UpperToLower[*++zString]; }
+ }else{
+ while( c2 != 0 && c2 != c ){ c2 = *++zString; }
+ }
+ if( c2==0 ) return 0;
+ if( patternCompare(&zPattern[1],zString,pInfo) ) return 1;
+ sqliteNextChar(zString);
+ }
+ return 0;
+ }
+ }else if( c==matchOne ){
+ if( *zString==0 ) return 0;
+ sqliteNextChar(zString);
+ zPattern++;
+ }else if( c==matchSet ){
+ int prior_c = 0;
+ seen = 0;
+ invert = 0;
+ c = sqliteCharVal(zString);
+ if( c==0 ) return 0;
+ c2 = *++zPattern;
+ if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
+ if( c2==']' ){
+ if( c==']' ) seen = 1;
+ c2 = *++zPattern;
+ }
+ while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){
+ if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){
+ zPattern++;
+ c2 = sqliteCharVal(zPattern);
+ if( c>=prior_c && c<=c2 ) seen = 1;
+ prior_c = 0;
+ }else if( c==c2 ){
+ seen = 1;
+ prior_c = c2;
+ }else{
+ prior_c = c2;
+ }
+ sqliteNextChar(zPattern);
+ }
+ if( c2==0 || (seen ^ invert)==0 ) return 0;
+ sqliteNextChar(zString);
+ zPattern++;
}else{
- c = sqlite3ReadUniChar(zString, &offset, &enc, 1);
- }
-
-skip_read:
-
-#if defined(TRACE_LIKE) && !defined(NDEBUG)
- printf("State=%d:(%d, %d) Input=%d\n",
- (aState - pState), pState->val, pState->failstate, c);
-#endif
-
- if( pState->val==-1 || pState->val==c ){
- pState++;
- }else{
- struct LikeState *pFailState = &aState[pState->failstate];
- if( pState!=pFailState ){
- pState = pFailState;
- if( c && pState>=aState ) goto skip_read;
+ if( noCase ){
+ if( sqlite3UpperToLower[c] != sqlite3UpperToLower[*zString] ) return 0;
+ }else{
+ if( c != *zString ) return 0;
}
+ zPattern++;
+ zString++;
}
- }while( c && pState>=aState );
-
- if( (pState-aState)==pLike->nState || (pState-aState)<-1 ){
- sqlite3_result_int(context, 1);
- }else{
- sqlite3_result_int(context, 0);
}
+ return *zString==0;
}
-#endif
+
/*
** Implementation of the like() SQL function. This function implements
const unsigned char *zA = sqlite3_value_text(argv[0]);
const unsigned char *zB = sqlite3_value_text(argv[1]);
if( zA && zB ){
- sqlite3_result_int(context, sqlite3utf8LikeCompare(zA, zB));
+ sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo));
}
}
const unsigned char *zA = sqlite3_value_text(argv[0]);
const unsigned char *zB = sqlite3_value_text(argv[1]);
if( zA && zB ){
- sqlite3_result_int(context, sqlite3GlobCompare(zA, zB));
+ sqlite3_result_int(context, patternCompare(zA, zB, &globInfo));
}
}
sqlite3VdbeMemRelease(pRes);
}
+
/*
** This function registered all of the above C functions as SQL
** functions. This should be the only routine in this file with
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.316 2004/08/21 17:54:45 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.317 2004/08/31 00:52:37 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
void sqlite3UnlinkAndDeleteTrigger(sqlite*,int,const char*);
void sqlite3Vacuum(Parse*, Token*);
int sqlite3RunVacuum(char**, sqlite*);
-int sqlite3GlobCompare(const unsigned char*,const unsigned char*);
char *sqlite3NameFromToken(Token*);
int sqlite3ExprCheck(Parse*, Expr*, int, int*);
int sqlite3ExprCompare(Expr*, Expr*);
int sqlite3FitsIn64Bits(const char *);
int sqlite3utf16ByteLen(const void *pData, int nChar);
int sqlite3utf8CharLen(const char *pData, int nByte);
-int sqlite3utf8LikeCompare(const unsigned char*, const unsigned char*);
+int sqlite3ReadUtf8(const unsigned char *);
int sqlite3PutVarint(unsigned char *, u64);
int sqlite3GetVarint(const unsigned char *, u64 *);
int sqlite3GetVarint32(const unsigned char *, u32 *);
void sqlite3ValueFree(sqlite3_value*);
sqlite3_value *sqlite3ValueNew();
sqlite3_value *sqlite3GetTransientValue(sqlite *db);
+extern const unsigned char sqlite3UpperToLower[];
#endif
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
-** $Id: utf.c,v 1.27 2004/08/08 23:39:19 drh Exp $
+** $Id: utf.c,v 1.28 2004/08/31 00:52:37 drh Exp $
**
** Notes on UTF-8:
**
#include "sqliteInt.h"
#include "vdbeInt.h"
-/*
-** The following macro, LOWERCASE(x), takes an integer representing a
-** unicode code point. The value returned is the same code point folded to
-** lower case, if applicable. SQLite currently understands the upper/lower
-** case relationship between the 26 characters used in the English
-** language only.
-**
-** This means that characters with umlauts etc. will not be folded
-** correctly (unless they are encoded as composite characters, which would
-** doubtless cause much trouble).
-*/
-#define LOWERCASE(x) (x<91?(int)(UpperToLower[x]):x)
-static unsigned char UpperToLower[91] = {
- 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,
-};
-
/*
** This table maps from the first byte of a UTF-8 character to the number
** of trailing bytes expected. A value '255' indicates that the table key
c -= xtra_utf8_bits[xtra]; \
} \
}
+int sqlite3ReadUtf8(const unsigned char *z){
+ int c;
+ READ_UTF8(z, c);
+ return c;
+}
#define SKIP_UTF8(zIn) { \
zIn += (xtra_utf8_bytes[*(u8 *)zIn] + 1); \
return (z-(char const *)zIn)-((c==0)?2:0);
}
-/*
-** Compare two UTF-8 strings for equality using the "LIKE" operator of
-** SQL. The '%' character matches any sequence of 0 or more
-** characters and '_' matches any single character. Case is
-** not significant.
-*/
-int sqlite3utf8LikeCompare(
- const unsigned char *zPattern,
- const unsigned char *zString
-){
- register int c;
- int c2;
-
- while( (c = LOWERCASE(*zPattern))!=0 ){
- switch( c ){
- case '%': {
- while( (c=zPattern[1]) == '%' || c == '_' ){
- if( c=='_' ){
- if( *zString==0 ) return 0;
- SKIP_UTF8(zString);
- }
- zPattern++;
- }
- if( c==0 ) return 1;
- c = LOWERCASE(c);
- while( (c2=LOWERCASE(*zString))!=0 ){
- while( c2 != 0 && c2 != c ){
- zString++;
- c2 = LOWERCASE(*zString);
- }
- if( c2==0 ) return 0;
- if( sqlite3utf8LikeCompare(&zPattern[1],zString) ) return 1;
- SKIP_UTF8(zString);
- }
- return 0;
- }
- case '_': {
- if( *zString==0 ) return 0;
- SKIP_UTF8(zString);
- zPattern++;
- break;
- }
- default: {
- if( c != LOWERCASE(*zString) ) return 0;
- zPattern++;
- zString++;
- break;
- }
- }
- }
- return *zString==0;
-}
-
/*
** UTF-16 implementation of the substr()
*/
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.113 2004/08/18 02:10:15 drh Exp $
+** $Id: util.c,v 1.114 2004/08/31 00:52:37 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
/* An array to map all upper-case characters into their corresponding
** lower-case character.
*/
-static unsigned char UpperToLower[] = {
+const unsigned char sqlite3UpperToLower[] = {
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,
234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
252,253,254,255
};
+#define UpperToLower sqlite3UpperToLower
/*
** This function computes a hash on the name of a keyword.
return i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0);
}
-#if 1 /* We are now always UTF-8 */
-/*
-** X is a pointer to the first byte of a UTF-8 character. Increment
-** X so that it points to the next character. This only works right
-** if X points to a well-formed UTF-8 string.
-*/
-#define sqliteNextChar(X) while( (0xc0&*++(X))==0x80 ){}
-#define sqliteCharVal(X) sqlite3ReadUtf8(X)
-
-#else /* !defined(SQLITE_UTF8) */
-/*
-** For iso8859 encoding, the next character is just the next byte.
-*/
-#define sqliteNextChar(X) (++(X));
-#define sqliteCharVal(X) ((int)*(X))
-
-#endif /* defined(SQLITE_UTF8) */
-
-
-#if 1 /* We are now always UTF-8 */
-/*
-** Convert the UTF-8 character to which z points into a 31-bit
-** UCS character. This only works right if z points to a well-formed
-** UTF-8 string.
-*/
-int sqlite3ReadUtf8(const unsigned char *z){
- int c;
- static const char initVal[] = {
- 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, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 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, 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, 0,
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 254,
- 255,
- };
- c = initVal[*(z++)];
- while( (0xc0&*z)==0x80 ){
- c = (c<<6) | (0x3f&*(z++));
- }
- return c;
-}
-#endif
-
-/*
-** Compare two UTF-8 strings for equality where the first string can
-** potentially be a "glob" expression. Return true (1) if they
-** are the same and false (0) if they are different.
-**
-** Globbing rules:
-**
-** '*' Matches any sequence of zero or more characters.
-**
-** '?' Matches exactly one character.
-**
-** [...] Matches one character from the enclosed list of
-** characters.
-**
-** [^...] Matches one character not in the enclosed list.
-**
-** With the [...] and [^...] matching, a ']' character can be included
-** in the list by making it the first character after '[' or '^'. A
-** range of characters can be specified using '-'. Example:
-** "[a-z]" matches any single lower-case letter. To match a '-', make
-** it the last character in the list.
-**
-** This routine is usually quick, but can be N**2 in the worst case.
-**
-** Hints: to match '*' or '?', put them in "[]". Like this:
-**
-** abc[*]xyz Matches "abc*xyz" only
-*/
-int
-sqlite3GlobCompare(const unsigned char *zPattern, const unsigned char *zString){
- register int c;
- int invert;
- int seen;
- int c2;
-
- while( (c = *zPattern)!=0 ){
- switch( c ){
- case '*':
- while( (c=zPattern[1]) == '*' || c == '?' ){
- if( c=='?' ){
- if( *zString==0 ) return 0;
- sqliteNextChar(zString);
- }
- zPattern++;
- }
- if( c==0 ) return 1;
- if( c=='[' ){
- while( *zString && sqlite3GlobCompare(&zPattern[1],zString)==0 ){
- sqliteNextChar(zString);
- }
- return *zString!=0;
- }else{
- while( (c2 = *zString)!=0 ){
- while( c2 != 0 && c2 != c ){ c2 = *++zString; }
- if( c2==0 ) return 0;
- if( sqlite3GlobCompare(&zPattern[1],zString) ) return 1;
- sqliteNextChar(zString);
- }
- return 0;
- }
- case '?': {
- if( *zString==0 ) return 0;
- sqliteNextChar(zString);
- zPattern++;
- break;
- }
- case '[': {
- int prior_c = 0;
- seen = 0;
- invert = 0;
- c = sqliteCharVal(zString);
- if( c==0 ) return 0;
- c2 = *++zPattern;
- if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
- if( c2==']' ){
- if( c==']' ) seen = 1;
- c2 = *++zPattern;
- }
- while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){
- if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){
- zPattern++;
- c2 = sqliteCharVal(zPattern);
- if( c>=prior_c && c<=c2 ) seen = 1;
- prior_c = 0;
- }else if( c==c2 ){
- seen = 1;
- prior_c = c2;
- }else{
- prior_c = c2;
- }
- sqliteNextChar(zPattern);
- }
- if( c2==0 || (seen ^ invert)==0 ) return 0;
- sqliteNextChar(zString);
- zPattern++;
- break;
- }
- default: {
- if( c != *zString ) return 0;
- zPattern++;
- zString++;
- break;
- }
- }
- }
- return *zString==0;
-}
/*
** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.