diff --git a/manifest b/manifest index 6cb46f2971..67df4a77ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rearrange\sthe\sgrammar\ssome\sso\sthat\stokens\sthat\sare\sused\stogether\sappear\ntogether\sin\sthe\sgrammar\sfile.\s\sThis\sreduces\sthe\ssize\sof\sthe\sparser\stables\nand\ssome\sof\sthe\sjump\stables\sin\sswitch\sstatements.\s(CVS\s1262) -D 2004-02-22T16:27:00 +C Code\scleanup\sin\sthe\sdate\sand\stime\sfunctions.\s(CVS\s1263) +D 2004-02-22T17:49:33 F Makefile.in cfd75c46b335881999333a9e4b982fa8491f200b F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -29,11 +29,11 @@ F src/btree.h 41cb3ff6ebc3f6da2d0a074e39ff8c7a2287469f F src/btree_rb.c 32b2cb4285c0fbd53b89de021637b63d52257e54 F src/build.c f6ef61a2b9524f5d1fd66a500747b6a5c114dd0f F src/copy.c 391ce142f6b1faa093867ecee134f61a5028a9af -F src/date.c 6120c591cd905799318018cc67df53e9bdfaef28 +F src/date.c 3025642cee50d5c41aef4a22cbc41aa7e543c922 F src/delete.c 8e2ff752bf485906effcc64f267cdd7227463567 F src/encode.c 9e70ea1e4e746f23f18180949e94f1bb1c2220d3 F src/expr.c 7bb3a1ffbf3233b663f017d5296a718156f1f5fb -F src/func.c 36504a3458a5501ce960c46c74ead32aab9b306a +F src/func.c a2265f29e6a286203c9dfeb835d9a50439617805 F src/hash.c 9b56ef3b291e25168f630d5643a4264ec011c70e F src/hash.h 3247573ab95b9dd90bcca0307a75d9a16da1ccc7 F src/insert.c ad2902c171d23b92e2b350db2da86e36062e044b @@ -50,19 +50,19 @@ F src/random.c 775913e0b7fbd6295d21f12a7bd35b46387c44b2 F src/select.c 9a41dace754f0dab5e991e402c05fa3c24d04f19 F src/shell.c c3d3404fa82bb0808444fda9884d1bb572fd18b9 F src/sqlite.h.in 64f016cd5ce190643a0f47760188fdf4e0b2227e -F src/sqliteInt.h de32ca5481b9ffc30c3ec0d9ff97b505eaa2f016 +F src/sqliteInt.h a3e8f422803abf1e6ba07e15ffe5070a50f8b5e5 F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895 F src/tclsqlite.c b84dafe3a8532ff534c36e96bd38880e4b9cedf3 -F src/test1.c bf07ff6666c97b3fb91732deba3d4e6373960259 +F src/test1.c 9aa62b89d420e6763b5e7ae89a47f6cf87370477 F src/test2.c 75819b0f2c63c6a0fd6995445881f2eb94036996 F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5 F src/test4.c dcbbbb382626fd466a7c46907f74db35fc8bad64 F src/tokenize.c 6676b946fd8825b67ab52140af4fdc57a70bda48 F src/trigger.c a9927b57c865b6f3df3fb5e40c9824d722660ded F src/update.c e6eed1a4a429cc28f57533365c72293794c904cf -F src/util.c 8fbed02d3d5d29d4b236772f779778599c911e21 +F src/util.c 122bc174f6c8c2eb6a9127d9f13c4c74f83b85e4 F src/vacuum.c d9e80c2b36ee1f623dbf1bdf3cedad24a23f87ac -F src/vdbe.c f14e8e2ef82cb8480394697c40644d70195598e5 +F src/vdbe.c af187d86cb1bcc1ead227245350d1693c28c77a2 F src/vdbe.h b1b22ffca48f593d375fd846c583679d49c2e5c9 F src/vdbeInt.h b40ff02ce39fd076e6ff3369e19c1bbfe1986682 F src/vdbeaux.c 88ebe3aa963478f3cee9fb6e3d8ca9db1bafacb2 @@ -189,7 +189,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P f36b122d9767fa9e6dc5bcce04b5606d67cad3d9 -R 376533278e07e4ce9f2dde354b5969cb +P d372c16ec6621dbab371bff7f1803ca096862984 +R 26dc1ce48ade981ea71375567947b9f1 U drh -Z b87ef4aa1ac83c5f79b5688ea16271fe +Z 69ec7e76ed86d8c90a49976c004def1a diff --git a/manifest.uuid b/manifest.uuid index 256c737f99..f74d9b4cf0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d372c16ec6621dbab371bff7f1803ca096862984 \ No newline at end of file +9b3bcde1530091602e551435ffd7820eb79727d5 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 3a4addc9e6..e7c438e619 100644 --- a/src/date.c +++ b/src/date.c @@ -16,7 +16,7 @@ ** sqliteRegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.11 2004/02/21 03:28:18 drh Exp $ +** $Id: date.c,v 1.12 2004/02/22 17:49:33 drh Exp $ ** ** NOTES: ** @@ -74,17 +74,50 @@ struct DateTime { /* -** Convert N digits from zDate into an integer. Return -** -1 if zDate does not begin with N digits. +** Convert zDate into one or more integers. Additional arguments +** come in groups of 5 as follows: +** +** N number of digits in the integer +** min minimum allowed value of the integer +** max maximum allowed value of the integer +** nextC first character after the integer +** pVal where to write the integers value. +** +** Conversions continue until one with nextC==0 is encountered. +** The function returns the number of successful conversions. */ -static int getDigits(const char *zDate, int N){ - int val = 0; - while( N-- ){ - if( !isdigit(*zDate) ) return -1; - val = val*10 + *zDate - '0'; +static int getDigits(const char *zDate, ...){ + va_list ap; + int val; + int N; + int min; + int max; + int nextC; + int *pVal; + int cnt = 0; + va_start(ap, zDate); + do{ + N = va_arg(ap, int); + min = va_arg(ap, int); + max = va_arg(ap, int); + nextC = va_arg(ap, int); + pVal = va_arg(ap, int*); + val = 0; + while( N-- ){ + if( !isdigit(*zDate) ){ + return cnt; + } + val = val*10 + *zDate - '0'; + zDate++; + } + if( valmax || (nextC!=0 && nextC!=*zDate) ){ + return cnt; + } + *pVal = val; zDate++; - } - return val; + cnt++; + }while( nextC ); + return cnt; } /* @@ -92,38 +125,9 @@ static int getDigits(const char *zDate, int N){ ** the number of digits converted. */ static int getValue(const char *z, double *pR){ - double r = 0.0; - double rDivide = 1.0; - int isNeg = 0; - int nChar = 0; - if( *z=='+' ){ - z++; - nChar++; - }else if( *z=='-' ){ - z++; - isNeg = 1; - nChar++; - } - if( !isdigit(*z) ) return 0; - while( isdigit(*z) ){ - r = r*10.0 + *z - '0'; - nChar++; - z++; - } - if( *z=='.' && isdigit(z[1]) ){ - z++; - nChar++; - while( isdigit(*z) ){ - r = r*10.0 + *z - '0'; - rDivide *= 10.0; - nChar++; - z++; - } - r /= rDivide; - } - if( *z!=0 && !isspace(*z) ) return 0; - *pR = isNeg ? -r : r; - return nChar; + const char *zEnd; + *pR = sqliteAtoF(z, &zEnd); + return zEnd - z; } /* @@ -151,14 +155,10 @@ static int parseTimezone(const char *zDate, DateTime *p){ return *zDate!=0; } zDate++; - nHr = getDigits(zDate, 2); - if( nHr<0 || nHr>14 ) return 1; - zDate += 2; - if( zDate[0]!=':' ) return 1; - zDate++; - nMn = getDigits(zDate, 2); - if( nMn<0 || nMn>59 ) return 1; - zDate += 2; + if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){ + return 1; + } + zDate += 5; p->tz = sgn*(nMn + nHr*60); while( isspace(*zDate) ){ zDate++; } return *zDate!=0; @@ -174,16 +174,16 @@ static int parseTimezone(const char *zDate, DateTime *p){ static int parseHhMmSs(const char *zDate, DateTime *p){ int h, m, s; double ms = 0.0; - h = getDigits(zDate, 2); - if( h<0 || zDate[2]!=':' ) return 1; - zDate += 3; - m = getDigits(zDate, 2); - if( m<0 || m>59 ) return 1; - zDate += 2; + if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){ + return 1; + } + zDate += 5; if( *zDate==':' ){ - s = getDigits(&zDate[1], 2); - if( s<0 || s>59 ) return 1; - zDate += 3; + zDate++; + if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){ + return 1; + } + zDate += 2; if( *zDate=='.' && isdigit(zDate[1]) ){ double rScale = 1.0; zDate++; @@ -268,18 +268,13 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ }else{ neg = 0; } - Y = getDigits(zDate, 4); - if( Y<0 || zDate[4]!='-' ) return 1; - zDate += 5; - M = getDigits(zDate, 2); - if( M<=0 || M>12 || zDate[2]!='-' ) return 1; - zDate += 3; - D = getDigits(zDate, 2); - if( D<=0 || D>31 ) return 1; - zDate += 2; + if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){ + return 1; + } + zDate += 10; while( isspace(*zDate) ){ zDate++; } - if( isdigit(*zDate) ){ - if( parseHhMmSs(zDate, p) ) return 1; + if( parseHhMmSs(zDate, p)==0 ){ + /* We got the time */ }else if( *zDate==0 ){ p->validHMS = 0; }else{ @@ -327,7 +322,7 @@ static int parseDateOrTime(const char *zDate, DateTime *p){ } return 1; }else if( sqliteIsNumber(zDate) ){ - p->rJD = sqliteAtoF(zDate); + p->rJD = sqliteAtoF(zDate, 0); p->validJD = 1; return 0; } diff --git a/src/func.c b/src/func.c index 2f30619de2..e5c1761e17 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.40 2004/02/20 22:53:39 rdc Exp $ +** $Id: func.c,v 1.41 2004/02/22 17:49:34 drh Exp $ */ #include #include @@ -147,7 +147,7 @@ static void roundFunc(sqlite_func *context, int argc, const char **argv){ n = argc==2 ? atoi(argv[1]) : 0; if( n>30 ) n = 30; if( n<0 ) n = 0; - r = sqliteAtoF(argv[0]); + r = sqliteAtoF(argv[0], 0); sprintf(zBuf,"%.*f",n,r); sqlite_set_result_string(context, zBuf, -1); } @@ -408,7 +408,7 @@ static void sumStep(sqlite_func *context, int argc, const char **argv){ if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ - p->sum += sqliteAtoF(argv[0]); + p->sum += sqliteAtoF(argv[0], 0); p->cnt++; } } @@ -446,7 +446,7 @@ static void stdDevStep(sqlite_func *context, int argc, const char **argv){ if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ - x = sqliteAtoF(argv[0]); + x = sqliteAtoF(argv[0], 0); p->sum += x; p->sum2 += x*x; p->cnt++; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2baeab5e97..a265e78c86 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.217 2004/02/21 19:02:30 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.218 2004/02/22 17:49:34 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -1257,6 +1257,6 @@ int sqliteFixSelect(DbFixer*, Select*); int sqliteFixExpr(DbFixer*, Expr*); int sqliteFixExprList(DbFixer*, ExprList*); int sqliteFixTriggerStep(DbFixer*, TriggerStep*); -double sqliteAtoF(const char *z); +double sqliteAtoF(const char *z, const char **); char *sqlite_snprintf(int,char*,const char*,...); int sqliteFitsIn32Bits(const char *); diff --git a/src/test1.c b/src/test1.c index e62c54db15..d17ebf255a 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.35 2004/02/21 19:41:04 drh Exp $ +** $Id: test1.c,v 1.36 2004/02/22 17:49:34 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -640,7 +640,7 @@ static void testFunc(sqlite_func *context, int argc, const char **argv){ }else if( sqliteStrICmp(argv[0],"int")==0 ){ sqlite_set_result_int(context, atoi(argv[1])); }else if( sqliteStrICmp(argv[0],"double")==0 ){ - sqlite_set_result_double(context, sqliteAtoF(argv[1])); + sqlite_set_result_double(context, sqliteAtoF(argv[1], 0)); }else{ sqlite_set_result_error(context,"first argument should be one of: " "string int double", -1); diff --git a/src/util.c b/src/util.c index fc1d26dfdf..16b3b46a05 100644 --- a/src/util.c +++ b/src/util.c @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.73 2004/02/21 19:02:31 drh Exp $ +** $Id: util.c,v 1.74 2004/02/22 17:49:34 drh Exp $ */ #include "sqliteInt.h" #include @@ -553,7 +553,7 @@ int sqliteIsNumber(const char *z){ ** of "." depending on how locale is set. But that would cause problems ** for SQL. So this routine always uses "." regardless of locale. */ -double sqliteAtoF(const char *z){ +double sqliteAtoF(const char *z, const char **pzEnd){ int sign = 1; LONGDOUBLE_TYPE v1 = 0.0; if( *z=='-' ){ @@ -601,6 +601,7 @@ double sqliteAtoF(const char *z){ v1 *= scale; } } + if( pzEnd ) *pzEnd = z; return sign<0 ? -v1 : v1; } @@ -650,8 +651,8 @@ int sqliteCompare(const char *atext, const char *btext){ result = -1; }else{ double rA, rB; - rA = sqliteAtoF(atext); - rB = sqliteAtoF(btext); + rA = sqliteAtoF(atext, 0); + rB = sqliteAtoF(btext, 0); if( rArB ){ @@ -743,8 +744,8 @@ int sqliteSortCompare(const char *a, const char *b){ res = -1; break; } - rA = sqliteAtoF(&a[1]); - rB = sqliteAtoF(&b[1]); + rA = sqliteAtoF(&a[1], 0); + rB = sqliteAtoF(&b[1], 0); if( rAflags&MEM_Real)==0){ hardRealify(P); } static void hardRealify(Mem *pStack){ if( pStack->flags & MEM_Str ){ - pStack->r = sqliteAtoF(pStack->z); + pStack->r = sqliteAtoF(pStack->z, 0); }else if( pStack->flags & MEM_Int ){ pStack->r = pStack->i; }else{ @@ -2039,7 +2039,7 @@ case OP_MakeKey: { if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){ pRec->r = pRec->i; }else if( (flags & (MEM_Real|MEM_Int))==0 ){ - pRec->r = sqliteAtoF(pRec->z); + pRec->r = sqliteAtoF(pRec->z, 0); } Release(pRec); z = pRec->zShort;