00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "sqliteInt.h"
00054
00055
00056
00057
00058
00059 #define etRADIX 1
00060 #define etFLOAT 2
00061 #define etEXP 3
00062 #define etGENERIC 4
00063 #define etSIZE 5
00064 #define etSTRING 6
00065 #define etDYNSTRING 7
00066 #define etPERCENT 8
00067 #define etCHARX 9
00068 #define etERROR 10
00069
00070 #define etCHARLIT 11
00071 #define etSQLESCAPE 12
00072 #define etSQLESCAPE2 13
00073
00074 #define etTOKEN 14
00075 #define etSRCLIST 15
00076
00077
00078
00079
00080
00081 typedef unsigned char etByte;
00082
00083
00084
00085
00086
00087 typedef struct et_info {
00088 char fmttype;
00089 etByte base;
00090 etByte flags;
00091 etByte type;
00092 char *charset;
00093 char *prefix;
00094 } et_info;
00095
00096
00097
00098
00099 #define FLAG_SIGNED 1
00100 #define FLAG_INTERN 2
00101
00102
00103
00104
00105
00106
00107 static et_info fmtinfo[] = {
00108 { 'd', 10, 1, etRADIX, "0123456789", 0 },
00109 { 's', 0, 0, etSTRING, 0, 0 },
00110 { 'z', 0, 2, etDYNSTRING, 0, 0 },
00111 { 'q', 0, 0, etSQLESCAPE, 0, 0 },
00112 { 'Q', 0, 0, etSQLESCAPE2, 0, 0 },
00113 { 'c', 0, 0, etCHARX, 0, 0 },
00114 { 'o', 8, 0, etRADIX, "01234567", "0" },
00115 { 'u', 10, 0, etRADIX, "0123456789", 0 },
00116 { 'x', 16, 0, etRADIX, "0123456789abcdef", "x0" },
00117 { 'X', 16, 0, etRADIX, "0123456789ABCDEF", "X0" },
00118 { 'f', 0, 1, etFLOAT, 0, 0 },
00119 { 'e', 0, 1, etEXP, "e", 0 },
00120 { 'E', 0, 1, etEXP, "E", 0 },
00121 { 'g', 0, 1, etGENERIC, "e", 0 },
00122 { 'G', 0, 1, etGENERIC, "E", 0 },
00123 { 'i', 10, 1, etRADIX, "0123456789", 0 },
00124 { 'n', 0, 0, etSIZE, 0, 0 },
00125 { '%', 0, 0, etPERCENT, 0, 0 },
00126 { 'p', 10, 0, etRADIX, "0123456789", 0 },
00127 { 'T', 0, 2, etTOKEN, 0, 0 },
00128 { 'S', 0, 2, etSRCLIST, 0, 0 },
00129 };
00130 #define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
00131
00132
00133
00134
00135
00136 #ifndef etNOFLOATINGPOINT
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
00151 int digit;
00152 LONGDOUBLE_TYPE d;
00153 if( (*cnt)++ >= 16 ) return '0';
00154 digit = (int)*val;
00155 d = digit;
00156 digit += '0';
00157 *val = (*val - d)*10.0;
00158 return digit;
00159 }
00160 #endif
00161
00162 #define etBUFSIZE 1000
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 static int vxprintf(
00192 void (*func)(void*,const char*,int),
00193 void *arg,
00194 int useExtended,
00195 const char *fmt,
00196 va_list ap
00197 ){
00198 int c;
00199 char *bufpt;
00200 int precision;
00201 int length;
00202 int idx;
00203 int count;
00204 int width;
00205 etByte flag_leftjustify;
00206 etByte flag_plussign;
00207 etByte flag_blanksign;
00208 etByte flag_alternateform;
00209 etByte flag_zeropad;
00210 etByte flag_long;
00211 unsigned long longvalue;
00212 LONGDOUBLE_TYPE realvalue;
00213 et_info *infop;
00214 char buf[etBUFSIZE];
00215 char prefix;
00216 etByte errorflag = 0;
00217 etByte xtype;
00218 char *zExtra;
00219 static char spaces[] = " ";
00220 #define etSPACESIZE (sizeof(spaces)-1)
00221 #ifndef etNOFLOATINGPOINT
00222 int exp;
00223 double rounder;
00224 etByte flag_dp;
00225 etByte flag_rtz;
00226 etByte flag_exp;
00227 int nsd;
00228 #endif
00229
00230 func(arg,"",0);
00231 count = length = 0;
00232 bufpt = 0;
00233 for(; (c=(*fmt))!=0; ++fmt){
00234 if( c!='%' ){
00235 int amt;
00236 bufpt = (char *)fmt;
00237 amt = 1;
00238 while( (c=(*++fmt))!='%' && c!=0 ) amt++;
00239 (*func)(arg,bufpt,amt);
00240 count += amt;
00241 if( c==0 ) break;
00242 }
00243 if( (c=(*++fmt))==0 ){
00244 errorflag = 1;
00245 (*func)(arg,"%",1);
00246 count++;
00247 break;
00248 }
00249
00250 flag_leftjustify = flag_plussign = flag_blanksign =
00251 flag_alternateform = flag_zeropad = 0;
00252 do{
00253 switch( c ){
00254 case '-': flag_leftjustify = 1; c = 0; break;
00255 case '+': flag_plussign = 1; c = 0; break;
00256 case ' ': flag_blanksign = 1; c = 0; break;
00257 case '#': flag_alternateform = 1; c = 0; break;
00258 case '0': flag_zeropad = 1; c = 0; break;
00259 default: break;
00260 }
00261 }while( c==0 && (c=(*++fmt))!=0 );
00262
00263 width = 0;
00264 if( c=='*' ){
00265 width = va_arg(ap,int);
00266 if( width<0 ){
00267 flag_leftjustify = 1;
00268 width = -width;
00269 }
00270 c = *++fmt;
00271 }else{
00272 while( c>='0' && c<='9' ){
00273 width = width*10 + c - '0';
00274 c = *++fmt;
00275 }
00276 }
00277 if( width > etBUFSIZE-10 ){
00278 width = etBUFSIZE-10;
00279 }
00280
00281 if( c=='.' ){
00282 precision = 0;
00283 c = *++fmt;
00284 if( c=='*' ){
00285 precision = va_arg(ap,int);
00286 if( precision<0 ) precision = -precision;
00287 c = *++fmt;
00288 }else{
00289 while( c>='0' && c<='9' ){
00290 precision = precision*10 + c - '0';
00291 c = *++fmt;
00292 }
00293 }
00294
00295 if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40;
00296 }else{
00297 precision = -1;
00298 }
00299
00300 if( c=='l' ){
00301 flag_long = 1;
00302 c = *++fmt;
00303 }else{
00304 flag_long = 0;
00305 }
00306
00307 infop = 0;
00308 xtype = etERROR;
00309 for(idx=0; idx<etNINFO; idx++){
00310 if( c==fmtinfo[idx].fmttype ){
00311 infop = &fmtinfo[idx];
00312 if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
00313 xtype = infop->type;
00314 }
00315 break;
00316 }
00317 }
00318 zExtra = 0;
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 switch( xtype ){
00339 case etRADIX:
00340 if( flag_long ) longvalue = va_arg(ap,long);
00341 else longvalue = va_arg(ap,int);
00342 #if 1
00343
00344
00345 if( longvalue==0 ) flag_alternateform = 0;
00346 #else
00347
00348
00349 if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;
00350 #endif
00351 if( infop->flags & FLAG_SIGNED ){
00352 if( *(long*)&longvalue<0 ){
00353 longvalue = -*(long*)&longvalue;
00354 prefix = '-';
00355 }else if( flag_plussign ) prefix = '+';
00356 else if( flag_blanksign ) prefix = ' ';
00357 else prefix = 0;
00358 }else prefix = 0;
00359 if( flag_zeropad && precision<width-(prefix!=0) ){
00360 precision = width-(prefix!=0);
00361 }
00362 bufpt = &buf[etBUFSIZE-1];
00363 {
00364 register char *cset;
00365 register int base;
00366 cset = infop->charset;
00367 base = infop->base;
00368 do{
00369 *(--bufpt) = cset[longvalue%base];
00370 longvalue = longvalue/base;
00371 }while( longvalue>0 );
00372 }
00373 length = &buf[etBUFSIZE-1]-bufpt;
00374 for(idx=precision-length; idx>0; idx--){
00375 *(--bufpt) = '0';
00376 }
00377 if( prefix ) *(--bufpt) = prefix;
00378 if( flag_alternateform && infop->prefix ){
00379 char *pre, x;
00380 pre = infop->prefix;
00381 if( *bufpt!=pre[0] ){
00382 for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
00383 }
00384 }
00385 length = &buf[etBUFSIZE-1]-bufpt;
00386 break;
00387 case etFLOAT:
00388 case etEXP:
00389 case etGENERIC:
00390 realvalue = va_arg(ap,double);
00391 #ifndef etNOFLOATINGPOINT
00392 if( precision<0 ) precision = 6;
00393 if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
00394 if( realvalue<0.0 ){
00395 realvalue = -realvalue;
00396 prefix = '-';
00397 }else{
00398 if( flag_plussign ) prefix = '+';
00399 else if( flag_blanksign ) prefix = ' ';
00400 else prefix = 0;
00401 }
00402 if( infop->type==etGENERIC && precision>0 ) precision--;
00403 rounder = 0.0;
00404 #if 0
00405
00406 for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
00407 #else
00408
00409 for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
00410 #endif
00411 if( infop->type==etFLOAT ) realvalue += rounder;
00412
00413 exp = 0;
00414 if( realvalue>0.0 ){
00415 while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
00416 while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
00417 while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
00418 while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
00419 if( exp>350 || exp<-350 ){
00420 bufpt = "NaN";
00421 length = 3;
00422 break;
00423 }
00424 }
00425 bufpt = buf;
00426
00427
00428
00429
00430 flag_exp = xtype==etEXP;
00431 if( xtype!=etFLOAT ){
00432 realvalue += rounder;
00433 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
00434 }
00435 if( xtype==etGENERIC ){
00436 flag_rtz = !flag_alternateform;
00437 if( exp<-4 || exp>precision ){
00438 xtype = etEXP;
00439 }else{
00440 precision = precision - exp;
00441 xtype = etFLOAT;
00442 }
00443 }else{
00444 flag_rtz = 0;
00445 }
00446
00447
00448
00449
00450 nsd = 0;
00451 if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
00452 flag_dp = (precision>0 || flag_alternateform);
00453 if( prefix ) *(bufpt++) = prefix;
00454 if( exp<0 ) *(bufpt++) = '0';
00455 else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);
00456 if( flag_dp ) *(bufpt++) = '.';
00457 for(exp++; exp<0 && precision>0; precision--, exp++){
00458 *(bufpt++) = '0';
00459 }
00460 while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
00461 *(bufpt--) = 0;
00462 if( flag_rtz && flag_dp ){
00463 while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
00464 if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
00465 }
00466 bufpt++;
00467 }else{
00468 flag_dp = (precision>0 || flag_alternateform);
00469 if( prefix ) *(bufpt++) = prefix;
00470 *(bufpt++) = et_getdigit(&realvalue,&nsd);
00471 if( flag_dp ) *(bufpt++) = '.';
00472 while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
00473 bufpt--;
00474 if( flag_rtz && flag_dp ){
00475 while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
00476 if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
00477 }
00478 bufpt++;
00479 if( exp || flag_exp ){
00480 *(bufpt++) = infop->charset[0];
00481 if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; }
00482 else { *(bufpt++) = '+'; }
00483 if( exp>=100 ){
00484 *(bufpt++) = (exp/100)+'0';
00485 exp %= 100;
00486 }
00487 *(bufpt++) = exp/10+'0';
00488 *(bufpt++) = exp%10+'0';
00489 }
00490 }
00491
00492
00493
00494 length = bufpt-buf;
00495 bufpt = buf;
00496
00497
00498
00499 if( flag_zeropad && !flag_leftjustify && length < width){
00500 int i;
00501 int nPad = width - length;
00502 for(i=width; i>=nPad; i--){
00503 bufpt[i] = bufpt[i-nPad];
00504 }
00505 i = prefix!=0;
00506 while( nPad-- ) bufpt[i++] = '0';
00507 length = width;
00508 }
00509 #endif
00510 break;
00511 case etSIZE:
00512 *(va_arg(ap,int*)) = count;
00513 length = width = 0;
00514 break;
00515 case etPERCENT:
00516 buf[0] = '%';
00517 bufpt = buf;
00518 length = 1;
00519 break;
00520 case etCHARLIT:
00521 case etCHARX:
00522 c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
00523 if( precision>=0 ){
00524 for(idx=1; idx<precision; idx++) buf[idx] = c;
00525 length = precision;
00526 }else{
00527 length =1;
00528 }
00529 bufpt = buf;
00530 break;
00531 case etSTRING:
00532 case etDYNSTRING:
00533 bufpt = va_arg(ap,char*);
00534 if( bufpt==0 ){
00535 bufpt = "";
00536 }else if( xtype==etDYNSTRING ){
00537 zExtra = bufpt;
00538 }
00539 length = strlen(bufpt);
00540 if( precision>=0 && precision<length ) length = precision;
00541 break;
00542 case etSQLESCAPE:
00543 case etSQLESCAPE2:
00544 {
00545 int i, j, n, c, isnull;
00546 char *arg = va_arg(ap,char*);
00547 isnull = arg==0;
00548 if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
00549 for(i=n=0; (c=arg[i])!=0; i++){
00550 if( c=='\'' ) n++;
00551 }
00552 n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0);
00553 if( n>etBUFSIZE ){
00554 bufpt = zExtra = sqliteMalloc( n );
00555 if( bufpt==0 ) return -1;
00556 }else{
00557 bufpt = buf;
00558 }
00559 j = 0;
00560 if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
00561 for(i=0; (c=arg[i])!=0; i++){
00562 bufpt[j++] = c;
00563 if( c=='\'' ) bufpt[j++] = c;
00564 }
00565 if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
00566 bufpt[j] = 0;
00567 length = j;
00568 if( precision>=0 && precision<length ) length = precision;
00569 }
00570 break;
00571 case etTOKEN: {
00572 Token *pToken = va_arg(ap, Token*);
00573 (*func)(arg, pToken->z, pToken->n);
00574 length = width = 0;
00575 break;
00576 }
00577 case etSRCLIST: {
00578 SrcList *pSrc = va_arg(ap, SrcList*);
00579 int k = va_arg(ap, int);
00580 struct SrcList_item *pItem = &pSrc->a[k];
00581 assert( k>=0 && k<pSrc->nSrc );
00582 if( pItem->zDatabase && pItem->zDatabase[0] ){
00583 (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase));
00584 (*func)(arg, ".", 1);
00585 }
00586 (*func)(arg, pItem->zName, strlen(pItem->zName));
00587 length = width = 0;
00588 break;
00589 }
00590 case etERROR:
00591 buf[0] = '%';
00592 buf[1] = c;
00593 errorflag = 0;
00594 idx = 1+(c!=0);
00595 (*func)(arg,"%",idx);
00596 count += idx;
00597 if( c==0 ) fmt--;
00598 break;
00599 }
00600
00601
00602
00603
00604
00605 if( !flag_leftjustify ){
00606 register int nspace;
00607 nspace = width-length;
00608 if( nspace>0 ){
00609 count += nspace;
00610 while( nspace>=etSPACESIZE ){
00611 (*func)(arg,spaces,etSPACESIZE);
00612 nspace -= etSPACESIZE;
00613 }
00614 if( nspace>0 ) (*func)(arg,spaces,nspace);
00615 }
00616 }
00617 if( length>0 ){
00618 (*func)(arg,bufpt,length);
00619 count += length;
00620 }
00621 if( flag_leftjustify ){
00622 register int nspace;
00623 nspace = width-length;
00624 if( nspace>0 ){
00625 count += nspace;
00626 while( nspace>=etSPACESIZE ){
00627 (*func)(arg,spaces,etSPACESIZE);
00628 nspace -= etSPACESIZE;
00629 }
00630 if( nspace>0 ) (*func)(arg,spaces,nspace);
00631 }
00632 }
00633 if( zExtra ){
00634 sqliteFree(zExtra);
00635 }
00636 }
00637 return errorflag ? -1 : count;
00638 }
00639
00640
00641
00642
00643
00644 struct sgMprintf {
00645 char *zBase;
00646 char *zText;
00647 int nChar;
00648 int nTotal;
00649 int nAlloc;
00650 void *(*xRealloc)(void*,int);
00651 };
00652
00653
00654
00655
00656
00657
00658
00659 static void mout(void *arg, const char *zNewText, int nNewChar){
00660 struct sgMprintf *pM = (struct sgMprintf*)arg;
00661 pM->nTotal += nNewChar;
00662 if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
00663 if( pM->xRealloc==0 ){
00664 nNewChar = pM->nAlloc - pM->nChar - 1;
00665 }else{
00666 pM->nAlloc = pM->nChar + nNewChar*2 + 1;
00667 if( pM->zText==pM->zBase ){
00668 pM->zText = pM->xRealloc(0, pM->nAlloc);
00669 if( pM->zText && pM->nChar ){
00670 memcpy(pM->zText, pM->zBase, pM->nChar);
00671 }
00672 }else{
00673 pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
00674 }
00675 }
00676 }
00677 if( pM->zText ){
00678 if( nNewChar>0 ){
00679 memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
00680 pM->nChar += nNewChar;
00681 }
00682 pM->zText[pM->nChar] = 0;
00683 }
00684 }
00685
00686
00687
00688
00689
00690 static char *base_vprintf(
00691 void *(*xRealloc)(void*,int),
00692 int useInternal,
00693 char *zInitBuf,
00694 int nInitBuf,
00695 const char *zFormat,
00696 va_list ap
00697 ){
00698 struct sgMprintf sM;
00699 sM.zBase = sM.zText = zInitBuf;
00700 sM.nChar = sM.nTotal = 0;
00701 sM.nAlloc = nInitBuf;
00702 sM.xRealloc = xRealloc;
00703 vxprintf(mout, &sM, useInternal, zFormat, ap);
00704 if( xRealloc ){
00705 if( sM.zText==sM.zBase ){
00706 sM.zText = xRealloc(0, sM.nChar+1);
00707 memcpy(sM.zText, sM.zBase, sM.nChar+1);
00708 }else if( sM.nAlloc>sM.nChar+10 ){
00709 sM.zText = xRealloc(sM.zText, sM.nChar+1);
00710 }
00711 }
00712 return sM.zText;
00713 }
00714
00715
00716
00717
00718 static void *printf_realloc(void *old, int size){
00719 return sqliteRealloc(old,size);
00720 }
00721
00722
00723
00724
00725
00726 char *sqliteVMPrintf(const char *zFormat, va_list ap){
00727 char zBase[1000];
00728 return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
00729 }
00730
00731
00732
00733
00734
00735 char *sqliteMPrintf(const char *zFormat, ...){
00736 va_list ap;
00737 char *z;
00738 char zBase[1000];
00739 va_start(ap, zFormat);
00740 z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
00741 va_end(ap);
00742 return z;
00743 }
00744
00745
00746
00747
00748
00749 char *sqlite_mprintf(const char *zFormat, ...){
00750 va_list ap;
00751 char *z;
00752 char zBuf[200];
00753
00754 va_start(ap,zFormat);
00755 z = base_vprintf((void*(*)(void*,int))realloc, 0,
00756 zBuf, sizeof(zBuf), zFormat, ap);
00757 va_end(ap);
00758 return z;
00759 }
00760
00761
00762
00763 char *sqlite_vmprintf(const char *zFormat, va_list ap){
00764 char zBuf[200];
00765 return base_vprintf((void*(*)(void*,int))realloc, 0,
00766 zBuf, sizeof(zBuf), zFormat, ap);
00767 }
00768
00769
00770
00771
00772
00773
00774
00775 char *sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
00776 char *z;
00777 va_list ap;
00778
00779 va_start(ap,zFormat);
00780 z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
00781 va_end(ap);
00782 return z;
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 int sqlite_exec_printf(
00794 sqlite *db,
00795 const char *sqlFormat,
00796 sqlite_callback xCallback,
00797 void *pArg,
00798 char **errmsg,
00799 ...
00800 ){
00801 va_list ap;
00802 int rc;
00803
00804 va_start(ap, errmsg);
00805 rc = sqlite_exec_vprintf(db, sqlFormat, xCallback, pArg, errmsg, ap);
00806 va_end(ap);
00807 return rc;
00808 }
00809 int sqlite_exec_vprintf(
00810 sqlite *db,
00811 const char *sqlFormat,
00812 sqlite_callback xCallback,
00813 void *pArg,
00814 char **errmsg,
00815 va_list ap
00816 ){
00817 char *zSql;
00818 int rc;
00819
00820 zSql = sqlite_vmprintf(sqlFormat, ap);
00821 rc = sqlite_exec(db, zSql, xCallback, pArg, errmsg);
00822 free(zSql);
00823 return rc;
00824 }
00825 int sqlite_get_table_printf(
00826 sqlite *db,
00827 const char *sqlFormat,
00828 char ***resultp,
00829 int *nrow,
00830 int *ncol,
00831 char **errmsg,
00832 ...
00833 ){
00834 va_list ap;
00835 int rc;
00836
00837 va_start(ap, errmsg);
00838 rc = sqlite_get_table_vprintf(db, sqlFormat, resultp, nrow, ncol, errmsg, ap);
00839 va_end(ap);
00840 return rc;
00841 }
00842 int sqlite_get_table_vprintf(
00843 sqlite *db,
00844 const char *sqlFormat,
00845 char ***resultp,
00846 int *nrow,
00847 int *ncolumn,
00848 char **errmsg,
00849 va_list ap
00850 ){
00851 char *zSql;
00852 int rc;
00853
00854 zSql = sqlite_vmprintf(sqlFormat, ap);
00855 rc = sqlite_get_table(db, zSql, resultp, nrow, ncolumn, errmsg);
00856 free(zSql);
00857 return rc;
00858 }