| [25] | 1 | /* | 
|---|
 | 2 |  * tclGetDate.y -- | 
|---|
 | 3 |  * | 
|---|
 | 4 |  *      Contains yacc grammar for parsing date and time strings. The output of | 
|---|
 | 5 |  *      this file should be the file tclDate.c which is used directly in the | 
|---|
 | 6 |  *      Tcl sources. Note that this file is largely obsolete in Tcl 8.5; it is | 
|---|
 | 7 |  *      only used when doing free-form date parsing, an ill-defined process | 
|---|
 | 8 |  *      anyway. | 
|---|
 | 9 |  * | 
|---|
 | 10 |  * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans. | 
|---|
 | 11 |  * Copyright (c) 1995-1997 Sun Microsystems, Inc. | 
|---|
 | 12 |  * | 
|---|
 | 13 |  * See the file "license.terms" for information on usage and redistribution of | 
|---|
 | 14 |  * this file, and for a DISCLAIMER OF ALL WARRANTIES. | 
|---|
 | 15 |  * | 
|---|
 | 16 |  * RCS: @(#) $Id: tclGetDate.y,v 1.38 2007/12/13 15:23:17 dgp Exp $ | 
|---|
 | 17 |  */ | 
|---|
 | 18 |  | 
|---|
 | 19 | %{ | 
|---|
 | 20 | /* | 
|---|
 | 21 |  * tclDate.c -- | 
|---|
 | 22 |  * | 
|---|
 | 23 |  *      This file is generated from a yacc grammar defined in the file | 
|---|
 | 24 |  *      tclGetDate.y. It should not be edited directly. | 
|---|
 | 25 |  * | 
|---|
 | 26 |  * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans. | 
|---|
 | 27 |  * Copyright (c) 1995-1997 Sun Microsystems, Inc. | 
|---|
 | 28 |  * | 
|---|
 | 29 |  * See the file "license.terms" for information on usage and redistribution of | 
|---|
 | 30 |  * this file, and for a DISCLAIMER OF ALL WARRANTIES. | 
|---|
 | 31 |  * | 
|---|
 | 32 |  */ | 
|---|
 | 33 |  | 
|---|
 | 34 | #include "tclInt.h" | 
|---|
 | 35 |  | 
|---|
 | 36 | /* | 
|---|
 | 37 |  * Bison generates several labels that happen to be unused. MS Visual C++ | 
|---|
 | 38 |  * doesn't like that, and complains. Tell it to shut up. | 
|---|
 | 39 |  */ | 
|---|
 | 40 |  | 
|---|
 | 41 | #ifdef _MSC_VER | 
|---|
 | 42 | #pragma warning( disable : 4102 ) | 
|---|
 | 43 | #endif /* _MSC_VER */ | 
|---|
 | 44 |  | 
|---|
 | 45 | /* | 
|---|
 | 46 |  * yyparse will accept a 'struct DateInfo' as its parameter; that's where the | 
|---|
 | 47 |  * parsed fields will be returned. | 
|---|
 | 48 |  */ | 
|---|
 | 49 |  | 
|---|
 | 50 | typedef struct DateInfo { | 
|---|
 | 51 |     time_t dateYear; | 
|---|
 | 52 |     time_t dateMonth; | 
|---|
 | 53 |     time_t dateDay; | 
|---|
 | 54 |     int dateHaveDate; | 
|---|
 | 55 |  | 
|---|
 | 56 |     time_t dateHour; | 
|---|
 | 57 |     time_t dateMinutes; | 
|---|
 | 58 |     time_t dateSeconds; | 
|---|
 | 59 |     int dateMeridian; | 
|---|
 | 60 |     int dateHaveTime; | 
|---|
 | 61 |  | 
|---|
 | 62 |     time_t dateTimezone; | 
|---|
 | 63 |     int dateDSTmode; | 
|---|
 | 64 |     int dateHaveZone; | 
|---|
 | 65 |  | 
|---|
 | 66 |     time_t dateRelMonth; | 
|---|
 | 67 |     time_t dateRelDay; | 
|---|
 | 68 |     time_t dateRelSeconds; | 
|---|
 | 69 |     int dateHaveRel; | 
|---|
 | 70 |  | 
|---|
 | 71 |     time_t dateMonthOrdinal; | 
|---|
 | 72 |     int dateHaveOrdinalMonth; | 
|---|
 | 73 |  | 
|---|
 | 74 |     time_t dateDayOrdinal; | 
|---|
 | 75 |     time_t dateDayNumber; | 
|---|
 | 76 |     int dateHaveDay; | 
|---|
 | 77 |  | 
|---|
 | 78 |     char *dateInput; | 
|---|
 | 79 |     time_t *dateRelPointer; | 
|---|
 | 80 |  | 
|---|
 | 81 |     int dateDigitCount; | 
|---|
 | 82 | } DateInfo; | 
|---|
 | 83 |  | 
|---|
 | 84 | #define YYPARSE_PARAM   info | 
|---|
 | 85 | #define YYLEX_PARAM     info | 
|---|
 | 86 |  | 
|---|
 | 87 | #define YYMALLOC        ckalloc | 
|---|
 | 88 | #define YYFREE(x)       (ckfree((void*) (x))) | 
|---|
 | 89 |  | 
|---|
 | 90 | #define yyDSTmode       (((DateInfo *) info)->dateDSTmode) | 
|---|
 | 91 | #define yyDayOrdinal    (((DateInfo *) info)->dateDayOrdinal) | 
|---|
 | 92 | #define yyDayNumber     (((DateInfo *) info)->dateDayNumber) | 
|---|
 | 93 | #define yyMonthOrdinal  (((DateInfo *) info)->dateMonthOrdinal) | 
|---|
 | 94 | #define yyHaveDate      (((DateInfo *) info)->dateHaveDate) | 
|---|
 | 95 | #define yyHaveDay       (((DateInfo *) info)->dateHaveDay) | 
|---|
 | 96 | #define yyHaveOrdinalMonth (((DateInfo *) info)->dateHaveOrdinalMonth) | 
|---|
 | 97 | #define yyHaveRel       (((DateInfo *) info)->dateHaveRel) | 
|---|
 | 98 | #define yyHaveTime      (((DateInfo *) info)->dateHaveTime) | 
|---|
 | 99 | #define yyHaveZone      (((DateInfo *) info)->dateHaveZone) | 
|---|
 | 100 | #define yyTimezone      (((DateInfo *) info)->dateTimezone) | 
|---|
 | 101 | #define yyDay           (((DateInfo *) info)->dateDay) | 
|---|
 | 102 | #define yyMonth         (((DateInfo *) info)->dateMonth) | 
|---|
 | 103 | #define yyYear          (((DateInfo *) info)->dateYear) | 
|---|
 | 104 | #define yyHour          (((DateInfo *) info)->dateHour) | 
|---|
 | 105 | #define yyMinutes       (((DateInfo *) info)->dateMinutes) | 
|---|
 | 106 | #define yySeconds       (((DateInfo *) info)->dateSeconds) | 
|---|
 | 107 | #define yyMeridian      (((DateInfo *) info)->dateMeridian) | 
|---|
 | 108 | #define yyRelMonth      (((DateInfo *) info)->dateRelMonth) | 
|---|
 | 109 | #define yyRelDay        (((DateInfo *) info)->dateRelDay) | 
|---|
 | 110 | #define yyRelSeconds    (((DateInfo *) info)->dateRelSeconds) | 
|---|
 | 111 | #define yyRelPointer    (((DateInfo *) info)->dateRelPointer) | 
|---|
 | 112 | #define yyInput         (((DateInfo *) info)->dateInput) | 
|---|
 | 113 | #define yyDigitCount    (((DateInfo *) info)->dateDigitCount) | 
|---|
 | 114 |  | 
|---|
 | 115 | #define EPOCH           1970 | 
|---|
 | 116 | #define START_OF_TIME   1902 | 
|---|
 | 117 | #define END_OF_TIME     2037 | 
|---|
 | 118 |  | 
|---|
 | 119 | /* | 
|---|
 | 120 |  * The offset of tm_year of struct tm returned by localtime, gmtime, etc. | 
|---|
 | 121 |  * Posix requires 1900. | 
|---|
 | 122 |  */ | 
|---|
 | 123 |  | 
|---|
 | 124 | #define TM_YEAR_BASE    1900 | 
|---|
 | 125 |  | 
|---|
 | 126 | #define HOUR(x)         ((int) (60 * x)) | 
|---|
 | 127 | #define SECSPERDAY      (24L * 60L * 60L) | 
|---|
 | 128 | #define IsLeapYear(x)   ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0)) | 
|---|
 | 129 |  | 
|---|
 | 130 | /* | 
|---|
 | 131 |  * An entry in the lexical lookup table. | 
|---|
 | 132 |  */ | 
|---|
 | 133 |  | 
|---|
 | 134 | typedef struct _TABLE { | 
|---|
 | 135 |     char *name; | 
|---|
 | 136 |     int type; | 
|---|
 | 137 |     time_t value; | 
|---|
 | 138 | } TABLE; | 
|---|
 | 139 |  | 
|---|
 | 140 | /* | 
|---|
 | 141 |  * Daylight-savings mode: on, off, or not yet known. | 
|---|
 | 142 |  */ | 
|---|
 | 143 |  | 
|---|
 | 144 | typedef enum _DSTMODE { | 
|---|
 | 145 |     DSTon, DSToff, DSTmaybe | 
|---|
 | 146 | } DSTMODE; | 
|---|
 | 147 |  | 
|---|
 | 148 | /* | 
|---|
 | 149 |  * Meridian: am, pm, or 24-hour style. | 
|---|
 | 150 |  */ | 
|---|
 | 151 |  | 
|---|
 | 152 | typedef enum _MERIDIAN { | 
|---|
 | 153 |     MERam, MERpm, MER24 | 
|---|
 | 154 | } MERIDIAN; | 
|---|
 | 155 |  | 
|---|
 | 156 | /* | 
|---|
 | 157 |  * Prototypes of internal functions. | 
|---|
 | 158 |  */ | 
|---|
 | 159 |  | 
|---|
 | 160 | static int              LookupWord(char *buff); | 
|---|
 | 161 | static void             TclDateerror(char *s); | 
|---|
 | 162 | static int              TclDatelex(void *info); | 
|---|
 | 163 | static time_t           ToSeconds(time_t Hours, time_t Minutes, | 
|---|
 | 164 |                             time_t Seconds, MERIDIAN Meridian); | 
|---|
 | 165 | MODULE_SCOPE int        yyparse(void *); | 
|---|
 | 166 |  | 
|---|
 | 167 | %} | 
