| Index: third_party/sqlite/src/src/printf.c
 | 
| diff --git a/third_party/sqlite/src/src/printf.c b/third_party/sqlite/src/src/printf.c
 | 
| index d8d838693fcd44b6350360f4b2707019a0bbe233..da2fdf610df5ed771b86e44b65e2f6ddeea5ea2f 100644
 | 
| --- a/third_party/sqlite/src/src/printf.c
 | 
| +++ b/third_party/sqlite/src/src/printf.c
 | 
| @@ -5,8 +5,6 @@
 | 
|  ** an historical reference.  Most of the "enhancements" have been backed
 | 
|  ** out so that the functionality is now the same as standard printf().
 | 
|  **
 | 
| -** $Id: printf.c,v 1.104 2009/06/03 01:24:54 drh Exp $
 | 
| -**
 | 
|  **************************************************************************
 | 
|  **
 | 
|  ** The following modules is an enhanced replacement for the "printf" subroutines
 | 
| @@ -462,7 +460,9 @@ void sqlite3VXPrintf(
 | 
|        case etEXP:
 | 
|        case etGENERIC:
 | 
|          realvalue = va_arg(ap,double);
 | 
| -#ifndef SQLITE_OMIT_FLOATING_POINT
 | 
| +#ifdef SQLITE_OMIT_FLOATING_POINT
 | 
| +        length = 0;
 | 
| +#else
 | 
|          if( precision<0 ) precision = 6;         /* Set default precision */
 | 
|          if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
 | 
|          if( realvalue<0.0 ){
 | 
| @@ -608,7 +608,7 @@ void sqlite3VXPrintf(
 | 
|            while( nPad-- ) bufpt[i++] = '0';
 | 
|            length = width;
 | 
|          }
 | 
| -#endif
 | 
| +#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */
 | 
|          break;
 | 
|        case etSIZE:
 | 
|          *(va_arg(ap,int*)) = pAccum->nChar;
 | 
| @@ -647,14 +647,15 @@ void sqlite3VXPrintf(
 | 
|        case etSQLESCAPE:
 | 
|        case etSQLESCAPE2:
 | 
|        case etSQLESCAPE3: {
 | 
| -        int i, j, n, isnull;
 | 
| +        int i, j, k, n, isnull;
 | 
|          int needQuote;
 | 
|          char ch;
 | 
|          char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
 | 
|          char *escarg = va_arg(ap,char*);
 | 
|          isnull = escarg==0;
 | 
|          if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
 | 
| -        for(i=n=0; (ch=escarg[i])!=0; i++){
 | 
| +        k = precision;
 | 
| +        for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
 | 
|            if( ch==q )  n++;
 | 
|          }
 | 
|          needQuote = !isnull && xtype==etSQLESCAPE2;
 | 
| @@ -670,15 +671,17 @@ void sqlite3VXPrintf(
 | 
|          }
 | 
|          j = 0;
 | 
|          if( needQuote ) bufpt[j++] = q;
 | 
| -        for(i=0; (ch=escarg[i])!=0; i++){
 | 
| -          bufpt[j++] = ch;
 | 
| +        k = i;
 | 
| +        for(i=0; i<k; i++){
 | 
| +          bufpt[j++] = ch = escarg[i];
 | 
|            if( ch==q ) bufpt[j++] = ch;
 | 
|          }
 | 
|          if( needQuote ) bufpt[j++] = q;
 | 
|          bufpt[j] = 0;
 | 
|          length = j;
 | 
| -        /* The precision is ignored on %q and %Q */
 | 
| -        /* if( precision>=0 && precision<length ) length = precision; */
 | 
| +        /* The precision in %q and %Q means how many input characters to
 | 
| +        ** consume, not the length of the output...
 | 
| +        ** if( precision>=0 && precision<length ) length = precision; */
 | 
|          break;
 | 
|        }
 | 
|        case etTOKEN: {
 | 
| @@ -769,7 +772,11 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
 | 
|        }else{
 | 
|          p->nAlloc = (int)szNew;
 | 
|        }
 | 
| -      zNew = sqlite3DbMallocRaw(p->db, p->nAlloc );
 | 
| +      if( p->useMalloc==1 ){
 | 
| +        zNew = sqlite3DbMallocRaw(p->db, p->nAlloc );
 | 
| +      }else{
 | 
| +        zNew = sqlite3_malloc(p->nAlloc);
 | 
| +      }
 | 
|        if( zNew ){
 | 
|          memcpy(zNew, p->zText, p->nChar);
 | 
|          sqlite3StrAccumReset(p);
 | 
| @@ -794,7 +801,11 @@ char *sqlite3StrAccumFinish(StrAccum *p){
 | 
|    if( p->zText ){
 | 
|      p->zText[p->nChar] = 0;
 | 
|      if( p->useMalloc && p->zText==p->zBase ){
 | 
| -      p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
 | 
| +      if( p->useMalloc==1 ){
 | 
| +        p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
 | 
| +      }else{
 | 
| +        p->zText = sqlite3_malloc(p->nChar+1);
 | 
| +      }
 | 
|        if( p->zText ){
 | 
|          memcpy(p->zText, p->zBase, p->nChar+1);
 | 
|        }else{
 | 
| @@ -810,7 +821,11 @@ char *sqlite3StrAccumFinish(StrAccum *p){
 | 
|  */
 | 
|  void sqlite3StrAccumReset(StrAccum *p){
 | 
|    if( p->zText!=p->zBase ){
 | 
| -    sqlite3DbFree(p->db, p->zText);
 | 
| +    if( p->useMalloc==1 ){
 | 
| +      sqlite3DbFree(p->db, p->zText);
 | 
| +    }else{
 | 
| +      sqlite3_free(p->zText);
 | 
| +    }
 | 
|    }
 | 
|    p->zText = 0;
 | 
|  }
 | 
| @@ -892,6 +907,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
 | 
|    if( sqlite3_initialize() ) return 0;
 | 
|  #endif
 | 
|    sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
 | 
| +  acc.useMalloc = 2;
 | 
|    sqlite3VXPrintf(&acc, 0, zFormat, ap);
 | 
|    z = sqlite3StrAccumFinish(&acc);
 | 
|    return z;
 | 
| @@ -936,6 +952,38 @@ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
 | 
|    return z;
 | 
|  }
 | 
|  
 | 
| +/*
 | 
| +** This is the routine that actually formats the sqlite3_log() message.
 | 
| +** We house it in a separate routine from sqlite3_log() to avoid using
 | 
| +** stack space on small-stack systems when logging is disabled.
 | 
| +**
 | 
| +** sqlite3_log() must render into a static buffer.  It cannot dynamically
 | 
| +** allocate memory because it might be called while the memory allocator
 | 
| +** mutex is held.
 | 
| +*/
 | 
| +static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
 | 
| +  StrAccum acc;                          /* String accumulator */
 | 
| +  char zMsg[SQLITE_PRINT_BUF_SIZE*3];    /* Complete log message */
 | 
| +
 | 
| +  sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
 | 
| +  acc.useMalloc = 0;
 | 
| +  sqlite3VXPrintf(&acc, 0, zFormat, ap);
 | 
| +  sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
 | 
| +                           sqlite3StrAccumFinish(&acc));
 | 
| +}
 | 
| +
 | 
| +/*
 | 
| +** Format and write a message to the log if logging is enabled.
 | 
| +*/
 | 
| +void sqlite3_log(int iErrCode, const char *zFormat, ...){
 | 
| +  va_list ap;                             /* Vararg list */
 | 
| +  if( sqlite3GlobalConfig.xLog ){
 | 
| +    va_start(ap, zFormat);
 | 
| +    renderLogMsg(iErrCode, zFormat, ap);
 | 
| +    va_end(ap);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  #if defined(SQLITE_DEBUG)
 | 
|  /*
 | 
|  ** A version of printf() that understands %lld.  Used for debugging.
 | 
| @@ -956,3 +1004,15 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
 | 
|    fflush(stdout);
 | 
|  }
 | 
|  #endif
 | 
| +
 | 
| +#ifndef SQLITE_OMIT_TRACE
 | 
| +/*
 | 
| +** variable-argument wrapper around sqlite3VXPrintf().
 | 
| +*/
 | 
| +void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
 | 
| +  va_list ap;
 | 
| +  va_start(ap,zFormat);
 | 
| +  sqlite3VXPrintf(p, 1, zFormat, ap);
 | 
| +  va_end(ap);
 | 
| +}
 | 
| +#endif
 | 
| 
 |