/ Check-in [2756f7af]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Cleanup the printf code to make it smaller and more modular. Fix a memory leak in the new OP_ContextPush opcode. (CVS 1258)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2756f7af3382fa9d186ab99cf76f469fb891a3c3
User & Date: drh 2004-02-21 19:02:30
Context
2004-02-21
19:17
Fix a long-standing memory leak that the new last_insert_rowid() tests brought to light. (CVS 1259) check-in: 7d5ede5b user: drh tags: trunk
19:02
Cleanup the printf code to make it smaller and more modular. Fix a memory leak in the new OP_ContextPush opcode. (CVS 1258) check-in: 2756f7af user: drh tags: trunk
14:00
Flag pragmas like vdbe_trace now return their current setting if they are called with no arguments. (CVS 1257) check-in: 6a5fb5b8 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/printf.c.

    48     48   **         faster than the library printf for SUN OS 4.1.
    49     49   **
    50     50   **      +  All functions are fully reentrant.
    51     51   **
    52     52   */
    53     53   #include "sqliteInt.h"
    54     54   
    55         -/*
    56         -** Undefine COMPATIBILITY to make some slight changes in the way things
    57         -** work.  I think the changes are an improvement, but they are not
    58         -** backwards compatible.
    59         -*/
    60         -/* #define COMPATIBILITY       / * Compatible with SUN OS 4.1 */
    61         -
    62     55   /*
    63     56   ** Conversion types fall into various categories as defined by the
    64     57   ** following enumeration.
    65     58   */
    66     59   #define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
    67     60   #define etFLOAT       2 /* Floating point.  %f */
    68     61   #define etEXP         3 /* Exponentional notation. %e and %E */
................................................................................
    74     67   #define etCHARX       9 /* Characters. %c */
    75     68   #define etERROR      10 /* Used to indicate no such conversion type */
    76     69   /* The rest are extensions, not normally found in printf() */
    77     70   #define etCHARLIT    11 /* Literal characters.  %' */
    78     71   #define etSQLESCAPE  12 /* Strings with '\'' doubled.  %q */
    79     72   #define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
    80     73                             NULL pointers replaced by SQL NULL.  %Q */
           74  +#define etTOKEN      14 /* a pointer to a Token structure */
           75  +#define etSRCLIST    15 /* a pointer to a SrcList */
    81     76   
    82     77   
    83     78   /*
    84     79   ** An "etByte" is an 8-bit unsigned value.
    85     80   */
    86     81   typedef unsigned char etByte;
    87     82   
................................................................................
   125    120     {  'E',  0, 1, etEXP,        "E",                0    },
   126    121     {  'g',  0, 1, etGENERIC,    "e",                0    },
   127    122     {  'G',  0, 1, etGENERIC,    "E",                0    },
   128    123     {  'i', 10, 1, etRADIX,      "0123456789",       0    },
   129    124     {  'n',  0, 0, etSIZE,       0,                  0    },
   130    125     {  '%',  0, 0, etPERCENT,    0,                  0    },
   131    126     {  'p', 10, 0, etRADIX,      "0123456789",       0    },
          127  +  {  'T',  0, 2, etTOKEN,      0,                  0    },
          128  +  {  'S',  0, 2, etSRCLIST,    0,                  0    },
   132    129   };
   133    130   #define etNINFO  (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
   134    131   
   135    132   /*
   136    133   ** If NOFLOATINGPOINT is defined, then none of the floating point
   137    134   ** conversions will work.
   138    135   */