|---|
 | 168 |  | 
|---|
 | 169 | %union { | 
|---|
 | 170 |     time_t Number; | 
|---|
 | 171 |     enum _MERIDIAN Meridian; | 
|---|
 | 172 | } | 
|---|
 | 173 |  | 
|---|
 | 174 | %token  tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT | 
|---|
 | 175 | %token  tSTARDATE tSEC_UNIT tSNUMBER tUNUMBER tZONE tEPOCH tDST tISOBASE | 
|---|
 | 176 | %token  tDAY_UNIT tNEXT | 
|---|
 | 177 |  | 
|---|
 | 178 | %type   <Number>        tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT tDST | 
|---|
 | 179 | %type   <Number>        tSEC_UNIT tSNUMBER tUNUMBER tZONE tISOBASE tDAY_UNIT | 
|---|
 | 180 | %type   <Number>        unit sign tNEXT tSTARDATE | 
|---|
 | 181 | %type   <Meridian>      tMERIDIAN o_merid | 
|---|
 | 182 |  | 
|---|
 | 183 | %% | 
|---|
 | 184 |  | 
|---|
 | 185 | spec    : /* NULL */ | 
|---|
 | 186 |         | spec item | 
|---|
 | 187 |         ; | 
|---|
 | 188 |  | 
|---|
 | 189 | item    : time { | 
|---|
 | 190 |             yyHaveTime++; | 
|---|
 | 191 |         } | 
|---|
 | 192 |         | zone { | 
|---|
 | 193 |             yyHaveZone++; | 
|---|
 | 194 |         } | 
|---|
 | 195 |         | date { | 
|---|
 | 196 |             yyHaveDate++; | 
|---|
 | 197 |         } | 
|---|
 | 198 |         | ordMonth { | 
|---|
 | 199 |             yyHaveOrdinalMonth++; | 
|---|
 | 200 |         } | 
|---|
 | 201 |         | day { | 
|---|
 | 202 |             yyHaveDay++; | 
|---|
 | 203 |         } | 
|---|
 | 204 |         | relspec { | 
|---|
 | 205 |             yyHaveRel++; | 
|---|
 | 206 |         } | 
|---|
 | 207 |         | iso { | 
|---|
 | 208 |             yyHaveTime++; | 
|---|
 | 209 |             yyHaveDate++; | 
|---|
 | 210 |         } | 
|---|
 | 211 |         | trek { | 
|---|
 | 212 |             yyHaveTime++; | 
|---|
 | 213 |             yyHaveDate++; | 
|---|
 | 214 |             yyHaveRel++; | 
|---|
 | 215 |         } | 
|---|
 | 216 |         | number | 
|---|
 | 217 |         ; | 
|---|
 | 218 |  | 
|---|
 | 219 | time    : tUNUMBER tMERIDIAN { | 
|---|
 | 220 |             yyHour = $1; | 
|---|
 | 221 |             yyMinutes = 0; | 
|---|
 | 222 |             yySeconds = 0; | 
|---|
 | 223 |             yyMeridian = $2; | 
|---|
 | 224 |         } | 
|---|
 | 225 |         | tUNUMBER ':' tUNUMBER o_merid { | 
|---|
 | 226 |             yyHour = $1; | 
|---|
 | 227 |             yyMinutes = $3; | 
|---|
 | 228 |             yySeconds = 0; | 
|---|
 | 229 |             yyMeridian = $4; | 
|---|
 | 230 |         } | 
|---|
 | 231 |         | tUNUMBER ':' tUNUMBER '-' tUNUMBER { | 
|---|
 | 232 |             yyHour = $1; | 
|---|
 | 233 |             yyMinutes = $3; | 
|---|
 | 234 |             yyMeridian = MER24; | 
|---|
 | 235 |             yyDSTmode = DSToff; | 
|---|
 | 236 |             yyTimezone = ($5 % 100 + ($5 / 100) * 60); | 
|---|
 | 237 |             ++yyHaveZone; | 
|---|
 | 238 |         } | 
|---|
 | 239 |         | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid { | 
|---|
 | 240 |             yyHour = $1; | 
|---|
 | 241 |             yyMinutes = $3; | 
|---|
 | 242 |             yySeconds = $5; | 
|---|
 | 243 |             yyMeridian = $6; | 
|---|
 | 244 |         } | 
|---|
 | 245 |         | tUNUMBER ':' tUNUMBER ':' tUNUMBER '-' tUNUMBER { | 
|---|
 | 246 |             yyHour = $1; | 
|---|
 | 247 |             yyMinutes = $3; | 
|---|
 | 248 |             yySeconds = $5; | 
|---|
 | 249 |             yyMeridian = MER24; | 
|---|
 | 250 |             yyDSTmode = DSToff; | 
|---|
 | 251 |             yyTimezone = ($7 % 100 + ($7 / 100) * 60); | 
|---|
 | 252 |             ++yyHaveZone; | 
|---|
 | 253 |         } | 
|---|
 | 254 |         ; | 
|---|
 | 255 |  | 
|---|
 | 256 | zone    : tZONE tDST { | 
|---|
 | 257 |             yyTimezone = $1; | 
|---|
 | 258 |             yyDSTmode = DSTon; | 
|---|
 | 259 |         } | 
|---|
 | 260 |         | tZONE { | 
|---|
 | 261 |             yyTimezone = $1; | 
|---|
 | 262 |             yyDSTmode = DSToff; | 
|---|
 | 263 |         } | 
|---|
 | 264 |         | tDAYZONE { | 
|---|
 | 265 |             yyTimezone = $1; | 
|---|
 | 266 |             yyDSTmode = DSTon; | 
|---|
 | 267 |         } | 
|---|
 | 268 |         ; | 
|---|
 | 269 |  | 
|---|
 | 270 | day     : tDAY { | 
|---|
 | 271 |             yyDayOrdinal = 1; | 
|---|
 | 272 |             yyDayNumber = $1; | 
|---|
 | 273 |         } | 
