]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the "," flag to printf().
authordrh <drh@noemail.net>
Fri, 10 Feb 2017 19:38:36 +0000 (19:38 +0000)
committerdrh <drh@noemail.net>
Fri, 10 Feb 2017 19:38:36 +0000 (19:38 +0000)
FossilOrigin-Name: 064445b12f99f76e9a12957be97edd520ab3ae27

manifest
manifest.uuid
src/printf.c
test/printf2.test

index 3dd0a8d9c45518324d974a5324d5511633403c8c..53d7e16ed6c33c18e1ddd2a0c0dfc3d843bf9783 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Cleanup\sthe\susage\sof\sthe\sSQLITE_DISABLE_INTRINSIC\scompile-time\soption.\nRemove\sthe\sSQLITE_RUNTIME_BYTEORDER\scompile-time\soption.\s\sUse\n-DSQLITE_BYTEORDER=0\sinstead.\s\sFix\sa\sbug\sin\sR-Tree\sthat\soccurs\swhen\scompiling\non\sa\sknown\slittle-endian\smachine\swithout\sthe\suse\sof\sintrinsic\sbyteswapping\nfunctions.
-D 2017-02-09T17:12:22.122
+C Add\sthe\s","\sflag\sto\sprintf().
+D 2017-02-10T19:38:36.506
 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99
@@ -390,7 +390,7 @@ F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
 F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d
 F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a
 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
-F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd
+F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
@@ -1021,7 +1021,7 @@ F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
 F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
 F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264
 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
-F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
+F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad
 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
 F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
@@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 1afec5758b624e6a066d4e7ef50695095e9d7ff1
-R d99a1e96a3817ca7543fc882a1f70881
+P 798fb9d70d2e5f95e64237b04d6692360133381a
+R c3dc7f748658995c87bb25e10706fab3
 U drh
-Z 871c0b5ab0829dba2d37da91622734c8
+Z 3add84968b9ef1dfcf3d7b3eaefd30ad
index afdafcf9aa5ee6dae8a8e7478daf8ef8175a822e..8090b2db3660bf045ce6100b4a3d6d4453ed9a41 100644 (file)
@@ -1 +1 @@
-798fb9d70d2e5f95e64237b04d6692360133381a
\ No newline at end of file
+064445b12f99f76e9a12957be97edd520ab3ae27
\ No newline at end of file
index ede86f12088f4b307c97d9aea9490b58e2974c9f..241338b266b3b4283d5266c8056c0c567d8fb760 100644 (file)
@@ -15,7 +15,7 @@
 ** Conversion types fall into various categories as defined by the
 ** following enumeration.
 */
-#define etRADIX       0 /* Integer types.  %d, %x, %o, and so forth */
+#define etRADIX       0 /* non-decimal integer types.  %x %o */
 #define etFLOAT       1 /* Floating point.  %f */
 #define etEXP         2 /* Exponentional notation. %e and %E */
 #define etGENERIC     3 /* Floating or exponential, depending on exponent. %g */
@@ -33,8 +33,9 @@
 #define etPOINTER    13 /* The %p conversion */
 #define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
 #define etORDINAL    15 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
+#define etDECIMAL    16 /* %d or %u, but not %x, %o */
 
-#define etINVALID    16 /* Any unrecognized conversion type */
+#define etINVALID    17 /* Any unrecognized conversion type */
 
 
 /*
@@ -58,8 +59,8 @@ typedef struct et_info {   /* Information about each format field */
 /*
 ** Allowed values for et_info.flags
 */
