This is parsedate.c in view mode; [Download] [Up]
# line 2 "parsedate.y" /* $Revision: 1.1.1.1 $ ** ** Originally written by Steven M. Bellovin <smb@research.att.com> while ** at the University of North Carolina at Chapel Hill. Later tweaked by ** a couple of people on Usenet. Completely overhauled by Rich $alz ** <rsalz@osf.org> and Jim Berets <jberets@bbn.com> in August, 1990. ** Further revised (removed obsolete constructs and cleaned up timezone ** names) in August, 1991, by Rich. Paul Eggert <eggert@twinsun.com> ** helped in September, 1992. ** ** This grammar has six shift/reduce conflicts. ** ** This code is in the public domain and has no copyright. */ /* SUPPRESS 530 *//* Empty body for statement */ /* SUPPRESS 593 on yyerrlab *//* Label was not used */ /* SUPPRESS 593 on yynewstate *//* Label was not used */ /* SUPPRESS 595 on yypvt *//* Automatic variable may be used before set */ #include <stdio.h> #include <sys/types.h> #include <ctype.h> #include <time.h> #define yyparse date_parse #define yylex date_lex #define yyerror date_error /* See the LeapYears table in Convert. */ #define EPOCH 1970 #define END_OF_TIME 2038 /* Constants for general time calculations. */ #define DST_OFFSET 1 #define SECSPERDAY (24L * 60L * 60L) /* Readability for TABLE stuff. */ #define HOUR(x) (x * 60) #define LPAREN '(' #define RPAREN ')' #define IS7BIT(x) ((unsigned int)(x) < 0200) #define SIZEOF(array) ((int)(sizeof array / sizeof array[0])) #define ENDOF(array) (&array[SIZEOF(array)]) /* ** An entry in the lexical lookup table. */ typedef struct _TABLE { char *name; int type; time_t value; } TABLE; /* ** Daylight-savings mode: on, off, or not yet known. */ typedef enum _DSTMODE { DSTon, DSToff, DSTmaybe } DSTMODE; /* ** Meridian: am, pm, or 24-hour style. */ typedef enum _MERIDIAN { MERam, MERpm, MER24 } MERIDIAN; /* ** Global variables. We could get rid of most of them by using a yacc ** union, but this is more efficient. (This routine predates the ** yacc %union construct.) */ static char *yyInput; static DSTMODE yyDSTmode; static int yyHaveDate; static int yyHaveRel; static int yyHaveTime; static time_t yyTimezone; static time_t yyDay; static time_t yyHour; static time_t yyMinutes; static time_t yyMonth; static time_t yySeconds; static time_t yyYear; static MERIDIAN yyMeridian; static time_t yyRelMonth; static time_t yyRelSeconds; extern struct tm *localtime(); static void date_error(); # line 98 "parsedate.y" typedef union { time_t Number; enum _MERIDIAN Meridian; } YYSTYPE; # define tDAY 257 # define tDAYZONE 258 # define tMERIDIAN 259 # define tMONTH 260 # define tMONTH_UNIT 261 # define tSEC_UNIT 262 # define tSNUMBER 263 # define tUNUMBER 264 # define tZONE 265 #define yyclearin yychar = -1 #define yyerrok yyerrflag = 0 extern int yychar; extern short yyerrflag; #ifndef YYMAXDEPTH #define YYMAXDEPTH 150 #endif YYSTYPE yylval, yyval; # define YYERRCODE 256 # line 284 "parsedate.y" /* Month and day table. */ static TABLE MonthDayTable[] = { { "january", tMONTH, 1 }, { "february", tMONTH, 2 }, { "march", tMONTH, 3 }, { "april", tMONTH, 4 }, { "may", tMONTH, 5 }, { "june", tMONTH, 6 }, { "july", tMONTH, 7 }, { "august", tMONTH, 8 }, { "september", tMONTH, 9 }, { "october", tMONTH, 10 }, { "november", tMONTH, 11 }, { "december", tMONTH, 12 }, /* The value of the day isn't used... */ { "sunday", tDAY, 0 }, { "monday", tDAY, 0 }, { "tuesday", tDAY, 0 }, { "wednesday", tDAY, 0 }, { "thursday", tDAY, 0 }, { "friday", tDAY, 0 }, { "saturday", tDAY, 0 }, }; /* Time units table. */ static TABLE UnitsTable[] = { { "year", tMONTH_UNIT, 12 }, { "month", tMONTH_UNIT, 1 }, { "week", tSEC_UNIT, 7L * 24 * 60 * 60 }, { "day", tSEC_UNIT, 1L * 24 * 60 * 60 }, { "hour", tSEC_UNIT, 60 * 60 }, { "minute", tSEC_UNIT, 60 }, { "min", tSEC_UNIT, 60 }, { "second", tSEC_UNIT, 1 }, { "sec", tSEC_UNIT, 1 }, }; /* Timezone table. */ static TABLE TimezoneTable[] = { { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */ { "ut", tZONE, HOUR( 0) }, /* Universal */ { "utc", tZONE, HOUR( 0) }, /* Universal Coordinated */ { "cut", tZONE, HOUR( 0) }, /* Coordinated Universal */ { "z", tZONE, HOUR( 0) }, /* Greenwich Mean */ { "wet", tZONE, HOUR( 0) }, /* Western European */ { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */ { "nst", tZONE, HOUR(3)+30 }, /* Newfoundland Standard */ { "ndt", tDAYZONE, HOUR(3)+30 }, /* Newfoundland Daylight */ { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */ { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */ { "est", tZONE, HOUR( 5) }, /* Eastern Standard */ { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */ { "cst", tZONE, HOUR( 6) }, /* Central Standard */ { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */ { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */ { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */ { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */ { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */ { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */ { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */ { "akst", tZONE, HOUR( 9) }, /* Alaska Standard */ { "akdt", tDAYZONE, HOUR( 9) }, /* Alaska Daylight */ { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */ { "hast", tZONE, HOUR(10) }, /* Hawaii-Aleutian Standard */ { "hadt", tDAYZONE, HOUR(10) }, /* Hawaii-Aleutian Daylight */ { "ces", tDAYZONE, -HOUR(1) }, /* Central European Summer */ { "cest", tDAYZONE, -HOUR(1) }, /* Central European Summer */ { "mez", tZONE, -HOUR(1) }, /* Middle European */ { "mezt", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ { "cet", tZONE, -HOUR(1) }, /* Central European */ { "met", tZONE, -HOUR(1) }, /* Middle European */ { "eet", tZONE, -HOUR(2) }, /* Eastern Europe */ { "msk", tZONE, -HOUR(3) }, /* Moscow Winter */ { "msd", tDAYZONE, -HOUR(3) }, /* Moscow Summer */ { "wast", tZONE, -HOUR(8) }, /* West Australian Standard */ { "wadt", tDAYZONE, -HOUR(8) }, /* West Australian Daylight */ { "hkt", tZONE, -HOUR(8) }, /* Hong Kong */ { "cct", tZONE, -HOUR(8) }, /* China Coast */ { "jst", tZONE, -HOUR(9) }, /* Japan Standard */ { "kst", tZONE, -HOUR(9) }, /* Korean Standard */ { "kdt", tZONE, -HOUR(9) }, /* Korean Daylight */ { "cast", tZONE, -(HOUR(9)+30) }, /* Central Australian Standard */ { "cadt", tDAYZONE, -(HOUR(9)+30) }, /* Central Australian Daylight */ { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */ { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */ { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */ { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ /* For completeness we include the following entries. */ #if 0 /* Duplicate names. Either they conflict with a zone listed above * (which is either more likely to be seen or just been in circulation * longer), or they conflict with another zone in this section and * we could not reasonably choose one over the other. */ { "fst", tZONE, HOUR( 2) }, /* Fernando De Noronha Standard */ { "fdt", tDAYZONE, HOUR( 2) }, /* Fernando De Noronha Daylight */ { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */ { "est", tZONE, HOUR( 3) }, /* Eastern Standard (Brazil) */ { "edt", tDAYZONE, HOUR( 3) }, /* Eastern Daylight (Brazil) */ { "wst", tZONE, HOUR( 4) }, /* Western Standard (Brazil) */ { "wdt", tDAYZONE, HOUR( 4) }, /* Western Daylight (Brazil) */ { "cst", tZONE, HOUR( 5) }, /* Chile Standard */ { "cdt", tDAYZONE, HOUR( 5) }, /* Chile Daylight */ { "ast", tZONE, HOUR( 5) }, /* Acre Standard */ { "adt", tDAYZONE, HOUR( 5) }, /* Acre Daylight */ { "cst", tZONE, HOUR( 5) }, /* Cuba Standard */ { "cdt", tDAYZONE, HOUR( 5) }, /* Cuba Daylight */ { "est", tZONE, HOUR( 6) }, /* Easter Island Standard */ { "edt", tDAYZONE, HOUR( 6) }, /* Easter Island Daylight */ { "sst", tZONE, HOUR(11) }, /* Samoa Standard */ { "ist", tZONE, -HOUR(2) }, /* Israel Standard */ { "idt", tDAYZONE, -HOUR(2) }, /* Israel Daylight */ { "idt", tDAYZONE, -(HOUR(3)+30) }, /* Iran Daylight */ { "ist", tZONE, -(HOUR(3)+30) }, /* Iran Standard */ { "cst", tZONE, -HOUR(8) }, /* China Standard */ { "cdt", tDAYZONE, -HOUR(8) }, /* China Daylight */ { "sst", tZONE, -HOUR(8) }, /* Singapore Standard */ /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */ { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */ { "wat", tZONE, -HOUR(1) }, /* West Africa */ { "at", tZONE, HOUR( 2) }, /* Azores */ { "gst", tZONE, -HOUR(10) }, /* Guam Standard */ { "nft", tZONE, HOUR(3)+30 }, /* Newfoundland */ { "idlw", tZONE, HOUR(12) }, /* International Date Line West */ { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */ { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */ { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */ { "fwt", tZONE, -HOUR(1) }, /* French Winter */ { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */ { "bt", tZONE, -HOUR(3) }, /* Baghdad */ { "it", tZONE, -(HOUR(3)+30) }, /* Iran */ { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */ { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */ { "ist", tZONE, -(HOUR(5)+30) }, /* Indian Standard */ { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */ { "nst", tZONE, -HOUR(7) }, /* North Sumatra */ { "sst", tZONE, -HOUR(7) }, /* South Sumatra */ { "jt", tZONE, -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */ { "nzt", tZONE, -HOUR(12) }, /* New Zealand */ { "idle", tZONE, -HOUR(12) }, /* International Date Line East */ { "cat", tZONE, HOUR(10) }, /* -- expired 1967 */ { "nt", tZONE, HOUR(11) }, /* -- expired 1967 */ { "ahst", tZONE, HOUR(10) }, /* -- expired 1983 */ { "hdt", tDAYZONE, HOUR(10) }, /* -- expired 1986 */ #endif /* 0 */ }; /* ARGSUSED */ static void date_error(s) char *s; { /* NOTREACHED */ } static time_t ToSeconds(Hours, Minutes, Seconds, Meridian) time_t Hours; time_t Minutes; time_t Seconds; MERIDIAN Meridian; { if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61) return -1; if (Meridian == MER24) { if (Hours < 0 || Hours > 23) return -1; } else { if (Hours < 1 || Hours > 12) return -1; if (Hours == 12) Hours = 0; if (Meridian == MERpm) Hours += 12; } return (Hours * 60L + Minutes) * 60L + Seconds; } static time_t Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, dst) time_t Month; time_t Day; time_t Year; time_t Hours; time_t Minutes; time_t Seconds; MERIDIAN Meridian; DSTMODE dst; { static int DaysNormal[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static int DaysLeap[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static int LeapYears[] = { 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036 }; register int *yp; register int *mp; register time_t Julian; register int i; time_t tod; if (Year < 0) Year = -Year; if (Year < 100) Year += 1900; if (Year < EPOCH) Year += 100; for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++) if (Year == *yp) { mp = DaysLeap; break; } if (Year < EPOCH || Year > END_OF_TIME || Month < 1 || Month > 12 /* NOSTRICT *//* conversion from long may lose accuracy */ || Day < 1 || Day > mp[(int)Month]) return -1; Julian = Day - 1 + (Year - EPOCH) * 365; for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++) if (Year <= *yp) break; for (i = 1; i < Month; i++) Julian += *++mp; Julian *= SECSPERDAY; Julian += yyTimezone * 60L; if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) return -1; Julian += tod; tod = Julian; if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst)) Julian -= DST_OFFSET * 60L * 60L; return Julian; } static time_t DSTcorrect(Start, Future) time_t Start; time_t Future; { time_t StartDay; time_t FutureDay; StartDay = (localtime(&Start)->tm_hour + 1) % 24; FutureDay = (localtime(&Future)->tm_hour + 1) % 24; return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60L * 60L; } static time_t RelativeMonth(Start, RelMonth) time_t Start; time_t RelMonth; { struct tm *tm; time_t Month; time_t Year; tm = localtime(&Start); Month = 12 * tm->tm_year + tm->tm_mon + RelMonth; Year = Month / 12; Month = Month % 12 + 1; return DSTcorrect(Start, Convert(Month, (time_t)tm->tm_mday, Year, (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, MER24, DSTmaybe)); } static int LookupWord(buff, length) char *buff; register int length; { register char *p; register char *q; register TABLE *tp; register int c; p = buff; c = p[0]; /* See if we have an abbreviation for a month. */ if (length == 3 || (length == 4 && p[3] == '.')) for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) { q = tp->name; if (c == q[0] && p[1] == q[1] && p[2] == q[2]) { yylval.Number = tp->value; return tp->type; } } else for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) if (c == tp->name[0] && strcmp(p, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } /* Try for a timezone. */ for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) if (c == tp->name[0] && p[1] == tp->name[1] && strcmp(p, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } /* Try the units table. */ for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) if (c == tp->name[0] && strcmp(p, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } /* Strip off any plural and try the units table again. */ if (--length > 0 && p[length] == 's') { p[length] = '\0'; for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) if (c == tp->name[0] && strcmp(p, tp->name) == 0) { p[length] = 's'; yylval.Number = tp->value; return tp->type; } p[length] = 's'; } length++; /* Drop out any periods. */ for (p = buff, q = (char*)buff; *q; q++) if (*q != '.') *p++ = *q; *p = '\0'; /* Try the meridians. */ if (buff[1] == 'm' && buff[2] == '\0') { if (buff[0] == 'a') { yylval.Meridian = MERam; return tMERIDIAN; } if (buff[0] == 'p') { yylval.Meridian = MERpm; return tMERIDIAN; } } /* If we saw any periods, try the timezones again. */ if (p - buff != length) { c = buff[0]; for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) if (c == tp->name[0] && p[1] == tp->name[1] && strcmp(p, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } } /* Unknown word -- assume GMT timezone. */ yylval.Number = 0; return tZONE; } int date_lex() { register char c; register char *p; char buff[20]; register int sign; register int i; register int nesting; for ( ; ; ) { /* Get first character after the whitespace. */ for ( ; ; ) { while (isspace(*yyInput)) yyInput++; c = *yyInput; /* Ignore RFC 822 comments, typically time zone names. */ if (c != LPAREN) break; for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; ) if (c == LPAREN) nesting++; else if (!IS7BIT(c) || c == '\0' || c == '\r' || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c)))) /* Lexical error: bad comment. */ return '?'; yyInput++; } /* A number? */ if (isdigit(c) || c == '-' || c == '+') { if (c == '-' || c == '+') { sign = c == '-' ? -1 : 1; yyInput++; if (!isdigit(*yyInput)) /* Skip the plus or minus sign. */ continue; } else sign = 0; for (i = 0; (c = *yyInput++) != '\0' && isdigit(c); ) i = 10 * i + c - '0'; yyInput--; yylval.Number = sign < 0 ? -i : i; return sign ? tSNUMBER : tUNUMBER; } /* A word? */ if (isalpha(c)) { for (p = buff; (c = *yyInput++) == '.' || isalpha(c); ) if (p < &buff[sizeof buff - 1]) *p++ = isupper(c) ? tolower(c) : c; *p = '\0'; yyInput--; return LookupWord(buff, p - buff); } return *yyInput++; } } time_t parsedate(p) char *p; { extern int date_parse(); time_t Start; yyInput = p; yyYear = 0; yyMonth = 0; yyDay = 0; yyTimezone = 0; yyDSTmode = DSTmaybe; yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; yyRelSeconds = 0; yyRelMonth = 0; yyHaveDate = 0; yyHaveRel = 0; yyHaveTime = 0; if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1) return -1; if (yyHaveDate || yyHaveTime) { Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, yyMeridian, yyDSTmode); if (Start < 0) return -1; } else return -1; Start += yyRelSeconds; if (yyRelMonth) Start += RelativeMonth(Start, yyRelMonth); /* Have to do *something* with a legitimate -1 so it's distinguishable * from the error return value. (Alternately could set errno on error.) */ return Start == -1 ? 0 : Start; } #ifdef TEST #if YYDEBUG extern int yydebug; #endif /* YYDEBUG */ /* ARGSUSED */ int main(ac, av) int ac; char *av[]; { char buff[128]; time_t d; #if YYDEBUG yydebug = 1; #endif /* YYDEBUG */ (void)printf("Enter date, or blank line to exit.\n\t> "); for ( ; ; ) { (void)printf("\t> "); (void)fflush(stdout); if (gets(buff) == NULL || buff[0] == '\n') break; #if YYDEBUG if (strcmp(buff, "yydebug") == 0) { yydebug = !yydebug; printf("yydebug = %s\n", yydebug ? "on" : "off"); continue; } #endif /* YYDEBUG */ d = parsedate(buff); if (d == -1) (void)printf("Bad format - couldn't convert.\n"); else (void)printf("%s", ctime(&d)); } exit(0); /* NOTREACHED */ } #endif /* TEST */ short yyexca[] ={ -1, 1, 0, -1, -2, 0, }; # define YYNPROD 30 # define YYLAST 216 short yyact[]={ 17, 12, 34, 40, 39, 21, 14, 8, 11, 14, 7, 16, 38, 9, 6, 36, 31, 29, 28, 27, 22, 14, 25, 24, 37, 35, 30, 23, 13, 15, 5, 4, 3, 2, 1, 10, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 14, 0, 0, 0, 0, 21, 18, 20, 19 }; short yypact[]={ -1000,-250,-1000,-257,-1000,-1000, -47,-244, -17,-239, -1000,-242,-1000,-1000,-1000,-1000,-245,-246,-247,-1000, -1000,-1000, -18,-248,-1000,-1000,-1000, -56, -22,-1000, -249,-236,-1000,-1000,-252,-260,-1000,-261,-254,-1000, -1000,-1000,-1000 }; short yypgo[]={ 0, 28, 35, 29, 34, 33, 32, 31, 30 }; short yyr1[]={ 0, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 2, 2, 2, 2, 1, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 3, 3 }; short yyr2[]={ 0, 0, 2, 1, 2, 1, 1, 2, 4, 4, 6, 6, 1, 1, 2, 1, 1, 3, 5, 2, 4, 2, 3, 5, 2, 2, 2, 2, 0, 1 }; short yychk[]={ -1000, -4, -5, -6, -7, -8, 264, 260, 257, 263, -2, 265, 258, -1, 263, -3, 58, 47, 260, 262, 261, 259, 264, 44, 262, 261, -1, 264, 264, 264, 44, 264, -3, -1, 58, 47, 264, 260, 264, 264, 264, -3, -1 }; short yydef[]={ 1, -2, 2, 3, 5, 6, 28, 0, 0, 0, 4, 12, 13, 15, 16, 7, 0, 0, 21, 25, 27, 29, 19, 0, 24, 26, 14, 28, 17, 22, 0, 0, 8, 9, 0, 0, 20, 0, 28, 18, 23, 10, 11 }; # line 1 "/usr/lib/yaccpar" # define YYFLAG -1000 # define YYERROR goto yyerrlab # define YYACCEPT return(0) # define YYABORT return(1) /* parser for yacc output */ #ifdef YYDEBUG int yydebug = 0; /* 1 for debugging */ #endif YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */ int yychar = -1; /* current input token number */ int yynerrs = 0; /* number of errors */ short yyerrflag = 0; /* error recovery flag */ int yyparse() { short yys[YYMAXDEPTH]; short yyj, yym; register YYSTYPE *yypvt; register short yystate, *yyps, yyn; register YYSTYPE *yypv; register short *yyxi; yystate = 0; yychar = -1; yynerrs = 0; yyerrflag = 0; yyps= &yys[-1]; yypv= &yyv[-1]; yystack: /* put a state and value onto the stack */ #ifdef YYDEBUG if( yydebug ) printf( "state %d, char 0%o\n", yystate, yychar ); #endif if( ++yyps>= &yys[YYMAXDEPTH] ) { yyerror( "yacc stack overflow" ); return(1); } *yyps = yystate; ++yypv; *yypv = yyval; yynewstate: yyn = yypact[yystate]; if( yyn<= YYFLAG ) goto yydefault; /* simple state */ if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0; if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault; if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */ yychar = -1; yyval = yylval; yystate = yyn; if( yyerrflag > 0 ) --yyerrflag; goto yystack; } yydefault: /* default state action */ if( (yyn=yydef[yystate]) == -2 ) { if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0; /* look through exception table */ for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */ while( *(yyxi+=2) >= 0 ){ if( *yyxi == yychar ) break; } if( (yyn = yyxi[1]) < 0 ) return(0); /* accept */ } if( yyn == 0 ){ /* error */ /* error ... attempt to resume parsing */ switch( yyerrflag ){ case 0: /* brand new error */ yyerror( "syntax error" ); ++yynerrs; case 1: case 2: /* incompletely recovered error ... try again */ yyerrflag = 3; /* find a state where "error" is a legal shift action */ while ( yyps >= yys ) { yyn = yypact[*yyps] + YYERRCODE; if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){ yystate = yyact[yyn]; /* simulate a shift of "error" */ goto yystack; } yyn = yypact[*yyps]; /* the current yyps has no shift onn "error", pop stack */ #ifdef YYDEBUG if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] ); #endif --yyps; --yypv; } /* there is no state on the stack with an error shift ... abort */ yyabort: return(1); case 3: /* no shift yet; clobber input char */ #ifdef YYDEBUG if( yydebug ) printf( "error recovery discards char %d\n", yychar ); #endif if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */ yychar = -1; goto yynewstate; /* try again in the same state */ } } /* reduction by production yyn */ #ifdef YYDEBUG if( yydebug ) printf("reduce %d\n",yyn); #endif yyps -= yyr2[yyn]; yypvt = yypv; yypv -= yyr2[yyn]; yyval = yypv[1]; yym=yyn; /* consult goto table to find next state */ yyn = yyr1[yyn]; yyj = yypgo[yyn] + *yyps + 1; if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]]; switch(yym){ case 3: # line 116 "parsedate.y" { yyHaveTime++; #ifdef lint /* I am compulsive about lint natterings... */ if (yyHaveTime == -1) { YYERROR; } #endif /* lint */ } break; case 4: # line 125 "parsedate.y" { yyHaveTime++; yyTimezone = yypvt[-0].Number; } break; case 5: # line 129 "parsedate.y" { yyHaveDate++; } break; case 6: # line 132 "parsedate.y" { yyHaveRel = 1; } break; case 7: # line 137 "parsedate.y" { if (yypvt[-1].Number < 100) { yyHour = yypvt[-1].Number; yyMinutes = 0; } else { yyHour = yypvt[-1].Number / 100; yyMinutes = yypvt[-1].Number % 100; } yySeconds = 0; yyMeridian = yypvt[-0].Meridian; } break; case 8: # line 149 "parsedate.y" { yyHour = yypvt[-3].Number; yyMinutes = yypvt[-1].Number; yySeconds = 0; yyMeridian = yypvt[-0].Meridian; } break; case 9: # line 155 "parsedate.y" { yyHour = yypvt[-3].Number; yyMinutes = yypvt[-1].Number; yyTimezone = yypvt[-0].Number; yyMeridian = MER24; yyDSTmode = DSToff; } break; case 10: # line 162 "parsedate.y" { yyHour = yypvt[-5].Number; yyMinutes = yypvt[-3].Number; yySeconds = yypvt[-1].Number; yyMeridian = yypvt[-0].Meridian; } break; case 11: # line 168 "parsedate.y" { yyHour = yypvt[-5].Number; yyMinutes = yypvt[-3].Number; yySeconds = yypvt[-1].Number; yyTimezone = yypvt[-0].Number; yyMeridian = MER24; yyDSTmode = DSToff; } break; case 12: # line 178 "parsedate.y" { yyval.Number = yypvt[-0].Number; yyDSTmode = DSToff; } break; case 13: # line 182 "parsedate.y" { yyval.Number = yypvt[-0].Number; yyDSTmode = DSTon; } break; case 14: # line 186 "parsedate.y" { /* Only allow "GMT+300" and "GMT-0800" */ if (yypvt[-1].Number != 0) { YYABORT; } yyval.Number = yypvt[-0].Number; yyDSTmode = DSToff; } break; case 15: # line 194 "parsedate.y" { yyval.Number = yypvt[-0].Number; yyDSTmode = DSToff; } break; case 16: # line 200 "parsedate.y" { int i; /* Unix and GMT and numeric timezones -- a little confusing. */ if (yypvt[-0].Number < 0) { /* Don't work with negative modulus. */ yypvt[-0].Number = -yypvt[-0].Number; if (yypvt[-0].Number > 9999 || (i = yypvt[-0].Number % 100) >= 60) { YYABORT; } yyval.Number = (yypvt[-0].Number / 100) * 60 + i; } else { if (yypvt[-0].Number > 9999 || (i = yypvt[-0].Number % 100) >= 60) { YYABORT; } yyval.Number = -((yypvt[-0].Number / 100) * 60 + i); } } break; case 17: # line 221 "parsedate.y" { yyMonth = yypvt[-2].Number; yyDay = yypvt[-0].Number; } break; case 18: # line 225 "parsedate.y" { if (yypvt[-4].Number > 100) { yyYear = yypvt[-4].Number; yyMonth = yypvt[-2].Number; yyDay = yypvt[-0].Number; } else { yyMonth = yypvt[-4].Number; yyDay = yypvt[-2].Number; yyYear = yypvt[-0].Number; } } break; case 19: # line 237 "parsedate.y" { yyMonth = yypvt[-1].Number; yyDay = yypvt[-0].Number; } break; case 20: # line 241 "parsedate.y" { yyMonth = yypvt[-3].Number; yyDay = yypvt[-2].Number; yyYear = yypvt[-0].Number; } break; case 21: # line 246 "parsedate.y" { yyDay = yypvt[-1].Number; yyMonth = yypvt[-0].Number; } break; case 22: # line 250 "parsedate.y" { yyDay = yypvt[-2].Number; yyMonth = yypvt[-1].Number; yyYear = yypvt[-0].Number; } break; case 23: # line 255 "parsedate.y" { yyDay = yypvt[-2].Number; yyMonth = yypvt[-1].Number; yyYear = yypvt[-0].Number; } break; case 24: # line 262 "parsedate.y" { yyRelSeconds += yypvt[-1].Number * yypvt[-0].Number; } break; case 25: # line 265 "parsedate.y" { yyRelSeconds += yypvt[-1].Number * yypvt[-0].Number; } break; case 26: # line 268 "parsedate.y" { yyRelMonth += yypvt[-1].Number * yypvt[-0].Number; } break; case 27: # line 271 "parsedate.y" { yyRelMonth += yypvt[-1].Number * yypvt[-0].Number; } break; case 28: # line 276 "parsedate.y" { yyval.Meridian = MER24; } break; case 29: # line 279 "parsedate.y" { yyval.Meridian = yypvt[-0].Meridian; } break; # line 148 "/usr/lib/yaccpar" } goto yystack; /* stack new state and value */ }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.