Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Code cleanup in the date and time functions. (CVS 1263) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9b3bcde1530091602e551435ffd7820e |
User & Date: | drh 2004-02-22 17:49:33.000 |
Context
2004-02-22
| ||
18:40 | Use sqliteErrorMsg instead of sqliteSetString whereever practical. (CVS 1264) (check-in: 69aac043af user: drh tags: trunk) | |
17:49 | Code cleanup in the date and time functions. (CVS 1263) (check-in: 9b3bcde153 user: drh tags: trunk) | |
16:27 | Rearrange the grammar some so that tokens that are used together appear together in the grammar file. This reduces the size of the parser tables and some of the jump tables in switch statements. (CVS 1262) (check-in: d372c16ec6 user: drh tags: trunk) | |
Changes
Changes to src/date.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: date.c,v 1.12 2004/02/22 17:49:33 drh Exp $ ** ** NOTES: ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian ** calendar system. |
︙ | ︙ | |||
70 71 72 73 74 75 76 | char validHMS; /* True if h,m,s are valid */ char validJD; /* True if rJD is valid */ char validTZ; /* True if tz is valid */ }; /* | | > > | > > > > > > > | > | > > > > > > > > > > > > > > | | > > | | | > | > > > > > > < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | char validHMS; /* True if h,m,s are valid */ char validJD; /* True if rJD is valid */ char validTZ; /* True if tz is valid */ }; /* ** 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, ...){ 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( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){ return cnt; } *pVal = val; zDate++; cnt++; }while( nextC ); return cnt; } /* ** Read text from z[] and convert into a floating point number. Return ** the number of digits converted. */ static int getValue(const char *z, double *pR){ const char *zEnd; *pR = sqliteAtoF(z, &zEnd); return zEnd - z; } /* ** Parse a timezone extension on the end of a date-time. ** The extension is of the form: ** ** (+/-)HH:MM |
︙ | ︙ | |||
147 148 149 150 151 152 153 | sgn = -1; }else if( *zDate=='+' ){ sgn = +1; }else{ return *zDate!=0; } zDate++; | | < < | < < < > | | < < < | > | > | | > | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | sgn = -1; }else if( *zDate=='+' ){ sgn = +1; }else{ return *zDate!=0; } zDate++; 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; } /* ** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF. ** The HH, MM, and SS must each be exactly 2 digits. The ** fractional seconds FFFF can be one or more digits. ** ** Return 1 if there is a parsing error and 0 on success. */ static int parseHhMmSs(const char *zDate, DateTime *p){ int h, m, s; double ms = 0.0; if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){ return 1; } zDate += 5; if( *zDate==':' ){ zDate++; if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){ return 1; } zDate += 2; if( *zDate=='.' && isdigit(zDate[1]) ){ double rScale = 1.0; zDate++; while( isdigit(*zDate) ){ ms = ms*10.0 + *zDate - '0'; rScale *= 10.0; zDate++; |
︙ | ︙ | |||
264 265 266 267 268 269 270 | if( zDate[0]=='-' ){ zDate++; neg = 1; }else{ neg = 0; } | | < < < < < < | > | < | > | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | if( zDate[0]=='-' ){ zDate++; neg = 1; }else{ neg = 0; } 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( parseHhMmSs(zDate, p)==0 ){ /* We got the time */ }else if( *zDate==0 ){ p->validHMS = 0; }else{ return 1; } p->validJD = 0; p->validYMD = 1; |
︙ | ︙ | |||
323 324 325 326 327 328 329 | if( sqliteOsCurrentTime(&r)==0 ){ p->rJD = r; p->validJD = 1; return 0; } return 1; }else if( sqliteIsNumber(zDate) ){ | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | if( sqliteOsCurrentTime(&r)==0 ){ p->rJD = r; p->validJD = 1; return 0; } return 1; }else if( sqliteIsNumber(zDate) ){ p->rJD = sqliteAtoF(zDate, 0); p->validJD = 1; return 0; } return 1; } /* |
︙ | ︙ |
Changes to src/func.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: func.c,v 1.41 2004/02/22 17:49:34 drh Exp $ */ #include <ctype.h> #include <math.h> #include <stdlib.h> #include <assert.h> #include "sqliteInt.h" #include "os.h" |
︙ | ︙ | |||
143 144 145 146 147 148 149 | double r; char zBuf[100]; assert( argc==1 || argc==2 ); if( argv[0]==0 || (argc==2 && argv[1]==0) ) return; n = argc==2 ? atoi(argv[1]) : 0; if( n>30 ) n = 30; if( n<0 ) n = 0; | | | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | double r; char zBuf[100]; assert( argc==1 || argc==2 ); if( argv[0]==0 || (argc==2 && argv[1]==0) ) return; n = argc==2 ? atoi(argv[1]) : 0; if( n>30 ) n = 30; if( n<0 ) n = 0; r = sqliteAtoF(argv[0], 0); sprintf(zBuf,"%.*f",n,r); sqlite_set_result_string(context, zBuf, -1); } /* ** Implementation of the upper() and lower() SQL functions. */ |
︙ | ︙ | |||
404 405 406 407 408 409 410 | ** Routines used to compute the sum or average. */ static void sumStep(sqlite_func *context, int argc, const char **argv){ SumCtx *p; if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ | | | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 | ** Routines used to compute the sum or average. */ static void sumStep(sqlite_func *context, int argc, const char **argv){ SumCtx *p; if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ p->sum += sqliteAtoF(argv[0], 0); p->cnt++; } } static void sumFinalize(sqlite_func *context){ SumCtx *p; p = sqlite_aggregate_context(context, sizeof(*p)); sqlite_set_result_double(context, p ? p->sum : 0.0); |
︙ | ︙ | |||
442 443 444 445 446 447 448 | */ static void stdDevStep(sqlite_func *context, int argc, const char **argv){ StdDevCtx *p; double x; if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ | | | 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | */ static void stdDevStep(sqlite_func *context, int argc, const char **argv){ StdDevCtx *p; double x; if( argc<1 ) return; p = sqlite_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ x = sqliteAtoF(argv[0], 0); p->sum += x; p->sum2 += x*x; p->cnt++; } } static void stdDevFinalize(sqlite_func *context){ double rN = sqlite_aggregate_count(context); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.218 2004/02/22 17:49:34 drh Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "parse.h" #include "btree.h" #include <stdio.h> |
︙ | ︙ | |||
1253 1254 1255 1256 1257 1258 1259 | int mode, int nPg, Btree **ppBtree); int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqliteFixSrcList(DbFixer*, SrcList*); int sqliteFixSelect(DbFixer*, Select*); int sqliteFixExpr(DbFixer*, Expr*); int sqliteFixExprList(DbFixer*, ExprList*); int sqliteFixTriggerStep(DbFixer*, TriggerStep*); | | | 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 | int mode, int nPg, Btree **ppBtree); int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqliteFixSrcList(DbFixer*, SrcList*); int sqliteFixSelect(DbFixer*, Select*); int sqliteFixExpr(DbFixer*, Expr*); int sqliteFixExprList(DbFixer*, ExprList*); int sqliteFixTriggerStep(DbFixer*, TriggerStep*); double sqliteAtoF(const char *z, const char **); char *sqlite_snprintf(int,char*,const char*,...); int sqliteFitsIn32Bits(const char *); |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.36 2004/02/22 17:49:34 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
636 637 638 639 640 641 642 | sqlite_set_result_string(context, argv[1], -1); }else if( argv[1]==0 ){ sqlite_set_result_error(context, "2nd argument may not be NULL if the " "first argument is not \"string\"", -1); }else if( sqliteStrICmp(argv[0],"int")==0 ){ sqlite_set_result_int(context, atoi(argv[1])); }else if( sqliteStrICmp(argv[0],"double")==0 ){ | | | 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | sqlite_set_result_string(context, argv[1], -1); }else if( argv[1]==0 ){ sqlite_set_result_error(context, "2nd argument may not be NULL if the " "first argument is not \"string\"", -1); }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], 0)); }else{ sqlite_set_result_error(context,"first argument should be one of: " "string int double", -1); } argc -= 2; argv += 2; } |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.74 2004/02/22 17:49:34 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** If malloc() ever fails, this global variable gets set to 1. |
︙ | ︙ | |||
549 550 551 552 553 554 555 | ** is not, the result is undefined. ** ** This routine is used instead of the library atof() function because ** the library atof() might want to use "," as the decimal point instead ** of "." depending on how locale is set. But that would cause problems ** for SQL. So this routine always uses "." regardless of locale. */ | | | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | ** is not, the result is undefined. ** ** This routine is used instead of the library atof() function because ** the library atof() might want to use "," as the decimal point instead ** 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, const char **pzEnd){ int sign = 1; LONGDOUBLE_TYPE v1 = 0.0; if( *z=='-' ){ sign = -1; z++; }else if( *z=='+' ){ z++; |
︙ | ︙ | |||
597 598 599 600 601 602 603 604 605 606 607 608 609 610 | while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; } if( esign<0 ){ v1 /= scale; }else{ v1 *= scale; } } return sign<0 ? -v1 : v1; } /* ** The string zNum represents an integer. There might be some other ** information following the integer too, but that part is ignored. ** If the integer that the prefix of zNum represents will fit in a | > | 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; } if( esign<0 ){ v1 /= scale; }else{ v1 *= scale; } } if( pzEnd ) *pzEnd = z; return sign<0 ? -v1 : v1; } /* ** The string zNum represents an integer. There might be some other ** information following the integer too, but that part is ignored. ** If the integer that the prefix of zNum represents will fit in a |
︙ | ︙ | |||
646 647 648 649 650 651 652 | isNumA = sqliteIsNumber(atext); isNumB = sqliteIsNumber(btext); if( isNumA ){ if( !isNumB ){ result = -1; }else{ double rA, rB; | | | | 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 | isNumA = sqliteIsNumber(atext); isNumB = sqliteIsNumber(btext); if( isNumA ){ if( !isNumB ){ result = -1; }else{ double rA, rB; rA = sqliteAtoF(atext, 0); rB = sqliteAtoF(btext, 0); if( rA<rB ){ result = -1; }else if( rA>rB ){ result = +1; }else{ result = 0; } |
︙ | ︙ | |||
739 740 741 742 743 744 745 | isNumB = sqliteIsNumber(&b[1]); if( isNumA ){ double rA, rB; if( !isNumB ){ res = -1; break; } | | | | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | isNumB = sqliteIsNumber(&b[1]); if( isNumA ){ double rA, rB; if( !isNumB ){ res = -1; break; } rA = sqliteAtoF(&a[1], 0); rB = sqliteAtoF(&b[1], 0); if( rA<rB ){ res = -1; break; } if( rA>rB ){ res = +1; break; |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.267 2004/02/22 17:49:34 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
331 332 333 334 335 336 337 | ** ** Any prior string or integer representation is retained. ** NULLs are converted into 0.0. */ #define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); } static void hardRealify(Mem *pStack){ if( pStack->flags & MEM_Str ){ | | | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | ** ** Any prior string or integer representation is retained. ** NULLs are converted into 0.0. */ #define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); } static void hardRealify(Mem *pStack){ if( pStack->flags & MEM_Str ){ pStack->r = sqliteAtoF(pStack->z, 0); }else if( pStack->flags & MEM_Int ){ pStack->r = pStack->i; }else{ pStack->r = 0.0; } pStack->flags |= MEM_Real; } |
︙ | ︙ | |||
2035 2036 2037 2038 2039 2040 2041 | Stringify(pRec); pRec->flags &= ~(MEM_Int|MEM_Real); nByte += pRec->n+1; }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){ if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){ pRec->r = pRec->i; }else if( (flags & (MEM_Real|MEM_Int))==0 ){ | | | 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 | Stringify(pRec); pRec->flags &= ~(MEM_Int|MEM_Real); nByte += pRec->n+1; }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){ 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, 0); } Release(pRec); z = pRec->zShort; sqliteRealToSortable(pRec->r, z); len = strlen(z); pRec->z = 0; pRec->flags = MEM_Real; |
︙ | ︙ |