-#define FLAG_SIGNED  1     /* True if the value to convert is signed */
-#define FLAG_STRING  4     /* Allow infinity precision */
+#define FLAG_SIGNED    1     /* True if the value to convert is signed */
+#define FLAG_STRING    4     /* Allow infinite precision */
 
 
 /*
@@ -69,7 +70,7 @@ typedef struct et_info {   /* Information about each format field */
 static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
 static const char aPrefix[] = "-x0\000X0";
 static const et_info fmtinfo[] = {
-  {  'd', 10, 1, etRADIX,      0,  0 },
+  {  'd', 10, 1, etDECIMAL,    0,  0 },
   {  's',  0, 4, etSTRING,     0,  0 },
   {  'g',  0, 1, etGENERIC,    30, 0 },
   {  'z',  0, 4, etDYNSTRING,  0,  0 },
@@ -78,7 +79,7 @@ static const et_info fmtinfo[] = {
   {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
   {  'c',  0, 0, etCHARX,      0,  0 },
   {  'o',  8, 0, etRADIX,      0,  2 },
-  {  'u', 10, 0, etRADIX,      0,  0 },
+  {  'u', 10, 0, etDECIMAL,    0,  0 },
   {  'x', 16, 0, etRADIX,      16, 1 },
   {  'X', 16, 0, etRADIX,      0,  4 },
 #ifndef SQLITE_OMIT_FLOATING_POINT
@@ -87,7 +88,7 @@ static const et_info fmtinfo[] = {
   {  'E',  0, 1, etEXP,        14, 0 },
   {  'G',  0, 1, etGENERIC,    14, 0 },
 #endif
-  {  'i', 10, 1, etRADIX,      0,  0 },
+  {  'i', 10, 1, etDECIMAL,    0,  0 },
   {  'n',  0, 0, etSIZE,       0,  0 },
   {  '%',  0, 0, etPERCENT,    0,  0 },
   {  'p', 16, 0, etPOINTER,    0,  1 },
@@ -179,14 +180,13 @@ void sqlite3VXPrintf(
   int idx;                   /* A general purpose loop counter */
   int width;                 /* Width of the current field */
   etByte flag_leftjustify;   /* True if "-" flag is present */
-  etByte flag_plussign;      /* True if "+" flag is present */
-  etByte flag_blanksign;     /* True if " " flag is present */
+  etByte flag_prefix;        /* '+' or ' ' or 0 for prefix */
   etByte flag_alternateform; /* True if "#" flag is present */
   etByte flag_altform2;      /* True if "!" flag is present */
   etByte flag_zeropad;       /* True if field width constant starts with zero */
-  etByte flag_long;          /* True if "l" flag is present */
-  etByte flag_longlong;      /* True if the "ll" flag is present */
+  etByte flag_long;          /* 1 for the "l" flag, 2 for "ll", 0 by default */
   etByte done;               /* Loop termination flag */
+  etByte cThousand;          /* Thousands separator for %d and %u */
   etByte xtype = etINVALID;  /* Conversion paradigm */
   u8 bArgList;               /* True for SQLITE_PRINTF_SQLFUNC */
   char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
@@ -229,17 +229,18 @@ void sqlite3VXPrintf(
       break;
     }
     /* Find out what flags are present */
-    flag_leftjustify = flag_plussign = flag_blanksign = 
+    flag_leftjustify = flag_prefix = cThousand =
      flag_alternateform = flag_altform2 = flag_zeropad = 0;
     done = 0;
     do{
       switch( c ){
         case '-':   flag_leftjustify = 1;     break;
-        case '+':   flag_plussign = 1;        break;
-        case ' ':   flag_blanksign = 1;       break;
+        case '+':   flag_prefix = '+';        break;
+        case ' ':   flag_prefix = ' ';        break;
         case '#':   flag_alternateform = 1;   break;
         case '!':   flag_altform2 = 1;        break;
         case '0':   flag_zeropad = 1;         break;
+        case ',':   cThousand = ',';          break;
         default:    done = 1;                 break;
       }
     }while( !done && (c=(*++fmt))!=0 );
@@ -309,13 +310,11 @@ void sqlite3VXPrintf(
       flag_long = 1;
       c = *++fmt;
       if( c=='l' ){
-        flag_longlong = 1;
+        flag_long = 2;
         c = *++fmt;
-      }else{
-        flag_longlong = 0;
       }
     }else{
-      flag_long = flag_longlong = 0;
+      flag_long = 0;
     }
     /* Fetch the info entry for the field */
     infop = &fmtinfo[0];
@@ -333,15 +332,11 @@ void sqlite3VXPrintf(
     **
     **   flag_alternateform          TRUE if a '#' is present.
     **   flag_altform2               TRUE if a '!' is present.
-    **   flag_plussign               TRUE if a '+' is present.
+    **   flag_prefix                 '+' or ' ' or zero
     **   flag_leftjustify            TRUE if a '-' is present or if the
     **                               field width was negative.
     **   flag_zeropad                TRUE if the width began with 0.
-    **   flag_long                   TRUE if the letter 'l' (ell) prefixed
-    **                               the conversion character.
-    **   flag_longlong               TRUE if the letter 'll' (ell ell) prefixed
-    **                               the conversion character.
-    **   flag_blanksign              TRUE if a ' ' is present.
+    **   flag_long                   1 for "l", 2 for "ll"
     **   width                       The specified field width.  This is
     **                               always non-negative.  Zero is the default.
     **   precision                   The specified precision.  The default
@@ -351,19 +346,24 @@ void sqlite3VXPrintf(
     */
     switch( xtype ){
       case etPOINTER:
-        flag_longlong = sizeof(char*)==sizeof(i64);
-        flag_long = sizeof(char*)==sizeof(long int);
+        flag_long = sizeof(char*)==sizeof(i64) ? 2 :
+                     sizeof(char*)==sizeof(long int) ? 1 : 0;
         /* Fall through into the next case */
       case etORDINAL:
-      case etRADIX:
+      case etRADIX:      
+        cThousand = 0;
+        /* Fall through into the next case */
+      case etDECIMAL:
         if( infop->flags & FLAG_SIGNED ){
           i64 v;
           if( bArgList ){
             v = getIntArg(pArgList);
-          }else if( flag_longlong ){
-            v = va_arg(ap,i64);
           }else if( flag_long ){
-            v = va_arg(ap,long int);
+            if( flag_long==2 ){
+              v = va_arg(ap,i64) ;
+            }else{
+              v = va_arg(ap,long int);
+            }
           }else{
             v = va_arg(ap,int);
           }
@@ -376,17 +376,17 @@ void sqlite3VXPrintf(
             prefix = '-';
           }else{
             longvalue = v;
-            if( flag_plussign )        prefix = '+';
-            else if( flag_blanksign )  prefix = ' ';
-            else                       prefix = 0;
+            prefix = flag_prefix;
           }
         }else{
           if( bArgList ){
             longvalue = (u64)getIntArg(pArgList);
-          }else if( flag_longlong ){
-            longvalue = va_arg(ap,u64);
           }else if( flag_long ){
-            longvalue = va_arg(ap,unsigned long int);
+            if( flag_long==2 ){
+              longvalue = va_arg(ap,u64);
+            }else{
+              longvalue = va_arg(ap,unsigned long int);
+            }
           }else{
             longvalue = va_arg(ap,unsigned int);
           }
@@ -396,11 +396,11 @@ void sqlite3VXPrintf(
         if( flag_zeropad && precision<width-(prefix!=0) ){
           precision = width-(prefix!=0);
         }
-        if( precision<etBUFSIZE-10 ){
+        if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
           nOut = etBUFSIZE;
           zOut = buf;
         }else{
-          nOut = precision + 10;
+          nOut = precision + 10 + precision/3;
           zOut = zExtra = sqlite3Malloc( nOut );
           if( zOut==0 ){
             setStrAccumError(pAccum, STRACCUM_NOMEM);
@@ -426,8 +426,23 @@ void sqlite3VXPrintf(
           }while( longvalue>0 );
         }
         length = (int)(&zOut[nOut-1]-bufpt);
-        for(idx=precision-length; idx>0; idx--){
+        while( precision>length ){
           *(--bufpt) = '0';                             /* Zero pad */
+          length++;
+        }
+        if( cThousand ){
+          int nn = (length - 1)/3;  /* Number of "," to insert */
+          int ix = (length - 1)%3 + 1;
+          bufpt -= nn;
+          for(idx=0; nn>0; idx++){
+            bufpt[idx] = bufpt[idx+nn];
+            ix--;
+            if( ix==0 ){
+              bufpt[++idx] = cThousand;
+              nn--;
+              ix = 3;
+            }
+          }
         }
         if( prefix ) *(--bufpt) = prefix;               /* Add sign */
         if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
@@ -454,9 +469,7 @@ void sqlite3VXPrintf(
           realvalue = -realvalue;
           prefix = '-';
         }else{
-          if( flag_plussign )          prefix = '+';
-          else if( flag_blanksign )    prefix = ' ';
-          else                         prefix = 0;
+          prefix = flag_prefix;
         }
         if( xtype==etGENERIC && precision>0 ) precision--;
         testcase( precision>0xfff );
index fb031bd68fbde3b0c84ac0da662a4c68930e47c2..d30966d1679756f99377615e0eef295486b61e7f 100644 (file)
@@ -116,6 +116,37 @@ do_execsql_test printf2-3.5 {
   SELECT printf('|%7.8c|%-7.8c|','*','*');
 } {|********|********|}
 
+# The "," separator
+do_execsql_test printf2-4.1 {
+  SELECT printf('|%,d|%,d|',0,-1);
+} {|0|-1|}
+do_execsql_test printf2-4.2 {
+  SELECT printf('|%,d|%,d|',12,-12);
+} {|12|-12|}
+do_execsql_test printf2-4.3 {
+  SELECT printf('|%,d|%,d|',123,-123);
+} {|123|-123|}
+do_execsql_test printf2-4.4 {
+  SELECT printf('|%,d|%,d|',1234,-1234);
+} {|1,234|-1,234|}
+do_execsql_test printf2-4.5 {
+  SELECT printf('|%,d|%,d|',12345,-12345);
+} {|12,345|-12,345|}
+do_execsql_test printf2-4.6 {
+  SELECT printf('|%,d|%,d|',123456,-123456);
+} {|123,456|-123,456|}
+do_execsql_test printf2-4.7 {
+  SELECT printf('|%,d|%,d|',1234567,-1234567);
+} {|1,234,567|-1,234,567|}
+do_execsql_test printf2-4.8 {
+  SELECT printf('|%,d|%,d|',12345678,-12345678);
+} {|12,345,678|-12,345,678|}
+do_execsql_test printf2-4.9 {
+  SELECT printf('|%,d|%,d|',123456789,-123456789);
+} {|123,456,789|-123,456,789|}
+do_execsql_test printf2-4.10 {
+  SELECT printf('|%,d|%,d|',1234567890,-1234567890);
+} {|1,234,567,890|-1,234,567,890|}