parse_date.c
来自「a little DFA compiler.」· C语言 代码 · 共 4,324 行 · 第 1/5 页
C
4,324 行
/* Generated by re2c */#line 1 "parse_date.re"/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2006 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Derick Rethans <derick@derickrethans.nl> | +----------------------------------------------------------------------+ */#include "timelib.h"#include <stdio.h>#include <ctype.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if defined(_MSC_VER)# define strtoll(s, f, b) _atoi64(s)#elif !defined(HAVE_STRTOLL)# if defined(HAVE_ATOLL)# define strtoll(s, f, b) atoll(s)# else# define strtoll(s, f, b) strtol(s, f, b)# endif#endif#define TIMELIB_SECOND 1#define TIMELIB_MINUTE 2#define TIMELIB_HOUR 3#define TIMELIB_DAY 4#define TIMELIB_MONTH 5#define TIMELIB_YEAR 6#define TIMELIB_WEEKDAY 7#define EOI 257#define TIME 258#define DATE 259#define TIMELIB_XMLRPC_SOAP 260#define TIMELIB_TIME12 261#define TIMELIB_TIME24 262#define TIMELIB_GNU_NOCOLON 263#define TIMELIB_GNU_NOCOLON_TZ 264#define TIMELIB_ISO_NOCOLON 265#define TIMELIB_AMERICAN 266#define TIMELIB_ISO_DATE 267#define TIMELIB_DATE_FULL 268#define TIMELIB_DATE_TEXT 269#define TIMELIB_DATE_NOCOLON 270#define TIMELIB_PG_YEARDAY 271#define TIMELIB_PG_TEXT 272#define TIMELIB_PG_REVERSE 273#define TIMELIB_CLF 274#define TIMELIB_DATE_NO_DAY 275#define TIMELIB_SHORTDATE_WITH_TIME 276#define TIMELIB_DATE_FULL_POINTED 277#define TIMELIB_TIME24_WITH_ZONE 278#define TIMELIB_ISO_WEEK 279#define TIMELIB_TIMEZONE 300#define TIMELIB_AGO 301#define TIMELIB_RELATIVE 310#define TIMELIB_ERROR 999typedef unsigned char uchar;#define BSIZE 8192#define YYCTYPE uchar#define YYCURSOR cursor#define YYLIMIT s->lim#define YYMARKER s->ptr#define YYFILL(n) return EOI;#define RET(i) {s->cur = cursor; return i;}#define timelib_string_free free#define TIMELIB_HAVE_TIME() { if (s->time->have_time) { return TIMELIB_ERROR; } else { s->time->have_time = 1; s->time->h = 0; s->time->i = 0; s->time->s = 0; s->time->f = 0; } }#define TIMELIB_UNHAVE_TIME() { s->time->have_time = 0; s->time->h = 0; s->time->i = 0; s->time->s = 0; s->time->f = 0; }#define TIMELIB_HAVE_DATE() { if (s->time->have_date) { return TIMELIB_ERROR; } else { s->time->have_date = 1; } }#define TIMELIB_UNHAVE_DATE() { s->time->have_date = 0; s->time->d = 0; s->time->m = 0; s->time->y = 0; }#define TIMELIB_HAVE_RELATIVE() { s->time->have_relative = 1; s->time->relative.weekday_behavior = 0; }#define TIMELIB_HAVE_WEEKDAY_RELATIVE() { s->time->have_weekday_relative = 1; }#define TIMELIB_HAVE_TZ() { s->cur = cursor; if (s->time->have_zone) { return TIMELIB_ERROR; } else { s->time.have_zone = 1; } }#define TIMELIB_INIT s->cur = cursor; str = timelib_string(s); ptr = str#define TIMELIB_DEINIT timelib_string_free(str)#define TIMELIB_ADJUST_RELATIVE_WEEKDAY() if (in->time.have_weekday_relative && (in.rel.d > 0)) { in.rel.d -= 7; }#define TIMELIB_PROCESS_YEAR(x) { \ if ((x) == -1) { \ /* (x) = 0; */ \ } else if ((x) < 100) { \ if ((x) < 70) { \ (x) += 2000; \ } else { \ (x) += 1900; \ } \ } \}#ifdef DEBUG_PARSER#define DEBUG_OUTPUT(s) printf("%s\n", s);#define YYDEBUG(s,c) { if (s != -1) { printf("state: %d ", s); printf("[%c]\n", c); } }#else#define DEBUG_OUTPUT(s)#define YYDEBUG(s,c)#endif#include "timelib_structs.h"typedef struct timelib_elems { unsigned int c; /* Number of elements */ char **v; /* Values */} timelib_elems;typedef struct Scanner { int fd; uchar *lim, *str, *ptr, *cur, *tok, *pos; unsigned int line, len; int errors; struct timelib_time *time; timelib_tzdb *tzdb;} Scanner;typedef struct _timelib_lookup_table { const char *name; int type; int value;} timelib_lookup_table;typedef struct _timelib_relunit { const char *name; int unit; int multiplier;} timelib_relunit;#define HOUR(a) (int)(a * 60)/* The timezone table. */static timelib_tz_lookup_table timelib_timezone_lookup[] = {#include "timezonemap.h" { NULL, 0, 0, NULL },};static timelib_tz_lookup_table timelib_timezone_fallbackmap[] = {#include "fallbackmap.h" { NULL, 0, 0, NULL },};static timelib_tz_lookup_table timelib_timezone_utc[] = { { "utc", 0, 0, "UTC" },};static timelib_relunit const timelib_relunit_lookup[] = { { "sec", TIMELIB_SECOND, 1 }, { "secs", TIMELIB_SECOND, 1 }, { "second", TIMELIB_SECOND, 1 }, { "seconds", TIMELIB_SECOND, 1 }, { "min", TIMELIB_MINUTE, 1 }, { "mins", TIMELIB_MINUTE, 1 }, { "minute", TIMELIB_MINUTE, 1 }, { "minutes", TIMELIB_MINUTE, 1 }, { "hour", TIMELIB_HOUR, 1 }, { "hours", TIMELIB_HOUR, 1 }, { "day", TIMELIB_DAY, 1 }, { "days", TIMELIB_DAY, 1 }, { "week", TIMELIB_DAY, 7 }, { "weeks", TIMELIB_DAY, 7 }, { "fortnight", TIMELIB_DAY, 14 }, { "fortnights", TIMELIB_DAY, 14 }, { "forthnight", TIMELIB_DAY, 14 }, { "forthnights", TIMELIB_DAY, 14 }, { "month", TIMELIB_MONTH, 1 }, { "months", TIMELIB_MONTH, 1 }, { "year", TIMELIB_YEAR, 1 }, { "years", TIMELIB_YEAR, 1 }, { "monday", TIMELIB_WEEKDAY, 1 }, { "mon", TIMELIB_WEEKDAY, 1 }, { "tuesday", TIMELIB_WEEKDAY, 2 }, { "tue", TIMELIB_WEEKDAY, 2 }, { "wednesday", TIMELIB_WEEKDAY, 3 }, { "wed", TIMELIB_WEEKDAY, 3 }, { "thursday", TIMELIB_WEEKDAY, 4 }, { "thu", TIMELIB_WEEKDAY, 4 }, { "friday", TIMELIB_WEEKDAY, 5 }, { "fri", TIMELIB_WEEKDAY, 5 }, { "saturday", TIMELIB_WEEKDAY, 6 }, { "sat", TIMELIB_WEEKDAY, 6 }, { "sunday", TIMELIB_WEEKDAY, 0 }, { "sun", TIMELIB_WEEKDAY, 0 }, { NULL, 0, 0 }};/* The relative text table. */static timelib_lookup_table const timelib_reltext_lookup[] = { { "first", 0, 1 }, { "next", 0, 1 }, { "second", 0, 2 }, { "third", 0, 3 }, { "fourth", 0, 4 }, { "fifth", 0, 5 }, { "sixth", 0, 6 }, { "seventh", 0, 7 }, { "eight", 0, 8 }, { "ninth", 0, 9 }, { "tenth", 0, 10 }, { "eleventh", 0, 11 }, { "twelfth", 0, 12 }, { "last", 0, -1 }, { "previous", 0, -1 }, { "this", 1, 0 }, { NULL, 1, 0 }};/* The month table. */static timelib_lookup_table const timelib_month_lookup[] = { { "jan", 0, 1 }, { "feb", 0, 2 }, { "mar", 0, 3 }, { "apr", 0, 4 }, { "may", 0, 5 }, { "jun", 0, 6 }, { "jul", 0, 7 }, { "aug", 0, 8 }, { "sep", 0, 9 }, { "sept", 0, 9 }, { "oct", 0, 10 }, { "nov", 0, 11 }, { "dec", 0, 12 }, { "i", 0, 1 }, { "ii", 0, 2 }, { "iii", 0, 3 }, { "iv", 0, 4 }, { "v", 0, 5 }, { "vi", 0, 6 }, { "vii", 0, 7 }, { "viii", 0, 8 }, { "ix", 0, 9 }, { "x", 0, 10 }, { "xi", 0, 11 }, { "xii", 0, 12 }, { "january", 0, 1 }, { "february", 0, 2 }, { "march", 0, 3 }, { "april", 0, 4 }, { "may", 0, 5 }, { "june", 0, 6 }, { "july", 0, 7 }, { "august", 0, 8 }, { "september", 0, 9 }, { "october", 0, 10 }, { "november", 0, 11 }, { "december", 0, 12 }, { NULL, 0, 0 }};#if 0static char* timelib_ltrim(char *s){ char *ptr = s; while (ptr[0] == ' ') { ptr++; } return ptr;}#endif#if 0uchar *fill(Scanner *s, uchar *cursor){ if(!s->eof){ unsigned int cnt = s->tok - s->bot; if(cnt){ memcpy(s->bot, s->tok, s->lim - s->tok); s->tok = s->bot; s->ptr -= cnt; cursor -= cnt; s->pos -= cnt; s->lim -= cnt; } if((s->top - s->lim) < BSIZE){ uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar)); memcpy(buf, s->tok, s->lim - s->tok); s->tok = buf; s->ptr = &buf[s->ptr - s->bot]; cursor = &buf[cursor - s->bot]; s->pos = &buf[s->pos - s->bot]; s->lim = &buf[s->lim - s->bot]; s->top = &s->lim[BSIZE]; free(s->bot); s->bot = buf; } if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){ s->eof = &s->lim[cnt]; *(s->eof)++ = '\n'; } s->lim += cnt; } return cursor;}#endifstatic timelib_sll timelib_meridian(char **ptr, timelib_sll h){ timelib_sll retval = 0; while (!strchr("AaPp", **ptr)) { ++*ptr; } if (**ptr == 'a' || **ptr == 'A') { if (h == 12) { retval = -12; } } else if (h != 12) { retval = 12; } ++*ptr; if (**ptr == '.') { *ptr += 3; } else { ++*ptr; } return retval;}static char *timelib_string(Scanner *s){ char *tmp = calloc(1, s->cur - s->tok + 1); memcpy(tmp, s->tok, s->cur - s->tok); return tmp;}static timelib_sll timelib_get_nr(char **ptr, int max_length){ char *begin, *end, *str; timelib_sll tmp_nr = -1; int len = 0; while ((**ptr < '0') || (**ptr > '9')) { if (**ptr == '\0') { return -1; } ++*ptr; } begin = *ptr; while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) { ++*ptr; ++len; } end = *ptr; str = calloc(1, end - begin + 1); memcpy(str, begin, end - begin); tmp_nr = strtoll(str, NULL, 10); free(str); return tmp_nr;}static void timelib_skip_day_suffix(char **ptr){ if (isspace(**ptr)) { return; } if (!strncasecmp(*ptr, "nd", 2) || !strncasecmp(*ptr, "rd", 2) ||!strncasecmp(*ptr, "st", 2) || !strncasecmp(*ptr, "th", 2)) { *ptr += 2; }}static double timelib_get_frac_nr(char **ptr, int max_length){ char *begin, *end, *str; double tmp_nr = -1; int len = 0; while ((**ptr != '.') && ((**ptr < '0') || (**ptr > '9'))) { if (**ptr == '\0') { return -1; } ++*ptr; } begin = *ptr; while (((**ptr == '.') || ((**ptr >= '0') && (**ptr <= '9'))) && len < max_length) { ++*ptr; ++len; } end = *ptr; str = calloc(1, end - begin + 1); memcpy(str, begin, end - begin); tmp_nr = strtod(str, NULL); free(str); return tmp_nr;}static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length){ timelib_ull dir = 1; while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) { if (**ptr == '\0') { return -1; } ++*ptr; } if (**ptr == '+') { ++*ptr; } else if (**ptr == '-') { dir = -1; ++*ptr; } return dir * timelib_get_nr(ptr, max_length);}static long timelib_parse_tz_cor(char **ptr){ char *begin = *ptr, *end; long tmp; while (**ptr != '\0') { ++*ptr; } end = *ptr; switch (end - begin) { case 1: case 2: return HOUR(strtol(begin, NULL, 10)); break; case 3: case 4: if (begin[1] == ':') { tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10); return tmp; } else if (begin[2] == ':') { tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10); return tmp; } else { tmp = strtol(begin, NULL, 10); return HOUR(tmp / 100) + tmp % 100; } case 5: tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10); return tmp; } return 0;}static timelib_sll timelib_lookup_relative_text(char **ptr, int *behavior){ char *word; char *begin = *ptr, *end; timelib_sll value = 0; const timelib_lookup_table *tp; while ((**ptr >= 'A' && **ptr <= 'Z') || (**ptr >= 'a' && **ptr <= 'z')) { ++*ptr; } end = *ptr; word = calloc(1, end - begin + 1); memcpy(word, begin, end - begin); for (tp = timelib_reltext_lookup; tp->name; tp++) { if (strcasecmp(word, tp->name) == 0) { value = tp->value; *behavior = tp->type; } } free(word); return value;}static timelib_sll timelib_get_relative_text(char **ptr, int *behavior){ while (**ptr == ' ' || **ptr == '-' || **ptr == '/') { ++*ptr; } return timelib_lookup_relative_text(ptr, behavior);}static long timelib_lookup_month(char **ptr){ char *word; char *begin = *ptr, *end; long value = 0; const timelib_lookup_table *tp; while ((**ptr >= 'A' && **ptr <= 'Z') || (**ptr >= 'a' && **ptr <= 'z')) { ++*ptr; } end = *ptr; word = calloc(1, end - begin + 1); memcpy(word, begin, end - begin); for (tp = timelib_month_lookup; tp->name; tp++) { if (strcasecmp(word, tp->name) == 0) { value = tp->value; } } free(word); return value;}static long timelib_get_month(char **ptr){ while (**ptr == ' ' || **ptr == '-' || **ptr == '.' || **ptr == '/') { ++*ptr; } return timelib_lookup_month(ptr);}static void timelib_eat_spaces(char **ptr){ while (**ptr == ' ') { ++*ptr; }}static const timelib_relunit* timelib_lookup_relunit(char **ptr){ char *word; char *begin = *ptr, *end; const timelib_relunit *tp, *value = NULL; while (**ptr != '\0' && **ptr != ' ') { ++*ptr; } end = *ptr; word = calloc(1, end - begin + 1); memcpy(word, begin, end - begin); for (tp = timelib_relunit_lookup; tp->name; tp++) { if (strcasecmp(word, tp->name) == 0) { value = tp; break; } } free(word); return value;}static void timelib_set_relative(char **ptr, timelib_sll amount, int behavior, Scanner *s){ const timelib_relunit* relunit; relunit = timelib_lookup_relunit(ptr); switch (relunit->unit) { case TIMELIB_SECOND: s->time->relative.s += amount * relunit->multiplier; break; case TIMELIB_MINUTE: s->time->relative.i += amount * relunit->multiplier; break; case TIMELIB_HOUR: s->time->relative.h += amount * relunit->multiplier; break; case TIMELIB_DAY: s->time->relative.d += amount * relunit->multiplier; break; case TIMELIB_MONTH: s->time->relative.m += amount * relunit->multiplier; break; case TIMELIB_YEAR: s->time->relative.y += amount * relunit->multiplier; break; case TIMELIB_WEEKDAY: TIMELIB_HAVE_WEEKDAY_RELATIVE(); TIMELIB_UNHAVE_TIME(); s->time->relative.d += (amount > 0 ? amount - 1 : amount) * 7; s->time->relative.weekday = relunit->multiplier; s->time->relative.weekday_behavior = behavior; break; }}static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffset, int isdst){ int first_found = 0; timelib_tz_lookup_table *tp, *first_found_elem; timelib_tz_lookup_table *fmp; if (strcasecmp("utc", word) == 0 || strcasecmp("gmt", word) == 0) { return timelib_timezone_utc; } for (tp = timelib_timezone_lookup; tp->name; tp++) { if (strcasecmp(word, tp->name) == 0) { if (!first_found) { first_found = 1; first_found_elem = tp; if (gmtoffset == -1) { return tp; } } if (tp->gmtoffset == gmtoffset) { return tp; } } } if (first_found) { return first_found_elem; } /* Still didn't find anything, let's find the zone solely based on * offset/isdst then */ for (fmp = timelib_timezone_fallbackmap; fmp->name; fmp++) { if ((fmp->gmtoffset * 3600) == gmtoffset && fmp->type == isdst) { return fmp; } } return NULL;}static long timelib_lookup_zone(char **ptr, int *dst, char **tz_abbr, int *found){ char *word; char *begin = *ptr, *end; long value = 0; timelib_tz_lookup_table *tp; while (**ptr != '\0' && **ptr != ')') { ++*ptr; } end = *ptr; word = calloc(1, end - begin + 1); memcpy(word, begin, end - begin); if ((tp = zone_search(word, -1, 0))) { value = -tp->gmtoffset / 60; *dst = tp->type; value += tp->type * 60; *found = 1; } else { *found = 0; } *tz_abbr = word; return value;}static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, timelib_tzdb *tzdb){ timelib_tzinfo *res; long retval = 0; *tz_not_found = 0; while (**ptr == ' ' || **ptr == '(') { ++*ptr; } if (**ptr == '+') { ++*ptr; t->is_localtime = 1; t->zone_type = TIMELIB_ZONETYPE_OFFSET; *tz_not_found = 0; t->dst = 0; retval = -1 * timelib_parse_tz_cor(ptr); } else if (**ptr == '-') { ++*ptr; t->is_localtime = 1; t->zone_type = TIMELIB_ZONETYPE_OFFSET; *tz_not_found = 0; t->dst = 0; retval = timelib_parse_tz_cor(ptr); } else { int found = 0; long offset; char *tz_abbr; t->is_localtime = 1; t->zone_type = TIMELIB_ZONETYPE_ABBR; offset = timelib_lookup_zone(ptr, dst, &tz_abbr, &found);#if 0 /* If we found a TimeZone identifier, use it */ if (tz_name) { t->tz_info = timelib_parse_tzfile(tz_name); t->zone_type = TIMELIB_ZONETYPE_ID; }#endif /* If we have a TimeZone identifier to start with, use it */ if (strstr(tz_abbr, "/")) { if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) { t->tz_info = res; t->zone_type = TIMELIB_ZONETYPE_ID; found++; } } if (t->zone_type != TIMELIB_ZONETYPE_ID) { timelib_time_tz_abbr_update(t, tz_abbr); } free(tz_abbr); *tz_not_found = (found == 0); retval = offset; } while (**ptr == ')') { ++*ptr; } return retval;}#define timelib_split_free(arg) { \ int i; \ for (i = 0; i < arg.c; i++) { \ free(arg.v[i]); \ } \ if (arg.v) { \ free(arg.v); \ } \}static int scan(Scanner *s){ uchar *cursor = s->cur; char *str, *ptr = NULL; std: s->tok = cursor; s->len = 0;#line 845 "parse_date.re"#line 743 "<stdout>"{ YYCTYPE yych; unsigned int yyaccept = 0; if((YYLIMIT - YYCURSOR) < 26) YYFILL(26); yych = *YYCURSOR; switch(yych) { case 0x00: case 0x0A: goto yy48; case ' ': goto yy45; case '(': goto yy42; case '+': case '-': goto yy41; case ',': case '.': goto yy47; case '0': goto yy13; case '1': goto yy14; case '2': goto yy15; case '3': goto yy16; case '4': case '5': case '6': case '7': case '8': case '9': goto yy17; case '@': goto yy11; case 'A': goto yy25; case 'B': case 'C': case 'G': case 'H': case 'K': case 'Q': case 'R': case 'U': case 'Z': goto yy43; case 'D': goto yy31; case 'E': goto yy35; case 'F': goto yy23; case 'I': goto yy18; case 'J': goto yy21; case 'L': goto yy37; case 'M': goto yy7; case 'N': goto yy5; case 'O': goto yy29; case 'P': goto yy39; case 'S': goto yy27; case 'T': goto yy9; case 'V': goto yy19; case 'W': goto yy33; case 'X': goto yy20; case 'Y': goto yy2; case 'a': goto yy26; case 'b': case 'c': case 'g': case 'h': case 'i': case 'k': case 'q': case 'r': case 'u': case 'v': case 'x': case 'z': goto yy44; case 'd': goto yy32; case 'e': goto yy36; case 'f': goto yy24; case 'j': goto yy22; case 'l': goto yy38; case 'm': goto yy8; case 'n': goto yy6; case 'o': goto yy30; case 'p': goto yy40; case 's': goto yy28; case 't': goto yy10; case 'w': goto yy34; case 'y': goto yy4; default: goto yy50; }yy2: ++YYCURSOR; switch((yych = *YYCURSOR)) { case ')': goto yy132; case 'A': case 'B': case 'C': case 'D': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': goto yy133; case 'E': goto yy1302; case 'a': case 'b': case 'c': case 'd': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?