xref: /illumos-gate/usr/src/lib/libsqlite/src/util.c (revision 1da57d55)
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