Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix the %c format character in sqlite3VXPrintf() so that it correctly handles precisions larger than 70. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | branch-3.8.7 |
Files: | files | file ages | folders |
SHA1: | 839a6df9f98b90fb593534a62145d9c9 |
User & Date: | drh 2014-11-12 14:12:28 |
Context
2014-11-13
| ||
13:42 | When a transaction or savepoint rollback occurs, save the positions of all open read-cursors so that they can be restored following the rollback operation. Cherry-pick of check-in [dd03a2802f3f27] check-in: 402780a9 user: drh tags: branch-3.8.7 | |
2014-11-12
| ||
14:12 | Fix the %c format character in sqlite3VXPrintf() so that it correctly handles precisions larger than 70. check-in: 839a6df9 user: drh tags: branch-3.8.7 | |
14:07 | Make sure that NULL results from OP_Column are fully and completely NULL and do not have the MEM_Ephem bit set. Fix for ticket [094d39a4c95ee4]. check-in: e1017745 user: drh tags: branch-3.8.7 | |
2014-10-29
| ||
18:20 | Fix the %c format character in sqlite3VXPrintf() so that it correctly handles precisions larger than 70. check-in: 08a27440 user: drh tags: trunk | |
Changes
Changes to src/printf.c.
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 ... 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 ... 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 ... 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 ... 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 |
u8 useIntern; /* Ok to use internal conversions (ex: %T) */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ sqlite_uint64 longvalue; /* Value for integer types */ LONGDOUBLE_TYPE realvalue; /* Value for real types */ const et_info *infop; /* Pointer to the appropriate info structure */ char *zOut; /* Rendering buffer */ int nOut; /* Size of the rendering buffer */ char *zExtra; /* Malloced memory used by some conversion */ #ifndef SQLITE_OMIT_FLOATING_POINT int exp, e2; /* exponent of real numbers */ int nsd; /* Number of significant digits returned */ double rounder; /* Used for rounding floating point values */ etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ #endif ................................................................................ xtype = infop->type; }else{ return; } break; } } zExtra = 0; /* ** At this point, variables are initialized as follows: ** ** flag_alternateform TRUE if a '#' is present. ** flag_altform2 TRUE if a '!' is present. ** flag_plussign TRUE if a '+' is present. ................................................................................ case etCHARX: if( bArgList ){ bufpt = getTextArg(pArgList); c = bufpt ? bufpt[0] : 0; }else{ c = va_arg(ap,int); } buf[0] = (char)c; if( precision>=0 ){ for(idx=1; idx<precision; idx++) buf[idx] = (char)c; length = precision; }else{ length =1; } bufpt = buf; break; case etSTRING: case etDYNSTRING: if( bArgList ){ bufpt = getTextArg(pArgList); }else{ ................................................................................ }/* End switch over the format type */ /* ** The text of the conversion is pointed to by "bufpt" and is ** "length" characters long. The field width is "width". Do ** the output. */ width -= length; if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width); sqlite3StrAccumAppend(pAccum, bufpt, length); if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width); if( zExtra ) sqlite3_free(zExtra); }/* End for loop over the format string */ } /* End of function */ /* ** Enlarge the memory allocation on a StrAccum object so that it is ** able to accept at least N more bytes of text. ** ................................................................................ return 0; } } return N; } /* ** Append N space characters to the given string buffer. */ void sqlite3AppendSpace(StrAccum *p, int N){ if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return; while( (N--)>0 ) p->zText[p->nChar++] = ' '; } /* ** The StrAccum "p" is not large enough to accept N new bytes of z[]. ** So enlarge if first, then do the append. ** ** This is a helper routine to sqlite3StrAccumAppend() that does special-case |
| < | | | | | | | > > > | | > | > > | | | |
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 ... 325 326 327 328 329 330 331 332 333 334 335 336 337 338 ... 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 ... 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 ... 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 |
u8 useIntern; /* Ok to use internal conversions (ex: %T) */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ sqlite_uint64 longvalue; /* Value for integer types */ LONGDOUBLE_TYPE realvalue; /* Value for real types */ const et_info *infop; /* Pointer to the appropriate info structure */ char *zOut; /* Rendering buffer */ int nOut; /* Size of the rendering buffer */ char *zExtra = 0; /* Malloced memory used by some conversion */ #ifndef SQLITE_OMIT_FLOATING_POINT int exp, e2; /* exponent of real numbers */ int nsd; /* Number of significant digits returned */ double rounder; /* Used for rounding floating point values */ etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ #endif ................................................................................ xtype = infop->type; }else{ return; } break; } } /* ** At this point, variables are initialized as follows: ** ** flag_alternateform TRUE if a '#' is present. ** flag_altform2 TRUE if a '!' is present. ** flag_plussign TRUE if a '+' is present. ................................................................................ case etCHARX: if( bArgList ){ bufpt = getTextArg(pArgList); c = bufpt ? bufpt[0] : 0; }else{ c = va_arg(ap,int); } if( precision>1 ){ width -= precision-1; if( width>1 && !flag_leftjustify ){ sqlite3AppendChar(pAccum, width-1, ' '); width = 0; } sqlite3AppendChar(pAccum, precision-1, c); } length = 1; buf[0] = c; bufpt = buf; break; case etSTRING: case etDYNSTRING: if( bArgList ){ bufpt = getTextArg(pArgList); }else{ ................................................................................ }/* End switch over the format type */ /* ** The text of the conversion is pointed to by "bufpt" and is ** "length" characters long. The field width is "width". Do ** the output. */ width -= length; if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); sqlite3StrAccumAppend(pAccum, bufpt, length); if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); if( zExtra ){ sqlite3_free(zExtra); zExtra = 0; } }/* End for loop over the format string */ } /* End of function */ /* ** Enlarge the memory allocation on a StrAccum object so that it is ** able to accept at least N more bytes of text. ** ................................................................................ return 0; } } return N; } /* ** Append N copies of character c to the given string buffer. */ void sqlite3AppendChar(StrAccum *p, int N, char c){ if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return; while( (N--)>0 ) p->zText[p->nChar++] = c; } /* ** The StrAccum "p" is not large enough to accept N new bytes of z[]. ** So enlarge if first, then do the append. ** ** This is a helper routine to sqlite3StrAccumAppend() that does special-case |
Changes to src/sqliteInt.h.
3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 |
);
int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *);
void sqlite3StrAccumInit(StrAccum*, char*, int, int);
void sqlite3StrAccumAppend(StrAccum*,const char*,int);
void sqlite3StrAccumAppendAll(StrAccum*,const char*);
void sqlite3AppendSpace(StrAccum*,int);
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumReset(StrAccum*);
void sqlite3SelectDestInit(SelectDest*,int,int);
Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
void sqlite3BackupRestart(sqlite3_backup *);
void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
|
| |
3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 |
); int sqlite3ApiExit(sqlite3 *db, int); int sqlite3OpenTempDatabase(Parse *); void sqlite3StrAccumInit(StrAccum*, char*, int, int); void sqlite3StrAccumAppend(StrAccum*,const char*,int); void sqlite3StrAccumAppendAll(StrAccum*,const char*); void sqlite3AppendChar(StrAccum*,int,char); char *sqlite3StrAccumFinish(StrAccum*); void sqlite3StrAccumReset(StrAccum*); void sqlite3SelectDestInit(SelectDest*,int,int); Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); void sqlite3BackupRestart(sqlite3_backup *); void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); |
Changes to test/printf2.test.
90 91 92 93 94 95 96 97 98 99 |
# argument list, missing arguments are assumed to have a NULL value, # which is translated into 0 or 0.0 for numeric formats or an empty # string for %s. # do_execsql_test printf2-2.3 { SELECT printf('%s=(%d/%g/%s)',a) FROM t1 ORDER BY a; } {-1=(0/0/) 1=(0/0/) 1.5=(0/0/) abc=(0/0/)} finish_test |
> > > > > > > > > > > > > > > > > > > > |
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# argument list, missing arguments are assumed to have a NULL value, # which is translated into 0 or 0.0 for numeric formats or an empty # string for %s. # do_execsql_test printf2-2.3 { SELECT printf('%s=(%d/%g/%s)',a) FROM t1 ORDER BY a; } {-1=(0/0/) 1=(0/0/) 1.5=(0/0/) abc=(0/0/)} # The precision of the %c conversion causes the character to repeat. # do_execsql_test printf2-3.1 { SELECT printf('|%110.100c|','*'); } {{| ****************************************************************************************************|}} do_execsql_test printf2-3.2 { SELECT printf('|%-110.100c|','*'); } {{|**************************************************************************************************** |}} do_execsql_test printf2-3.3 { SELECT printf('|%9.8c|%-9.8c|','*','*'); } {{| ********|******** |}} do_execsql_test printf2-3.4 { SELECT printf('|%8.8c|%-8.8c|','*','*'); } {|********|********|} do_execsql_test printf2-3.5 { SELECT printf('|%7.8c|%-7.8c|','*','*'); } {|********|********|} finish_test |