/ Check-in [b9c7ecc2]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added %Q format specifier: like %q but automatic enclosing in single quotes, NULL pointers replaced by NULL w/o single-quotes. (CVS 621)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:b9c7ecc2f9d8d7d57c51dc4ba0aaa520e89eb31f
User & Date: chw 2002-06-16 04:55:48
Context
2002-06-16
04:56
Added printf-4.(2-4) test cases to test new %Q format specifier. (CVS 622) check-in: 7d5fc35b user: chw tags: trunk
04:55
Added %Q format specifier: like %q but automatic enclosing in single quotes, NULL pointers replaced by NULL w/o single-quotes. (CVS 621) check-in: b9c7ecc2 user: chw tags: trunk
04:54
Changed sqlite_mprintf_str to allow a NULL string parameter. Command template now is cmd FORMAT INT INT ?STRING?. When STRING omitted a NULL is passed to sqlite_mprintf. (CVS 620) check-in: 8bc71157 user: chw tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/printf.c.

    68     68      etSTRING,           /* Strings. %s */
    69     69      etPERCENT,          /* Percent symbol. %% */
    70     70      etCHARX,            /* Characters. %c */
    71     71      etERROR,            /* Used to indicate no such conversion type */
    72     72   /* The rest are extensions, not normally found in printf() */
    73     73      etCHARLIT,          /* Literal characters.  %' */
    74     74      etSQLESCAPE,        /* Strings with '\'' doubled.  %q */
           75  +   etSQLESCAPE2,       /* Strings with '\'' doubled and enclosed in '',
           76  +                          NULL pointers replaced by SQL NULL.  %Q */
    75     77      etORDINAL           /* 1st, 2nd, 3rd and so forth */
    76     78   };
    77     79   
    78     80   /*
    79     81   ** Each builtin conversion character (ex: the 'd' in "%d") is described
    80     82   ** by an instance of the following structure
    81     83   */
................................................................................
    92     94   ** The following table is searched linearly, so it is good to put the
    93     95   ** most frequently used conversion types first.
    94     96   */
    95     97   static et_info fmtinfo[] = {
    96     98     { 'd',  10,  "0123456789",       1,    0, etRADIX,      },
    97     99     { 's',   0,  0,                  0,    0, etSTRING,     }, 
    98    100     { 'q',   0,  0,                  0,    0, etSQLESCAPE,  },
          101  +  { 'Q',   0,  0,                  0,    0, etSQLESCAPE2, },
    99    102     { 'c',   0,  0,                  0,    0, etCHARX,      },
   100    103     { 'o',   8,  "01234567",         0,  "0", etRADIX,      },
   101    104     { 'u',  10,  "0123456789",       0,    0, etRADIX,      },
   102    105     { 'x',  16,  "0123456789abcdef", 0, "x0", etRADIX,      },
   103    106     { 'X',  16,  "0123456789ABCDEF", 0, "X0", etRADIX,      },
   104    107     { 'r',  10,  "0123456789",       0,    0, etORDINAL,    },
   105    108     { 'f',   0,  0,                  1,    0, etFLOAT,      },
................................................................................
   549    552         case etSTRING:
   550    553           zMem = bufpt = va_arg(ap,char*);
   551    554           if( bufpt==0 ) bufpt = "(null)";
   552    555           length = strlen(bufpt);
   553    556           if( precision>=0 && precision<length ) length = precision;
   554    557           break;
   555    558         case etSQLESCAPE:
          559  +      case etSQLESCAPE2:
   556    560           {
   557         -          int i, j, n, c;
          561  +          int i, j, n, c, isnull;
   558    562             char *arg = va_arg(ap,char*);
   559         -          if( arg==0 ) arg = "(NULL)";
          563  +          isnull = arg==0;
          564  +          if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
   560    565             for(i=n=0; (c=arg[i])!=0; i++){
   561    566               if( c=='\'' )  n++;
   562    567             }
   563         -          n += i + 1;
          568  +          n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0);
   564    569             if( n>etBUFSIZE ){
   565    570               bufpt = zExtra = sqliteMalloc( n );
   566    571               if( bufpt==0 ) return -1;
   567    572             }else{
   568    573               bufpt = buf;
   569    574             }
   570         -          for(i=j=0; (c=arg[i])!=0; i++){
          575  +          j = 0;
          576  +          if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
          577  +          for(i=0; (c=arg[i])!=0; i++){
   571    578               bufpt[j++] = c;
   572    579               if( c=='\'' ) bufpt[j++] = c;
   573    580             }
          581  +          if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
   574    582             bufpt[j] = 0;
   575    583             length = j;
   576    584             if( precision>=0 && precision<length ) length = precision;
   577    585           }
   578    586           break;
   579    587         case etERROR:
   580    588           buf[0] = '%';