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