| 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
|
|
|