drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 1 | /* |
drh | b19a2bc | 2001-09-16 00:13:26 +0000 | [diff] [blame] | 2 | ** 2001 September 15 |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 3 | ** |
drh | b19a2bc | 2001-09-16 00:13:26 +0000 | [diff] [blame] | 4 | ** The author disclaims copyright to this source code. In place of |
| 5 | ** a legal notice, here is a blessing: |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 6 | ** |
drh | b19a2bc | 2001-09-16 00:13:26 +0000 | [diff] [blame] | 7 | ** May you do good and not evil. |
| 8 | ** May you find forgiveness for yourself and forgive others. |
| 9 | ** May you share freely, never taking more than you give. |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 10 | ** |
| 11 | ************************************************************************* |
| 12 | ** Utility functions used throughout sqlite. |
| 13 | ** |
| 14 | ** This file contains functions for allocating memory, comparing |
| 15 | ** strings, and stuff like that. |
| 16 | ** |
drh | 326dce7 | 2003-01-29 14:06:07 +0000 | [diff] [blame^] | 17 | ** $Id: util.c,v 1.57 2003/01/29 14:06:09 drh Exp $ |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 18 | */ |
| 19 | #include "sqliteInt.h" |
| 20 | #include <stdarg.h> |
| 21 | #include <ctype.h> |
| 22 | |
drh | 7c68d60 | 2000-10-11 19:28:51 +0000 | [diff] [blame] | 23 | /* |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 24 | ** If malloc() ever fails, this global variable gets set to 1. |
| 25 | ** This causes the library to abort and never again function. |
| 26 | */ |
| 27 | int sqlite_malloc_failed = 0; |
| 28 | |
| 29 | /* |
drh | 7c68d60 | 2000-10-11 19:28:51 +0000 | [diff] [blame] | 30 | ** If MEMORY_DEBUG is defined, then use versions of malloc() and |
| 31 | ** free() that track memory usage and check for buffer overruns. |
| 32 | */ |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 33 | #ifdef MEMORY_DEBUG |
| 34 | |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 35 | /* |
drh | 8c82b35 | 2000-12-10 18:23:50 +0000 | [diff] [blame] | 36 | ** For keeping track of the number of mallocs and frees. This |
| 37 | ** is used to check for memory leaks. |
| 38 | */ |
| 39 | int sqlite_nMalloc; /* Number of sqliteMalloc() calls */ |
| 40 | int sqlite_nFree; /* Number of sqliteFree() calls */ |
| 41 | int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */ |
drh | d94a669 | 2002-08-25 18:29:11 +0000 | [diff] [blame] | 42 | #if MEMORY_DEBUG>1 |
| 43 | static int memcnt = 0; |
| 44 | #endif |
drh | 8c82b35 | 2000-12-10 18:23:50 +0000 | [diff] [blame] | 45 | |
| 46 | |
| 47 | /* |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 48 | ** Allocate new memory and set it to zero. Return NULL if |
| 49 | ** no memory is available. |
| 50 | */ |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 51 | void *sqliteMalloc_(int n, int bZero, char *zFile, int line){ |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 52 | void *p; |
| 53 | int *pi; |
| 54 | int k; |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 55 | if( sqlite_iMallocFail>=0 ){ |
| 56 | sqlite_iMallocFail--; |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 57 | if( sqlite_iMallocFail==0 ){ |
| 58 | sqlite_malloc_failed++; |
drh | 6d4abfb | 2001-10-22 02:58:08 +0000 | [diff] [blame] | 59 | #if MEMORY_DEBUG>1 |
| 60 | fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n", |
| 61 | n, zFile,line); |
| 62 | #endif |
| 63 | sqlite_iMallocFail--; |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 64 | return 0; |
| 65 | } |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 66 | } |
drh | b072950 | 2001-03-14 12:35:57 +0000 | [diff] [blame] | 67 | if( n==0 ) return 0; |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 68 | k = (n+sizeof(int)-1)/sizeof(int); |
| 69 | pi = malloc( (3+k)*sizeof(int)); |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 70 | if( pi==0 ){ |
| 71 | sqlite_malloc_failed++; |
| 72 | return 0; |
| 73 | } |
drh | 6d4abfb | 2001-10-22 02:58:08 +0000 | [diff] [blame] | 74 | sqlite_nMalloc++; |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 75 | pi[0] = 0xdead1122; |
| 76 | pi[1] = n; |
| 77 | pi[k+2] = 0xdead3344; |
| 78 | p = &pi[2]; |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 79 | memset(p, bZero==0, n); |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 80 | #if MEMORY_DEBUG>1 |
drh | d94a669 | 2002-08-25 18:29:11 +0000 | [diff] [blame] | 81 | fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n", |
| 82 | ++memcnt, n, (int)p, zFile,line); |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 83 | #endif |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 84 | return p; |
| 85 | } |
| 86 | |
| 87 | /* |
drh | ed6c867 | 2003-01-12 18:02:16 +0000 | [diff] [blame] | 88 | ** Check to see if the given pointer was obtained from sqliteMalloc() |
| 89 | ** and is able to hold at least N bytes. Raise an exception if this |
| 90 | ** is not the case. |
| 91 | ** |
| 92 | ** This routine is used for testing purposes only. |
| 93 | */ |
| 94 | void sqliteCheckMemory(void *p, int N){ |
| 95 | int *pi = p; |
| 96 | int n, k; |
| 97 | pi -= 2; |
| 98 | assert( pi[0]==0xdead1122 ); |
| 99 | n = pi[1]; |
| 100 | assert( N>=0 && N<n ); |
| 101 | k = (n+sizeof(int)-1)/sizeof(int); |
| 102 | assert( pi[k+2]==0xdead3344 ); |
| 103 | } |
| 104 | |
| 105 | /* |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 106 | ** Free memory previously obtained from sqliteMalloc() |
| 107 | */ |
| 108 | void sqliteFree_(void *p, char *zFile, int line){ |
| 109 | if( p ){ |
| 110 | int *pi, k, n; |
| 111 | pi = p; |
| 112 | pi -= 2; |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 113 | sqlite_nFree++; |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 114 | if( pi[0]!=0xdead1122 ){ |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 115 | fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p); |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 116 | return; |
| 117 | } |
| 118 | n = pi[1]; |
| 119 | k = (n+sizeof(int)-1)/sizeof(int); |
| 120 | if( pi[k+2]!=0xdead3344 ){ |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 121 | fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p); |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 122 | return; |
| 123 | } |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 124 | memset(pi, 0xff, (k+3)*sizeof(int)); |
| 125 | #if MEMORY_DEBUG>1 |
drh | d94a669 | 2002-08-25 18:29:11 +0000 | [diff] [blame] | 126 | fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n", |
| 127 | ++memcnt, n, (int)p, zFile,line); |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 128 | #endif |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 129 | free(pi); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | /* |
| 134 | ** Resize a prior allocation. If p==0, then this routine |
| 135 | ** works just like sqliteMalloc(). If n==0, then this routine |
| 136 | ** works just like sqliteFree(). |
| 137 | */ |
| 138 | void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){ |
| 139 | int *oldPi, *pi, k, oldN, oldK; |
| 140 | void *p; |
| 141 | if( oldP==0 ){ |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 142 | return sqliteMalloc_(n,1,zFile,line); |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 143 | } |
| 144 | if( n==0 ){ |
| 145 | sqliteFree_(oldP,zFile,line); |
| 146 | return 0; |
| 147 | } |
| 148 | oldPi = oldP; |
| 149 | oldPi -= 2; |
| 150 | if( oldPi[0]!=0xdead1122 ){ |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 151 | fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)p); |
drh | 9bb61fe | 2000-06-05 16:01:39 +0000 | [diff] [blame] | 152 | return 0; |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 153 | } |
| 154 | oldN = oldPi[1]; |
| 155 | oldK = (oldN+sizeof(int)-1)/sizeof(int); |
| 156 | if( oldPi[oldK+2]!=0xdead3344 ){ |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 157 | fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n", (int)p); |
drh | 9bb61fe | 2000-06-05 16:01:39 +0000 | [diff] [blame] | 158 | return 0; |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 159 | } |
| 160 | k = (n + sizeof(int) - 1)/sizeof(int); |
| 161 | pi = malloc( (k+3)*sizeof(int) ); |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 162 | if( pi==0 ){ |
| 163 | sqlite_malloc_failed++; |
| 164 | return 0; |
| 165 | } |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 166 | pi[0] = 0xdead1122; |
| 167 | pi[1] = n; |
| 168 | pi[k+2] = 0xdead3344; |
| 169 | p = &pi[2]; |
| 170 | memcpy(p, oldP, n>oldN ? oldN : n); |
| 171 | if( n>oldN ){ |
| 172 | memset(&((char*)p)[oldN], 0, n-oldN); |
| 173 | } |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 174 | memset(oldPi, 0xab, (oldK+3)*sizeof(int)); |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 175 | free(oldPi); |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 176 | #if MEMORY_DEBUG>1 |
drh | d94a669 | 2002-08-25 18:29:11 +0000 | [diff] [blame] | 177 | fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n", |
| 178 | ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line); |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 179 | #endif |
drh | dcc581c | 2000-05-30 13:44:19 +0000 | [diff] [blame] | 180 | return p; |
| 181 | } |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 182 | |
| 183 | /* |
| 184 | ** Make a duplicate of a string into memory obtained from malloc() |
| 185 | ** Free the original string using sqliteFree(). |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 186 | ** |
| 187 | ** This routine is called on all strings that are passed outside of |
| 188 | ** the SQLite library. That way clients can free the string using free() |
| 189 | ** rather than having to call sqliteFree(). |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 190 | */ |
| 191 | void sqliteStrRealloc(char **pz){ |
| 192 | char *zNew; |
| 193 | if( pz==0 || *pz==0 ) return; |
| 194 | zNew = malloc( strlen(*pz) + 1 ); |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 195 | if( zNew==0 ){ |
| 196 | sqlite_malloc_failed++; |
| 197 | sqliteFree(*pz); |
| 198 | *pz = 0; |
| 199 | } |
| 200 | strcpy(zNew, *pz); |
drh | c3c2fc9 | 2000-05-31 22:58:39 +0000 | [diff] [blame] | 201 | sqliteFree(*pz); |
| 202 | *pz = zNew; |
| 203 | } |
| 204 | |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 205 | /* |
| 206 | ** Make a copy of a string in memory obtained from sqliteMalloc() |
| 207 | */ |
| 208 | char *sqliteStrDup_(const char *z, char *zFile, int line){ |
drh | ff78bd2 | 2002-02-27 01:47:11 +0000 | [diff] [blame] | 209 | char *zNew; |
| 210 | if( z==0 ) return 0; |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 211 | zNew = sqliteMalloc_(strlen(z)+1, 0, zFile, line); |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 212 | if( zNew ) strcpy(zNew, z); |
| 213 | return zNew; |
| 214 | } |
| 215 | char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){ |
drh | ff78bd2 | 2002-02-27 01:47:11 +0000 | [diff] [blame] | 216 | char *zNew; |
| 217 | if( z==0 ) return 0; |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 218 | zNew = sqliteMalloc_(n+1, 0, zFile, line); |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 219 | if( zNew ){ |
| 220 | memcpy(zNew, z, n); |
| 221 | zNew[n] = 0; |
| 222 | } |
| 223 | return zNew; |
| 224 | } |
drh | 7c68d60 | 2000-10-11 19:28:51 +0000 | [diff] [blame] | 225 | #endif /* MEMORY_DEBUG */ |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 226 | |
drh | 7c68d60 | 2000-10-11 19:28:51 +0000 | [diff] [blame] | 227 | /* |
| 228 | ** The following versions of malloc() and free() are for use in a |
| 229 | ** normal build. |
| 230 | */ |
| 231 | #if !defined(MEMORY_DEBUG) |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 232 | |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 233 | /* |
| 234 | ** Allocate new memory and set it to zero. Return NULL if |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 235 | ** no memory is available. See also sqliteMallocRaw(). |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 236 | */ |
| 237 | void *sqliteMalloc(int n){ |
drh | 2678058 | 2002-10-20 15:46:22 +0000 | [diff] [blame] | 238 | void *p; |
| 239 | if( n==0 ) return 0; |
| 240 | p = malloc(n); |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 241 | if( p==0 ){ |
| 242 | sqlite_malloc_failed++; |
| 243 | return 0; |
| 244 | } |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 245 | memset(p, 0, n); |
| 246 | return p; |
| 247 | } |
| 248 | |
| 249 | /* |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 250 | ** Allocate new memory but do not set it to zero. Return NULL if |
| 251 | ** no memory is available. See also sqliteMalloc(). |
| 252 | */ |
| 253 | void *sqliteMallocRaw(int n){ |
| 254 | void *p; |
| 255 | if( n==0 ) return 0; |
| 256 | p = malloc(n); |
| 257 | if( p==0 ){ |
| 258 | sqlite_malloc_failed++; |
| 259 | return 0; |
| 260 | } |
| 261 | return p; |
| 262 | } |
| 263 | |
| 264 | /* |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 265 | ** Free memory previously obtained from sqliteMalloc() |
| 266 | */ |
| 267 | void sqliteFree(void *p){ |
drh | 305cea6 | 2000-05-29 17:44:25 +0000 | [diff] [blame] | 268 | if( p ){ |
drh | 305cea6 | 2000-05-29 17:44:25 +0000 | [diff] [blame] | 269 | free(p); |
| 270 | } |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 271 | } |
| 272 | |
| 273 | /* |
| 274 | ** Resize a prior allocation. If p==0, then this routine |
| 275 | ** works just like sqliteMalloc(). If n==0, then this routine |
| 276 | ** works just like sqliteFree(). |
| 277 | */ |
| 278 | void *sqliteRealloc(void *p, int n){ |
drh | 6d4abfb | 2001-10-22 02:58:08 +0000 | [diff] [blame] | 279 | void *p2; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 280 | if( p==0 ){ |
| 281 | return sqliteMalloc(n); |
| 282 | } |
| 283 | if( n==0 ){ |
| 284 | sqliteFree(p); |
| 285 | return 0; |
| 286 | } |
drh | 6d4abfb | 2001-10-22 02:58:08 +0000 | [diff] [blame] | 287 | p2 = realloc(p, n); |
| 288 | if( p2==0 ){ |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 289 | sqlite_malloc_failed++; |
| 290 | } |
drh | 6d4abfb | 2001-10-22 02:58:08 +0000 | [diff] [blame] | 291 | return p2; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 292 | } |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 293 | |
| 294 | /* |
| 295 | ** Make a copy of a string in memory obtained from sqliteMalloc() |
| 296 | */ |
| 297 | char *sqliteStrDup(const char *z){ |
drh | 567c604 | 2002-02-28 04:10:29 +0000 | [diff] [blame] | 298 | char *zNew; |
| 299 | if( z==0 ) return 0; |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 300 | zNew = sqliteMallocRaw(strlen(z)+1); |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 301 | if( zNew ) strcpy(zNew, z); |
| 302 | return zNew; |
| 303 | } |
| 304 | char *sqliteStrNDup(const char *z, int n){ |
drh | 567c604 | 2002-02-28 04:10:29 +0000 | [diff] [blame] | 305 | char *zNew; |
| 306 | if( z==0 ) return 0; |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 307 | zNew = sqliteMallocRaw(n+1); |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 308 | if( zNew ){ |
| 309 | memcpy(zNew, z, n); |
| 310 | zNew[n] = 0; |
| 311 | } |
| 312 | return zNew; |
| 313 | } |
drh | 7c68d60 | 2000-10-11 19:28:51 +0000 | [diff] [blame] | 314 | #endif /* !defined(MEMORY_DEBUG) */ |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 315 | |
| 316 | /* |
| 317 | ** Create a string from the 2nd and subsequent arguments (up to the |
| 318 | ** first NULL argument), store the string in memory obtained from |
| 319 | ** sqliteMalloc() and make the pointer indicated by the 1st argument |
| 320 | ** point to that string. |
| 321 | */ |
| 322 | void sqliteSetString(char **pz, const char *zFirst, ...){ |
| 323 | va_list ap; |
| 324 | int nByte; |
| 325 | const char *z; |
| 326 | char *zResult; |
| 327 | |
| 328 | if( pz==0 ) return; |
| 329 | nByte = strlen(zFirst) + 1; |
| 330 | va_start(ap, zFirst); |
| 331 | while( (z = va_arg(ap, const char*))!=0 ){ |
| 332 | nByte += strlen(z); |
| 333 | } |
| 334 | va_end(ap); |
| 335 | sqliteFree(*pz); |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 336 | *pz = zResult = sqliteMallocRaw( nByte ); |
drh | 6d4abfb | 2001-10-22 02:58:08 +0000 | [diff] [blame] | 337 | if( zResult==0 ){ |
| 338 | return; |
| 339 | } |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 340 | strcpy(zResult, zFirst); |
| 341 | zResult += strlen(zResult); |
| 342 | va_start(ap, zFirst); |
| 343 | while( (z = va_arg(ap, const char*))!=0 ){ |
| 344 | strcpy(zResult, z); |
| 345 | zResult += strlen(zResult); |
| 346 | } |
| 347 | va_end(ap); |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 348 | #ifdef MEMORY_DEBUG |
| 349 | #if MEMORY_DEBUG>1 |
| 350 | fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz); |
| 351 | #endif |
| 352 | #endif |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 353 | } |
| 354 | |
| 355 | /* |
| 356 | ** Works like sqliteSetString, but each string is now followed by |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 357 | ** a length integer which specifies how much of the source string |
| 358 | ** to copy (in bytes). -1 means use the whole string. |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 359 | */ |
| 360 | void sqliteSetNString(char **pz, ...){ |
| 361 | va_list ap; |
| 362 | int nByte; |
| 363 | const char *z; |
| 364 | char *zResult; |
| 365 | int n; |
| 366 | |
| 367 | if( pz==0 ) return; |
| 368 | nByte = 0; |
| 369 | va_start(ap, pz); |
| 370 | while( (z = va_arg(ap, const char*))!=0 ){ |
| 371 | n = va_arg(ap, int); |
| 372 | if( n<=0 ) n = strlen(z); |
| 373 | nByte += n; |
| 374 | } |
| 375 | va_end(ap); |
| 376 | sqliteFree(*pz); |
drh | 8c1238a | 2003-01-02 14:43:55 +0000 | [diff] [blame] | 377 | *pz = zResult = sqliteMallocRaw( nByte + 1 ); |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 378 | if( zResult==0 ) return; |
| 379 | va_start(ap, pz); |
| 380 | while( (z = va_arg(ap, const char*))!=0 ){ |
| 381 | n = va_arg(ap, int); |
| 382 | if( n<=0 ) n = strlen(z); |
| 383 | strncpy(zResult, z, n); |
| 384 | zResult += n; |
| 385 | } |
| 386 | *zResult = 0; |
drh | 6e142f5 | 2000-06-08 13:36:40 +0000 | [diff] [blame] | 387 | #ifdef MEMORY_DEBUG |
| 388 | #if MEMORY_DEBUG>1 |
| 389 | fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz); |
| 390 | #endif |
| 391 | #endif |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 392 | va_end(ap); |
| 393 | } |
| 394 | |
drh | 982cef7 | 2000-05-30 16:27:03 +0000 | [diff] [blame] | 395 | /* |
| 396 | ** Convert an SQL-style quoted string into a normal string by removing |
| 397 | ** the quote characters. The conversion is done in-place. If the |
| 398 | ** input does not begin with a quote character, then this routine |
| 399 | ** is a no-op. |
drh | 2f4392f | 2002-02-14 21:42:51 +0000 | [diff] [blame] | 400 | ** |
| 401 | ** 2002-Feb-14: This routine is extended to remove MS-Access style |
| 402 | ** brackets from around identifers. For example: "[a-b-c]" becomes |
| 403 | ** "a-b-c". |
drh | 982cef7 | 2000-05-30 16:27:03 +0000 | [diff] [blame] | 404 | */ |
| 405 | void sqliteDequote(char *z){ |
| 406 | int quote; |
| 407 | int i, j; |
drh | daffd0e | 2001-04-11 14:28:42 +0000 | [diff] [blame] | 408 | if( z==0 ) return; |
drh | 982cef7 | 2000-05-30 16:27:03 +0000 | [diff] [blame] | 409 | quote = z[0]; |
drh | 2f4392f | 2002-02-14 21:42:51 +0000 | [diff] [blame] | 410 | switch( quote ){ |
| 411 | case '\'': break; |
| 412 | case '"': break; |
| 413 | case '[': quote = ']'; break; |
| 414 | default: return; |
| 415 | } |
drh | 982cef7 | 2000-05-30 16:27:03 +0000 | [diff] [blame] | 416 | for(i=1, j=0; z[i]; i++){ |
| 417 | if( z[i]==quote ){ |
| 418 | if( z[i+1]==quote ){ |
| 419 | z[j++] = quote; |
| 420 | i++; |
| 421 | }else{ |
| 422 | z[j++] = 0; |
| 423 | break; |
| 424 | } |
| 425 | }else{ |
| 426 | z[j++] = z[i]; |
| 427 | } |
| 428 | } |
| 429 | } |
| 430 | |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 431 | /* An array to map all upper-case characters into their corresponding |
| 432 | ** lower-case character. |
| 433 | */ |
| 434 | static unsigned char UpperToLower[] = { |
| 435 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, |
| 436 | 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, |
| 437 | 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, |
| 438 | 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, |
| 439 | 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121, |
| 440 | 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107, |
| 441 | 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125, |
| 442 | 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, |
| 443 | 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161, |
| 444 | 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179, |
| 445 | 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197, |
| 446 | 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215, |
| 447 | 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233, |
| 448 | 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251, |
| 449 | 252,253,254,255 |
| 450 | }; |
| 451 | |
| 452 | /* |
| 453 | ** This function computes a hash on the name of a keyword. |
| 454 | ** Case is not significant. |
| 455 | */ |
| 456 | int sqliteHashNoCase(const char *z, int n){ |
| 457 | int h = 0; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 458 | if( n<=0 ) n = strlen(z); |
drh | db5ed6d | 2001-09-18 22:17:44 +0000 | [diff] [blame] | 459 | while( n > 0 ){ |
drh | 8cfbf08 | 2001-09-19 13:22:39 +0000 | [diff] [blame] | 460 | h = (h<<3) ^ h ^ UpperToLower[(unsigned char)*z++]; |
drh | db5ed6d | 2001-09-18 22:17:44 +0000 | [diff] [blame] | 461 | n--; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 462 | } |
| 463 | if( h<0 ) h = -h; |
| 464 | return h; |
| 465 | } |
| 466 | |
| 467 | /* |
drh | 967e8b7 | 2000-06-21 13:59:10 +0000 | [diff] [blame] | 468 | ** Some systems have stricmp(). Others have strcasecmp(). Because |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 469 | ** there is no consistency, we will define our own. |
| 470 | */ |
| 471 | int sqliteStrICmp(const char *zLeft, const char *zRight){ |
| 472 | register unsigned char *a, *b; |
| 473 | a = (unsigned char *)zLeft; |
| 474 | b = (unsigned char *)zRight; |
| 475 | while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } |
| 476 | return *a - *b; |
| 477 | } |
| 478 | int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){ |
| 479 | register unsigned char *a, *b; |
| 480 | a = (unsigned char *)zLeft; |
| 481 | b = (unsigned char *)zRight; |
| 482 | while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } |
drh | bec2bf4 | 2000-05-29 23:48:22 +0000 | [diff] [blame] | 483 | return N<0 ? 0 : *a - *b; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 484 | } |
| 485 | |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 486 | #if 0 /* NOT USED */ |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 487 | /* |
| 488 | ** The sortStrCmp() function below is used to order elements according |
| 489 | ** to the ORDER BY clause of a SELECT. The sort order is a little different |
| 490 | ** from what one might expect. This note attempts to describe what is |
| 491 | ** going on. |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 492 | ** |
| 493 | ** We want the main string comparision function used for sorting to |
| 494 | ** sort both numbers and alphanumeric words into the correct sequence. |
| 495 | ** The same routine should do both without prior knowledge of which |
| 496 | ** type of text the input represents. It should even work for strings |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 497 | ** which are a mixture of text and numbers. (It does not work for |
| 498 | ** numeric substrings in exponential notation, however.) |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 499 | ** |
| 500 | ** To accomplish this, we keep track of a state number while scanning |
| 501 | ** the two strings. The states are as follows: |
| 502 | ** |
| 503 | ** 1 Beginning of word |
| 504 | ** 2 Arbitrary text |
| 505 | ** 3 Integer |
| 506 | ** 4 Negative integer |
| 507 | ** 5 Real number |
| 508 | ** 6 Negative real |
| 509 | ** |
| 510 | ** The scan begins in state 1, beginning of word. Transitions to other |
| 511 | ** states are determined by characters seen, as shown in the following |
| 512 | ** chart: |
| 513 | ** |
| 514 | ** Current State Character Seen New State |
| 515 | ** -------------------- -------------- ------------------- |
| 516 | ** 0 Beginning of word "-" 3 Negative integer |
| 517 | ** digit 2 Integer |
| 518 | ** space 0 Beginning of word |
| 519 | ** otherwise 1 Arbitrary text |
| 520 | ** |
| 521 | ** 1 Arbitrary text space 0 Beginning of word |
| 522 | ** digit 2 Integer |
| 523 | ** otherwise 1 Arbitrary text |
| 524 | ** |
| 525 | ** 2 Integer space 0 Beginning of word |
| 526 | ** "." 4 Real number |
| 527 | ** digit 2 Integer |
| 528 | ** otherwise 1 Arbitrary text |
| 529 | ** |
| 530 | ** 3 Negative integer space 0 Beginning of word |
| 531 | ** "." 5 Negative Real num |
| 532 | ** digit 3 Negative integer |
| 533 | ** otherwise 1 Arbitrary text |
| 534 | ** |
| 535 | ** 4 Real number space 0 Beginning of word |
| 536 | ** digit 4 Real number |
| 537 | ** otherwise 1 Arbitrary text |
| 538 | ** |
| 539 | ** 5 Negative real num space 0 Beginning of word |
| 540 | ** digit 5 Negative real num |
| 541 | ** otherwise 1 Arbitrary text |
| 542 | ** |
| 543 | ** To implement this state machine, we first classify each character |
| 544 | ** into on of the following categories: |
| 545 | ** |
| 546 | ** 0 Text |
| 547 | ** 1 Space |
| 548 | ** 2 Digit |
| 549 | ** 3 "-" |
| 550 | ** 4 "." |
| 551 | ** |
| 552 | ** Given an arbitrary character, the array charClass[] maps that character |
| 553 | ** into one of the atove categories. |
| 554 | */ |
| 555 | static const unsigned char charClass[] = { |
| 556 | /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ |
| 557 | /* 0x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, |
| 558 | /* 1x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 559 | /* 2x */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, |
| 560 | /* 3x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, |
| 561 | /* 4x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 562 | /* 5x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 563 | /* 6x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 564 | /* 7x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 565 | /* 8x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 566 | /* 9x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 567 | /* Ax */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 568 | /* Bx */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 569 | /* Cx */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 570 | /* Dx */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 571 | /* Ex */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 572 | /* Fx */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 573 | }; |
| 574 | #define N_CHAR_CLASS 5 |
| 575 | |
| 576 | /* |
| 577 | ** Given the current state number (0 thru 5), this array figures |
| 578 | ** the new state number given the character class. |
| 579 | */ |
| 580 | static const unsigned char stateMachine[] = { |
| 581 | /* Text, Space, Digit, "-", "." */ |
| 582 | 1, 0, 2, 3, 1, /* State 0: Beginning of word */ |
| 583 | 1, 0, 2, 1, 1, /* State 1: Arbitrary text */ |
| 584 | 1, 0, 2, 1, 4, /* State 2: Integer */ |
| 585 | 1, 0, 3, 1, 5, /* State 3: Negative integer */ |
| 586 | 1, 0, 4, 1, 1, /* State 4: Real number */ |
| 587 | 1, 0, 5, 1, 1, /* State 5: Negative real num */ |
| 588 | }; |
| 589 | |
| 590 | /* This routine does a comparison of two strings. Case is used only |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 591 | ** if useCase!=0. Numeric substrings compare in numerical order for the |
| 592 | ** most part but this routine does not understand exponential notation. |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 593 | */ |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 594 | static int sortStrCmp(const char *atext, const char *btext, int useCase){ |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 595 | register unsigned char *a, *b, *map, ca, cb; |
| 596 | int result; |
| 597 | register int cclass = 0; |
| 598 | |
| 599 | a = (unsigned char *)atext; |
| 600 | b = (unsigned char *)btext; |
| 601 | if( useCase ){ |
| 602 | do{ |
| 603 | if( (ca= *a++)!=(cb= *b++) ) break; |
| 604 | cclass = stateMachine[cclass*N_CHAR_CLASS + charClass[ca]]; |
| 605 | }while( ca!=0 ); |
| 606 | }else{ |
| 607 | map = UpperToLower; |
| 608 | do{ |
| 609 | if( (ca=map[*a++])!=(cb=map[*b++]) ) break; |
| 610 | cclass = stateMachine[cclass*N_CHAR_CLASS + charClass[ca]]; |
| 611 | }while( ca!=0 ); |
drh | 9208643 | 2002-01-22 14:11:29 +0000 | [diff] [blame] | 612 | if( ca>='[' && ca<='`' ) cb = b[-1]; |
| 613 | if( cb>='[' && cb<='`' ) ca = a[-1]; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 614 | } |
| 615 | switch( cclass ){ |
| 616 | case 0: |
| 617 | case 1: { |
| 618 | if( isdigit(ca) && isdigit(cb) ){ |
| 619 | cclass = 2; |
| 620 | } |
| 621 | break; |
| 622 | } |
| 623 | default: { |
| 624 | break; |
| 625 | } |
| 626 | } |
| 627 | switch( cclass ){ |
| 628 | case 2: |
| 629 | case 3: { |
| 630 | if( isdigit(ca) ){ |
| 631 | if( isdigit(cb) ){ |
| 632 | int acnt, bcnt; |
| 633 | acnt = bcnt = 0; |
| 634 | while( isdigit(*a++) ) acnt++; |
| 635 | while( isdigit(*b++) ) bcnt++; |
| 636 | result = acnt - bcnt; |
| 637 | if( result==0 ) result = ca-cb; |
| 638 | }else{ |
| 639 | result = 1; |
| 640 | } |
| 641 | }else if( isdigit(cb) ){ |
| 642 | result = -1; |
| 643 | }else if( ca=='.' ){ |
| 644 | result = 1; |
| 645 | }else if( cb=='.' ){ |
| 646 | result = -1; |
| 647 | }else{ |
| 648 | result = ca - cb; |
| 649 | cclass = 2; |
| 650 | } |
| 651 | if( cclass==3 ) result = -result; |
| 652 | break; |
| 653 | } |
| 654 | case 0: |
| 655 | case 1: |
| 656 | case 4: { |
| 657 | result = ca - cb; |
| 658 | break; |
| 659 | } |
| 660 | case 5: { |
| 661 | result = cb - ca; |
| 662 | }; |
| 663 | } |
| 664 | return result; |
| 665 | } |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 666 | #endif /* NOT USED */ |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 667 | |
drh | a5c2ad0 | 2000-09-14 01:21:10 +0000 | [diff] [blame] | 668 | /* |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 669 | ** Return TRUE if z is a pure numeric string. Return FALSE if the |
| 670 | ** string contains any character which is not part of a number. |
| 671 | ** |
| 672 | ** Am empty string is considered numeric. |
drh | a5c2ad0 | 2000-09-14 01:21:10 +0000 | [diff] [blame] | 673 | */ |
drh | e684090 | 2002-03-06 03:08:25 +0000 | [diff] [blame] | 674 | static int sqliteIsNumber(const char *z){ |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 675 | if( *z=='-' || *z=='+' ) z++; |
| 676 | if( !isdigit(*z) ){ |
| 677 | return *z==0; |
drh | a5c2ad0 | 2000-09-14 01:21:10 +0000 | [diff] [blame] | 678 | } |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 679 | z++; |
| 680 | while( isdigit(*z) ){ z++; } |
| 681 | if( *z=='.' ){ |
| 682 | z++; |
| 683 | if( !isdigit(*z) ) return 0; |
| 684 | while( isdigit(*z) ){ z++; } |
| 685 | if( *z=='e' || *z=='E' ){ |
| 686 | z++; |
| 687 | if( *z=='+' || *z=='-' ) z++; |
| 688 | if( !isdigit(*z) ) return 0; |
| 689 | while( isdigit(*z) ){ z++; } |
| 690 | } |
drh | a5c2ad0 | 2000-09-14 01:21:10 +0000 | [diff] [blame] | 691 | } |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 692 | return *z==0; |
drh | a5c2ad0 | 2000-09-14 01:21:10 +0000 | [diff] [blame] | 693 | } |
| 694 | |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 695 | /* This comparison routine is what we use for comparison operations |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 696 | ** between numeric values in an SQL expression. "Numeric" is a little |
| 697 | ** bit misleading here. What we mean is that the strings have a |
| 698 | ** type of "numeric" from the point of view of SQL. The strings |
| 699 | ** do not necessarily contain numbers. They could contain text. |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 700 | ** |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 701 | ** If the input strings both look like actual numbers then they |
| 702 | ** compare in numerical order. Numerical strings are always less |
| 703 | ** than non-numeric strings so if one input string looks like a |
| 704 | ** number and the other does not, then the one that looks like |
| 705 | ** a number is the smaller. Non-numeric strings compare in |
| 706 | ** lexigraphical order (the same order as strcmp()). |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 707 | */ |
| 708 | int sqliteCompare(const char *atext, const char *btext){ |
| 709 | int result; |
drh | 0bce835 | 2002-02-28 00:41:10 +0000 | [diff] [blame] | 710 | int isNumA, isNumB; |
| 711 | if( atext==0 ){ |
drh | 8912d10 | 2002-05-26 21:34:58 +0000 | [diff] [blame] | 712 | return -1; |
drh | 0bce835 | 2002-02-28 00:41:10 +0000 | [diff] [blame] | 713 | }else if( btext==0 ){ |
| 714 | return 1; |
| 715 | } |
drh | e684090 | 2002-03-06 03:08:25 +0000 | [diff] [blame] | 716 | isNumA = sqliteIsNumber(atext); |
| 717 | isNumB = sqliteIsNumber(btext); |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 718 | if( isNumA ){ |
| 719 | if( !isNumB ){ |
| 720 | result = -1; |
| 721 | }else{ |
| 722 | double rA, rB; |
| 723 | rA = atof(atext); |
| 724 | rB = atof(btext); |
| 725 | if( rA<rB ){ |
| 726 | result = -1; |
| 727 | }else if( rA>rB ){ |
| 728 | result = +1; |
| 729 | }else{ |
| 730 | result = 0; |
drh | a5c2ad0 | 2000-09-14 01:21:10 +0000 | [diff] [blame] | 731 | } |
| 732 | } |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 733 | }else if( isNumB ){ |
| 734 | result = +1; |
| 735 | }else { |
| 736 | result = strcmp(atext, btext); |
drh | a5c2ad0 | 2000-09-14 01:21:10 +0000 | [diff] [blame] | 737 | } |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 738 | return result; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 739 | } |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 740 | |
| 741 | /* |
drh | 16e5955 | 2000-07-31 11:57:37 +0000 | [diff] [blame] | 742 | ** This routine is used for sorting. Each key is a list of one or more |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 743 | ** null-terminated elements. The list is terminated by two nulls in |
| 744 | ** a row. For example, the following text is a key with three elements |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 745 | ** |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 746 | ** Aone\000Dtwo\000Athree\000\000 |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 747 | ** |
drh | da30d36 | 2002-08-26 19:55:07 +0000 | [diff] [blame] | 748 | ** All elements begin with one of the characters "+-AD" and end with "\000" |
| 749 | ** with zero or more text elements in between. Except, NULL elements |
| 750 | ** consist of the special two-character sequence "N\000". |
| 751 | ** |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 752 | ** Both arguments will have the same number of elements. This routine |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 753 | ** returns negative, zero, or positive if the first argument is less |
| 754 | ** than, equal to, or greater than the first. (Result is a-b). |
| 755 | ** |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 756 | ** Each element begins with one of the characters "+", "-", "A", "D". |
drh | 38640e1 | 2002-07-05 21:42:36 +0000 | [diff] [blame] | 757 | ** This character determines the sort order and collating sequence: |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 758 | ** |
drh | 38640e1 | 2002-07-05 21:42:36 +0000 | [diff] [blame] | 759 | ** + Sort numerically in ascending order |
| 760 | ** - Sort numerically in descending order |
| 761 | ** A Sort as strings in ascending order |
| 762 | ** D Sort as strings in descending order. |
| 763 | ** |
| 764 | ** For the "+" and "-" sorting, pure numeric strings (strings for which the |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 765 | ** isNum() function above returns TRUE) always compare less than strings |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 766 | ** that are not pure numerics. Non-numeric strings compare in memcmp() |
| 767 | ** order. This is the same sort order as the sqliteCompare() function |
| 768 | ** above generates. |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 769 | ** |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 770 | ** The last point is a change from version 2.6.3 to version 2.7.0. In |
| 771 | ** version 2.6.3 and earlier, substrings of digits compare in numerical |
| 772 | ** and case was used only to break a tie. |
| 773 | ** |
| 774 | ** Elements that begin with 'A' or 'D' compare in memcmp() order regardless |
| 775 | ** of whether or not they look like a number. |
| 776 | ** |
| 777 | ** Note that the sort order imposed by the rules above is the same |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 778 | ** from the ordering defined by the "<", "<=", ">", and ">=" operators |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 779 | ** of expressions and for indices. This was not the case for version |
| 780 | ** 2.6.3 and earlier. |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 781 | */ |
| 782 | int sqliteSortCompare(const char *a, const char *b){ |
| 783 | int len; |
| 784 | int res = 0; |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 785 | int isNumA, isNumB; |
drh | 294fb92 | 2002-09-30 01:31:21 +0000 | [diff] [blame] | 786 | int dir = 0; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 787 | |
| 788 | while( res==0 && *a && *b ){ |
drh | da30d36 | 2002-08-26 19:55:07 +0000 | [diff] [blame] | 789 | if( a[0]=='N' || b[0]=='N' ){ |
| 790 | if( a[0]==b[0] ){ |
| 791 | a += 2; |
| 792 | b += 2; |
| 793 | continue; |
| 794 | } |
| 795 | if( a[0]=='N' ){ |
| 796 | dir = b[0]; |
| 797 | res = -1; |
| 798 | }else{ |
| 799 | dir = a[0]; |
| 800 | res = +1; |
| 801 | } |
drh | f570f01 | 2002-05-31 15:51:25 +0000 | [diff] [blame] | 802 | break; |
| 803 | } |
drh | da30d36 | 2002-08-26 19:55:07 +0000 | [diff] [blame] | 804 | assert( a[0]==b[0] ); |
| 805 | if( (dir=a[0])=='A' || a[0]=='D' ){ |
drh | 38640e1 | 2002-07-05 21:42:36 +0000 | [diff] [blame] | 806 | res = strcmp(&a[1],&b[1]); |
| 807 | if( res ) break; |
| 808 | }else{ |
| 809 | isNumA = sqliteIsNumber(&a[1]); |
| 810 | isNumB = sqliteIsNumber(&b[1]); |
| 811 | if( isNumA ){ |
| 812 | double rA, rB; |
| 813 | if( !isNumB ){ |
| 814 | res = -1; |
| 815 | break; |
| 816 | } |
| 817 | rA = atof(&a[1]); |
| 818 | rB = atof(&b[1]); |
| 819 | if( rA<rB ){ |
| 820 | res = -1; |
| 821 | break; |
| 822 | } |
| 823 | if( rA>rB ){ |
| 824 | res = +1; |
| 825 | break; |
| 826 | } |
| 827 | }else if( isNumB ){ |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 828 | res = +1; |
| 829 | break; |
drh | 38640e1 | 2002-07-05 21:42:36 +0000 | [diff] [blame] | 830 | }else{ |
drh | a9e99ae | 2002-08-13 23:02:57 +0000 | [diff] [blame] | 831 | res = strcmp(&a[1],&b[1]); |
| 832 | if( res ) break; |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 833 | } |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 834 | } |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 835 | len = strlen(&a[1]) + 2; |
| 836 | a += len; |
| 837 | b += len; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 838 | } |
drh | da30d36 | 2002-08-26 19:55:07 +0000 | [diff] [blame] | 839 | if( dir=='-' || dir=='D' ) res = -res; |
drh | 7589723 | 2000-05-29 14:26:00 +0000 | [diff] [blame] | 840 | return res; |
| 841 | } |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 842 | |
drh | 9bbca4c | 2001-11-06 04:00:18 +0000 | [diff] [blame] | 843 | /* |
drh | 7a7c739 | 2001-11-24 00:31:46 +0000 | [diff] [blame] | 844 | ** Some powers of 64. These constants are needed in the |
| 845 | ** sqliteRealToSortable() routine below. |
drh | 9bbca4c | 2001-11-06 04:00:18 +0000 | [diff] [blame] | 846 | */ |
| 847 | #define _64e3 (64.0 * 64.0 * 64.0) |
| 848 | #define _64e4 (64.0 * 64.0 * 64.0 * 64.0) |
| 849 | #define _64e15 (_64e3 * _64e4 * _64e4 * _64e4) |
| 850 | #define _64e16 (_64e4 * _64e4 * _64e4 * _64e4) |
| 851 | #define _64e63 (_64e15 * _64e16 * _64e16 * _64e16) |
| 852 | #define _64e64 (_64e16 * _64e16 * _64e16 * _64e16) |
| 853 | |
| 854 | /* |
| 855 | ** The following procedure converts a double-precision floating point |
| 856 | ** number into a string. The resulting string has the property that |
| 857 | ** two such strings comparied using strcmp() or memcmp() will give the |
drh | 5a2c2c2 | 2001-11-21 02:21:11 +0000 | [diff] [blame] | 858 | ** same results as a numeric comparison of the original floating point |
| 859 | ** numbers. |
drh | 9bbca4c | 2001-11-06 04:00:18 +0000 | [diff] [blame] | 860 | ** |
| 861 | ** This routine is used to generate database keys from floating point |
| 862 | ** numbers such that the keys sort in the same order as the original |
| 863 | ** floating point numbers even though the keys are compared using |
| 864 | ** memcmp(). |
| 865 | ** |
| 866 | ** The calling function should have allocated at least 14 characters |
| 867 | ** of space for the buffer z[]. |
| 868 | */ |
| 869 | void sqliteRealToSortable(double r, char *z){ |
| 870 | int neg; |
| 871 | int exp; |
| 872 | int cnt = 0; |
| 873 | |
| 874 | /* This array maps integers between 0 and 63 into base-64 digits. |
| 875 | ** The digits must be chosen such at their ASCII codes are increasing. |
| 876 | ** This means we can not use the traditional base-64 digit set. */ |
| 877 | static const char zDigit[] = |
| 878 | "0123456789" |
| 879 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 880 | "abcdefghijklmnopqrstuvwxyz" |
| 881 | "|~"; |
| 882 | if( r<0.0 ){ |
| 883 | neg = 1; |
| 884 | r = -r; |
| 885 | *z++ = '-'; |
| 886 | } else { |
| 887 | neg = 0; |
| 888 | *z++ = '0'; |
| 889 | } |
| 890 | exp = 0; |
| 891 | |
| 892 | if( r==0.0 ){ |
| 893 | exp = -1024; |
| 894 | }else if( r<(0.5/64.0) ){ |
| 895 | while( r < 0.5/_64e64 && exp > -961 ){ r *= _64e64; exp -= 64; } |
| 896 | while( r < 0.5/_64e16 && exp > -1009 ){ r *= _64e16; exp -= 16; } |
| 897 | while( r < 0.5/_64e4 && exp > -1021 ){ r *= _64e4; exp -= 4; } |
| 898 | while( r < 0.5/64.0 && exp > -1024 ){ r *= 64.0; exp -= 1; } |
| 899 | }else if( r>=0.5 ){ |
| 900 | while( r >= 0.5*_64e63 && exp < 960 ){ r *= 1.0/_64e64; exp += 64; } |
| 901 | while( r >= 0.5*_64e15 && exp < 1008 ){ r *= 1.0/_64e16; exp += 16; } |
| 902 | while( r >= 0.5*_64e3 && exp < 1020 ){ r *= 1.0/_64e4; exp += 4; } |
| 903 | while( r >= 0.5 && exp < 1023 ){ r *= 1.0/64.0; exp += 1; } |
| 904 | } |
| 905 | if( neg ){ |
| 906 | exp = -exp; |
| 907 | r = -r; |
| 908 | } |
| 909 | exp += 1024; |
| 910 | r += 0.5; |
| 911 | if( exp<0 ) return; |
| 912 | if( exp>=2048 || r>=1.0 ){ |
| 913 | strcpy(z, "~~~~~~~~~~~~"); |
| 914 | return; |
| 915 | } |
| 916 | *z++ = zDigit[(exp>>6)&0x3f]; |
| 917 | *z++ = zDigit[exp & 0x3f]; |
| 918 | while( r>0.0 && cnt<10 ){ |
| 919 | int digit; |
| 920 | r *= 64.0; |
drh | 1ab4300 | 2002-01-14 09:28:19 +0000 | [diff] [blame] | 921 | digit = (int)r; |
drh | 9bbca4c | 2001-11-06 04:00:18 +0000 | [diff] [blame] | 922 | assert( digit>=0 && digit<64 ); |
| 923 | *z++ = zDigit[digit & 0x3f]; |
| 924 | r -= digit; |
| 925 | cnt++; |
| 926 | } |
| 927 | *z = 0; |
| 928 | } |
| 929 | |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 930 | #ifdef SQLITE_UTF8 |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 931 | /* |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 932 | ** X is a pointer to the first byte of a UTF-8 character. Increment |
| 933 | ** X so that it points to the next character. This only works right |
| 934 | ** if X points to a well-formed UTF-8 string. |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 935 | */ |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 936 | #define sqliteNextChar(X) while( (0xc0&*++(X))==0x80 ){} |
| 937 | #define sqliteCharVal(X) sqlite_utf8_to_int(X) |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 938 | |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 939 | #else /* !defined(SQLITE_UTF8) */ |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 940 | /* |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 941 | ** For iso8859 encoding, the next character is just the next byte. |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 942 | */ |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 943 | #define sqliteNextChar(X) (++(X)); |
| 944 | #define sqliteCharVal(X) ((int)*(X)) |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 945 | |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 946 | #endif /* defined(SQLITE_UTF8) */ |
| 947 | |
| 948 | |
| 949 | #ifdef SQLITE_UTF8 |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 950 | /* |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 951 | ** Convert the UTF-8 character to which z points into a 31-bit |
| 952 | ** UCS character. This only works right if z points to a well-formed |
| 953 | ** UTF-8 string. |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 954 | */ |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 955 | static int sqlite_utf8_to_int(const unsigned char *z){ |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 956 | int c; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 957 | static const int initVal[] = { |
| 958 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
| 959 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, |
| 960 | 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, |
| 961 | 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, |
| 962 | 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, |
| 963 | 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, |
| 964 | 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, |
| 965 | 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, |
| 966 | 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, |
| 967 | 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, |
| 968 | 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, |
| 969 | 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, |
| 970 | 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 0, 1, 2, |
| 971 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, |
| 972 | 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, |
| 973 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
| 974 | 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 254, |
| 975 | 255, |
| 976 | }; |
| 977 | c = initVal[*(z++)]; |
| 978 | while( (0xc0&*z)==0x80 ){ |
| 979 | c = (c<<6) | (0x3f&*(z++)); |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 980 | } |
| 981 | return c; |
| 982 | } |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 983 | #endif |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 984 | |
| 985 | /* |
| 986 | ** Compare two UTF-8 strings for equality where the first string can |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 987 | ** potentially be a "glob" expression. Return true (1) if they |
| 988 | ** are the same and false (0) if they are different. |
| 989 | ** |
| 990 | ** Globbing rules: |
| 991 | ** |
| 992 | ** '*' Matches any sequence of zero or more characters. |
| 993 | ** |
| 994 | ** '?' Matches exactly one character. |
| 995 | ** |
| 996 | ** [...] Matches one character from the enclosed list of |
| 997 | ** characters. |
| 998 | ** |
| 999 | ** [^...] Matches one character not in the enclosed list. |
| 1000 | ** |
| 1001 | ** With the [...] and [^...] matching, a ']' character can be included |
| 1002 | ** in the list by making it the first character after '[' or '^'. A |
| 1003 | ** range of characters can be specified using '-'. Example: |
| 1004 | ** "[a-z]" matches any single lower-case letter. To match a '-', make |
| 1005 | ** it the last character in the list. |
| 1006 | ** |
| 1007 | ** This routine is usually quick, but can be N**2 in the worst case. |
| 1008 | ** |
| 1009 | ** Hints: to match '*' or '?', put them in "[]". Like this: |
| 1010 | ** |
| 1011 | ** abc[*]xyz Matches "abc*xyz" only |
| 1012 | */ |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1013 | int |
| 1014 | sqliteGlobCompare(const unsigned char *zPattern, const unsigned char *zString){ |
| 1015 | register int c; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1016 | int invert; |
| 1017 | int seen; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1018 | int c2; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1019 | |
| 1020 | while( (c = *zPattern)!=0 ){ |
| 1021 | switch( c ){ |
| 1022 | case '*': |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1023 | while( (c=zPattern[1]) == '*' || c == '?' ){ |
| 1024 | if( c=='?' ){ |
| 1025 | if( *zString==0 ) return 0; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1026 | sqliteNextChar(zString); |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1027 | } |
| 1028 | zPattern++; |
| 1029 | } |
| 1030 | if( c==0 ) return 1; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1031 | if( c=='[' ){ |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1032 | while( *zString && sqliteGlobCompare(&zPattern[1],zString)==0 ){ |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1033 | sqliteNextChar(zString); |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1034 | } |
| 1035 | return *zString!=0; |
| 1036 | }else{ |
| 1037 | while( (c2 = *zString)!=0 ){ |
| 1038 | while( c2 != 0 && c2 != c ){ c2 = *++zString; } |
drh | c61053b | 2000-06-04 12:58:36 +0000 | [diff] [blame] | 1039 | if( c2==0 ) return 0; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1040 | if( sqliteGlobCompare(&zPattern[1],zString) ) return 1; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1041 | sqliteNextChar(zString); |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1042 | } |
| 1043 | return 0; |
| 1044 | } |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1045 | case '?': { |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1046 | if( *zString==0 ) return 0; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1047 | sqliteNextChar(zString); |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1048 | zPattern++; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1049 | break; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1050 | } |
| 1051 | case '[': { |
| 1052 | int prior_c = 0; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1053 | seen = 0; |
| 1054 | invert = 0; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1055 | c = sqliteCharVal(zString); |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1056 | if( c==0 ) return 0; |
| 1057 | c2 = *++zPattern; |
| 1058 | if( c2=='^' ){ invert = 1; c2 = *++zPattern; } |
| 1059 | if( c2==']' ){ |
| 1060 | if( c==']' ) seen = 1; |
| 1061 | c2 = *++zPattern; |
| 1062 | } |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1063 | while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){ |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1064 | if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){ |
| 1065 | zPattern++; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1066 | c2 = sqliteCharVal(zPattern); |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1067 | if( c>=prior_c && c<=c2 ) seen = 1; |
| 1068 | prior_c = 0; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1069 | }else if( c==c2 ){ |
| 1070 | seen = 1; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1071 | prior_c = c2; |
| 1072 | }else{ |
| 1073 | prior_c = c2; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1074 | } |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1075 | sqliteNextChar(zPattern); |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1076 | } |
| 1077 | if( c2==0 || (seen ^ invert)==0 ) return 0; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1078 | sqliteNextChar(zString); |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1079 | zPattern++; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1080 | break; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1081 | } |
| 1082 | default: { |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1083 | if( c != *zString ) return 0; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1084 | zPattern++; |
| 1085 | zString++; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1086 | break; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1087 | } |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1088 | } |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1089 | } |
| 1090 | return *zString==0; |
| 1091 | } |
| 1092 | |
| 1093 | /* |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1094 | ** Compare two UTF-8 strings for equality using the "LIKE" operator of |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1095 | ** SQL. The '%' character matches any sequence of 0 or more |
| 1096 | ** characters and '_' matches any single character. Case is |
| 1097 | ** not significant. |
| 1098 | ** |
| 1099 | ** This routine is just an adaptation of the sqliteGlobCompare() |
| 1100 | ** routine above. |
| 1101 | */ |
| 1102 | int |
| 1103 | sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){ |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1104 | register int c; |
| 1105 | int c2; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1106 | |
| 1107 | while( (c = UpperToLower[*zPattern])!=0 ){ |
| 1108 | switch( c ){ |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1109 | case '%': { |
| 1110 | while( (c=zPattern[1]) == '%' || c == '_' ){ |
| 1111 | if( c=='_' ){ |
| 1112 | if( *zString==0 ) return 0; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1113 | sqliteNextChar(zString); |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1114 | } |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1115 | zPattern++; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1116 | } |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1117 | if( c==0 ) return 1; |
| 1118 | c = UpperToLower[c]; |
| 1119 | while( (c2=UpperToLower[*zString])!=0 ){ |
| 1120 | while( c2 != 0 && c2 != c ){ c2 = UpperToLower[*++zString]; } |
| 1121 | if( c2==0 ) return 0; |
| 1122 | if( sqliteLikeCompare(&zPattern[1],zString) ) return 1; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1123 | sqliteNextChar(zString); |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1124 | } |
| 1125 | return 0; |
| 1126 | } |
| 1127 | case '_': { |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1128 | if( *zString==0 ) return 0; |
drh | 297ecf1 | 2001-04-05 15:57:13 +0000 | [diff] [blame] | 1129 | sqliteNextChar(zString); |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1130 | zPattern++; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1131 | break; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1132 | } |
| 1133 | default: { |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1134 | if( c != UpperToLower[*zString] ) return 0; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1135 | zPattern++; |
| 1136 | zString++; |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1137 | break; |
drh | e17a7e3 | 2001-04-04 21:10:18 +0000 | [diff] [blame] | 1138 | } |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1139 | } |
drh | dce2cbe | 2000-05-31 02:27:49 +0000 | [diff] [blame] | 1140 | } |
| 1141 | return *zString==0; |
| 1142 | } |
drh | 5e00f6c | 2001-09-13 13:46:56 +0000 | [diff] [blame] | 1143 | |
| 1144 | /* |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1145 | ** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY. |
| 1146 | ** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN |
| 1147 | ** when this routine is called. |
| 1148 | ** |
| 1149 | ** This routine is a attempt to detect if two threads use the |
| 1150 | ** same sqlite* pointer at the same time. There is a race |
| 1151 | ** condition so it is possible that the error is not detected. |
| 1152 | ** But usually the problem will be seen. The result will be an |
drh | c27a1ce | 2002-06-14 20:58:45 +0000 | [diff] [blame] | 1153 | ** error which can be used to debug the application that is |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1154 | ** using SQLite incorrectly. |
drh | e7e8bc7 | 2002-12-17 13:05:25 +0000 | [diff] [blame] | 1155 | ** |
| 1156 | ** Ticket #202: If db->magic is not a valid open value, take care not |
| 1157 | ** to modify the db structure at all. It could be that db is a stale |
| 1158 | ** pointer. In other words, it could be that there has been a prior |
| 1159 | ** call to sqlite_close(db) and db has been deallocated. And we do |
| 1160 | ** not want to write into deallocated memory. |
drh | 5e00f6c | 2001-09-13 13:46:56 +0000 | [diff] [blame] | 1161 | */ |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1162 | int sqliteSafetyOn(sqlite *db){ |
| 1163 | if( db->magic==SQLITE_MAGIC_OPEN ){ |
| 1164 | db->magic = SQLITE_MAGIC_BUSY; |
| 1165 | return 0; |
drh | e7e8bc7 | 2002-12-17 13:05:25 +0000 | [diff] [blame] | 1166 | }else if( db->magic==SQLITE_MAGIC_BUSY || db->magic==SQLITE_MAGIC_ERROR ){ |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1167 | db->magic = SQLITE_MAGIC_ERROR; |
| 1168 | db->flags |= SQLITE_Interrupt; |
drh | 5e00f6c | 2001-09-13 13:46:56 +0000 | [diff] [blame] | 1169 | } |
drh | e7e8bc7 | 2002-12-17 13:05:25 +0000 | [diff] [blame] | 1170 | return 1; |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1171 | } |
| 1172 | |
| 1173 | /* |
| 1174 | ** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN. |
| 1175 | ** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY |
| 1176 | ** when this routine is called. |
| 1177 | */ |
| 1178 | int sqliteSafetyOff(sqlite *db){ |
| 1179 | if( db->magic==SQLITE_MAGIC_BUSY ){ |
| 1180 | db->magic = SQLITE_MAGIC_OPEN; |
| 1181 | return 0; |
drh | e7e8bc7 | 2002-12-17 13:05:25 +0000 | [diff] [blame] | 1182 | }else if( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ERROR ){ |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1183 | db->magic = SQLITE_MAGIC_ERROR; |
| 1184 | db->flags |= SQLITE_Interrupt; |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1185 | } |
drh | e7e8bc7 | 2002-12-17 13:05:25 +0000 | [diff] [blame] | 1186 | return 1; |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1187 | } |
| 1188 | |
| 1189 | /* |
| 1190 | ** Check to make sure we are not currently executing an sqlite_exec(). |
| 1191 | ** If we are currently in an sqlite_exec(), return true and set |
| 1192 | ** sqlite.magic to SQLITE_MAGIC_ERROR. This will cause a complete |
| 1193 | ** shutdown of the database. |
| 1194 | ** |
| 1195 | ** This routine is used to try to detect when API routines are called |
| 1196 | ** at the wrong time or in the wrong sequence. |
| 1197 | */ |
| 1198 | int sqliteSafetyCheck(sqlite *db){ |
drh | 326dce7 | 2003-01-29 14:06:07 +0000 | [diff] [blame^] | 1199 | if( db->pVdbe!=0 ){ |
drh | c22bd47 | 2002-05-10 13:14:07 +0000 | [diff] [blame] | 1200 | db->magic = SQLITE_MAGIC_ERROR; |
| 1201 | return 1; |
| 1202 | } |
| 1203 | return 0; |
drh | 5e00f6c | 2001-09-13 13:46:56 +0000 | [diff] [blame] | 1204 | } |