diff options
Diffstat (limited to 'ext/date/lib/parse_date.c')
| -rw-r--r-- | ext/date/lib/parse_date.c | 180 |
1 files changed, 123 insertions, 57 deletions
diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index 0539fa80f..467279a3b 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Sun Jun 5 15:26:42 2011 */ +/* Generated by re2c 0.13.5 on Mon Dec 5 22:02:41 2011 */ /* +----------------------------------------------------------------------+ | PHP Version 5 | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: parse_date.c 311831 2011-06-05 13:30:01Z bjori $ */ +/* $Id: parse_date.c 320481 2011-12-06 06:21:08Z derick $ */ #include "timelib.h" @@ -120,8 +120,8 @@ typedef unsigned char uchar; #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) == TIMELIB_UNSET) { \ +#define TIMELIB_PROCESS_YEAR(x, l) { \ + if (((x) == TIMELIB_UNSET) || ((l) >= 4)) { \ /* (x) = 0; */ \ } else if ((x) < 100) { \ if ((x) < 70) { \ @@ -439,7 +439,7 @@ static char *timelib_string(Scanner *s) return tmp; } -static timelib_sll timelib_get_nr(char **ptr, int max_length) +static timelib_sll timelib_get_nr_ex(char **ptr, int max_length, int *scanned_length) { char *begin, *end, *str; timelib_sll tmp_nr = TIMELIB_UNSET; @@ -457,6 +457,9 @@ static timelib_sll timelib_get_nr(char **ptr, int max_length) ++len; } end = *ptr; + if (scanned_length) { + *scanned_length = end - begin; + } str = calloc(1, end - begin + 1); memcpy(str, begin, end - begin); tmp_nr = strtoll(str, NULL, 10); @@ -464,6 +467,11 @@ static timelib_sll timelib_get_nr(char **ptr, int max_length) return tmp_nr; } +static timelib_sll timelib_get_nr(char **ptr, int max_length) +{ + return timelib_get_nr_ex(ptr, max_length, NULL); +} + static void timelib_skip_day_suffix(char **ptr) { if (isspace(**ptr)) { @@ -776,7 +784,7 @@ static long timelib_lookup_zone(char **ptr, int *dst, char **tz_abbr, int *found return value; } -static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb) +static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_wrapper) { timelib_tzinfo *res; long retval = 0; @@ -825,7 +833,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_ #endif /* If we have a TimeZone identifier to start with, use it */ if (strstr(tz_abbr, "/") || strcmp(tz_abbr, "UTC") == 0) { - if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) { + if ((res = tz_wrapper(tz_abbr, tzdb)) != NULL) { t->tz_info = res; t->zone_type = TIMELIB_ZONETYPE_ID; found++; @@ -854,7 +862,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_ } \ } -static int scan(Scanner *s) +static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper) { uchar *cursor = s->cur; char *str, *ptr = NULL; @@ -1026,7 +1034,7 @@ yy4: DEBUG_OUTPUT("tzcorrection | tz"); TIMELIB_INIT; TIMELIB_HAVE_TZ(); - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); if (tz_not_found) { add_error(s, "The timezone could not be found in the database"); } @@ -4173,13 +4181,14 @@ yy198: yy199: YYDEBUG(199, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("datetextual | datenoyear"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); s->time->m = timelib_get_month((char **) &ptr); s->time->d = timelib_get_nr((char **) &ptr, 2); - s->time->y = timelib_get_nr((char **) &ptr, 4); - TIMELIB_PROCESS_YEAR(s->time->y); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } @@ -4471,7 +4480,7 @@ yy223: } if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); if (tz_not_found) { add_error(s, "The timezone could not be found in the database"); } @@ -5376,13 +5385,14 @@ yy294: yy295: YYDEBUG(295, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("datenoday"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); s->time->m = timelib_get_month((char **) &ptr); - s->time->y = timelib_get_nr((char **) &ptr, 4); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); s->time->d = 1; - TIMELIB_PROCESS_YEAR(s->time->y); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } @@ -6606,13 +6616,14 @@ yy362: yy364: YYDEBUG(364, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("pgtextshort"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); s->time->m = timelib_get_month((char **) &ptr); s->time->d = timelib_get_nr((char **) &ptr, 2); - s->time->y = timelib_get_nr((char **) &ptr, 4); - TIMELIB_PROCESS_YEAR(s->time->y); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } @@ -9783,7 +9794,7 @@ yy491: } if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); if (tz_not_found) { add_error(s, "The timezone could not be found in the database"); } @@ -10224,14 +10235,15 @@ yy534: yy535: YYDEBUG(535, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("datefull"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); s->time->d = timelib_get_nr((char **) &ptr, 2); timelib_skip_day_suffix((char **) &ptr); s->time->m = timelib_get_month((char **) &ptr); - s->time->y = timelib_get_nr((char **) &ptr, 4); - TIMELIB_PROCESS_YEAR(s->time->y); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_DATE_FULL; } @@ -11017,13 +11029,14 @@ yy611: yy612: YYDEBUG(612, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("pointed date YY"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); s->time->d = timelib_get_nr((char **) &ptr, 2); s->time->m = timelib_get_nr((char **) &ptr, 2); - s->time->y = timelib_get_nr((char **) &ptr, 2); - TIMELIB_PROCESS_YEAR(s->time->y); + s->time->y = timelib_get_nr_ex((char **) &ptr, 2, &length); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_DATE_FULL_POINTED; } @@ -11668,13 +11681,14 @@ yy656: yy657: YYDEBUG(657, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("gnudateshort"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); - s->time->y = timelib_get_nr((char **) &ptr, 4); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); s->time->m = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2); - TIMELIB_PROCESS_YEAR(s->time->y); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } @@ -11784,14 +11798,15 @@ yy666: yy667: YYDEBUG(667, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("americanshort | american"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); s->time->m = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2); if (*ptr == '/') { - s->time->y = timelib_get_nr((char **) &ptr, 4); - TIMELIB_PROCESS_YEAR(s->time->y); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); + TIMELIB_PROCESS_YEAR(s->time->y, length); } TIMELIB_DEINIT; return TIMELIB_AMERICAN; @@ -12040,7 +12055,7 @@ yy701: s->time->h = timelib_get_nr((char **) &ptr, 2); s->time->i = timelib_get_nr((char **) &ptr, 2); s->time->s = timelib_get_nr((char **) &ptr, 2); - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); if (tz_not_found) { add_error(s, "The timezone could not be found in the database"); } @@ -12599,13 +12614,14 @@ yy763: yy764: YYDEBUG(764, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("iso8601date2"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); - s->time->y = timelib_get_nr((char **) &ptr, 4); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); s->time->m = timelib_get_nr((char **) &ptr, 2); s->time->d = timelib_get_nr((char **) &ptr, 2); - TIMELIB_PROCESS_YEAR(s->time->y); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } @@ -12648,13 +12664,14 @@ yy771: ++YYCURSOR; YYDEBUG(772, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("pgtextreverse"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); - s->time->y = timelib_get_nr((char **) &ptr, 4); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); s->time->m = timelib_get_month((char **) &ptr); s->time->d = timelib_get_nr((char **) &ptr, 2); - TIMELIB_PROCESS_YEAR(s->time->y); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } @@ -12953,13 +12970,14 @@ yy793: yy794: YYDEBUG(794, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("datenodayrev"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); - s->time->y = timelib_get_nr((char **) &ptr, 4); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); s->time->m = timelib_get_month((char **) &ptr); s->time->d = 1; - TIMELIB_PROCESS_YEAR(s->time->y); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } @@ -13284,13 +13302,14 @@ yy821: yy822: YYDEBUG(822, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("pgydotd"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); - s->time->y = timelib_get_nr((char **) &ptr, 4); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); s->time->d = timelib_get_nr((char **) &ptr, 3); s->time->m = 1; - TIMELIB_PROCESS_YEAR(s->time->y); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_PG_YEARDAY; } @@ -13411,7 +13430,7 @@ yy843: if (*ptr == '.') { s->time->f = timelib_get_frac_nr((char **) &ptr, 9); if (*ptr) { /* timezone is optional */ - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); if (tz_not_found) { add_error(s, "The timezone could not be found in the database"); } @@ -14611,13 +14630,14 @@ yy973: yy974: YYDEBUG(974, *YYCURSOR); { + int length = 0; DEBUG_OUTPUT("gnudateshorter"); TIMELIB_INIT; TIMELIB_HAVE_DATE(); - s->time->y = timelib_get_nr((char **) &ptr, 4); + s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length); s->time->m = timelib_get_nr((char **) &ptr, 2); s->time->d = 1; - TIMELIB_PROCESS_YEAR(s->time->y); + TIMELIB_PROCESS_YEAR(s->time->y, length); TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } @@ -15751,7 +15771,7 @@ yy1076: s->time->s = timelib_get_nr((char **) &ptr, 2); if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); if (tz_not_found) { add_error(s, "The timezone could not be found in the database"); } @@ -24652,7 +24672,7 @@ yy1537: #define YYMAXFILL 31 -timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container **errors, const timelib_tzdb *tzdb) +timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper) { Scanner in; int t; @@ -24707,7 +24727,7 @@ timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container in.time->zone_type = 0; do { - t = scan(&in); + t = scan(&in, tz_get_wrapper); #ifdef DEBUG_PARSER printf("%d\n", t); #endif @@ -24762,7 +24782,7 @@ static void timelib_time_reset_unset_fields(timelib_time *time) if (time->f == TIMELIB_UNSET ) time->f = 0.0; } -timelib_time *timelib_parse_from_format(char *format, char *string, int len, timelib_error_container **errors, const timelib_tzdb *tzdb) +timelib_time *timelib_parse_from_format(char *format, char *string, int len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper) { char *fptr = format; char *ptr = string; @@ -24770,6 +24790,7 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim timelib_sll tmp; Scanner in; Scanner *s = ∈ + int allow_extra = 0; memset(&in, 0, sizeof(in)); in.errors = malloc(sizeof(struct timelib_error_container)); @@ -24798,8 +24819,19 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim switch (*fptr) { case 'D': /* three letter day */ case 'l': /* full day */ - if (!timelib_lookup_relunit((char **) &ptr)) { - add_pbf_error(s, "A textual day could not be found", string, begin); + { + const timelib_relunit* tmprel = 0; + + tmprel = timelib_lookup_relunit((char **) &ptr); + if (!tmprel) { + add_pbf_error(s, "A textual day could not be found", string, begin); + break; + } else { + in.time->have_relative = 1; + in.time->relative.have_weekday_relative = 1; + in.time->relative.weekday = tmprel->multiplier; + in.time->relative.weekday_behavior = 1; + } } break; case 'd': /* two digit day, with leading zero */ @@ -24812,13 +24844,14 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim case 'S': /* day suffix, ignored, nor checked */ timelib_skip_day_suffix((char **) &ptr); break; - case 'z': /* day of year - resets month (0 based) */ + case 'z': /* day of year - resets month (0 based) - also initializes everything else to !TIMELIB_UNSET */ TIMELIB_CHECK_NUMBER; if ((tmp = timelib_get_nr((char **) &ptr, 3)) == TIMELIB_UNSET) { add_pbf_error(s, "A three digit day-of-year could not be found", string, begin); } else { s->time->m = 1; s->time->d = tmp + 1; + timelib_do_normalize(s->time); } break; @@ -24839,11 +24872,14 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim } break; case 'y': /* two digit year */ - TIMELIB_CHECK_NUMBER; - if ((s->time->y = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) { - add_pbf_error(s, "A two digit year could not be found", string, begin); + { + int length = 0; + TIMELIB_CHECK_NUMBER; + if ((s->time->y = timelib_get_nr_ex((char **) &ptr, 2, &length)) == TIMELIB_UNSET) { + add_pbf_error(s, "A two digit year could not be found", string, begin); + } + TIMELIB_PROCESS_YEAR(s->time->y, length); } - TIMELIB_PROCESS_YEAR(s->time->y); break; case 'Y': /* four digit year */ TIMELIB_CHECK_NUMBER; @@ -24879,15 +24915,31 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim } break; case 'i': /* two digit minute, with leading zero */ - TIMELIB_CHECK_NUMBER; - if ((s->time->i = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) { - add_pbf_error(s, "A two digit minute could not be found", string, begin); + { + int length; + timelib_sll min; + + TIMELIB_CHECK_NUMBER; + min = timelib_get_nr_ex((char **) &ptr, 2, &length); + if (min == TIMELIB_UNSET || length != 2) { + add_pbf_error(s, "A two digit minute could not be found", string, begin); + } else { + s->time->i = min; + } } break; case 's': /* two digit second, with leading zero */ - TIMELIB_CHECK_NUMBER; - if ((s->time->s = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) { - add_pbf_error(s, "A two digit second could not be found", string, begin); + { + int length; + timelib_sll sec; + + TIMELIB_CHECK_NUMBER; + sec = timelib_get_nr_ex((char **) &ptr, 2, &length); + if (sec == TIMELIB_UNSET || length != 2) { + add_pbf_error(s, "A two second minute could not be found", string, begin); + } else { + s->time->s = sec; + } } break; case 'u': /* up to six digit millisecond */ @@ -24928,7 +24980,7 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim case 'O': /* timezone */ { int tz_not_found; - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper); if (tz_not_found) { add_pbf_error(s, "The timezone could not be found in the database", string, begin); } @@ -24983,6 +25035,10 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim timelib_eat_until_separator((char **) &ptr); break; + case '+': /* allow extra chars in the format */ + allow_extra = 1; + break; + default: if (*fptr != *ptr) { add_pbf_error(s, "The format separator does not match", string, begin); @@ -24992,11 +25048,20 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim fptr++; } if (*ptr) { - add_pbf_error(s, "Trailing data", string, ptr); + if (allow_extra) { + add_pbf_warning(s, "Trailing data", string, ptr); + } else { + add_pbf_error(s, "Trailing data", string, ptr); + } + } + /* ignore trailing +'s */ + while (*fptr == '+') { + fptr++; } if (*fptr) { /* Trailing | and ! specifiers are valid. */ - while (*fptr) { + int done = 0; + while (*fptr && !done) { switch (*fptr++) { case '!': /* reset all fields to default */ timelib_time_reset_fields(s->time); @@ -25008,6 +25073,7 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim default: add_pbf_error(s, "Data missing", string, ptr); + done = 1; } } } |