|---|
 | 274 |         | tDAY ',' { | 
|---|
 | 275 |             yyDayOrdinal = 1; | 
|---|
 | 276 |             yyDayNumber = $1; | 
|---|
 | 277 |         } | 
|---|
 | 278 |         | tUNUMBER tDAY { | 
|---|
 | 279 |             yyDayOrdinal = $1; | 
|---|
 | 280 |             yyDayNumber = $2; | 
|---|
 | 281 |         } | 
|---|
 | 282 |         | sign tUNUMBER tDAY { | 
|---|
 | 283 |             yyDayOrdinal = $1 * $2; | 
|---|
 | 284 |             yyDayNumber = $3; | 
|---|
 | 285 |         } | 
|---|
 | 286 |         | tNEXT tDAY { | 
|---|
 | 287 |             yyDayOrdinal = 2; | 
|---|
 | 288 |             yyDayNumber = $2; | 
|---|
 | 289 |         } | 
|---|
 | 290 |         ; | 
|---|
 | 291 |  | 
|---|
 | 292 | date    : tUNUMBER '/' tUNUMBER { | 
|---|
 | 293 |             yyMonth = $1; | 
|---|
 | 294 |             yyDay = $3; | 
|---|
 | 295 |         } | 
|---|
 | 296 |         | tUNUMBER '/' tUNUMBER '/' tUNUMBER { | 
|---|
 | 297 |             yyMonth = $1; | 
|---|
 | 298 |             yyDay = $3; | 
|---|
 | 299 |             yyYear = $5; | 
|---|
 | 300 |         } | 
|---|
 | 301 |         | tISOBASE { | 
|---|
 | 302 |             yyYear = $1 / 10000; | 
|---|
 | 303 |             yyMonth = ($1 % 10000)/100; | 
|---|
 | 304 |             yyDay = $1 % 100; | 
|---|
 | 305 |         } | 
|---|
 | 306 |         | tUNUMBER '-' tMONTH '-' tUNUMBER { | 
|---|
 | 307 |             yyDay = $1; | 
|---|
 | 308 |             yyMonth = $3; | 
|---|
 | 309 |             yyYear = $5; | 
|---|
 | 310 |         } | 
|---|
 | 311 |         | tUNUMBER '-' tUNUMBER '-' tUNUMBER { | 
|---|
 | 312 |             yyMonth = $3; | 
|---|
 | 313 |             yyDay = $5; | 
|---|
 | 314 |             yyYear = $1; | 
|---|
 | 315 |         } | 
|---|
 | 316 |         | tMONTH tUNUMBER { | 
|---|
 | 317 |             yyMonth = $1; | 
|---|
 | 318 |             yyDay = $2; | 
|---|
 | 319 |         } | 
|---|
 | 320 |         | tMONTH tUNUMBER ',' tUNUMBER { | 
|---|
 | 321 |             yyMonth = $1; | 
|---|
 | 322 |             yyDay = $2; | 
|---|
 | 323 |             yyYear = $4; | 
|---|
 | 324 |         } | 
|---|
 | 325 |         | tUNUMBER tMONTH { | 
|---|
 | 326 |             yyMonth = $2; | 
|---|
 | 327 |             yyDay = $1; | 
|---|
 | 328 |         } | 
|---|
 | 329 |         | tEPOCH { | 
|---|
 | 330 |             yyMonth = 1; | 
|---|
 | 331 |             yyDay = 1; | 
|---|
 | 332 |             yyYear = EPOCH; | 
|---|
 | 333 |         } | 
|---|
 | 334 |         | tUNUMBER tMONTH tUNUMBER { | 
|---|
 | 335 |             yyMonth = $2; | 
|---|
 | 336 |             yyDay = $1; | 
|---|
 | 337 |             yyYear = $3; | 
|---|
 | 338 |         } | 
|---|
 | 339 |         ; | 
|---|
 | 340 |  | 
|---|
 | 341 | ordMonth: tNEXT tMONTH { | 
|---|
 | 342 |             yyMonthOrdinal = 1; | 
|---|
 | 343 |             yyMonth = $2; | 
|---|
 | 344 |         } | 
|---|
 | 345 |         | tNEXT tUNUMBER tMONTH { | 
|---|
 | 346 |             yyMonthOrdinal = $2; | 
|---|
 | 347 |             yyMonth = $3; | 
|---|
 | 348 |         } | 
|---|
 | 349 |         ; | 
|---|
 | 350 |  | 
|---|
 | 351 | iso     : tISOBASE tZONE tISOBASE { | 
|---|
 | 352 |             if ($2 != HOUR( 7)) YYABORT; | 
|---|
 | 353 |             yyYear = $1 / 10000; | 
|---|
 | 354 |             yyMonth = ($1 % 10000)/100; | 
|---|
 | 355 |             yyDay = $1 % 100; | 
|---|
 | 356 |             yyHour = $3 / 10000; | 
|---|
 | 357 |             yyMinutes = ($3 % 10000)/100; | 
|---|
 | 358 |             yySeconds = $3 % 100; | 
|---|
 | 359 |         } | 
|---|
 | 360 |         | tISOBASE tZONE tUNUMBER ':' tUNUMBER ':' tUNUMBER { | 
|---|
 | 361 |             if ($2 != HOUR( 7)) YYABORT; | 
|---|
 | 362 |             yyYear = $1 / 10000; | 
|---|
 | 363 |             yyMonth = ($1 % 10000)/100; | 
|---|
 | 364 |             yyDay = $1 % 100; | 
|---|
 | 365 |             yyHour = $3; | 
|---|
 | 366 |             yyMinutes = $5; | 
|---|
 | 367 |             yySeconds = $7; | 
|---|
 | 368 |         } | 
|---|
 | 369 |         | tISOBASE tISOBASE { | 
|---|
 | 370 |             yyYear = $1 / 10000; | 
|---|
 | 371 |             yyMonth = ($1 % 10000)/100; | 
|---|
 | 372 |             yyDay = $1 % 100; | 
|---|
 | 373 |             yyHour = $2 / 10000; | 
|---|
 | 374 |             yyMinutes = ($2 % 10000)/100; | 
|---|
 | 375 |             yySeconds = $2 % 100; | 
|---|
 | 376 |         } | 
|---|
 | 377 |         ; | 
|---|
 | 378 |  | 
|---|
 | 379 | trek    : tSTARDATE tUNUMBER '.' tUNUMBER { | 
|---|
 | 380 |             /* | 
|---|
 | 381 |              * Offset computed year by -377 so that the returned years will be | 
|---|
 | 382 |              * in a range accessible with a 32 bit clock seconds value. | 
|---|
 | 383 |              */ | 
|---|
 | 384 |  | 
|---|
 | 385 |             yyYear = $2/1000 + 2323 - 377; | 
|---|
 | 386 |             yyDay  = 1; | 
|---|
 | 387 |             yyMonth = 1; | 
|---|
 | 388 |             yyRelDay += (($2%1000)*(365 + IsLeapYear(yyYear)))/1000; | 
|---|
 | 389 |             yyRelSeconds += $4 * 144 * 60; | 
|---|
 | 390 |         } | 
|---|
 | 391 |         ; | 
|---|
 | 392 |  | 
|---|
 | 393 | relspec : relunits tAGO { | 
|---|
 | 394 |             yyRelSeconds *= -1; | 
|---|
 | 395 |             yyRelMonth *= -1; | 
|---|
 | 396 |             yyRelDay *= -1; | 
|---|
 | 397 |         } | 
|---|
 | 398 |         | relunits | 
|---|
 | 399 |         ; | 
|---|
 | 400 |  | 
|---|
 | 401 | relunits : sign tUNUMBER unit { | 
|---|
 | 402 |             *yyRelPointer += $1 * $2 * $3; | 
|---|
 | 403 |         } | 
|---|
 | 404 |         | tUNUMBER unit { | 
|---|
 | 405 |             *yyRelPointer += $1 * $2; | 
|---|
 | 406 |         } | 
|---|
 | 407 |         | tNEXT unit { | 
|---|
 | 408 |             *yyRelPointer += $2; | 
|---|
 | 409 |         } | 
|---|
 | 410 |         | tNEXT tUNUMBER unit { | 
|---|
 | 411 |             *yyRelPointer += $2 * $3; | 
|---|
 | 412 |         } | 
