| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** The "printf" code that follows dates from the 1980's. It is in | 2 ** The "printf" code that follows dates from the 1980's. It is in |
| 3 ** the public domain. The original comments are included here for | 3 ** the public domain. |
| 4 ** completeness. They are very out-of-date but might be useful as | |
| 5 ** an historical reference. Most of the "enhancements" have been backed | |
| 6 ** out so that the functionality is now the same as standard printf(). | |
| 7 ** | 4 ** |
| 8 ************************************************************************** | 5 ************************************************************************** |
| 9 ** | 6 ** |
| 10 ** This file contains code for a set of "printf"-like routines. These | 7 ** This file contains code for a set of "printf"-like routines. These |
| 11 ** routines format strings much like the printf() from the standard C | 8 ** routines format strings much like the printf() from the standard C |
| 12 ** library, though the implementation here has enhancements to support | 9 ** library, though the implementation here has enhancements to support |
| 13 ** SQLlite. | 10 ** SQLite. |
| 14 */ | 11 */ |
| 15 #include "sqliteInt.h" | 12 #include "sqliteInt.h" |
| 16 | 13 |
| 17 /* | 14 /* |
| 18 ** If the strchrnul() library function is available, then set | |
| 19 ** HAVE_STRCHRNUL. If that routine is not available, this module | |
| 20 ** will supply its own. The built-in version is slower than | |
| 21 ** the glibc version so the glibc version is definitely preferred. | |
| 22 */ | |
| 23 #if !defined(HAVE_STRCHRNUL) | |
| 24 # define HAVE_STRCHRNUL 0 | |
| 25 #endif | |
| 26 | |
| 27 | |
| 28 /* | |
| 29 ** Conversion types fall into various categories as defined by the | 15 ** Conversion types fall into various categories as defined by the |
| 30 ** following enumeration. | 16 ** following enumeration. |
| 31 */ | 17 */ |
| 32 #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ | 18 #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ |
| 33 #define etFLOAT 2 /* Floating point. %f */ | 19 #define etFLOAT 2 /* Floating point. %f */ |
| 34 #define etEXP 3 /* Exponentional notation. %e and %E */ | 20 #define etEXP 3 /* Exponentional notation. %e and %E */ |
| 35 #define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */ | 21 #define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */ |
| 36 #define etSIZE 5 /* Return number of characters processed so far. %n */ | 22 #define etSIZE 5 /* Return number of characters processed so far. %n */ |
| 37 #define etSTRING 6 /* Strings. %s */ | 23 #define etSTRING 6 /* Strings. %s */ |
| 38 #define etDYNSTRING 7 /* Dynamically allocated strings. %z */ | 24 #define etDYNSTRING 7 /* Dynamically allocated strings. %z */ |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 digit += '0'; | 128 digit += '0'; |
| 143 *val = (*val - d)*10.0; | 129 *val = (*val - d)*10.0; |
| 144 return (char)digit; | 130 return (char)digit; |
| 145 } | 131 } |
| 146 #endif /* SQLITE_OMIT_FLOATING_POINT */ | 132 #endif /* SQLITE_OMIT_FLOATING_POINT */ |
| 147 | 133 |
| 148 /* | 134 /* |
| 149 ** Set the StrAccum object to an error mode. | 135 ** Set the StrAccum object to an error mode. |
| 150 */ | 136 */ |
| 151 static void setStrAccumError(StrAccum *p, u8 eError){ | 137 static void setStrAccumError(StrAccum *p, u8 eError){ |
| 138 assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG ); |
| 152 p->accError = eError; | 139 p->accError = eError; |
| 153 p->nAlloc = 0; | 140 p->nAlloc = 0; |
| 154 } | 141 } |
| 155 | 142 |
| 156 /* | 143 /* |
| 157 ** Extra argument values from a PrintfArguments object | 144 ** Extra argument values from a PrintfArguments object |
| 158 */ | 145 */ |
| 159 static sqlite3_int64 getIntArg(PrintfArguments *p){ | 146 static sqlite3_int64 getIntArg(PrintfArguments *p){ |
| 160 if( p->nArg<=p->nUsed ) return 0; | 147 if( p->nArg<=p->nUsed ) return 0; |
| 161 return sqlite3_value_int64(p->apArg[p->nUsed++]); | 148 return sqlite3_value_int64(p->apArg[p->nUsed++]); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 case '-': flag_leftjustify = 1; break; | 243 case '-': flag_leftjustify = 1; break; |
| 257 case '+': flag_plussign = 1; break; | 244 case '+': flag_plussign = 1; break; |
| 258 case ' ': flag_blanksign = 1; break; | 245 case ' ': flag_blanksign = 1; break; |
| 259 case '#': flag_alternateform = 1; break; | 246 case '#': flag_alternateform = 1; break; |
| 260 case '!': flag_altform2 = 1; break; | 247 case '!': flag_altform2 = 1; break; |
| 261 case '0': flag_zeropad = 1; break; | 248 case '0': flag_zeropad = 1; break; |
| 262 default: done = 1; break; | 249 default: done = 1; break; |
| 263 } | 250 } |
| 264 }while( !done && (c=(*++fmt))!=0 ); | 251 }while( !done && (c=(*++fmt))!=0 ); |
| 265 /* Get the field width */ | 252 /* Get the field width */ |
| 266 width = 0; | |
| 267 if( c=='*' ){ | 253 if( c=='*' ){ |
| 268 if( bArgList ){ | 254 if( bArgList ){ |
| 269 width = (int)getIntArg(pArgList); | 255 width = (int)getIntArg(pArgList); |
| 270 }else{ | 256 }else{ |
| 271 width = va_arg(ap,int); | 257 width = va_arg(ap,int); |
| 272 } | 258 } |
| 273 if( width<0 ){ | 259 if( width<0 ){ |
| 274 flag_leftjustify = 1; | 260 flag_leftjustify = 1; |
| 275 width = -width; | 261 width = width >= -2147483647 ? -width : 0; |
| 276 } | 262 } |
| 277 c = *++fmt; | 263 c = *++fmt; |
| 278 }else{ | 264 }else{ |
| 265 unsigned wx = 0; |
| 279 while( c>='0' && c<='9' ){ | 266 while( c>='0' && c<='9' ){ |
| 280 width = width*10 + c - '0'; | 267 wx = wx*10 + c - '0'; |
| 281 c = *++fmt; | 268 c = *++fmt; |
| 282 } | 269 } |
| 270 testcase( wx>0x7fffffff ); |
| 271 width = wx & 0x7fffffff; |
| 283 } | 272 } |
| 273 assert( width>=0 ); |
| 274 #ifdef SQLITE_PRINTF_PRECISION_LIMIT |
| 275 if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ |
| 276 width = SQLITE_PRINTF_PRECISION_LIMIT; |
| 277 } |
| 278 #endif |
| 279 |
| 284 /* Get the precision */ | 280 /* Get the precision */ |
| 285 if( c=='.' ){ | 281 if( c=='.' ){ |
| 286 precision = 0; | |
| 287 c = *++fmt; | 282 c = *++fmt; |
| 288 if( c=='*' ){ | 283 if( c=='*' ){ |
| 289 if( bArgList ){ | 284 if( bArgList ){ |
| 290 precision = (int)getIntArg(pArgList); | 285 precision = (int)getIntArg(pArgList); |
| 291 }else{ | 286 }else{ |
| 292 precision = va_arg(ap,int); | 287 precision = va_arg(ap,int); |
| 293 } | 288 } |
| 294 if( precision<0 ) precision = -precision; | |
| 295 c = *++fmt; | 289 c = *++fmt; |
| 290 if( precision<0 ){ |
| 291 precision = precision >= -2147483647 ? -precision : -1; |
| 292 } |
| 296 }else{ | 293 }else{ |
| 294 unsigned px = 0; |
| 297 while( c>='0' && c<='9' ){ | 295 while( c>='0' && c<='9' ){ |
| 298 precision = precision*10 + c - '0'; | 296 px = px*10 + c - '0'; |
| 299 c = *++fmt; | 297 c = *++fmt; |
| 300 } | 298 } |
| 299 testcase( px>0x7fffffff ); |
| 300 precision = px & 0x7fffffff; |
| 301 } | 301 } |
| 302 }else{ | 302 }else{ |
| 303 precision = -1; | 303 precision = -1; |
| 304 } | 304 } |
| 305 assert( precision>=(-1) ); |
| 306 #ifdef SQLITE_PRINTF_PRECISION_LIMIT |
| 307 if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){ |
| 308 precision = SQLITE_PRINTF_PRECISION_LIMIT; |
| 309 } |
| 310 #endif |
| 311 |
| 312 |
| 305 /* Get the conversion type modifier */ | 313 /* Get the conversion type modifier */ |
| 306 if( c=='l' ){ | 314 if( c=='l' ){ |
| 307 flag_long = 1; | 315 flag_long = 1; |
| 308 c = *++fmt; | 316 c = *++fmt; |
| 309 if( c=='l' ){ | 317 if( c=='l' ){ |
| 310 flag_longlong = 1; | 318 flag_longlong = 1; |
| 311 c = *++fmt; | 319 c = *++fmt; |
| 312 }else{ | 320 }else{ |
| 313 flag_longlong = 0; | 321 flag_longlong = 0; |
| 314 } | 322 } |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 if( precision<0 ) precision = 6; /* Set default precision */ | 462 if( precision<0 ) precision = 6; /* Set default precision */ |
| 455 if( realvalue<0.0 ){ | 463 if( realvalue<0.0 ){ |
| 456 realvalue = -realvalue; | 464 realvalue = -realvalue; |
| 457 prefix = '-'; | 465 prefix = '-'; |
| 458 }else{ | 466 }else{ |
| 459 if( flag_plussign ) prefix = '+'; | 467 if( flag_plussign ) prefix = '+'; |
| 460 else if( flag_blanksign ) prefix = ' '; | 468 else if( flag_blanksign ) prefix = ' '; |
| 461 else prefix = 0; | 469 else prefix = 0; |
| 462 } | 470 } |
| 463 if( xtype==etGENERIC && precision>0 ) precision--; | 471 if( xtype==etGENERIC && precision>0 ) precision--; |
| 464 for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){} | 472 testcase( precision>0xfff ); |
| 473 for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){} |
| 465 if( xtype==etFLOAT ) realvalue += rounder; | 474 if( xtype==etFLOAT ) realvalue += rounder; |
| 466 /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ | 475 /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ |
| 467 exp = 0; | 476 exp = 0; |
| 468 if( sqlite3IsNaN((double)realvalue) ){ | 477 if( sqlite3IsNaN((double)realvalue) ){ |
| 469 bufpt = "NaN"; | 478 bufpt = "NaN"; |
| 470 length = 3; | 479 length = 3; |
| 471 break; | 480 break; |
| 472 } | 481 } |
| 473 if( realvalue>0.0 ){ | 482 if( realvalue>0.0 ){ |
| 474 LONGDOUBLE_TYPE scale = 1.0; | 483 LONGDOUBLE_TYPE scale = 1.0; |
| 475 while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;} | 484 while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;} |
| 476 while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; } | 485 while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; } |
| 477 while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; } | |
| 478 while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } | 486 while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } |
| 479 realvalue /= scale; | 487 realvalue /= scale; |
| 480 while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } | 488 while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } |
| 481 while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } | 489 while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } |
| 482 if( exp>350 ){ | 490 if( exp>350 ){ |
| 483 if( prefix=='-' ){ | 491 bufpt = buf; |
| 484 bufpt = "-Inf"; | 492 buf[0] = prefix; |
| 485 }else if( prefix=='+' ){ | 493 memcpy(buf+(prefix!=0),"Inf",4); |
| 486 bufpt = "+Inf"; | 494 length = 3+(prefix!=0); |
| 487 }else{ | |
| 488 bufpt = "Inf"; | |
| 489 } | |
| 490 length = sqlite3Strlen30(bufpt); | |
| 491 break; | 495 break; |
| 492 } | 496 } |
| 493 } | 497 } |
| 494 bufpt = buf; | 498 bufpt = buf; |
| 495 /* | 499 /* |
| 496 ** If the field type is etGENERIC, then convert to either etEXP | 500 ** If the field type is etGENERIC, then convert to either etEXP |
| 497 ** or etFLOAT, as appropriate. | 501 ** or etFLOAT, as appropriate. |
| 498 */ | 502 */ |
| 499 if( xtype!=etFLOAT ){ | 503 if( xtype!=etFLOAT ){ |
| 500 realvalue += rounder; | 504 realvalue += rounder; |
| 501 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } | 505 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } |
| 502 } | 506 } |
| 503 if( xtype==etGENERIC ){ | 507 if( xtype==etGENERIC ){ |
| 504 flag_rtz = !flag_alternateform; | 508 flag_rtz = !flag_alternateform; |
| 505 if( exp<-4 || exp>precision ){ | 509 if( exp<-4 || exp>precision ){ |
| 506 xtype = etEXP; | 510 xtype = etEXP; |
| 507 }else{ | 511 }else{ |
| 508 precision = precision - exp; | 512 precision = precision - exp; |
| 509 xtype = etFLOAT; | 513 xtype = etFLOAT; |
| 510 } | 514 } |
| 511 }else{ | 515 }else{ |
| 512 flag_rtz = flag_altform2; | 516 flag_rtz = flag_altform2; |
| 513 } | 517 } |
| 514 if( xtype==etEXP ){ | 518 if( xtype==etEXP ){ |
| 515 e2 = 0; | 519 e2 = 0; |
| 516 }else{ | 520 }else{ |
| 517 e2 = exp; | 521 e2 = exp; |
| 518 } | 522 } |
| 519 if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){ | 523 if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){ |
| 520 bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 ); | 524 bufpt = zExtra |
| 525 = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 ); |
| 521 if( bufpt==0 ){ | 526 if( bufpt==0 ){ |
| 522 setStrAccumError(pAccum, STRACCUM_NOMEM); | 527 setStrAccumError(pAccum, STRACCUM_NOMEM); |
| 523 return; | 528 return; |
| 524 } | 529 } |
| 525 } | 530 } |
| 526 zOut = bufpt; | 531 zOut = bufpt; |
| 527 nsd = 16 + flag_altform2*10; | 532 nsd = 16 + flag_altform2*10; |
| 528 flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; | 533 flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; |
| 529 /* The sign in front of the number */ | 534 /* The sign in front of the number */ |
| 530 if( prefix ){ | 535 if( prefix ){ |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 sqlite3AppendChar(pAccum, precision-1, c); | 633 sqlite3AppendChar(pAccum, precision-1, c); |
| 629 } | 634 } |
| 630 length = 1; | 635 length = 1; |
| 631 buf[0] = c; | 636 buf[0] = c; |
| 632 bufpt = buf; | 637 bufpt = buf; |
| 633 break; | 638 break; |
| 634 case etSTRING: | 639 case etSTRING: |
| 635 case etDYNSTRING: | 640 case etDYNSTRING: |
| 636 if( bArgList ){ | 641 if( bArgList ){ |
| 637 bufpt = getTextArg(pArgList); | 642 bufpt = getTextArg(pArgList); |
| 643 xtype = etSTRING; |
| 638 }else{ | 644 }else{ |
| 639 bufpt = va_arg(ap,char*); | 645 bufpt = va_arg(ap,char*); |
| 640 } | 646 } |
| 641 if( bufpt==0 ){ | 647 if( bufpt==0 ){ |
| 642 bufpt = ""; | 648 bufpt = ""; |
| 643 }else if( xtype==etDYNSTRING && !bArgList ){ | 649 }else if( xtype==etDYNSTRING ){ |
| 644 zExtra = bufpt; | 650 zExtra = bufpt; |
| 645 } | 651 } |
| 646 if( precision>=0 ){ | 652 if( precision>=0 ){ |
| 647 for(length=0; length<precision && bufpt[length]; length++){} | 653 for(length=0; length<precision && bufpt[length]; length++){} |
| 648 }else{ | 654 }else{ |
| 649 length = sqlite3Strlen30(bufpt); | 655 length = sqlite3Strlen30(bufpt); |
| 650 } | 656 } |
| 651 break; | 657 break; |
| 652 case etSQLESCAPE: | 658 case etSQLESCAPE: /* Escape ' characters */ |
| 653 case etSQLESCAPE2: | 659 case etSQLESCAPE2: /* Escape ' and enclose in '...' */ |
| 654 case etSQLESCAPE3: { | 660 case etSQLESCAPE3: { /* Escape " characters */ |
| 655 int i, j, k, n, isnull; | 661 int i, j, k, n, isnull; |
| 656 int needQuote; | 662 int needQuote; |
| 657 char ch; | 663 char ch; |
| 658 char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ | 664 char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ |
| 659 char *escarg; | 665 char *escarg; |
| 660 | 666 |
| 661 if( bArgList ){ | 667 if( bArgList ){ |
| 662 escarg = getTextArg(pArgList); | 668 escarg = getTextArg(pArgList); |
| 663 }else{ | 669 }else{ |
| 664 escarg = va_arg(ap,char*); | 670 escarg = va_arg(ap,char*); |
| 665 } | 671 } |
| 666 isnull = escarg==0; | 672 isnull = escarg==0; |
| 667 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); | 673 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); |
| 668 k = precision; | 674 k = precision; |
| 669 for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){ | 675 for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){ |
| 670 if( ch==q ) n++; | 676 if( ch==q ) n++; |
| 671 } | 677 } |
| 672 needQuote = !isnull && xtype==etSQLESCAPE2; | 678 needQuote = !isnull && xtype==etSQLESCAPE2; |
| 673 n += i + 1 + needQuote*2; | 679 n += i + 3; |
| 674 if( n>etBUFSIZE ){ | 680 if( n>etBUFSIZE ){ |
| 675 bufpt = zExtra = sqlite3Malloc( n ); | 681 bufpt = zExtra = sqlite3Malloc( n ); |
| 676 if( bufpt==0 ){ | 682 if( bufpt==0 ){ |
| 677 setStrAccumError(pAccum, STRACCUM_NOMEM); | 683 setStrAccumError(pAccum, STRACCUM_NOMEM); |
| 678 return; | 684 return; |
| 679 } | 685 } |
| 680 }else{ | 686 }else{ |
| 681 bufpt = buf; | 687 bufpt = buf; |
| 682 } | 688 } |
| 683 j = 0; | 689 j = 0; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 ** The text of the conversion is pointed to by "bufpt" and is | 733 ** The text of the conversion is pointed to by "bufpt" and is |
| 728 ** "length" characters long. The field width is "width". Do | 734 ** "length" characters long. The field width is "width". Do |
| 729 ** the output. | 735 ** the output. |
| 730 */ | 736 */ |
| 731 width -= length; | 737 width -= length; |
| 732 if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); | 738 if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); |
| 733 sqlite3StrAccumAppend(pAccum, bufpt, length); | 739 sqlite3StrAccumAppend(pAccum, bufpt, length); |
| 734 if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); | 740 if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); |
| 735 | 741 |
| 736 if( zExtra ){ | 742 if( zExtra ){ |
| 737 sqlite3_free(zExtra); | 743 sqlite3DbFree(pAccum->db, zExtra); |
| 738 zExtra = 0; | 744 zExtra = 0; |
| 739 } | 745 } |
| 740 }/* End for loop over the format string */ | 746 }/* End for loop over the format string */ |
| 741 } /* End of function */ | 747 } /* End of function */ |
| 742 | 748 |
| 743 /* | 749 /* |
| 744 ** Enlarge the memory allocation on a StrAccum object so that it is | 750 ** Enlarge the memory allocation on a StrAccum object so that it is |
| 745 ** able to accept at least N more bytes of text. | 751 ** able to accept at least N more bytes of text. |
| 746 ** | 752 ** |
| 747 ** Return the number of bytes of text that StrAccum is able to accept | 753 ** Return the number of bytes of text that StrAccum is able to accept |
| 748 ** after the attempted enlargement. The value returned might be zero. | 754 ** after the attempted enlargement. The value returned might be zero. |
| 749 */ | 755 */ |
| 750 static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ | 756 static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ |
| 751 char *zNew; | 757 char *zNew; |
| 752 assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */ | 758 assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ |
| 753 if( p->accError ){ | 759 if( p->accError ){ |
| 754 testcase(p->accError==STRACCUM_TOOBIG); | 760 testcase(p->accError==STRACCUM_TOOBIG); |
| 755 testcase(p->accError==STRACCUM_NOMEM); | 761 testcase(p->accError==STRACCUM_NOMEM); |
| 756 return 0; | 762 return 0; |
| 757 } | 763 } |
| 758 if( !p->useMalloc ){ | 764 if( p->mxAlloc==0 ){ |
| 759 N = p->nAlloc - p->nChar - 1; | 765 N = p->nAlloc - p->nChar - 1; |
| 760 setStrAccumError(p, STRACCUM_TOOBIG); | 766 setStrAccumError(p, STRACCUM_TOOBIG); |
| 761 return N; | 767 return N; |
| 762 }else{ | 768 }else{ |
| 763 char *zOld = (p->zText==p->zBase ? 0 : p->zText); | 769 char *zOld = p->bMalloced ? p->zText : 0; |
| 764 i64 szNew = p->nChar; | 770 i64 szNew = p->nChar; |
| 771 assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) ); |
| 765 szNew += N + 1; | 772 szNew += N + 1; |
| 773 if( szNew+p->nChar<=p->mxAlloc ){ |
| 774 /* Force exponential buffer size growth as long as it does not overflow, |
| 775 ** to avoid having to call this routine too often */ |
| 776 szNew += p->nChar; |
| 777 } |
| 766 if( szNew > p->mxAlloc ){ | 778 if( szNew > p->mxAlloc ){ |
| 767 sqlite3StrAccumReset(p); | 779 sqlite3StrAccumReset(p); |
| 768 setStrAccumError(p, STRACCUM_TOOBIG); | 780 setStrAccumError(p, STRACCUM_TOOBIG); |
| 769 return 0; | 781 return 0; |
| 770 }else{ | 782 }else{ |
| 771 p->nAlloc = (int)szNew; | 783 p->nAlloc = (int)szNew; |
| 772 } | 784 } |
| 773 if( p->useMalloc==1 ){ | 785 if( p->db ){ |
| 774 zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); | 786 zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); |
| 775 }else{ | 787 }else{ |
| 776 zNew = sqlite3_realloc(zOld, p->nAlloc); | 788 zNew = sqlite3_realloc64(zOld, p->nAlloc); |
| 777 } | 789 } |
| 778 if( zNew ){ | 790 if( zNew ){ |
| 779 assert( p->zText!=0 || p->nChar==0 ); | 791 assert( p->zText!=0 || p->nChar==0 ); |
| 780 if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); | 792 if( !p->bMalloced && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); |
| 781 p->zText = zNew; | 793 p->zText = zNew; |
| 794 p->nAlloc = sqlite3DbMallocSize(p->db, zNew); |
| 795 p->bMalloced = 1; |
| 782 }else{ | 796 }else{ |
| 783 sqlite3StrAccumReset(p); | 797 sqlite3StrAccumReset(p); |
| 784 setStrAccumError(p, STRACCUM_NOMEM); | 798 setStrAccumError(p, STRACCUM_NOMEM); |
| 785 return 0; | 799 return 0; |
| 786 } | 800 } |
| 787 } | 801 } |
| 788 return N; | 802 return N; |
| 789 } | 803 } |
| 790 | 804 |
| 791 /* | 805 /* |
| 792 ** Append N copies of character c to the given string buffer. | 806 ** Append N copies of character c to the given string buffer. |
| 793 */ | 807 */ |
| 794 void sqlite3AppendChar(StrAccum *p, int N, char c){ | 808 void sqlite3AppendChar(StrAccum *p, int N, char c){ |
| 795 if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return; | 809 testcase( p->nChar + (i64)N > 0x7fffffff ); |
| 810 if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ |
| 811 return; |
| 812 } |
| 813 assert( (p->zText==p->zBase)==(p->bMalloced==0) ); |
| 796 while( (N--)>0 ) p->zText[p->nChar++] = c; | 814 while( (N--)>0 ) p->zText[p->nChar++] = c; |
| 797 } | 815 } |
| 798 | 816 |
| 799 /* | 817 /* |
| 800 ** The StrAccum "p" is not large enough to accept N new bytes of z[]. | 818 ** The StrAccum "p" is not large enough to accept N new bytes of z[]. |
| 801 ** So enlarge if first, then do the append. | 819 ** So enlarge if first, then do the append. |
| 802 ** | 820 ** |
| 803 ** This is a helper routine to sqlite3StrAccumAppend() that does special-case | 821 ** This is a helper routine to sqlite3StrAccumAppend() that does special-case |
| 804 ** work (enlarging the buffer) using tail recursion, so that the | 822 ** work (enlarging the buffer) using tail recursion, so that the |
| 805 ** sqlite3StrAccumAppend() routine can use fast calling semantics. | 823 ** sqlite3StrAccumAppend() routine can use fast calling semantics. |
| 806 */ | 824 */ |
| 807 static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ | 825 static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ |
| 808 N = sqlite3StrAccumEnlarge(p, N); | 826 N = sqlite3StrAccumEnlarge(p, N); |
| 809 if( N>0 ){ | 827 if( N>0 ){ |
| 810 memcpy(&p->zText[p->nChar], z, N); | 828 memcpy(&p->zText[p->nChar], z, N); |
| 811 p->nChar += N; | 829 p->nChar += N; |
| 812 } | 830 } |
| 831 assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) ); |
| 813 } | 832 } |
| 814 | 833 |
| 815 /* | 834 /* |
| 816 ** Append N bytes of text from z to the StrAccum object. Increase the | 835 ** Append N bytes of text from z to the StrAccum object. Increase the |
| 817 ** size of the memory allocation for StrAccum if necessary. | 836 ** size of the memory allocation for StrAccum if necessary. |
| 818 */ | 837 */ |
| 819 void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ | 838 void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ |
| 820 assert( z!=0 ); | 839 assert( z!=0 || N==0 ); |
| 821 assert( p->zText!=0 || p->nChar==0 || p->accError ); | 840 assert( p->zText!=0 || p->nChar==0 || p->accError ); |
| 822 assert( N>=0 ); | 841 assert( N>=0 ); |
| 823 assert( p->accError==0 || p->nAlloc==0 ); | 842 assert( p->accError==0 || p->nAlloc==0 ); |
| 824 if( p->nChar+N >= p->nAlloc ){ | 843 if( p->nChar+N >= p->nAlloc ){ |
| 825 enlargeAndAppend(p,z,N); | 844 enlargeAndAppend(p,z,N); |
| 826 }else{ | 845 }else{ |
| 827 assert( p->zText ); | 846 assert( p->zText ); |
| 828 p->nChar += N; | 847 p->nChar += N; |
| 829 memcpy(&p->zText[p->nChar-N], z, N); | 848 memcpy(&p->zText[p->nChar-N], z, N); |
| 830 } | 849 } |
| 831 } | 850 } |
| 832 | 851 |
| 833 /* | 852 /* |
| 834 ** Append the complete text of zero-terminated string z[] to the p string. | 853 ** Append the complete text of zero-terminated string z[] to the p string. |
| 835 */ | 854 */ |
| 836 void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ | 855 void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ |
| 837 sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); | 856 sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); |
| 838 } | 857 } |
| 839 | 858 |
| 840 | 859 |
| 841 /* | 860 /* |
| 842 ** Finish off a string by making sure it is zero-terminated. | 861 ** Finish off a string by making sure it is zero-terminated. |
| 843 ** Return a pointer to the resulting string. Return a NULL | 862 ** Return a pointer to the resulting string. Return a NULL |
| 844 ** pointer if any kind of error was encountered. | 863 ** pointer if any kind of error was encountered. |
| 845 */ | 864 */ |
| 846 char *sqlite3StrAccumFinish(StrAccum *p){ | 865 char *sqlite3StrAccumFinish(StrAccum *p){ |
| 847 if( p->zText ){ | 866 if( p->zText ){ |
| 867 assert( (p->zText==p->zBase)==(p->bMalloced==0) ); |
| 848 p->zText[p->nChar] = 0; | 868 p->zText[p->nChar] = 0; |
| 849 if( p->useMalloc && p->zText==p->zBase ){ | 869 if( p->mxAlloc>0 && p->bMalloced==0 ){ |
| 850 if( p->useMalloc==1 ){ | 870 p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); |
| 851 p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); | |
| 852 }else{ | |
| 853 p->zText = sqlite3_malloc(p->nChar+1); | |
| 854 } | |
| 855 if( p->zText ){ | 871 if( p->zText ){ |
| 856 memcpy(p->zText, p->zBase, p->nChar+1); | 872 memcpy(p->zText, p->zBase, p->nChar+1); |
| 873 p->bMalloced = 1; |
| 857 }else{ | 874 }else{ |
| 858 setStrAccumError(p, STRACCUM_NOMEM); | 875 setStrAccumError(p, STRACCUM_NOMEM); |
| 859 } | 876 } |
| 860 } | 877 } |
| 861 } | 878 } |
| 862 return p->zText; | 879 return p->zText; |
| 863 } | 880 } |
| 864 | 881 |
| 865 /* | 882 /* |
| 866 ** Reset an StrAccum string. Reclaim all malloced memory. | 883 ** Reset an StrAccum string. Reclaim all malloced memory. |
| 867 */ | 884 */ |
| 868 void sqlite3StrAccumReset(StrAccum *p){ | 885 void sqlite3StrAccumReset(StrAccum *p){ |
| 869 if( p->zText!=p->zBase ){ | 886 assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) ); |
| 870 if( p->useMalloc==1 ){ | 887 if( p->bMalloced ){ |
| 871 sqlite3DbFree(p->db, p->zText); | 888 sqlite3DbFree(p->db, p->zText); |
| 872 }else{ | 889 p->bMalloced = 0; |
| 873 sqlite3_free(p->zText); | |
| 874 } | |
| 875 } | 890 } |
| 876 p->zText = 0; | 891 p->zText = 0; |
| 877 } | 892 } |
| 878 | 893 |
| 879 /* | 894 /* |
| 880 ** Initialize a string accumulator | 895 ** Initialize a string accumulator. |
| 896 ** |
| 897 ** p: The accumulator to be initialized. |
| 898 ** db: Pointer to a database connection. May be NULL. Lookaside |
| 899 ** memory is used if not NULL. db->mallocFailed is set appropriately |
| 900 ** when not NULL. |
| 901 ** zBase: An initial buffer. May be NULL in which case the initial buffer |
| 902 ** is malloced. |
| 903 ** n: Size of zBase in bytes. If total space requirements never exceed |
| 904 ** n then no memory allocations ever occur. |
| 905 ** mx: Maximum number of bytes to accumulate. If mx==0 then no memory |
| 906 ** allocations will ever occur. |
| 881 */ | 907 */ |
| 882 void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){ | 908 void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ |
| 883 p->zText = p->zBase = zBase; | 909 p->zText = p->zBase = zBase; |
| 884 p->db = 0; | 910 p->db = db; |
| 885 p->nChar = 0; | 911 p->nChar = 0; |
| 886 p->nAlloc = n; | 912 p->nAlloc = n; |
| 887 p->mxAlloc = mx; | 913 p->mxAlloc = mx; |
| 888 p->useMalloc = 1; | |
| 889 p->accError = 0; | 914 p->accError = 0; |
| 915 p->bMalloced = 0; |
| 890 } | 916 } |
| 891 | 917 |
| 892 /* | 918 /* |
| 893 ** Print into memory obtained from sqliteMalloc(). Use the internal | 919 ** Print into memory obtained from sqliteMalloc(). Use the internal |
| 894 ** %-conversion extensions. | 920 ** %-conversion extensions. |
| 895 */ | 921 */ |
| 896 char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ | 922 char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ |
| 897 char *z; | 923 char *z; |
| 898 char zBase[SQLITE_PRINT_BUF_SIZE]; | 924 char zBase[SQLITE_PRINT_BUF_SIZE]; |
| 899 StrAccum acc; | 925 StrAccum acc; |
| 900 assert( db!=0 ); | 926 assert( db!=0 ); |
| 901 sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), | 927 sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), |
| 902 db->aLimit[SQLITE_LIMIT_LENGTH]); | 928 db->aLimit[SQLITE_LIMIT_LENGTH]); |
| 903 acc.db = db; | |
| 904 sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap); | 929 sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap); |
| 905 z = sqlite3StrAccumFinish(&acc); | 930 z = sqlite3StrAccumFinish(&acc); |
| 906 if( acc.accError==STRACCUM_NOMEM ){ | 931 if( acc.accError==STRACCUM_NOMEM ){ |
| 907 db->mallocFailed = 1; | 932 db->mallocFailed = 1; |
| 908 } | 933 } |
| 909 return z; | 934 return z; |
| 910 } | 935 } |
| 911 | 936 |
| 912 /* | 937 /* |
| 913 ** Print into memory obtained from sqliteMalloc(). Use the internal | 938 ** Print into memory obtained from sqliteMalloc(). Use the internal |
| 914 ** %-conversion extensions. | 939 ** %-conversion extensions. |
| 915 */ | 940 */ |
| 916 char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ | 941 char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ |
| 917 va_list ap; | 942 va_list ap; |
| 918 char *z; | 943 char *z; |
| 919 va_start(ap, zFormat); | 944 va_start(ap, zFormat); |
| 920 z = sqlite3VMPrintf(db, zFormat, ap); | 945 z = sqlite3VMPrintf(db, zFormat, ap); |
| 921 va_end(ap); | 946 va_end(ap); |
| 922 return z; | 947 return z; |
| 923 } | 948 } |
| 924 | 949 |
| 925 /* | 950 /* |
| 926 ** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting | |
| 927 ** the string and before returning. This routine is intended to be used | |
| 928 ** to modify an existing string. For example: | |
| 929 ** | |
| 930 ** x = sqlite3MPrintf(db, x, "prefix %s suffix", x); | |
| 931 ** | |
| 932 */ | |
| 933 char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){ | |
| 934 va_list ap; | |
| 935 char *z; | |
| 936 va_start(ap, zFormat); | |
| 937 z = sqlite3VMPrintf(db, zFormat, ap); | |
| 938 va_end(ap); | |
| 939 sqlite3DbFree(db, zStr); | |
| 940 return z; | |
| 941 } | |
| 942 | |
| 943 /* | |
| 944 ** Print into memory obtained from sqlite3_malloc(). Omit the internal | 951 ** Print into memory obtained from sqlite3_malloc(). Omit the internal |
| 945 ** %-conversion extensions. | 952 ** %-conversion extensions. |
| 946 */ | 953 */ |
| 947 char *sqlite3_vmprintf(const char *zFormat, va_list ap){ | 954 char *sqlite3_vmprintf(const char *zFormat, va_list ap){ |
| 948 char *z; | 955 char *z; |
| 949 char zBase[SQLITE_PRINT_BUF_SIZE]; | 956 char zBase[SQLITE_PRINT_BUF_SIZE]; |
| 950 StrAccum acc; | 957 StrAccum acc; |
| 958 |
| 959 #ifdef SQLITE_ENABLE_API_ARMOR |
| 960 if( zFormat==0 ){ |
| 961 (void)SQLITE_MISUSE_BKPT; |
| 962 return 0; |
| 963 } |
| 964 #endif |
| 951 #ifndef SQLITE_OMIT_AUTOINIT | 965 #ifndef SQLITE_OMIT_AUTOINIT |
| 952 if( sqlite3_initialize() ) return 0; | 966 if( sqlite3_initialize() ) return 0; |
| 953 #endif | 967 #endif |
| 954 sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); | 968 sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); |
| 955 acc.useMalloc = 2; | |
| 956 sqlite3VXPrintf(&acc, 0, zFormat, ap); | 969 sqlite3VXPrintf(&acc, 0, zFormat, ap); |
| 957 z = sqlite3StrAccumFinish(&acc); | 970 z = sqlite3StrAccumFinish(&acc); |
| 958 return z; | 971 return z; |
| 959 } | 972 } |
| 960 | 973 |
| 961 /* | 974 /* |
| 962 ** Print into memory obtained from sqlite3_malloc()(). Omit the internal | 975 ** Print into memory obtained from sqlite3_malloc()(). Omit the internal |
| 963 ** %-conversion extensions. | 976 ** %-conversion extensions. |
| 964 */ | 977 */ |
| 965 char *sqlite3_mprintf(const char *zFormat, ...){ | 978 char *sqlite3_mprintf(const char *zFormat, ...){ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 983 ** Oops: The first two arguments of sqlite3_snprintf() are backwards | 996 ** Oops: The first two arguments of sqlite3_snprintf() are backwards |
| 984 ** from the snprintf() standard. Unfortunately, it is too late to change | 997 ** from the snprintf() standard. Unfortunately, it is too late to change |
| 985 ** this without breaking compatibility, so we just have to live with the | 998 ** this without breaking compatibility, so we just have to live with the |
| 986 ** mistake. | 999 ** mistake. |
| 987 ** | 1000 ** |
| 988 ** sqlite3_vsnprintf() is the varargs version. | 1001 ** sqlite3_vsnprintf() is the varargs version. |
| 989 */ | 1002 */ |
| 990 char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ | 1003 char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ |
| 991 StrAccum acc; | 1004 StrAccum acc; |
| 992 if( n<=0 ) return zBuf; | 1005 if( n<=0 ) return zBuf; |
| 993 sqlite3StrAccumInit(&acc, zBuf, n, 0); | 1006 #ifdef SQLITE_ENABLE_API_ARMOR |
| 994 acc.useMalloc = 0; | 1007 if( zBuf==0 || zFormat==0 ) { |
| 1008 (void)SQLITE_MISUSE_BKPT; |
| 1009 if( zBuf ) zBuf[0] = 0; |
| 1010 return zBuf; |
| 1011 } |
| 1012 #endif |
| 1013 sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); |
| 995 sqlite3VXPrintf(&acc, 0, zFormat, ap); | 1014 sqlite3VXPrintf(&acc, 0, zFormat, ap); |
| 996 return sqlite3StrAccumFinish(&acc); | 1015 return sqlite3StrAccumFinish(&acc); |
| 997 } | 1016 } |
| 998 char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ | 1017 char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ |
| 999 char *z; | 1018 char *z; |
| 1000 va_list ap; | 1019 va_list ap; |
| 1001 va_start(ap,zFormat); | 1020 va_start(ap,zFormat); |
| 1002 z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); | 1021 z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); |
| 1003 va_end(ap); | 1022 va_end(ap); |
| 1004 return z; | 1023 return z; |
| 1005 } | 1024 } |
| 1006 | 1025 |
| 1007 /* | 1026 /* |
| 1008 ** This is the routine that actually formats the sqlite3_log() message. | 1027 ** This is the routine that actually formats the sqlite3_log() message. |
| 1009 ** We house it in a separate routine from sqlite3_log() to avoid using | 1028 ** We house it in a separate routine from sqlite3_log() to avoid using |
| 1010 ** stack space on small-stack systems when logging is disabled. | 1029 ** stack space on small-stack systems when logging is disabled. |
| 1011 ** | 1030 ** |
| 1012 ** sqlite3_log() must render into a static buffer. It cannot dynamically | 1031 ** sqlite3_log() must render into a static buffer. It cannot dynamically |
| 1013 ** allocate memory because it might be called while the memory allocator | 1032 ** allocate memory because it might be called while the memory allocator |
| 1014 ** mutex is held. | 1033 ** mutex is held. |
| 1034 ** |
| 1035 ** sqlite3VXPrintf() might ask for *temporary* memory allocations for |
| 1036 ** certain format characters (%q) or for very large precisions or widths. |
| 1037 ** Care must be taken that any sqlite3_log() calls that occur while the |
| 1038 ** memory mutex is held do not use these mechanisms. |
| 1015 */ | 1039 */ |
| 1016 static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ | 1040 static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ |
| 1017 StrAccum acc; /* String accumulator */ | 1041 StrAccum acc; /* String accumulator */ |
| 1018 char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ | 1042 char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ |
| 1019 | 1043 |
| 1020 sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0); | 1044 sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); |
| 1021 acc.useMalloc = 0; | |
| 1022 sqlite3VXPrintf(&acc, 0, zFormat, ap); | 1045 sqlite3VXPrintf(&acc, 0, zFormat, ap); |
| 1023 sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, | 1046 sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, |
| 1024 sqlite3StrAccumFinish(&acc)); | 1047 sqlite3StrAccumFinish(&acc)); |
| 1025 } | 1048 } |
| 1026 | 1049 |
| 1027 /* | 1050 /* |
| 1028 ** Format and write a message to the log if logging is enabled. | 1051 ** Format and write a message to the log if logging is enabled. |
| 1029 */ | 1052 */ |
| 1030 void sqlite3_log(int iErrCode, const char *zFormat, ...){ | 1053 void sqlite3_log(int iErrCode, const char *zFormat, ...){ |
| 1031 va_list ap; /* Vararg list */ | 1054 va_list ap; /* Vararg list */ |
| 1032 if( sqlite3GlobalConfig.xLog ){ | 1055 if( sqlite3GlobalConfig.xLog ){ |
| 1033 va_start(ap, zFormat); | 1056 va_start(ap, zFormat); |
| 1034 renderLogMsg(iErrCode, zFormat, ap); | 1057 renderLogMsg(iErrCode, zFormat, ap); |
| 1035 va_end(ap); | 1058 va_end(ap); |
| 1036 } | 1059 } |
| 1037 } | 1060 } |
| 1038 | 1061 |
| 1039 #if defined(SQLITE_DEBUG) | 1062 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) |
| 1040 /* | 1063 /* |
| 1041 ** A version of printf() that understands %lld. Used for debugging. | 1064 ** A version of printf() that understands %lld. Used for debugging. |
| 1042 ** The printf() built into some versions of windows does not understand %lld | 1065 ** The printf() built into some versions of windows does not understand %lld |
| 1043 ** and segfaults if you give it a long long int. | 1066 ** and segfaults if you give it a long long int. |
| 1044 */ | 1067 */ |
| 1045 void sqlite3DebugPrintf(const char *zFormat, ...){ | 1068 void sqlite3DebugPrintf(const char *zFormat, ...){ |
| 1046 va_list ap; | 1069 va_list ap; |
| 1047 StrAccum acc; | 1070 StrAccum acc; |
| 1048 char zBuf[500]; | 1071 char zBuf[500]; |
| 1049 sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0); | 1072 sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); |
| 1050 acc.useMalloc = 0; | |
| 1051 va_start(ap,zFormat); | 1073 va_start(ap,zFormat); |
| 1052 sqlite3VXPrintf(&acc, 0, zFormat, ap); | 1074 sqlite3VXPrintf(&acc, 0, zFormat, ap); |
| 1053 va_end(ap); | 1075 va_end(ap); |
| 1054 sqlite3StrAccumFinish(&acc); | 1076 sqlite3StrAccumFinish(&acc); |
| 1055 fprintf(stdout,"%s", zBuf); | 1077 fprintf(stdout,"%s", zBuf); |
| 1056 fflush(stdout); | 1078 fflush(stdout); |
| 1057 } | 1079 } |
| 1058 #endif | 1080 #endif |
| 1059 | 1081 |
| 1060 #ifdef SQLITE_DEBUG | |
| 1061 /************************************************************************* | |
| 1062 ** Routines for implementing the "TreeView" display of hierarchical | |
| 1063 ** data structures for debugging. | |
| 1064 ** | |
| 1065 ** The main entry points (coded elsewhere) are: | |
| 1066 ** sqlite3TreeViewExpr(0, pExpr, 0); | |
| 1067 ** sqlite3TreeViewExprList(0, pList, 0, 0); | |
| 1068 ** sqlite3TreeViewSelect(0, pSelect, 0); | |
| 1069 ** Insert calls to those routines while debugging in order to display | |
| 1070 ** a diagram of Expr, ExprList, and Select objects. | |
| 1071 ** | |
| 1072 */ | |
| 1073 /* Add a new subitem to the tree. The moreToFollow flag indicates that this | |
| 1074 ** is not the last item in the tree. */ | |
| 1075 TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ | |
| 1076 if( p==0 ){ | |
| 1077 p = sqlite3_malloc( sizeof(*p) ); | |
| 1078 if( p==0 ) return 0; | |
| 1079 memset(p, 0, sizeof(*p)); | |
| 1080 }else{ | |
| 1081 p->iLevel++; | |
| 1082 } | |
| 1083 assert( moreToFollow==0 || moreToFollow==1 ); | |
| 1084 if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow; | |
| 1085 return p; | |
| 1086 } | |
| 1087 /* Finished with one layer of the tree */ | |
| 1088 void sqlite3TreeViewPop(TreeView *p){ | |
| 1089 if( p==0 ) return; | |
| 1090 p->iLevel--; | |
| 1091 if( p->iLevel<0 ) sqlite3_free(p); | |
| 1092 } | |
| 1093 /* Generate a single line of output for the tree, with a prefix that contains | |
| 1094 ** all the appropriate tree lines */ | |
| 1095 void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ | |
| 1096 va_list ap; | |
| 1097 int i; | |
| 1098 StrAccum acc; | |
| 1099 char zBuf[500]; | |
| 1100 sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0); | |
| 1101 acc.useMalloc = 0; | |
| 1102 if( p ){ | |
| 1103 for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){ | |
| 1104 sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4); | |
| 1105 } | |
| 1106 sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); | |
| 1107 } | |
| 1108 va_start(ap, zFormat); | |
| 1109 sqlite3VXPrintf(&acc, 0, zFormat, ap); | |
| 1110 va_end(ap); | |
| 1111 if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1); | |
| 1112 sqlite3StrAccumFinish(&acc); | |
| 1113 fprintf(stdout,"%s", zBuf); | |
| 1114 fflush(stdout); | |
| 1115 } | |
| 1116 /* Shorthand for starting a new tree item that consists of a single label */ | |
| 1117 void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){ | |
| 1118 p = sqlite3TreeViewPush(p, moreToFollow); | |
| 1119 sqlite3TreeViewLine(p, "%s", zLabel); | |
| 1120 } | |
| 1121 #endif /* SQLITE_DEBUG */ | |
| 1122 | 1082 |
| 1123 /* | 1083 /* |
| 1124 ** variable-argument wrapper around sqlite3VXPrintf(). | 1084 ** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument |
| 1085 ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. |
| 1125 */ | 1086 */ |
| 1126 void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){ | 1087 void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){ |
| 1127 va_list ap; | 1088 va_list ap; |
| 1128 va_start(ap,zFormat); | 1089 va_start(ap,zFormat); |
| 1129 sqlite3VXPrintf(p, bFlags, zFormat, ap); | 1090 sqlite3VXPrintf(p, bFlags, zFormat, ap); |
| 1130 va_end(ap); | 1091 va_end(ap); |
| 1131 } | 1092 } |
| OLD | NEW |