/ Check-in [ca31c663]
Login

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

Overview
Comment:In the printf() library, measure width and precision in characters rather than bytes if the "!" (alternate-form-2) flag is present on a %s or %z substitution.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | printf-enhancement
Files: files | file ages | folders
SHA3-256: ca31c6630422fca70e626dd38aae96296bd8535d491ca52391624a5e7e663636
User & Date: drh 2018-02-19 17:03:23
Context
2018-02-19
18:03
Make the alternate-form-2 flag ("!") change the meaning of width and precision from bytes to characters for the %q, %Q, and %w extensions of printf(). check-in: 391540ac user: drh tags: printf-enhancement
17:03
In the printf() library, measure width and precision in characters rather than bytes if the "!" (alternate-form-2) flag is present on a %s or %z substitution. check-in: ca31c663 user: drh tags: printf-enhancement
16:34
Only try to use the geteuid() interface on unix if HAVE_FCHOWN is defined. This fixes the build for vxWorks, we are told. check-in: 38f654dc user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/printf.c.

   650    650           }
   651    651           if( bufpt==0 ){
   652    652             bufpt = "";
   653    653           }else if( xtype==etDYNSTRING ){
   654    654             zExtra = bufpt;
   655    655           }
   656    656           if( precision>=0 ){
   657         -          for(length=0; length<precision && bufpt[length]; length++){}
          657  +          if( flag_altform2 ){
          658  +            /* Set length to the number of bytes needed in order to display
          659  +            ** precision characters */
          660  +            unsigned char *z = (unsigned char*)bufpt;
          661  +            while( precision-- > 0 && z[0] ){
          662  +              SQLITE_SKIP_UTF8(z);
          663  +            }
          664  +            length = (int)(z - (unsigned char*)bufpt);
          665  +          }else{
          666  +            for(length=0; length<precision && bufpt[length]; length++){}
          667  +          }
   658    668           }else{
   659    669             length = 0x7fffffff & (int)strlen(bufpt);
   660    670           }
          671  +        if( flag_altform2 && width>0 ){
          672  +          /* Adjust width to account for extra bytes in UTF-8 characters */
          673  +          int ii = length - 1;
          674  +          while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
          675  +        }
   661    676           break;
   662    677         case etSQLESCAPE:           /* Escape ' characters */
   663    678         case etSQLESCAPE2:          /* Escape ' and enclose in '...' */
   664    679         case etSQLESCAPE3: {        /* Escape " characters */
   665    680           int i, j, k, n, isnull;
   666    681           int needQuote;
   667    682           char ch;
................................................................................
   696    711           for(i=0; i<k; i++){
   697    712             bufpt[j++] = ch = escarg[i];
   698    713             if( ch==q ) bufpt[j++] = ch;
   699    714           }
   700    715           if( needQuote ) bufpt[j++] = q;
   701    716           bufpt[j] = 0;
   702    717           length = j;
   703         -        /* The precision in %q and %Q means how many input characters to
          718  +        /* The precision in %q and %Q means how many input bytes to
   704    719           ** consume, not the length of the output...
   705    720           ** if( precision>=0 && precision<length ) length = precision; */
   706    721           break;
   707    722         }
   708    723         case etTOKEN: {
   709    724           Token *pToken;
   710    725           if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
................................................................................
   738    753           assert( xtype==etINVALID );
   739    754           return;
   740    755         }
   741    756       }/* End switch over the format type */
   742    757       /*
   743    758       ** The text of the conversion is pointed to by "bufpt" and is
   744    759       ** "length" characters long.  The field width is "width".  Do
   745         -    ** the output.
          760  +    ** the output.  Both length and width are in bytes, not characters,
          761  +    ** at this point.  If the "!" flag was present on string conversions
          762  +    ** indicating that width and precision should be expressed in characters,
          763  +    ** then the values have been translated prior to reaching this point.
   746    764       */
   747    765       width -= length;
   748    766       if( width>0 ){
   749    767         if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
   750    768         sqlite3StrAccumAppend(pAccum, bufpt, length);
   751    769         if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
   752    770       }else{