|---|
 | 413 |         | unit { | 
|---|
 | 414 |             *yyRelPointer += $1; | 
|---|
 | 415 |         } | 
|---|
 | 416 |         ; | 
|---|
 | 417 |  | 
|---|
 | 418 | sign    : '-' { | 
|---|
 | 419 |             $$ = -1; | 
|---|
 | 420 |         } | 
|---|
 | 421 |         | '+' { | 
|---|
 | 422 |             $$ =  1; | 
|---|
 | 423 |         } | 
|---|
 | 424 |         ; | 
|---|
 | 425 |  | 
|---|
 | 426 | unit    : tSEC_UNIT { | 
|---|
 | 427 |             $$ = $1; | 
|---|
 | 428 |             yyRelPointer = &yyRelSeconds; | 
|---|
 | 429 |         } | 
|---|
 | 430 |         | tDAY_UNIT { | 
|---|
 | 431 |             $$ = $1; | 
|---|
 | 432 |             yyRelPointer = &yyRelDay; | 
|---|
 | 433 |         } | 
|---|
 | 434 |         | tMONTH_UNIT { | 
|---|
 | 435 |             $$ = $1; | 
|---|
 | 436 |             yyRelPointer = &yyRelMonth; | 
|---|
 | 437 |         } | 
|---|
 | 438 |         ; | 
|---|
 | 439 |  | 
|---|
 | 440 | number  : tUNUMBER { | 
|---|
 | 441 |             if (yyHaveTime && yyHaveDate && !yyHaveRel) { | 
|---|
 | 442 |                 yyYear = $1; | 
|---|
 | 443 |             } else { | 
|---|
 | 444 |                 yyHaveTime++; | 
|---|
 | 445 |                 if (yyDigitCount <= 2) { | 
|---|
 | 446 |                     yyHour = $1; | 
|---|
 | 447 |                     yyMinutes = 0; | 
|---|
 | 448 |                 } else { | 
|---|
 | 449 |                     yyHour = $1 / 100; | 
|---|
 | 450 |                     yyMinutes = $1 % 100; | 
|---|
 | 451 |                 } | 
|---|
 | 452 |                 yySeconds = 0; | 
|---|
 | 453 |                 yyMeridian = MER24; | 
|---|
 | 454 |             } | 
|---|
 | 455 |         } | 
|---|
 | 456 |         ; | 
|---|
 | 457 |  | 
|---|
 | 458 | o_merid : /* NULL */ { | 
|---|
 | 459 |             $$ = MER24; | 
|---|
 | 460 |         } | 
|---|
 | 461 |         | tMERIDIAN { | 
|---|
 | 462 |             $$ = $1; | 
|---|
 | 463 |         } | 
|---|
 | 464 |         ; | 
|---|
 | 465 |  | 
|---|
 | 466 | %% | 
|---|
 | 467 | MODULE_SCOPE int yychar; | 
|---|
 | 468 | MODULE_SCOPE YYSTYPE yylval; | 
|---|
 | 469 | MODULE_SCOPE int yynerrs; | 
|---|
 | 470 |  | 
|---|
 | 471 | /* | 
|---|
 | 472 |  * Month and day table. | 
|---|
 | 473 |  */ | 
|---|
 | 474 |  | 
|---|
 | 475 | static TABLE MonthDayTable[] = { | 
|---|
 | 476 |     { "january",        tMONTH,  1 }, | 
|---|
 | 477 |     { "february",       tMONTH,  2 }, | 
|---|
 | 478 |     { "march",          tMONTH,  3 }, | 
|---|
 | 479 |     { "april",          tMONTH,  4 }, | 
|---|
 | 480 |     { "may",            tMONTH,  5 }, | 
|---|
 | 481 |     { "june",           tMONTH,  6 }, | 
|---|
 | 482 |     { "july",           tMONTH,  7 }, | 
|---|
 | 483 |     { "august",         tMONTH,  8 }, | 
|---|
 | 484 |     { "september",      tMONTH,  9 }, | 
|---|
 | 485 |     { "sept",           tMONTH,  9 }, | 
|---|
 | 486 |     { "october",        tMONTH, 10 }, | 
|---|
 | 487 |     { "november",       tMONTH, 11 }, | 
|---|
 | 488 |     { "december",       tMONTH, 12 }, | 
|---|
 | 489 |     { "sunday",         tDAY, 0 }, | 
|---|
 | 490 |     { "monday",         tDAY, 1 }, | 
|---|
 | 491 |     { "tuesday",        tDAY, 2 }, | 
|---|
 | 492 |     { "tues",           tDAY, 2 }, | 
|---|
 | 493 |     { "wednesday",      tDAY, 3 }, | 
|---|
 | 494 |     { "wednes",         tDAY, 3 }, | 
|---|
 | 495 |     { "thursday",       tDAY, 4 }, | 
|---|
 | 496 |     { "thur",           tDAY, 4 }, | 
|---|
 | 497 |     { "thurs",          tDAY, 4 }, | 
|---|
 | 498 |     { "friday",         tDAY, 5 }, | 
|---|
 | 499 |     { "saturday",       tDAY, 6 }, | 
|---|
 | 500 |     { NULL } | 
|---|
 | 501 | }; | 
|---|
 | 502 |  | 
|---|
 | 503 | /* | 
|---|
 | 504 |  * Time units table. | 
|---|
 | 505 |  */ | 
|---|
 | 506 |  | 
|---|
 | 507 | static TABLE UnitsTable[] = { | 
|---|
 | 508 |     { "year",           tMONTH_UNIT,    12 }, | 
|---|
 | 509 |     { "month",          tMONTH_UNIT,     1 }, | 
|---|
 | 510 |     { "fortnight",      tDAY_UNIT,      14 }, | 
|---|
 | 511 |     { "week",           tDAY_UNIT,       7 }, | 
|---|
 | 512 |     { "day",            tDAY_UNIT,       1 }, | 
|---|
 | 513 |     { "hour",           tSEC_UNIT, 60 * 60 }, | 
|---|
 | 514 |     { "minute",         tSEC_UNIT,      60 }, | 
|---|
 | 515 |     { "min",            tSEC_UNIT,      60 }, | 
|---|
 | 516 |     { "second",         tSEC_UNIT,       1 }, | 
|---|
 | 517 |     { "sec",            tSEC_UNIT,       1 }, | 
|---|
 | 518 |     { NULL } | 
|---|
 | 519 | }; | 
|---|
 | 520 |  | 
|---|
 | 521 | /* | 
|---|
 | 522 |  * Assorted relative-time words. | 
|---|
 | 523 |  */ | 
|---|
 | 524 |  | 
|---|
 | 525 | static TABLE OtherTable[] = { | 
|---|
 | 526 |     { "tomorrow",       tDAY_UNIT,      1 }, | 
|---|
 | 527 |     { "yesterday",      tDAY_UNIT,      -1 }, | 
|---|
 | 528 |     { "today",          tDAY_UNIT,      0 }, | 
|---|
 | 529 |     { "now",            tSEC_UNIT,      0 }, | 
|---|
 | 530 |     { "last",           tUNUMBER,       -1 }, | 
|---|
 | 531 |     { "this",           tSEC_UNIT,      0 }, | 
|---|
 | 532 |     { "next",           tNEXT,          1 }, | 
|---|
 | 533 | #if 0 | 
|---|
 | 534 |     { "first",          tUNUMBER,       1 }, | 
|---|
 | 535 |     { "second",         tUNUMBER,       2 }, | 
|---|
 | 536 |     { "third",          tUNUMBER,       3 }, | 
|---|
 | 537 |     { "fourth",         tUNUMBER,       4 }, | 
|---|
 | 538 |     { "fifth",          tUNUMBER,       5 }, | 
|---|
 | 539 |     { "sixth",          tUNUMBER,       6 }, | 
|---|
 | 540 |     { "seventh",        tUNUMBER,       7 }, | 
|---|
 | 541 |     { "eighth",         tUNUMBER,       8 }, | 
|---|
 | 542 |     { "ninth",          tUNUMBER,       9 }, | 
|---|
 | 543 |     { "tenth",          tUNUMBER,       10 }, | 
|---|
 | 544 |     { "eleventh",       tUNUMBER,       11 }, | 
|---|
 | 545 |     { "twelfth",        tUNUMBER,       12 }, | 
|---|
 | 546 | #endif | 
|---|
 | 547 |     { "ago",            tAGO,           1 }, | 
|---|
 | 548 |     { "epoch",          tEPOCH,         0 }, | 
|---|
 | 549 |     { "stardate",       tSTARDATE,      0 }, | 
|---|
 | 550 |     { NULL } | 
|---|
 | 551 | }; | 
