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