................................................................................
   188    185   **          the function "func".  Returns -1 on a error.
   189    186   **
   190    187   ** Note that the order in which automatic variables are declared below
   191    188   ** seems to make a big difference in determining how fast this beast
   192    189   ** will run.
   193    190   */
   194    191   static int vxprintf(
   195         -  void (*func)(void*,char*,int),
   196         -  void *arg,
   197         -  const char *fmt,
   198         -  va_list ap
          192  +  void (*func)(void*,const char*,int),     /* Consumer of text */
          193  +  void *arg,                         /* First argument to the consumer */
          194  +  int useExtended,                   /* Allow extended %-conversions */
          195  +  const char *fmt,                   /* Format string */
          196  +  va_list ap                         /* arguments */
   199    197   ){
   200    198     int c;                     /* Next character in the format string */
   201    199     char *bufpt;               /* Pointer to the conversion buffer */
   202    200     int precision;             /* Precision of the current field */
   203    201     int length;                /* Length of the field */
   204    202     int idx;                   /* A general purpose loop counter */
   205    203     int count;                 /* Total number of characters output */
................................................................................
   280    278       }
   281    279       /* Get the precision */
   282    280       if( c=='.' ){
   283    281         precision = 0;
   284    282         c = *++fmt;
   285    283         if( c=='*' ){
   286    284           precision = va_arg(ap,int);
   287         -#ifndef etCOMPATIBILITY
   288         -        /* This is sensible, but SUN OS 4.1 doesn't do it. */
   289    285           if( precision<0 ) precision = -precision;
   290         -#endif
   291    286           c = *++fmt;
   292    287         }else{
   293    288           while( c>='0' && c<='9' ){
   294    289             precision = precision*10 + c - '0';
   295    290             c = *++fmt;
   296    291           }
   297    292         }
................................................................................
   309    304       }
   310    305       /* Fetch the info entry for the field */
   311    306       infop = 0;
   312    307       xtype = etERROR;
   313    308       for(idx=0; idx<etNINFO; idx++){
   314    309         if( c==fmtinfo[idx].fmttype ){
   315    310           infop = &fmtinfo[idx];
   316         -        xtype = infop->type;
          311  +        if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
          312  +          xtype = infop->type;
          313  +        }
   317    314           break;
   318    315         }
   319    316       }
   320    317       zExtra = 0;
   321    318   
   322    319       /*
   323    320       ** At this point, variables are initialized as follows:
................................................................................
   337    334       **   xtype                       The class of the conversion.
   338    335       **   infop                       Pointer to the appropriate info struct.
   339    336       */
   340    337       switch( xtype ){
   341    338         case etRADIX:
   342    339           if( flag_long )  longvalue = va_arg(ap,long);
   343    340           else             longvalue = va_arg(ap,int);
   344         -#ifdef etCOMPATIBILITY
          341  +#if 1
   345    342           /* For the format %#x, the value zero is printed "0" not "0x0".
   346    343           ** I think this is stupid. */
   347    344           if( longvalue==0 ) flag_alternateform = 0;
   348    345   #else
   349    346           /* More sensible: turn off the prefix for octal (to prevent "00"),
   350    347           ** but leave the prefix for hex. */
   351    348           if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;
................................................................................
   399    396           }else{
   400    397             if( flag_plussign )          prefix = '+';
   401    398             else if( flag_blanksign )    prefix = ' ';
   402    399             else                         prefix = 0;
   403    400           }
   404    401           if( infop->type==etGENERIC && precision>0 ) precision--;
   405    402           rounder = 0.0;
   406         -#ifdef COMPATIBILITY
          403  +#if 0
   407    404           /* Rounding works like BSD when the constant 0.4999 is used.  Wierd! */
   408    405           for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
   409    406   #else
   410    407           /* It makes more sense to use 0.5 */
   411    408           for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
   412    409   #endif
   413    410           if( infop->type==etFLOAT ) realvalue += rounder;
................................................................................
   567    564             }
   568    565             if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
   569    566             bufpt[j] = 0;
   570    567             length = j;
   571    568             if( precision>=0 && precision<length ) length = precision;
   572    569           }
   573    570           break;
          571  +      case etTOKEN: {
          572  +        Token *pToken = va_arg(ap, Token*);
          573  +        (*func)(arg, pToken->z, pToken->n);
          574  +        length = width = 0;
          575  +        break;
          576  +      }
          577  +      case etSRCLIST: {
          578  +        SrcList *pSrc = va_arg(ap, SrcList*);
          579  +        int k = va_arg(ap, int);
          580  +        struct SrcList_item *pItem = &pSrc->a[k];
          581  +        assert( k>=0 && k<pSrc->nSrc );
          582  +        if( pItem->zDatabase && pItem->zDatabase[0] ){
          583  +          (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase));
          584  +          (*func)(arg, ".", 1);
          585  +        }
          586  +        (*func)(arg, pItem->zName, strlen(pItem->zName));
          587  +        length = width = 0;
          588  +        break;
          589  +      }
   574    590         case etERROR:
   575    591           buf[0] = '%';
   576    592           buf[1] = c;
   577    593           errorflag = 0;
   578    594           idx = 1+(c!=0);
   579    595           (*func)(arg,"%",idx);
   580    596           count += idx;