|---|
 | 552 |  | 
|---|
 | 553 | /* | 
|---|
 | 554 |  * The timezone table. (Note: This table was modified to not use any floating | 
|---|
 | 555 |  * point constants to work around an SGI compiler bug). | 
|---|
 | 556 |  */ | 
|---|
 | 557 |  | 
|---|
 | 558 | static TABLE TimezoneTable[] = { | 
|---|
 | 559 |     { "gmt",    tZONE,     HOUR( 0) },      /* Greenwich Mean */ | 
|---|
 | 560 |     { "ut",     tZONE,     HOUR( 0) },      /* Universal (Coordinated) */ | 
|---|
 | 561 |     { "utc",    tZONE,     HOUR( 0) }, | 
|---|
 | 562 |     { "uct",    tZONE,     HOUR( 0) },      /* Universal Coordinated Time */ | 
|---|
 | 563 |     { "wet",    tZONE,     HOUR( 0) },      /* Western European */ | 
|---|
 | 564 |     { "bst",    tDAYZONE,  HOUR( 0) },      /* British Summer */ | 
|---|
 | 565 |     { "wat",    tZONE,     HOUR( 1) },      /* West Africa */ | 
|---|
 | 566 |     { "at",     tZONE,     HOUR( 2) },      /* Azores */ | 
|---|
 | 567 | #if     0 | 
|---|
 | 568 |     /* For completeness.  BST is also British Summer, and GST is | 
|---|
 | 569 |      * also Guam Standard. */ | 
|---|
 | 570 |     { "bst",    tZONE,     HOUR( 3) },      /* Brazil Standard */ | 
|---|
 | 571 |     { "gst",    tZONE,     HOUR( 3) },      /* Greenland Standard */ | 
|---|
 | 572 | #endif | 
|---|
 | 573 |     { "nft",    tZONE,     HOUR( 7/2) },    /* Newfoundland */ | 
|---|
 | 574 |     { "nst",    tZONE,     HOUR( 7/2) },    /* Newfoundland Standard */ | 
|---|
 | 575 |     { "ndt",    tDAYZONE,  HOUR( 7/2) },    /* Newfoundland Daylight */ | 
|---|
 | 576 |     { "ast",    tZONE,     HOUR( 4) },      /* Atlantic Standard */ | 
|---|
 | 577 |     { "adt",    tDAYZONE,  HOUR( 4) },      /* Atlantic Daylight */ | 
|---|
 | 578 |     { "est",    tZONE,     HOUR( 5) },      /* Eastern Standard */ | 
|---|
 | 579 |     { "edt",    tDAYZONE,  HOUR( 5) },      /* Eastern Daylight */ | 
|---|
 | 580 |     { "cst",    tZONE,     HOUR( 6) },      /* Central Standard */ | 
|---|
 | 581 |     { "cdt",    tDAYZONE,  HOUR( 6) },      /* Central Daylight */ | 
|---|
 | 582 |     { "mst",    tZONE,     HOUR( 7) },      /* Mountain Standard */ | 
|---|
 | 583 |     { "mdt",    tDAYZONE,  HOUR( 7) },      /* Mountain Daylight */ | 
|---|
 | 584 |     { "pst",    tZONE,     HOUR( 8) },      /* Pacific Standard */ | 
|---|
 | 585 |     { "pdt",    tDAYZONE,  HOUR( 8) },      /* Pacific Daylight */ | 
|---|
 | 586 |     { "yst",    tZONE,     HOUR( 9) },      /* Yukon Standard */ | 
|---|
 | 587 |     { "ydt",    tDAYZONE,  HOUR( 9) },      /* Yukon Daylight */ | 
|---|
 | 588 |     { "hst",    tZONE,     HOUR(10) },      /* Hawaii Standard */ | 
|---|
 | 589 |     { "hdt",    tDAYZONE,  HOUR(10) },      /* Hawaii Daylight */ | 
|---|
 | 590 |     { "cat",    tZONE,     HOUR(10) },      /* Central Alaska */ | 
|---|
 | 591 |     { "ahst",   tZONE,     HOUR(10) },      /* Alaska-Hawaii Standard */ | 
|---|
 | 592 |     { "nt",     tZONE,     HOUR(11) },      /* Nome */ | 
|---|
 | 593 |     { "idlw",   tZONE,     HOUR(12) },      /* International Date Line West */ | 
|---|
 | 594 |     { "cet",    tZONE,    -HOUR( 1) },      /* Central European */ | 
|---|
 | 595 |     { "cest",   tDAYZONE, -HOUR( 1) },      /* Central European Summer */ | 
|---|
 | 596 |     { "met",    tZONE,    -HOUR( 1) },      /* Middle European */ | 
|---|
 | 597 |     { "mewt",   tZONE,    -HOUR( 1) },      /* Middle European Winter */ | 
|---|
 | 598 |     { "mest",   tDAYZONE, -HOUR( 1) },      /* Middle European Summer */ | 
|---|
 | 599 |     { "swt",    tZONE,    -HOUR( 1) },      /* Swedish Winter */ | 
|---|
 | 600 |     { "sst",    tDAYZONE, -HOUR( 1) },      /* Swedish Summer */ | 
|---|
 | 601 |     { "fwt",    tZONE,    -HOUR( 1) },      /* French Winter */ | 
|---|
 | 602 |     { "fst",    tDAYZONE, -HOUR( 1) },      /* French Summer */ | 
|---|
 | 603 |     { "eet",    tZONE,    -HOUR( 2) },      /* Eastern Europe, USSR Zone 1 */ | 
|---|
 | 604 |     { "bt",     tZONE,    -HOUR( 3) },      /* Baghdad, USSR Zone 2 */ | 
|---|
 | 605 |     { "it",     tZONE,    -HOUR( 7/2) },    /* Iran */ | 
|---|
 | 606 |     { "zp4",    tZONE,    -HOUR( 4) },      /* USSR Zone 3 */ | 
|---|
 | 607 |     { "zp5",    tZONE,    -HOUR( 5) },      /* USSR Zone 4 */ | 
|---|
 | 608 |     { "ist",    tZONE,    -HOUR(11/2) },    /* Indian Standard */ | 
|---|
 | 609 |     { "zp6",    tZONE,    -HOUR( 6) },      /* USSR Zone 5 */ | 
|---|
 | 610 | #if     0 | 
|---|
 | 611 |     /* For completeness.  NST is also Newfoundland Stanard, nad SST is | 
|---|
 | 612 |      * also Swedish Summer. */ | 
|---|
 | 613 |     { "nst",    tZONE,    -HOUR(13/2) },    /* North Sumatra */ | 
|---|
 | 614 |     { "sst",    tZONE,    -HOUR( 7) },      /* South Sumatra, USSR Zone 6 */ | 
|---|
 | 615 | #endif  /* 0 */ | 
|---|
 | 616 |     { "wast",   tZONE,    -HOUR( 7) },      /* West Australian Standard */ | 
|---|
 | 617 |     { "wadt",   tDAYZONE, -HOUR( 7) },      /* West Australian Daylight */ | 
|---|
 | 618 |     { "jt",     tZONE,    -HOUR(15/2) },    /* Java (3pm in Cronusland!) */ | 
|---|
 | 619 |     { "cct",    tZONE,    -HOUR( 8) },      /* China Coast, USSR Zone 7 */ | 
|---|
 | 620 |     { "jst",    tZONE,    -HOUR( 9) },      /* Japan Standard, USSR Zone 8 */ | 
|---|
 | 621 |     { "jdt",    tDAYZONE, -HOUR( 9) },      /* Japan Daylight */ | 
|---|
 | 622 |     { "kst",    tZONE,    -HOUR( 9) },      /* Korea Standard */ | 
|---|
 | 623 |     { "kdt",    tDAYZONE, -HOUR( 9) },      /* Korea Daylight */ | 
|---|
 | 624 |     { "cast",   tZONE,    -HOUR(19/2) },    /* Central Australian Standard */ | 
|---|
 | 625 |     { "cadt",   tDAYZONE, -HOUR(19/2) },    /* Central Australian Daylight */ | 
|---|
 | 626 |     { "east",   tZONE,    -HOUR(10) },      /* Eastern Australian Standard */ | 
|---|
 | 627 |     { "eadt",   tDAYZONE, -HOUR(10) },      /* Eastern Australian Daylight */ | 
|---|
 | 628 |     { "gst",    tZONE,    -HOUR(10) },      /* Guam Standard, USSR Zone 9 */ | 
|---|
 | 629 |     { "nzt",    tZONE,    -HOUR(12) },      /* New Zealand */ | 
|---|
 | 630 |     { "nzst",   tZONE,    -HOUR(12) },      /* New Zealand Standard */ | 
|---|
 | 631 |     { "nzdt",   tDAYZONE, -HOUR(12) },      /* New Zealand Daylight */ | 
|---|
 | 632 |     { "idle",   tZONE,    -HOUR(12) },      /* International Date Line East */ | 
|---|
 | 633 |     /* ADDED BY Marco Nijdam */ | 
|---|
 | 634 |     { "dst",    tDST,     HOUR( 0) },       /* DST on (hour is ignored) */ | 
|---|
 | 635 |     /* End ADDED */ | 
|---|
 | 636 |     {  NULL  } | 
|---|
 | 637 | }; | 
