SQLite

Check-in [b9c7ecc2f9]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b9c7ecc2f9d8d7d57c51dc4ba0aaa520e89eb31f
User & Date: chw 2002-06-16 04:55:48.000
Context
2002-06-16
04:56
Added printf-4.(2-4) test cases to test new %Q format specifier. (CVS 622) (check-in: 7d5fc35b5d 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: b9c7ecc2f9 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: 8bc711571d user: chw tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/printf.c.
68
69
70
71
72
73
74


75
76
77
78
79
80
81
   etSTRING,           /* Strings. %s */
   etPERCENT,          /* Percent symbol. %% */
   etCHARX,            /* Characters. %c */
   etERROR,            /* Used to indicate no such conversion type */
/* The rest are extensions, not normally found in printf() */
   etCHARLIT,          /* Literal characters.  %' */
   etSQLESCAPE,        /* Strings with '\'' doubled.  %q */


   etORDINAL           /* 1st, 2nd, 3rd and so forth */
};

/*
** Each builtin conversion character (ex: the 'd' in "%d") is described
** by an instance of the following structure
*/







>
>







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
   etSTRING,           /* Strings. %s */
   etPERCENT,          /* Percent symbol. %% */
   etCHARX,            /* Characters. %c */
   etERROR,            /* Used to indicate no such conversion type */
/* The rest are extensions, not normally found in printf() */
   etCHARLIT,          /* Literal characters.  %' */
   etSQLESCAPE,        /* Strings with '\'' doubled.  %q */
   etSQLESCAPE2,       /* Strings with '\'' doubled and enclosed in '',
                          NULL pointers replaced by SQL NULL.  %Q */
   etORDINAL           /* 1st, 2nd, 3rd and so forth */
};

/*
** Each builtin conversion character (ex: the 'd' in "%d") is described
** by an instance of the following structure
*/
92
93
94
95
96
97
98

99
100
101
102
103
104
105
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.
*/
static et_info fmtinfo[] = {
  { 'd',  10,  "0123456789",       1,    0, etRADIX,      },
  { 's',   0,  0,                  0,    0, etSTRING,     }, 
  { 'q',   0,  0,                  0,    0, etSQLESCAPE,  },

  { 'c',   0,  0,                  0,    0, etCHARX,      },
  { 'o',   8,  "01234567",         0,  "0", etRADIX,      },
  { 'u',  10,  "0123456789",       0,    0, etRADIX,      },
  { 'x',  16,  "0123456789abcdef", 0, "x0", etRADIX,      },
  { 'X',  16,  "0123456789ABCDEF", 0, "X0", etRADIX,      },
  { 'r',  10,  "0123456789",       0,    0, etORDINAL,    },
  { 'f',   0,  0,                  1,    0, etFLOAT,      },







>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.
*/
static et_info fmtinfo[] = {
  { 'd',  10,  "0123456789",       1,    0, etRADIX,      },
  { 's',   0,  0,                  0,    0, etSTRING,     }, 
  { 'q',   0,  0,                  0,    0, etSQLESCAPE,  },
  { 'Q',   0,  0,                  0,    0, etSQLESCAPE2, },
  { 'c',   0,  0,                  0,    0, etCHARX,      },
  { 'o',   8,  "01234567",         0,  "0", etRADIX,      },
  { 'u',  10,  "0123456789",       0,    0, etRADIX,      },
  { 'x',  16,  "0123456789abcdef", 0, "x0", etRADIX,      },
  { 'X',  16,  "0123456789ABCDEF", 0, "X0", etRADIX,      },
  { 'r',  10,  "0123456789",       0,    0, etORDINAL,    },
  { 'f',   0,  0,                  1,    0, etFLOAT,      },
549
550
551
552
553
554
555

556
557
558
559

560
561
562
563
564
565
566
567
568
569


570
571
572
573

574
575
576
577
578
579
580
      case etSTRING:
        zMem = bufpt = va_arg(ap,char*);
        if( bufpt==0 ) bufpt = "(null)";
        length = strlen(bufpt);
        if( precision>=0 && precision<length ) length = precision;
        break;
      case etSQLESCAPE:

        {
          int i, j, n, c;
          char *arg = va_arg(ap,char*);
          if( arg==0 ) arg = "(NULL)";

          for(i=n=0; (c=arg[i])!=0; i++){
            if( c=='\'' )  n++;
          }
          n += i + 1;
          if( n>etBUFSIZE ){
            bufpt = zExtra = sqliteMalloc( n );
            if( bufpt==0 ) return -1;
          }else{
            bufpt = buf;
          }


          for(i=j=0; (c=arg[i])!=0; i++){
            bufpt[j++] = c;
            if( c=='\'' ) bufpt[j++] = c;
          }

          bufpt[j] = 0;
          length = j;
          if( precision>=0 && precision<length ) length = precision;
        }
        break;
      case etERROR:
        buf[0] = '%';







>

|

|
>



|






>
>
|



>







552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
      case etSTRING:
        zMem = bufpt = va_arg(ap,char*);
        if( bufpt==0 ) bufpt = "(null)";
        length = strlen(bufpt);
        if( precision>=0 && precision<length ) length = precision;
        break;
      case etSQLESCAPE:
      case etSQLESCAPE2:
        {
          int i, j, n, c, isnull;
          char *arg = va_arg(ap,char*);
          isnull = arg==0;
          if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
          for(i=n=0; (c=arg[i])!=0; i++){
            if( c=='\'' )  n++;
          }
          n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0);
          if( n>etBUFSIZE ){
            bufpt = zExtra = sqliteMalloc( n );
            if( bufpt==0 ) return -1;
          }else{
            bufpt = buf;
          }
          j = 0;
          if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
          for(i=0; (c=arg[i])!=0; i++){
            bufpt[j++] = c;
            if( c=='\'' ) bufpt[j++] = c;
          }
          if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
          bufpt[j] = 0;
          length = j;
          if( precision>=0 && precision<length ) length = precision;
        }
        break;
      case etERROR:
        buf[0] = '%';