................................................................................
   611    627             (*func)(arg,spaces,etSPACESIZE);
   612    628             nspace -= etSPACESIZE;
   613    629           }
   614    630           if( nspace>0 ) (*func)(arg,spaces,nspace);
   615    631         }
   616    632       }
   617    633       if( zExtra ){
   618         -      if( xtype==etDYNSTRING ){
   619         -        free(zExtra);
   620         -      }else{
   621         -        sqliteFree(zExtra);
   622         -      }
          634  +      sqliteFree(zExtra);
   623    635       }
   624    636     }/* End for loop over the format string */
   625    637     return errorflag ? -1 : count;
   626    638   } /* End of function */
   627    639   
   628    640   
   629    641   /* This structure is used to store state information about the
   630    642   ** write to memory that is currently in progress.
   631    643   */
   632    644   struct sgMprintf {
   633    645     char *zBase;     /* A base allocation */
   634    646     char *zText;     /* The string collected so far */
   635    647     int  nChar;      /* Length of the string so far */
          648  +  int  nTotal;     /* Output size if unconstrained */
   636    649     int  nAlloc;     /* Amount of space allocated in zText */
          650  +  void *(*xRealloc)(void*,int);  /* Function used to realloc memory */
   637    651   };
   638    652   
   639    653   /* 
   640    654   ** This function implements the callback from vxprintf. 
   641    655   **
   642    656   ** This routine add nNewChar characters of text in zNewText to
   643    657   ** the sgMprintf structure pointed to by "arg".
   644    658   */
   645         -static void mout(void *arg, char *zNewText, int nNewChar){
          659  +static void mout(void *arg, const char *zNewText, int nNewChar){
   646    660     struct sgMprintf *pM = (struct sgMprintf*)arg;
          661  +  pM->nTotal += nNewChar;
   647    662     if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
   648         -    pM->nAlloc = pM->nChar + nNewChar*2 + 1;
   649         -    if( pM->zText==pM->zBase ){
   650         -      pM->zText = sqliteMalloc(pM->nAlloc);
   651         -      if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar);
          663  +    if( pM->xRealloc==0 ){
          664  +      nNewChar =  pM->nAlloc - pM->nChar - 1;
   652    665       }else{
   653         -      char *z = sqliteRealloc(pM->zText, pM->nAlloc);
   654         -      if( z==0 ){
   655         -        sqliteFree(pM->zText);
   656         -        pM->nChar = 0;
   657         -        pM->nAlloc = 0;
          666  +      pM->nAlloc = pM->nChar + nNewChar*2 + 1;
          667  +      if( pM->zText==pM->zBase ){
          668  +        pM->zText = pM->xRealloc(0, pM->nAlloc);
          669  +        if( pM->zText && pM->nChar ){
          670  +          memcpy(pM->zText, pM->zBase, pM->nChar);
          671  +        }
          672  +      }else{
          673  +        pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
   658    674         }
   659         -      pM->zText = z;
   660    675       }
   661    676     }
   662         -  if( pM->zText ){
          677  +  if( pM->zText && nNewChar>0 ){
   663    678       memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
   664    679       pM->nChar += nNewChar;
   665    680       pM->zText[pM->nChar] = 0;
   666    681     }
   667    682   }
   668    683   
   669    684   /*
   670         -** sqlite_mprintf() works like printf(), but allocations memory to hold the
   671         -** resulting string and returns a pointer to the allocated memory.  Use
   672         -** sqliteFree() to release the memory allocated.
          685  +** This routine is a wrapper around xprintf() that invokes mout() as
          686  +** the consumer.  
          687  +*/
          688  +static char *base_vprintf(
          689  +  void *(*xRealloc)(void*,int),   /* Routine to realloc memory. May be NULL */
          690  +  int useInternal,                /* Use internal %-conversions if true */
          691  +  char *zInitBuf,                 /* Initially write here, before mallocing */
          692  +  int nInitBuf,                   /* Size of zInitBuf[] */
          693  +  const char *zFormat,            /* format string */
          694  +  va_list ap                      /* arguments */
          695  +){
          696  +  struct sgMprintf sM;
          697  +  sM.zBase = sM.zText = zInitBuf;
          698  +  sM.nChar = sM.nTotal = 0;
          699  +  sM.nAlloc = nInitBuf;
          700  +  sM.xRealloc = xRealloc;
          701  +  vxprintf(mout, &sM, useInternal, zFormat, ap);
          702  +  if( xRealloc ){
          703  +    if( sM.zText==sM.zBase ){
          704  +      sM.zText = xRealloc(0, sM.nChar+1);
          705  +      memcpy(sM.zText, sM.zBase, sM.nChar+1);
          706  +    }else if( sM.nAlloc>sM.nChar+10 ){
          707  +      sM.zText = xRealloc(sM.zText, sM.nChar+1);
          708  +    }
          709  +  }
          710  +  return sM.zText;
          711  +}
          712  +
          713  +/*
          714  +** Realloc that is a real function, not a macro.
          715  +*/
          716  +static void *printf_realloc(void *old, int size){
          717  +  return sqliteRealloc(old,size);
          718  +}
          719  +
          720  +/*
          721  +** Print into memory obtained from sqliteMalloc().  Use the internal
          722  +** %-conversion extensions.
          723  +*/
          724  +char *sqliteVMPrintf(const char *zFormat, va_list ap){
          725  +  char zBase[1000];
          726  +  return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
          727  +}
          728  +
          729  +/*
          730  +** Print into memory obtained from sqliteMalloc().  Use the internal
          731  +** %-conversion extensions.
   673    732   */
   674    733   char *sqliteMPrintf(const char *zFormat, ...){
   675    734     va_list ap;
   676         -  struct sgMprintf sMprintf;
   677         -  char zBuf[200];
   678         -
   679         -  sMprintf.nChar = 0;
   680         -  sMprintf.nAlloc = sizeof(zBuf);
   681         -  sMprintf.zText = zBuf;
   682         -  sMprintf.zBase = zBuf;
   683         -  va_start(ap,zFormat);
   684         -  vxprintf(mout,&sMprintf,zFormat,ap);
          735  +  char *z;
          736  +  char zBase[1000];
          737  +  va_start(ap, zFormat);
          738  +  z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
   685    739     va_end(ap);
   686         -  sMprintf.zText[sMprintf.nChar] = 0;
   687         -  return sqliteRealloc(sMprintf.zText, sMprintf.nChar+1);
          740  +  return z;
   688    741   }
   689    742   
   690    743   /*
   691         -** sqlite_mprintf() works like printf(), but allocations memory to hold the
   692         -** resulting string and returns a pointer to the allocated memory.  Use
   693         -** sqliteFree() to release the memory allocated.
          744  +** Print into memory obtained from malloc().  Do not use the internal
          745  +** %-conversion extensions.  This routine is for use by external users.
   694    746   */
   695    747   char *sqlite_mprintf(const char *zFormat, ...){
   696    748     va_list ap;
   697         -  struct sgMprintf sMprintf;
   698         -  char *zNew;
          749  +  char *z;
   699    750     char zBuf[200];
   700    751   
   701         -  sMprintf.nChar = 0;
   702         -  sMprintf.nAlloc = sizeof(zBuf);
   703         -  sMprintf.zText = zBuf;
   704         -  sMprintf.zBase = zBuf;
   705    752     va_start(ap,zFormat);
   706         -  vxprintf(mout,&sMprintf,zFormat,ap);
          753  +  z = base_vprintf((void*(*)(void*,int))realloc, 0, 
          754  +                   zBuf, sizeof(zBuf), zFormat, ap);
   707    755     va_end(ap);
   708         -  sMprintf.zText[sMprintf.nChar] = 0;
   709         -  zNew = malloc( sMprintf.nChar+1 );
   710         -  if( zNew ) strcpy(zNew,sMprintf.zText);
   711         -  if( sMprintf.zText!=sMprintf.zBase ){
   712         -    sqliteFree(sMprintf.zText);
   713         -  }
   714         -  return zNew;
          756  +  return z;
   715    757   }
   716    758   
   717    759   /* This is the varargs version of sqlite_mprintf.  
   718    760   */
   719    761   char *sqlite_vmprintf(const char *zFormat, va_list ap){
   720         -  struct sgMprintf sMprintf;
   721         -  char *zNew;
   722    762     char zBuf[200];
   723         -  sMprintf.nChar = 0;
   724         -  sMprintf.zText = zBuf;
   725         -  sMprintf.nAlloc = sizeof(zBuf);
   726         -  sMprintf.zBase = zBuf;
   727         -  vxprintf(mout,&sMprintf,zFormat,ap);
   728         -  sMprintf.zText[sMprintf.nChar] = 0;
   729         -  zNew = malloc( sMprintf.nChar+1 );
   730         -  if( zNew ) strcpy(zNew,sMprintf.zText);
   731         -  if( sMprintf.zText!=sMprintf.zBase ){
   732         -    sqliteFree(sMprintf.zText);
   733         -  }
   734         -  return zNew;
   735         -}
   736         -
   737         -/* 
   738         -** This function implements the callback from vxprintf. 
   739         -**
   740         -** This routine add nNewChar characters of text in zNewText to
   741         -** the sgMprintf structure pointed to by "arg".  Unlike mout() above,
   742         -** this routine does not allocate new space when the buffer fills.
   743         -** It just truncates.
   744         -*/
   745         -static void sout(void *arg, char *zNewText, int nNewChar){
   746         -  struct sgMprintf *pM = (struct sgMprintf*)arg;
   747         -  if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
   748         -    nNewChar = pM->nAlloc - pM->nChar - 1;
   749         -    if( nNewChar<=0 ) return;
   750         -  }
   751         -  memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
   752         -  pM->nChar += nNewChar;
   753         -  pM->zText[pM->nChar] = 0;
          763  +  return base_vprintf((void*(*)(void*,int))realloc, 0,
          764  +                      zBuf, sizeof(zBuf), zFormat, ap);
   754    765   }
   755    766   
   756    767   /*
   757         -** sqlite_sprintf() works like sprintf() except that it ignores the
          768  +** sqlite_snprintf() works like snprintf() except that it ignores the
   758    769   ** current locale settings.  This is important for SQLite because we
   759    770   ** are not able to use a "," as the decimal point in place of "." as
   760    771   ** specified by some locales.
   761    772   */
   762         -int sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
          773  +char *sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
          774  +  char *z;
   763    775     va_list ap;
   764         -  struct sgMprintf sMprintf;
   765    776   
   766         -  sMprintf.nChar = 0;
   767         -  sMprintf.nAlloc = n;
   768         -  sMprintf.zText = zBuf;
   769         -  sMprintf.zBase = zBuf;
   770    777     va_start(ap,zFormat);
   771         -  vxprintf(sout,&sMprintf,zFormat,ap);
          778  +  z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
   772    779     va_end(ap);
   773         -  return sMprintf.nChar;
          780  +  return z;
   774    781   }
   775         -
   776         -
   777    782   
   778    783   /*
   779    784   ** The following four routines implement the varargs versions of the
   780    785   ** sqlite_exec() and sqlite_get_table() interfaces.  See the sqlite.h
   781    786   ** header files for a more detailed description of how these interfaces
   782    787   ** work.
   783    788   **

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.216 2004/02/21 13:31:10 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.217 2004/02/21 19:02:30 drh Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite.h"
    18     18   #include "hash.h"
    19     19   #include "parse.h"
    20     20   #include "btree.h"
    21     21   #include <stdio.h>
................................................................................
   178    178   # define sqliteMallocRaw(X) sqliteMalloc_(X,0,__FILE__,__LINE__)
   179    179   # define sqliteFree(X)      sqliteFree_(X,__FILE__,__LINE__)
   180    180   # define sqliteRealloc(X,Y) sqliteRealloc_(X,Y,__FILE__,__LINE__)
   181    181   # define sqliteStrDup(X)    sqliteStrDup_(X,__FILE__,__LINE__)
   182    182   # define sqliteStrNDup(X,Y) sqliteStrNDup_(X,Y,__FILE__,__LINE__)
   183    183     void sqliteStrRealloc(char**);
   184    184   #else
          185  +# define sqliteRealloc_(X,Y) sqliteRealloc(X,Y)
   185    186   # define sqliteStrRealloc(X)
   186    187   #endif
   187    188   
   188    189   /*
   189    190   ** This variable gets set if malloc() ever fails.  After it gets set,
   190    191   ** the SQLite library shuts down permanently.
   191    192   */
