00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <eggdrop/eggdrop.h>
00019
00020 #define EPOCH 1970
00021 #define START_OF_TIME 1902
00022 #define END_OF_TIME 2037
00023
00024
00025
00026
00027
00028
00029
00030
00031 #define TM_YEAR_BASE 1900
00032
00033 #define HOUR(x) ((int) (60 * x))
00034 #define SECSPERDAY (24L * 60L * 60L)
00035 #define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
00036
00037
00038
00039
00040 typedef struct _TABLE {
00041 char *name;
00042 int type;
00043 time_t value;
00044 } TABLE;
00045
00046
00047
00048
00049
00050 typedef enum _DSTMODE {
00051 DSTon, DSToff, DSTmaybe
00052 } DSTMODE;
00053
00054
00055
00056
00057 typedef enum _MERIDIAN {
00058 MERam, MERpm, MER24
00059 } MERIDIAN;
00060
00061
00062
00063
00064
00065
00066
00067
00068 static char *date_DateInput;
00069 static DSTMODE date_DateDSTmode;
00070 static time_t date_DateDayOrdinal;
00071 static time_t date_DateDayNumber;
00072 static time_t date_DateMonthOrdinal;
00073 static int date_DateHaveDate;
00074 static int date_DateHaveDay;
00075 static int date_DateHaveOrdinalMonth;
00076 static int date_DateHaveRel;
00077 static int date_DateHaveTime;
00078 static int date_DateHaveZone;
00079 static time_t date_DateTimezone;
00080 static time_t date_DateDay;
00081 static time_t date_DateHour;
00082 static time_t date_DateMinutes;
00083 static time_t date_DateMonth;
00084 static time_t date_DateSeconds;
00085 static time_t date_DateYear;
00086 static MERIDIAN date_DateMeridian;
00087 static time_t date_DateRelMonth;
00088 static time_t date_DateRelDay;
00089 static time_t date_DateRelSeconds;
00090 static time_t *date_DateRelPointer;
00091
00092
00093
00094
00095 static void date_Dateerror(char *s);
00096 static time_t ToSeconds(time_t Hours, time_t Minutes,
00097 time_t Seconds, MERIDIAN Meridian);
00098 static int Convert(time_t Month, time_t Day, time_t Year,
00099 time_t Hours, time_t Minutes, time_t Seconds,
00100 MERIDIAN Meridia, DSTMODE DSTmode, time_t *TimePtr);
00101 static time_t DSTcorrect(time_t Start, time_t Future);
00102 static time_t NamedDay(time_t Start, time_t DayOrdinal,
00103 time_t DayNumber);
00104 static time_t NamedMonth(time_t Start, time_t MonthOrdinal,
00105 time_t MonthNumber);
00106 static int RelativeMonth(time_t Start, time_t RelMonth,
00107 time_t *TimePtr);
00108 static int RelativeDay(time_t Start, time_t RelDay,
00109 time_t *TimePtr);
00110 static int LookupWord(char *buff);
00111 static int date_Datelex(void);
00112
00113 int
00114 date_Dateparse(void);
00115 typedef union
00116 #ifdef __cplusplus
00117 YYSTYPE
00118 #endif
00119 {
00120 time_t Number;
00121 enum _MERIDIAN Meridian;
00122 } YYSTYPE;
00123 # define tAGO 257
00124 # define tDAY 258
00125 # define tDAYZONE 259
00126 # define tID 260
00127 # define tMERIDIAN 261
00128 # define tMINUTE_UNIT 262
00129 # define tMONTH 263
00130 # define tMONTH_UNIT 264
00131 # define tSTARDATE 265
00132 # define tSEC_UNIT 266
00133 # define tSNUMBER 267
00134 # define tUNUMBER 268
00135 # define tZONE 269
00136 # define tEPOCH 270
00137 # define tDST 271
00138 # define tISOBASE 272
00139 # define tDAY_UNIT 273
00140 # define tNEXT 274
00141
00142
00143
00144
00145 #if defined(__cplusplus) || defined(__STDC__)
00146
00147 #if defined(__cplusplus) && defined(__EXTERN_C__)
00148 extern "C" {
00149 #endif
00150 #ifndef date_Dateerror
00151 #if defined(__cplusplus)
00152 void date_Dateerror(char *);
00153 #endif
00154 #endif
00155 #ifndef date_Datelex
00156 int date_Datelex(void);
00157 #endif
00158 int date_Dateparse(void);
00159 #if defined(__cplusplus) && defined(__EXTERN_C__)
00160 }
00161 #endif
00162
00163 #endif
00164
00165 #define date_Dateclearin date_Datechar = -1
00166 #define date_Dateerrok date_Dateerrflag = 0
00167 extern int date_Datechar;
00168 extern int date_Dateerrflag;
00169 YYSTYPE date_Datelval;
00170 YYSTYPE date_Dateval;
00171 typedef int date_Datetabelem;
00172 #ifndef YYMAXDEPTH
00173 #define YYMAXDEPTH 150
00174 #endif
00175 #if YYMAXDEPTH > 0
00176 int date_Date_date_Dates[YYMAXDEPTH], *date_Dates = date_Date_date_Dates;
00177 YYSTYPE date_Date_date_Datev[YYMAXDEPTH], *date_Datev = date_Date_date_Datev;
00178 #else
00179 int *date_Dates;
00180 YYSTYPE *date_Datev;
00181 #endif
00182 static int date_Datemaxdepth = YYMAXDEPTH;
00183 # define YYERRCODE 256
00184
00185
00186
00187
00188
00189 static TABLE MonthDayTable[] = {
00190 { "january", tMONTH, 1 },
00191 { "february", tMONTH, 2 },
00192 { "march", tMONTH, 3 },
00193 { "april", tMONTH, 4 },
00194 { "may", tMONTH, 5 },
00195 { "june", tMONTH, 6 },
00196 { "july", tMONTH, 7 },
00197 { "august", tMONTH, 8 },
00198 { "september", tMONTH, 9 },
00199 { "sept", tMONTH, 9 },
00200 { "october", tMONTH, 10 },
00201 { "november", tMONTH, 11 },
00202 { "december", tMONTH, 12 },
00203 { "sunday", tDAY, 0 },
00204 { "monday", tDAY, 1 },
00205 { "tuesday", tDAY, 2 },
00206 { "tues", tDAY, 2 },
00207 { "wednesday", tDAY, 3 },
00208 { "wednes", tDAY, 3 },
00209 { "thursday", tDAY, 4 },
00210 { "thur", tDAY, 4 },
00211 { "thurs", tDAY, 4 },
00212 { "friday", tDAY, 5 },
00213 { "saturday", tDAY, 6 },
00214 { NULL }
00215 };
00216
00217
00218
00219
00220 static TABLE UnitsTable[] = {
00221 { "year", tMONTH_UNIT, 12 },
00222 { "month", tMONTH_UNIT, 1 },
00223 { "fortnight", tDAY_UNIT, 14 },
00224 { "week", tDAY_UNIT, 7 },
00225 { "day", tDAY_UNIT, 1 },
00226 { "hour", tSEC_UNIT, 60 * 60 },
00227 { "minute", tSEC_UNIT, 60 },
00228 { "min", tSEC_UNIT, 60 },
00229 { "second", tSEC_UNIT, 1 },
00230 { "sec", tSEC_UNIT, 1 },
00231 { NULL }
00232 };
00233
00234
00235
00236
00237 static TABLE OtherTable[] = {
00238 { "tomorrow", tDAY_UNIT, 1 },
00239 { "yesterday", tDAY_UNIT, -1 },
00240 { "today", tDAY_UNIT, 0 },
00241 { "now", tSEC_UNIT, 0 },
00242 { "last", tUNUMBER, -1 },
00243 { "this", tSEC_UNIT, 0 },
00244 { "next", tNEXT, 1 },
00245 #if 0
00246 { "first", tUNUMBER, 1 },
00247 { "second", tUNUMBER, 2 },
00248 { "third", tUNUMBER, 3 },
00249 { "fourth", tUNUMBER, 4 },
00250 { "fifth", tUNUMBER, 5 },
00251 { "sixth", tUNUMBER, 6 },
00252 { "seventh", tUNUMBER, 7 },
00253 { "eighth", tUNUMBER, 8 },
00254 { "ninth", tUNUMBER, 9 },
00255 { "tenth", tUNUMBER, 10 },
00256 { "eleventh", tUNUMBER, 11 },
00257 { "twelfth", tUNUMBER, 12 },
00258 #endif
00259 { "ago", tAGO, 1 },
00260 { "epoch", tEPOCH, 0 },
00261 { "stardate", tSTARDATE, 0},
00262 { NULL }
00263 };
00264
00265
00266
00267
00268
00269 static TABLE TimezoneTable[] = {
00270 { "gmt", tZONE, HOUR( 0) },
00271 { "ut", tZONE, HOUR( 0) },
00272 { "utc", tZONE, HOUR( 0) },
00273 { "uct", tZONE, HOUR( 0) },
00274 { "wet", tZONE, HOUR( 0) },
00275 { "bst", tDAYZONE, HOUR( 0) },
00276 { "wat", tZONE, HOUR( 1) },
00277 { "at", tZONE, HOUR( 2) },
00278 #if 0
00279
00280
00281 { "bst", tZONE, HOUR( 3) },
00282 { "gst", tZONE, HOUR( 3) },
00283 #endif
00284 { "nft", tZONE, HOUR( 7/2) },
00285 { "nst", tZONE, HOUR( 7/2) },
00286 { "ndt", tDAYZONE, HOUR( 7/2) },
00287 { "ast", tZONE, HOUR( 4) },
00288 { "adt", tDAYZONE, HOUR( 4) },
00289 { "est", tZONE, HOUR( 5) },
00290 { "edt", tDAYZONE, HOUR( 5) },
00291 { "cst", tZONE, HOUR( 6) },
00292 { "cdt", tDAYZONE, HOUR( 6) },
00293 { "mst", tZONE, HOUR( 7) },
00294 { "mdt", tDAYZONE, HOUR( 7) },
00295 { "pst", tZONE, HOUR( 8) },
00296 { "pdt", tDAYZONE, HOUR( 8) },
00297 { "yst", tZONE, HOUR( 9) },
00298 { "ydt", tDAYZONE, HOUR( 9) },
00299 { "hst", tZONE, HOUR(10) },
00300 { "hdt", tDAYZONE, HOUR(10) },
00301 { "cat", tZONE, HOUR(10) },
00302 { "ahst", tZONE, HOUR(10) },
00303 { "nt", tZONE, HOUR(11) },
00304 { "idlw", tZONE, HOUR(12) },
00305 { "cet", tZONE, -HOUR( 1) },
00306 { "cest", tDAYZONE, -HOUR( 1) },
00307 { "met", tZONE, -HOUR( 1) },
00308 { "mewt", tZONE, -HOUR( 1) },
00309 { "mest", tDAYZONE, -HOUR( 1) },
00310 { "swt", tZONE, -HOUR( 1) },
00311 { "sst", tDAYZONE, -HOUR( 1) },
00312 { "fwt", tZONE, -HOUR( 1) },
00313 { "fst", tDAYZONE, -HOUR( 1) },
00314 { "eet", tZONE, -HOUR( 2) },
00315 { "bt", tZONE, -HOUR( 3) },
00316 { "it", tZONE, -HOUR( 7/2) },
00317 { "zp4", tZONE, -HOUR( 4) },
00318 { "zp5", tZONE, -HOUR( 5) },
00319 { "ist", tZONE, -HOUR(11/2) },
00320 { "zp6", tZONE, -HOUR( 6) },
00321 #if 0
00322
00323
00324 { "nst", tZONE, -HOUR(13/2) },
00325 { "sst", tZONE, -HOUR( 7) },
00326 #endif
00327 { "wast", tZONE, -HOUR( 7) },
00328 { "wadt", tDAYZONE, -HOUR( 7) },
00329 { "jt", tZONE, -HOUR(15/2) },
00330 { "cct", tZONE, -HOUR( 8) },
00331 { "jst", tZONE, -HOUR( 9) },
00332 { "cast", tZONE, -HOUR(19/2) },
00333 { "cadt", tDAYZONE, -HOUR(19/2) },
00334 { "east", tZONE, -HOUR(10) },
00335 { "eadt", tDAYZONE, -HOUR(10) },
00336 { "gst", tZONE, -HOUR(10) },
00337 { "nzt", tZONE, -HOUR(12) },
00338 { "nzst", tZONE, -HOUR(12) },
00339 { "nzdt", tDAYZONE, -HOUR(12) },
00340 { "idle", tZONE, -HOUR(12) },
00341
00342 { "dst", tDST, HOUR( 0) },
00343
00344 { NULL }
00345 };
00346
00347
00348
00349
00350 static TABLE MilitaryTable[] = {
00351 { "a", tZONE, HOUR( 1) },
00352 { "b", tZONE, HOUR( 2) },
00353 { "c", tZONE, HOUR( 3) },
00354 { "d", tZONE, HOUR( 4) },
00355 { "e", tZONE, HOUR( 5) },
00356 { "f", tZONE, HOUR( 6) },
00357 { "g", tZONE, HOUR( 7) },
00358 { "h", tZONE, HOUR( 8) },
00359 { "i", tZONE, HOUR( 9) },
00360 { "k", tZONE, HOUR( 10) },
00361 { "l", tZONE, HOUR( 11) },
00362 { "m", tZONE, HOUR( 12) },
00363 { "n", tZONE, HOUR(- 1) },
00364 { "o", tZONE, HOUR(- 2) },
00365 { "p", tZONE, HOUR(- 3) },
00366 { "q", tZONE, HOUR(- 4) },
00367 { "r", tZONE, HOUR(- 5) },
00368 { "s", tZONE, HOUR(- 6) },
00369 { "t", tZONE, HOUR(- 7) },
00370 { "u", tZONE, HOUR(- 8) },
00371 { "v", tZONE, HOUR(- 9) },
00372 { "w", tZONE, HOUR(-10) },
00373 { "x", tZONE, HOUR(-11) },
00374 { "y", tZONE, HOUR(-12) },
00375 { "z", tZONE, HOUR( 0) },
00376 { NULL }
00377 };
00378
00379
00380
00381
00382
00383 static void
00384 date_Dateerror(s)
00385 char *s;
00386 {
00387 }
00388
00389 int date_timezone()
00390 {
00391 struct tm gmt, local;
00392 time_t now;
00393 int zone;
00394
00395 time(&now);
00396 gmt = *(gmtime(&now));
00397 local = *(localtime(&now));
00398 local.tm_isdst = gmt.tm_isdst = 0;
00399 zone = (int)(mktime(&local) - mktime(&gmt));
00400 return(zone/60);
00401 }
00402
00403 static time_t
00404 ToSeconds(Hours, Minutes, Seconds, Meridian)
00405 time_t Hours;
00406 time_t Minutes;
00407 time_t Seconds;
00408 MERIDIAN Meridian;
00409 {
00410 if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
00411 return -1;
00412 switch (Meridian) {
00413 case MER24:
00414 if (Hours < 0 || Hours > 23)
00415 return -1;
00416 return (Hours * 60L + Minutes) * 60L + Seconds;
00417 case MERam:
00418 if (Hours < 1 || Hours > 12)
00419 return -1;
00420 return ((Hours % 12) * 60L + Minutes) * 60L + Seconds;
00421 case MERpm:
00422 if (Hours < 1 || Hours > 12)
00423 return -1;
00424 return (((Hours % 12) + 12) * 60L + Minutes) * 60L + Seconds;
00425 }
00426 return -1;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 static int
00446 Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode, TimePtr)
00447 time_t Month;
00448 time_t Day;
00449 time_t Year;
00450 time_t Hours;
00451 time_t Minutes;
00452 time_t Seconds;
00453 MERIDIAN Meridian;
00454 DSTMODE DSTmode;
00455 time_t *TimePtr;
00456 {
00457 static int DaysInMonth[12] = {
00458 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00459 };
00460 time_t tod;
00461 time_t Julian;
00462 int i;
00463
00464
00465
00466
00467
00468
00469 DaysInMonth[1] = IsLeapYear(Year) ? 29 : 28;
00470
00471
00472 if (Month < 1 || Month > 12
00473 || Year < START_OF_TIME || Year > END_OF_TIME
00474 || Day < 1 || Day > DaysInMonth[(int)--Month])
00475 return -1;
00476
00477
00478
00479
00480 for (Julian = Day - 1, i = 0; i < Month; i++)
00481 Julian += DaysInMonth[i];
00482 if (Year >= EPOCH) {
00483 for (i = EPOCH; i < Year; i++)
00484 Julian += 365 + IsLeapYear(i);
00485 } else {
00486 for (i = Year; i < EPOCH; i++)
00487 Julian -= 365 + IsLeapYear(i);
00488 }
00489 Julian *= SECSPERDAY;
00490
00491
00492 Julian += date_DateTimezone * 60L;
00493
00494
00495 if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
00496 return -1;
00497 Julian += tod;
00498
00499
00500 if (DSTmode == DSTon
00501 || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
00502 Julian -= 60 * 60;
00503 *TimePtr = Julian;
00504 return 0;
00505 }
00506
00507
00508 static time_t
00509 DSTcorrect(Start, Future)
00510 time_t Start;
00511 time_t Future;
00512 {
00513 time_t StartDay;
00514 time_t FutureDay;
00515 StartDay = (localtime(&Start)->tm_hour + 1) % 24;
00516 FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
00517 return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
00518 }
00519
00520
00521 static time_t
00522 NamedDay(Start, DayOrdinal, DayNumber)
00523 time_t Start;
00524 time_t DayOrdinal;
00525 time_t DayNumber;
00526 {
00527 struct tm *tm;
00528 time_t now;
00529
00530 now = Start;
00531 tm = localtime(&now);
00532 now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
00533 now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
00534 return DSTcorrect(Start, now);
00535 }
00536
00537 static time_t
00538 NamedMonth(Start, MonthOrdinal, MonthNumber)
00539 time_t Start;
00540 time_t MonthOrdinal;
00541 time_t MonthNumber;
00542 {
00543 struct tm *tm;
00544 time_t now;
00545 int result;
00546
00547 now = Start;
00548 tm = localtime(&now);
00549
00550
00551
00552
00553
00554
00555 tm->tm_year += MonthOrdinal;
00556 if (tm->tm_mon < MonthNumber - 1) {
00557 tm->tm_year--;
00558 }
00559 result = Convert(MonthNumber, (time_t) 1, tm->tm_year + TM_YEAR_BASE,
00560 (time_t) 0, (time_t) 0, (time_t) 0, MER24, DSTmaybe, &now);
00561 if (result < 0) {
00562 return 0;
00563 }
00564 return DSTcorrect(Start, now);
00565 }
00566
00567 static int
00568 RelativeMonth(Start, RelMonth, TimePtr)
00569 time_t Start;
00570 time_t RelMonth;
00571 time_t *TimePtr;
00572 {
00573 struct tm *tm;
00574 time_t Month;
00575 time_t Year;
00576 time_t Julian;
00577 int result;
00578
00579 if (RelMonth == 0) {
00580 *TimePtr = 0;
00581 return 0;
00582 }
00583 tm = localtime(&Start);
00584 Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;
00585 Year = Month / 12;
00586 Month = Month % 12 + 1;
00587 result = Convert(Month, (time_t) tm->tm_mday, Year,
00588 (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
00589 MER24, DSTmaybe, &Julian);
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 if (date_DateTimezone == 0) {
00604 Julian += date_timezone() * 60L;
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 while ((result != 0) && (tm->tm_mday > 28)) {
00616 tm->tm_mday--;
00617 result = Convert(Month, (time_t) tm->tm_mday, Year,
00618 (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
00619 MER24, DSTmaybe, &Julian);
00620 }
00621 if (result != 0) {
00622 return -1;
00623 }
00624 *TimePtr = DSTcorrect(Start, Julian);
00625 return 0;
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 static int
00647 RelativeDay(Start, RelDay, TimePtr)
00648 time_t Start;
00649 time_t RelDay;
00650 time_t *TimePtr;
00651 {
00652 time_t new;
00653
00654 new = Start + (RelDay * 60 * 60 * 24);
00655 *TimePtr = DSTcorrect(Start, new);
00656 return 1;
00657 }
00658
00659 static int
00660 LookupWord(buff)
00661 char *buff;
00662 {
00663 register char *p;
00664 register char *q;
00665 register TABLE *tp;
00666 int i;
00667 int abbrev;
00668
00669
00670
00671
00672
00673 str_tolower(buff);
00674
00675 if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
00676 date_Datelval.Meridian = MERam;
00677 return tMERIDIAN;
00678 }
00679 if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
00680 date_Datelval.Meridian = MERpm;
00681 return tMERIDIAN;
00682 }
00683
00684
00685
00686
00687 if (strlen(buff) == 3) {
00688 abbrev = 1;
00689 } else if (strlen(buff) == 4 && buff[3] == '.') {
00690 abbrev = 1;
00691 buff[3] = '\0';
00692 } else {
00693 abbrev = 0;
00694 }
00695
00696 for (tp = MonthDayTable; tp->name; tp++) {
00697 if (abbrev) {
00698 if (strncmp(buff, tp->name, 3) == 0) {
00699 date_Datelval.Number = tp->value;
00700 return tp->type;
00701 }
00702 } else if (strcmp(buff, tp->name) == 0) {
00703 date_Datelval.Number = tp->value;
00704 return tp->type;
00705 }
00706 }
00707
00708 for (tp = TimezoneTable; tp->name; tp++) {
00709 if (strcmp(buff, tp->name) == 0) {
00710 date_Datelval.Number = tp->value;
00711 return tp->type;
00712 }
00713 }
00714
00715 for (tp = UnitsTable; tp->name; tp++) {
00716 if (strcmp(buff, tp->name) == 0) {
00717 date_Datelval.Number = tp->value;
00718 return tp->type;
00719 }
00720 }
00721
00722
00723
00724
00725 i = strlen(buff) - 1;
00726 if (buff[i] == 's') {
00727 buff[i] = '\0';
00728 for (tp = UnitsTable; tp->name; tp++) {
00729 if (strcmp(buff, tp->name) == 0) {
00730 date_Datelval.Number = tp->value;
00731 return tp->type;
00732 }
00733 }
00734 }
00735
00736 for (tp = OtherTable; tp->name; tp++) {
00737 if (strcmp(buff, tp->name) == 0) {
00738 date_Datelval.Number = tp->value;
00739 return tp->type;
00740 }
00741 }
00742
00743
00744
00745
00746 if (buff[1] == '\0' && !(*buff & 0x80)
00747 && isalpha(*buff)) {
00748 for (tp = MilitaryTable; tp->name; tp++) {
00749 if (strcmp(buff, tp->name) == 0) {
00750 date_Datelval.Number = tp->value;
00751 return tp->type;
00752 }
00753 }
00754 }
00755
00756
00757
00758
00759 for (i = 0, p = q = buff; *q; q++)
00760 if (*q != '.') {
00761 *p++ = *q;
00762 } else {
00763 i++;
00764 }
00765 *p = '\0';
00766 if (i) {
00767 for (tp = TimezoneTable; tp->name; tp++) {
00768 if (strcmp(buff, tp->name) == 0) {
00769 date_Datelval.Number = tp->value;
00770 return tp->type;
00771 }
00772 }
00773 }
00774
00775 return tID;
00776 }
00777
00778
00779 static int
00780 date_Datelex()
00781 {
00782 register char c;
00783 register char *p;
00784 char buff[20];
00785 int Count;
00786
00787 for ( ; ; ) {
00788 while (isspace(*date_DateInput)) {
00789 date_DateInput++;
00790 }
00791
00792 if (isdigit((c = *date_DateInput))) {
00793
00794 Count = 0;
00795 for (date_Datelval.Number = 0;
00796 isdigit((c = *date_DateInput++)); ) {
00797 date_Datelval.Number = 10 * date_Datelval.Number + c - '0';
00798 Count++;
00799 }
00800 date_DateInput--;
00801
00802 if (Count >= 6) {
00803 return tISOBASE;
00804 } else {
00805 return tUNUMBER;
00806 }
00807 }
00808 if (!(c & 0x80) && isalpha(c)) {
00809 for (p = buff; isalpha((c = *date_DateInput++))
00810 || c == '.'; ) {
00811 if (p < &buff[sizeof buff - 1]) {
00812 *p++ = c;
00813 }
00814 }
00815 *p = '\0';
00816 date_DateInput--;
00817 return LookupWord(buff);
00818 }
00819 if (c != '(') {
00820 return *date_DateInput++;
00821 }
00822 Count = 0;
00823 do {
00824 c = *date_DateInput++;
00825 if (c == '\0') {
00826 return c;
00827 } else if (c == '(') {
00828 Count++;
00829 } else if (c == ')') {
00830 Count--;
00831 }
00832 } while (Count > 0);
00833 }
00834 }
00835
00836
00837
00838
00839
00840 int date_scan(char *timestr, time_t *now, int zone, time_t *timeptr)
00841 {
00842 struct tm *tm;
00843 time_t Start;
00844 time_t Time;
00845 time_t tod;
00846 int thisyear;
00847
00848
00849 if (zone == EGG_TIMEZONE_LOOKUP) zone = date_timezone();
00850
00851 date_DateInput = timestr;
00852
00853 Start = *now;
00854 tm = localtime(&Start);
00855 thisyear = tm->tm_year + TM_YEAR_BASE;
00856 date_DateYear = thisyear;
00857 date_DateMonth = tm->tm_mon + 1;
00858 date_DateDay = tm->tm_mday;
00859 date_DateTimezone = zone;
00860 if (zone == -50000) {
00861 date_DateDSTmode = DSToff;
00862 date_DateTimezone = 0;
00863 } else {
00864 date_DateDSTmode = DSTmaybe;
00865 }
00866 date_DateHour = 0;
00867 date_DateMinutes = 0;
00868 date_DateSeconds = 0;
00869 date_DateMeridian = MER24;
00870 date_DateRelSeconds = 0;
00871 date_DateRelMonth = 0;
00872 date_DateRelDay = 0;
00873 date_DateRelPointer = NULL;
00874
00875 date_DateHaveDate = 0;
00876 date_DateHaveDay = 0;
00877 date_DateHaveOrdinalMonth = 0;
00878 date_DateHaveRel = 0;
00879 date_DateHaveTime = 0;
00880 date_DateHaveZone = 0;
00881
00882 if (date_Dateparse() || date_DateHaveTime > 1 || date_DateHaveZone > 1 || date_DateHaveDate > 1 ||
00883 date_DateHaveDay > 1 || date_DateHaveOrdinalMonth > 1) {
00884 return -1;
00885 }
00886
00887 if (date_DateHaveDate || date_DateHaveTime || date_DateHaveDay) {
00888 if (date_DateYear < 0) {
00889 date_DateYear = -date_DateYear;
00890 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 if (date_DateYear < 100) {
00902 if (date_DateYear >= 69) {
00903 date_DateYear += 1900;
00904 } else {
00905 date_DateYear += 2000;
00906 }
00907 }
00908 if (Convert(date_DateMonth, date_DateDay, date_DateYear, date_DateHour, date_DateMinutes, date_DateSeconds,
00909 date_DateMeridian, date_DateDSTmode, &Start) < 0) {
00910 return -1;
00911 }
00912 } else {
00913 Start = *now;
00914 if (!date_DateHaveRel) {
00915 Start -= ((tm->tm_hour * 60L * 60L) +
00916 tm->tm_min * 60L) + tm->tm_sec;
00917 }
00918 }
00919
00920 Start += date_DateRelSeconds;
00921 if (RelativeMonth(Start, date_DateRelMonth, &Time) < 0) {
00922 return -1;
00923 }
00924 Start += Time;
00925
00926 if (RelativeDay(Start, date_DateRelDay, &Time) < 0) {
00927 return -1;
00928 }
00929 Start += Time;
00930
00931 if (date_DateHaveDay && !date_DateHaveDate) {
00932 tod = NamedDay(Start, date_DateDayOrdinal, date_DateDayNumber);
00933 Start += tod;
00934 }
00935
00936 if (date_DateHaveOrdinalMonth) {
00937 tod = NamedMonth(Start, date_DateMonthOrdinal, date_DateMonth);
00938 Start += tod;
00939 }
00940
00941 *timeptr = Start;
00942 return 0;
00943 }
00944 static date_Datetabelem date_Dateexca[] ={
00945 -1, 1,
00946 0, -1,
00947 -2, 0,
00948 };
00949 # define YYNPROD 56
00950 # define YYLAST 261
00951 static date_Datetabelem date_Dateact[]={
00952
00953 24, 40, 23, 36, 54, 81, 41, 28, 53, 26,
00954 37, 42, 58, 38, 56, 28, 27, 26, 28, 33,
00955 26, 32, 61, 50, 27, 80, 76, 27, 51, 75,
00956 74, 73, 30, 72, 71, 70, 69, 52, 49, 48,
00957 47, 45, 39, 62, 78, 46, 79, 68, 25, 65,
00958 60, 67, 66, 55, 44, 21, 63, 11, 10, 9,
00959 8, 35, 7, 6, 5, 4, 3, 43, 2, 1,
00960 20, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00961 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00962 0, 57, 0, 0, 59, 77, 0, 0, 0, 0,
00963 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00964 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00965 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00966 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00967 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00968 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00969 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00970 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00971 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00972 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00973 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00974 0, 0, 0, 0, 0, 19, 14, 0, 0, 0,
00975 16, 28, 22, 26, 0, 12, 13, 17, 0, 15,
00976 27, 18, 31, 0, 0, 29, 0, 34, 28, 0,
00977 26, 0, 0, 0, 0, 0, 0, 27, 0, 0,
00978 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,
00979 64 };
00980 static date_Datetabelem date_Datepact[]={
00981
00982 -10000000, -43,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,
00983 -10000000,-10000000, -26, -268,-10000000, -259, -226,-10000000, -257, 10,
00984 -227, -212, -228,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,
00985 -229,-10000000, -230, -240, -231,-10000000,-10000000, -264,-10000000, 9,
00986 -10000000,-10000000, -249,-10000000,-10000000, -246,-10000000, 4, -2, 2,
00987 7, 6,-10000000,-10000000, -11, -232,-10000000,-10000000,-10000000,-10000000,
00988 -233,-10000000, -234, -235,-10000000, -237, -238, -239, -242,-10000000,
00989 -10000000,-10000000, -1,-10000000,-10000000,-10000000, -12,-10000000, -243, -263,
00990 -10000000,-10000000 };
00991 static date_Datetabelem date_Datepgo[]={
00992
00993 0, 48, 70, 22, 69, 68, 66, 65, 64, 63,
00994 62, 60, 59, 58, 57, 55 };
00995 static date_Datetabelem date_Dater1[]={
00996
00997 0, 4, 4, 5, 5, 5, 5, 5, 5, 5,
00998 5, 5, 6, 6, 6, 6, 6, 7, 7, 7,
00999 10, 10, 10, 10, 10, 8, 8, 8, 8, 8,
01000 8, 8, 8, 8, 8, 9, 9, 12, 12, 12,
01001 13, 11, 11, 15, 15, 15, 15, 15, 2, 2,
01002 1, 1, 1, 14, 3, 3 };
01003 static date_Datetabelem date_Dater2[]={
01004
01005 0, 0, 4, 3, 3, 3, 3, 3, 3, 3,
01006 3, 2, 5, 9, 11, 13, 15, 5, 3, 3,
01007 3, 5, 5, 7, 5, 7, 11, 3, 11, 11,
01008 5, 9, 5, 3, 7, 5, 7, 7, 15, 5,
01009 9, 5, 2, 7, 5, 5, 7, 3, 3, 3,
01010 3, 3, 3, 3, 1, 3 };
01011 static date_Datetabelem date_Datechk[]={
01012
01013 -10000000, -4, -5, -6, -7, -8, -9, -10, -11, -12,
01014 -13, -14, 268, 269, 259, 272, 263, 270, 274, 258,
01015 -2, -15, 265, 45, 43, -1, 266, 273, 264, 261,
01016 58, 258, 47, 45, 263, -1, 271, 269, 272, 268,
01017 258, 263, 268, -1, 44, 268, 257, 268, 268, 268,
01018 263, 268, 268, 272, 268, 44, 263, -1, 258, -1,
01019 46, -3, 45, 58, 261, 47, 45, 45, 58, 268,
01020 268, 268, 268, 268, 268, 268, 268, -3, 45, 58,
01021 268, 268 };
01022 static date_Datetabelem date_Datedef[]={
01023
01024 1, -2, 2, 3, 4, 5, 6, 7, 8, 9,
01025 10, 11, 53, 18, 19, 27, 0, 33, 0, 20,
01026 0, 42, 0, 48, 49, 47, 50, 51, 52, 12,
01027 0, 22, 0, 0, 32, 44, 17, 0, 39, 30,
01028 24, 35, 0, 45, 21, 0, 41, 0, 54, 25,
01029 0, 0, 34, 37, 0, 0, 36, 46, 23, 43,
01030 0, 13, 0, 0, 55, 0, 0, 0, 0, 31,
01031 40, 14, 54, 26, 28, 29, 0, 15, 0, 0,
01032 16, 38 };
01033 typedef struct
01034 #ifdef __cplusplus
01035 date_Datetoktype
01036 #endif
01037 { char *t_name; int t_val; } date_Datetoktype;
01038 #ifndef YYDEBUG
01039 # define YYDEBUG 0
01040 #endif
01041
01042 #if YYDEBUG
01043
01044 date_Datetoktype date_Datetoks[] =
01045 {
01046 "tAGO", 257,
01047 "tDAY", 258,
01048 "tDAYZONE", 259,
01049 "tID", 260,
01050 "tMERIDIAN", 261,
01051 "tMINUTE_UNIT", 262,
01052 "tMONTH", 263,
01053 "tMONTH_UNIT", 264,
01054 "tSTARDATE", 265,
01055 "tSEC_UNIT", 266,
01056 "tSNUMBER", 267,
01057 "tUNUMBER", 268,
01058 "tZONE", 269,
01059 "tEPOCH", 270,
01060 "tDST", 271,
01061 "tISOBASE", 272,
01062 "tDAY_UNIT", 273,
01063 "tNEXT", 274,
01064 "-unknown-", -1
01065 };
01066
01067 char * date_Datereds[] =
01068 {
01069 "-no such reduction-",
01070 "spec : /* empty */",
01071 "spec : spec item",
01072 "item : time",
01073 "item : zone",
01074 "item : date",
01075 "item : ordMonth",
01076 "item : day",
01077 "item : relspec",
01078 "item : iso",
01079 "item : trek",
01080 "item : number",
01081 "time : tUNUMBER tMERIDIAN",
01082 "time : tUNUMBER ':' tUNUMBER o_merid",
01083 "time : tUNUMBER ':' tUNUMBER '-' tUNUMBER",
01084 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
01085 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER '-' tUNUMBER",
01086 "zone : tZONE tDST",
01087 "zone : tZONE",
01088 "zone : tDAYZONE",
01089 "day : tDAY",
01090 "day : tDAY ','",
01091 "day : tUNUMBER tDAY",
01092 "day : sign tUNUMBER tDAY",
01093 "day : tNEXT tDAY",
01094 "date : tUNUMBER '/' tUNUMBER",
01095 "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
01096 "date : tISOBASE",
01097 "date : tUNUMBER '-' tMONTH '-' tUNUMBER",
01098 "date : tUNUMBER '-' tUNUMBER '-' tUNUMBER",
01099 "date : tMONTH tUNUMBER",
01100 "date : tMONTH tUNUMBER ',' tUNUMBER",
01101 "date : tUNUMBER tMONTH",
01102 "date : tEPOCH",
01103 "date : tUNUMBER tMONTH tUNUMBER",
01104 "ordMonth : tNEXT tMONTH",
01105 "ordMonth : tNEXT tUNUMBER tMONTH",
01106 "iso : tISOBASE tZONE tISOBASE",
01107 "iso : tISOBASE tZONE tUNUMBER ':' tUNUMBER ':' tUNUMBER",
01108 "iso : tISOBASE tISOBASE",
01109 "trek : tSTARDATE tUNUMBER '.' tUNUMBER",
01110 "relspec : relunits tAGO",
01111 "relspec : relunits",
01112 "relunits : sign tUNUMBER unit",
01113 "relunits : tUNUMBER unit",
01114 "relunits : tNEXT unit",
01115 "relunits : tNEXT tUNUMBER unit",
01116 "relunits : unit",
01117 "sign : '-'",
01118 "sign : '+'",
01119 "unit : tSEC_UNIT",
01120 "unit : tDAY_UNIT",
01121 "unit : tMONTH_UNIT",
01122 "number : tUNUMBER",
01123 "o_merid : /* empty */",
01124 "o_merid : tMERIDIAN",
01125 };
01126 #endif
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 #define YYERROR goto date_Dateerrlab
01140 #define YYACCEPT return(0)
01141 #define YYABORT return(1)
01142 #define YYBACKUP( newtoken, newvalue )\
01143 {\
01144 if ( date_Datechar >= 0 || ( date_Dater2[ date_Datetmp ] >> 1 ) != 1 )\
01145 {\
01146 date_Dateerror( "syntax error - cannot backup" );\
01147 goto date_Dateerrlab;\
01148 }\
01149 date_Datechar = newtoken;\
01150 date_Datestate = *date_Dateps;\
01151 date_Datelval = newvalue;\
01152 goto date_Datenewstate;\
01153 }
01154 #define YYRECOVERING() (!!date_Dateerrflag)
01155 #define YYNEW(type) malloc(sizeof(type) * date_Datenewmax)
01156 #define YYCOPY(to, from, type) \
01157 (type *) memcpy(to, (char *) from, date_Datemaxdepth * sizeof (type))
01158 #define YYENLARGE( from, type) \
01159 (type *) realloc((char *) from, date_Datenewmax * sizeof(type))
01160 #ifndef YYDEBUG
01161 # define YYDEBUG 1
01162 #endif
01163
01164
01165
01166
01167 int date_Datedebug;
01168
01169
01170
01171
01172 #define YYFLAG (-10000000)
01173
01174
01175
01176
01177 YYSTYPE *date_Datepv;
01178 int *date_Dateps;
01179
01180 int date_Datestate;
01181 int date_Datetmp;
01182
01183 int date_Datenerrs;
01184 int date_Dateerrflag;
01185 int date_Datechar;
01186
01187
01188
01189 #ifdef YYNMBCHARS
01190 #define YYLEX() date_Datecvtok(date_Datelex())
01191
01192
01193
01194
01195
01196 #if defined(__STDC__) || defined(__cplusplus)
01197 int date_Datecvtok(int i)
01198 #else
01199 int date_Datecvtok(i) int i;
01200 #endif
01201 {
01202 int first = 0;
01203 int last = YYNMBCHARS - 1;
01204 int mid;
01205 wchar_t j;
01206
01207 if(i&0x60000000){
01208 if( date_Datembchars[last].character < i ){
01209 return i;
01210 }
01211 while ((last>=first)&&(first>=0)) {
01212 mid = (first+last)/2;
01213 j = date_Datembchars[mid].character;
01214 if( j==i ){
01215 return date_Datembchars[mid].tvalue;
01216 }else if( j<i ){
01217 first = mid + 1;
01218 }else{
01219 last = mid -1;
01220 }
01221 }
01222
01223 return i;
01224 }else{
01225 return i;
01226 }
01227 }
01228 #else
01229 #define YYLEX() date_Datelex()
01230 #endif
01232
01233
01234
01235 #if defined(__STDC__) || defined(__cplusplus)
01236 int date_Dateparse(void)
01237 #else
01238 int date_Dateparse()
01239 #endif
01240 {
01241 register YYSTYPE *date_Datepvt = 0;
01242
01243 #if defined(__cplusplus) || defined(lint)
01244
01245
01246
01247
01248 static int __yaccpar_lint_hack__ = 0;
01249 switch (__yaccpar_lint_hack__)
01250 {
01251 case 1: goto date_Dateerrlab;
01252 case 2: goto date_Datenewstate;
01253 }
01254 #endif
01255
01256
01257
01258
01259 date_Datepv = &date_Datev[-1];
01260 date_Dateps = &date_Dates[-1];
01261 date_Datestate = 0;
01262 date_Datetmp = 0;
01263 date_Datenerrs = 0;
01264 date_Dateerrflag = 0;
01265 date_Datechar = -1;
01266
01267 #if YYMAXDEPTH <= 0
01268 if (date_Datemaxdepth <= 0)
01269 {
01270 if ((date_Datemaxdepth = YYEXPAND(0)) <= 0)
01271 {
01272 date_Dateerror("yacc initialization error");
01273 YYABORT;
01274 }
01275 }
01276 #endif
01277
01278 {
01279 register YYSTYPE *date_Date_pv;
01280 register int *date_Date_ps;
01281 register int date_Date_state;
01282 register int date_Date_n;
01283 goto date_Datestack;
01284
01285
01286
01287
01288
01289 date_Date_pv = date_Datepv;
01290 date_Date_ps = date_Dateps;
01291 date_Date_state = date_Datestate;
01292 goto date_Date_newstate;
01293
01294
01295
01296
01297
01298 date_Datestack:
01299 date_Date_pv = date_Datepv;
01300 date_Date_ps = date_Dateps;
01301 date_Date_state = date_Datestate;
01302
01303
01304
01305
01306 date_Date_stack:
01307
01308
01309
01310 #if YYDEBUG
01311
01312
01313
01314
01315
01316
01317 if ( date_Datedebug )
01318 {
01319 register int date_Date_i;
01320
01321 printf( "State %d, token ", date_Date_state );
01322 if ( date_Datechar == 0 )
01323 printf( "end-of-file\n" );
01324 else if ( date_Datechar < 0 )
01325 printf( "-none-\n" );
01326 else
01327 {
01328 for ( date_Date_i = 0; date_Datetoks[date_Date_i].t_val >= 0;
01329 date_Date_i++ )
01330 {
01331 if ( date_Datetoks[date_Date_i].t_val == date_Datechar )
01332 break;
01333 }
01334 printf( "%s\n", date_Datetoks[date_Date_i].t_name );
01335 }
01336 }
01337 #endif
01338 if ( ++date_Date_ps >= &date_Dates[ date_Datemaxdepth ] )
01339 {
01340
01341
01342
01343
01344 long date_Dateps_index = (date_Date_ps - date_Dates);
01345 long date_Datepv_index = (date_Date_pv - date_Datev);
01346 long date_Datepvt_index = (date_Datepvt - date_Datev);
01347 int date_Datenewmax;
01348 #ifdef YYEXPAND
01349 date_Datenewmax = YYEXPAND(date_Datemaxdepth);
01350 #else
01351 date_Datenewmax = 2 * date_Datemaxdepth;
01352 if (date_Datemaxdepth == YYMAXDEPTH)
01353 {
01354 char *newdate_Dates = (char *)YYNEW(int);
01355 char *newdate_Datev = (char *)YYNEW(YYSTYPE);
01356 if (newdate_Dates != 0 && newdate_Datev != 0)
01357 {
01358 date_Dates = YYCOPY(newdate_Dates, date_Dates, int);
01359 date_Datev = YYCOPY(newdate_Datev, date_Datev, YYSTYPE);
01360 }
01361 else
01362 date_Datenewmax = 0;
01363 }
01364 else
01365 {
01366 date_Dates = YYENLARGE(date_Dates, int);
01367 date_Datev = YYENLARGE(date_Datev, YYSTYPE);
01368 if (date_Dates == 0 || date_Datev == 0)
01369 date_Datenewmax = 0;
01370 }
01371 #endif
01372 if (date_Datenewmax <= date_Datemaxdepth)
01373 {
01374 date_Dateerror( "yacc stack overflow" );
01375 YYABORT;
01376 }
01377 date_Datemaxdepth = date_Datenewmax;
01378
01379 date_Date_ps = date_Dates + date_Dateps_index;
01380 date_Date_pv = date_Datev + date_Datepv_index;
01381 date_Datepvt = date_Datev + date_Datepvt_index;
01382 }
01383 *date_Date_ps = date_Date_state;
01384 *++date_Date_pv = date_Dateval;
01385
01386
01387
01388
01389 date_Date_newstate:
01390 if ( ( date_Date_n = date_Datepact[ date_Date_state ] ) <= YYFLAG )
01391 goto date_Datedefault;
01392 #if YYDEBUG
01393
01394
01395
01396 date_Datetmp = date_Datechar < 0;
01397 #endif
01398 if ( ( date_Datechar < 0 ) && ( ( date_Datechar = YYLEX() ) < 0 ) )
01399 date_Datechar = 0;
01400 #if YYDEBUG
01401 if ( date_Datedebug && date_Datetmp )
01402 {
01403 register int date_Date_i;
01404
01405 printf( "Received token " );
01406 if ( date_Datechar == 0 )
01407 printf( "end-of-file\n" );
01408 else if ( date_Datechar < 0 )
01409 printf( "-none-\n" );
01410 else
01411 {
01412 for ( date_Date_i = 0; date_Datetoks[date_Date_i].t_val >= 0;
01413 date_Date_i++ )
01414 {
01415 if ( date_Datetoks[date_Date_i].t_val == date_Datechar )
01416 break;
01417 }
01418 printf( "%s\n", date_Datetoks[date_Date_i].t_name );
01419 }
01420 }
01421 #endif
01422 if ( ( ( date_Date_n += date_Datechar ) < 0 ) || ( date_Date_n >= YYLAST ) )
01423 goto date_Datedefault;
01424 if ( date_Datechk[ date_Date_n = date_Dateact[ date_Date_n ] ] == date_Datechar )
01425 {
01426 date_Datechar = -1;
01427 date_Dateval = date_Datelval;
01428 date_Date_state = date_Date_n;
01429 if ( date_Dateerrflag > 0 )
01430 date_Dateerrflag--;
01431 goto date_Date_stack;
01432 }
01433
01434 date_Datedefault:
01435 if ( ( date_Date_n = date_Datedef[ date_Date_state ] ) == -2 )
01436 {
01437 #if YYDEBUG
01438 date_Datetmp = date_Datechar < 0;
01439 #endif
01440 if ( ( date_Datechar < 0 ) && ( ( date_Datechar = YYLEX() ) < 0 ) )
01441 date_Datechar = 0;
01442 #if YYDEBUG
01443 if ( date_Datedebug && date_Datetmp )
01444 {
01445 register int date_Date_i;
01446
01447 printf( "Received token " );
01448 if ( date_Datechar == 0 )
01449 printf( "end-of-file\n" );
01450 else if ( date_Datechar < 0 )
01451 printf( "-none-\n" );
01452 else
01453 {
01454 for ( date_Date_i = 0;
01455 date_Datetoks[date_Date_i].t_val >= 0;
01456 date_Date_i++ )
01457 {
01458 if ( date_Datetoks[date_Date_i].t_val
01459 == date_Datechar )
01460 {
01461 break;
01462 }
01463 }
01464 printf( "%s\n", date_Datetoks[date_Date_i].t_name );
01465 }
01466 }
01467 #endif
01468
01469
01470
01471 {
01472 register int *date_Datexi = date_Dateexca;
01473
01474 while ( ( *date_Datexi != -1 ) ||
01475 ( date_Datexi[1] != date_Date_state ) )
01476 {
01477 date_Datexi += 2;
01478 }
01479 while ( ( *(date_Datexi += 2) >= 0 ) &&
01480 ( *date_Datexi != date_Datechar ) )
01481 ;
01482 if ( ( date_Date_n = date_Datexi[1] ) < 0 )
01483 YYACCEPT;
01484 }
01485 }
01486
01487
01488
01489
01490 if ( date_Date_n == 0 )
01491 {
01492
01493 switch ( date_Dateerrflag )
01494 {
01495 case 0:
01496 date_Dateerror( "syntax error" );
01497 goto skip_init;
01498
01499
01500
01501
01502 date_Date_pv = date_Datepv;
01503 date_Date_ps = date_Dateps;
01504 date_Date_state = date_Datestate;
01505 skip_init:
01506 date_Datenerrs++;
01507
01508 case 1:
01509 case 2:
01510
01511 date_Dateerrflag = 3;
01512
01513
01514
01515
01516 while ( date_Date_ps >= date_Dates )
01517 {
01518 date_Date_n = date_Datepact[ *date_Date_ps ] + YYERRCODE;
01519 if ( date_Date_n >= 0 && date_Date_n < YYLAST &&
01520 date_Datechk[date_Dateact[date_Date_n]] == YYERRCODE) {
01521
01522
01523
01524 date_Date_state = date_Dateact[ date_Date_n ];
01525 goto date_Date_stack;
01526 }
01527
01528
01529
01530
01531 #if YYDEBUG
01532 # define _POP_ "Error recovery pops state %d, uncovers state %d\n"
01533 if ( date_Datedebug )
01534 printf( _POP_, *date_Date_ps,
01535 date_Date_ps[-1] );
01536 # undef _POP_
01537 #endif
01538 date_Date_ps--;
01539 date_Date_pv--;
01540 }
01541
01542
01543
01544
01545 YYABORT;
01546 case 3:
01547 #if YYDEBUG
01548
01549
01550
01551
01552
01553
01554
01555 if ( date_Datedebug )
01556 {
01557 register int date_Date_i;
01558
01559 printf( "Error recovery discards " );
01560 if ( date_Datechar == 0 )
01561 printf( "token end-of-file\n" );
01562 else if ( date_Datechar < 0 )
01563 printf( "token -none-\n" );
01564 else
01565 {
01566 for ( date_Date_i = 0;
01567 date_Datetoks[date_Date_i].t_val >= 0;
01568 date_Date_i++ )
01569 {
01570 if ( date_Datetoks[date_Date_i].t_val
01571 == date_Datechar )
01572 {
01573 break;
01574 }
01575 }
01576 printf( "token %s\n",
01577 date_Datetoks[date_Date_i].t_name );
01578 }
01579 }
01580 #endif
01581 if ( date_Datechar == 0 )
01582 YYABORT;
01583 date_Datechar = -1;
01584 goto date_Date_newstate;
01585 }
01586 }
01587
01588
01589
01590
01591 #if YYDEBUG
01592
01593
01594
01595
01596
01597 if ( date_Datedebug )
01598 printf( "Reduce by (%d) \"%s\"\n",
01599 date_Date_n, date_Datereds[ date_Date_n ] );
01600 #endif
01601 date_Datetmp = date_Date_n;
01602 date_Datepvt = date_Date_pv;
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615 {
01616
01617 register int date_Date_len = date_Dater2[ date_Date_n ];
01618
01619 if ( !( date_Date_len & 01 ) )
01620 {
01621 date_Date_len >>= 1;
01622 date_Dateval = ( date_Date_pv -= date_Date_len )[1];
01623 date_Date_state = date_Datepgo[ date_Date_n = date_Dater1[ date_Date_n ] ] +
01624 *( date_Date_ps -= date_Date_len ) + 1;
01625 if ( date_Date_state >= YYLAST ||
01626 date_Datechk[ date_Date_state =
01627 date_Dateact[ date_Date_state ] ] != -date_Date_n )
01628 {
01629 date_Date_state = date_Dateact[ date_Datepgo[ date_Date_n ] ];
01630 }
01631 goto date_Date_stack;
01632 }
01633 date_Date_len >>= 1;
01634 date_Dateval = ( date_Date_pv -= date_Date_len )[1];
01635 date_Date_state = date_Datepgo[ date_Date_n = date_Dater1[ date_Date_n ] ] +
01636 *( date_Date_ps -= date_Date_len ) + 1;
01637 if ( date_Date_state >= YYLAST ||
01638 date_Datechk[ date_Date_state = date_Dateact[ date_Date_state ] ] != -date_Date_n )
01639 {
01640 date_Date_state = date_Dateact[ date_Datepgo[ date_Date_n ] ];
01641 }
01642 }
01643
01644 date_Datestate = date_Date_state;
01645 date_Dateps = date_Date_ps;
01646 date_Datepv = date_Date_pv;
01647 }
01648
01649
01650
01651 switch( date_Datetmp )
01652 {
01653
01654 case 3:{
01655 date_DateHaveTime++;
01656 } break;
01657 case 4:{
01658 date_DateHaveZone++;
01659 } break;
01660 case 5:{
01661 date_DateHaveDate++;
01662 } break;
01663 case 6:{
01664 date_DateHaveOrdinalMonth++;
01665 } break;
01666 case 7:{
01667 date_DateHaveDay++;
01668 } break;
01669 case 8:{
01670 date_DateHaveRel++;
01671 } break;
01672 case 9:{
01673 date_DateHaveTime++;
01674 date_DateHaveDate++;
01675 } break;
01676 case 10:{
01677 date_DateHaveTime++;
01678 date_DateHaveDate++;
01679 date_DateHaveRel++;
01680 } break;
01681 case 12:{
01682 date_DateHour = date_Datepvt[-1].Number;
01683 date_DateMinutes = 0;
01684 date_DateSeconds = 0;
01685 date_DateMeridian = date_Datepvt[-0].Meridian;
01686 } break;
01687 case 13:{
01688 date_DateHour = date_Datepvt[-3].Number;
01689 date_DateMinutes = date_Datepvt[-1].Number;
01690 date_DateSeconds = 0;
01691 date_DateMeridian = date_Datepvt[-0].Meridian;
01692 } break;
01693 case 14:{
01694 date_DateHour = date_Datepvt[-4].Number;
01695 date_DateMinutes = date_Datepvt[-2].Number;
01696 date_DateMeridian = MER24;
01697 date_DateDSTmode = DSToff;
01698 date_DateTimezone = (date_Datepvt[-0].Number % 100 + (date_Datepvt[-0].Number / 100) * 60);
01699 } break;
01700 case 15:{
01701 date_DateHour = date_Datepvt[-5].Number;
01702 date_DateMinutes = date_Datepvt[-3].Number;
01703 date_DateSeconds = date_Datepvt[-1].Number;
01704 date_DateMeridian = date_Datepvt[-0].Meridian;
01705 } break;
01706 case 16:{
01707 date_DateHour = date_Datepvt[-6].Number;
01708 date_DateMinutes = date_Datepvt[-4].Number;
01709 date_DateSeconds = date_Datepvt[-2].Number;
01710 date_DateMeridian = MER24;
01711 date_DateDSTmode = DSToff;
01712 date_DateTimezone = (date_Datepvt[-0].Number % 100 + (date_Datepvt[-0].Number / 100) * 60);
01713 } break;
01714 case 17:{
01715 date_DateTimezone = date_Datepvt[-1].Number;
01716 date_DateDSTmode = DSTon;
01717 } break;
01718 case 18:{
01719 date_DateTimezone = date_Datepvt[-0].Number;
01720 date_DateDSTmode = DSToff;
01721 } break;
01722 case 19:{
01723 date_DateTimezone = date_Datepvt[-0].Number;
01724 date_DateDSTmode = DSTon;
01725 } break;
01726 case 20:{
01727 date_DateDayOrdinal = 1;
01728 date_DateDayNumber = date_Datepvt[-0].Number;
01729 } break;
01730 case 21:{
01731 date_DateDayOrdinal = 1;
01732 date_DateDayNumber = date_Datepvt[-1].Number;
01733 } break;
01734 case 22:{
01735 date_DateDayOrdinal = date_Datepvt[-1].Number;
01736 date_DateDayNumber = date_Datepvt[-0].Number;
01737 } break;
01738 case 23:{
01739 date_DateDayOrdinal = date_Datepvt[-2].Number * date_Datepvt[-1].Number;
01740 date_DateDayNumber = date_Datepvt[-0].Number;
01741 } break;
01742 case 24:{
01743 date_DateDayOrdinal = 2;
01744 date_DateDayNumber = date_Datepvt[-0].Number;
01745 } break;
01746 case 25:{
01747 date_DateMonth = date_Datepvt[-2].Number;
01748 date_DateDay = date_Datepvt[-0].Number;
01749 } break;
01750 case 26:{
01751 date_DateMonth = date_Datepvt[-4].Number;
01752 date_DateDay = date_Datepvt[-2].Number;
01753 date_DateYear = date_Datepvt[-0].Number;
01754 } break;
01755 case 27:{
01756 date_DateYear = date_Datepvt[-0].Number / 10000;
01757 date_DateMonth = (date_Datepvt[-0].Number % 10000)/100;
01758 date_DateDay = date_Datepvt[-0].Number % 100;
01759 } break;
01760 case 28:{
01761 date_DateDay = date_Datepvt[-4].Number;
01762 date_DateMonth = date_Datepvt[-2].Number;
01763 date_DateYear = date_Datepvt[-0].Number;
01764 } break;
01765 case 29:{
01766 date_DateMonth = date_Datepvt[-2].Number;
01767 date_DateDay = date_Datepvt[-0].Number;
01768 date_DateYear = date_Datepvt[-4].Number;
01769 } break;
01770 case 30:{
01771 date_DateMonth = date_Datepvt[-1].Number;
01772 date_DateDay = date_Datepvt[-0].Number;
01773 } break;
01774 case 31:{
01775 date_DateMonth = date_Datepvt[-3].Number;
01776 date_DateDay = date_Datepvt[-2].Number;
01777 date_DateYear = date_Datepvt[-0].Number;
01778 } break;
01779 case 32:{
01780 date_DateMonth = date_Datepvt[-0].Number;
01781 date_DateDay = date_Datepvt[-1].Number;
01782 } break;
01783 case 33:{
01784 date_DateMonth = 1;
01785 date_DateDay = 1;
01786 date_DateYear = EPOCH;
01787 } break;
01788 case 34:{
01789 date_DateMonth = date_Datepvt[-1].Number;
01790 date_DateDay = date_Datepvt[-2].Number;
01791 date_DateYear = date_Datepvt[-0].Number;
01792 } break;
01793 case 35:{
01794 date_DateMonthOrdinal = 1;
01795 date_DateMonth = date_Datepvt[-0].Number;
01796 } break;
01797 case 36:{
01798 date_DateMonthOrdinal = date_Datepvt[-1].Number;
01799 date_DateMonth = date_Datepvt[-0].Number;
01800 } break;
01801 case 37:{
01802 if (date_Datepvt[-1].Number != HOUR(- 7)) YYABORT;
01803 date_DateYear = date_Datepvt[-2].Number / 10000;
01804 date_DateMonth = (date_Datepvt[-2].Number % 10000)/100;
01805 date_DateDay = date_Datepvt[-2].Number % 100;
01806 date_DateHour = date_Datepvt[-0].Number / 10000;
01807 date_DateMinutes = (date_Datepvt[-0].Number % 10000)/100;
01808 date_DateSeconds = date_Datepvt[-0].Number % 100;
01809 } break;
01810 case 38:{
01811 if (date_Datepvt[-5].Number != HOUR(- 7)) YYABORT;
01812 date_DateYear = date_Datepvt[-6].Number / 10000;
01813 date_DateMonth = (date_Datepvt[-6].Number % 10000)/100;
01814 date_DateDay = date_Datepvt[-6].Number % 100;
01815 date_DateHour = date_Datepvt[-4].Number;
01816 date_DateMinutes = date_Datepvt[-2].Number;
01817 date_DateSeconds = date_Datepvt[-0].Number;
01818 } break;
01819 case 39:{
01820 date_DateYear = date_Datepvt[-1].Number / 10000;
01821 date_DateMonth = (date_Datepvt[-1].Number % 10000)/100;
01822 date_DateDay = date_Datepvt[-1].Number % 100;
01823 date_DateHour = date_Datepvt[-0].Number / 10000;
01824 date_DateMinutes = (date_Datepvt[-0].Number % 10000)/100;
01825 date_DateSeconds = date_Datepvt[-0].Number % 100;
01826 } break;
01827 case 40:{
01828
01829
01830
01831
01832 date_DateYear = date_Datepvt[-2].Number/1000 + 2323 - 377;
01833 date_DateDay = 1;
01834 date_DateMonth = 1;
01835 date_DateRelDay += ((date_Datepvt[-2].Number%1000)*(365 + IsLeapYear(date_DateYear)))/1000;
01836 date_DateRelSeconds += date_Datepvt[-0].Number * 144 * 60;
01837 } break;
01838 case 41:{
01839 date_DateRelSeconds *= -1;
01840 date_DateRelMonth *= -1;
01841 date_DateRelDay *= -1;
01842 } break;
01843 case 43:{ *date_DateRelPointer += date_Datepvt[-2].Number * date_Datepvt[-1].Number * date_Datepvt[-0].Number; } break;
01844 case 44:{ *date_DateRelPointer += date_Datepvt[-1].Number * date_Datepvt[-0].Number; } break;
01845 case 45:{ *date_DateRelPointer += date_Datepvt[-0].Number; } break;
01846 case 46:{ *date_DateRelPointer += date_Datepvt[-1].Number * date_Datepvt[-0].Number; } break;
01847 case 47:{ *date_DateRelPointer += date_Datepvt[-0].Number; } break;
01848 case 48:{ date_Dateval.Number = -1; } break;
01849 case 49:{ date_Dateval.Number = 1; } break;
01850 case 50:{ date_Dateval.Number = date_Datepvt[-0].Number; date_DateRelPointer = &date_DateRelSeconds; } break;
01851 case 51:{ date_Dateval.Number = date_Datepvt[-0].Number; date_DateRelPointer = &date_DateRelDay; } break;
01852 case 52:{ date_Dateval.Number = date_Datepvt[-0].Number; date_DateRelPointer = &date_DateRelMonth; } break;
01853 case 53:{
01854 if (date_DateHaveTime && date_DateHaveDate && !date_DateHaveRel) {
01855 date_DateYear = date_Datepvt[-0].Number;
01856 } else {
01857 date_DateHaveTime++;
01858 if (date_Datepvt[-0].Number < 100) {
01859 date_DateHour = date_Datepvt[-0].Number;
01860 date_DateMinutes = 0;
01861 } else {
01862 date_DateHour = date_Datepvt[-0].Number / 100;
01863 date_DateMinutes = date_Datepvt[-0].Number % 100;
01864 }
01865 date_DateSeconds = 0;
01866 date_DateMeridian = MER24;
01867 }
01868 } break;
01869 case 54:{
01870 date_Dateval.Meridian = MER24;
01871 } break;
01872 case 55:{
01873 date_Dateval.Meridian = date_Datepvt[-0].Meridian;
01874 } break;
01875 }
01876 goto date_Datestack;
01877 }
01878