📄 getdate.y
字号:
{ "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */ { "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */#if 0 { "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */ { "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */#endif { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */ { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */ { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */ { "nzt", tZONE, -HOUR(12) }, /* New Zealand */ { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */ { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ { "idle", tZONE, -HOUR(12) }, /* International Date Line East */ { NULL }};/* Military timezone table. */static TABLE const MilitaryTable[] = { { "a", tZONE, HOUR( 1) }, { "b", tZONE, HOUR( 2) }, { "c", tZONE, HOUR( 3) }, { "d", tZONE, HOUR( 4) }, { "e", tZONE, HOUR( 5) }, { "f", tZONE, HOUR( 6) }, { "g", tZONE, HOUR( 7) }, { "h", tZONE, HOUR( 8) }, { "i", tZONE, HOUR( 9) }, { "k", tZONE, HOUR( 10) }, { "l", tZONE, HOUR( 11) }, { "m", tZONE, HOUR( 12) }, { "n", tZONE, HOUR(- 1) }, { "o", tZONE, HOUR(- 2) }, { "p", tZONE, HOUR(- 3) }, { "q", tZONE, HOUR(- 4) }, { "r", tZONE, HOUR(- 5) }, { "s", tZONE, HOUR(- 6) }, { "t", tZONE, HOUR(- 7) }, { "u", tZONE, HOUR(- 8) }, { "v", tZONE, HOUR(- 9) }, { "w", tZONE, HOUR(-10) }, { "x", tZONE, HOUR(-11) }, { "y", tZONE, HOUR(-12) }, { "z", tZONE, HOUR( 0) }, { NULL }};static int LookupWord(char * buff, YYSTYPE * yylval){ register char *p; register char *q; register const TABLE *tp; int i; int abbrev; /* Make it lowercase. */ for (p = buff; *p != '\0'; p++) *p = (char)tolower(*p); if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) { yylval->Meridian = MERam; return tMERIDIAN; } if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) { yylval->Meridian = MERpm; return tMERIDIAN; } /* See if we have an abbreviation for a month. */ if (strlen(buff) == 3) abbrev = 1; else if (strlen(buff) == 4 && buff[3] == '.') { abbrev = 1; buff[3] = '\0'; } else abbrev = 0; for (tp = MonthDayTable; tp->name; tp++) { if (abbrev) { if (strncmp(buff, tp->name, 3) == 0) { yylval->Number = tp->value; return tp->type; } } else if (strcmp(buff, tp->name) == 0) { yylval->Number = tp->value; return tp->type; } } for (tp = TimezoneTable; tp->name; tp++) if (strcmp(buff, tp->name) == 0) { yylval->Number = tp->value; return tp->type; } if (strcmp(buff, "dst") == 0) return tDST; for (tp = UnitsTable; tp->name; tp++) if (strcmp(buff, tp->name) == 0) { yylval->Number = tp->value; return tp->type; } /* Strip off any plural and try the units table again. */ i = strlen(buff) - 1; if (buff[i] == 's') { buff[i] = '\0'; for (tp = UnitsTable; tp->name; tp++) if (strcmp(buff, tp->name) == 0) { yylval->Number = tp->value; return tp->type; } buff[i] = 's'; /* Put back for "this" in OtherTable. */ } for (tp = OtherTable; tp->name; tp++) if (strcmp(buff, tp->name) == 0) { yylval->Number = tp->value; return tp->type; } /* Military timezones. */ if (buff[1] == '\0' && isalpha(*buff)) { for (tp = MilitaryTable; tp->name; tp++) if (strcmp(buff, tp->name) == 0) { yylval->Number = tp->value; return tp->type; } } /* Drop out any periods and try the timezone table again. */ for (i = 0, p = q = buff; *q; q++) if (*q != '.') *p++ = *q; else i++; *p = '\0'; if (i) for (tp = TimezoneTable; tp->name; tp++) if (strcmp(buff, tp->name) == 0) { yylval->Number = tp->value; return tp->type; } for (i = 1; i <= 12; i++) for (abbrev = 0; abbrev < 2; abbrev++) if (PTimeIsMonthName(buff, i, abbrev)) { yylval->Number = i; return tMONTH; } for (i = 1; i <= 7; i++) for (abbrev = 0; abbrev < 2; abbrev++) if (PTimeIsDayName(buff, i, abbrev)) { yylval->Number = i; return tDAY; } return tID;}#ifdef _MSC_VER#pragma warning(disable:4211)#endif#ifndef __GNUC__static#endifint yylex(YYSTYPE * yylval, void * yyInput){ register char *p; char buff[20]; int Count; int sign; register int c = PTimeGetChar(yyInput); while (c != EOF && c != '\0' && c != '\n') { while (isspace(c)) c = PTimeGetChar(yyInput); if (isdigit(c) || c == '-' || c == '+') { if (c == '-' || c == '+') { sign = c == '-' ? -1 : 1; if (!isdigit(c = PTimeGetChar(yyInput))) /* skip the '-' sign */ continue; } else sign = 0; yylval->Number = 0; while (isdigit(c)) { yylval->Number = 10 * yylval->Number + c - '0'; c = PTimeGetChar(yyInput); } PTimeUngetChar(yyInput, c); if (sign < 0) yylval->Number = -yylval->Number; return sign ? tSNUMBER : tUNUMBER; } if (isalpha(c)) { for (p = buff; isalpha(c) || c == '.'; c = PTimeGetChar(yyInput)) { if (p < &buff[sizeof(buff)-1]) *p++ = (char)c; } *p = '\0'; PTimeUngetChar(yyInput, c); return LookupWord(buff, yylval); } if (c != '(') return c; Count = 0; do { c = PTimeGetChar(yyInput); if (c == '\0' || c == EOF) return c; if (c == '(') Count++; else if (c == ')') Count--; } while (Count > 0); } return EOF;}#ifdef _MSC_VER#pragma warning(default:4211)#endifstatic time_t ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian){ if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) return -1; switch (Meridian) { case MER24: if (Hours < 0 || Hours > 23) return -1; return (Hours * 60L + Minutes) * 60L + Seconds; case MERam: if (Hours < 1 || Hours > 12) return -1; if (Hours == 12) Hours = 0; return (Hours * 60L + Minutes) * 60L + Seconds; case MERpm: if (Hours < 1 || Hours > 12) return -1; if (Hours == 12) Hours = 0; return ((Hours + 12) * 60L + Minutes) * 60L + Seconds; } return -1;}static time_t Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian, DSTMODE DSTmode, time_t yyTimezone){ static int DaysInMonth[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; time_t tod; time_t Julian; int i; if (Year < 0) Year = -Year; if (Year < 70) Year += 2000; else if (Year < 100) Year += 1900; DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 29 : 28; /* Checking for 2038 bogusly assumes that time_t is 32 bits. But I'm too lazy to try to check for time_t overflow in another way. */ if (Year < EPOCH || Year > 2038 || Month < 1 || Month > 12 /* Lint fluff: "conversion from long may lose accuracy" */ || Day < 1 || Day > DaysInMonth[(int)--Month]) return -1; for (Julian = Day - 1, i = 0; i < Month; i++) Julian += DaysInMonth[i]; for (i = EPOCH; i < Year; i++) Julian += 365 + (i % 4 == 0); Julian *= SECSPERDAY; Julian += yyTimezone * 60L; if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) return -1; Julian += tod; if (DSTmode == DSTon || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst)) Julian -= 60 * 60; return Julian;}static time_t DSTcorrect(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) * 60L * 60L;}static time_t RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber){ struct tm *tm; time_t now; now = Start; tm = localtime(&now); now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); return DSTcorrect(Start, now);}static time_t RelativeMonth(time_t Start, time_t RelMonth, time_t yyTimezone){ struct tm *tm; time_t Month; time_t Year; if (RelMonth == 0) return 0; 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, yyTimezone));}static void SetPossibleDate(struct Variables * var, time_t possible_day, time_t possible_month, time_t possible_year){ int date_order; if (possible_day > 31) /* test for ymd */ date_order = 2; else if (possible_day > 12) /* test for dmy */ date_order = 1; else if (possible_month > 12) /* test for mdy */ date_order = 0; else { static int default_date_order = -1; if (default_date_order < 0) default_date_order = PTimeGetDateOrder(); date_order = default_date_order; } switch (date_order) { case 0 : var->yyDay = possible_month; var->yyMonth = possible_day; var->yyYear = possible_year; break; case 1 : var->yyDay = possible_day; var->yyMonth = possible_month; var->yyYear = possible_year; break; default : var->yyDay = possible_year; var->yyMonth = possible_month; var->yyYear = possible_day; }}time_t STDAPICALLTYPE PTimeParse(void * inputStream, struct tm * now, int timezone){ time_t Start; struct Variables var; var.yyInput = inputStream; var.yyYear = now->tm_year + 1900; var.yyMonth = now->tm_mon + 1; var.yyDay = now->tm_mday; var.yyTimezone = -timezone; var.yyDSTmode = DSTmaybe; var.yyHour = 0; var.yyMinutes = 0; var.yySeconds = 0; var.yyMeridian = MER24; var.yyRelSeconds = 0; var.yyRelMonth = 0; var.yyHaveDate = 0; var.yyHaveDay = 0; var.yyHaveRel = 0; var.yyHaveTime = 0; var.yyHaveZone = 0; yyparse(&var); if (var.yyHaveTime > 1 || var.yyHaveZone > 1 || var.yyHaveDate > 1 || var.yyHaveDay > 1) return -1; if (var.yyHaveTime == 0 && var.yyHaveZone == 0 && var.yyHaveDate == 0 && var.yyHaveDay == 0 && var.yyHaveRel == 0) return -1; if (var.yyHaveDate || var.yyHaveTime || var.yyHaveDay) { Start = Convert(var.yyMonth, var.yyDay, var.yyYear, var.yyHour, var.yyMinutes, var.yySeconds, var.yyMeridian, var.yyDSTmode, var.yyTimezone); if (Start < 0) return -1; } else { time(&Start); if (!var.yyHaveRel) Start -= ((now->tm_hour * 60L + now->tm_min) * 60L) + now->tm_sec; } Start += var.yyRelSeconds; Start += RelativeMonth(Start, var.yyRelMonth, var.yyTimezone); if (var.yyHaveDay && !var.yyHaveDate) Start += RelativeDate(Start, var.yyDayOrdinal, var.yyDayNumber); /* 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 _MSC_VER#pragma warning(disable:4100 4211)#endif#ifdef __GNUC__int yyerror(const char * s){ return 0;}#elsestatic void yyerror(const char * s){}#endif#ifdef _MSC_VER#pragma warning(default:4100 4211)#endif/* End of file ***************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -