| Index: third_party/sqlite/sqlite-src-3100200/src/printf.c
|
| diff --git a/third_party/sqlite/src/src/printf.c b/third_party/sqlite/sqlite-src-3100200/src/printf.c
|
| similarity index 84%
|
| copy from third_party/sqlite/src/src/printf.c
|
| copy to third_party/sqlite/sqlite-src-3100200/src/printf.c
|
| index 387b9e90c18e241a983095429b235d0b2d95f1ec..969950c15484c9e4c8263923fb7b6554885688c8 100644
|
| --- a/third_party/sqlite/src/src/printf.c
|
| +++ b/third_party/sqlite/sqlite-src-3100200/src/printf.c
|
| @@ -1,31 +1,17 @@
|
| /*
|
| ** The "printf" code that follows dates from the 1980's. It is in
|
| -** the public domain. The original comments are included here for
|
| -** completeness. They are very out-of-date but might be useful as
|
| -** an historical reference. Most of the "enhancements" have been backed
|
| -** out so that the functionality is now the same as standard printf().
|
| +** the public domain.
|
| **
|
| **************************************************************************
|
| **
|
| ** This file contains code for a set of "printf"-like routines. These
|
| ** routines format strings much like the printf() from the standard C
|
| ** library, though the implementation here has enhancements to support
|
| -** SQLlite.
|
| +** SQLite.
|
| */
|
| #include "sqliteInt.h"
|
|
|
| /*
|
| -** If the strchrnul() library function is available, then set
|
| -** HAVE_STRCHRNUL. If that routine is not available, this module
|
| -** will supply its own. The built-in version is slower than
|
| -** the glibc version so the glibc version is definitely preferred.
|
| -*/
|
| -#if !defined(HAVE_STRCHRNUL)
|
| -# define HAVE_STRCHRNUL 0
|
| -#endif
|
| -
|
| -
|
| -/*
|
| ** Conversion types fall into various categories as defined by the
|
| ** following enumeration.
|
| */
|
| @@ -149,6 +135,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
|
| ** Set the StrAccum object to an error mode.
|
| */
|
| static void setStrAccumError(StrAccum *p, u8 eError){
|
| + assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
|
| p->accError = eError;
|
| p->nAlloc = 0;
|
| }
|
| @@ -263,7 +250,6 @@ void sqlite3VXPrintf(
|
| }
|
| }while( !done && (c=(*++fmt))!=0 );
|
| /* Get the field width */
|
| - width = 0;
|
| if( c=='*' ){
|
| if( bArgList ){
|
| width = (int)getIntArg(pArgList);
|
| @@ -272,18 +258,27 @@ void sqlite3VXPrintf(
|
| }
|
| if( width<0 ){
|
| flag_leftjustify = 1;
|
| - width = -width;
|
| + width = width >= -2147483647 ? -width : 0;
|
| }
|
| c = *++fmt;
|
| }else{
|
| + unsigned wx = 0;
|
| while( c>='0' && c<='9' ){
|
| - width = width*10 + c - '0';
|
| + wx = wx*10 + c - '0';
|
| c = *++fmt;
|
| }
|
| + testcase( wx>0x7fffffff );
|
| + width = wx & 0x7fffffff;
|
| + }
|
| + assert( width>=0 );
|
| +#ifdef SQLITE_PRINTF_PRECISION_LIMIT
|
| + if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
|
| + width = SQLITE_PRINTF_PRECISION_LIMIT;
|
| }
|
| +#endif
|
| +
|
| /* Get the precision */
|
| if( c=='.' ){
|
| - precision = 0;
|
| c = *++fmt;
|
| if( c=='*' ){
|
| if( bArgList ){
|
| @@ -291,17 +286,30 @@ void sqlite3VXPrintf(
|
| }else{
|
| precision = va_arg(ap,int);
|
| }
|
| - if( precision<0 ) precision = -precision;
|
| c = *++fmt;
|
| + if( precision<0 ){
|
| + precision = precision >= -2147483647 ? -precision : -1;
|
| + }
|
| }else{
|
| + unsigned px = 0;
|
| while( c>='0' && c<='9' ){
|
| - precision = precision*10 + c - '0';
|
| + px = px*10 + c - '0';
|
| c = *++fmt;
|
| }
|
| + testcase( px>0x7fffffff );
|
| + precision = px & 0x7fffffff;
|
| }
|
| }else{
|
| precision = -1;
|
| }
|
| + assert( precision>=(-1) );
|
| +#ifdef SQLITE_PRINTF_PRECISION_LIMIT
|
| + if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
|
| + precision = SQLITE_PRINTF_PRECISION_LIMIT;
|
| + }
|
| +#endif
|
| +
|
| +
|
| /* Get the conversion type modifier */
|
| if( c=='l' ){
|
| flag_long = 1;
|
| @@ -461,7 +469,8 @@ void sqlite3VXPrintf(
|
| else prefix = 0;
|
| }
|
| if( xtype==etGENERIC && precision>0 ) precision--;
|
| - for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
|
| + testcase( precision>0xfff );
|
| + for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
|
| if( xtype==etFLOAT ) realvalue += rounder;
|
| /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
|
| exp = 0;
|
| @@ -473,21 +482,16 @@ void sqlite3VXPrintf(
|
| if( realvalue>0.0 ){
|
| LONGDOUBLE_TYPE scale = 1.0;
|
| while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
|
| - while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
|
| - while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
|
| + while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; }
|
| while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
|
| realvalue /= scale;
|
| while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
|
| while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
|
| if( exp>350 ){
|
| - if( prefix=='-' ){
|
| - bufpt = "-Inf";
|
| - }else if( prefix=='+' ){
|
| - bufpt = "+Inf";
|
| - }else{
|
| - bufpt = "Inf";
|
| - }
|
| - length = sqlite3Strlen30(bufpt);
|
| + bufpt = buf;
|
| + buf[0] = prefix;
|
| + memcpy(buf+(prefix!=0),"Inf",4);
|
| + length = 3+(prefix!=0);
|
| break;
|
| }
|
| }
|
| @@ -516,8 +520,9 @@ void sqlite3VXPrintf(
|
| }else{
|
| e2 = exp;
|
| }
|
| - if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
|
| - bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
|
| + if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
|
| + bufpt = zExtra
|
| + = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
|
| if( bufpt==0 ){
|
| setStrAccumError(pAccum, STRACCUM_NOMEM);
|
| return;
|
| @@ -635,12 +640,13 @@ void sqlite3VXPrintf(
|
| case etDYNSTRING:
|
| if( bArgList ){
|
| bufpt = getTextArg(pArgList);
|
| + xtype = etSTRING;
|
| }else{
|
| bufpt = va_arg(ap,char*);
|
| }
|
| if( bufpt==0 ){
|
| bufpt = "";
|
| - }else if( xtype==etDYNSTRING && !bArgList ){
|
| + }else if( xtype==etDYNSTRING ){
|
| zExtra = bufpt;
|
| }
|
| if( precision>=0 ){
|
| @@ -649,9 +655,9 @@ void sqlite3VXPrintf(
|
| length = sqlite3Strlen30(bufpt);
|
| }
|
| break;
|
| - case etSQLESCAPE:
|
| - case etSQLESCAPE2:
|
| - case etSQLESCAPE3: {
|
| + case etSQLESCAPE: /* Escape ' characters */
|
| + case etSQLESCAPE2: /* Escape ' and enclose in '...' */
|
| + case etSQLESCAPE3: { /* Escape " characters */
|
| int i, j, k, n, isnull;
|
| int needQuote;
|
| char ch;
|
| @@ -670,7 +676,7 @@ void sqlite3VXPrintf(
|
| if( ch==q ) n++;
|
| }
|
| needQuote = !isnull && xtype==etSQLESCAPE2;
|
| - n += i + 1 + needQuote*2;
|
| + n += i + 3;
|
| if( n>etBUFSIZE ){
|
| bufpt = zExtra = sqlite3Malloc( n );
|
| if( bufpt==0 ){
|
| @@ -734,7 +740,7 @@ void sqlite3VXPrintf(
|
| if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
|
|
|
| if( zExtra ){
|
| - sqlite3_free(zExtra);
|
| + sqlite3DbFree(pAccum->db, zExtra);
|
| zExtra = 0;
|
| }
|
| }/* End for loop over the format string */
|
| @@ -749,20 +755,26 @@ void sqlite3VXPrintf(
|
| */
|
| static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
| char *zNew;
|
| - assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
|
| + assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
|
| if( p->accError ){
|
| testcase(p->accError==STRACCUM_TOOBIG);
|
| testcase(p->accError==STRACCUM_NOMEM);
|
| return 0;
|
| }
|
| - if( !p->useMalloc ){
|
| + if( p->mxAlloc==0 ){
|
| N = p->nAlloc - p->nChar - 1;
|
| setStrAccumError(p, STRACCUM_TOOBIG);
|
| return N;
|
| }else{
|
| - char *zOld = (p->zText==p->zBase ? 0 : p->zText);
|
| + char *zOld = p->bMalloced ? p->zText : 0;
|
| i64 szNew = p->nChar;
|
| + assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
|
| szNew += N + 1;
|
| + if( szNew+p->nChar<=p->mxAlloc ){
|
| + /* Force exponential buffer size growth as long as it does not overflow,
|
| + ** to avoid having to call this routine too often */
|
| + szNew += p->nChar;
|
| + }
|
| if( szNew > p->mxAlloc ){
|
| sqlite3StrAccumReset(p);
|
| setStrAccumError(p, STRACCUM_TOOBIG);
|
| @@ -770,15 +782,17 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
| }else{
|
| p->nAlloc = (int)szNew;
|
| }
|
| - if( p->useMalloc==1 ){
|
| + if( p->db ){
|
| zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
|
| }else{
|
| - zNew = sqlite3_realloc(zOld, p->nAlloc);
|
| + zNew = sqlite3_realloc64(zOld, p->nAlloc);
|
| }
|
| if( zNew ){
|
| assert( p->zText!=0 || p->nChar==0 );
|
| - if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
|
| + if( !p->bMalloced && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
|
| p->zText = zNew;
|
| + p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
|
| + p->bMalloced = 1;
|
| }else{
|
| sqlite3StrAccumReset(p);
|
| setStrAccumError(p, STRACCUM_NOMEM);
|
| @@ -792,7 +806,11 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
| ** Append N copies of character c to the given string buffer.
|
| */
|
| void sqlite3AppendChar(StrAccum *p, int N, char c){
|
| - if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
|
| + testcase( p->nChar + (i64)N > 0x7fffffff );
|
| + if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
|
| + return;
|
| + }
|
| + assert( (p->zText==p->zBase)==(p->bMalloced==0) );
|
| while( (N--)>0 ) p->zText[p->nChar++] = c;
|
| }
|
|
|
| @@ -810,6 +828,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
|
| memcpy(&p->zText[p->nChar], z, N);
|
| p->nChar += N;
|
| }
|
| + assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
|
| }
|
|
|
| /*
|
| @@ -817,7 +836,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
|
| ** size of the memory allocation for StrAccum if necessary.
|
| */
|
| void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
|
| - assert( z!=0 );
|
| + assert( z!=0 || N==0 );
|
| assert( p->zText!=0 || p->nChar==0 || p->accError );
|
| assert( N>=0 );
|
| assert( p->accError==0 || p->nAlloc==0 );
|
| @@ -845,15 +864,13 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
|
| */
|
| char *sqlite3StrAccumFinish(StrAccum *p){
|
| if( p->zText ){
|
| + assert( (p->zText==p->zBase)==(p->bMalloced==0) );
|
| p->zText[p->nChar] = 0;
|
| - if( p->useMalloc && p->zText==p->zBase ){
|
| - if( p->useMalloc==1 ){
|
| - p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
|
| - }else{
|
| - p->zText = sqlite3_malloc(p->nChar+1);
|
| - }
|
| + if( p->mxAlloc>0 && p->bMalloced==0 ){
|
| + p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
|
| if( p->zText ){
|
| memcpy(p->zText, p->zBase, p->nChar+1);
|
| + p->bMalloced = 1;
|
| }else{
|
| setStrAccumError(p, STRACCUM_NOMEM);
|
| }
|
| @@ -866,27 +883,36 @@ char *sqlite3StrAccumFinish(StrAccum *p){
|
| ** Reset an StrAccum string. Reclaim all malloced memory.
|
| */
|
| void sqlite3StrAccumReset(StrAccum *p){
|
| - if( p->zText!=p->zBase ){
|
| - if( p->useMalloc==1 ){
|
| - sqlite3DbFree(p->db, p->zText);
|
| - }else{
|
| - sqlite3_free(p->zText);
|
| - }
|
| + assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
|
| + if( p->bMalloced ){
|
| + sqlite3DbFree(p->db, p->zText);
|
| + p->bMalloced = 0;
|
| }
|
| p->zText = 0;
|
| }
|
|
|
| /*
|
| -** Initialize a string accumulator
|
| +** Initialize a string accumulator.
|
| +**
|
| +** p: The accumulator to be initialized.
|
| +** db: Pointer to a database connection. May be NULL. Lookaside
|
| +** memory is used if not NULL. db->mallocFailed is set appropriately
|
| +** when not NULL.
|
| +** zBase: An initial buffer. May be NULL in which case the initial buffer
|
| +** is malloced.
|
| +** n: Size of zBase in bytes. If total space requirements never exceed
|
| +** n then no memory allocations ever occur.
|
| +** mx: Maximum number of bytes to accumulate. If mx==0 then no memory
|
| +** allocations will ever occur.
|
| */
|
| -void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
|
| +void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
|
| p->zText = p->zBase = zBase;
|
| - p->db = 0;
|
| + p->db = db;
|
| p->nChar = 0;
|
| p->nAlloc = n;
|
| p->mxAlloc = mx;
|
| - p->useMalloc = 1;
|
| p->accError = 0;
|
| + p->bMalloced = 0;
|
| }
|
|
|
| /*
|
| @@ -898,9 +924,8 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
|
| char zBase[SQLITE_PRINT_BUF_SIZE];
|
| StrAccum acc;
|
| assert( db!=0 );
|
| - sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
|
| + sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
|
| db->aLimit[SQLITE_LIMIT_LENGTH]);
|
| - acc.db = db;
|
| sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
|
| z = sqlite3StrAccumFinish(&acc);
|
| if( acc.accError==STRACCUM_NOMEM ){
|
| @@ -923,24 +948,6 @@ char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
|
| }
|
|
|
| /*
|
| -** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
|
| -** the string and before returning. This routine is intended to be used
|
| -** to modify an existing string. For example:
|
| -**
|
| -** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
|
| -**
|
| -*/
|
| -char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
|
| - va_list ap;
|
| - char *z;
|
| - va_start(ap, zFormat);
|
| - z = sqlite3VMPrintf(db, zFormat, ap);
|
| - va_end(ap);
|
| - sqlite3DbFree(db, zStr);
|
| - return z;
|
| -}
|
| -
|
| -/*
|
| ** Print into memory obtained from sqlite3_malloc(). Omit the internal
|
| ** %-conversion extensions.
|
| */
|
| @@ -948,11 +955,17 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
|
| char *z;
|
| char zBase[SQLITE_PRINT_BUF_SIZE];
|
| StrAccum acc;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( zFormat==0 ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| #ifndef SQLITE_OMIT_AUTOINIT
|
| if( sqlite3_initialize() ) return 0;
|
| #endif
|
| - sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
|
| - acc.useMalloc = 2;
|
| + sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
|
| sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
| z = sqlite3StrAccumFinish(&acc);
|
| return z;
|
| @@ -990,8 +1003,14 @@ char *sqlite3_mprintf(const char *zFormat, ...){
|
| char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
| StrAccum acc;
|
| if( n<=0 ) return zBuf;
|
| - sqlite3StrAccumInit(&acc, zBuf, n, 0);
|
| - acc.useMalloc = 0;
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( zBuf==0 || zFormat==0 ) {
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + if( zBuf ) zBuf[0] = 0;
|
| + return zBuf;
|
| + }
|
| +#endif
|
| + sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
|
| sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
| return sqlite3StrAccumFinish(&acc);
|
| }
|
| @@ -1012,13 +1031,17 @@ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
|
| ** 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.
|
| +**
|
| +** sqlite3VXPrintf() might ask for *temporary* memory allocations for
|
| +** certain format characters (%q) or for very large precisions or widths.
|
| +** Care must be taken that any sqlite3_log() calls that occur while the
|
| +** memory mutex is held do not use these mechanisms.
|
| */
|
| 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;
|
| + sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
|
| sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
| sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
|
| sqlite3StrAccumFinish(&acc));
|
| @@ -1036,7 +1059,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...){
|
| }
|
| }
|
|
|
| -#if defined(SQLITE_DEBUG)
|
| +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
|
| /*
|
| ** A version of printf() that understands %lld. Used for debugging.
|
| ** The printf() built into some versions of windows does not understand %lld
|
| @@ -1046,8 +1069,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
| va_list ap;
|
| StrAccum acc;
|
| char zBuf[500];
|
| - sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
|
| - acc.useMalloc = 0;
|
| + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
| va_start(ap,zFormat);
|
| sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
| va_end(ap);
|
| @@ -1057,71 +1079,10 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
| }
|
| #endif
|
|
|
| -#ifdef SQLITE_DEBUG
|
| -/*************************************************************************
|
| -** Routines for implementing the "TreeView" display of hierarchical
|
| -** data structures for debugging.
|
| -**
|
| -** The main entry points (coded elsewhere) are:
|
| -** sqlite3TreeViewExpr(0, pExpr, 0);
|
| -** sqlite3TreeViewExprList(0, pList, 0, 0);
|
| -** sqlite3TreeViewSelect(0, pSelect, 0);
|
| -** Insert calls to those routines while debugging in order to display
|
| -** a diagram of Expr, ExprList, and Select objects.
|
| -**
|
| -*/
|
| -/* Add a new subitem to the tree. The moreToFollow flag indicates that this
|
| -** is not the last item in the tree. */
|
| -TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
|
| - if( p==0 ){
|
| - p = sqlite3_malloc( sizeof(*p) );
|
| - if( p==0 ) return 0;
|
| - memset(p, 0, sizeof(*p));
|
| - }else{
|
| - p->iLevel++;
|
| - }
|
| - assert( moreToFollow==0 || moreToFollow==1 );
|
| - if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
|
| - return p;
|
| -}
|
| -/* Finished with one layer of the tree */
|
| -void sqlite3TreeViewPop(TreeView *p){
|
| - if( p==0 ) return;
|
| - p->iLevel--;
|
| - if( p->iLevel<0 ) sqlite3_free(p);
|
| -}
|
| -/* Generate a single line of output for the tree, with a prefix that contains
|
| -** all the appropriate tree lines */
|
| -void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
|
| - va_list ap;
|
| - int i;
|
| - StrAccum acc;
|
| - char zBuf[500];
|
| - sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
|
| - acc.useMalloc = 0;
|
| - if( p ){
|
| - for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
|
| - sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
|
| - }
|
| - sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
|
| - }
|
| - va_start(ap, zFormat);
|
| - sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
| - va_end(ap);
|
| - if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
|
| - sqlite3StrAccumFinish(&acc);
|
| - fprintf(stdout,"%s", zBuf);
|
| - fflush(stdout);
|
| -}
|
| -/* Shorthand for starting a new tree item that consists of a single label */
|
| -void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){
|
| - p = sqlite3TreeViewPush(p, moreToFollow);
|
| - sqlite3TreeViewLine(p, "%s", zLabel);
|
| -}
|
| -#endif /* SQLITE_DEBUG */
|
|
|
| /*
|
| -** variable-argument wrapper around sqlite3VXPrintf().
|
| +** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument
|
| +** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
|
| */
|
| void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
|
| va_list ap;
|
|
|