|---|
 | 638 |  | 
|---|
 | 639 | /* | 
|---|
 | 640 |  * Military timezone table. | 
|---|
 | 641 |  */ | 
|---|
 | 642 |  | 
|---|
 | 643 | static TABLE    MilitaryTable[] = { | 
|---|
 | 644 |     { "a",      tZONE,  -HOUR( 1) }, | 
|---|
 | 645 |     { "b",      tZONE,  -HOUR( 2) }, | 
|---|
 | 646 |     { "c",      tZONE,  -HOUR( 3) }, | 
|---|
 | 647 |     { "d",      tZONE,  -HOUR( 4) }, | 
|---|
 | 648 |     { "e",      tZONE,  -HOUR( 5) }, | 
|---|
 | 649 |     { "f",      tZONE,  -HOUR( 6) }, | 
|---|
 | 650 |     { "g",      tZONE,  -HOUR( 7) }, | 
|---|
 | 651 |     { "h",      tZONE,  -HOUR( 8) }, | 
|---|
 | 652 |     { "i",      tZONE,  -HOUR( 9) }, | 
|---|
 | 653 |     { "k",      tZONE,  -HOUR(10) }, | 
|---|
 | 654 |     { "l",      tZONE,  -HOUR(11) }, | 
|---|
 | 655 |     { "m",      tZONE,  -HOUR(12) }, | 
|---|
 | 656 |     { "n",      tZONE,  HOUR(  1) }, | 
|---|
 | 657 |     { "o",      tZONE,  HOUR(  2) }, | 
|---|
 | 658 |     { "p",      tZONE,  HOUR(  3) }, | 
|---|
 | 659 |     { "q",      tZONE,  HOUR(  4) }, | 
|---|
 | 660 |     { "r",      tZONE,  HOUR(  5) }, | 
|---|
 | 661 |     { "s",      tZONE,  HOUR(  6) }, | 
|---|
 | 662 |     { "t",      tZONE,  HOUR(  7) }, | 
|---|
 | 663 |     { "u",      tZONE,  HOUR(  8) }, | 
|---|
 | 664 |     { "v",      tZONE,  HOUR(  9) }, | 
|---|
 | 665 |     { "w",      tZONE,  HOUR( 10) }, | 
|---|
 | 666 |     { "x",      tZONE,  HOUR( 11) }, | 
|---|
 | 667 |     { "y",      tZONE,  HOUR( 12) }, | 
|---|
 | 668 |     { "z",      tZONE,  HOUR( 0) }, | 
|---|
 | 669 |     { NULL } | 
|---|
 | 670 | }; | 
|---|
 | 671 |  | 
|---|
 | 672 | /* | 
|---|
 | 673 |  * Dump error messages in the bit bucket. | 
|---|
 | 674 |  */ | 
|---|
 | 675 |  | 
|---|
 | 676 | static void | 
|---|
 | 677 | TclDateerror( | 
|---|
 | 678 |     char *s) | 
|---|
 | 679 | { | 
|---|
 | 680 | } | 
|---|
 | 681 |  | 
|---|
 | 682 | static time_t | 
|---|
 | 683 | ToSeconds( | 
|---|
 | 684 |     time_t Hours, | 
|---|
 | 685 |     time_t Minutes, | 
|---|
 | 686 |     time_t Seconds, | 
|---|
 | 687 |     MERIDIAN Meridian) | 
|---|
 | 688 | { | 
|---|
 | 689 |     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) { | 
|---|
 | 690 |         return -1; | 
|---|
 | 691 |     } | 
|---|
 | 692 |     switch (Meridian) { | 
|---|
 | 693 |     case MER24: | 
|---|
 | 694 |         if (Hours < 0 || Hours > 23) { | 
|---|
 | 695 |             return -1; | 
|---|
 | 696 |         } | 
|---|
 | 697 |         return (Hours * 60L + Minutes) * 60L + Seconds; | 
|---|
 | 698 |     case MERam: | 
|---|
 | 699 |         if (Hours < 1 || Hours > 12) { | 
|---|
 | 700 |             return -1; | 
|---|
 | 701 |         } | 
|---|
 | 702 |         return ((Hours % 12) * 60L + Minutes) * 60L + Seconds; | 
|---|
 | 703 |     case MERpm: | 
|---|
 | 704 |         if (Hours < 1 || Hours > 12) { | 
|---|
 | 705 |             return -1; | 
|---|
 | 706 |         } | 
|---|
 | 707 |         return (((Hours % 12) + 12) * 60L + Minutes) * 60L + Seconds; | 
|---|
 | 708 |     } | 
|---|
 | 709 |     return -1;                  /* Should never be reached */ | 
|---|
 | 710 | } | 
|---|
 | 711 |  | 
|---|
 | 712 | static int | 
|---|
 | 713 | LookupWord( | 
|---|
 | 714 |     char *buff) | 
|---|
 | 715 | { | 
|---|
 | 716 |     register char *p; | 
|---|
 | 717 |     register char *q; | 
|---|
 | 718 |     register TABLE *tp; | 
|---|
 | 719 |     int i, abbrev; | 
|---|
 | 720 |  | 
|---|
 | 721 |     /* | 
|---|
 | 722 |      * Make it lowercase. | 
|---|
 | 723 |      */ | 
|---|
 | 724 |  | 
|---|
 | 725 |     Tcl_UtfToLower(buff); | 
|---|
 | 726 |  | 
|---|
 | 727 |     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) { | 
|---|
 | 728 |         yylval.Meridian = MERam; | 
|---|
 | 729 |         return tMERIDIAN; | 
|---|
 | 730 |     } | 
|---|
 | 731 |     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) { | 
|---|
 | 732 |         yylval.Meridian = MERpm; | 
|---|
 | 733 |         return tMERIDIAN; | 
|---|
 | 734 |     } | 
|---|
 | 735 |  | 
|---|
 | 736 |     /* | 
|---|
 | 737 |      * See if we have an abbreviation for a month. | 
|---|
 | 738 |      */ | 
|---|
 | 739 |  | 
|---|
 | 740 |     if (strlen(buff) == 3) { | 
|---|
 | 741 |         abbrev = 1; | 
|---|
 | 742 |     } else if (strlen(buff) == 4 && buff[3] == '.') { | 
|---|
 | 743 |         abbrev = 1; | 
|---|
 | 744 |         buff[3] = '\0'; | 
|---|
 | 745 |     } else { | 
|---|
 | 746 |         abbrev = 0; | 
|---|
 | 747 |     } | 
|---|
 | 748 |  | 
|---|
 | 749 |     for (tp = MonthDayTable; tp->name; tp++) { | 
|---|
 | 750 |         if (abbrev) { | 
|---|
 | 751 |             if (strncmp(buff, tp->name, 3) == 0) { | 
|---|
 | 752 |                 yylval.Number = tp->value; | 
|---|
 | 753 |                 return tp->type; | 
|---|
 | 754 |             } | 
|---|
 | 755 |         } else if (strcmp(buff, tp->name) == 0) { | 
|---|
 | 756 |             yylval.Number = tp->value; | 
|---|
 | 757 |             return tp->type; | 
|---|
 | 758 |         } | 
|---|
 | 759 |     } | 