................................................................................
  1107   1108     void *sqliteMallocRaw(int);
  1108   1109     void sqliteFree(void*);
  1109   1110     void *sqliteRealloc(void*,int);
  1110   1111     char *sqliteStrDup(const char*);
  1111   1112     char *sqliteStrNDup(const char*, int);
  1112   1113   # define sqliteCheckMemory(a,b)
  1113   1114   #endif
  1114         -char *sqliteMPrintf(const char *,...);
         1115  +char *sqliteMPrintf(const char*, ...);
         1116  +char *sqliteVMPrintf(const char*, va_list);
  1115   1117   void sqliteSetString(char **, const char *, ...);
  1116   1118   void sqliteSetNString(char **, ...);
  1117   1119   void sqliteErrorMsg(Parse*, const char*, ...);
  1118   1120   void sqliteDequote(char*);
  1119   1121   int sqliteKeywordCode(const char*, int);
  1120   1122   int sqliteRunParser(Parse*, const char*, char **);
  1121   1123   void sqliteExec(Parse*);
................................................................................
  1252   1254   int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*);
  1253   1255   int sqliteFixSrcList(DbFixer*, SrcList*);
  1254   1256   int sqliteFixSelect(DbFixer*, Select*);
  1255   1257   int sqliteFixExpr(DbFixer*, Expr*);
  1256   1258   int sqliteFixExprList(DbFixer*, ExprList*);
  1257   1259   int sqliteFixTriggerStep(DbFixer*, TriggerStep*);
  1258   1260   double sqliteAtoF(const char *z);
  1259         -int sqlite_snprintf(int,char*,const char*,...);
         1261  +char *sqlite_snprintf(int,char*,const char*,...);
  1260   1262   int sqliteFitsIn32Bits(const char *);

