17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate ** 2001 September 15
37c478bd9Sstevel@tonic-gate **
47c478bd9Sstevel@tonic-gate ** The author disclaims copyright to this source code. In place of
57c478bd9Sstevel@tonic-gate ** a legal notice, here is a blessing:
67c478bd9Sstevel@tonic-gate **
77c478bd9Sstevel@tonic-gate ** May you do good and not evil.
87c478bd9Sstevel@tonic-gate ** May you find forgiveness for yourself and forgive others.
97c478bd9Sstevel@tonic-gate ** May you share freely, never taking more than you give.
107c478bd9Sstevel@tonic-gate **
117c478bd9Sstevel@tonic-gate *************************************************************************
127c478bd9Sstevel@tonic-gate ** Utility functions used throughout sqlite.
137c478bd9Sstevel@tonic-gate **
147c478bd9Sstevel@tonic-gate ** This file contains functions for allocating memory, comparing
157c478bd9Sstevel@tonic-gate ** strings, and stuff like that.
167c478bd9Sstevel@tonic-gate **
177c478bd9Sstevel@tonic-gate ** $Id: util.c,v 1.74.2.1 2004/07/15 13:08:41 drh Exp $
187c478bd9Sstevel@tonic-gate */
197c478bd9Sstevel@tonic-gate #include "sqliteInt.h"
207c478bd9Sstevel@tonic-gate #include <stdarg.h>
217c478bd9Sstevel@tonic-gate #include <ctype.h>
227c478bd9Sstevel@tonic-gate
237c478bd9Sstevel@tonic-gate /*
247c478bd9Sstevel@tonic-gate ** If malloc() ever fails, this global variable gets set to 1.
257c478bd9Sstevel@tonic-gate ** This causes the library to abort and never again function.
267c478bd9Sstevel@tonic-gate */
277c478bd9Sstevel@tonic-gate int sqlite_malloc_failed = 0;
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate ** If MEMORY_DEBUG is defined, then use versions of malloc() and
317c478bd9Sstevel@tonic-gate ** free() that track memory usage and check for buffer overruns.
327c478bd9Sstevel@tonic-gate */
337c478bd9Sstevel@tonic-gate #ifdef MEMORY_DEBUG
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate /*
367c478bd9Sstevel@tonic-gate ** For keeping track of the number of mallocs and frees. This
377c478bd9Sstevel@tonic-gate ** is used to check for memory leaks.
387c478bd9Sstevel@tonic-gate */
397c478bd9Sstevel@tonic-gate int sqlite_nMalloc; /* Number of sqliteMalloc() calls */
407c478bd9Sstevel@tonic-gate int sqlite_nFree; /* Number of sqliteFree() calls */
417c478bd9Sstevel@tonic-gate int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */
427c478bd9Sstevel@tonic-gate #if MEMORY_DEBUG>1
437c478bd9Sstevel@tonic-gate static int memcnt = 0;
447c478bd9Sstevel@tonic-gate #endif
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate /*
477c478bd9Sstevel@tonic-gate ** Number of 32-bit guard words
487c478bd9Sstevel@tonic-gate */
497c478bd9Sstevel@tonic-gate #define N_GUARD 1
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate /*
527c478bd9Sstevel@tonic-gate ** Allocate new memory and set it to zero. Return NULL if
537c478bd9Sstevel@tonic-gate ** no memory is available.
547c478bd9Sstevel@tonic-gate */
sqliteMalloc_(int n,int bZero,char * zFile,int line)557c478bd9Sstevel@tonic-gate void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
567c478bd9Sstevel@tonic-gate void *p;
577c478bd9Sstevel@tonic-gate int *pi;
587c478bd9Sstevel@tonic-gate int i, k;
597c478bd9Sstevel@tonic-gate if( sqlite_iMallocFail>=0 ){
607c478bd9Sstevel@tonic-gate sqlite_iMallocFail--;
617c478bd9Sstevel@tonic-gate if( sqlite_iMallocFail==0 ){
627c478bd9Sstevel@tonic-gate sqlite_malloc_failed++;
637c478bd9Sstevel@tonic-gate #if MEMORY_DEBUG>1
647c478bd9Sstevel@tonic-gate fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",
657c478bd9Sstevel@tonic-gate n, zFile,line);
667c478bd9Sstevel@tonic-gate #endif
677c478bd9Sstevel@tonic-gate sqlite_iMallocFail--;
687c478bd9Sstevel@tonic-gate return 0;
697c478bd9Sstevel@tonic-gate }
707c478bd9Sstevel@tonic-gate }
717c478bd9Sstevel@tonic-gate if( n==0 ) return 0;
727c478bd9Sstevel@tonic-gate k = (n+sizeof(int)-1)/sizeof(int);
737c478bd9Sstevel@tonic-gate pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
747c478bd9Sstevel@tonic-gate if( pi==0 ){
757c478bd9Sstevel@tonic-gate sqlite_malloc_failed++;
767c478bd9Sstevel@tonic-gate return 0;
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate sqlite_nMalloc++;
797c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
807c478bd9Sstevel@tonic-gate pi[N_GUARD] = n;
817c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;
827c478bd9Sstevel@tonic-gate p = &pi[N_GUARD+1];
837c478bd9Sstevel@tonic-gate memset(p, bZero==0, n);
847c478bd9Sstevel@tonic-gate #if MEMORY_DEBUG>1
857c478bd9Sstevel@tonic-gate fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",
867c478bd9Sstevel@tonic-gate ++memcnt, n, (int)p, zFile,line);
877c478bd9Sstevel@tonic-gate #endif
887c478bd9Sstevel@tonic-gate return p;
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate /*
927c478bd9Sstevel@tonic-gate ** Check to see if the given pointer was obtained from sqliteMalloc()
937c478bd9Sstevel@tonic-gate ** and is able to hold at least N bytes. Raise an exception if this
947c478bd9Sstevel@tonic-gate ** is not the case.
957c478bd9Sstevel@tonic-gate **
967c478bd9Sstevel@tonic-gate ** This routine is used for testing purposes only.
977c478bd9Sstevel@tonic-gate */
sqliteCheckMemory(void * p,int N)987c478bd9Sstevel@tonic-gate void sqliteCheckMemory(void *p, int N){
997c478bd9Sstevel@tonic-gate int *pi = p;
1007c478bd9Sstevel@tonic-gate int n, i, k;
1017c478bd9Sstevel@tonic-gate pi -= N_GUARD+1;
1027c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++){
1037c478bd9Sstevel@tonic-gate assert( pi[i]==0xdead1122 );
1047c478bd9Sstevel@tonic-gate }
1057c478bd9Sstevel@tonic-gate n = pi[N_GUARD];
1067c478bd9Sstevel@tonic-gate assert( N>=0 && N<n );
1077c478bd9Sstevel@tonic-gate k = (n+sizeof(int)-1)/sizeof(int);
1087c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++){
1097c478bd9Sstevel@tonic-gate assert( pi[k+N_GUARD+1+i]==0xdead3344 );
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate /*
1147c478bd9Sstevel@tonic-gate ** Free memory previously obtained from sqliteMalloc()
1157c478bd9Sstevel@tonic-gate */
sqliteFree_(void * p,char * zFile,int line)1167c478bd9Sstevel@tonic-gate void sqliteFree_(void *p, char *zFile, int line){
1177c478bd9Sstevel@tonic-gate if( p ){
1187c478bd9Sstevel@tonic-gate int *pi, i, k, n;
1197c478bd9Sstevel@tonic-gate pi = p;
1207c478bd9Sstevel@tonic-gate pi -= N_GUARD+1;
1217c478bd9Sstevel@tonic-gate sqlite_nFree++;
1227c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++){
1237c478bd9Sstevel@tonic-gate if( pi[i]!=0xdead1122 ){
1247c478bd9Sstevel@tonic-gate fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
1257c478bd9Sstevel@tonic-gate return;
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate n = pi[N_GUARD];
1297c478bd9Sstevel@tonic-gate k = (n+sizeof(int)-1)/sizeof(int);
1307c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++){
1317c478bd9Sstevel@tonic-gate if( pi[k+N_GUARD+1+i]!=0xdead3344 ){
1327c478bd9Sstevel@tonic-gate fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
1337c478bd9Sstevel@tonic-gate return;
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate }
1367c478bd9Sstevel@tonic-gate memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));
1377c478bd9Sstevel@tonic-gate #if MEMORY_DEBUG>1
1387c478bd9Sstevel@tonic-gate fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",
1397c478bd9Sstevel@tonic-gate ++memcnt, n, (int)p, zFile,line);
1407c478bd9Sstevel@tonic-gate #endif
1417c478bd9Sstevel@tonic-gate free(pi);
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate /*
1467c478bd9Sstevel@tonic-gate ** Resize a prior allocation. If p==0, then this routine
1477c478bd9Sstevel@tonic-gate ** works just like sqliteMalloc(). If n==0, then this routine
1487c478bd9Sstevel@tonic-gate ** works just like sqliteFree().
1497c478bd9Sstevel@tonic-gate */
sqliteRealloc_(void * oldP,int n,char * zFile,int line)1507c478bd9Sstevel@tonic-gate void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
1517c478bd9Sstevel@tonic-gate int *oldPi, *pi, i, k, oldN, oldK;
1527c478bd9Sstevel@tonic-gate void *p;
1537c478bd9Sstevel@tonic-gate if( oldP==0 ){
1547c478bd9Sstevel@tonic-gate return sqliteMalloc_(n,1,zFile,line);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate if( n==0 ){
1577c478bd9Sstevel@tonic-gate sqliteFree_(oldP,zFile,line);
1587c478bd9Sstevel@tonic-gate return 0;
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate oldPi = oldP;
1617c478bd9Sstevel@tonic-gate oldPi -= N_GUARD+1;
1627c478bd9Sstevel@tonic-gate if( oldPi[0]!=0xdead1122 ){
1637c478bd9Sstevel@tonic-gate fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)oldP);
1647c478bd9Sstevel@tonic-gate return 0;
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate oldN = oldPi[N_GUARD];
1677c478bd9Sstevel@tonic-gate oldK = (oldN+sizeof(int)-1)/sizeof(int);
1687c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++){
1697c478bd9Sstevel@tonic-gate if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){
1707c478bd9Sstevel@tonic-gate fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n",
1717c478bd9Sstevel@tonic-gate (int)oldP);
1727c478bd9Sstevel@tonic-gate return 0;
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate k = (n + sizeof(int) - 1)/sizeof(int);
1767c478bd9Sstevel@tonic-gate pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
1777c478bd9Sstevel@tonic-gate if( pi==0 ){
1787c478bd9Sstevel@tonic-gate sqlite_malloc_failed++;
1797c478bd9Sstevel@tonic-gate return 0;
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
1827c478bd9Sstevel@tonic-gate pi[N_GUARD] = n;
1837c478bd9Sstevel@tonic-gate for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;
1847c478bd9Sstevel@tonic-gate p = &pi[N_GUARD+1];
1857c478bd9Sstevel@tonic-gate memcpy(p, oldP, n>oldN ? oldN : n);
1867c478bd9Sstevel@tonic-gate if( n>oldN ){
1877c478bd9Sstevel@tonic-gate memset(&((char*)p)[oldN], 0, n-oldN);
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));
1907c478bd9Sstevel@tonic-gate free(oldPi);
1917c478bd9Sstevel@tonic-gate #if MEMORY_DEBUG>1
1927c478bd9Sstevel@tonic-gate fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",
1937c478bd9Sstevel@tonic-gate ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line);
1947c478bd9Sstevel@tonic-gate #endif
1957c478bd9Sstevel@tonic-gate return p;
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate /*
1997c478bd9Sstevel@tonic-gate ** Make a duplicate of a string into memory obtained from malloc()
2007c478bd9Sstevel@tonic-gate ** Free the original string using sqliteFree().
2017c478bd9Sstevel@tonic-gate **
2027c478bd9Sstevel@tonic-gate ** This routine is called on all strings that are passed outside of
2037c478bd9Sstevel@tonic-gate ** the SQLite library. That way clients can free the string using free()
2047c478bd9Sstevel@tonic-gate ** rather than having to call sqliteFree().
2057c478bd9Sstevel@tonic-gate */
sqliteStrRealloc(char ** pz)2067c478bd9Sstevel@tonic-gate void sqliteStrRealloc(char **pz){
2077c478bd9Sstevel@tonic-gate char *zNew;
2087c478bd9Sstevel@tonic-gate if( pz==0 || *pz==0 ) return;
2097c478bd9Sstevel@tonic-gate zNew = malloc( strlen(*pz) + 1 );
2107c478bd9Sstevel@tonic-gate if( zNew==0 ){
2117c478bd9Sstevel@tonic-gate sqlite_malloc_failed++;
2127c478bd9Sstevel@tonic-gate sqliteFree(*pz);
2137c478bd9Sstevel@tonic-gate *pz = 0;
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate strcpy(zNew, *pz);
2167c478bd9Sstevel@tonic-gate sqliteFree(*pz);
2177c478bd9Sstevel@tonic-gate *pz = zNew;
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate /*
2217c478bd9Sstevel@tonic-gate ** Make a copy of a string in memory obtained from sqliteMalloc()
2227c478bd9Sstevel@tonic-gate */
sqliteStrDup_(const char * z,char * zFile,int line)2237c478bd9Sstevel@tonic-gate char *sqliteStrDup_(const char *z, char *zFile, int line){
2247c478bd9Sstevel@tonic-gate char *zNew;
2257c478bd9Sstevel@tonic-gate if( z==0 ) return 0;
2267c478bd9Sstevel@tonic-gate zNew = sqliteMalloc_(strlen(z)+1, 0, zFile, line);
2277c478bd9Sstevel@tonic-gate if( zNew ) strcpy(zNew, z);
2287c478bd9Sstevel@tonic-gate return zNew;
2297c478bd9Sstevel@tonic-gate }
sqliteStrNDup_(const char * z,int n,char * zFile,int line)2307c478bd9Sstevel@tonic-gate char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){
2317c478bd9Sstevel@tonic-gate char *zNew;
2327c478bd9Sstevel@tonic-gate if( z==0 ) return 0;
2337c478bd9Sstevel@tonic-gate zNew = sqliteMalloc_(n+1, 0, zFile, line);
2347c478bd9Sstevel@tonic-gate if( zNew ){
2357c478bd9Sstevel@tonic-gate memcpy(zNew, z, n);
2367c478bd9Sstevel@tonic-gate zNew[n] = 0;
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate return zNew;
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate #endif /* MEMORY_DEBUG */
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate /*
2437c478bd9Sstevel@tonic-gate ** The following versions of malloc() and free() are for use in a
2447c478bd9Sstevel@tonic-gate ** normal build.
2457c478bd9Sstevel@tonic-gate */
2467c478bd9Sstevel@tonic-gate #if !defined(MEMORY_DEBUG)
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate /*
2497c478bd9Sstevel@tonic-gate ** Allocate new memory and set it to zero. Return NULL if
2507c478bd9Sstevel@tonic-gate ** no memory is available. See also sqliteMallocRaw().
2517c478bd9Sstevel@tonic-gate */
sqliteMalloc(int n)2527c478bd9Sstevel@tonic-gate void *sqliteMalloc(int n){
2537c478bd9Sstevel@tonic-gate void *p;
2547c478bd9Sstevel@tonic-gate if( (p = malloc(n))==0 ){
2557c478bd9Sstevel@tonic-gate if( n>0 ) sqlite_malloc_failed++;
2567c478bd9Sstevel@tonic-gate }else{
2577c478bd9Sstevel@tonic-gate memset(p, 0, n);
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate return p;
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate /*
2637c478bd9Sstevel@tonic-gate ** Allocate new memory but do not set it to zero. Return NULL if
2647c478bd9Sstevel@tonic-gate ** no memory is available. See also sqliteMalloc().
2657c478bd9Sstevel@tonic-gate */
sqliteMallocRaw(int n)2667c478bd9Sstevel@tonic-gate void *sqliteMallocRaw(int n){
2677c478bd9Sstevel@tonic-gate void *p;
2687c478bd9Sstevel@tonic-gate if( (p = malloc(n))==0 ){
2697c478bd9Sstevel@tonic-gate if( n>0 ) sqlite_malloc_failed++;
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate return p;
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate /*
2757c478bd9Sstevel@tonic-gate ** Free memory previously obtained from sqliteMalloc()
2767c478bd9Sstevel@tonic-gate */
sqliteFree(void * p)2777c478bd9Sstevel@tonic-gate void sqliteFree(void *p){
2787c478bd9Sstevel@tonic-gate if( p ){
2797c478bd9Sstevel@tonic-gate free(p);
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate /*
2847c478bd9Sstevel@tonic-gate ** Resize a prior allocation. If p==0, then this routine
2857c478bd9Sstevel@tonic-gate ** works just like sqliteMalloc(). If n==0, then this routine
2867c478bd9Sstevel@tonic-gate ** works just like sqliteFree().
2877c478bd9Sstevel@tonic-gate */
sqliteRealloc(void * p,int n)2887c478bd9Sstevel@tonic-gate void *sqliteRealloc(void *p, int n){
2897c478bd9Sstevel@tonic-gate void *p2;
2907c478bd9Sstevel@tonic-gate if( p==0 ){
2917c478bd9Sstevel@tonic-gate return sqliteMalloc(n);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate if( n==0 ){
2947c478bd9Sstevel@tonic-gate sqliteFree(p);
2957c478bd9Sstevel@tonic-gate return 0;
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate p2 = realloc(p, n);
2987c478bd9Sstevel@tonic-gate if( p2==0 ){
2997c478bd9Sstevel@tonic-gate sqlite_malloc_failed++;
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate return p2;
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate /*
3057c478bd9Sstevel@tonic-gate ** Make a copy of a string in memory obtained from sqliteMalloc()
3067c478bd9Sstevel@tonic-gate */
sqliteStrDup(const char * z)3077c478bd9Sstevel@tonic-gate char *sqliteStrDup(const char *z){
3087c478bd9Sstevel@tonic-gate char *zNew;
3097c478bd9Sstevel@tonic-gate if( z==0 ) return 0;
3107c478bd9Sstevel@tonic-gate zNew = sqliteMallocRaw(strlen(z)+1);
3117c478bd9Sstevel@tonic-gate if( zNew ) strcpy(zNew, z);
3127c478bd9Sstevel@tonic-gate return zNew;
3137c478bd9Sstevel@tonic-gate }
sqliteStrNDup(const char * z,int n)3147c478bd9Sstevel@tonic-gate char *sqliteStrNDup(const char *z, int n){
3157c478bd9Sstevel@tonic-gate char *zNew;
3167c478bd9Sstevel@tonic-gate if( z==0 ) return 0;
3177c478bd9Sstevel@tonic-gate zNew = sqliteMallocRaw(n+1);
3187c478bd9Sstevel@tonic-gate if( zNew ){
3197c478bd9Sstevel@tonic-gate memcpy(zNew, z, n);
3207c478bd9Sstevel@tonic-gate zNew[n] = 0;
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate return zNew;
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate #endif /* !defined(MEMORY_DEBUG) */
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate /*
3277c478bd9Sstevel@tonic-gate ** Create a string from the 2nd and subsequent arguments (up to the
3287c478bd9Sstevel@tonic-gate ** first NULL argument), store the string in memory obtained from
3297c478bd9Sstevel@tonic-gate ** sqliteMalloc() and make the pointer indicated by the 1st argument
330*1da57d55SToomas Soome ** point to that string. The 1st argument must either be NULL or
3317c478bd9Sstevel@tonic-gate ** point to memory obtained from sqliteMalloc().
3327c478bd9Sstevel@tonic-gate */
sqliteSetString(char ** pz,const char * zFirst,...)3337c478bd9Sstevel@tonic-gate void sqliteSetString(char **pz, const char *zFirst, ...){
3347c478bd9Sstevel@tonic-gate va_list ap;
3357c478bd9Sstevel@tonic-gate int nByte;
3367c478bd9Sstevel@tonic-gate const char *z;
3377c478bd9Sstevel@tonic-gate char *zResult;
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate if( pz==0 ) return;
3407c478bd9Sstevel@tonic-gate nByte = strlen(zFirst) + 1;
3417c478bd9Sstevel@tonic-gate va_start(ap, zFirst);
3427c478bd9Sstevel@tonic-gate while( (z = va_arg(ap, const char*))!=0 ){
3437c478bd9Sstevel@tonic-gate nByte += strlen(z);
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate va_end(ap);
3467c478bd9Sstevel@tonic-gate sqliteFree(*pz);
3477c478bd9Sstevel@tonic-gate *pz = zResult = sqliteMallocRaw( nByte );
3487c478bd9Sstevel@tonic-gate if( zResult==0 ){
3497c478bd9Sstevel@tonic-gate return;
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate strcpy(zResult, zFirst);
3527c478bd9Sstevel@tonic-gate zResult += strlen(zResult);
3537c478bd9Sstevel@tonic-gate va_start(ap, zFirst);
3547c478bd9Sstevel@tonic-gate while( (z = va_arg(ap, const char*))!=0 ){
3557c478bd9Sstevel@tonic-gate strcpy(zResult, z);
3567c478bd9Sstevel@tonic-gate zResult += strlen(zResult);
3577c478bd9Sstevel@tonic-gate }
3587c478bd9Sstevel@tonic-gate va_end(ap);
3597c478bd9Sstevel@tonic-gate #ifdef MEMORY_DEBUG
3607c478bd9Sstevel@tonic-gate #if MEMORY_DEBUG>1
3617c478bd9Sstevel@tonic-gate fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
3627c478bd9Sstevel@tonic-gate #endif
3637c478bd9Sstevel@tonic-gate #endif
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate /*
3677c478bd9Sstevel@tonic-gate ** Works like sqliteSetString, but each string is now followed by
368*1da57d55SToomas Soome ** a length integer which specifies how much of the source string
369*1da57d55SToomas Soome ** to copy (in bytes). -1 means use the whole string. The 1st
370*1da57d55SToomas Soome ** argument must either be NULL or point to memory obtained from
3717c478bd9Sstevel@tonic-gate ** sqliteMalloc().
3727c478bd9Sstevel@tonic-gate */
sqliteSetNString(char ** pz,...)3737c478bd9Sstevel@tonic-gate void sqliteSetNString(char **pz, ...){
3747c478bd9Sstevel@tonic-gate va_list ap;
3757c478bd9Sstevel@tonic-gate int nByte;
3767c478bd9Sstevel@tonic-gate const char *z;
3777c478bd9Sstevel@tonic-gate char *zResult;
3787c478bd9Sstevel@tonic-gate int n;
3797c478bd9Sstevel@tonic-gate
3807c478bd9Sstevel@tonic-gate if( pz==0 ) return;
3817c478bd9Sstevel@tonic-gate nByte = 0;
3827c478bd9Sstevel@tonic-gate va_start(ap, pz);
3837c478bd9Sstevel@tonic-gate while( (z = va_arg(ap, const char*))!=0 ){
3847c478bd9Sstevel@tonic-gate n = va_arg(ap, int);
3857c478bd9Sstevel@tonic-gate if( n<=0 ) n = strlen(z);
3867c478bd9Sstevel@tonic-gate nByte += n;
3877c478bd9Sstevel@tonic-gate }
3887c478bd9Sstevel@tonic-gate va_end(ap);
3897c478bd9Sstevel@tonic-gate sqliteFree(*pz);
3907c478bd9Sstevel@tonic-gate *pz = zResult = sqliteMallocRaw( nByte + 1 );
3917c478bd9Sstevel@tonic-gate if( zResult==0 ) return;
3927c478bd9Sstevel@tonic-gate va_start(ap, pz);
3937c478bd9Sstevel@tonic-gate while( (z = va_arg(ap, const char*))!=0 ){
3947c478bd9Sstevel@tonic-gate n = va_arg(ap, int);
3957c478bd9Sstevel@tonic-gate if( n<=0 ) n = strlen(z);
3967c478bd9Sstevel@tonic-gate strncpy(zResult, z, n);
3977c478bd9Sstevel@tonic-gate zResult += n;
3987c478bd9Sstevel@tonic-gate }
3997c478bd9Sstevel@tonic-gate *zResult = 0;
4007c478bd9Sstevel@tonic-gate #ifdef MEMORY_DEBUG
4017c478bd9Sstevel@tonic-gate #if MEMORY_DEBUG>1
4027c478bd9Sstevel@tonic-gate fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
4037c478bd9Sstevel@tonic-gate #endif
4047c478bd9Sstevel@tonic-gate #endif
4057c478bd9Sstevel@tonic-gate va_end(ap);
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate /*
4097c478bd9Sstevel@tonic-gate ** Add an error message to pParse->zErrMsg and increment pParse->nErr.
4107c478bd9Sstevel@tonic-gate ** The following formatting characters are allowed:
4117c478bd9Sstevel@tonic-gate **
4127c478bd9Sstevel@tonic-gate ** %s Insert a string
4137c478bd9Sstevel@tonic-gate ** %z A string that should be freed after use
4147c478bd9Sstevel@tonic-gate ** %d Insert an integer
4157c478bd9Sstevel@tonic-gate ** %T Insert a token
4167c478bd9Sstevel@tonic-gate ** %S Insert the first element of a SrcList
4177c478bd9Sstevel@tonic-gate */
sqliteErrorMsg(Parse * pParse,const char * zFormat,...)4187c478bd9Sstevel@tonic-gate void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){
4197c478bd9Sstevel@tonic-gate va_list ap;
4207c478bd9Sstevel@tonic-gate pParse->nErr++;
4217c478bd9Sstevel@tonic-gate sqliteFree(pParse->zErrMsg);
4227c478bd9Sstevel@tonic-gate va_start(ap, zFormat);
4237c478bd9Sstevel@tonic-gate pParse->zErrMsg = sqliteVMPrintf(zFormat, ap);
4247c478bd9Sstevel@tonic-gate va_end(ap);
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate /*
4287c478bd9Sstevel@tonic-gate ** Convert an SQL-style quoted string into a normal string by removing
4297c478bd9Sstevel@tonic-gate ** the quote characters. The conversion is done in-place. If the
4307c478bd9Sstevel@tonic-gate ** input does not begin with a quote character, then this routine
4317c478bd9Sstevel@tonic-gate ** is a no-op.
4327c478bd9Sstevel@tonic-gate **
4337c478bd9Sstevel@tonic-gate ** 2002-Feb-14: This routine is extended to remove MS-Access style
4347c478bd9Sstevel@tonic-gate ** brackets from around identifers. For example: "[a-b-c]" becomes
4357c478bd9Sstevel@tonic-gate ** "a-b-c".
4367c478bd9Sstevel@tonic-gate */
sqliteDequote(char * z)4377c478bd9Sstevel@tonic-gate void sqliteDequote(char *z){
4387c478bd9Sstevel@tonic-gate int quote;
4397c478bd9Sstevel@tonic-gate int i, j;
4407c478bd9Sstevel@tonic-gate if( z==0 ) return;
4417c478bd9Sstevel@tonic-gate quote = z[0];
4427c478bd9Sstevel@tonic-gate switch( quote ){
4437c478bd9Sstevel@tonic-gate case '\'': break;
4447c478bd9Sstevel@tonic-gate case '"': break;
4457c478bd9Sstevel@tonic-gate case '[': quote = ']'; break;
4467c478bd9Sstevel@tonic-gate default: return;
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate for(i=1, j=0; z[i]; i++){
4497c478bd9Sstevel@tonic-gate if( z[i]==quote ){
4507c478bd9Sstevel@tonic-gate if( z[i+1]==quote ){
4517c478bd9Sstevel@tonic-gate z[j++] = quote;
4527c478bd9Sstevel@tonic-gate i++;
4537c478bd9Sstevel@tonic-gate }else{
4547c478bd9Sstevel@tonic-gate z[j++] = 0;
4557c478bd9Sstevel@tonic-gate break;
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate }else{
4587c478bd9Sstevel@tonic-gate z[j++] = z[i];
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate }
4617c478bd9Sstevel@tonic-gate }
4627c478bd9Sstevel@tonic-gate
4637c478bd9Sstevel@tonic-gate /* An array to map all upper-case characters into their corresponding
464*1da57d55SToomas Soome ** lower-case character.
4657c478bd9Sstevel@tonic-gate */
4667c478bd9Sstevel@tonic-gate static unsigned char UpperToLower[] = {
4677c478bd9Sstevel@tonic-gate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
4687c478bd9Sstevel@tonic-gate 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
4697c478bd9Sstevel@tonic-gate 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
4707c478bd9Sstevel@tonic-gate 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
4717c478bd9Sstevel@tonic-gate 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
4727c478bd9Sstevel@tonic-gate 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
4737c478bd9Sstevel@tonic-gate 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
4747c478bd9Sstevel@tonic-gate 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
4757c478bd9Sstevel@tonic-gate 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
4767c478bd9Sstevel@tonic-gate 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
4777c478bd9Sstevel@tonic-gate 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
4787c478bd9Sstevel@tonic-gate 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
4797c478bd9Sstevel@tonic-gate 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
4807c478bd9Sstevel@tonic-gate 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
4817c478bd9Sstevel@tonic-gate 252,253,254,255
4827c478bd9Sstevel@tonic-gate };
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate /*
4857c478bd9Sstevel@tonic-gate ** This function computes a hash on the name of a keyword.
4867c478bd9Sstevel@tonic-gate ** Case is not significant.
4877c478bd9Sstevel@tonic-gate */
sqliteHashNoCase(const char * z,int n)4887c478bd9Sstevel@tonic-gate int sqliteHashNoCase(const char *z, int n){
4897c478bd9Sstevel@tonic-gate int h = 0;
4907c478bd9Sstevel@tonic-gate if( n<=0 ) n = strlen(z);
4917c478bd9Sstevel@tonic-gate while( n > 0 ){
4927c478bd9Sstevel@tonic-gate h = (h<<3) ^ h ^ UpperToLower[(unsigned char)*z++];
4937c478bd9Sstevel@tonic-gate n--;
4947c478bd9Sstevel@tonic-gate }
4957c478bd9Sstevel@tonic-gate return h & 0x7fffffff;
4967c478bd9Sstevel@tonic-gate }
4977c478bd9Sstevel@tonic-gate
4987c478bd9Sstevel@tonic-gate /*
4997c478bd9Sstevel@tonic-gate ** Some systems have stricmp(). Others have strcasecmp(). Because
5007c478bd9Sstevel@tonic-gate ** there is no consistency, we will define our own.
5017c478bd9Sstevel@tonic-gate */
sqliteStrICmp(const char * zLeft,const char * zRight)5027c478bd9Sstevel@tonic-gate int sqliteStrICmp(const char *zLeft, const char *zRight){
5037c478bd9Sstevel@tonic-gate register unsigned char *a, *b;
5047c478bd9Sstevel@tonic-gate a = (unsigned char *)zLeft;
5057c478bd9Sstevel@tonic-gate b = (unsigned char *)zRight;
5067c478bd9Sstevel@tonic-gate while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
5077c478bd9Sstevel@tonic-gate return UpperToLower[*a] - UpperToLower[*b];
5087c478bd9Sstevel@tonic-gate }
sqliteStrNICmp(const char * zLeft,const char * zRight,int N)5097c478bd9Sstevel@tonic-gate int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
5107c478bd9Sstevel@tonic-gate register unsigned char *a, *b;
5117c478bd9Sstevel@tonic-gate a = (unsigned char *)zLeft;
5127c478bd9Sstevel@tonic-gate b = (unsigned char *)zRight;
5137c478bd9Sstevel@tonic-gate while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
5147c478bd9Sstevel@tonic-gate return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate
5177c478bd9Sstevel@tonic-gate /*
5187c478bd9Sstevel@tonic-gate ** Return TRUE if z is a pure numeric string. Return FALSE if the
5197c478bd9Sstevel@tonic-gate ** string contains any character which is not part of a number.
5207c478bd9Sstevel@tonic-gate **
5217c478bd9Sstevel@tonic-gate ** Am empty string is considered non-numeric.
5227c478bd9Sstevel@tonic-gate */
sqliteIsNumber(const char * z)5237c478bd9Sstevel@tonic-gate int sqliteIsNumber(const char *z){
5247c478bd9Sstevel@tonic-gate if( *z=='-' || *z=='+' ) z++;
5257c478bd9Sstevel@tonic-gate if( !isdigit(*z) ){
5267c478bd9Sstevel@tonic-gate return 0;
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate z++;
5297c478bd9Sstevel@tonic-gate while( isdigit(*z) ){ z++; }
5307c478bd9Sstevel@tonic-gate if( *z=='.' ){
5317c478bd9Sstevel@tonic-gate z++;
5327c478bd9Sstevel@tonic-gate if( !isdigit(*z) ) return 0;
5337c478bd9Sstevel@tonic-gate while( isdigit(*z) ){ z++; }
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate if( *z=='e' || *z=='E' ){
5367c478bd9Sstevel@tonic-gate z++;
5377c478bd9Sstevel@tonic-gate if( *z=='+' || *z=='-' ) z++;
5387c478bd9Sstevel@tonic-gate if( !isdigit(*z) ) return 0;
5397c478bd9Sstevel@tonic-gate while( isdigit(*z) ){ z++; }
5407c478bd9Sstevel@tonic-gate }
5417c478bd9Sstevel@tonic-gate return *z==0;
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate
5447c478bd9Sstevel@tonic-gate /*
5457c478bd9Sstevel@tonic-gate ** The string z[] is an ascii representation of a real number.
5467c478bd9Sstevel@tonic-gate ** Convert this string to a double.
5477c478bd9Sstevel@tonic-gate **
5487c478bd9Sstevel@tonic-gate ** This routine assumes that z[] really is a valid number. If it
5497c478bd9Sstevel@tonic-gate ** is not, the result is undefined.
5507c478bd9Sstevel@tonic-gate **
5517c478bd9Sstevel@tonic-gate ** This routine is used instead of the library atof() function because
5527c478bd9Sstevel@tonic-gate ** the library atof() might want to use "," as the decimal point instead
5537c478bd9Sstevel@tonic-gate ** of "." depending on how locale is set. But that would cause problems
5547c478bd9Sstevel@tonic-gate ** for SQL. So this routine always uses "." regardless of locale.
5557c478bd9Sstevel@tonic-gate */
sqliteAtoF(const char * z,const char ** pzEnd)5567c478bd9Sstevel@tonic-gate double sqliteAtoF(const char *z, const char **pzEnd){
5577c478bd9Sstevel@tonic-gate int sign = 1;
5587c478bd9Sstevel@tonic-gate LONGDOUBLE_TYPE v1 = 0.0;
5597c478bd9Sstevel@tonic-gate if( *z=='-' ){
5607c478bd9Sstevel@tonic-gate sign = -1;
5617c478bd9Sstevel@tonic-gate z++;
5627c478bd9Sstevel@tonic-gate }else if( *z=='+' ){
5637c478bd9Sstevel@tonic-gate z++;
5647c478bd9Sstevel@tonic-gate }
5657c478bd9Sstevel@tonic-gate while( isdigit(*z) ){
5667c478bd9Sstevel@tonic-gate v1 = v1*10.0 + (*z - '0');
5677c478bd9Sstevel@tonic-gate z++;
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate if( *z=='.' ){
5707c478bd9Sstevel@tonic-gate LONGDOUBLE_TYPE divisor = 1.0;
5717c478bd9Sstevel@tonic-gate z++;
5727c478bd9Sstevel@tonic-gate while( isdigit(*z) ){
5737c478bd9Sstevel@tonic-gate v1 = v1*10.0 + (*z - '0');
5747c478bd9Sstevel@tonic-gate divisor *= 10.0;
5757c478bd9Sstevel@tonic-gate z++;
5767c478bd9Sstevel@tonic-gate }
5777c478bd9Sstevel@tonic-gate v1 /= divisor;
5787c478bd9Sstevel@tonic-gate }
5797c478bd9Sstevel@tonic-gate if( *z=='e' || *z=='E' ){
5807c478bd9Sstevel@tonic-gate int esign = 1;
5817c478bd9Sstevel@tonic-gate int eval = 0;
5827c478bd9Sstevel@tonic-gate LONGDOUBLE_TYPE scale = 1.0;
5837c478bd9Sstevel@tonic-gate z++;
5847c478bd9Sstevel@tonic-gate if( *z=='-' ){
5857c478bd9Sstevel@tonic-gate esign = -1;
5867c478bd9Sstevel@tonic-gate z++;
5877c478bd9Sstevel@tonic-gate }else if( *z=='+' ){
5887c478bd9Sstevel@tonic-gate z++;
5897c478bd9Sstevel@tonic-gate }
5907c478bd9Sstevel@tonic-gate while( isdigit(*z) ){
5917c478bd9Sstevel@tonic-gate eval = eval*10 + *z - '0';
5927c478bd9Sstevel@tonic-gate z++;
5937c478bd9Sstevel@tonic-gate }
5947c478bd9Sstevel@tonic-gate while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
5957c478bd9Sstevel@tonic-gate while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
5967c478bd9Sstevel@tonic-gate while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
5977c478bd9Sstevel@tonic-gate while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
5987c478bd9Sstevel@tonic-gate if( esign<0 ){
5997c478bd9Sstevel@tonic-gate v1 /= scale;
6007c478bd9Sstevel@tonic-gate }else{
6017c478bd9Sstevel@tonic-gate v1 *= scale;
6027c478bd9Sstevel@tonic-gate }
6037c478bd9Sstevel@tonic-gate }
6047c478bd9Sstevel@tonic-gate if( pzEnd ) *pzEnd = z;
6057c478bd9Sstevel@tonic-gate return sign<0 ? -v1 : v1;
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate /*
6097c478bd9Sstevel@tonic-gate ** The string zNum represents an integer. There might be some other
6107c478bd9Sstevel@tonic-gate ** information following the integer too, but that part is ignored.
6117c478bd9Sstevel@tonic-gate ** If the integer that the prefix of zNum represents will fit in a
6127c478bd9Sstevel@tonic-gate ** 32-bit signed integer, return TRUE. Otherwise return FALSE.
6137c478bd9Sstevel@tonic-gate **
6147c478bd9Sstevel@tonic-gate ** This routine returns FALSE for the string -2147483648 even that
6157c478bd9Sstevel@tonic-gate ** that number will, in theory fit in a 32-bit integer. But positive
6167c478bd9Sstevel@tonic-gate ** 2147483648 will not fit in 32 bits. So it seems safer to return
6177c478bd9Sstevel@tonic-gate ** false.
6187c478bd9Sstevel@tonic-gate */
sqliteFitsIn32Bits(const char * zNum)6197c478bd9Sstevel@tonic-gate int sqliteFitsIn32Bits(const char *zNum){
6207c478bd9Sstevel@tonic-gate int i, c;
6217c478bd9Sstevel@tonic-gate if( *zNum=='-' || *zNum=='+' ) zNum++;
6227c478bd9Sstevel@tonic-gate for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
6237c478bd9Sstevel@tonic-gate return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate
6267c478bd9Sstevel@tonic-gate /* This comparison routine is what we use for comparison operations
6277c478bd9Sstevel@tonic-gate ** between numeric values in an SQL expression. "Numeric" is a little
6287c478bd9Sstevel@tonic-gate ** bit misleading here. What we mean is that the strings have a
6297c478bd9Sstevel@tonic-gate ** type of "numeric" from the point of view of SQL. The strings
6307c478bd9Sstevel@tonic-gate ** do not necessarily contain numbers. They could contain text.
6317c478bd9Sstevel@tonic-gate **
6327c478bd9Sstevel@tonic-gate ** If the input strings both look like actual numbers then they
633*1da57d55SToomas Soome ** compare in numerical order. Numerical strings are always less
6347c478bd9Sstevel@tonic-gate ** than non-numeric strings so if one input string looks like a
6357c478bd9Sstevel@tonic-gate ** number and the other does not, then the one that looks like
636*1da57d55SToomas Soome ** a number is the smaller. Non-numeric strings compare in
6377c478bd9Sstevel@tonic-gate ** lexigraphical order (the same order as strcmp()).
6387c478bd9Sstevel@tonic-gate */
sqliteCompare(const char * atext,const char * btext)6397c478bd9Sstevel@tonic-gate int sqliteCompare(const char *atext, const char *btext){
6407c478bd9Sstevel@tonic-gate int result;
6417c478bd9Sstevel@tonic-gate int isNumA, isNumB;
6427c478bd9Sstevel@tonic-gate if( atext==0 ){
6437c478bd9Sstevel@tonic-gate return -1;
6447c478bd9Sstevel@tonic-gate }else if( btext==0 ){
6457c478bd9Sstevel@tonic-gate return 1;
6467c478bd9Sstevel@tonic-gate }
6477c478bd9Sstevel@tonic-gate isNumA = sqliteIsNumber(atext);
6487c478bd9Sstevel@tonic-gate isNumB = sqliteIsNumber(btext);
6497c478bd9Sstevel@tonic-gate if( isNumA ){
6507c478bd9Sstevel@tonic-gate if( !isNumB ){
6517c478bd9Sstevel@tonic-gate result = -1;
6527c478bd9Sstevel@tonic-gate }else{
6537c478bd9Sstevel@tonic-gate double rA, rB;
6547c478bd9Sstevel@tonic-gate rA = sqliteAtoF(atext, 0);
6557c478bd9Sstevel@tonic-gate rB = sqliteAtoF(btext, 0);
6567c478bd9Sstevel@tonic-gate if( rA<rB ){
6577c478bd9Sstevel@tonic-gate result = -1;
6587c478bd9Sstevel@tonic-gate }else if( rA>rB ){
6597c478bd9Sstevel@tonic-gate result = +1;
6607c478bd9Sstevel@tonic-gate }else{
6617c478bd9Sstevel@tonic-gate result = 0;
6627c478bd9Sstevel@tonic-gate }
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate }else if( isNumB ){
6657c478bd9Sstevel@tonic-gate result = +1;
6667c478bd9Sstevel@tonic-gate }else {
6677c478bd9Sstevel@tonic-gate result = strcmp(atext, btext);
6687c478bd9Sstevel@tonic-gate }
669*1da57d55SToomas Soome return result;
6707c478bd9Sstevel@tonic-gate }
6717c478bd9Sstevel@tonic-gate
6727c478bd9Sstevel@tonic-gate /*
6737c478bd9Sstevel@tonic-gate ** This routine is used for sorting. Each key is a list of one or more
6747c478bd9Sstevel@tonic-gate ** null-terminated elements. The list is terminated by two nulls in
6757c478bd9Sstevel@tonic-gate ** a row. For example, the following text is a key with three elements
6767c478bd9Sstevel@tonic-gate **
6777c478bd9Sstevel@tonic-gate ** Aone\000Dtwo\000Athree\000\000
6787c478bd9Sstevel@tonic-gate **
6797c478bd9Sstevel@tonic-gate ** All elements begin with one of the characters "+-AD" and end with "\000"
6807c478bd9Sstevel@tonic-gate ** with zero or more text elements in between. Except, NULL elements
6817c478bd9Sstevel@tonic-gate ** consist of the special two-character sequence "N\000".
6827c478bd9Sstevel@tonic-gate **
6837c478bd9Sstevel@tonic-gate ** Both arguments will have the same number of elements. This routine
6847c478bd9Sstevel@tonic-gate ** returns negative, zero, or positive if the first argument is less
6857c478bd9Sstevel@tonic-gate ** than, equal to, or greater than the first. (Result is a-b).
6867c478bd9Sstevel@tonic-gate **
6877c478bd9Sstevel@tonic-gate ** Each element begins with one of the characters "+", "-", "A", "D".
6887c478bd9Sstevel@tonic-gate ** This character determines the sort order and collating sequence:
6897c478bd9Sstevel@tonic-gate **
6907c478bd9Sstevel@tonic-gate ** + Sort numerically in ascending order
6917c478bd9Sstevel@tonic-gate ** - Sort numerically in descending order
6927c478bd9Sstevel@tonic-gate ** A Sort as strings in ascending order
6937c478bd9Sstevel@tonic-gate ** D Sort as strings in descending order.
6947c478bd9Sstevel@tonic-gate **
6957c478bd9Sstevel@tonic-gate ** For the "+" and "-" sorting, pure numeric strings (strings for which the
6967c478bd9Sstevel@tonic-gate ** isNum() function above returns TRUE) always compare less than strings
6977c478bd9Sstevel@tonic-gate ** that are not pure numerics. Non-numeric strings compare in memcmp()
6987c478bd9Sstevel@tonic-gate ** order. This is the same sort order as the sqliteCompare() function
6997c478bd9Sstevel@tonic-gate ** above generates.
7007c478bd9Sstevel@tonic-gate **
7017c478bd9Sstevel@tonic-gate ** The last point is a change from version 2.6.3 to version 2.7.0. In
702*1da57d55SToomas Soome ** version 2.6.3 and earlier, substrings of digits compare in numerical
7037c478bd9Sstevel@tonic-gate ** and case was used only to break a tie.
7047c478bd9Sstevel@tonic-gate **
7057c478bd9Sstevel@tonic-gate ** Elements that begin with 'A' or 'D' compare in memcmp() order regardless
7067c478bd9Sstevel@tonic-gate ** of whether or not they look like a number.
7077c478bd9Sstevel@tonic-gate **
7087c478bd9Sstevel@tonic-gate ** Note that the sort order imposed by the rules above is the same
7097c478bd9Sstevel@tonic-gate ** from the ordering defined by the "<", "<=", ">", and ">=" operators
7107c478bd9Sstevel@tonic-gate ** of expressions and for indices. This was not the case for version
7117c478bd9Sstevel@tonic-gate ** 2.6.3 and earlier.
7127c478bd9Sstevel@tonic-gate */
sqliteSortCompare(const char * a,const char * b)7137c478bd9Sstevel@tonic-gate int sqliteSortCompare(const char *a, const char *b){
7147c478bd9Sstevel@tonic-gate int res = 0;
7157c478bd9Sstevel@tonic-gate int isNumA, isNumB;
7167c478bd9Sstevel@tonic-gate int dir = 0;
7177c478bd9Sstevel@tonic-gate
7187c478bd9Sstevel@tonic-gate while( res==0 && *a && *b ){
7197c478bd9Sstevel@tonic-gate if( a[0]=='N' || b[0]=='N' ){
7207c478bd9Sstevel@tonic-gate if( a[0]==b[0] ){
7217c478bd9Sstevel@tonic-gate a += 2;
7227c478bd9Sstevel@tonic-gate b += 2;
7237c478bd9Sstevel@tonic-gate continue;
7247c478bd9Sstevel@tonic-gate }
7257c478bd9Sstevel@tonic-gate if( a[0]=='N' ){
7267c478bd9Sstevel@tonic-gate dir = b[0];
7277c478bd9Sstevel@tonic-gate res = -1;
7287c478bd9Sstevel@tonic-gate }else{
7297c478bd9Sstevel@tonic-gate dir = a[0];
7307c478bd9Sstevel@tonic-gate res = +1;
7317c478bd9Sstevel@tonic-gate }
7327c478bd9Sstevel@tonic-gate break;
7337c478bd9Sstevel@tonic-gate }
7347c478bd9Sstevel@tonic-gate assert( a[0]==b[0] );
7357c478bd9Sstevel@tonic-gate if( (dir=a[0])=='A' || a[0]=='D' ){
7367c478bd9Sstevel@tonic-gate res = strcmp(&a[1],&b[1]);
7377c478bd9Sstevel@tonic-gate if( res ) break;
7387c478bd9Sstevel@tonic-gate }else{
7397c478bd9Sstevel@tonic-gate isNumA = sqliteIsNumber(&a[1]);
7407c478bd9Sstevel@tonic-gate isNumB = sqliteIsNumber(&b[1]);
7417c478bd9Sstevel@tonic-gate if( isNumA ){
7427c478bd9Sstevel@tonic-gate double rA, rB;
7437c478bd9Sstevel@tonic-gate if( !isNumB ){
7447c478bd9Sstevel@tonic-gate res = -1;
7457c478bd9Sstevel@tonic-gate break;
7467c478bd9Sstevel@tonic-gate }
7477c478bd9Sstevel@tonic-gate rA = sqliteAtoF(&a[1], 0);
7487c478bd9Sstevel@tonic-gate rB = sqliteAtoF(&b[1], 0);
7497c478bd9Sstevel@tonic-gate if( rA<rB ){
7507c478bd9Sstevel@tonic-gate res = -1;
7517c478bd9Sstevel@tonic-gate break;
7527c478bd9Sstevel@tonic-gate }
7537c478bd9Sstevel@tonic-gate if( rA>rB ){
7547c478bd9Sstevel@tonic-gate res = +1;
7557c478bd9Sstevel@tonic-gate break;
7567c478bd9Sstevel@tonic-gate }
7577c478bd9Sstevel@tonic-gate }else if( isNumB ){
7587c478bd9Sstevel@tonic-gate res = +1;
7597c478bd9Sstevel@tonic-gate break;
7607c478bd9Sstevel@tonic-gate }else{
7617c478bd9Sstevel@tonic-gate res = strcmp(&a[1],&b[1]);
7627c478bd9Sstevel@tonic-gate if( res ) break;
7637c478bd9Sstevel@tonic-gate }
7647c478bd9Sstevel@tonic-gate }
7657c478bd9Sstevel@tonic-gate a += strlen(&a[1]) + 2;
7667c478bd9Sstevel@tonic-gate b += strlen(&b[1]) + 2;
7677c478bd9Sstevel@tonic-gate }
7687c478bd9Sstevel@tonic-gate if( dir=='-' || dir=='D' ) res = -res;
7697c478bd9Sstevel@tonic-gate return res;
7707c478bd9Sstevel@tonic-gate }
7717c478bd9Sstevel@tonic-gate
7727c478bd9Sstevel@tonic-gate /*
7737c478bd9Sstevel@tonic-gate ** Some powers of 64. These constants are needed in the
7747c478bd9Sstevel@tonic-gate ** sqliteRealToSortable() routine below.
7757c478bd9Sstevel@tonic-gate */
7767c478bd9Sstevel@tonic-gate #define _64e3 (64.0 * 64.0 * 64.0)
7777c478bd9Sstevel@tonic-gate #define _64e4 (64.0 * 64.0 * 64.0 * 64.0)
7787c478bd9Sstevel@tonic-gate #define _64e15 (_64e3 * _64e4 * _64e4 * _64e4)
7797c478bd9Sstevel@tonic-gate #define _64e16 (_64e4 * _64e4 * _64e4 * _64e4)
7807c478bd9Sstevel@tonic-gate #define _64e63 (_64e15 * _64e16 * _64e16 * _64e16)
7817c478bd9Sstevel@tonic-gate #define _64e64 (_64e16 * _64e16 * _64e16 * _64e16)
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate /*
7847c478bd9Sstevel@tonic-gate ** The following procedure converts a double-precision floating point
7857c478bd9Sstevel@tonic-gate ** number into a string. The resulting string has the property that
7867c478bd9Sstevel@tonic-gate ** two such strings comparied using strcmp() or memcmp() will give the
7877c478bd9Sstevel@tonic-gate ** same results as a numeric comparison of the original floating point
7887c478bd9Sstevel@tonic-gate ** numbers.
7897c478bd9Sstevel@tonic-gate **
7907c478bd9Sstevel@tonic-gate ** This routine is used to generate database keys from floating point
7917c478bd9Sstevel@tonic-gate ** numbers such that the keys sort in the same order as the original
7927c478bd9Sstevel@tonic-gate ** floating point numbers even though the keys are compared using
7937c478bd9Sstevel@tonic-gate ** memcmp().
7947c478bd9Sstevel@tonic-gate **
7957c478bd9Sstevel@tonic-gate ** The calling function should have allocated at least 14 characters
7967c478bd9Sstevel@tonic-gate ** of space for the buffer z[].
7977c478bd9Sstevel@tonic-gate */
sqliteRealToSortable(double r,char * z)7987c478bd9Sstevel@tonic-gate void sqliteRealToSortable(double r, char *z){
7997c478bd9Sstevel@tonic-gate int neg;
8007c478bd9Sstevel@tonic-gate int exp;
8017c478bd9Sstevel@tonic-gate int cnt = 0;
8027c478bd9Sstevel@tonic-gate
8037c478bd9Sstevel@tonic-gate /* This array maps integers between 0 and 63 into base-64 digits.
8047c478bd9Sstevel@tonic-gate ** The digits must be chosen such at their ASCII codes are increasing.
8057c478bd9Sstevel@tonic-gate ** This means we can not use the traditional base-64 digit set. */
806*1da57d55SToomas Soome static const char zDigit[] =
8077c478bd9Sstevel@tonic-gate "0123456789"
8087c478bd9Sstevel@tonic-gate "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
8097c478bd9Sstevel@tonic-gate "abcdefghijklmnopqrstuvwxyz"
8107c478bd9Sstevel@tonic-gate "|~";
8117c478bd9Sstevel@tonic-gate if( r<0.0 ){
8127c478bd9Sstevel@tonic-gate neg = 1;
8137c478bd9Sstevel@tonic-gate r = -r;
8147c478bd9Sstevel@tonic-gate *z++ = '-';
8157c478bd9Sstevel@tonic-gate } else {
8167c478bd9Sstevel@tonic-gate neg = 0;
8177c478bd9Sstevel@tonic-gate *z++ = '0';
8187c478bd9Sstevel@tonic-gate }
8197c478bd9Sstevel@tonic-gate exp = 0;
8207c478bd9Sstevel@tonic-gate
8217c478bd9Sstevel@tonic-gate if( r==0.0 ){
8227c478bd9Sstevel@tonic-gate exp = -1024;
8237c478bd9Sstevel@tonic-gate }else if( r<(0.5/64.0) ){
8247c478bd9Sstevel@tonic-gate while( r < 0.5/_64e64 && exp > -961 ){ r *= _64e64; exp -= 64; }
8257c478bd9Sstevel@tonic-gate while( r < 0.5/_64e16 && exp > -1009 ){ r *= _64e16; exp -= 16; }
8267c478bd9Sstevel@tonic-gate while( r < 0.5/_64e4 && exp > -1021 ){ r *= _64e4; exp -= 4; }
8277c478bd9Sstevel@tonic-gate while( r < 0.5/64.0 && exp > -1024 ){ r *= 64.0; exp -= 1; }
8287c478bd9Sstevel@tonic-gate }else if( r>=0.5 ){
8297c478bd9Sstevel@tonic-gate while( r >= 0.5*_64e63 && exp < 960 ){ r *= 1.0/_64e64; exp += 64; }
8307c478bd9Sstevel@tonic-gate while( r >= 0.5*_64e15 && exp < 1008 ){ r *= 1.0/_64e16; exp += 16; }
8317c478bd9Sstevel@tonic-gate while( r >= 0.5*_64e3 && exp < 1020 ){ r *= 1.0/_64e4; exp += 4; }
8327c478bd9Sstevel@tonic-gate while( r >= 0.5 && exp < 1023 ){ r *= 1.0/64.0; exp += 1; }
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate if( neg ){
8357c478bd9Sstevel@tonic-gate exp = -exp;
8367c478bd9Sstevel@tonic-gate r = -r;
8377c478bd9Sstevel@tonic-gate }
8387c478bd9Sstevel@tonic-gate exp += 1024;
8397c478bd9Sstevel@tonic-gate r += 0.5;
8407c478bd9Sstevel@tonic-gate if( exp<0 ) return;
8417c478bd9Sstevel@tonic-gate if( exp>=2048 || r>=1.0 ){
8427c478bd9Sstevel@tonic-gate strcpy(z, "~~~~~~~~~~~~");
8437c478bd9Sstevel@tonic-gate return;
8447c478bd9Sstevel@tonic-gate }
8457c478bd9Sstevel@tonic-gate *z++ = zDigit[(exp>>6)&0x3f];
8467c478bd9Sstevel@tonic-gate *z++ = zDigit[exp & 0x3f];
8477c478bd9Sstevel@tonic-gate while( r>0.0 && cnt<10 ){
8487c478bd9Sstevel@tonic-gate int digit;
8497c478bd9Sstevel@tonic-gate r *= 64.0;
8507c478bd9Sstevel@tonic-gate digit = (int)r;
8517c478bd9Sstevel@tonic-gate assert( digit>=0 && digit<64 );
8527c478bd9Sstevel@tonic-gate *z++ = zDigit[digit & 0x3f];
8537c478bd9Sstevel@tonic-gate r -= digit;
8547c478bd9Sstevel@tonic-gate cnt++;
8557c478bd9Sstevel@tonic-gate }
8567c478bd9Sstevel@tonic-gate *z = 0;
8577c478bd9Sstevel@tonic-gate }
8587c478bd9Sstevel@tonic-gate
8597c478bd9Sstevel@tonic-gate #ifdef SQLITE_UTF8
8607c478bd9Sstevel@tonic-gate /*
8617c478bd9Sstevel@tonic-gate ** X is a pointer to the first byte of a UTF-8 character. Increment
8627c478bd9Sstevel@tonic-gate ** X so that it points to the next character. This only works right
8637c478bd9Sstevel@tonic-gate ** if X points to a well-formed UTF-8 string.
8647c478bd9Sstevel@tonic-gate */
8657c478bd9Sstevel@tonic-gate #define sqliteNextChar(X) while( (0xc0&*++(X))==0x80 ){}
8667c478bd9Sstevel@tonic-gate #define sqliteCharVal(X) sqlite_utf8_to_int(X)
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate #else /* !defined(SQLITE_UTF8) */
8697c478bd9Sstevel@tonic-gate /*
8707c478bd9Sstevel@tonic-gate ** For iso8859 encoding, the next character is just the next byte.
8717c478bd9Sstevel@tonic-gate */
8727c478bd9Sstevel@tonic-gate #define sqliteNextChar(X) (++(X));
8737c478bd9Sstevel@tonic-gate #define sqliteCharVal(X) ((int)*(X))
8747c478bd9Sstevel@tonic-gate
8757c478bd9Sstevel@tonic-gate #endif /* defined(SQLITE_UTF8) */
8767c478bd9Sstevel@tonic-gate
8777c478bd9Sstevel@tonic-gate
8787c478bd9Sstevel@tonic-gate #ifdef SQLITE_UTF8
8797c478bd9Sstevel@tonic-gate /*
8807c478bd9Sstevel@tonic-gate ** Convert the UTF-8 character to which z points into a 31-bit
8817c478bd9Sstevel@tonic-gate ** UCS character. This only works right if z points to a well-formed
8827c478bd9Sstevel@tonic-gate ** UTF-8 string.
8837c478bd9Sstevel@tonic-gate */
sqlite_utf8_to_int(const unsigned char * z)8847c478bd9Sstevel@tonic-gate static int sqlite_utf8_to_int(const unsigned char *z){
8857c478bd9Sstevel@tonic-gate int c;
8867c478bd9Sstevel@tonic-gate static const int initVal[] = {
8877c478bd9Sstevel@tonic-gate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
8887c478bd9Sstevel@tonic-gate 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
8897c478bd9Sstevel@tonic-gate 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
8907c478bd9Sstevel@tonic-gate 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
8917c478bd9Sstevel@tonic-gate 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
8927c478bd9Sstevel@tonic-gate 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
8937c478bd9Sstevel@tonic-gate 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
8947c478bd9Sstevel@tonic-gate 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
8957c478bd9Sstevel@tonic-gate 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
8967c478bd9Sstevel@tonic-gate 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
8977c478bd9Sstevel@tonic-gate 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
8987c478bd9Sstevel@tonic-gate 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
8997c478bd9Sstevel@tonic-gate 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 0, 1, 2,
9007c478bd9Sstevel@tonic-gate 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
9017c478bd9Sstevel@tonic-gate 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0,
9027c478bd9Sstevel@tonic-gate 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
9037c478bd9Sstevel@tonic-gate 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 254,
9047c478bd9Sstevel@tonic-gate 255,
9057c478bd9Sstevel@tonic-gate };
9067c478bd9Sstevel@tonic-gate c = initVal[*(z++)];
9077c478bd9Sstevel@tonic-gate while( (0xc0&*z)==0x80 ){
9087c478bd9Sstevel@tonic-gate c = (c<<6) | (0x3f&*(z++));
9097c478bd9Sstevel@tonic-gate }
9107c478bd9Sstevel@tonic-gate return c;
9117c478bd9Sstevel@tonic-gate }
9127c478bd9Sstevel@tonic-gate #endif
9137c478bd9Sstevel@tonic-gate
9147c478bd9Sstevel@tonic-gate /*
9157c478bd9Sstevel@tonic-gate ** Compare two UTF-8 strings for equality where the first string can
9167c478bd9Sstevel@tonic-gate ** potentially be a "glob" expression. Return true (1) if they
9177c478bd9Sstevel@tonic-gate ** are the same and false (0) if they are different.
9187c478bd9Sstevel@tonic-gate **
9197c478bd9Sstevel@tonic-gate ** Globbing rules:
9207c478bd9Sstevel@tonic-gate **
9217c478bd9Sstevel@tonic-gate ** '*' Matches any sequence of zero or more characters.
9227c478bd9Sstevel@tonic-gate **
9237c478bd9Sstevel@tonic-gate ** '?' Matches exactly one character.
9247c478bd9Sstevel@tonic-gate **
9257c478bd9Sstevel@tonic-gate ** [...] Matches one character from the enclosed list of
9267c478bd9Sstevel@tonic-gate ** characters.
9277c478bd9Sstevel@tonic-gate **
9287c478bd9Sstevel@tonic-gate ** [^...] Matches one character not in the enclosed list.
9297c478bd9Sstevel@tonic-gate **
9307c478bd9Sstevel@tonic-gate ** With the [...] and [^...] matching, a ']' character can be included
9317c478bd9Sstevel@tonic-gate ** in the list by making it the first character after '[' or '^'. A
9327c478bd9Sstevel@tonic-gate ** range of characters can be specified using '-'. Example:
9337c478bd9Sstevel@tonic-gate ** "[a-z]" matches any single lower-case letter. To match a '-', make
9347c478bd9Sstevel@tonic-gate ** it the last character in the list.
9357c478bd9Sstevel@tonic-gate **
9367c478bd9Sstevel@tonic-gate ** This routine is usually quick, but can be N**2 in the worst case.
9377c478bd9Sstevel@tonic-gate **
9387c478bd9Sstevel@tonic-gate ** Hints: to match '*' or '?', put them in "[]". Like this:
9397c478bd9Sstevel@tonic-gate **
9407c478bd9Sstevel@tonic-gate ** abc[*]xyz Matches "abc*xyz" only
9417c478bd9Sstevel@tonic-gate */
942*1da57d55SToomas Soome int
sqliteGlobCompare(const unsigned char * zPattern,const unsigned char * zString)9437c478bd9Sstevel@tonic-gate sqliteGlobCompare(const unsigned char *zPattern, const unsigned char *zString){
9447c478bd9Sstevel@tonic-gate register int c;
9457c478bd9Sstevel@tonic-gate int invert;
9467c478bd9Sstevel@tonic-gate int seen;
9477c478bd9Sstevel@tonic-gate int c2;
9487c478bd9Sstevel@tonic-gate
9497c478bd9Sstevel@tonic-gate while( (c = *zPattern)!=0 ){
9507c478bd9Sstevel@tonic-gate switch( c ){
9517c478bd9Sstevel@tonic-gate case '*':
9527c478bd9Sstevel@tonic-gate while( (c=zPattern[1]) == '*' || c == '?' ){
9537c478bd9Sstevel@tonic-gate if( c=='?' ){
9547c478bd9Sstevel@tonic-gate if( *zString==0 ) return 0;
9557c478bd9Sstevel@tonic-gate sqliteNextChar(zString);
9567c478bd9Sstevel@tonic-gate }
9577c478bd9Sstevel@tonic-gate zPattern++;
9587c478bd9Sstevel@tonic-gate }
9597c478bd9Sstevel@tonic-gate if( c==0 ) return 1;
9607c478bd9Sstevel@tonic-gate if( c=='[' ){
9617c478bd9Sstevel@tonic-gate while( *zString && sqliteGlobCompare(&zPattern[1],zString)==0 ){
9627c478bd9Sstevel@tonic-gate sqliteNextChar(zString);
9637c478bd9Sstevel@tonic-gate }
9647c478bd9Sstevel@tonic-gate return *zString!=0;
9657c478bd9Sstevel@tonic-gate }else{
9667c478bd9Sstevel@tonic-gate while( (c2 = *zString)!=0 ){
9677c478bd9Sstevel@tonic-gate while( c2 != 0 && c2 != c ){ c2 = *++zString; }
9687c478bd9Sstevel@tonic-gate if( c2==0 ) return 0;
9697c478bd9Sstevel@tonic-gate if( sqliteGlobCompare(&zPattern[1],zString) ) return 1;
9707c478bd9Sstevel@tonic-gate sqliteNextChar(zString);
9717c478bd9Sstevel@tonic-gate }
9727c478bd9Sstevel@tonic-gate return 0;
9737c478bd9Sstevel@tonic-gate }
9747c478bd9Sstevel@tonic-gate case '?': {
9757c478bd9Sstevel@tonic-gate if( *zString==0 ) return 0;
9767c478bd9Sstevel@tonic-gate sqliteNextChar(zString);
9777c478bd9Sstevel@tonic-gate zPattern++;
9787c478bd9Sstevel@tonic-gate break;
9797c478bd9Sstevel@tonic-gate }
9807c478bd9Sstevel@tonic-gate case '[': {
9817c478bd9Sstevel@tonic-gate int prior_c = 0;
9827c478bd9Sstevel@tonic-gate seen = 0;
9837c478bd9Sstevel@tonic-gate invert = 0;
9847c478bd9Sstevel@tonic-gate c = sqliteCharVal(zString);
9857c478bd9Sstevel@tonic-gate if( c==0 ) return 0;
9867c478bd9Sstevel@tonic-gate c2 = *++zPattern;
9877c478bd9Sstevel@tonic-gate if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
9887c478bd9Sstevel@tonic-gate if( c2==']' ){
9897c478bd9Sstevel@tonic-gate if( c==']' ) seen = 1;
9907c478bd9Sstevel@tonic-gate c2 = *++zPattern;
9917c478bd9Sstevel@tonic-gate }
9927c478bd9Sstevel@tonic-gate while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){
9937c478bd9Sstevel@tonic-gate if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){
9947c478bd9Sstevel@tonic-gate zPattern++;
9957c478bd9Sstevel@tonic-gate c2 = sqliteCharVal(zPattern);
9967c478bd9Sstevel@tonic-gate if( c>=prior_c && c<=c2 ) seen = 1;
9977c478bd9Sstevel@tonic-gate prior_c = 0;
9987c478bd9Sstevel@tonic-gate }else if( c==c2 ){
9997c478bd9Sstevel@tonic-gate seen = 1;
10007c478bd9Sstevel@tonic-gate prior_c = c2;
10017c478bd9Sstevel@tonic-gate }else{
10027c478bd9Sstevel@tonic-gate prior_c = c2;
10037c478bd9Sstevel@tonic-gate }
10047c478bd9Sstevel@tonic-gate sqliteNextChar(zPattern);
10057c478bd9Sstevel@tonic-gate }
10067c478bd9Sstevel@tonic-gate if( c2==0 || (seen ^ invert)==0 ) return 0;
10077c478bd9Sstevel@tonic-gate sqliteNextChar(zString);
10087c478bd9Sstevel@tonic-gate zPattern++;
10097c478bd9Sstevel@tonic-gate break;
10107c478bd9Sstevel@tonic-gate }
10117c478bd9Sstevel@tonic-gate default: {
10127c478bd9Sstevel@tonic-gate if( c != *zString ) return 0;
10137c478bd9Sstevel@tonic-gate zPattern++;
10147c478bd9Sstevel@tonic-gate zString++;
10157c478bd9Sstevel@tonic-gate break;
10167c478bd9Sstevel@tonic-gate }
10177c478bd9Sstevel@tonic-gate }
10187c478bd9Sstevel@tonic-gate }
10197c478bd9Sstevel@tonic-gate return *zString==0;
10207c478bd9Sstevel@tonic-gate }
10217c478bd9Sstevel@tonic-gate
10227c478bd9Sstevel@tonic-gate /*
10237c478bd9Sstevel@tonic-gate ** Compare two UTF-8 strings for equality using the "LIKE" operator of
10247c478bd9Sstevel@tonic-gate ** SQL. The '%' character matches any sequence of 0 or more
10257c478bd9Sstevel@tonic-gate ** characters and '_' matches any single character. Case is
10267c478bd9Sstevel@tonic-gate ** not significant.
10277c478bd9Sstevel@tonic-gate **
10287c478bd9Sstevel@tonic-gate ** This routine is just an adaptation of the sqliteGlobCompare()
10297c478bd9Sstevel@tonic-gate ** routine above.
10307c478bd9Sstevel@tonic-gate */
1031*1da57d55SToomas Soome int
sqliteLikeCompare(const unsigned char * zPattern,const unsigned char * zString)10327c478bd9Sstevel@tonic-gate sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
10337c478bd9Sstevel@tonic-gate register int c;
10347c478bd9Sstevel@tonic-gate int c2;
10357c478bd9Sstevel@tonic-gate
10367c478bd9Sstevel@tonic-gate while( (c = UpperToLower[*zPattern])!=0 ){
10377c478bd9Sstevel@tonic-gate switch( c ){
10387c478bd9Sstevel@tonic-gate case '%': {
10397c478bd9Sstevel@tonic-gate while( (c=zPattern[1]) == '%' || c == '_' ){
10407c478bd9Sstevel@tonic-gate if( c=='_' ){
10417c478bd9Sstevel@tonic-gate if( *zString==0 ) return 0;
10427c478bd9Sstevel@tonic-gate sqliteNextChar(zString);
10437c478bd9Sstevel@tonic-gate }
10447c478bd9Sstevel@tonic-gate zPattern++;
10457c478bd9Sstevel@tonic-gate }
10467c478bd9Sstevel@tonic-gate if( c==0 ) return 1;
10477c478bd9Sstevel@tonic-gate c = UpperToLower[c];
10487c478bd9Sstevel@tonic-gate while( (c2=UpperToLower[*zString])!=0 ){
10497c478bd9Sstevel@tonic-gate while( c2 != 0 && c2 != c ){ c2 = UpperToLower[*++zString]; }
10507c478bd9Sstevel@tonic-gate if( c2==0 ) return 0;
10517c478bd9Sstevel@tonic-gate if( sqliteLikeCompare(&zPattern[1],zString) ) return 1;
10527c478bd9Sstevel@tonic-gate sqliteNextChar(zString);
10537c478bd9Sstevel@tonic-gate }
10547c478bd9Sstevel@tonic-gate return 0;
10557c478bd9Sstevel@tonic-gate }
10567c478bd9Sstevel@tonic-gate case '_': {
10577c478bd9Sstevel@tonic-gate if( *zString==0 ) return 0;
10587c478bd9Sstevel@tonic-gate sqliteNextChar(zString);
10597c478bd9Sstevel@tonic-gate zPattern++;
10607c478bd9Sstevel@tonic-gate break;
10617c478bd9Sstevel@tonic-gate }
10627c478bd9Sstevel@tonic-gate default: {
10637c478bd9Sstevel@tonic-gate if( c != UpperToLower[*zString] ) return 0;
10647c478bd9Sstevel@tonic-gate zPattern++;
10657c478bd9Sstevel@tonic-gate zString++;
10667c478bd9Sstevel@tonic-gate break;
10677c478bd9Sstevel@tonic-gate }
10687c478bd9Sstevel@tonic-gate }
10697c478bd9Sstevel@tonic-gate }
10707c478bd9Sstevel@tonic-gate return *zString==0;
10717c478bd9Sstevel@tonic-gate }
10727c478bd9Sstevel@tonic-gate
10737c478bd9Sstevel@tonic-gate /*
10747c478bd9Sstevel@tonic-gate ** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.
10757c478bd9Sstevel@tonic-gate ** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
10767c478bd9Sstevel@tonic-gate ** when this routine is called.
10777c478bd9Sstevel@tonic-gate **
10787c478bd9Sstevel@tonic-gate ** This routine is a attempt to detect if two threads use the
1079*1da57d55SToomas Soome ** same sqlite* pointer at the same time. There is a race
10807c478bd9Sstevel@tonic-gate ** condition so it is possible that the error is not detected.
10817c478bd9Sstevel@tonic-gate ** But usually the problem will be seen. The result will be an
10827c478bd9Sstevel@tonic-gate ** error which can be used to debug the application that is
10837c478bd9Sstevel@tonic-gate ** using SQLite incorrectly.
10847c478bd9Sstevel@tonic-gate **
10857c478bd9Sstevel@tonic-gate ** Ticket #202: If db->magic is not a valid open value, take care not
10867c478bd9Sstevel@tonic-gate ** to modify the db structure at all. It could be that db is a stale
10877c478bd9Sstevel@tonic-gate ** pointer. In other words, it could be that there has been a prior
10887c478bd9Sstevel@tonic-gate ** call to sqlite_close(db) and db has been deallocated. And we do
10897c478bd9Sstevel@tonic-gate ** not want to write into deallocated memory.
10907c478bd9Sstevel@tonic-gate */
sqliteSafetyOn(sqlite * db)10917c478bd9Sstevel@tonic-gate int sqliteSafetyOn(sqlite *db){
10927c478bd9Sstevel@tonic-gate if( db->magic==SQLITE_MAGIC_OPEN ){
10937c478bd9Sstevel@tonic-gate db->magic = SQLITE_MAGIC_BUSY;
10947c478bd9Sstevel@tonic-gate return 0;
10957c478bd9Sstevel@tonic-gate }else if( db->magic==SQLITE_MAGIC_BUSY || db->magic==SQLITE_MAGIC_ERROR
10967c478bd9Sstevel@tonic-gate || db->want_to_close ){
10977c478bd9Sstevel@tonic-gate db->magic = SQLITE_MAGIC_ERROR;
10987c478bd9Sstevel@tonic-gate db->flags |= SQLITE_Interrupt;
10997c478bd9Sstevel@tonic-gate }
11007c478bd9Sstevel@tonic-gate return 1;
11017c478bd9Sstevel@tonic-gate }
11027c478bd9Sstevel@tonic-gate
11037c478bd9Sstevel@tonic-gate /*
11047c478bd9Sstevel@tonic-gate ** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
11057c478bd9Sstevel@tonic-gate ** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
11067c478bd9Sstevel@tonic-gate ** when this routine is called.
11077c478bd9Sstevel@tonic-gate */
sqliteSafetyOff(sqlite * db)11087c478bd9Sstevel@tonic-gate int sqliteSafetyOff(sqlite *db){
11097c478bd9Sstevel@tonic-gate if( db->magic==SQLITE_MAGIC_BUSY ){
11107c478bd9Sstevel@tonic-gate db->magic = SQLITE_MAGIC_OPEN;
11117c478bd9Sstevel@tonic-gate return 0;
11127c478bd9Sstevel@tonic-gate }else if( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ERROR
11137c478bd9Sstevel@tonic-gate || db->want_to_close ){
11147c478bd9Sstevel@tonic-gate db->magic = SQLITE_MAGIC_ERROR;
11157c478bd9Sstevel@tonic-gate db->flags |= SQLITE_Interrupt;
11167c478bd9Sstevel@tonic-gate }
11177c478bd9Sstevel@tonic-gate return 1;
11187c478bd9Sstevel@tonic-gate }
11197c478bd9Sstevel@tonic-gate
11207c478bd9Sstevel@tonic-gate /*
11217c478bd9Sstevel@tonic-gate ** Check to make sure we are not currently executing an sqlite_exec().
11227c478bd9Sstevel@tonic-gate ** If we are currently in an sqlite_exec(), return true and set
11237c478bd9Sstevel@tonic-gate ** sqlite.magic to SQLITE_MAGIC_ERROR. This will cause a complete
11247c478bd9Sstevel@tonic-gate ** shutdown of the database.
11257c478bd9Sstevel@tonic-gate **
11267c478bd9Sstevel@tonic-gate ** This routine is used to try to detect when API routines are called
11277c478bd9Sstevel@tonic-gate ** at the wrong time or in the wrong sequence.
11287c478bd9Sstevel@tonic-gate */
sqliteSafetyCheck(sqlite * db)11297c478bd9Sstevel@tonic-gate int sqliteSafetyCheck(sqlite *db){
11307c478bd9Sstevel@tonic-gate if( db->pVdbe!=0 ){
11317c478bd9Sstevel@tonic-gate db->magic = SQLITE_MAGIC_ERROR;
11327c478bd9Sstevel@tonic-gate return 1;
11337c478bd9Sstevel@tonic-gate }
11347c478bd9Sstevel@tonic-gate return 0;
11357c478bd9Sstevel@tonic-gate }
1136