|---|
 | 760 |  | 
|---|
 | 761 |     for (tp = TimezoneTable; tp->name; tp++) { | 
|---|
 | 762 |         if (strcmp(buff, tp->name) == 0) { | 
|---|
 | 763 |             yylval.Number = tp->value; | 
|---|
 | 764 |             return tp->type; | 
|---|
 | 765 |         } | 
|---|
 | 766 |     } | 
|---|
 | 767 |  | 
|---|
 | 768 |     for (tp = UnitsTable; tp->name; tp++) { | 
|---|
 | 769 |         if (strcmp(buff, tp->name) == 0) { | 
|---|
 | 770 |             yylval.Number = tp->value; | 
|---|
 | 771 |             return tp->type; | 
|---|
 | 772 |         } | 
|---|
 | 773 |     } | 
|---|
 | 774 |  | 
|---|
 | 775 |     /* | 
|---|
 | 776 |      * Strip off any plural and try the units table again. | 
|---|
 | 777 |      */ | 
|---|
 | 778 |  | 
|---|
 | 779 |     i = strlen(buff) - 1; | 
|---|
 | 780 |     if (i > 0 && buff[i] == 's') { | 
|---|
 | 781 |         buff[i] = '\0'; | 
|---|
 | 782 |         for (tp = UnitsTable; tp->name; tp++) { | 
|---|
 | 783 |             if (strcmp(buff, tp->name) == 0) { | 
|---|
 | 784 |                 yylval.Number = tp->value; | 
|---|
 | 785 |                 return tp->type; | 
|---|
 | 786 |             } | 
|---|
 | 787 |         } | 
|---|
 | 788 |     } | 
|---|
 | 789 |  | 
|---|
 | 790 |     for (tp = OtherTable; tp->name; tp++) { | 
|---|
 | 791 |         if (strcmp(buff, tp->name) == 0) { | 
|---|
 | 792 |             yylval.Number = tp->value; | 
|---|
 | 793 |             return tp->type; | 
|---|
 | 794 |         } | 
|---|
 | 795 |     } | 
|---|
 | 796 |  | 
|---|
 | 797 |     /* | 
|---|
 | 798 |      * Military timezones. | 
|---|
 | 799 |      */ | 
|---|
 | 800 |  | 
|---|
 | 801 |     if (buff[1] == '\0' && !(*buff & 0x80) | 
|---|
 | 802 |             && isalpha(UCHAR(*buff))) {                 /* INTL: ISO only */ | 
|---|
 | 803 |         for (tp = MilitaryTable; tp->name; tp++) { | 
|---|
 | 804 |             if (strcmp(buff, tp->name) == 0) { | 
|---|
 | 805 |                 yylval.Number = tp->value; | 
|---|
 | 806 |                 return tp->type; | 
|---|
 | 807 |             } | 
|---|
 | 808 |         } | 
|---|
 | 809 |     } | 
|---|
 | 810 |  | 
|---|
 | 811 |     /* | 
|---|
 | 812 |      * Drop out any periods and try the timezone table again. | 
|---|
 | 813 |      */ | 
|---|
 | 814 |  | 
|---|
 | 815 |     for (i = 0, p = q = buff; *q; q++) { | 
|---|
 | 816 |         if (*q != '.') { | 
|---|
 | 817 |             *p++ = *q; | 
|---|
 | 818 |         } else { | 
|---|
 | 819 |             i++; | 
|---|
 | 820 |         } | 
|---|
 | 821 |     } | 
|---|
 | 822 |     *p = '\0'; | 
|---|
 | 823 |     if (i) { | 
|---|
 | 824 |         for (tp = TimezoneTable; tp->name; tp++) { | 
|---|
 | 825 |             if (strcmp(buff, tp->name) == 0) { | 
|---|
 | 826 |                 yylval.Number = tp->value; | 
|---|
 | 827 |                 return tp->type; | 
|---|
 | 828 |             } | 
|---|
 | 829 |         } | 
|---|
 | 830 |     } | 
|---|
 | 831 |  | 
|---|
 | 832 |     return tID; | 
|---|
 | 833 | } | 
|---|
 | 834 |  | 
|---|
 | 835 | static int | 
|---|
 | 836 | TclDatelex( | 
|---|
 | 837 |     void *info) | 
|---|
 | 838 | { | 
|---|
 | 839 |     register char c; | 
|---|
 | 840 |     register char *p; | 
|---|
 | 841 |     char buff[20]; | 
|---|
 | 842 |     int Count; | 
|---|
 | 843 |  | 
|---|
 | 844 |     for ( ; ; ) { | 
|---|
 | 845 |         while (isspace(UCHAR(*yyInput))) { | 
|---|
 | 846 |             yyInput++; | 
|---|
 | 847 |         } | 
|---|
 | 848 |  | 
|---|
 | 849 |         if (isdigit(UCHAR(c = *yyInput))) { /* INTL: digit */ | 
|---|
 | 850 |             /* | 
|---|
 | 851 |              * Convert the string into a number; count the number of digits. | 
|---|
 | 852 |              */ | 
|---|
 | 853 |  | 
|---|
 | 854 |             Count = 0; | 
|---|
 | 855 |             for (yylval.Number = 0; | 
|---|
 | 856 |                     isdigit(UCHAR(c = *yyInput++)); ) {   /* INTL: digit */ | 
|---|
 | 857 |                 yylval.Number = 10 * yylval.Number + c - '0'; | 
|---|
 | 858 |                 Count++; | 
|---|
 | 859 |             } | 
|---|
 | 860 |             yyInput--; | 
|---|
 | 861 |             yyDigitCount = Count; | 
|---|
 | 862 |  | 
|---|
 | 863 |             /* | 
|---|
 | 864 |              * A number with 6 or more digits is considered an ISO 8601 base. | 
|---|
 | 865 |              */ | 
|---|
 | 866 |  | 
|---|
 | 867 |             if (Count >= 6) { | 
|---|
 | 868 |                 return tISOBASE; | 
|---|
 | 869 |             } else { | 
|---|
 | 870 |                 return tUNUMBER; | 
|---|
 | 871 |             } | 
|---|
 | 872 |         } | 
|---|
 | 873 |         if (!(c & 0x80) && isalpha(UCHAR(c))) {           /* INTL: ISO only. */ | 
|---|
 | 874 |             for (p = buff; isalpha(UCHAR(c = *yyInput++)) /* INTL: ISO only. */ | 
|---|
 | 875 |                      || c == '.'; ) { | 
|---|
 | 876 |                 if (p < &buff[sizeof buff - 1]) { | 
|---|
 | 877 |                     *p++ = c; | 
|---|
 | 878 |                 } | 
|---|
 | 879 |             } | 
|---|
 | 880 |             *p = '\0'; | 
|---|
 | 881 |             yyInput--; | 
|---|
 | 882 |             return LookupWord(buff); | 
|---|
 | 883 |         } | 
|---|
 | 884 |         if (c != '(') { | 
|---|
 | 885 |             return *yyInput++; | 
|---|
 | 886 |         } | 
|---|
 | 887 |         Count = 0; | 
|---|
 | 888 |         do { | 
|---|
 | 889 |             c = *yyInput++; | 
|---|
 | 890 |             if (c == '\0') { | 
|---|
 | 891 |                 return c; | 
|---|
 | 892 |             } else if (c == '(') { | 
|---|
 | 893 |                 Count++; | 
|---|
 | 894 |             } else if (c == ')') { | 
|---|
 | 895 |                 Count--; | 
|---|
 | 896 |             } | 
|---|
 | 897 |         } while (Count > 0); | 
|---|
 | 898 |     } | 
|---|
 | 899 | } | 
|---|
 | 900 |  | 
|---|
 | 901 | int | 
|---|
 | 902 | TclClockOldscanObjCmd( | 
|---|
 | 903 |     ClientData clientData,      /* Unused */ | 
|---|
 | 904 |     Tcl_Interp *interp,         /* Tcl interpreter */ | 
|---|
 | 905 |     int objc,                   /* Count of paraneters */ | 
|---|
 | 906 |     Tcl_Obj *CONST *objv)       /* Parameters */ | 
