Add the "," flag to printf().
FossilOrigin-Name: 064445b12f99f76e9a12957be97edd520ab3ae27
This commit is contained in:
parent
a39284bfa8
commit
2c338a9d9a
14
manifest
14
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
|
||||
|
@ -1 +1 @@
|
||||
798fb9d70d2e5f95e64237b04d6692360133381a
|
||||
064445b12f99f76e9a12957be97edd520ab3ae27
|
97
src/printf.c
97
src/printf.c
@ -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 );
|
||||
|
@ -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|}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user