PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - pdo_sqlite/sqlite/src - printf.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 330
Code covered: 44.2 % Executed lines: 146
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:15 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.