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