1 /* vi:set ts=4 sts=4 sw=4: */
3 * 2005 July 14, Markku Sukanen
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().
16 ** The following modules is an enhanced replacement for the "printf" subroutines
17 ** found in the standard C library. The following enhancements are
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
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
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.
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.
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 */
104 * Allowed values for et_info.flags
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.
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
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.
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.
159 static int et_getdigit(LONGDOUBLE_TYPE
*val
, int *cnt
)
163 if( (*cnt
)++ >= 16 ) return '0';
167 *val
= (*val
- d
)*10.0;
172 #define etBUFSIZE 1000 /* Size of the output buffer */
175 * The root program. All variations call this core.
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.
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.
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
231 static const char spaces
[] =
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 */
246 for(; (c
=(*fmt
))!=0; ++fmt
)
253 while( (c
=(*++fmt
))!='%' && c
!=0 ) amt
++;
254 (*func
)(arg
,bufpt
,amt
);
258 if( (c
=(*++fmt
))==0 )
265 /* Find out what flags are present */
266 flag_leftjustify
= flag_plussign
= flag_blanksign
=
267 flag_alternateform
= flag_zeropad
= 0;
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;
278 }while( !c
&& (c
=(*++fmt
))!=0 );
280 /* Get the field width */
284 width
= va_arg(ap
,int);
287 flag_leftjustify
= 1;
294 while( c
>='0' && c
<='9' )
296 width
= width
*10 + c
- '0';
300 if( width
> etBUFSIZE
-10 )
301 width
= etBUFSIZE
-10;
303 /* Get the precision */
310 precision
= va_arg(ap
,int);
311 if( precision
<0 ) precision
= -precision
;
316 while( c
>='0' && c
<='9' )
318 precision
= precision
*10 + c
- '0';
322 } else precision
= -1;
324 /* Get the conversion type modifier */
333 } else flag_longlong
= 0;
334 } else flag_long
= flag_longlong
= 0;
336 /* Fetch the info entry for the field */
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 )
352 * Limit the precision to prevent overflowing buf[] during
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
374 * precision The specified precision. The default
376 * xtype The class of the conversion.
377 * infop Pointer to the appropriate info struct.
382 flag_longlong
= sizeof(char*)==sizeof(i64
);
383 flag_long
= sizeof(char*)==sizeof(long int);
384 /* Fall through into the next case */
386 if( infop
->flags
& FLAG_SIGNED
)
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);
400 if( flag_plussign
) prefix
= '+';
401 else if( flag_blanksign
) prefix
= ' ';
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);
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 */
420 cset
= &aDigits
[infop
->charset
];
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" */
435 pre
= &aPrefix
[infop
->prefix
];
437 for(; (x
=(*pre
))!=0; pre
++)
440 length
= &buf
[etBUFSIZE
-1]-bufpt
;
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;
452 realvalue
= -realvalue
;
457 if( flag_plussign
) prefix
= '+';
458 else if( flag_blanksign
) prefix
= ' ';
461 if( infop
->type
==etGENERIC
&& precision
>0 ) precision
--;
465 * Rounding works like BSD when the constant 0.4999 is used.
468 for(idx
=precision
, rounder
=0.4999; idx
>0; idx
--, rounder
*=0.1);
470 /* It makes more sense to use 0.5 */
471 for(idx
=precision
, rounder
=0.5; idx
>0; idx
--, rounder
*=0.1);
473 if( infop
->type
==etFLOAT
) realvalue
+= rounder
;
474 /* Normalize realvalue to within 10.0 > realvalue >= 1.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 )
495 * If the field type is etGENERIC, then convert to either etEXP
496 * or etFLOAT, as appropriate.
498 flag_exp
= xtype
==etEXP
;
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
)
510 precision
= precision
- exp
;
516 * The "exp+precision" test causes output to be of type etEXP
517 * if the precision is too large to fit in buf[].
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
++)
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 */
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
];
560 if( exp
<0 ){ *(bufpt
++) = '-'; exp
= -exp
; }
561 else { *(bufpt
++) = '+'; }
564 *(bufpt
++) = (exp
/100)+'0'; /* 100's digit */
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.
580 * Special case: Add leading zeros if the flag_zeropad flag is
581 * set and we are not left justified.
583 if( flag_zeropad
&& !flag_leftjustify
&& length
< width
)
586 int nPad
= width
- length
;
587 for(i
=width
; i
>=nPad
; i
--)
588 bufpt
[i
] = bufpt
[i
-nPad
];
590 while( nPad
-- ) bufpt
[i
++] = '0';
597 *(va_arg(ap
,int*)) = count
;
609 c
= buf
[0] = (xtype
==etCHARX
? va_arg(ap
,int) : *++fmt
);
612 for(idx
=1; idx
<precision
; idx
++) buf
[idx
] = c
;
620 bufpt
= va_arg(ap
,char*);
623 else if( xtype
==etDYNSTRING
)
625 length
= strlen(bufpt
);
626 if( precision
>=0 && precision
<length
) length
= precision
;
632 int i
, j
, n
, c
, isnull
;
634 char *arg
= va_arg(ap
,char*);
637 arg
= (xtype
==etSQLESCAPE2
? "NULL" : "(NULL)");
638 for(i
=n
=0; (c
=arg
[i
])!=0; i
++)
641 needQuote
= !isnull
&& xtype
==etSQLESCAPE2
;
642 n
+= i
+ 1 + needQuote
*2;
645 bufpt
= zExtra
= sqliteMalloc( n
);
646 if( bufpt
==0 ) return -1;
649 if( needQuote
) bufpt
[j
++] = '\'';
650 for(i
=0; (c
=arg
[i
])!=0; i
++)
653 if( c
=='\'' ) bufpt
[j
++] = c
;
655 if( needQuote
) bufpt
[j
++] = '\'';
658 if( precision
>=0 && precision
<length
) length
= precision
;
664 Token
*pToken
= va_arg(ap
, Token
*);
665 if( pToken
&& pToken
->z
)
666 (*func
)(arg
, pToken
->z
, pToken
->n
);
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
));
693 (*func
)(arg
,"%",idx
);
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.
703 if( !flag_leftjustify
)
706 nspace
= width
-length
;
710 while( nspace
>=etSPACESIZE
)
712 (*func
)(arg
,spaces
,etSPACESIZE
);
713 nspace
-= etSPACESIZE
;
715 if( nspace
>0 ) (*func
)(arg
,spaces
,nspace
);
720 (*func
)(arg
,bufpt
,length
);
723 if( flag_leftjustify
)
726 nspace
= width
-length
;
730 while( nspace
>=etSPACESIZE
)
732 (*func
)(arg
,spaces
,etSPACESIZE
);
733 nspace
-= etSPACESIZE
;
735 if( nspace
>0 ) (*func
)(arg
,spaces
,nspace
);
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.
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".
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;
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
);
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
801 static char *base_vprintf(
802 void *(*xRealloc
)(void*,int), /* Routine to realloc memory. May be
804 int useInternal
, /* Use internal %-conversions if true */
805 char *zInitBuf
, /* Initially write here, before
807 int nInitBuf
, /* Size of zInitBuf[] */
808 const char *zFormat
, /* format string */
809 va_list ap
/* arguments */
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
);
820 if( sM
.zText
==sM
.zBase
)
822 sM
.zText
= xRealloc(0, sM
.nChar
+1);
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);
834 * Realloc that is a real function, not a macro.
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.
846 char *sqlite3VMPrintf(const char *zFormat
, va_list ap
)
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.
857 char *sqlite3MPrintf(const char *zFormat
, ...)
862 va_start(ap
, zFormat
);
863 z
= base_vprintf(printf_realloc
, 1, zBase
, sizeof(zBase
), zFormat
, ap
);
870 * Print into memory obtained from malloc(). Do not use the internal
871 * %-conversion extensions. This routine is for use by external users.
873 char *sqlite3_mprintf(const char *zFormat
, ...)
879 va_start(ap
,zFormat
);
880 z
= base_vprintf((void*(*)(void*,int))realloc
, 0, zBuf
, sizeof(zBuf
),
888 * This is the varargs version of sqlite3_mprintf.
890 char *sqlite3_vmprintf(const char *zFormat
, va_list ap
)
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.
903 char *sqlite3_snprintf(int n
, char *zBuf
, const char *zFormat
, ...)
908 va_start(ap
,zFormat
);
909 z
= base_vprintf(0, 0, zBuf
, n
, zFormat
, ap
);
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);
925 va_start(ap
, zFormat
);
926 base_vprintf(0, 0, zBuf
, sizeof(zBuf
), zFormat
, ap
);
928 fprintf(stdout
,"%d: %s", getpid(), zBuf
);