📄 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> | +----------------------------------------------------------------------+ *//* $Id: parse_date.re,v 1.59 2006/07/27 13:01:10 iliaa Exp $ */#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 TIMELIB_SPECIAL 8#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) { add_error(s, "Double time specification"); timelib_string_free(str); 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) { add_error(s, "Double date specification"); timelib_string_free(str); 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 = 1; }#define TIMELIB_HAVE_WEEKDAY_RELATIVE() { s->time->have_weekday_relative = 1; }#define TIMELIB_HAVE_SPECIAL_RELATIVE() { s->time->have_special_relative = 1; }#define TIMELIB_HAVE_TZ() { s->cur = cursor; if (s->time->have_zone) { add_warning(s, "Double timezone specification"); timelib_string_free(str); 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; struct timelib_error_container *errors; struct timelib_time *time; const 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. */const static timelib_tz_lookup_table timelib_timezone_lookup[] = {#include "timezonemap.h" { NULL, 0, 0, NULL },};const static timelib_tz_lookup_table timelib_timezone_fallbackmap[] = {#include "fallbackmap.h" { NULL, 0, 0, NULL },};const 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 }, { "weekday", TIMELIB_SPECIAL, TIMELIB_SPECIAL_WEEKDAY }, { "weekdays", TIMELIB_SPECIAL, TIMELIB_SPECIAL_WEEKDAY }, { 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[0] == '\t') { 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 void add_warning(Scanner *s, char *error){ s->errors->warning_count++; s->errors->warning_messages = realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message)); s->errors->warning_messages[s->errors->warning_count - 1].position = s->tok ? s->tok - s->str : 0; s->errors->warning_messages[s->errors->warning_count - 1].character = s->tok ? *s->tok : 0; s->errors->warning_messages[s->errors->warning_count - 1].message = strdup(error);}static void add_error(Scanner *s, char *error){ s->errors->error_count++; s->errors->error_messages = realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message)); s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0; s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0; s->errors->error_messages[s->errors->error_count - 1].message = strdup(error);}static 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 == '\t' || **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 == '\t' || **ptr == '-' || **ptr == '.' || **ptr == '/') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -