-/* Generated by re2c 0.12.1 on Thu Jul 12 20:33:20 2007 */
+/* Generated by re2c 0.12.1 on Sun Jan 13 15:57:11 2008 */
#line 1 "ext/date/lib/parse_date.re"
/*
+----------------------------------------------------------------------+
s->errors->error_messages[s->errors->error_count - 1].message = strdup(error);
}
+static void add_pbf_warning(Scanner *s, char *error, char *sptr, char *cptr)
+{
+ 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 = cptr - sptr;
+ s->errors->warning_messages[s->errors->warning_count - 1].character = *cptr;
+ s->errors->warning_messages[s->errors->warning_count - 1].message = strdup(error);
+}
+
+static void add_pbf_error(Scanner *s, char *error, char *sptr, char *cptr)
+{
+ 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 = cptr - sptr;
+ s->errors->error_messages[s->errors->error_count - 1].character = *cptr;
+ 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;
return retval;
}
+static timelib_sll timelib_meridian_with_check(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;
+ if (**ptr != 'm' && **ptr != 'M') {
+ return TIMELIB_UNSET;
+ }
+ ++*ptr;
+ if (**ptr != '.' ) {
+ return TIMELIB_UNSET;
+ }
+ ++*ptr;
+ } else if (**ptr == 'm' || **ptr == 'M') {
+ ++*ptr;
+ } else {
+ return TIMELIB_UNSET;
+ }
+ return retval;
+}
+
static char *timelib_string(Scanner *s)
{
char *tmp = calloc(1, s->cur - s->tok + 1);
}
}
+static void timelib_eat_until_seperator(char **ptr)
+{
+ while (strchr(" \t.,:;/-0123456789", **ptr) == NULL) {
+ ++*ptr;
+ }
+}
+
static const timelib_relunit* timelib_lookup_relunit(char **ptr)
{
char *word;
std:
s->tok = cursor;
s->len = 0;
-#line 889 "ext/date/lib/parse_date.re"
+#line 947 "ext/date/lib/parse_date.re"
{
0, 0, 0, 0, 0, 0, 0, 0,
};
-#line 815 "ext/date/lib/parse_date.c"
+#line 873 "ext/date/lib/parse_date.c"
{
YYCTYPE yych;
unsigned int yyaccept = 0;
}
yy3:
YYDEBUG(3, *YYCURSOR);
-#line 1443 "ext/date/lib/parse_date.re"
+#line 1501 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("tzcorrection | tz");
TIMELIB_DEINIT;
return TIMELIB_TIMEZONE;
}
-#line 934 "ext/date/lib/parse_date.c"
+#line 992 "ext/date/lib/parse_date.c"
yy4:
YYDEBUG(4, *YYCURSOR);
yych = *++YYCURSOR;
if(yych <= '9') goto yy1274;
yy12:
YYDEBUG(12, *YYCURSOR);
-#line 1538 "ext/date/lib/parse_date.re"
+#line 1596 "ext/date/lib/parse_date.re"
{
add_error(s, "Unexpected character");
goto std;
}
-#line 1250 "ext/date/lib/parse_date.c"
+#line 1308 "ext/date/lib/parse_date.c"
yy13:
YYDEBUG(13, *YYCURSOR);
yyaccept = 1;
if(yych <= '9') goto yy51;
yy46:
YYDEBUG(46, *YYCURSOR);
-#line 1527 "ext/date/lib/parse_date.re"
+#line 1585 "ext/date/lib/parse_date.re"
{
goto std;
}
-#line 2260 "ext/date/lib/parse_date.c"
+#line 2318 "ext/date/lib/parse_date.c"
yy47:
YYDEBUG(47, *YYCURSOR);
yych = *++YYCURSOR;
YYDEBUG(48, *YYCURSOR);
++YYCURSOR;
YYDEBUG(49, *YYCURSOR);
-#line 1532 "ext/date/lib/parse_date.re"
+#line 1590 "ext/date/lib/parse_date.re"
{
s->pos = cursor; s->line++;
goto std;
}
-#line 2274 "ext/date/lib/parse_date.c"
+#line 2332 "ext/date/lib/parse_date.c"
yy50:
YYDEBUG(50, *YYCURSOR);
yych = *++YYCURSOR;
if(yych == 's') goto yy70;
yy69:
YYDEBUG(69, *YYCURSOR);
-#line 1511 "ext/date/lib/parse_date.re"
+#line 1569 "ext/date/lib/parse_date.re"
{
timelib_ull i;
DEBUG_OUTPUT("relative");
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 2668 "ext/date/lib/parse_date.c"
+#line 2726 "ext/date/lib/parse_date.c"
yy70:
YYDEBUG(70, *YYCURSOR);
yych = *++YYCURSOR;
if(yych == 's') goto yy175;
yy174:
YYDEBUG(174, *YYCURSOR);
-#line 1416 "ext/date/lib/parse_date.re"
+#line 1474 "ext/date/lib/parse_date.re"
{
timelib_sll i;
int behavior = 0;
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 3592 "ext/date/lib/parse_date.c"
+#line 3650 "ext/date/lib/parse_date.c"
yy175:
YYDEBUG(175, *YYCURSOR);
yych = *++YYCURSOR;
}
yy276:
YYDEBUG(276, *YYCURSOR);
-#line 1400 "ext/date/lib/parse_date.re"
+#line 1458 "ext/date/lib/parse_date.re"
{
const timelib_relunit* relunit;
DEBUG_OUTPUT("daytext");
TIMELIB_DEINIT;
return TIMELIB_WEEKDAY;
}
-#line 4782 "ext/date/lib/parse_date.c"
+#line 4840 "ext/date/lib/parse_date.c"
yy277:
YYDEBUG(277, *YYCURSOR);
yych = *++YYCURSOR;
}
yy303:
YYDEBUG(303, *YYCURSOR);
-#line 1433 "ext/date/lib/parse_date.re"
+#line 1491 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("monthtext");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_TEXT;
}
-#line 5268 "ext/date/lib/parse_date.c"
+#line 5326 "ext/date/lib/parse_date.c"
yy304:
YYDEBUG(304, *YYCURSOR);
++YYCURSOR;
}
yy308:
YYDEBUG(308, *YYCURSOR);
-#line 1212 "ext/date/lib/parse_date.re"
+#line 1270 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("datetextual | datenoyear");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_TEXT;
}
-#line 5331 "ext/date/lib/parse_date.c"
+#line 5389 "ext/date/lib/parse_date.c"
yy309:
YYDEBUG(309, *YYCURSOR);
yyaccept = 7;
}
yy332:
YYDEBUG(332, *YYCURSOR);
-#line 1481 "ext/date/lib/parse_date.re"
+#line 1539 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz");
TIMELIB_DEINIT;
return TIMELIB_SHORTDATE_WITH_TIME;
}
-#line 5633 "ext/date/lib/parse_date.c"
+#line 5691 "ext/date/lib/parse_date.c"
yy333:
YYDEBUG(333, *YYCURSOR);
yyaccept = 8;
YYDEBUG(385, *YYCURSOR);
++YYCURSOR;
YYDEBUG(386, *YYCURSOR);
-#line 1457 "ext/date/lib/parse_date.re"
+#line 1515 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("dateshortwithtimeshort12 | dateshortwithtimelong12");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_SHORTDATE_WITH_TIME;
}
-#line 6267 "ext/date/lib/parse_date.c"
+#line 6325 "ext/date/lib/parse_date.c"
yy387:
YYDEBUG(387, *YYCURSOR);
yych = *++YYCURSOR;
if(yych <= '9') goto yy397;
yy402:
YYDEBUG(402, *YYCURSOR);
-#line 1186 "ext/date/lib/parse_date.re"
+#line 1244 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("datenoday");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_NO_DAY;
}
-#line 6455 "ext/date/lib/parse_date.c"
+#line 6513 "ext/date/lib/parse_date.c"
yy403:
YYDEBUG(403, *YYCURSOR);
yyaccept = 7;
if(yych <= '9') goto yy474;
yy473:
YYDEBUG(473, *YYCURSOR);
-#line 1326 "ext/date/lib/parse_date.re"
+#line 1384 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("pgtextshort");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_PG_TEXT;
}
-#line 7703 "ext/date/lib/parse_date.c"
+#line 7761 "ext/date/lib/parse_date.c"
yy474:
YYDEBUG(474, *YYCURSOR);
yych = *++YYCURSOR;
}
yy558:
YYDEBUG(558, *YYCURSOR);
-#line 1382 "ext/date/lib/parse_date.re"
+#line 1440 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("ago");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_AGO;
}
-#line 9601 "ext/date/lib/parse_date.c"
+#line 9659 "ext/date/lib/parse_date.c"
yy559:
YYDEBUG(559, *YYCURSOR);
yyaccept = 6;
++YYCURSOR;
yy660:
YYDEBUG(660, *YYCURSOR);
-#line 1097 "ext/date/lib/parse_date.re"
+#line 1155 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("iso8601date4 | iso8601date2 | iso8601dateslash | dateslash");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 12207 "ext/date/lib/parse_date.c"
+#line 12265 "ext/date/lib/parse_date.c"
yy661:
YYDEBUG(661, *YYCURSOR);
yyaccept = 0;
}
yy681:
YYDEBUG(681, *YYCURSOR);
-#line 1225 "ext/date/lib/parse_date.re"
+#line 1283 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("datenoyearrev");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_TEXT;
}
-#line 12778 "ext/date/lib/parse_date.c"
+#line 12836 "ext/date/lib/parse_date.c"
yy682:
YYDEBUG(682, *YYCURSOR);
yyaccept = 11;
YYDEBUG(693, *YYCURSOR);
++YYCURSOR;
YYDEBUG(694, *YYCURSOR);
-#line 973 "ext/date/lib/parse_date.re"
+#line 1031 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("timetiny12 | timeshort12 | timelong12");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_TIME12;
}
-#line 12935 "ext/date/lib/parse_date.c"
+#line 12993 "ext/date/lib/parse_date.c"
yy695:
YYDEBUG(695, *YYCURSOR);
yyaccept = 12;
}
yy696:
YYDEBUG(696, *YYCURSOR);
-#line 990 "ext/date/lib/parse_date.re"
+#line 1048 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long");
TIMELIB_DEINIT;
return TIMELIB_TIME24_WITH_ZONE;
}
-#line 12973 "ext/date/lib/parse_date.c"
+#line 13031 "ext/date/lib/parse_date.c"
yy697:
YYDEBUG(697, *YYCURSOR);
yyaccept = 12;
if(yych <= '9') goto yy730;
yy724:
YYDEBUG(724, *YYCURSOR);
-#line 1147 "ext/date/lib/parse_date.re"
+#line 1205 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("datefull");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_FULL;
}
-#line 13254 "ext/date/lib/parse_date.c"
+#line 13312 "ext/date/lib/parse_date.c"
yy725:
YYDEBUG(725, *YYCURSOR);
yych = *++YYCURSOR;
if(yych <= '9') goto yy797;
yy796:
YYDEBUG(796, *YYCURSOR);
-#line 1173 "ext/date/lib/parse_date.re"
+#line 1231 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("pointed date YY");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_FULL_POINTED;
}
-#line 14022 "ext/date/lib/parse_date.c"
+#line 14080 "ext/date/lib/parse_date.c"
yy797:
YYDEBUG(797, *YYCURSOR);
yych = *++YYCURSOR;
YYDEBUG(798, *YYCURSOR);
++YYCURSOR;
YYDEBUG(799, *YYCURSOR);
-#line 1161 "ext/date/lib/parse_date.re"
+#line 1219 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("pointed date YYYY");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_FULL_POINTED;
}
-#line 14042 "ext/date/lib/parse_date.c"
+#line 14100 "ext/date/lib/parse_date.c"
yy800:
YYDEBUG(800, *YYCURSOR);
yyaccept = 12;
}
yy844:
YYDEBUG(844, *YYCURSOR);
-#line 1134 "ext/date/lib/parse_date.re"
+#line 1192 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("gnudateshort");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 14672 "ext/date/lib/parse_date.c"
+#line 14730 "ext/date/lib/parse_date.c"
yy845:
YYDEBUG(845, *YYCURSOR);
yyaccept = 14;
}
yy854:
YYDEBUG(854, *YYCURSOR);
-#line 1082 "ext/date/lib/parse_date.re"
+#line 1140 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("americanshort | american");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_AMERICAN;
}
-#line 14792 "ext/date/lib/parse_date.c"
+#line 14850 "ext/date/lib/parse_date.c"
yy855:
YYDEBUG(855, *YYCURSOR);
yyaccept = 15;
if(yych <= ':') goto yy890;
yy887:
YYDEBUG(887, *YYCURSOR);
-#line 1352 "ext/date/lib/parse_date.re"
+#line 1410 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("clf");
TIMELIB_DEINIT;
return TIMELIB_CLF;
}
-#line 15035 "ext/date/lib/parse_date.c"
+#line 15093 "ext/date/lib/parse_date.c"
yy888:
YYDEBUG(888, *YYCURSOR);
yych = *++YYCURSOR;
}
yy942:
YYDEBUG(942, *YYCURSOR);
-#line 1109 "ext/date/lib/parse_date.re"
+#line 1167 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("iso8601date2");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 15542 "ext/date/lib/parse_date.c"
+#line 15600 "ext/date/lib/parse_date.c"
yy943:
YYDEBUG(943, *YYCURSOR);
yych = *++YYCURSOR;
YYDEBUG(949, *YYCURSOR);
++YYCURSOR;
YYDEBUG(950, *YYCURSOR);
-#line 1339 "ext/date/lib/parse_date.re"
+#line 1397 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("pgtextreverse");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_PG_TEXT;
}
-#line 15593 "ext/date/lib/parse_date.c"
+#line 15651 "ext/date/lib/parse_date.c"
yy951:
YYDEBUG(951, *YYCURSOR);
yych = *++YYCURSOR;
}
yy962:
YYDEBUG(962, *YYCURSOR);
-#line 1373 "ext/date/lib/parse_date.re"
+#line 1431 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("year4");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_CLF;
}
-#line 15739 "ext/date/lib/parse_date.c"
+#line 15797 "ext/date/lib/parse_date.c"
yy963:
YYDEBUG(963, *YYCURSOR);
yych = *++YYCURSOR;
}
yy972:
YYDEBUG(972, *YYCURSOR);
-#line 1199 "ext/date/lib/parse_date.re"
+#line 1257 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("datenodayrev");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_NO_DAY;
}
-#line 15902 "ext/date/lib/parse_date.c"
+#line 15960 "ext/date/lib/parse_date.c"
yy973:
YYDEBUG(973, *YYCURSOR);
yych = *++YYCURSOR;
if(yych <= '7') goto yy995;
yy993:
YYDEBUG(993, *YYCURSOR);
-#line 1307 "ext/date/lib/parse_date.re"
+#line 1365 "ext/date/lib/parse_date.re"
{
timelib_sll w, d;
DEBUG_OUTPUT("isoweek");
TIMELIB_DEINIT;
return TIMELIB_ISO_WEEK;
}
-#line 16135 "ext/date/lib/parse_date.c"
+#line 16193 "ext/date/lib/parse_date.c"
yy994:
YYDEBUG(994, *YYCURSOR);
yych = *++YYCURSOR;
YYDEBUG(995, *YYCURSOR);
++YYCURSOR;
YYDEBUG(996, *YYCURSOR);
-#line 1288 "ext/date/lib/parse_date.re"
+#line 1346 "ext/date/lib/parse_date.re"
{
timelib_sll w, d;
DEBUG_OUTPUT("isoweekday");
TIMELIB_DEINIT;
return TIMELIB_ISO_WEEK;
}
-#line 16163 "ext/date/lib/parse_date.c"
+#line 16221 "ext/date/lib/parse_date.c"
yy997:
YYDEBUG(997, *YYCURSOR);
yych = *++YYCURSOR;
}
yy1000:
YYDEBUG(1000, *YYCURSOR);
-#line 1275 "ext/date/lib/parse_date.re"
+#line 1333 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("pgydotd");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_PG_YEARDAY;
}
-#line 16239 "ext/date/lib/parse_date.c"
+#line 16297 "ext/date/lib/parse_date.c"
yy1001:
YYDEBUG(1001, *YYCURSOR);
yych = *++YYCURSOR;
++YYCURSOR;
yy1021:
YYDEBUG(1021, *YYCURSOR);
-#line 1249 "ext/date/lib/parse_date.re"
+#line 1307 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx | exif");
TIMELIB_DEINIT;
return TIMELIB_XMLRPC_SOAP;
}
-#line 16367 "ext/date/lib/parse_date.c"
+#line 16425 "ext/date/lib/parse_date.c"
yy1022:
YYDEBUG(1022, *YYCURSOR);
yych = *++YYCURSOR;
}
yy1027:
YYDEBUG(1027, *YYCURSOR);
-#line 1237 "ext/date/lib/parse_date.re"
+#line 1295 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("datenocolon");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_DATE_NOCOLON;
}
-#line 16640 "ext/date/lib/parse_date.c"
+#line 16698 "ext/date/lib/parse_date.c"
yy1028:
YYDEBUG(1028, *YYCURSOR);
yych = *++YYCURSOR;
if(yych <= '9') goto yy1174;
yy1152:
YYDEBUG(1152, *YYCURSOR);
-#line 1122 "ext/date/lib/parse_date.re"
+#line 1180 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("gnudateshorter");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 17571 "ext/date/lib/parse_date.c"
+#line 17629 "ext/date/lib/parse_date.c"
yy1153:
YYDEBUG(1153, *YYCURSOR);
yyaccept = 23;
}
yy1243:
YYDEBUG(1243, *YYCURSOR);
-#line 1016 "ext/date/lib/parse_date.re"
+#line 1074 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("gnunocolon");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_GNU_NOCOLON;
}
-#line 18584 "ext/date/lib/parse_date.c"
+#line 18642 "ext/date/lib/parse_date.c"
yy1244:
YYDEBUG(1244, *YYCURSOR);
yych = *++YYCURSOR;
}
yy1251:
YYDEBUG(1251, *YYCURSOR);
-#line 1062 "ext/date/lib/parse_date.re"
+#line 1120 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("iso8601nocolon");
TIMELIB_DEINIT;
return TIMELIB_ISO_NOCOLON;
}
-#line 18695 "ext/date/lib/parse_date.c"
+#line 18753 "ext/date/lib/parse_date.c"
yy1252:
YYDEBUG(1252, *YYCURSOR);
yyaccept = 26;
if(yych <= '9') goto yy1274;
yy1276:
YYDEBUG(1276, *YYCURSOR);
-#line 949 "ext/date/lib/parse_date.re"
+#line 1007 "ext/date/lib/parse_date.re"
{
timelib_ull i;
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 19338 "ext/date/lib/parse_date.c"
+#line 19396 "ext/date/lib/parse_date.c"
yy1277:
YYDEBUG(1277, *YYCURSOR);
yych = *++YYCURSOR;
++YYCURSOR;
yy1306:
YYDEBUG(1306, *YYCURSOR);
-#line 937 "ext/date/lib/parse_date.re"
+#line 995 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("tomorrow");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 19785 "ext/date/lib/parse_date.c"
+#line 19843 "ext/date/lib/parse_date.c"
yy1307:
YYDEBUG(1307, *YYCURSOR);
yych = *++YYCURSOR;
}
yy1309:
YYDEBUG(1309, *YYCURSOR);
-#line 927 "ext/date/lib/parse_date.re"
+#line 985 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("midnight | today");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 19829 "ext/date/lib/parse_date.c"
+#line 19887 "ext/date/lib/parse_date.c"
yy1310:
YYDEBUG(1310, *YYCURSOR);
yych = *++YYCURSOR;
}
yy1387:
YYDEBUG(1387, *YYCURSOR);
-#line 906 "ext/date/lib/parse_date.re"
+#line 964 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("now");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 21610 "ext/date/lib/parse_date.c"
+#line 21668 "ext/date/lib/parse_date.c"
yy1388:
YYDEBUG(1388, *YYCURSOR);
yych = *++YYCURSOR;
}
yy1395:
YYDEBUG(1395, *YYCURSOR);
-#line 915 "ext/date/lib/parse_date.re"
+#line 973 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("noon");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 21760 "ext/date/lib/parse_date.c"
+#line 21818 "ext/date/lib/parse_date.c"
yy1396:
YYDEBUG(1396, *YYCURSOR);
yyaccept = 0;
++YYCURSOR;
yy1418:
YYDEBUG(1418, *YYCURSOR);
-#line 894 "ext/date/lib/parse_date.re"
+#line 952 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("yesterday");
TIMELIB_INIT;
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 22251 "ext/date/lib/parse_date.c"
+#line 22309 "ext/date/lib/parse_date.c"
yy1419:
YYDEBUG(1419, *YYCURSOR);
yyaccept = 0;
}
}
}
-#line 1542 "ext/date/lib/parse_date.re"
+#line 1600 "ext/date/lib/parse_date.re"
}
return in.time;
}
+#define TIMELIB_CHECK_NUMBER \
+ if (strchr("0123456789", *ptr) == NULL) \
+ { \
+ add_pbf_error(s, "Unexpected data found.", string, begin); \
+ }
+
+
+timelib_time *timelib_parse_from_format(char *format, char *string, int len, timelib_error_container **errors, const timelib_tzdb *tzdb)
+{
+ char *fptr = format;
+ char *ptr = string;
+ char *begin;
+ timelib_sll tmp;
+ Scanner in;
+ Scanner *s = ∈
+
+ memset(&in, 0, sizeof(in));
+ in.errors = malloc(sizeof(struct timelib_error_container));
+ in.errors->warning_count = 0;
+ in.errors->warning_messages = NULL;
+ in.errors->error_count = 0;
+ in.errors->error_messages = NULL;
+
+ in.time = timelib_time_ctor();
+ in.time->y = TIMELIB_UNSET;
+ in.time->d = TIMELIB_UNSET;
+ in.time->m = TIMELIB_UNSET;
+ in.time->h = TIMELIB_UNSET;
+ in.time->i = TIMELIB_UNSET;
+ in.time->s = TIMELIB_UNSET;
+ in.time->f = TIMELIB_UNSET;
+ in.time->z = TIMELIB_UNSET;
+ in.time->dst = TIMELIB_UNSET;
+ in.tzdb = tzdb;
+ in.time->is_localtime = 0;
+ in.time->zone_type = 0;
+
+ /* Loop over the format string */
+ while (*fptr && *ptr) {
+ begin = ptr;
+ switch (*fptr) {
+ case 'd': // two digit day, with leading zero
+ case 'j': // two digit day, without leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->d = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A two digit day could not be found", string, begin);
+ }
+ break;
+ case 'S': // day suffix, ignored, nor checked
+ timelib_skip_day_suffix((char **) &ptr);
+ break;
+ case 'z': // day of year - resets month (0 based)
+ 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;
+ }
+ break;
+
+ case 'm': // two digit month, with leading zero
+ case 'n': // two digit month, without leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->m = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A two digit month could not be found", string, begin);
+ }
+ break;
+ case 'M': // three letter month
+ case 'F': // full month
+ tmp = timelib_lookup_month((char **) &ptr);
+ if (!tmp) {
+ add_pbf_error(s, "A textual month could not be found", string, begin);
+ } else {
+ s->time->m = tmp;
+ }
+ 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);
+ }
+ TIMELIB_PROCESS_YEAR(s->time->y);
+ break;
+ case 'Y': // four digit year
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->y = timelib_get_nr((char **) &ptr, 4)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A four digit year could not be found", string, begin);
+ }
+ break;
+ case 'g': // two digit hour, with leading zero
+ case 'h': // two digit hour, without leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A two digit hour could not be found", string, begin);
+ }
+ if (s->time->h > 12) {
+ add_pbf_error(s, "Hour can not be higher than 12", string, begin);
+ }
+ break;
+ case 'G': // two digit hour, with leading zero
+ case 'H': // two digit hour, without leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A two digit hour could not be found", string, begin);
+ }
+ break;
+ case 'a': // am/pm/a.m./p.m.
+ case 'A': // AM/PM/A.M./P.M.
+ if (s->time->h == TIMELIB_UNSET) {
+ add_pbf_error(s, "Meridian can only come after an hour has been found", string, begin);
+ } else if ((tmp = timelib_meridian_with_check((char **) &ptr, s->time->h)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A meridian could no tbe found", string, begin);
+ } else {
+ s->time->h += tmp;
+ }
+ 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);
+ }
+ 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);
+ }
+ break;
+ case 'u': // five digit millisecond, with leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->f = timelib_get_nr((char **) &ptr, 5)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A five digit millisecond could not be found", string, begin);
+ }
+ break;
+ case ' ': // any sort of whitespace (' ' and \t)
+ timelib_eat_spaces((char **) &ptr);
+ break;
+ case 'U': // epoch seconds
+ TIMELIB_CHECK_NUMBER;
+ TIMELIB_HAVE_RELATIVE();
+ tmp = timelib_get_unsigned_nr((char **) &ptr, 24);
+ s->time->y = 1970;
+ s->time->m = 1;
+ s->time->d = 1;
+ s->time->h = s->time->i = s->time->s = 0;
+ s->time->f = 0.0;
+ s->time->relative.s += tmp;
+ s->time->is_localtime = 1;
+ s->time->zone_type = TIMELIB_ZONETYPE_OFFSET;
+ s->time->z = 0;
+ break;
+
+ case 'e': // timezone
+ {
+ int tz_not_found;
+ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb);
+ if (tz_not_found) {
+ add_pbf_error(s, "The timezone could not be found in the database", string, begin);
+ }
+ }
+ break;
+
+ case '#': // separation symbol
+ if (*ptr == ';' || *ptr == ':' || *ptr == '/' || *ptr == '.' || *ptr == ',' || *ptr == '-') {
+ ++ptr;
+ } else {
+ add_pbf_error(s, "The seperation symbol ([;:/.,-]) could not be found", string, begin);
+ }
+ break;
+
+ case '?': // random char
+ ++ptr;
+ break;
+
+ case '*': // random chars until a seperator or number ([ \t.,:;/-0123456789])
+ timelib_eat_until_seperator((char **) &ptr);
+ break;
+
+ default:
+ if (*fptr != *ptr) {
+ add_pbf_error(s, "The format seperator does not match", string, begin);
+ }
+ ptr++;
+ }
+ fptr++;
+ }
+ if (*ptr) {
+ add_pbf_error(s, "Trailing data", string, ptr);
+ }
+ if (*fptr) {
+ add_pbf_error(s, "Data missing", string, ptr);
+ }
+
+ if (errors) {
+ *errors = in.errors;
+ } else {
+ timelib_error_container_dtor(in.errors);
+ }
+ return in.time;
+}
+
void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options)
{
if (!(options && TIMELIB_OVERRIDE_TIME) && parsed->have_date && !parsed->have_time) {
s->errors->error_messages[s->errors->error_count - 1].message = strdup(error);
}
+static void add_pbf_warning(Scanner *s, char *error, char *sptr, char *cptr)
+{
+ 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 = cptr - sptr;
+ s->errors->warning_messages[s->errors->warning_count - 1].character = *cptr;
+ s->errors->warning_messages[s->errors->warning_count - 1].message = strdup(error);
+}
+
+static void add_pbf_error(Scanner *s, char *error, char *sptr, char *cptr)
+{
+ 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 = cptr - sptr;
+ s->errors->error_messages[s->errors->error_count - 1].character = *cptr;
+ 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;
return retval;
}
+static timelib_sll timelib_meridian_with_check(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;
+ if (**ptr != 'm' && **ptr != 'M') {
+ return TIMELIB_UNSET;
+ }
+ ++*ptr;
+ if (**ptr != '.' ) {
+ return TIMELIB_UNSET;
+ }
+ ++*ptr;
+ } else if (**ptr == 'm' || **ptr == 'M') {
+ ++*ptr;
+ } else {
+ return TIMELIB_UNSET;
+ }
+ return retval;
+}
+
static char *timelib_string(Scanner *s)
{
char *tmp = calloc(1, s->cur - s->tok + 1);
}
}
+static void timelib_eat_until_seperator(char **ptr)
+{
+ while (strchr(" \t.,:;/-0123456789", **ptr) == NULL) {
+ ++*ptr;
+ }
+}
+
static const timelib_relunit* timelib_lookup_relunit(char **ptr)
{
char *word;
return in.time;
}
+#define TIMELIB_CHECK_NUMBER \
+ if (strchr("0123456789", *ptr) == NULL) \
+ { \
+ add_pbf_error(s, "Unexpected data found.", string, begin); \
+ }
+
+
+timelib_time *timelib_parse_from_format(char *format, char *string, int len, timelib_error_container **errors, const timelib_tzdb *tzdb)
+{
+ char *fptr = format;
+ char *ptr = string;
+ char *begin;
+ timelib_sll tmp;
+ Scanner in;
+ Scanner *s = ∈
+
+ memset(&in, 0, sizeof(in));
+ in.errors = malloc(sizeof(struct timelib_error_container));
+ in.errors->warning_count = 0;
+ in.errors->warning_messages = NULL;
+ in.errors->error_count = 0;
+ in.errors->error_messages = NULL;
+
+ in.time = timelib_time_ctor();
+ in.time->y = TIMELIB_UNSET;
+ in.time->d = TIMELIB_UNSET;
+ in.time->m = TIMELIB_UNSET;
+ in.time->h = TIMELIB_UNSET;
+ in.time->i = TIMELIB_UNSET;
+ in.time->s = TIMELIB_UNSET;
+ in.time->f = TIMELIB_UNSET;
+ in.time->z = TIMELIB_UNSET;
+ in.time->dst = TIMELIB_UNSET;
+ in.tzdb = tzdb;
+ in.time->is_localtime = 0;
+ in.time->zone_type = 0;
+
+ /* Loop over the format string */
+ while (*fptr && *ptr) {
+ begin = ptr;
+ switch (*fptr) {
+ case 'd': // two digit day, with leading zero
+ case 'j': // two digit day, without leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->d = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A two digit day could not be found", string, begin);
+ }
+ break;
+ case 'S': // day suffix, ignored, nor checked
+ timelib_skip_day_suffix((char **) &ptr);
+ break;
+ case 'z': // day of year - resets month (0 based)
+ 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;
+ }
+ break;
+
+ case 'm': // two digit month, with leading zero
+ case 'n': // two digit month, without leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->m = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A two digit month could not be found", string, begin);
+ }
+ break;
+ case 'M': // three letter month
+ case 'F': // full month
+ tmp = timelib_lookup_month((char **) &ptr);
+ if (!tmp) {
+ add_pbf_error(s, "A textual month could not be found", string, begin);
+ } else {
+ s->time->m = tmp;
+ }
+ 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);
+ }
+ TIMELIB_PROCESS_YEAR(s->time->y);
+ break;
+ case 'Y': // four digit year
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->y = timelib_get_nr((char **) &ptr, 4)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A four digit year could not be found", string, begin);
+ }
+ break;
+ case 'g': // two digit hour, with leading zero
+ case 'h': // two digit hour, without leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A two digit hour could not be found", string, begin);
+ }
+ if (s->time->h > 12) {
+ add_pbf_error(s, "Hour can not be higher than 12", string, begin);
+ }
+ break;
+ case 'G': // two digit hour, with leading zero
+ case 'H': // two digit hour, without leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A two digit hour could not be found", string, begin);
+ }
+ break;
+ case 'a': // am/pm/a.m./p.m.
+ case 'A': // AM/PM/A.M./P.M.
+ if (s->time->h == TIMELIB_UNSET) {
+ add_pbf_error(s, "Meridian can only come after an hour has been found", string, begin);
+ } else if ((tmp = timelib_meridian_with_check((char **) &ptr, s->time->h)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A meridian could no tbe found", string, begin);
+ } else {
+ s->time->h += tmp;
+ }
+ 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);
+ }
+ 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);
+ }
+ break;
+ case 'u': // five digit millisecond, with leading zero
+ TIMELIB_CHECK_NUMBER;
+ if ((s->time->f = timelib_get_nr((char **) &ptr, 5)) == TIMELIB_UNSET) {
+ add_pbf_error(s, "A five digit millisecond could not be found", string, begin);
+ }
+ break;
+ case ' ': // any sort of whitespace (' ' and \t)
+ timelib_eat_spaces((char **) &ptr);
+ break;
+ case 'U': // epoch seconds
+ TIMELIB_CHECK_NUMBER;
+ TIMELIB_HAVE_RELATIVE();
+ tmp = timelib_get_unsigned_nr((char **) &ptr, 24);
+ s->time->y = 1970;
+ s->time->m = 1;
+ s->time->d = 1;
+ s->time->h = s->time->i = s->time->s = 0;
+ s->time->f = 0.0;
+ s->time->relative.s += tmp;
+ s->time->is_localtime = 1;
+ s->time->zone_type = TIMELIB_ZONETYPE_OFFSET;
+ s->time->z = 0;
+ break;
+
+ case 'e': // timezone
+ {
+ int tz_not_found;
+ s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb);
+ if (tz_not_found) {
+ add_pbf_error(s, "The timezone could not be found in the database", string, begin);
+ }
+ }
+ break;
+
+ case '#': // separation symbol
+ if (*ptr == ';' || *ptr == ':' || *ptr == '/' || *ptr == '.' || *ptr == ',' || *ptr == '-') {
+ ++ptr;
+ } else {
+ add_pbf_error(s, "The seperation symbol ([;:/.,-]) could not be found", string, begin);
+ }
+ break;
+
+ case '?': // random char
+ ++ptr;
+ break;
+
+ case '*': // random chars until a seperator or number ([ \t.,:;/-0123456789])
+ timelib_eat_until_seperator((char **) &ptr);
+ break;
+
+ default:
+ if (*fptr != *ptr) {
+ add_pbf_error(s, "The format seperator does not match", string, begin);
+ }
+ ptr++;
+ }
+ fptr++;
+ }
+ if (*ptr) {
+ add_pbf_error(s, "Trailing data", string, ptr);
+ }
+ if (*fptr) {
+ add_pbf_error(s, "Data missing", string, ptr);
+ }
+
+ if (errors) {
+ *errors = in.errors;
+ } else {
+ timelib_error_container_dtor(in.errors);
+ }
+ return in.time;
+}
+
void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options)
{
if (!(options && TIMELIB_OVERRIDE_TIME) && parsed->have_date && !parsed->have_time) {
/* Advanced Interface */
PHP_FE(date_create, NULL)
+ PHP_FE(date_create_from_format, NULL)
PHP_FE(date_parse, NULL)
+ PHP_FE(date_parse_from_format, NULL)
+ PHP_FE(date_get_last_errors, NULL)
PHP_FE(date_format, NULL)
PHP_FE(date_format_locale, NULL)
PHP_FE(date_modify, NULL)
const zend_function_entry date_funcs_date[] = {
PHP_ME(DateTime, __construct, NULL, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(createFromFormat, date_create_from_format, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(getLastErrors, date_get_last_errors, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME_MAPPING(format, date_format, NULL, 0)
PHP_ME_MAPPING(modify, date_modify, NULL, 0)
PHP_ME_MAPPING(getTimezone, date_timezone_get, NULL, 0)
php_date_global_timezone_db = NULL;
php_date_global_timezone_db_enabled = 0;
-
+
+ DATEG(last_errors) = NULL;
return SUCCESS;
}
/* }}} */
{
UNREGISTER_INI_ENTRIES();
+ if (DATEG(last_errors)) {
+ timelib_error_container_dtor(DATEG(last_errors));
+ }
+
return SUCCESS;
}
/* }}} */
return object;
}
-static void date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int time_str_len, zval *timezone_object TSRMLS_DC)
+/* Helper function used to store the latest found warnings and errors while
+ * parsing, from either strtotime or parse_from_format. */
+static void update_errors_warnings(timelib_error_container *last_errors)
+{
+ if (DATEG(last_errors)) {
+ timelib_error_container_dtor(DATEG(last_errors));
+ DATEG(last_errors) = NULL;
+ }
+ DATEG(last_errors) = last_errors;
+}
+
+static void date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int time_str_len, char *format, zval *timezone_object TSRMLS_DC)
{
timelib_time *now;
timelib_tzinfo *tzi;
}
timelib_time_dtor(dateobj->time);
}
- dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, &err, DATE_TIMEZONEDB);
- if (err) {
- if (err->error_count) {
- /* spit out the first library error message, at least */
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", time_str,
- err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message);
- }
- timelib_error_container_dtor(err);
+ if (format) {
+ dateobj->time = timelib_parse_from_format(format, time_str_len ? time_str : "", time_str_len ? time_str_len : 0, &err, DATE_TIMEZONEDB);
+ } else {
+ dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, &err, DATE_TIMEZONEDB);
}
+ // update last errors and warnings
+ update_errors_warnings(err);
+
if (timezone_object) {
php_timezone_obj *tzobj;
}
date_instantiate(date_ce_date, return_value TSRMLS_CC);
- date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, timezone_object TSRMLS_CC);
+ date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, NULL, timezone_object TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto DateTime date_create(string format, string time[, DateTimeZone object])
+ Returns new DateTime object
+*/
+PHP_FUNCTION(date_create_from_format)
+{
+ zval *timezone_object = NULL;
+ char *time_str = NULL, *format_str = NULL;
+ int time_str_len = 0, format_str_len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|O", &format_str, &format_str_len, &time_str, &time_str_len, &timezone_object, date_ce_timezone) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ date_instantiate(date_ce_date, return_value TSRMLS_CC);
+ date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, format_str, timezone_object TSRMLS_CC);
}
/* }}} */
php_set_error_handling(EH_THROW, NULL TSRMLS_CC);
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO", &time_str, &time_str_len, &timezone_object, date_ce_timezone)) {
- date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, timezone_object TSRMLS_CC);
+ date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, NULL, timezone_object TSRMLS_CC);
}
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
}
/* }}} */
-/* {{{ proto array date_parse(string date)
- Returns associative array with detailed info about given date
+/* Helper function used to add an associative array of warnings and errors to a zval */
+void zval_from_error_container(zval *z, timelib_error_container *error)
+{
+ int i;
+ zval *element;
+
+ add_ascii_assoc_long(z, "warning_count", error->warning_count);
+ MAKE_STD_ZVAL(element);
+ array_init(element);
+ for (i = 0; i < error->warning_count; i++) {
+ add_index_string(element, error->warning_messages[i].position, error->warning_messages[i].message, 1);
+ }
+ add_ascii_assoc_zval(z, "warnings", element);
+
+ add_ascii_assoc_long(z, "error_count", error->error_count);
+ MAKE_STD_ZVAL(element);
+ array_init(element);
+ for (i = 0; i < error->error_count; i++) {
+ add_index_string(element, error->error_messages[i].position, error->error_messages[i].message, 1);
+ }
+ add_ascii_assoc_zval(z, "errors", element);
+}
+
+/* {{{ proto array date_get_last_errorse()
+ Returns the warnings and errors found while parsing a date/time string.
*/
-PHP_FUNCTION(date_parse)
+PHP_FUNCTION(date_get_last_errors)
{
- char *date;
- int date_len, i;
- struct timelib_error_container *error;
- timelib_time *parsed_time;
- zval *element;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &date, &date_len) == FAILURE) {
+ array_init(return_value);
+ if (DATEG(last_errors)) {
+ zval_from_error_container(return_value, DATEG(last_errors));
+ } else {
RETURN_FALSE;
}
+}
+/* }}} */
+
+void php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAMETERS, timelib_time *parsed_time, struct timelib_error_container *error)
+{
+ zval *element;
- parsed_time = timelib_strtotime(date, date_len, &error, DATE_TIMEZONEDB);
array_init(return_value);
#define PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(name, elem) \
if (parsed_time->elem == -99999) { \
add_ascii_assoc_double(return_value, "fraction", parsed_time->f);
}
- add_ascii_assoc_long(return_value, "warning_count", error->warning_count);
- MAKE_STD_ZVAL(element);
- array_init(element);
- for (i = 0; i < error->warning_count; i++) {
- add_index_string(element, error->warning_messages[i].position, error->warning_messages[i].message, 1);
- }
- add_ascii_assoc_zval(return_value, "warnings", element);
+ zval_from_error_container(return_value, error);
- add_ascii_assoc_long(return_value, "error_count", error->error_count);
- MAKE_STD_ZVAL(element);
- array_init(element);
- for (i = 0; i < error->error_count; i++) {
- add_index_string(element, error->error_messages[i].position, error->error_messages[i].message, 1);
- }
- add_ascii_assoc_zval(return_value, "errors", element);
timelib_error_container_dtor(error);
add_ascii_assoc_bool(return_value, "is_localtime", parsed_time->is_localtime);
}
timelib_time_dtor(parsed_time);
}
+
+/* {{{ proto array date_parse(string date)
+ Returns associative array with detailed info about given date
+*/
+PHP_FUNCTION(date_parse)
+{
+ char *date;
+ int date_len;
+ struct timelib_error_container *error;
+ timelib_time *parsed_time;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &date, &date_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ parsed_time = timelib_strtotime(date, date_len, &error, DATE_TIMEZONEDB);
+ php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAM_PASSTHRU, parsed_time, error);
+}
/* }}} */
+/* {{{ proto array date_parse(string date)
+ Returns associative array with detailed info about given date
+*/
+PHP_FUNCTION(date_parse_from_format)
+{
+ char *date, *format;
+ int date_len, format_len;
+ struct timelib_error_container *error;
+ timelib_time *parsed_time;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &format, &format_len, &date, &date_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ parsed_time = timelib_parse_from_format(format, date, date_len, &error, DATE_TIMEZONEDB);
+ php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAM_PASSTHRU, parsed_time, error);
+}
+
/* {{{ proto string date_format(DateTime object, string format)
Returns date formatted according to given format
*/