forgotten commit. disabled until egl is adapted.
[AROS-Contrib.git] / sqlite3 / printf.c
blob0757e34772fa0dac6619bd701e55974307645b7b
1 /* vi:set ts=4 sts=4 sw=4: */
2 /*
3 * 2005 July 14, Markku Sukanen
4 * - modifying for AROS
5 * */
6 /**
7 * @file printf.c
8 *
9 * The "printf" code that follows dates from the 1980's. It is in the public
10 * domain. The original comments are included here for completeness. They are
11 * very out-of-date but might be useful as an historical reference. Most of
12 * the "enhancements" have been backed out so that the functionality is now the
13 * same as standard printf().
14 * */
16 ** The following modules is an enhanced replacement for the "printf" subroutines
17 ** found in the standard C library. The following enhancements are
18 ** supported:
20 ** + Additional functions. The standard set of "printf" functions
21 ** includes printf, fprintf, sprintf, vprintf, vfprintf, and
22 ** vsprintf. This module adds the following:
24 ** * snprintf -- Works like sprintf, but has an extra argument
25 ** which is the size of the buffer written to.
27 ** * mprintf -- Similar to sprintf. Writes output to memory
28 ** obtained from malloc.
30 ** * xprintf -- Calls a function to dispose of output.
32 ** * nprintf -- No output, but returns the number of characters
33 ** that would have been output by printf.
35 ** * A v- version (ex: vsnprintf) of every function is also
36 ** supplied.
38 ** + A few extensions to the formatting notation are supported:
40 ** * The "=" flag (similar to "-") causes the output to be
41 ** be centered in the appropriately sized field.
43 ** * The %b field outputs an integer in binary notation.
45 ** * The %c field now accepts a precision. The character output
46 ** is repeated by the number of times the precision specifies.
48 ** * The %' field works like %c, but takes as its character the
49 ** next character of the format string, instead of the next
50 ** argument. For example, printf("%.78'-") prints 78 minus
51 ** signs, the same as printf("%.78c",'-').
53 ** + When compiled using GCC on a SPARC, this version of printf is
54 ** faster than the library printf for SUN OS 4.1.
56 ** + All functions are fully reentrant.
59 #include "sqliteInt.h"
62 * Conversion types fall into various categories as defined by the following
63 * enumeration.
64 * */
65 #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
66 #define etFLOAT 2 /* Floating point. %f */
67 #define etEXP 3 /* Exponentional notation. %e and %E */
68 #define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */
69 #define etSIZE 5 /* Return number of characters processed so far. %n */
70 #define etSTRING 6 /* Strings. %s */
71 #define etDYNSTRING 7 /* Dynamically allocated strings. %z */
72 #define etPERCENT 8 /* Percent symbol. %% */
73 #define etCHARX 9 /* Characters. %c */
74 #define etERROR 10 /* Used to indicate no such conversion type */
75 /* The rest are extensions, not normally found in printf() */
76 #define etCHARLIT 11 /* Literal characters. %' */
77 #define etSQLESCAPE 12 /* Strings with '\'' doubled. %q */
78 #define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
79 NULL pointers replaced by SQL NULL. %Q */
80 #define etTOKEN 14 /* a pointer to a Token structure */
81 #define etSRCLIST 15 /* a pointer to a SrcList */
82 #define etPOINTER 16 /* The %p conversion */
86 * An "etByte" is an 8-bit unsigned value.
87 * */
88 typedef unsigned char etByte;
91 * Each builtin conversion character (ex: the 'd' in "%d") is described by an
92 * instance of the following structure.
93 * */
94 typedef struct et_info { /* Information about each format field */
95 char fmttype; /* The format field code letter */
96 etByte base; /* The base for radix conversion */
97 etByte flags; /* One or more of FLAG_ constants below */
98 etByte type; /* Conversion paradigm */
99 etByte charset; /* Offset into aDigits[] of the digits string */
100 etByte prefix; /* Offset into aPrefix[] of the prefix string */
101 } et_info;
104 * Allowed values for et_info.flags
105 * */
106 #define FLAG_SIGNED 1 /* True if the value to convert is signed */
107 #define FLAG_INTERN 2 /* True if for internal use only */
108 #define FLAG_STRING 4 /* Allow infinity precision */
112 * The following table is searched linearly, so it is good to put the most
113 * frequently used conversion types first.
114 * */
115 static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
116 static const char aPrefix[] = "-x0\000X0";
117 static const et_info fmtinfo[] = {
118 { 'd', 10, 1, etRADIX, 0, 0 },
119 { 's', 0, 4, etSTRING, 0, 0 },
120 { 'z', 0, 6, etDYNSTRING, 0, 0 },
121 { 'q', 0, 4, etSQLESCAPE, 0, 0 },
122 { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
123 { 'c', 0, 0, etCHARX, 0, 0 },
124 { 'o', 8, 0, etRADIX, 0, 2 },
125 { 'u', 10, 0, etRADIX, 0, 0 },
126 { 'x', 16, 0, etRADIX, 16, 1 },
127 { 'X', 16, 0, etRADIX, 0, 4 },
128 { 'f', 0, 1, etFLOAT, 0, 0 },
129 { 'e', 0, 1, etEXP, 30, 0 },
130 { 'E', 0, 1, etEXP, 14, 0 },
131 { 'g', 0, 1, etGENERIC, 30, 0 },
132 { 'G', 0, 1, etGENERIC, 14, 0 },
133 { 'i', 10, 1, etRADIX, 0, 0 },
134 { 'n', 0, 0, etSIZE, 0, 0 },
135 { '%', 0, 0, etPERCENT, 0, 0 },
136 { 'p', 16, 0, etPOINTER, 0, 1 },
137 { 'T', 0, 2, etTOKEN, 0, 0 },
138 { 'S', 0, 2, etSRCLIST, 0, 0 },
140 #define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
144 * If NOFLOATINGPOINT is defined, then none of the floating point conversions
145 * will work.
146 * */
147 #ifndef etNOFLOATINGPOINT
149 * "*val" is a double such that 0.1 <= *val < 10.0
150 * Return the ascii code for the leading digit of *val, then multiply "*val" by
151 * 10.0 to renormalize.
152 * Example:
153 * input: *val = 3.14159
154 * output: *val = 1.4159 function return = '3'
156 * The counter *cnt is incremented each time. After counter exceeds 16 (the
157 * number of significant digits in a 64-bit float) '0' is always returned.
158 * */
159 static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt)
161 int digit;
162 LONGDOUBLE_TYPE d;
163 if( (*cnt)++ >= 16 ) return '0';
164 digit = (int)*val;
165 d = digit;
166 digit += '0';
167 *val = (*val - d)*10.0;
168 return digit;
170 #endif
172 #define etBUFSIZE 1000 /* Size of the output buffer */
175 * The root program. All variations call this core.
177 * INPUTS:
178 * func This is a pointer to a function taking three arguments
179 * 1. A pointer to anything. Same as the "arg" parameter.
180 * 2. A pointer to the list of characters to be output (Note, this
181 * list is NOT null terminated.)
182 * 3. An integer number of characters to be output. (Note: This
183 * number might be zero.)
185 * arg This is the pointer to anything which will be passed as the first
186 * argument to "func". Use it for whatever you like.
188 * fmt This is the format string, as in the usual print.
190 * ap This is a pointer to a list of arguments. Same as in vfprint.
192 * OUTPUTS:
193 * The return value is the total number of characters sent to the
194 * function "func". Returns -1 on a error.
196 * Note that the order in which automatic variables are declared below seems to
197 * make a big difference in determining how fast this beast will run.
198 * */
199 static int vxprintf(
200 void (*func)(void*,const char*,int), /* Consumer of text */
201 void *arg, /* First argument to the consumer */
202 int useExtended, /* Allow extended %-conversions */
203 const char *fmt, /* Format string */
204 va_list ap /* arguments */
207 int c; /* Next character in the format string */
208 char *bufpt; /* Pointer to the conversion buffer */
209 int precision; /* Precision of the current field */
210 int length; /* Length of the field */
211 int idx; /* A general purpose loop counter */
212 int count; /* Total number of characters output */
213 int width; /* Width of the current field */
214 etByte flag_leftjustify; /* True if "-" flag is present */
215 etByte flag_plussign; /* True if "+" flag is present */
216 etByte flag_blanksign; /* True if " " flag is present */
217 etByte flag_alternateform; /* True if "#" flag is present */
218 etByte flag_zeropad; /* True if field width constant starts with 0 */
219 etByte flag_long; /* True if "l" flag is present */
220 etByte flag_longlong; /* True if the "ll" flag is present */
221 UINT64_TYPE longvalue; /* Value for integer types */
222 LONGDOUBLE_TYPE realvalue; /* Value for real types */
223 const et_info *infop; /* Pointer to the appropriate info structure */
224 char buf[etBUFSIZE]; /* Conversion buffer */
225 char prefix; /* Prefix character.
226 "+" or "-" or " " or '\0'. */
227 etByte errorflag = 0; /* True if an error is encountered */
228 etByte xtype; /* Conversion paradigm */
229 char *zExtra; /* Extra memory used for etTCLESCAPE
230 conversions */
231 static const char spaces[] =
232 " ";
233 #define etSPACESIZE (sizeof(spaces)-1)
234 #ifndef etNOFLOATINGPOINT
235 int exp; /* exponent of real numbers */
236 double rounder; /* Used for rounding floating point values */
237 etByte flag_dp; /* True if decimal point should be shown */
238 etByte flag_rtz; /* True if trailing zeros should be removed */
239 etByte flag_exp; /* True to force display of the exponent */
240 int nsd; /* Number of significant digits returned */
241 #endif
243 func(arg,"",0);
244 count = length = 0;
245 bufpt = 0;
246 for(; (c=(*fmt))!=0; ++fmt)
248 if( c!='%' )
250 int amt;
251 bufpt = (char *)fmt;
252 amt = 1;
253 while( (c=(*++fmt))!='%' && c!=0 ) amt++;
254 (*func)(arg,bufpt,amt);
255 count += amt;
256 if( c==0 ) break;
258 if( (c=(*++fmt))==0 )
260 errorflag = 1;
261 (*func)(arg,"%",1);
262 count++;
263 break;
265 /* Find out what flags are present */
266 flag_leftjustify = flag_plussign = flag_blanksign =
267 flag_alternateform = flag_zeropad = 0;
268 do {
269 switch( c )
271 case '-': flag_leftjustify = 1; c = 0; break;
272 case '+': flag_plussign = 1; c = 0; break;
273 case ' ': flag_blanksign = 1; c = 0; break;
274 case '#': flag_alternateform = 1; c = 0; break;
275 case '0': flag_zeropad = 1; c = 0; break;
276 default: break;
278 }while( !c && (c=(*++fmt))!=0 );
280 /* Get the field width */
281 width = 0;
282 if( c=='*' )
284 width = va_arg(ap,int);
285 if( width<0 )
287 flag_leftjustify = 1;
288 width = -width;
290 c = *++fmt;
292 else
294 while( c>='0' && c<='9' )
296 width = width*10 + c - '0';
297 c = *++fmt;
300 if( width > etBUFSIZE-10 )
301 width = etBUFSIZE-10;
303 /* Get the precision */
304 if( c=='.' )
306 precision = 0;
307 c = *++fmt;
308 if( c=='*' )
310 precision = va_arg(ap,int);
311 if( precision<0 ) precision = -precision;
312 c = *++fmt;
314 else
316 while( c>='0' && c<='9' )
318 precision = precision*10 + c - '0';
319 c = *++fmt;
322 } else precision = -1;
324 /* Get the conversion type modifier */
325 if( c=='l' )
327 flag_long = 1;
328 c = *++fmt;
329 if( c=='l' )
331 flag_longlong = 1;
332 c = *++fmt;
333 } else flag_longlong = 0;
334 } else flag_long = flag_longlong = 0;
336 /* Fetch the info entry for the field */
337 infop = 0;
338 xtype = etERROR;
339 for(idx=0; idx<etNINFO; idx++)
341 if( c==fmtinfo[idx].fmttype )
343 infop = &fmtinfo[idx];
344 if( useExtended || (infop->flags & FLAG_INTERN)==0 )
345 xtype = infop->type;
346 break;
349 zExtra = 0;
352 * Limit the precision to prevent overflowing buf[] during
353 * conversion.
354 * */
355 if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 )
356 precision = etBUFSIZE-40;
359 * At this point, variables are initialized as follows:
361 * flag_alternateform TRUE if a '#' is present.
362 * flag_plussign TRUE if a '+' is present.
363 * flag_leftjustify TRUE if a '-' is present or if the
364 * field width was negative.
365 * flag_zeropad TRUE if the width began with 0.
366 * flag_long TRUE if the letter 'l' (ell) prefixed
367 * the conversion character.
368 * flag_longlong TRUE if the letter 'll' (ell ell)
369 * prefixed the conversion character.
370 * flag_blanksign TRUE if a ' ' is present.
371 * width The specified field width. This is
372 * always non-negative. Zero is the
373 * default.
374 * precision The specified precision. The default
375 * is -1.
376 * xtype The class of the conversion.
377 * infop Pointer to the appropriate info struct.
378 * */
379 switch( xtype )
381 case etPOINTER:
382 flag_longlong = sizeof(char*)==sizeof(i64);
383 flag_long = sizeof(char*)==sizeof(long int);
384 /* Fall through into the next case */
385 case etRADIX:
386 if( infop->flags & FLAG_SIGNED )
388 i64 v;
389 if( flag_longlong ) v = va_arg(ap,i64);
390 else if( flag_long ) v = va_arg(ap,long int);
391 else v = va_arg(ap,int);
392 if( v<0 )
394 longvalue = -v;
395 prefix = '-';
397 else
399 longvalue = v;
400 if( flag_plussign ) prefix = '+';
401 else if( flag_blanksign ) prefix = ' ';
402 else prefix = 0;
405 else
407 if( flag_longlong ) longvalue = va_arg(ap,u64);
408 else if( flag_long ) longvalue
409 = va_arg(ap,unsigned long int);
410 else longvalue = va_arg(ap,unsigned int);
411 prefix = 0;
413 if( longvalue==0 ) flag_alternateform = 0;
414 if( flag_zeropad && precision<width-(prefix!=0) )
415 precision = width-(prefix!=0);
416 bufpt = &buf[etBUFSIZE-1];
418 register const char *cset; /* Use registers for speed */
419 register int base;
420 cset = &aDigits[infop->charset];
421 base = infop->base;
422 do { /* Convert to ascii */
423 *(--bufpt) = cset[longvalue%base];
424 longvalue = longvalue/base;
425 }while( longvalue>0 );
427 length = &buf[etBUFSIZE-1]-bufpt;
428 for(idx=precision-length; idx>0; idx--)
429 *(--bufpt) = '0'; /* Zero pad */
430 if( prefix ) *(--bufpt) = prefix; /* Add sign */
431 if( flag_alternateform && infop->prefix )
432 { /* Add "0" or "0x" */
433 const char *pre;
434 char x;
435 pre = &aPrefix[infop->prefix];
436 if( *bufpt!=pre[0] )
437 for(; (x=(*pre))!=0; pre++)
438 *(--bufpt) = x;
440 length = &buf[etBUFSIZE-1]-bufpt;
441 break;
443 case etFLOAT:
444 case etEXP:
445 case etGENERIC:
446 realvalue = va_arg(ap,double);
447 #ifndef etNOFLOATINGPOINT
448 if( precision<0 ) precision = 6; /* Set default precision */
449 if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
450 if( realvalue<0.0 )
452 realvalue = -realvalue;
453 prefix = '-';
455 else
457 if( flag_plussign ) prefix = '+';
458 else if( flag_blanksign ) prefix = ' ';
459 else prefix = 0;
461 if( infop->type==etGENERIC && precision>0 ) precision--;
462 rounder = 0.0;
463 #if 0
465 * Rounding works like BSD when the constant 0.4999 is used.
466 * Wierd!
467 * */
468 for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
469 #else
470 /* It makes more sense to use 0.5 */
471 for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
472 #endif
473 if( infop->type==etFLOAT ) realvalue += rounder;
474 /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
475 exp = 0;
476 if( realvalue>0.0 )
478 while( realvalue>=1e8 && exp<=350 )
479 { realvalue *= 1e-8; exp+=8; }
480 while( realvalue>=10.0 && exp<=350 )
481 { realvalue *= 0.1; exp++; }
482 while( realvalue<1e-8 && exp>=-350 )
483 { realvalue *= 1e8; exp-=8; }
484 while( realvalue<1.0 && exp>=-350 )
485 { realvalue *= 10.0; exp--; }
486 if( exp>350 || exp<-350 )
488 bufpt = "NaN";
489 length = 3;
490 break;
493 bufpt = buf;
495 * If the field type is etGENERIC, then convert to either etEXP
496 * or etFLOAT, as appropriate.
497 * */
498 flag_exp = xtype==etEXP;
499 if( xtype!=etFLOAT )
501 realvalue += rounder;
502 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
504 if( xtype==etGENERIC )
506 flag_rtz = !flag_alternateform;
507 if( exp<-4 || exp>precision )
508 xtype = etEXP;
509 else {
510 precision = precision - exp;
511 xtype = etFLOAT;
513 } else flag_rtz = 0;
516 * The "exp+precision" test causes output to be of type etEXP
517 * if the precision is too large to fit in buf[].
518 * */
519 nsd = 0;
520 if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 )
522 flag_dp = (precision>0 || flag_alternateform);
523 if( prefix ) *(bufpt++) = prefix; /* Sign */
524 if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */
525 else for(; exp>=0; exp--)
526 *(bufpt++) = et_getdigit(&realvalue,&nsd);
527 if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */
528 for(exp++; exp<0 && precision>0; precision--, exp++)
529 *(bufpt++) = '0';
530 while( (precision--)>0 )
531 *(bufpt++) = et_getdigit(&realvalue,&nsd);
532 *(bufpt--) = 0; /* Null terminate */
533 if( flag_rtz && flag_dp )
534 { /* Remove trailing zeros and "." */
535 while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
536 if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
538 bufpt++; /* point to next free slot */
540 else
542 /* etEXP or etGENERIC */
543 flag_dp = (precision>0 || flag_alternateform);
544 if( prefix ) *(bufpt++) = prefix; /* Sign */
545 *(bufpt++) = et_getdigit(&realvalue,&nsd);/* First digit */
546 if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */
547 while( (precision--)>0 )
548 *(bufpt++) = et_getdigit(&realvalue,&nsd);
549 bufpt--; /* point to last digit */
550 if( flag_rtz && flag_dp )
551 { /* Remove tail zeros */
552 while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
553 if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
555 bufpt++; /* point to next free slot */
556 if( exp || flag_exp )
558 *(bufpt++) = aDigits[infop->charset];
559 /* sign of exp */
560 if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; }
561 else { *(bufpt++) = '+'; }
562 if( exp>=100 )
564 *(bufpt++) = (exp/100)+'0'; /* 100's digit */
565 exp %= 100;
567 *(bufpt++) = exp/10+'0'; /* 10's digit */
568 *(bufpt++) = exp%10+'0'; /* 1's digit */
572 * The converted number is in buf[] and zero terminated.
573 * Output it. Note that the number is in the usual order, not
574 * reversed as with integer conversions.
575 * */
576 length = bufpt-buf;
577 bufpt = buf;
580 * Special case: Add leading zeros if the flag_zeropad flag is
581 * set and we are not left justified.
582 * */
583 if( flag_zeropad && !flag_leftjustify && length < width)
585 int i;
586 int nPad = width - length;
587 for(i=width; i>=nPad; i--)
588 bufpt[i] = bufpt[i-nPad];
589 i = prefix!=0;
590 while( nPad-- ) bufpt[i++] = '0';
591 length = width;
593 #endif
594 break;
596 case etSIZE:
597 *(va_arg(ap,int*)) = count;
598 length = width = 0;
599 break;
601 case etPERCENT:
602 buf[0] = '%';
603 bufpt = buf;
604 length = 1;
605 break;
607 case etCHARLIT:
608 case etCHARX:
609 c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
610 if( precision>=0 )
612 for(idx=1; idx<precision; idx++) buf[idx] = c;
613 length = precision;
614 } else length = 1;
615 bufpt = buf;
616 break;
618 case etSTRING:
619 case etDYNSTRING:
620 bufpt = va_arg(ap,char*);
621 if( bufpt==0 )
622 bufpt = "";
623 else if( xtype==etDYNSTRING )
624 zExtra = bufpt;
625 length = strlen(bufpt);
626 if( precision>=0 && precision<length ) length = precision;
627 break;
629 case etSQLESCAPE:
630 case etSQLESCAPE2:
632 int i, j, n, c, isnull;
633 int needQuote;
634 char *arg = va_arg(ap,char*);
635 isnull = arg==0;
636 if( isnull )
637 arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
638 for(i=n=0; (c=arg[i])!=0; i++)
639 if( c=='\'' )
640 n++;
641 needQuote = !isnull && xtype==etSQLESCAPE2;
642 n += i + 1 + needQuote*2;
643 if( n>etBUFSIZE )
645 bufpt = zExtra = sqliteMalloc( n );
646 if( bufpt==0 ) return -1;
647 } else bufpt = buf;
648 j = 0;
649 if( needQuote ) bufpt[j++] = '\'';
650 for(i=0; (c=arg[i])!=0; i++)
652 bufpt[j++] = c;
653 if( c=='\'' ) bufpt[j++] = c;
655 if( needQuote ) bufpt[j++] = '\'';
656 bufpt[j] = 0;
657 length = j;
658 if( precision>=0 && precision<length ) length = precision;
660 break;
662 case etTOKEN:
664 Token *pToken = va_arg(ap, Token*);
665 if( pToken && pToken->z )
666 (*func)(arg, pToken->z, pToken->n);
667 length = width = 0;
669 break;
671 case etSRCLIST:
673 SrcList *pSrc = va_arg(ap, SrcList*);
674 int k = va_arg(ap, int);
675 struct SrcList_item *pItem = &pSrc->a[k];
676 assert( k>=0 && k<pSrc->nSrc );
677 if( pItem->zDatabase && pItem->zDatabase[0] )
679 (*func)(arg, pItem->zDatabase,
680 strlen(pItem->zDatabase));
681 (*func)(arg, ".", 1);
683 (*func)(arg, pItem->zName, strlen(pItem->zName));
684 length = width = 0;
686 break;
688 case etERROR:
689 buf[0] = '%';
690 buf[1] = c;
691 errorflag = 0;
692 idx = 1+(c!=0);
693 (*func)(arg,"%",idx);
694 count += idx;
695 if( c==0 ) fmt--;
696 break;
697 }/* End switch over the format type */
700 * The text of the conversion is pointed to by "bufpt" and is "length"
701 * characters long. The field width is "width". Do the output.
702 * */
703 if( !flag_leftjustify )
705 register int nspace;
706 nspace = width-length;
707 if( nspace>0 )
709 count += nspace;
710 while( nspace>=etSPACESIZE )
712 (*func)(arg,spaces,etSPACESIZE);
713 nspace -= etSPACESIZE;
715 if( nspace>0 ) (*func)(arg,spaces,nspace);
718 if( length>0 )
720 (*func)(arg,bufpt,length);
721 count += length;
723 if( flag_leftjustify )
725 register int nspace;
726 nspace = width-length;
727 if( nspace>0 )
729 count += nspace;
730 while( nspace>=etSPACESIZE )
732 (*func)(arg,spaces,etSPACESIZE);
733 nspace -= etSPACESIZE;
735 if( nspace>0 ) (*func)(arg,spaces,nspace);
738 if( zExtra )
739 sqliteFree(zExtra);
740 }/* End for loop over the format string */
741 return errorflag ? -1 : count;
746 * This structure is used to store state information about the write to memory
747 * that is currently in progress.
748 * */
749 struct sgMprintf {
750 char *zBase; /* A base allocation */
751 char *zText; /* The string collected so far */
752 int nChar; /* Length of the string so far */
753 int nTotal; /* Output size if unconstrained */
754 int nAlloc; /* Amount of space allocated in zText */
755 void *(*xRealloc)(void*,int); /* Function used to realloc memory */
760 * This function implements the callback from vxprintf.
762 * This routine add nNewChar characters of text in zNewText to the sgMprintf
763 * structure pointed to by "arg".
764 * */
765 static void mout(void *arg, const char *zNewText, int nNewChar)
767 struct sgMprintf *pM = (struct sgMprintf*)arg;
768 pM->nTotal += nNewChar;
769 if( pM->nChar + nNewChar + 1 > pM->nAlloc )
771 if( pM->xRealloc==0 )
772 nNewChar = pM->nAlloc - pM->nChar - 1;
773 else
775 pM->nAlloc = pM->nChar + nNewChar*2 + 1;
776 if( pM->zText==pM->zBase )
778 pM->zText = pM->xRealloc(0, pM->nAlloc);
779 if( pM->zText && pM->nChar )
780 memcpy(pM->zText, pM->zBase, pM->nChar);
782 else pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
785 if( pM->zText )
787 if( nNewChar>0 )
789 memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
790 pM->nChar += nNewChar;
792 pM->zText[pM->nChar] = 0;
798 * This routine is a wrapper around xprintf() that invokes mout() as the
799 * consumer.
800 * */
801 static char *base_vprintf(
802 void *(*xRealloc)(void*,int), /* Routine to realloc memory. May be
803 NULL */
804 int useInternal, /* Use internal %-conversions if true */
805 char *zInitBuf, /* Initially write here, before
806 mallocing */
807 int nInitBuf, /* Size of zInitBuf[] */
808 const char *zFormat, /* format string */
809 va_list ap /* arguments */
812 struct sgMprintf sM;
813 sM.zBase = sM.zText = zInitBuf;
814 sM.nChar = sM.nTotal = 0;
815 sM.nAlloc = nInitBuf;
816 sM.xRealloc = xRealloc;
817 vxprintf(mout, &sM, useInternal, zFormat, ap);
818 if( xRealloc )
820 if( sM.zText==sM.zBase )
822 sM.zText = xRealloc(0, sM.nChar+1);
823 if( sM.zText )
824 memcpy(sM.zText, sM.zBase, sM.nChar+1);
826 else if( sM.nAlloc>sM.nChar+10 )
827 sM.zText = xRealloc(sM.zText, sM.nChar+1);
829 return sM.zText;
834 * Realloc that is a real function, not a macro.
835 * */
836 static void *printf_realloc(void *old, int size)
838 return sqliteRealloc(old,size);
843 * Print into memory obtained from sqliteMalloc(). Use the internal
844 * %-conversion extensions.
845 * */
846 char *sqlite3VMPrintf(const char *zFormat, va_list ap)
848 char zBase[1000];
849 return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
854 * Print into memory obtained from sqliteMalloc(). Use the internal
855 * %-conversion extensions.
856 * */
857 char *sqlite3MPrintf(const char *zFormat, ...)
859 va_list ap;
860 char *z;
861 char zBase[1000];
862 va_start(ap, zFormat);
863 z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
864 va_end(ap);
865 return z;
870 * Print into memory obtained from malloc(). Do not use the internal
871 * %-conversion extensions. This routine is for use by external users.
872 * */
873 char *sqlite3_mprintf(const char *zFormat, ...)
875 va_list ap;
876 char *z;
877 char zBuf[200];
879 va_start(ap,zFormat);
880 z = base_vprintf((void*(*)(void*,int))realloc, 0, zBuf, sizeof(zBuf),
881 zFormat, ap);
882 va_end(ap);
883 return z;
888 * This is the varargs version of sqlite3_mprintf.
889 * */
890 char *sqlite3_vmprintf(const char *zFormat, va_list ap)
892 char zBuf[200];
893 return base_vprintf((void*(*)(void*,int))realloc, 0,
894 zBuf, sizeof(zBuf), zFormat, ap);
899 * sqlite3_snprintf() works like snprintf() except that it ignores the current
900 * locale settings. This is important for SQLite because we are not able to use
901 * a "," as the decimal point in place of "." as specified by some locales.
902 * */
903 char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...)
905 char *z;
906 va_list ap;
908 va_start(ap,zFormat);
909 z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
910 va_end(ap);
911 return z;
915 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
917 ** A version of printf() that understands %lld. Used for debugging.
918 ** The printf() built into some versions of windows does not understand %lld
919 ** and segfaults if you give it a long long int.
921 void sqlite3DebugPrintf(const char *zFormat, ...){
922 extern int getpid(void);
923 va_list ap;
924 char zBuf[500];
925 va_start(ap, zFormat);
926 base_vprintf(0, 0, zBuf, sizeof(zBuf), zFormat, ap);
927 va_end(ap);
928 fprintf(stdout,"%d: %s", getpid(), zBuf);
929 fflush(stdout);
931 #endif