|---|
 | 907 | { | 
|---|
 | 908 |     Tcl_Obj *result, *resultElement; | 
|---|
 | 909 |     int yr, mo, da; | 
|---|
 | 910 |     DateInfo dateInfo; | 
|---|
 | 911 |     void *info = (void *) &dateInfo; | 
|---|
 | 912 |  | 
|---|
 | 913 |     if (objc != 5) { | 
|---|
 | 914 |         Tcl_WrongNumArgs(interp, 1, objv, | 
|---|
 | 915 |                 "stringToParse baseYear baseMonth baseDay" ); | 
|---|
 | 916 |         return TCL_ERROR; | 
|---|
 | 917 |     } | 
|---|
 | 918 |  | 
|---|
 | 919 |     yyInput = Tcl_GetString( objv[1] ); | 
|---|
 | 920 |  | 
|---|
 | 921 |     yyHaveDate = 0; | 
|---|
 | 922 |     if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK | 
|---|
 | 923 |             || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK | 
|---|
 | 924 |             || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) { | 
|---|
 | 925 |         return TCL_ERROR; | 
|---|
 | 926 |     } | 
|---|
 | 927 |     yyYear = yr; yyMonth = mo; yyDay = da; | 
|---|
 | 928 |  | 
|---|
 | 929 |     yyHaveTime = 0; | 
|---|
 | 930 |     yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; | 
|---|
 | 931 |  | 
|---|
 | 932 |     yyHaveZone = 0; | 
|---|
 | 933 |     yyTimezone = 0; yyDSTmode = DSTmaybe; | 
|---|
 | 934 |  | 
|---|
 | 935 |     yyHaveOrdinalMonth = 0; | 
|---|
 | 936 |     yyMonthOrdinal = 0; | 
|---|
 | 937 |  | 
|---|
 | 938 |     yyHaveDay = 0; | 
|---|
 | 939 |     yyDayOrdinal = 0; yyDayNumber = 0; | 
|---|
 | 940 |  | 
|---|
 | 941 |     yyHaveRel = 0; | 
|---|
 | 942 |     yyRelMonth = 0; yyRelDay = 0; yyRelSeconds = 0; yyRelPointer = NULL; | 
|---|
 | 943 |  | 
|---|
 | 944 |     if (yyparse(info)) { | 
|---|
 | 945 |         Tcl_SetObjResult(interp, Tcl_NewStringObj("syntax error", -1)); | 
|---|
 | 946 |         return TCL_ERROR; | 
|---|
 | 947 |     } | 
|---|
 | 948 |  | 
|---|
 | 949 |     if (yyHaveDate > 1) { | 
|---|
 | 950 |         Tcl_SetObjResult(interp, | 
|---|
 | 951 |                 Tcl_NewStringObj("more than one date in string", -1)); | 
|---|
 | 952 |         return TCL_ERROR; | 
|---|
 | 953 |     } | 
|---|
 | 954 |     if (yyHaveTime > 1) { | 
|---|
 | 955 |         Tcl_SetObjResult(interp, | 
|---|
 | 956 |                 Tcl_NewStringObj("more than one time of day in string", -1)); | 
|---|
 | 957 |         return TCL_ERROR; | 
|---|
 | 958 |     } | 
|---|
 | 959 |     if (yyHaveZone > 1) { | 
|---|
 | 960 |         Tcl_SetObjResult(interp, | 
|---|
 | 961 |                 Tcl_NewStringObj("more than one time zone in string", -1)); | 
|---|
 | 962 |         return TCL_ERROR; | 
|---|
 | 963 |     } | 
|---|
 | 964 |     if (yyHaveDay > 1) { | 
|---|
 | 965 |         Tcl_SetObjResult(interp, | 
|---|
 | 966 |                 Tcl_NewStringObj("more than one weekday in string", -1)); | 
|---|
 | 967 |         return TCL_ERROR; | 
|---|
 | 968 |     } | 
|---|
 | 969 |     if (yyHaveOrdinalMonth > 1) { | 
|---|
 | 970 |         Tcl_SetObjResult(interp, | 
|---|
 | 971 |                 Tcl_NewStringObj("more than one ordinal month in string", -1)); | 
|---|
 | 972 |         return TCL_ERROR; | 
|---|
 | 973 |     } | 
|---|
 | 974 |  | 
|---|
 | 975 |     result = Tcl_NewObj(); | 
|---|
 | 976 |     resultElement = Tcl_NewObj(); | 
|---|
 | 977 |     if (yyHaveDate) { | 
|---|
 | 978 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 979 |                 Tcl_NewIntObj((int) yyYear)); | 
|---|
 | 980 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 981 |                 Tcl_NewIntObj((int) yyMonth)); | 
|---|
 | 982 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 983 |                 Tcl_NewIntObj((int) yyDay)); | 
|---|
 | 984 |     } | 
|---|
 | 985 |     Tcl_ListObjAppendElement(interp, result, resultElement); | 
|---|
 | 986 |  | 
|---|
 | 987 |     if (yyHaveTime) { | 
|---|
 | 988 |         Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj((int) | 
|---|
 | 989 |                 ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian))); | 
|---|
 | 990 |     } else { | 
|---|
 | 991 |         Tcl_ListObjAppendElement(interp, result, Tcl_NewObj()); | 
|---|
 | 992 |     } | 
|---|
 | 993 |  | 
|---|
 | 994 |     resultElement = Tcl_NewObj(); | 
|---|
 | 995 |     if (yyHaveZone) { | 
|---|
 | 996 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 997 |                 Tcl_NewIntObj((int) -yyTimezone)); | 
|---|
 | 998 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 999 |                 Tcl_NewIntObj(1 - yyDSTmode)); | 
|---|
 | 1000 |     } | 
|---|
 | 1001 |     Tcl_ListObjAppendElement(interp, result, resultElement); | 
|---|
 | 1002 |  | 
|---|
 | 1003 |     resultElement = Tcl_NewObj(); | 
|---|
 | 1004 |     if (yyHaveRel) { | 
|---|
 | 1005 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 1006 |                 Tcl_NewIntObj((int) yyRelMonth)); | 
|---|
 | 1007 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 1008 |                 Tcl_NewIntObj((int) yyRelDay)); | 
|---|
 | 1009 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 1010 |                 Tcl_NewIntObj((int) yyRelSeconds)); | 
|---|
 | 1011 |     } | 
|---|
 | 1012 |     Tcl_ListObjAppendElement(interp, result, resultElement); | 
|---|
 | 1013 |  | 
|---|
 | 1014 |     resultElement = Tcl_NewObj(); | 
|---|
 | 1015 |     if (yyHaveDay && !yyHaveDate) { | 
|---|
 | 1016 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 1017 |                 Tcl_NewIntObj((int) yyDayOrdinal)); | 
|---|
 | 1018 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 1019 |                 Tcl_NewIntObj((int) yyDayNumber)); | 
|---|
 | 1020 |     } | 
|---|
 | 1021 |     Tcl_ListObjAppendElement(interp, result, resultElement); | 
|---|
 | 1022 |  | 
|---|
 | 1023 |     resultElement = Tcl_NewObj(); | 
|---|
 | 1024 |     if (yyHaveOrdinalMonth) { | 
|---|
 | 1025 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 1026 |                 Tcl_NewIntObj((int) yyMonthOrdinal)); | 
|---|
 | 1027 |         Tcl_ListObjAppendElement(interp, resultElement, | 
|---|
 | 1028 |                 Tcl_NewIntObj((int) yyMonth)); | 
|---|
 | 1029 |     } | 
|---|
 | 1030 |     Tcl_ListObjAppendElement(interp, result, resultElement); | 
|---|
 | 1031 |  | 
|---|
 | 1032 |     Tcl_SetObjResult(interp, result); | 
|---|
 | 1033 |     return TCL_OK; | 
|---|
 | 1034 | } | 
|---|
 | 1035 |  | 
|---|
 | 1036 | /* | 
|---|
 | 1037 |  * Local Variables: | 
|---|
 | 1038 |  * mode: c | 
|---|
 | 1039 |  * c-basic-offset: 4 | 
|---|
 | 1040 |  * fill-column: 78 | 
|---|
 | 1041 |  * End: | 
|---|
 | 1042 |  */ | 
|---|