source: trunk/src/3rdparty/sqlite/printf.c@ 205

Last change on this file since 205 was 205, checked in by rudi, 14 years ago

Added SQLite 2.8.17 sources. This allows to build at least one of the sql drivers / plugins.

File size: 30.3 KB
Line 
1/*
2** The "printf" code that follows dates from the 1980's. It is in
3** the public domain. The original comments are included here for
4** completeness. They are very out-of-date but might be useful as
5** an historical reference. Most of the "enhancements" have been backed
6** out so that the functionality is now the same as standard printf().
7**
8**************************************************************************
9**
10** The following modules is an enhanced replacement for the "printf" subroutines
11** found in the standard C library. The following enhancements are
12** supported:
13**
14** + Additional functions. The standard set of "printf" functions
15** includes printf, fprintf, sprintf, vprintf, vfprintf, and
16** vsprintf. This module adds the following:
17**
18** * snprintf -- Works like sprintf, but has an extra argument
19** which is the size of the buffer written to.
20**
21** * mprintf -- Similar to sprintf. Writes output to memory
22** obtained from malloc.
23**
24** * xprintf -- Calls a function to dispose of output.
25**
26** * nprintf -- No output, but returns the number of characters
27** that would have been output by printf.
28**
29** * A v- version (ex: vsnprintf) of every function is also
30** supplied.
31**
32** + A few extensions to the formatting notation are supported:
33**
34** * The "=" flag (similar to "-") causes the output to be
35** be centered in the appropriately sized field.
36**
37** * The %b field outputs an integer in binary notation.
38**
39** * The %c field now accepts a precision. The character output
40** is repeated by the number of times the precision specifies.
41**
42** * The %' field works like %c, but takes as its character the
43** next character of the format string, instead of the next
44** argument. For example, printf("%.78'-") prints 78 minus
45** signs, the same as printf("%.78c",'-').
46**
47** + When compiled using GCC on a SPARC, this version of printf is
48** faster than the library printf for SUN OS 4.1.
49**
50** + All functions are fully reentrant.
51**
52*/
53#include "sqliteInt.h"
54
55/*
56** Conversion types fall into various categories as defined by the
57** following enumeration.
58*/
59#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
60#define etFLOAT 2 /* Floating point. %f */
61#define etEXP 3 /* Exponentional notation. %e and %E */
62#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */
63#define etSIZE 5 /* Return number of characters processed so far. %n */
64#define etSTRING 6 /* Strings. %s */
65#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
66#define etPERCENT 8 /* Percent symbol. %% */
67#define etCHARX 9 /* Characters. %c */
68#define etERROR 10 /* Used to indicate no such conversion type */
69/* The rest are extensions, not normally found in printf() */
70#define etCHARLIT 11 /* Literal characters. %' */
71#define etSQLESCAPE 12 /* Strings with '\'' doubled. %q */
72#define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
73 NULL pointers replaced by SQL NULL. %Q */
74#define etTOKEN 14 /* a pointer to a Token structure */
75#define etSRCLIST 15 /* a pointer to a SrcList */
76
77
78/*
79** An "etByte" is an 8-bit unsigned value.
80*/
81typedef unsigned char etByte;
82
83/*
84** Each builtin conversion character (ex: the 'd' in "%d") is described
85** by an instance of the following structure
86*/
87typedef struct et_info { /* Information about each format field */
88 char fmttype; /* The format field code letter */
89 etByte base; /* The base for radix conversion */
90 etByte flags; /* One or more of FLAG_ constants below */
91 etByte type; /* Conversion paradigm */
92 char *charset; /* The character set for conversion */
93 char *prefix; /* Prefix on non-zero values in alt format */
94} et_info;
95
96/*
97** Allowed values for et_info.flags
98*/
99#define FLAG_SIGNED 1 /* True if the value to convert is signed */
100#define FLAG_INTERN 2 /* True if for internal use only */
101
102
103/*
104** The following table is searched linearly, so it is good to put the
105** most frequently used conversion types first.
106*/
107static et_info fmtinfo[] = {
108 { 'd', 10, 1, etRADIX, "0123456789", 0 },
109 { 's', 0, 0, etSTRING, 0, 0 },
110 { 'z', 0, 2, etDYNSTRING, 0, 0 },
111 { 'q', 0, 0, etSQLESCAPE, 0, 0 },
112 { 'Q', 0, 0, etSQLESCAPE2, 0, 0 },
113 { 'c', 0, 0, etCHARX, 0, 0 },
114 { 'o', 8, 0, etRADIX, "01234567", "0" },
115 { 'u', 10, 0, etRADIX, "0123456789", 0 },
116 { 'x', 16, 0, etRADIX, "0123456789abcdef", "x0" },
117 { 'X', 16, 0, etRADIX, "0123456789ABCDEF", "X0" },
118 { 'f', 0, 1, etFLOAT, 0, 0 },
119 { 'e', 0, 1, etEXP, "e", 0 },
120 { 'E', 0, 1, etEXP, "E", 0 },
121 { 'g', 0, 1, etGENERIC, "e", 0 },
122 { 'G', 0, 1, etGENERIC, "E", 0 },
123 { 'i', 10, 1, etRADIX, "0123456789", 0 },
124 { 'n', 0, 0, etSIZE, 0, 0 },
125 { '%', 0, 0, etPERCENT, 0, 0 },
126 { 'p', 10, 0, etRADIX, "0123456789", 0 },
127 { 'T', 0, 2, etTOKEN, 0, 0 },
128 { 'S', 0, 2, etSRCLIST, 0, 0 },
129};
130#define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
131
132/*
133** If NOFLOATINGPOINT is defined, then none of the floating point
134** conversions will work.
135*/
136#ifndef etNOFLOATINGPOINT
137/*
138** "*val" is a double such that 0.1 <= *val < 10.0
139** Return the ascii code for the leading digit of *val, then
140** multiply "*val" by 10.0 to renormalize.
141**
142** Example:
143** input: *val = 3.14159
144** output: *val = 1.4159 function return = '3'
145**
146** The counter *cnt is incremented each time. After counter exceeds
147** 16 (the number of significant digits in a 64-bit float) '0' is
148** always returned.
149*/
150static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
151 int digit;
152 LONGDOUBLE_TYPE d;
153 if( (*cnt)++ >= 16 ) return '0';
154 digit = (int)*val;
155 d = digit;
156 digit += '0';
157 *val = (*val - d)*10.0;
158 return digit;
159}
160#endif
161
162#define etBUFSIZE 1000 /* Size of the output buffer */
163
164/*
165** The root program. All variations call this core.
166**
167** INPUTS:
168** func This is a pointer to a function taking three arguments
169** 1. A pointer to anything. Same as the "arg" parameter.
170** 2. A pointer to the list of characters to be output
171** (Note, this list is NOT null terminated.)
172** 3. An integer number of characters to be output.
173** (Note: This number might be zero.)
174**
175** arg This is the pointer to anything which will be passed as the
176** first argument to "func". Use it for whatever you like.
177**
178** fmt This is the format string, as in the usual print.
179**
180** ap This is a pointer to a list of arguments. Same as in
181** vfprint.
182**
183** OUTPUTS:
184** The return value is the total number of characters sent to
185** the function "func". Returns -1 on a error.
186**
187** Note that the order in which automatic variables are declared below
188** seems to make a big difference in determining how fast this beast
189** will run.
190*/
191static int vxprintf(
192 void (*func)(void*,const char*,int), /* Consumer of text */
193 void *arg, /* First argument to the consumer */
194 int useExtended, /* Allow extended %-conversions */
195 const char *fmt, /* Format string */
196 va_list ap /* arguments */
197){
198 int c; /* Next character in the format string */
199 char *bufpt; /* Pointer to the conversion buffer */
200 int precision; /* Precision of the current field */
201 int length; /* Length of the field */
202 int idx; /* A general purpose loop counter */
203 int count; /* Total number of characters output */
204 int width; /* Width of the current field */
205 etByte flag_leftjustify; /* True if "-" flag is present */
206 etByte flag_plussign; /* True if "+" flag is present */
207 etByte flag_blanksign; /* True if " " flag is present */
208 etByte flag_alternateform; /* True if "#" flag is present */
209 etByte flag_zeropad; /* True if field width constant starts with zero */
210 etByte flag_long; /* True if "l" flag is present */
211 unsigned long longvalue; /* Value for integer types */
212 LONGDOUBLE_TYPE realvalue; /* Value for real types */
213 et_info *infop; /* Pointer to the appropriate info structure */
214 char buf[etBUFSIZE]; /* Conversion buffer */
215 char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
216 etByte errorflag = 0; /* True if an error is encountered */
217 etByte xtype; /* Conversion paradigm */
218 char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
219 static char spaces[] = " ";
220#define etSPACESIZE (sizeof(spaces)-1)
221#ifndef etNOFLOATINGPOINT
222 int exp; /* exponent of real numbers */
223 double rounder; /* Used for rounding floating point values */
224 etByte flag_dp; /* True if decimal point should be shown */
225 etByte flag_rtz; /* True if trailing zeros should be removed */
226 etByte flag_exp; /* True to force display of the exponent */
227 int nsd; /* Number of significant digits returned */
228#endif
229
230 func(arg,"",0);
231 count = length = 0;
232 bufpt = 0;
233 for(; (c=(*fmt))!=0; ++fmt){
234 if( c!='%' ){
235 int amt;
236 bufpt = (char *)fmt;
237 amt = 1;
238 while( (c=(*++fmt))!='%' && c!=0 ) amt++;
239 (*func)(arg,bufpt,amt);
240 count += amt;
241 if( c==0 ) break;
242 }
243 if( (c=(*++fmt))==0 ){
244 errorflag = 1;
245 (*func)(arg,"%",1);
246 count++;
247 break;
248 }
249 /* Find out what flags are present */
250 flag_leftjustify = flag_plussign = flag_blanksign =
251 flag_alternateform = flag_zeropad = 0;
252 do{
253 switch( c ){
254 case '-': flag_leftjustify = 1; c = 0; break;
255 case '+': flag_plussign = 1; c = 0; break;
256 case ' ': flag_blanksign = 1; c = 0; break;
257 case '#': flag_alternateform = 1; c = 0; break;
258 case '0': flag_zeropad = 1; c = 0; break;
259 default: break;
260 }
261 }while( c==0 && (c=(*++fmt))!=0 );
262 /* Get the field width */
263 width = 0;
264 if( c=='*' ){
265 width = va_arg(ap,int);
266 if( width<0 ){
267 flag_leftjustify = 1;
268 width = -width;
269 }
270 c = *++fmt;
271 }else{
272 while( c>='0' && c<='9' ){
273 width = width*10 + c - '0';
274 c = *++fmt;
275 }
276 }
277 if( width > etBUFSIZE-10 ){
278 width = etBUFSIZE-10;
279 }
280 /* Get the precision */
281 if( c=='.' ){
282 precision = 0;
283 c = *++fmt;
284 if( c=='*' ){
285 precision = va_arg(ap,int);
286 if( precision<0 ) precision = -precision;
287 c = *++fmt;
288 }else{
289 while( c>='0' && c<='9' ){
290 precision = precision*10 + c - '0';
291 c = *++fmt;
292 }
293 }
294 /* Limit the precision to prevent overflowing buf[] during conversion */
295 if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40;
296 }else{
297 precision = -1;
298 }
299 /* Get the conversion type modifier */
300 if( c=='l' ){
301 flag_long = 1;
302 c = *++fmt;
303 }else{
304 flag_long = 0;
305 }
306 /* Fetch the info entry for the field */
307 infop = 0;
308 xtype = etERROR;
309 for(idx=0; idx<etNINFO; idx++){
310 if( c==fmtinfo[idx].fmttype ){
311 infop = &fmtinfo[idx];
312 if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
313 xtype = infop->type;
314 }
315 break;
316 }
317 }
318 zExtra = 0;
319
320 /*
321 ** At this point, variables are initialized as follows:
322 **
323 ** flag_alternateform TRUE if a '#' is present.
324 ** flag_plussign TRUE if a '+' is present.
325 ** flag_leftjustify TRUE if a '-' is present or if the
326 ** field width was negative.
327 ** flag_zeropad TRUE if the width began with 0.
328 ** flag_long TRUE if the letter 'l' (ell) prefixed
329 ** the conversion character.
330 ** flag_blanksign TRUE if a ' ' is present.
331 ** width The specified field width. This is
332 ** always non-negative. Zero is the default.
333 ** precision The specified precision. The default
334 ** is -1.
335 ** xtype The class of the conversion.
336 ** infop Pointer to the appropriate info struct.
337 */
338 switch( xtype ){
339 case etRADIX:
340 if( flag_long ) longvalue = va_arg(ap,long);
341 else longvalue = va_arg(ap,int);
342#if 1
343 /* For the format %#x, the value zero is printed "0" not "0x0".
344 ** I think this is stupid. */
345 if( longvalue==0 ) flag_alternateform = 0;
346#else
347 /* More sensible: turn off the prefix for octal (to prevent "00"),
348 ** but leave the prefix for hex. */
349 if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;
350#endif
351 if( infop->flags & FLAG_SIGNED ){
352 if( *(long*)&longvalue<0 ){
353 longvalue = -*(long*)&longvalue;
354 prefix = '-';
355 }else if( flag_plussign ) prefix = '+';
356 else if( flag_blanksign ) prefix = ' ';
357 else prefix = 0;
358 }else prefix = 0;
359 if( flag_zeropad && precision<width-(prefix!=0) ){
360 precision = width-(prefix!=0);
361 }
362 bufpt = &buf[etBUFSIZE-1];
363 {
364 register char *cset; /* Use registers for speed */
365 register int base;
366 cset = infop->charset;
367 base = infop->base;
368 do{ /* Convert to ascii */
369 *(--bufpt) = cset[longvalue%base];
370 longvalue = longvalue/base;
371 }while( longvalue>0 );
372 }
373 length = &buf[etBUFSIZE-1]-bufpt;
374 for(idx=precision-length; idx>0; idx--){
375 *(--bufpt) = '0'; /* Zero pad */
376 }
377 if( prefix ) *(--bufpt) = prefix; /* Add sign */
378 if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
379 char *pre, x;
380 pre = infop->prefix;
381 if( *bufpt!=pre[0] ){
382 for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
383 }
384 }
385 length = &buf[etBUFSIZE-1]-bufpt;
386 break;
387 case etFLOAT:
388 case etEXP:
389 case etGENERIC:
390 realvalue = va_arg(ap,double);
391#ifndef etNOFLOATINGPOINT
392 if( precision<0 ) precision = 6; /* Set default precision */
393 if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
394 if( realvalue<0.0 ){
395 realvalue = -realvalue;
396 prefix = '-';
397 }else{
398 if( flag_plussign ) prefix = '+';
399 else if( flag_blanksign ) prefix = ' ';
400 else prefix = 0;
401 }
402 if( infop->type==etGENERIC && precision>0 ) precision--;
403 rounder = 0.0;
404#if 0
405 /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
406 for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
407#else
408 /* It makes more sense to use 0.5 */
409 for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
410#endif
411 if( infop->type==etFLOAT ) realvalue += rounder;
412 /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
413 exp = 0;
414 if( realvalue>0.0 ){
415 while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
416 while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
417 while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
418 while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
419 if( exp>350 || exp<-350 ){
420 bufpt = "NaN";
421 length = 3;
422 break;
423 }
424 }
425 bufpt = buf;
426 /*
427 ** If the field type is etGENERIC, then convert to either etEXP
428 ** or etFLOAT, as appropriate.
429 */
430 flag_exp = xtype==etEXP;
431 if( xtype!=etFLOAT ){
432 realvalue += rounder;
433 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
434 }
435 if( xtype==etGENERIC ){
436 flag_rtz = !flag_alternateform;
437 if( exp<-4 || exp>precision ){
438 xtype = etEXP;
439 }else{
440 precision = precision - exp;
441 xtype = etFLOAT;
442 }
443 }else{
444 flag_rtz = 0;
445 }
446 /*
447 ** The "exp+precision" test causes output to be of type etEXP if
448 ** the precision is too large to fit in buf[].
449 */
450 nsd = 0;
451 if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
452 flag_dp = (precision>0 || flag_alternateform);
453 if( prefix ) *(bufpt++) = prefix; /* Sign */
454 if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */
455 else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);
456 if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */
457 for(exp++; exp<0 && precision>0; precision--, exp++){
458 *(bufpt++) = '0';
459 }
460 while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
461 *(bufpt--) = 0; /* Null terminate */
462 if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */
463 while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
464 if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
465 }
466 bufpt++; /* point to next free slot */
467 }else{ /* etEXP or etGENERIC */
468 flag_dp = (precision>0 || flag_alternateform);
469 if( prefix ) *(bufpt++) = prefix; /* Sign */
470 *(bufpt++) = et_getdigit(&realvalue,&nsd); /* First digit */
471 if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */
472 while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
473 bufpt--; /* point to last digit */
474 if( flag_rtz && flag_dp ){ /* Remove tail zeros */
475 while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
476 if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
477 }
478 bufpt++; /* point to next free slot */
479 if( exp || flag_exp ){
480 *(bufpt++) = infop->charset[0];
481 if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
482 else { *(bufpt++) = '+'; }
483 if( exp>=100 ){
484 *(bufpt++) = (exp/100)+'0'; /* 100's digit */
485 exp %= 100;
486 }
487 *(bufpt++) = exp/10+'0'; /* 10's digit */
488 *(bufpt++) = exp%10+'0'; /* 1's digit */
489 }
490 }
491 /* The converted number is in buf[] and zero terminated. Output it.
492 ** Note that the number is in the usual order, not reversed as with
493 ** integer conversions. */
494 length = bufpt-buf;
495 bufpt = buf;
496
497 /* Special case: Add leading zeros if the flag_zeropad flag is
498 ** set and we are not left justified */
499 if( flag_zeropad && !flag_leftjustify && length < width){
500 int i;
501 int nPad = width - length;
502 for(i=width; i>=nPad; i--){
503 bufpt[i] = bufpt[i-nPad];
504 }
505 i = prefix!=0;
506 while( nPad-- ) bufpt[i++] = '0';
507 length = width;
508 }
509#endif
510 break;
511 case etSIZE:
512 *(va_arg(ap,int*)) = count;
513 length = width = 0;
514 break;
515 case etPERCENT:
516 buf[0] = '%';
517 bufpt = buf;
518 length = 1;
519 break;
520 case etCHARLIT:
521 case etCHARX:
522 c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
523 if( precision>=0 ){
524 for(idx=1; idx<precision; idx++) buf[idx] = c;
525 length = precision;
526 }else{
527 length =1;
528 }
529 bufpt = buf;
530 break;
531 case etSTRING:
532 case etDYNSTRING:
533 bufpt = va_arg(ap,char*);
534 if( bufpt==0 ){
535 bufpt = "";
536 }else if( xtype==etDYNSTRING ){
537 zExtra = bufpt;
538 }
539 length = strlen(bufpt);
540 if( precision>=0 && precision<length ) length = precision;
541 break;
542 case etSQLESCAPE:
543 case etSQLESCAPE2:
544 {
545 int i, j, n, c, isnull;
546 char *arg = va_arg(ap,char*);
547 isnull = arg==0;
548 if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
549 for(i=n=0; (c=arg[i])!=0; i++){
550 if( c=='\'' ) n++;
551 }
552 n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0);
553 if( n>etBUFSIZE ){
554 bufpt = zExtra = sqliteMalloc( n );
555 if( bufpt==0 ) return -1;
556 }else{
557 bufpt = buf;
558 }
559 j = 0;
560 if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
561 for(i=0; (c=arg[i])!=0; i++){
562 bufpt[j++] = c;
563 if( c=='\'' ) bufpt[j++] = c;
564 }
565 if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
566 bufpt[j] = 0;
567 length = j;
568 if( precision>=0 && precision<length ) length = precision;
569 }
570 break;
571 case etTOKEN: {
572 Token *pToken = va_arg(ap, Token*);
573 (*func)(arg, pToken->z, pToken->n);
574 length = width = 0;
575 break;
576 }
577 case etSRCLIST: {
578 SrcList *pSrc = va_arg(ap, SrcList*);
579 int k = va_arg(ap, int);
580 struct SrcList_item *pItem = &pSrc->a[k];
581 assert( k>=0 && k<pSrc->nSrc );
582 if( pItem->zDatabase && pItem->zDatabase[0] ){
583 (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase));
584 (*func)(arg, ".", 1);
585 }
586 (*func)(arg, pItem->zName, strlen(pItem->zName));
587 length = width = 0;
588 break;
589 }
590 case etERROR:
591 buf[0] = '%';
592 buf[1] = c;
593 errorflag = 0;
594 idx = 1+(c!=0);
595 (*func)(arg,"%",idx);
596 count += idx;
597 if( c==0 ) fmt--;
598 break;
599 }/* End switch over the format type */
600 /*
601 ** The text of the conversion is pointed to by "bufpt" and is
602 ** "length" characters long. The field width is "width". Do
603 ** the output.
604 */
605 if( !flag_leftjustify ){
606 register int nspace;
607 nspace = width-length;
608 if( nspace>0 ){
609 count += nspace;
610 while( nspace>=etSPACESIZE ){
611 (*func)(arg,spaces,etSPACESIZE);
612 nspace -= etSPACESIZE;
613 }
614 if( nspace>0 ) (*func)(arg,spaces,nspace);
615 }
616 }
617 if( length>0 ){
618 (*func)(arg,bufpt,length);
619 count += length;
620 }
621 if( flag_leftjustify ){
622 register int nspace;
623 nspace = width-length;
624 if( nspace>0 ){
625 count += nspace;
626 while( nspace>=etSPACESIZE ){
627 (*func)(arg,spaces,etSPACESIZE);
628 nspace -= etSPACESIZE;
629 }
630 if( nspace>0 ) (*func)(arg,spaces,nspace);
631 }
632 }
633 if( zExtra ){
634 sqliteFree(zExtra);
635 }
636 }/* End for loop over the format string */
637 return errorflag ? -1 : count;
638} /* End of function */
639
640
641/* This structure is used to store state information about the
642** write to memory that is currently in progress.
643*/
644struct sgMprintf {
645 char *zBase; /* A base allocation */
646 char *zText; /* The string collected so far */
647 int nChar; /* Length of the string so far */
648 int nTotal; /* Output size if unconstrained */
649 int nAlloc; /* Amount of space allocated in zText */
650 void *(*xRealloc)(void*,int); /* Function used to realloc memory */
651};
652
653/*
654** This function implements the callback from vxprintf.
655**
656** This routine add nNewChar characters of text in zNewText to
657** the sgMprintf structure pointed to by "arg".
658*/
659static void mout(void *arg, const char *zNewText, int nNewChar){
660 struct sgMprintf *pM = (struct sgMprintf*)arg;
661 pM->nTotal += nNewChar;
662 if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
663 if( pM->xRealloc==0 ){
664 nNewChar = pM->nAlloc - pM->nChar - 1;
665 }else{
666 pM->nAlloc = pM->nChar + nNewChar*2 + 1;
667 if( pM->zText==pM->zBase ){
668 pM->zText = pM->xRealloc(0, pM->nAlloc);
669 if( pM->zText && pM->nChar ){
670 memcpy(pM->zText, pM->zBase, pM->nChar);
671 }
672 }else{
673 pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
674 }
675 }
676 }
677 if( pM->zText ){
678 if( nNewChar>0 ){
679 memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
680 pM->nChar += nNewChar;
681 }
682 pM->zText[pM->nChar] = 0;
683 }
684}
685
686/*
687** This routine is a wrapper around xprintf() that invokes mout() as
688** the consumer.
689*/
690static char *base_vprintf(
691 void *(*xRealloc)(void*,int), /* Routine to realloc memory. May be NULL */
692 int useInternal, /* Use internal %-conversions if true */
693 char *zInitBuf, /* Initially write here, before mallocing */
694 int nInitBuf, /* Size of zInitBuf[] */
695 const char *zFormat, /* format string */
696 va_list ap /* arguments */
697){
698 struct sgMprintf sM;
699 sM.zBase = sM.zText = zInitBuf;
700 sM.nChar = sM.nTotal = 0;
701 sM.nAlloc = nInitBuf;
702 sM.xRealloc = xRealloc;
703 vxprintf(mout, &sM, useInternal, zFormat, ap);
704 if( xRealloc ){
705 if( sM.zText==sM.zBase ){
706 sM.zText = xRealloc(0, sM.nChar+1);
707 memcpy(sM.zText, sM.zBase, sM.nChar+1);
708 }else if( sM.nAlloc>sM.nChar+10 ){
709 sM.zText = xRealloc(sM.zText, sM.nChar+1);
710 }
711 }
712 return sM.zText;
713}
714
715/*
716** Realloc that is a real function, not a macro.
717*/
718static void *printf_realloc(void *old, int size){
719 return sqliteRealloc(old,size);
720}
721
722/*
723** Print into memory obtained from sqliteMalloc(). Use the internal
724** %-conversion extensions.
725*/
726char *sqliteVMPrintf(const char *zFormat, va_list ap){
727 char zBase[1000];
728 return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
729}
730
731/*
732** Print into memory obtained from sqliteMalloc(). Use the internal
733** %-conversion extensions.
734*/
735char *sqliteMPrintf(const char *zFormat, ...){
736 va_list ap;
737 char *z;
738 char zBase[1000];
739 va_start(ap, zFormat);
740 z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
741 va_end(ap);
742 return z;
743}
744
745/*
746** Print into memory obtained from malloc(). Do not use the internal
747** %-conversion extensions. This routine is for use by external users.
748*/
749char *sqlite_mprintf(const char *zFormat, ...){
750 va_list ap;
751 char *z;
752 char zBuf[200];
753
754 va_start(ap,zFormat);
755 z = base_vprintf((void*(*)(void*,int))realloc, 0,
756 zBuf, sizeof(zBuf), zFormat, ap);
757 va_end(ap);
758 return z;
759}
760
761/* This is the varargs version of sqlite_mprintf.
762*/
763char *sqlite_vmprintf(const char *zFormat, va_list ap){
764 char zBuf[200];
765 return base_vprintf((void*(*)(void*,int))realloc, 0,
766 zBuf, sizeof(zBuf), zFormat, ap);
767}
768
769/*
770** sqlite_snprintf() works like snprintf() except that it ignores the
771** current locale settings. This is important for SQLite because we
772** are not able to use a "," as the decimal point in place of "." as
773** specified by some locales.
774*/
775char *sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
776 char *z;
777 va_list ap;
778
779 va_start(ap,zFormat);
780 z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
781 va_end(ap);
782 return z;
783}
784
785/*
786** The following four routines implement the varargs versions of the
787** sqlite_exec() and sqlite_get_table() interfaces. See the sqlite.h
788** header files for a more detailed description of how these interfaces
789** work.
790**
791** These routines are all just simple wrappers.
792*/
793int sqlite_exec_printf(
794 sqlite *db, /* An open database */
795 const char *sqlFormat, /* printf-style format string for the SQL */
796 sqlite_callback xCallback, /* Callback function */
797 void *pArg, /* 1st argument to callback function */
798 char **errmsg, /* Error msg written here */
799 ... /* Arguments to the format string. */
800){
801 va_list ap;
802 int rc;
803
804 va_start(ap, errmsg);
805 rc = sqlite_exec_vprintf(db, sqlFormat, xCallback, pArg, errmsg, ap);
806 va_end(ap);
807 return rc;
808}
809int sqlite_exec_vprintf(
810 sqlite *db, /* An open database */
811 const char *sqlFormat, /* printf-style format string for the SQL */
812 sqlite_callback xCallback, /* Callback function */
813 void *pArg, /* 1st argument to callback function */
814 char **errmsg, /* Error msg written here */
815 va_list ap /* Arguments to the format string. */
816){
817 char *zSql;
818 int rc;
819
820 zSql = sqlite_vmprintf(sqlFormat, ap);
821 rc = sqlite_exec(db, zSql, xCallback, pArg, errmsg);
822 free(zSql);
823 return rc;
824}
825int sqlite_get_table_printf(
826 sqlite *db, /* An open database */
827 const char *sqlFormat, /* printf-style format string for the SQL */
828 char ***resultp, /* Result written to a char *[] that this points to */
829 int *nrow, /* Number of result rows written here */
830 int *ncol, /* Number of result columns written here */
831 char **errmsg, /* Error msg written here */
832 ... /* Arguments to the format string */
833){
834 va_list ap;
835 int rc;
836
837 va_start(ap, errmsg);
838 rc = sqlite_get_table_vprintf(db, sqlFormat, resultp, nrow, ncol, errmsg, ap);
839 va_end(ap);
840 return rc;
841}
842int sqlite_get_table_vprintf(
843 sqlite *db, /* An open database */
844 const char *sqlFormat, /* printf-style format string for the SQL */
845 char ***resultp, /* Result written to a char *[] that this points to */
846 int *nrow, /* Number of result rows written here */
847 int *ncolumn, /* Number of result columns written here */
848 char **errmsg, /* Error msg written here */
849 va_list ap /* Arguments to the format string */
850){
851 char *zSql;
852 int rc;
853
854 zSql = sqlite_vmprintf(sqlFormat, ap);
855 rc = sqlite_get_table(db, zSql, resultp, nrow, ncolumn, errmsg);
856 free(zSql);
857 return rc;
858}
Note: See TracBrowser for help on using the repository browser.