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 : */
150 0 : static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
151 : int digit;
152 : LONGDOUBLE_TYPE d;
153 0 : if( (*cnt)++ >= 16 ) return '0';
154 0 : digit = (int)*val;
155 0 : d = digit;
156 0 : digit += '0';
157 0 : *val = (*val - d)*10.0;
158 0 : 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 : */
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 608 : ){
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 608 : 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 608 : func(arg,"",0);
231 608 : count = length = 0;
232 608 : bufpt = 0;
233 1216 : for(; (c=(*fmt))!=0; ++fmt){
234 736 : if( c!='%' ){
235 : int amt;
236 556 : bufpt = (char *)fmt;
237 556 : amt = 1;
238 556 : while( (c=(*++fmt))!='%' && c!=0 ) amt++;
239 556 : (*func)(arg,bufpt,amt);
240 556 : count += amt;
241 556 : if( c==0 ) break;
242 : }
243 608 : if( (c=(*++fmt))==0 ){
244 0 : errorflag = 1;
245 0 : (*func)(arg,"%",1);
246 0 : count++;
247 0 : break;
248 : }
249 : /* Find out what flags are present */
250 608 : flag_leftjustify = flag_plussign = flag_blanksign =
251 : flag_alternateform = flag_zeropad = 0;
252 : do{
253 608 : switch( c ){
254 0 : case '-': flag_leftjustify = 1; c = 0; break;
255 0 : case '+': flag_plussign = 1; c = 0; break;
256 0 : case ' ': flag_blanksign = 1; c = 0; break;
257 0 : case '#': flag_alternateform = 1; c = 0; break;
258 0 : case '0': flag_zeropad = 1; c = 0; break;
259 : default: break;
260 : }
261 608 : }while( c==0 && (c=(*++fmt))!=0 );
262 : /* Get the field width */
263 608 : width = 0;
264 608 : if( c=='*' ){
265 0 : width = va_arg(ap,int);
266 0 : if( width<0 ){
267 0 : flag_leftjustify = 1;
268 0 : width = -width;
269 : }
270 0 : c = *++fmt;
271 : }else{
272 1216 : while( c>='0' && c<='9' ){
273 0 : width = width*10 + c - '0';
274 0 : c = *++fmt;
275 : }
276 : }
277 608 : if( width > etBUFSIZE-10 ){
278 0 : width = etBUFSIZE-10;
279 : }
280 : /* Get the precision */
281 608 : if( c=='.' ){
282 0 : precision = 0;
283 0 : c = *++fmt;
284 0 : if( c=='*' ){
285 0 : precision = va_arg(ap,int);
286 0 : if( precision<0 ) precision = -precision;
287 0 : c = *++fmt;
288 : }else{
289 0 : while( c>='0' && c<='9' ){
290 0 : precision = precision*10 + c - '0';
291 0 : c = *++fmt;
292 : }
293 : }
294 : /* Limit the precision to prevent overflowing buf[] during conversion */
295 0 : if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40;
296 : }else{
297 608 : precision = -1;
298 : }
299 : /* Get the conversion type modifier */
300 608 : if( c=='l' ){
301 0 : flag_long = 1;
302 0 : c = *++fmt;
303 : }else{
304 608 : flag_long = 0;
305 : }
306 : /* Fetch the info entry for the field */
307 608 : infop = 0;
308 608 : xtype = etERROR;
309 6701 : for(idx=0; idx<etNINFO; idx++){
310 6701 : if( c==fmtinfo[idx].fmttype ){
311 608 : infop = &fmtinfo[idx];
312 608 : if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
313 608 : xtype = infop->type;
314 : }
315 608 : break;
316 : }
317 : }
318 608 : 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 608 : switch( xtype ){
339 : case etRADIX:
340 169 : if( flag_long ) longvalue = va_arg(ap,long);
341 169 : 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 169 : 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 169 : if( infop->flags & FLAG_SIGNED ){
352 169 : if( *(long*)&longvalue<0 ){
353 0 : longvalue = -*(long*)&longvalue;
354 0 : prefix = '-';
355 169 : }else if( flag_plussign ) prefix = '+';
356 169 : else if( flag_blanksign ) prefix = ' ';
357 169 : else prefix = 0;
358 0 : }else prefix = 0;
359 169 : if( flag_zeropad && precision<width-(prefix!=0) ){
360 0 : precision = width-(prefix!=0);
361 : }
362 169 : bufpt = &buf[etBUFSIZE-1];
363 : {
364 : register char *cset; /* Use registers for speed */
365 : register int base;
366 169 : cset = infop->charset;
367 169 : base = infop->base;
368 : do{ /* Convert to ascii */
369 170 : *(--bufpt) = cset[longvalue%base];
370 170 : longvalue = longvalue/base;
371 170 : }while( longvalue>0 );
372 : }
373 169 : length = &buf[etBUFSIZE-1]-bufpt;
374 169 : for(idx=precision-length; idx>0; idx--){
375 0 : *(--bufpt) = '0'; /* Zero pad */
376 : }
377 169 : if( prefix ) *(--bufpt) = prefix; /* Add sign */
378 169 : if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
379 : char *pre, x;
380 0 : pre = infop->prefix;
381 0 : if( *bufpt!=pre[0] ){
382 0 : for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
383 : }
384 : }
385 169 : length = &buf[etBUFSIZE-1]-bufpt;
386 169 : break;
387 : case etFLOAT:
388 : case etEXP:
389 : case etGENERIC:
390 0 : realvalue = va_arg(ap,double);
391 : #ifndef etNOFLOATINGPOINT
392 0 : if( precision<0 ) precision = 6; /* Set default precision */
393 0 : if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
394 0 : if( realvalue<0.0 ){
395 0 : realvalue = -realvalue;
396 0 : prefix = '-';
397 : }else{
398 0 : if( flag_plussign ) prefix = '+';
399 0 : else if( flag_blanksign ) prefix = ' ';
400 0 : else prefix = 0;
401 : }
402 0 : if( infop->type==etGENERIC && precision>0 ) precision--;
403 0 : 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 0 : for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
410 : #endif
411 0 : if( infop->type==etFLOAT ) realvalue += rounder;
412 : /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
413 0 : exp = 0;
414 0 : if( realvalue>0.0 ){
415 0 : while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
416 0 : while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
417 0 : while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
418 0 : while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
419 0 : if( exp>350 || exp<-350 ){
420 0 : bufpt = "NaN";
421 0 : length = 3;
422 0 : break;
423 : }
424 : }
425 0 : bufpt = buf;
426 : /*
427 : ** If the field type is etGENERIC, then convert to either etEXP
428 : ** or etFLOAT, as appropriate.
429 : */
430 0 : flag_exp = xtype==etEXP;
431 0 : if( xtype!=etFLOAT ){
432 0 : realvalue += rounder;
433 0 : if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
434 : }
435 0 : if( xtype==etGENERIC ){
436 0 : flag_rtz = !flag_alternateform;
437 0 : if( exp<-4 || exp>precision ){
438 0 : xtype = etEXP;
439 : }else{
440 0 : precision = precision - exp;
441 0 : xtype = etFLOAT;
442 : }
443 : }else{
444 0 : 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 0 : nsd = 0;
451 0 : if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
452 0 : flag_dp = (precision>0 || flag_alternateform);
453 0 : if( prefix ) *(bufpt++) = prefix; /* Sign */
454 0 : if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */
455 0 : else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);
456 0 : if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */
457 0 : for(exp++; exp<0 && precision>0; precision--, exp++){
458 0 : *(bufpt++) = '0';
459 : }
460 0 : while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
461 0 : *(bufpt--) = 0; /* Null terminate */
462 0 : if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */
463 0 : while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
464 0 : if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
465 : }
466 0 : bufpt++; /* point to next free slot */
467 : }else{ /* etEXP or etGENERIC */
468 0 : flag_dp = (precision>0 || flag_alternateform);
469 0 : if( prefix ) *(bufpt++) = prefix; /* Sign */
470 0 : *(bufpt++) = et_getdigit(&realvalue,&nsd); /* First digit */
471 0 : if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */
472 0 : while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
473 0 : bufpt--; /* point to last digit */
474 0 : if( flag_rtz && flag_dp ){ /* Remove tail zeros */
475 0 : while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
476 0 : if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
477 : }
478 0 : bufpt++; /* point to next free slot */
479 0 : if( exp || flag_exp ){
480 0 : *(bufpt++) = infop->charset[0];
481 0 : if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
482 0 : else { *(bufpt++) = '+'; }
483 0 : if( exp>=100 ){
484 0 : *(bufpt++) = (exp/100)+'0'; /* 100's digit */
485 0 : exp %= 100;
486 : }
487 0 : *(bufpt++) = exp/10+'0'; /* 10's digit */
488 0 : *(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 0 : length = bufpt-buf;
495 0 : bufpt = buf;
496 :
497 : /* Special case: Add leading zeros if the flag_zeropad flag is
498 : ** set and we are not left justified */
499 0 : if( flag_zeropad && !flag_leftjustify && length < width){
500 : int i;
501 0 : int nPad = width - length;
502 0 : for(i=width; i>=nPad; i--){
503 0 : bufpt[i] = bufpt[i-nPad];
504 : }
505 0 : i = prefix!=0;
506 0 : while( nPad-- ) bufpt[i++] = '0';
507 0 : length = width;
508 : }
509 : #endif
510 0 : break;
511 : case etSIZE:
512 0 : *(va_arg(ap,int*)) = count;
513 0 : length = width = 0;
514 0 : break;
515 : case etPERCENT:
516 0 : buf[0] = '%';
517 0 : bufpt = buf;
518 0 : length = 1;
519 0 : break;
520 : case etCHARLIT:
521 : case etCHARX:
522 0 : c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
523 0 : if( precision>=0 ){
524 0 : for(idx=1; idx<precision; idx++) buf[idx] = c;
525 0 : length = precision;
526 : }else{
527 0 : length =1;
528 : }
529 0 : bufpt = buf;
530 0 : break;
531 : case etSTRING:
532 : case etDYNSTRING:
533 4 : bufpt = va_arg(ap,char*);
534 4 : if( bufpt==0 ){
535 0 : bufpt = "";
536 4 : }else if( xtype==etDYNSTRING ){
537 0 : zExtra = bufpt;
538 : }
539 4 : length = strlen(bufpt);
540 4 : if( precision>=0 && precision<length ) length = precision;
541 4 : break;
542 : case etSQLESCAPE:
543 : case etSQLESCAPE2:
544 : {
545 : int i, j, n, c, isnull;
546 136 : char *arg = va_arg(ap,char*);
547 136 : isnull = arg==0;
548 136 : if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
549 1123 : for(i=n=0; (c=arg[i])!=0; i++){
550 987 : if( c=='\'' ) n++;
551 : }
552 136 : n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0);
553 136 : if( n>etBUFSIZE ){
554 0 : bufpt = zExtra = sqliteMalloc( n );
555 0 : if( bufpt==0 ) return -1;
556 : }else{
557 136 : bufpt = buf;
558 : }
559 136 : j = 0;
560 136 : if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
561 1123 : for(i=0; (c=arg[i])!=0; i++){
562 987 : bufpt[j++] = c;
563 987 : if( c=='\'' ) bufpt[j++] = c;
564 : }
565 136 : if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
566 136 : bufpt[j] = 0;
567 136 : length = j;
568 136 : if( precision>=0 && precision<length ) length = precision;
569 : }
570 136 : break;
571 : case etTOKEN: {
572 299 : Token *pToken = va_arg(ap, Token*);
573 299 : (*func)(arg, pToken->z, pToken->n);
574 299 : length = width = 0;
575 299 : break;
576 : }
577 : case etSRCLIST: {
578 0 : SrcList *pSrc = va_arg(ap, SrcList*);
579 0 : int k = va_arg(ap, int);
580 0 : struct SrcList_item *pItem = &pSrc->a[k];
581 : assert( k>=0 && k<pSrc->nSrc );
582 0 : if( pItem->zDatabase && pItem->zDatabase[0] ){
583 0 : (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase));
584 0 : (*func)(arg, ".", 1);
585 : }
586 0 : (*func)(arg, pItem->zName, strlen(pItem->zName));
587 0 : length = width = 0;
588 0 : break;
589 : }
590 : case etERROR:
591 0 : buf[0] = '%';
592 0 : buf[1] = c;
593 0 : errorflag = 0;
594 0 : idx = 1+(c!=0);
595 0 : (*func)(arg,"%",idx);
596 0 : count += idx;
597 0 : 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 608 : if( !flag_leftjustify ){
606 : register int nspace;
607 608 : nspace = width-length;
608 608 : if( nspace>0 ){
609 0 : count += nspace;
610 0 : while( nspace>=etSPACESIZE ){
611 0 : (*func)(arg,spaces,etSPACESIZE);
612 0 : nspace -= etSPACESIZE;
613 : }
614 0 : if( nspace>0 ) (*func)(arg,spaces,nspace);
615 : }
616 : }
617 608 : if( length>0 ){
618 309 : (*func)(arg,bufpt,length);
619 309 : count += length;
620 : }
621 608 : if( flag_leftjustify ){
622 : register int nspace;
623 0 : nspace = width-length;
624 0 : if( nspace>0 ){
625 0 : count += nspace;
626 0 : while( nspace>=etSPACESIZE ){
627 0 : (*func)(arg,spaces,etSPACESIZE);
628 0 : nspace -= etSPACESIZE;
629 : }
630 0 : if( nspace>0 ) (*func)(arg,spaces,nspace);
631 : }
632 : }
633 608 : if( zExtra ){
634 0 : sqliteFree(zExtra);
635 : }
636 : }/* End for loop over the format string */
637 608 : 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 : */
659 1772 : static void mout(void *arg, const char *zNewText, int nNewChar){
660 1772 : struct sgMprintf *pM = (struct sgMprintf*)arg;
661 1772 : pM->nTotal += nNewChar;
662 1772 : if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
663 0 : if( pM->xRealloc==0 ){
664 0 : nNewChar = pM->nAlloc - pM->nChar - 1;
665 : }else{
666 0 : pM->nAlloc = pM->nChar + nNewChar*2 + 1;
667 0 : if( pM->zText==pM->zBase ){
668 0 : pM->zText = pM->xRealloc(0, pM->nAlloc);
669 0 : if( pM->zText && pM->nChar ){
670 0 : memcpy(pM->zText, pM->zBase, pM->nChar);
671 : }
672 : }else{
673 0 : pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
674 : }
675 : }
676 : }
677 1772 : if( pM->zText ){
678 1772 : if( nNewChar>0 ){
679 1164 : memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
680 1164 : pM->nChar += nNewChar;
681 : }
682 1772 : pM->zText[pM->nChar] = 0;
683 : }
684 1772 : }
685 :
686 : /*
687 : ** This routine is a wrapper around xprintf() that invokes mout() as
688 : ** the consumer.
689 : */
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 608 : ){
698 : struct sgMprintf sM;
699 608 : sM.zBase = sM.zText = zInitBuf;
700 608 : sM.nChar = sM.nTotal = 0;
701 608 : sM.nAlloc = nInitBuf;
702 608 : sM.xRealloc = xRealloc;
703 608 : vxprintf(mout, &sM, useInternal, zFormat, ap);
704 608 : if( xRealloc ){
705 439 : if( sM.zText==sM.zBase ){
706 439 : sM.zText = xRealloc(0, sM.nChar+1);
707 439 : memcpy(sM.zText, sM.zBase, sM.nChar+1);
708 0 : }else if( sM.nAlloc>sM.nChar+10 ){
709 0 : sM.zText = xRealloc(sM.zText, sM.nChar+1);
710 : }
711 : }
712 608 : return sM.zText;
713 : }
714 :
715 : /*
716 : ** Realloc that is a real function, not a macro.
717 : */
718 303 : static void *printf_realloc(void *old, int size){
719 303 : return sqliteRealloc(old,size);
720 : }
721 :
722 : /*
723 : ** Print into memory obtained from sqliteMalloc(). Use the internal
724 : ** %-conversion extensions.
725 : */
726 303 : char *sqliteVMPrintf(const char *zFormat, va_list ap){
727 : char zBase[1000];
728 303 : 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 : */
735 0 : char *sqliteMPrintf(const char *zFormat, ...){
736 : va_list ap;
737 : char *z;
738 : char zBase[1000];
739 0 : va_start(ap, zFormat);
740 0 : z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
741 0 : va_end(ap);
742 0 : 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 : */
749 136 : char *sqlite_mprintf(const char *zFormat, ...){
750 : va_list ap;
751 : char *z;
752 : char zBuf[200];
753 :
754 136 : va_start(ap,zFormat);
755 136 : z = base_vprintf((void*(*)(void*,int))realloc, 0,
756 : zBuf, sizeof(zBuf), zFormat, ap);
757 136 : va_end(ap);
758 136 : return z;
759 : }
760 :
761 : /* This is the varargs version of sqlite_mprintf.
762 : */
763 0 : char *sqlite_vmprintf(const char *zFormat, va_list ap){
764 : char zBuf[200];
765 0 : 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 : */
775 169 : char *sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
776 : char *z;
777 : va_list ap;
778 :
779 169 : va_start(ap,zFormat);
780 169 : z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
781 169 : va_end(ap);
782 169 : 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 : */
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 0 : ){
801 : va_list ap;
802 : int rc;
803 :
804 0 : va_start(ap, errmsg);
805 0 : rc = sqlite_exec_vprintf(db, sqlFormat, xCallback, pArg, errmsg, ap);
806 0 : va_end(ap);
807 0 : return rc;
808 : }
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 0 : ){
817 : char *zSql;
818 : int rc;
819 :
820 0 : zSql = sqlite_vmprintf(sqlFormat, ap);
821 0 : rc = sqlite_exec(db, zSql, xCallback, pArg, errmsg);
822 0 : free(zSql);
823 0 : return rc;
824 : }
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 0 : ){
834 : va_list ap;
835 : int rc;
836 :
837 0 : va_start(ap, errmsg);
838 0 : rc = sqlite_get_table_vprintf(db, sqlFormat, resultp, nrow, ncol, errmsg, ap);
839 0 : va_end(ap);
840 0 : return rc;
841 : }
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 0 : ){
851 : char *zSql;
852 : int rc;
853 :
854 0 : zSql = sqlite_vmprintf(sqlFormat, ap);
855 0 : rc = sqlite_get_table(db, zSql, resultp, nrow, ncolumn, errmsg);
856 0 : free(zSql);
857 0 : return rc;
858 : }
|