xref: /sqlite-3.40.0/src/printf.c (revision c023e03e)
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