1 /* 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 4 ** completeness. They are slightly out-of-date. 5 ** 6 ** The following modules is an enhanced replacement for the "printf" subroutines 7 ** found in the standard C library. The following enhancements are 8 ** supported: 9 ** 10 ** + Additional functions. The standard set of "printf" functions 11 ** includes printf, fprintf, sprintf, vprintf, vfprintf, and 12 ** vsprintf. This module adds the following: 13 ** 14 ** * snprintf -- Works like sprintf, but has an extra argument 15 ** which is the size of the buffer written to. 16 ** 17 ** * mprintf -- Similar to sprintf. Writes output to memory 18 ** obtained from malloc. 19 ** 20 ** * xprintf -- Calls a function to dispose of output. 21 ** 22 ** * nprintf -- No output, but returns the number of characters 23 ** that would have been output by printf. 24 ** 25 ** * A v- version (ex: vsnprintf) of every function is also 26 ** supplied. 27 ** 28 ** + A few extensions to the formatting notation are supported: 29 ** 30 ** * The "=" flag (similar to "-") causes the output to be 31 ** be centered in the appropriately sized field. 32 ** 33 ** * The %b field outputs an integer in binary notation. 34 ** 35 ** * The %c field now accepts a precision. The character output 36 ** is repeated by the number of times the precision specifies. 37 ** 38 ** * The %' field works like %c, but takes as its character the 39 ** next character of the format string, instead of the next 40 ** argument. For example, printf("%.78'-") prints 78 minus 41 ** signs, the same as printf("%.78c",'-'). 42 ** 43 ** + When compiled using GCC on a SPARC, this version of printf is 44 ** faster than the library printf for SUN OS 4.1. 45 ** 46 ** + All functions are fully reentrant. 47 ** 48 */ 49 #include "sqliteInt.h" 50 51 /* 52 ** Undefine COMPATIBILITY to make some slight changes in the way things 53 ** work. I think the changes are an improvement, but they are not 54 ** backwards compatible. 55 */ 56 /* #define COMPATIBILITY / * Compatible with SUN OS 4.1 */ 57 58 /* 59 ** Conversion types fall into various categories as defined by the 60 ** following enumeration. 61 */ 62 enum et_type { /* The type of the format field */ 63 etRADIX, /* Integer types. %d, %x, %o, and so forth */ 64 etFLOAT, /* Floating point. %f */ 65 etEXP, /* Exponentional notation. %e and %E */ 66 etGENERIC, /* Floating or exponential, depending on exponent. %g */ 67 etSIZE, /* Return number of characters processed so far. %n */ 68 etSTRING, /* Strings. %s */ 69 etDYNSTRING, /* Dynamically allocated strings. %z */ 70 etPERCENT, /* Percent symbol. %% */ 71 etCHARX, /* Characters. %c */ 72 etERROR, /* Used to indicate no such conversion type */ 73 /* The rest are extensions, not normally found in printf() */ 74 etCHARLIT, /* Literal characters. %' */ 75 etSQLESCAPE, /* Strings with '\'' doubled. %q */ 76 etSQLESCAPE2, /* Strings with '\'' doubled and enclosed in '', 77 NULL pointers replaced by SQL NULL. %Q */ 78 etORDINAL /* 1st, 2nd, 3rd and so forth */ 79 }; 80 81 /* 82 ** Each builtin conversion character (ex: the 'd' in "%d") is described 83 ** by an instance of the following structure 84 */ 85 typedef struct et_info { /* Information about each format field */ 86 int fmttype; /* The format field code letter */ 87 int base; /* The base for radix conversion */ 88 char *charset; /* The character set for conversion */ 89 int flag_signed; /* Is the quantity signed? */ 90 char *prefix; /* Prefix on non-zero values in alt format */ 91 enum et_type type; /* Conversion paradigm */ 92 } et_info; 93 94 /* 95 ** The following table is searched linearly, so it is good to put the 96 ** most frequently used conversion types first. 97 */ 98 static et_info fmtinfo[] = { 99 { 'd', 10, "0123456789", 1, 0, etRADIX, }, 100 { 's', 0, 0, 0, 0, etSTRING, }, 101 { 'z', 0, 0, 0, 0, etDYNSTRING, }, 102 { 'q', 0, 0, 0, 0, etSQLESCAPE, }, 103 { 'Q', 0, 0, 0, 0, etSQLESCAPE2, }, 104 { 'c', 0, 0, 0, 0, etCHARX, }, 105 { 'o', 8, "01234567", 0, "0", etRADIX, }, 106 { 'u', 10, "0123456789", 0, 0, etRADIX, }, 107 { 'x', 16, "0123456789abcdef", 0, "x0", etRADIX, }, 108 { 'X', 16, "0123456789ABCDEF", 0, "X0", etRADIX, }, 109 { 'r', 10, "0123456789", 0, 0, etORDINAL, }, 110 { 'f', 0, 0, 1, 0, etFLOAT, }, 111 { 'e', 0, "e", 1, 0, etEXP, }, 112 { 'E', 0, "E", 1, 0, etEXP, }, 113 { 'g', 0, "e", 1, 0, etGENERIC, }, 114 { 'G', 0, "E", 1, 0, etGENERIC, }, 115 { 'i', 10, "0123456789", 1, 0, etRADIX, }, 116 { 'n', 0, 0, 0, 0, etSIZE, }, 117 { '%', 0, 0, 0, 0, etPERCENT, }, 118 { 'b', 2, "01", 0, "b0", etRADIX, }, /* Binary */ 119 { 'p', 10, "0123456789", 0, 0, etRADIX, }, /* Pointers */ 120 { '\'', 0, 0, 0, 0, etCHARLIT, }, /* Literal char */ 121 }; 122 #define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0])) 123 124 /* 125 ** If NOFLOATINGPOINT is defined, then none of the floating point 126 ** conversions will work. 127 */ 128 #ifndef etNOFLOATINGPOINT 129 /* 130 ** "*val" is a double such that 0.1 <= *val < 10.0 131 ** Return the ascii code for the leading digit of *val, then 132 ** multiply "*val" by 10.0 to renormalize. 133 ** 134 ** Example: 135 ** input: *val = 3.14159 136 ** output: *val = 1.4159 function return = '3' 137 ** 138 ** The counter *cnt is incremented each time. After counter exceeds 139 ** 16 (the number of significant digits in a 64-bit float) '0' is 140 ** always returned. 141 */ 142 static int et_getdigit(double *val, int *cnt){ 143 int digit; 144 double d; 145 if( (*cnt)++ >= 16 ) return '0'; 146 digit = (int)*val; 147 d = digit; 148 digit += '0'; 149 *val = (*val - d)*10.0; 150 return digit; 151 } 152 #endif 153 154 #define etBUFSIZE 1000 /* Size of the output buffer */ 155 156 /* 157 ** The root program. All variations call this core. 158 ** 159 ** INPUTS: 160 ** func This is a pointer to a function taking three arguments 161 ** 1. A pointer to anything. Same as the "arg" parameter. 162 ** 2. A pointer to the list of characters to be output 163 ** (Note, this list is NOT null terminated.) 164 ** 3. An integer number of characters to be output. 165 ** (Note: This number might be zero.) 166 ** 167 ** arg This is the pointer to anything which will be passed as the 168 ** first argument to "func". Use it for whatever you like. 169 ** 170 ** fmt This is the format string, as in the usual print. 171 ** 172 ** ap This is a pointer to a list of arguments. Same as in 173 ** vfprint. 174 ** 175 ** OUTPUTS: 176 ** The return value is the total number of characters sent to 177 ** the function "func". Returns -1 on a error. 178 ** 179 ** Note that the order in which automatic variables are declared below 180 ** seems to make a big difference in determining how fast this beast 181 ** will run. 182 */ 183 static int vxprintf( 184 void (*func)(void*,char*,int), 185 void *arg, 186 const char *format, 187 va_list ap 188 ){ 189 register const char *fmt; /* The format string. */ 190 register int c; /* Next character in the format string */ 191 register char *bufpt; /* Pointer to the conversion buffer */ 192 register int precision; /* Precision of the current field */ 193 register int length; /* Length of the field */ 194 register int idx; /* A general purpose loop counter */ 195 int count; /* Total number of characters output */ 196 int width; /* Width of the current field */ 197 int flag_leftjustify; /* True if "-" flag is present */ 198 int flag_plussign; /* True if "+" flag is present */ 199 int flag_blanksign; /* True if " " flag is present */ 200 int flag_alternateform; /* True if "#" flag is present */ 201 int flag_zeropad; /* True if field width constant starts with zero */ 202 int flag_long; /* True if "l" flag is present */ 203 int flag_center; /* True if "=" flag is present */ 204 unsigned long longvalue; /* Value for integer types */ 205 double realvalue; /* Value for real types */ 206 et_info *infop; /* Pointer to the appropriate info structure */ 207 char buf[etBUFSIZE]; /* Conversion buffer */ 208 char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ 209 int errorflag = 0; /* True if an error is encountered */ 210 enum et_type xtype; /* Conversion paradigm */ 211 char *zExtra; /* Extra memory used for etTCLESCAPE conversions */ 212 static char spaces[] = " " 213 " "; 214 #define etSPACESIZE (sizeof(spaces)-1) 215 #ifndef etNOFLOATINGPOINT 216 int exp; /* exponent of real numbers */ 217 double rounder; /* Used for rounding floating point values */ 218 int flag_dp; /* True if decimal point should be shown */ 219 int flag_rtz; /* True if trailing zeros should be removed */ 220 int flag_exp; /* True to force display of the exponent */ 221 int nsd; /* Number of significant digits returned */ 222 #endif 223 224 fmt = format; /* Put in a register for speed */ 225 count = length = 0; 226 bufpt = 0; 227 for(; (c=(*fmt))!=0; ++fmt){ 228 if( c!='%' ){ 229 register int amt; 230 bufpt = (char *)fmt; 231 amt = 1; 232 while( (c=(*++fmt))!='%' && c!=0 ) amt++; 233 (*func)(arg,bufpt,amt); 234 count += amt; 235 if( c==0 ) break; 236 } 237 if( (c=(*++fmt))==0 ){ 238 errorflag = 1; 239 (*func)(arg,"%",1); 240 count++; 241 break; 242 } 243 /* Find out what flags are present */ 244 flag_leftjustify = flag_plussign = flag_blanksign = 245 flag_alternateform = flag_zeropad = flag_center = 0; 246 do{ 247 switch( c ){ 248 case '-': flag_leftjustify = 1; c = 0; break; 249 case '+': flag_plussign = 1; c = 0; break; 250 case ' ': flag_blanksign = 1; c = 0; break; 251 case '#': flag_alternateform = 1; c = 0; break; 252 case '0': flag_zeropad = 1; c = 0; break; 253 case '=': flag_center = 1; c = 0; break; 254 default: break; 255 } 256 }while( c==0 && (c=(*++fmt))!=0 ); 257 if( flag_center ) flag_leftjustify = 0; 258 /* Get the field width */ 259 width = 0; 260 if( c=='*' ){ 261 width = va_arg(ap,int); 262 if( width<0 ){ 263 flag_leftjustify = 1; 264 width = -width; 265 } 266 c = *++fmt; 267 }else{ 268 while( c>='0' && c<='9' ){ 269 width = width*10 + c - '0'; 270 c = *++fmt; 271 } 272 } 273 if( width > etBUFSIZE-10 ){ 274 width = etBUFSIZE-10; 275 } 276 /* Get the precision */ 277 if( c=='.' ){ 278 precision = 0; 279 c = *++fmt; 280 if( c=='*' ){ 281 precision = va_arg(ap,int); 282 #ifndef etCOMPATIBILITY 283 /* This is sensible, but SUN OS 4.1 doesn't do it. */ 284 if( precision<0 ) precision = -precision; 285 #endif 286 c = *++fmt; 287 }else{ 288 while( c>='0' && c<='9' ){ 289 precision = precision*10 + c - '0'; 290 c = *++fmt; 291 } 292 } 293 /* Limit the precision to prevent overflowing buf[] during conversion */ 294 if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40; 295 }else{ 296 precision = -1; 297 } 298 /* Get the conversion type modifier */ 299 if( c=='l' ){ 300 flag_long = 1; 301 c = *++fmt; 302 }else{ 303 flag_long = 0; 304 } 305 /* Fetch the info entry for the field */ 306 infop = 0; 307 for(idx=0; idx<etNINFO; idx++){ 308 if( c==fmtinfo[idx].fmttype ){ 309 infop = &fmtinfo[idx]; 310 break; 311 } 312 } 313 /* No info entry found. It must be an error. */ 314 if( infop==0 ){ 315 xtype = etERROR; 316 }else{ 317 xtype = infop->type; 318 } 319 zExtra = 0; 320 321 /* 322 ** At this point, variables are initialized as follows: 323 ** 324 ** flag_alternateform TRUE if a '#' is present. 325 ** flag_plussign TRUE if a '+' is present. 326 ** flag_leftjustify TRUE if a '-' is present or if the 327 ** field width was negative. 328 ** flag_zeropad TRUE if the width began with 0. 329 ** flag_long TRUE if the letter 'l' (ell) prefixed 330 ** the conversion character. 331 ** flag_blanksign TRUE if a ' ' is present. 332 ** width The specified field width. This is 333 ** always non-negative. Zero is the default. 334 ** precision The specified precision. The default 335 ** is -1. 336 ** xtype The class of the conversion. 337 ** infop Pointer to the appropriate info struct. 338 */ 339 switch( xtype ){ 340 case etORDINAL: 341 case etRADIX: 342 if( flag_long ) longvalue = va_arg(ap,long); 343 else longvalue = va_arg(ap,int); 344 #ifdef etCOMPATIBILITY 345 /* For the format %#x, the value zero is printed "0" not "0x0". 346 ** I think this is stupid. */ 347 if( longvalue==0 ) flag_alternateform = 0; 348 #else 349 /* More sensible: turn off the prefix for octal (to prevent "00"), 350 ** but leave the prefix for hex. */ 351 if( longvalue==0 && infop->base==8 ) flag_alternateform = 0; 352 #endif 353 if( infop->flag_signed ){ 354 if( *(long*)&longvalue<0 ){ 355 longvalue = -*(long*)&longvalue; 356 prefix = '-'; 357 }else if( flag_plussign ) prefix = '+'; 358 else if( flag_blanksign ) prefix = ' '; 359 else prefix = 0; 360 }else prefix = 0; 361 if( flag_zeropad && precision<width-(prefix!=0) ){ 362 precision = width-(prefix!=0); 363 } 364 bufpt = &buf[etBUFSIZE]; 365 if( xtype==etORDINAL ){ 366 long a,b; 367 a = longvalue%10; 368 b = longvalue%100; 369 bufpt -= 2; 370 if( a==0 || a>3 || (b>10 && b<14) ){ 371 bufpt[0] = 't'; 372 bufpt[1] = 'h'; 373 }else if( a==1 ){ 374 bufpt[0] = 's'; 375 bufpt[1] = 't'; 376 }else if( a==2 ){ 377 bufpt[0] = 'n'; 378 bufpt[1] = 'd'; 379 }else if( a==3 ){ 380 bufpt[0] = 'r'; 381 bufpt[1] = 'd'; 382 } 383 } 384 { 385 register char *cset; /* Use registers for speed */ 386 register int base; 387 cset = infop->charset; 388 base = infop->base; 389 do{ /* Convert to ascii */ 390 *(--bufpt) = cset[longvalue%base]; 391 longvalue = longvalue/base; 392 }while( longvalue>0 ); 393 } 394 length = &buf[etBUFSIZE]-bufpt; 395 for(idx=precision-length; idx>0; idx--){ 396 *(--bufpt) = '0'; /* Zero pad */ 397 } 398 if( prefix ) *(--bufpt) = prefix; /* Add sign */ 399 if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ 400 char *pre, x; 401 pre = infop->prefix; 402 if( *bufpt!=pre[0] ){ 403 for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x; 404 } 405 } 406 length = &buf[etBUFSIZE]-bufpt; 407 break; 408 case etFLOAT: 409 case etEXP: 410 case etGENERIC: 411 realvalue = va_arg(ap,double); 412 #ifndef etNOFLOATINGPOINT 413 if( precision<0 ) precision = 6; /* Set default precision */ 414 if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10; 415 if( realvalue<0.0 ){ 416 realvalue = -realvalue; 417 prefix = '-'; 418 }else{ 419 if( flag_plussign ) prefix = '+'; 420 else if( flag_blanksign ) prefix = ' '; 421 else prefix = 0; 422 } 423 if( infop->type==etGENERIC && precision>0 ) precision--; 424 rounder = 0.0; 425 #ifdef COMPATIBILITY 426 /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */ 427 for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); 428 #else 429 /* It makes more sense to use 0.5 */ 430 for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1); 431 #endif 432 if( infop->type==etFLOAT ) realvalue += rounder; 433 /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ 434 exp = 0; 435 if( realvalue>0.0 ){ 436 int k = 0; 437 while( realvalue>=1e8 && k++<100 ){ realvalue *= 1e-8; exp+=8; } 438 while( realvalue>=10.0 && k++<100 ){ realvalue *= 0.1; exp++; } 439 while( realvalue<1e-8 && k++<100 ){ realvalue *= 1e8; exp-=8; } 440 while( realvalue<1.0 && k++<100 ){ realvalue *= 10.0; exp--; } 441 if( k>=100 ){ 442 bufpt = "NaN"; 443 length = 3; 444 break; 445 } 446 } 447 bufpt = buf; 448 /* 449 ** If the field type is etGENERIC, then convert to either etEXP 450 ** or etFLOAT, as appropriate. 451 */ 452 flag_exp = xtype==etEXP; 453 if( xtype!=etFLOAT ){ 454 realvalue += rounder; 455 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } 456 } 457 if( xtype==etGENERIC ){ 458 flag_rtz = !flag_alternateform; 459 if( exp<-4 || exp>precision ){ 460 xtype = etEXP; 461 }else{ 462 precision = precision - exp; 463 xtype = etFLOAT; 464 } 465 }else{ 466 flag_rtz = 0; 467 } 468 /* 469 ** The "exp+precision" test causes output to be of type etEXP if 470 ** the precision is too large to fit in buf[]. 471 */ 472 nsd = 0; 473 if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){ 474 flag_dp = (precision>0 || flag_alternateform); 475 if( prefix ) *(bufpt++) = prefix; /* Sign */ 476 if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */ 477 else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd); 478 if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */ 479 for(exp++; exp<0 && precision>0; precision--, exp++){ 480 *(bufpt++) = '0'; 481 } 482 while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd); 483 *(bufpt--) = 0; /* Null terminate */ 484 if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */ 485 while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; 486 if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; 487 } 488 bufpt++; /* point to next free slot */ 489 }else{ /* etEXP or etGENERIC */ 490 flag_dp = (precision>0 || flag_alternateform); 491 if( prefix ) *(bufpt++) = prefix; /* Sign */ 492 *(bufpt++) = et_getdigit(&realvalue,&nsd); /* First digit */ 493 if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */ 494 while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd); 495 bufpt--; /* point to last digit */ 496 if( flag_rtz && flag_dp ){ /* Remove tail zeros */ 497 while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; 498 if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; 499 } 500 bufpt++; /* point to next free slot */ 501 if( exp || flag_exp ){ 502 *(bufpt++) = infop->charset[0]; 503 if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */ 504 else { *(bufpt++) = '+'; } 505 if( exp>=100 ){ 506 *(bufpt++) = (exp/100)+'0'; /* 100's digit */ 507 exp %= 100; 508 } 509 *(bufpt++) = exp/10+'0'; /* 10's digit */ 510 *(bufpt++) = exp%10+'0'; /* 1's digit */ 511 } 512 } 513 /* The converted number is in buf[] and zero terminated. Output it. 514 ** Note that the number is in the usual order, not reversed as with 515 ** integer conversions. */ 516 length = bufpt-buf; 517 bufpt = buf; 518 519 /* Special case: Add leading zeros if the flag_zeropad flag is 520 ** set and we are not left justified */ 521 if( flag_zeropad && !flag_leftjustify && length < width){ 522 int i; 523 int nPad = width - length; 524 for(i=width; i>=nPad; i--){ 525 bufpt[i] = bufpt[i-nPad]; 526 } 527 i = prefix!=0; 528 while( nPad-- ) bufpt[i++] = '0'; 529 length = width; 530 } 531 #endif 532 break; 533 case etSIZE: 534 *(va_arg(ap,int*)) = count; 535 length = width = 0; 536 break; 537 case etPERCENT: 538 buf[0] = '%'; 539 bufpt = buf; 540 length = 1; 541 break; 542 case etCHARLIT: 543 case etCHARX: 544 c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt); 545 if( precision>=0 ){ 546 for(idx=1; idx<precision; idx++) buf[idx] = c; 547 length = precision; 548 }else{ 549 length =1; 550 } 551 bufpt = buf; 552 break; 553 case etSTRING: 554 case etDYNSTRING: 555 bufpt = va_arg(ap,char*); 556 if( bufpt==0 ){ 557 bufpt = ""; 558 }else if( xtype==etDYNSTRING ){ 559 zExtra = bufpt; 560 } 561 length = strlen(bufpt); 562 if( precision>=0 && precision<length ) length = precision; 563 break; 564 case etSQLESCAPE: 565 case etSQLESCAPE2: 566 { 567 int i, j, n, c, isnull; 568 char *arg = va_arg(ap,char*); 569 isnull = arg==0; 570 if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); 571 for(i=n=0; (c=arg[i])!=0; i++){ 572 if( c=='\'' ) n++; 573 } 574 n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0); 575 if( n>etBUFSIZE ){ 576 bufpt = zExtra = sqliteMalloc( n ); 577 if( bufpt==0 ) return -1; 578 }else{ 579 bufpt = buf; 580 } 581 j = 0; 582 if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\''; 583 for(i=0; (c=arg[i])!=0; i++){ 584 bufpt[j++] = c; 585 if( c=='\'' ) bufpt[j++] = c; 586 } 587 if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\''; 588 bufpt[j] = 0; 589 length = j; 590 if( precision>=0 && precision<length ) length = precision; 591 } 592 break; 593 case etERROR: 594 buf[0] = '%'; 595 buf[1] = c; 596 errorflag = 0; 597 idx = 1+(c!=0); 598 (*func)(arg,"%",idx); 599 count += idx; 600 if( c==0 ) fmt--; 601 break; 602 }/* End switch over the format type */ 603 /* 604 ** The text of the conversion is pointed to by "bufpt" and is 605 ** "length" characters long. The field width is "width". Do 606 ** the output. 607 */ 608 if( !flag_leftjustify ){ 609 register int nspace; 610 nspace = width-length; 611 if( nspace>0 ){ 612 if( flag_center ){ 613 nspace = nspace/2; 614 width -= nspace; 615 flag_leftjustify = 1; 616 } 617 count += nspace; 618 while( nspace>=etSPACESIZE ){ 619 (*func)(arg,spaces,etSPACESIZE); 620 nspace -= etSPACESIZE; 621 } 622 if( nspace>0 ) (*func)(arg,spaces,nspace); 623 } 624 } 625 if( length>0 ){ 626 (*func)(arg,bufpt,length); 627 count += length; 628 } 629 if( flag_leftjustify ){ 630 register int nspace; 631 nspace = width-length; 632 if( nspace>0 ){ 633 count += nspace; 634 while( nspace>=etSPACESIZE ){ 635 (*func)(arg,spaces,etSPACESIZE); 636 nspace -= etSPACESIZE; 637 } 638 if( nspace>0 ) (*func)(arg,spaces,nspace); 639 } 640 } 641 if( zExtra ){ 642 if( xtype==etDYNSTRING ){ 643 free(zExtra); 644 }else{ 645 sqliteFree(zExtra); 646 } 647 } 648 }/* End for loop over the format string */ 649 return errorflag ? -1 : count; 650 } /* End of function */ 651 652 653 /* This structure is used to store state information about the 654 ** write to memory that is currently in progress. 655 */ 656 struct sgMprintf { 657 char *zBase; /* A base allocation */ 658 char *zText; /* The string collected so far */ 659 int nChar; /* Length of the string so far */ 660 int nAlloc; /* Amount of space allocated in zText */ 661 }; 662 663 /* 664 ** This function implements the callback from vxprintf. 665 ** 666 ** This routine add nNewChar characters of text in zNewText to 667 ** the sgMprintf structure pointed to by "arg". 668 */ 669 static void mout(void *arg, char *zNewText, int nNewChar){ 670 struct sgMprintf *pM = (struct sgMprintf*)arg; 671 if( pM->nChar + nNewChar + 1 > pM->nAlloc ){ 672 pM->nAlloc = pM->nChar + nNewChar*2 + 1; 673 if( pM->zText==pM->zBase ){ 674 pM->zText = sqliteMalloc(pM->nAlloc); 675 if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar); 676 }else{ 677 char *z = sqliteRealloc(pM->zText, pM->nAlloc); 678 if( z==0 ){ 679 sqliteFree(pM->zText); 680 pM->nChar = 0; 681 pM->nAlloc = 0; 682 } 683 pM->zText = z; 684 } 685 } 686 if( pM->zText ){ 687 memcpy(&pM->zText[pM->nChar], zNewText, nNewChar); 688 pM->nChar += nNewChar; 689 pM->zText[pM->nChar] = 0; 690 } 691 } 692 693 /* 694 ** sqlite_mprintf() works like printf(), but allocations memory to hold the 695 ** resulting string and returns a pointer to the allocated memory. Use 696 ** sqliteFree() to release the memory allocated. 697 */ 698 char *sqliteMPrintf(const char *zFormat, ...){ 699 va_list ap; 700 struct sgMprintf sMprintf; 701 char zBuf[200]; 702 703 sMprintf.nChar = 0; 704 sMprintf.nAlloc = sizeof(zBuf); 705 sMprintf.zText = zBuf; 706 sMprintf.zBase = zBuf; 707 va_start(ap,zFormat); 708 vxprintf(mout,&sMprintf,zFormat,ap); 709 va_end(ap); 710 sMprintf.zText[sMprintf.nChar] = 0; 711 return sqliteRealloc(sMprintf.zText, sMprintf.nChar+1); 712 } 713 714 /* 715 ** sqlite_mprintf() works like printf(), but allocations memory to hold the 716 ** resulting string and returns a pointer to the allocated memory. Use 717 ** sqliteFree() to release the memory allocated. 718 */ 719 char *sqlite_mprintf(const char *zFormat, ...){ 720 va_list ap; 721 struct sgMprintf sMprintf; 722 char *zNew; 723 char zBuf[200]; 724 725 sMprintf.nChar = 0; 726 sMprintf.nAlloc = sizeof(zBuf); 727 sMprintf.zText = zBuf; 728 sMprintf.zBase = zBuf; 729 va_start(ap,zFormat); 730 vxprintf(mout,&sMprintf,zFormat,ap); 731 va_end(ap); 732 sMprintf.zText[sMprintf.nChar] = 0; 733 zNew = malloc( sMprintf.nChar+1 ); 734 if( zNew ) strcpy(zNew,sMprintf.zText); 735 if( sMprintf.zText!=sMprintf.zBase ){ 736 sqliteFree(sMprintf.zText); 737 } 738 return zNew; 739 } 740 741 /* This is the varargs version of sqlite_mprintf. 742 */ 743 char *sqlite_vmprintf(const char *zFormat, va_list ap){ 744 struct sgMprintf sMprintf; 745 char *zNew; 746 char zBuf[200]; 747 sMprintf.nChar = 0; 748 sMprintf.zText = zBuf; 749 sMprintf.nAlloc = sizeof(zBuf); 750 sMprintf.zBase = zBuf; 751 vxprintf(mout,&sMprintf,zFormat,ap); 752 sMprintf.zText[sMprintf.nChar] = 0; 753 zNew = malloc( sMprintf.nChar+1 ); 754 if( zNew ) strcpy(zNew,sMprintf.zText); 755 if( sMprintf.zText!=sMprintf.zBase ){ 756 sqliteFree(sMprintf.zText); 757 } 758 return zNew; 759 } 760 761 /* 762 ** The following four routines implement the varargs versions of the 763 ** sqlite_exec() and sqlite_get_table() interfaces. See the sqlite.h 764 ** header files for a more detailed description of how these interfaces 765 ** work. 766 ** 767 ** These routines are all just simple wrappers. 768 */ 769 int sqlite_exec_printf( 770 sqlite *db, /* An open database */ 771 const char *sqlFormat, /* printf-style format string for the SQL */ 772 sqlite_callback xCallback, /* Callback function */ 773 void *pArg, /* 1st argument to callback function */ 774 char **errmsg, /* Error msg written here */ 775 ... /* Arguments to the format string. */ 776 ){ 777 va_list ap; 778 int rc; 779 780 va_start(ap, errmsg); 781 rc = sqlite_exec_vprintf(db, sqlFormat, xCallback, pArg, errmsg, ap); 782 va_end(ap); 783 return rc; 784 } 785 int sqlite_exec_vprintf( 786 sqlite *db, /* An open database */ 787 const char *sqlFormat, /* printf-style format string for the SQL */ 788 sqlite_callback xCallback, /* Callback function */ 789 void *pArg, /* 1st argument to callback function */ 790 char **errmsg, /* Error msg written here */ 791 va_list ap /* Arguments to the format string. */ 792 ){ 793 char *zSql; 794 int rc; 795 796 zSql = sqlite_vmprintf(sqlFormat, ap); 797 rc = sqlite_exec(db, zSql, xCallback, pArg, errmsg); 798 free(zSql); 799 return rc; 800 } 801 int sqlite_get_table_printf( 802 sqlite *db, /* An open database */ 803 const char *sqlFormat, /* printf-style format string for the SQL */ 804 char ***resultp, /* Result written to a char *[] that this points to */ 805 int *nrow, /* Number of result rows written here */ 806 int *ncol, /* Number of result columns written here */ 807 char **errmsg, /* Error msg written here */ 808 ... /* Arguments to the format string */ 809 ){ 810 va_list ap; 811 int rc; 812 813 va_start(ap, errmsg); 814 rc = sqlite_get_table_vprintf(db, sqlFormat, resultp, nrow, ncol, errmsg, ap); 815 va_end(ap); 816 return rc; 817 } 818 int sqlite_get_table_vprintf( 819 sqlite *db, /* An open database */ 820 const char *sqlFormat, /* printf-style format string for the SQL */ 821 char ***resultp, /* Result written to a char *[] that this points to */ 822 int *nrow, /* Number of result rows written here */ 823 int *ncolumn, /* Number of result columns written here */ 824 char **errmsg, /* Error msg written here */ 825 va_list ap /* Arguments to the format string */ 826 ){ 827 char *zSql; 828 int rc; 829 830 zSql = sqlite_vmprintf(sqlFormat, ap); 831 rc = sqlite_get_table(db, zSql, resultp, nrow, ncolumn, errmsg); 832 free(zSql); 833 return rc; 834 } 835