Changes to src/test1.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the printf() interface to SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test1.c,v 1.33 2004/02/08 18:07:35 drh Exp $
           16  +** $Id: test1.c,v 1.34 2004/02/21 19:02:30 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include "os.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
................................................................................
   176    176     int argc,              /* Number of arguments */
   177    177     char **argv            /* Text of each argument */
   178    178   ){
   179    179     char *zResult = 0;
   180    180     int i;
   181    181   
   182    182     for(i=2; i<argc; i++){
   183         -    zResult = sqlite_mprintf("%z%s%s", zResult, argv[1], argv[i]);
          183  +    zResult = sqliteMPrintf("%z%s%s", zResult, argv[1], argv[i]);
   184    184     }
   185    185     Tcl_AppendResult(interp, zResult, 0);
   186         -  sqlite_freemem(zResult);
          186  +  sqliteFree(zResult);
   187    187     return TCL_OK;
   188    188   }
   189    189   
   190    190   /*
   191    191   ** Usage:  sqlite_get_table_printf  DB  FORMAT  STRING
   192    192   **
   193    193   ** Invoke the sqlite_get_table_printf() interface using the open database

Changes to src/util.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Utility functions used throughout sqlite.
    13     13   **
    14     14   ** This file contains functions for allocating memory, comparing
    15     15   ** strings, and stuff like that.
    16     16   **
    17         -** $Id: util.c,v 1.72 2004/01/07 03:41:04 drh Exp $
           17  +** $Id: util.c,v 1.73 2004/02/21 19:02:31 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <stdarg.h>
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** If malloc() ever fails, this global variable gets set to 1.
................................................................................
   413    413   **      %z      A string that should be freed after use
   414    414   **      %d      Insert an integer
   415    415   **      %T      Insert a token
   416    416   **      %S      Insert the first element of a SrcList
   417    417   */
   418    418   void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){
   419    419     va_list ap;
   420         -  int nByte;
   421         -  int i, j;
   422         -  char *z;
   423         -  static char zNull[] = "NULL";
   424         -
   425    420     pParse->nErr++;
   426         -  nByte = 1 + strlen(zFormat);
          421  +  sqliteFree(pParse->zErrMsg);
   427    422     va_start(ap, zFormat);
   428         -  for(i=0; zFormat[i]; i++){
   429         -    if( zFormat[i]!='%' || zFormat[i+1]==0 ) continue;
   430         -    i++;
   431         -    switch( zFormat[i] ){
   432         -      case 'd': {
   433         -        (void)va_arg(ap, int);
   434         -        nByte += 20;
   435         -        break;
   436         -      }
   437         -      case 'z':
   438         -      case 's': {
   439         -        char *z2 = va_arg(ap, char*);
   440         -        if( z2==0 ) z2 = zNull;
   441         -        nByte += strlen(z2);
   442         -        break;
   443         -      }
   444         -      case 'T': {
   445         -        Token *p = va_arg(ap, Token*);
   446         -        nByte += p->n;
   447         -        break;
   448         -      }
   449         -      case 'S': {
   450         -        SrcList *p = va_arg(ap, SrcList*);
   451         -        int k = va_arg(ap, int);
   452         -        assert( p->nSrc>k && k>=0 );
   453         -        nByte += strlen(p->a[k].zName);
   454         -        if( p->a[k].zDatabase && p->a[k].zDatabase[0] ){
   455         -          nByte += strlen(p->a[k].zDatabase)+1;
   456         -        }
   457         -        break;
   458         -      }
   459         -      default: {
   460         -        nByte++;
   461         -        break;
   462         -      }
   463         -    }
   464         -  }
          423  +  pParse->zErrMsg = sqliteVMPrintf(zFormat, ap);
   465    424     va_end(ap);
   466         -  z = sqliteMalloc( nByte );
   467         -  if( z==0 ) return;
   468         -  sqliteFree(pParse->zErrMsg);
   469         -  pParse->zErrMsg = z;
   470         -  va_start(ap, zFormat);
   471         -  for(i=j=0; zFormat[i]; i++){
   472         -    if( zFormat[i]!='%' || zFormat[i+1]==0 ) continue;
   473         -    if( i>j ){
   474         -      memcpy(z, &zFormat[j], i-j);
   475         -      z += i-j;
   476         -    }
   477         -    j = i+2;
   478         -    i++;
   479         -    switch( zFormat[i] ){
   480         -      case 'd': {
   481         -        int x = va_arg(ap, int);
   482         -        sprintf(z, "%d", x);
   483         -        z += strlen(z);
   484         -        break;
   485         -      }
   486         -      case 'z':
   487         -      case 's': {
   488         -        int len;
   489         -        char *z2 = va_arg(ap, char*);
   490         -        if( z2==0 ) z2 = zNull;
   491         -        len = strlen(z2);
   492         -        memcpy(z, z2, len);
   493         -        z += len;
   494         -        if( zFormat[i]=='z' && z2!=zNull ){
   495         -          sqliteFree(z2);
   496         -        }
   497         -        break;
   498         -      }
   499         -      case 'T': {
   500         -        Token *p = va_arg(ap, Token*);
   501         -        memcpy(z, p->z, p->n);
   502         -        z += p->n;
   503         -        break;
   504         -      }
   505         -      case 'S': {
   506         -        int len;
   507         -        SrcList *p = va_arg(ap, SrcList*);
   508         -        int k = va_arg(ap, int);
   509         -        assert( p->nSrc>k && k>=0 );
   510         -        if( p->a[k].zDatabase && p->a[k].zDatabase[0] ){
   511         -          len = strlen(p->a[k].zDatabase);
   512         -          memcpy(z, p->a[k].zDatabase, len);
   513         -          z += len;
   514         -          *(z++) = '.';
   515         -        }
   516         -        len = strlen(p->a[k].zName);
   517         -        memcpy(z, p->a[k].zName, len);
   518         -        z += len;
   519         -        break;
   520         -      }
   521         -      default: {
   522         -        *(z++) = zFormat[i];
   523         -        break;
   524         -      }
   525         -    }
   526         -  }
   527         -  va_end(ap);
   528         -  if( i>j ){
   529         -    memcpy(z, &zFormat[j], i-j);
   530         -    z += i-j;
   531         -  }
   532         -  assert( (z - pParse->zErrMsg) < nByte );
   533         -  *z = 0;
   534    425   }
   535    426   
   536    427   /*
   537    428   ** Convert an SQL-style quoted string into a normal string by removing
   538    429   ** the quote characters.  The conversion is done in-place.  If the
   539    430   ** input does not begin with a quote character, then this routine
   540    431   ** is a no-op.

Changes to src/vdbeaux.c.

   783    783       for(ii = 0; ii < p->keylistStackDepth; ii++){
   784    784         sqliteVdbeKeylistFree(p->keylistStack[ii]);
   785    785       }
   786    786       sqliteFree(p->keylistStack);
   787    787       p->keylistStackDepth = 0;
   788    788       p->keylistStack = 0;
   789    789     }
          790  +  sqliteFree(p->contextStack);
          791  +  p->contextStack = 0;
   790    792     sqliteFree(p->zErrMsg);
   791    793     p->zErrMsg = 0;
   792    794   }
   793    795   
   794    796   /*
   795    797   ** Clean up a VDBE after execution but do not delete the VDBE just yet.
   796    798   ** Write any error messages into *pzErrMsg.  Return the result code.