Annotation of embedaddon/php/ext/date/lib/parse_date.re, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2010 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Authors: Derick Rethans <derick@derickrethans.nl> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: parse_date.re 320481 2011-12-06 06:21:08Z derick $ */
! 20:
! 21: #include "timelib.h"
! 22:
! 23: #include <stdio.h>
! 24: #include <ctype.h>
! 25: #include <math.h>
! 26: #include <assert.h>
! 27:
! 28: #ifdef HAVE_STDLIB_H
! 29: #include <stdlib.h>
! 30: #endif
! 31: #ifdef HAVE_STRING_H
! 32: #include <string.h>
! 33: #else
! 34: #include <strings.h>
! 35: #endif
! 36:
! 37: #if defined(_MSC_VER)
! 38: # define strtoll(s, f, b) _atoi64(s)
! 39: #elif !defined(HAVE_STRTOLL)
! 40: # if defined(HAVE_ATOLL)
! 41: # define strtoll(s, f, b) atoll(s)
! 42: # else
! 43: # define strtoll(s, f, b) strtol(s, f, b)
! 44: # endif
! 45: #endif
! 46:
! 47: #define TIMELIB_UNSET -99999
! 48:
! 49: #define TIMELIB_SECOND 1
! 50: #define TIMELIB_MINUTE 2
! 51: #define TIMELIB_HOUR 3
! 52: #define TIMELIB_DAY 4
! 53: #define TIMELIB_MONTH 5
! 54: #define TIMELIB_YEAR 6
! 55: #define TIMELIB_WEEKDAY 7
! 56: #define TIMELIB_SPECIAL 8
! 57:
! 58: #define EOI 257
! 59: #define TIME 258
! 60: #define DATE 259
! 61:
! 62: #define TIMELIB_XMLRPC_SOAP 260
! 63: #define TIMELIB_TIME12 261
! 64: #define TIMELIB_TIME24 262
! 65: #define TIMELIB_GNU_NOCOLON 263
! 66: #define TIMELIB_GNU_NOCOLON_TZ 264
! 67: #define TIMELIB_ISO_NOCOLON 265
! 68:
! 69: #define TIMELIB_AMERICAN 266
! 70: #define TIMELIB_ISO_DATE 267
! 71: #define TIMELIB_DATE_FULL 268
! 72: #define TIMELIB_DATE_TEXT 269
! 73: #define TIMELIB_DATE_NOCOLON 270
! 74: #define TIMELIB_PG_YEARDAY 271
! 75: #define TIMELIB_PG_TEXT 272
! 76: #define TIMELIB_PG_REVERSE 273
! 77: #define TIMELIB_CLF 274
! 78: #define TIMELIB_DATE_NO_DAY 275
! 79: #define TIMELIB_SHORTDATE_WITH_TIME 276
! 80: #define TIMELIB_DATE_FULL_POINTED 277
! 81: #define TIMELIB_TIME24_WITH_ZONE 278
! 82: #define TIMELIB_ISO_WEEK 279
! 83: #define TIMELIB_LF_DAY_OF_MONTH 280
! 84: #define TIMELIB_WEEK_DAY_OF_MONTH 281
! 85:
! 86: #define TIMELIB_TIMEZONE 300
! 87: #define TIMELIB_AGO 301
! 88:
! 89: #define TIMELIB_RELATIVE 310
! 90:
! 91: #define TIMELIB_ERROR 999
! 92:
! 93: /* Some compilers like AIX, defines uchar in sys/types.h */
! 94: #undef uchar
! 95: typedef unsigned char uchar;
! 96:
! 97: #define BSIZE 8192
! 98:
! 99: #define YYCTYPE uchar
! 100: #define YYCURSOR cursor
! 101: #define YYLIMIT s->lim
! 102: #define YYMARKER s->ptr
! 103: #define YYFILL(n) return EOI;
! 104:
! 105: #define RET(i) {s->cur = cursor; return i;}
! 106:
! 107: #define timelib_string_free free
! 108:
! 109: #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; } }
! 110: #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; }
! 111: #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; } }
! 112: #define TIMELIB_UNHAVE_DATE() { s->time->have_date = 0; s->time->d = 0; s->time->m = 0; s->time->y = 0; }
! 113: #define TIMELIB_HAVE_RELATIVE() { s->time->have_relative = 1; }
! 114: #define TIMELIB_HAVE_WEEKDAY_RELATIVE() { s->time->have_relative = 1; s->time->relative.have_weekday_relative = 1; }
! 115: #define TIMELIB_HAVE_SPECIAL_RELATIVE() { s->time->have_relative = 1; s->time->relative.have_special_relative = 1; }
! 116: #define TIMELIB_HAVE_TZ() { s->cur = cursor; if (s->time->have_zone) { s->time->have_zone > 1 ? add_error(s, "Double timezone specification") : add_warning(s, "Double timezone specification"); timelib_string_free(str); s->time->have_zone++; return TIMELIB_ERROR; } else { s->time->have_zone++; } }
! 117:
! 118: #define TIMELIB_INIT s->cur = cursor; str = timelib_string(s); ptr = str
! 119: #define TIMELIB_DEINIT timelib_string_free(str)
! 120: #define TIMELIB_ADJUST_RELATIVE_WEEKDAY() if (in->time.have_weekday_relative && (in.rel.d > 0)) { in.rel.d -= 7; }
! 121:
! 122: #define TIMELIB_PROCESS_YEAR(x, l) { \
! 123: if (((x) == TIMELIB_UNSET) || ((l) >= 4)) { \
! 124: /* (x) = 0; */ \
! 125: } else if ((x) < 100) { \
! 126: if ((x) < 70) { \
! 127: (x) += 2000; \
! 128: } else { \
! 129: (x) += 1900; \
! 130: } \
! 131: } \
! 132: }
! 133:
! 134: #ifdef DEBUG_PARSER
! 135: #define DEBUG_OUTPUT(s) printf("%s\n", s);
! 136: #define YYDEBUG(s,c) { if (s != -1) { printf("state: %d ", s); printf("[%c]\n", c); } }
! 137: #else
! 138: #define DEBUG_OUTPUT(s)
! 139: #define YYDEBUG(s,c)
! 140: #endif
! 141:
! 142: #include "timelib_structs.h"
! 143:
! 144: typedef struct timelib_elems {
! 145: unsigned int c; /* Number of elements */
! 146: char **v; /* Values */
! 147: } timelib_elems;
! 148:
! 149: typedef struct Scanner {
! 150: int fd;
! 151: uchar *lim, *str, *ptr, *cur, *tok, *pos;
! 152: unsigned int line, len;
! 153: struct timelib_error_container *errors;
! 154:
! 155: struct timelib_time *time;
! 156: const timelib_tzdb *tzdb;
! 157: } Scanner;
! 158:
! 159: typedef struct _timelib_lookup_table {
! 160: const char *name;
! 161: int type;
! 162: int value;
! 163: } timelib_lookup_table;
! 164:
! 165: typedef struct _timelib_relunit {
! 166: const char *name;
! 167: int unit;
! 168: int multiplier;
! 169: } timelib_relunit;
! 170:
! 171: #define HOUR(a) (int)(a * 60)
! 172:
! 173: /* The timezone table. */
! 174: const static timelib_tz_lookup_table timelib_timezone_lookup[] = {
! 175: #include "timezonemap.h"
! 176: { NULL, 0, 0, NULL },
! 177: };
! 178:
! 179: const static timelib_tz_lookup_table timelib_timezone_fallbackmap[] = {
! 180: #include "fallbackmap.h"
! 181: { NULL, 0, 0, NULL },
! 182: };
! 183:
! 184: const static timelib_tz_lookup_table timelib_timezone_utc[] = {
! 185: { "utc", 0, 0, "UTC" },
! 186: };
! 187:
! 188: static timelib_relunit const timelib_relunit_lookup[] = {
! 189: { "sec", TIMELIB_SECOND, 1 },
! 190: { "secs", TIMELIB_SECOND, 1 },
! 191: { "second", TIMELIB_SECOND, 1 },
! 192: { "seconds", TIMELIB_SECOND, 1 },
! 193: { "min", TIMELIB_MINUTE, 1 },
! 194: { "mins", TIMELIB_MINUTE, 1 },
! 195: { "minute", TIMELIB_MINUTE, 1 },
! 196: { "minutes", TIMELIB_MINUTE, 1 },
! 197: { "hour", TIMELIB_HOUR, 1 },
! 198: { "hours", TIMELIB_HOUR, 1 },
! 199: { "day", TIMELIB_DAY, 1 },
! 200: { "days", TIMELIB_DAY, 1 },
! 201: { "week", TIMELIB_DAY, 7 },
! 202: { "weeks", TIMELIB_DAY, 7 },
! 203: { "fortnight", TIMELIB_DAY, 14 },
! 204: { "fortnights", TIMELIB_DAY, 14 },
! 205: { "forthnight", TIMELIB_DAY, 14 },
! 206: { "forthnights", TIMELIB_DAY, 14 },
! 207: { "month", TIMELIB_MONTH, 1 },
! 208: { "months", TIMELIB_MONTH, 1 },
! 209: { "year", TIMELIB_YEAR, 1 },
! 210: { "years", TIMELIB_YEAR, 1 },
! 211:
! 212: { "monday", TIMELIB_WEEKDAY, 1 },
! 213: { "mon", TIMELIB_WEEKDAY, 1 },
! 214: { "tuesday", TIMELIB_WEEKDAY, 2 },
! 215: { "tue", TIMELIB_WEEKDAY, 2 },
! 216: { "wednesday", TIMELIB_WEEKDAY, 3 },
! 217: { "wed", TIMELIB_WEEKDAY, 3 },
! 218: { "thursday", TIMELIB_WEEKDAY, 4 },
! 219: { "thu", TIMELIB_WEEKDAY, 4 },
! 220: { "friday", TIMELIB_WEEKDAY, 5 },
! 221: { "fri", TIMELIB_WEEKDAY, 5 },
! 222: { "saturday", TIMELIB_WEEKDAY, 6 },
! 223: { "sat", TIMELIB_WEEKDAY, 6 },
! 224: { "sunday", TIMELIB_WEEKDAY, 0 },
! 225: { "sun", TIMELIB_WEEKDAY, 0 },
! 226:
! 227: { "weekday", TIMELIB_SPECIAL, TIMELIB_SPECIAL_WEEKDAY },
! 228: { "weekdays", TIMELIB_SPECIAL, TIMELIB_SPECIAL_WEEKDAY },
! 229: { NULL, 0, 0 }
! 230: };
! 231:
! 232: /* The relative text table. */
! 233: static timelib_lookup_table const timelib_reltext_lookup[] = {
! 234: { "first", 0, 1 },
! 235: { "next", 0, 1 },
! 236: { "second", 0, 2 },
! 237: { "third", 0, 3 },
! 238: { "fourth", 0, 4 },
! 239: { "fifth", 0, 5 },
! 240: { "sixth", 0, 6 },
! 241: { "seventh", 0, 7 },
! 242: { "eight", 0, 8 },
! 243: { "eighth", 0, 8 },
! 244: { "ninth", 0, 9 },
! 245: { "tenth", 0, 10 },
! 246: { "eleventh", 0, 11 },
! 247: { "twelfth", 0, 12 },
! 248: { "last", 0, -1 },
! 249: { "previous", 0, -1 },
! 250: { "this", 1, 0 },
! 251: { NULL, 1, 0 }
! 252: };
! 253:
! 254: /* The month table. */
! 255: static timelib_lookup_table const timelib_month_lookup[] = {
! 256: { "jan", 0, 1 },
! 257: { "feb", 0, 2 },
! 258: { "mar", 0, 3 },
! 259: { "apr", 0, 4 },
! 260: { "may", 0, 5 },
! 261: { "jun", 0, 6 },
! 262: { "jul", 0, 7 },
! 263: { "aug", 0, 8 },
! 264: { "sep", 0, 9 },
! 265: { "sept", 0, 9 },
! 266: { "oct", 0, 10 },
! 267: { "nov", 0, 11 },
! 268: { "dec", 0, 12 },
! 269: { "i", 0, 1 },
! 270: { "ii", 0, 2 },
! 271: { "iii", 0, 3 },
! 272: { "iv", 0, 4 },
! 273: { "v", 0, 5 },
! 274: { "vi", 0, 6 },
! 275: { "vii", 0, 7 },
! 276: { "viii", 0, 8 },
! 277: { "ix", 0, 9 },
! 278: { "x", 0, 10 },
! 279: { "xi", 0, 11 },
! 280: { "xii", 0, 12 },
! 281:
! 282: { "january", 0, 1 },
! 283: { "february", 0, 2 },
! 284: { "march", 0, 3 },
! 285: { "april", 0, 4 },
! 286: { "may", 0, 5 },
! 287: { "june", 0, 6 },
! 288: { "july", 0, 7 },
! 289: { "august", 0, 8 },
! 290: { "september", 0, 9 },
! 291: { "october", 0, 10 },
! 292: { "november", 0, 11 },
! 293: { "december", 0, 12 },
! 294: { NULL, 0, 0 }
! 295: };
! 296:
! 297: #if 0
! 298: static char* timelib_ltrim(char *s)
! 299: {
! 300: char *ptr = s;
! 301: while (ptr[0] == ' ' || ptr[0] == '\t') {
! 302: ptr++;
! 303: }
! 304: return ptr;
! 305: }
! 306: #endif
! 307:
! 308: #if 0
! 309: uchar *fill(Scanner *s, uchar *cursor){
! 310: if(!s->eof){
! 311: unsigned int cnt = s->tok - s->bot;
! 312: if(cnt){
! 313: memcpy(s->bot, s->tok, s->lim - s->tok);
! 314: s->tok = s->bot;
! 315: s->ptr -= cnt;
! 316: cursor -= cnt;
! 317: s->pos -= cnt;
! 318: s->lim -= cnt;
! 319: }
! 320: if((s->top - s->lim) < BSIZE){
! 321: uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
! 322: memcpy(buf, s->tok, s->lim - s->tok);
! 323: s->tok = buf;
! 324: s->ptr = &buf[s->ptr - s->bot];
! 325: cursor = &buf[cursor - s->bot];
! 326: s->pos = &buf[s->pos - s->bot];
! 327: s->lim = &buf[s->lim - s->bot];
! 328: s->top = &s->lim[BSIZE];
! 329: free(s->bot);
! 330: s->bot = buf;
! 331: }
! 332: if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
! 333: s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
! 334: }
! 335: s->lim += cnt;
! 336: }
! 337: return cursor;
! 338: }
! 339: #endif
! 340:
! 341: static void add_warning(Scanner *s, char *error)
! 342: {
! 343: s->errors->warning_count++;
! 344: s->errors->warning_messages = realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message));
! 345: s->errors->warning_messages[s->errors->warning_count - 1].position = s->tok ? s->tok - s->str : 0;
! 346: s->errors->warning_messages[s->errors->warning_count - 1].character = s->tok ? *s->tok : 0;
! 347: s->errors->warning_messages[s->errors->warning_count - 1].message = strdup(error);
! 348: }
! 349:
! 350: static void add_error(Scanner *s, char *error)
! 351: {
! 352: s->errors->error_count++;
! 353: s->errors->error_messages = realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
! 354: s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0;
! 355: s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0;
! 356: s->errors->error_messages[s->errors->error_count - 1].message = strdup(error);
! 357: }
! 358:
! 359: static void add_pbf_warning(Scanner *s, char *error, char *sptr, char *cptr)
! 360: {
! 361: s->errors->warning_count++;
! 362: s->errors->warning_messages = realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message));
! 363: s->errors->warning_messages[s->errors->warning_count - 1].position = cptr - sptr;
! 364: s->errors->warning_messages[s->errors->warning_count - 1].character = *cptr;
! 365: s->errors->warning_messages[s->errors->warning_count - 1].message = strdup(error);
! 366: }
! 367:
! 368: static void add_pbf_error(Scanner *s, char *error, char *sptr, char *cptr)
! 369: {
! 370: s->errors->error_count++;
! 371: s->errors->error_messages = realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
! 372: s->errors->error_messages[s->errors->error_count - 1].position = cptr - sptr;
! 373: s->errors->error_messages[s->errors->error_count - 1].character = *cptr;
! 374: s->errors->error_messages[s->errors->error_count - 1].message = strdup(error);
! 375: }
! 376:
! 377: static timelib_sll timelib_meridian(char **ptr, timelib_sll h)
! 378: {
! 379: timelib_sll retval = 0;
! 380:
! 381: while (!strchr("AaPp", **ptr)) {
! 382: ++*ptr;
! 383: }
! 384: if (**ptr == 'a' || **ptr == 'A') {
! 385: if (h == 12) {
! 386: retval = -12;
! 387: }
! 388: } else if (h != 12) {
! 389: retval = 12;
! 390: }
! 391: ++*ptr;
! 392: if (**ptr == '.') {
! 393: *ptr += 3;
! 394: } else {
! 395: ++*ptr;
! 396: }
! 397: return retval;
! 398: }
! 399:
! 400: static timelib_sll timelib_meridian_with_check(char **ptr, timelib_sll h)
! 401: {
! 402: timelib_sll retval = 0;
! 403:
! 404: while (!strchr("AaPp", **ptr)) {
! 405: ++*ptr;
! 406: }
! 407: if (**ptr == 'a' || **ptr == 'A') {
! 408: if (h == 12) {
! 409: retval = -12;
! 410: }
! 411: } else if (h != 12) {
! 412: retval = 12;
! 413: }
! 414: ++*ptr;
! 415: if (**ptr == '.') {
! 416: ++*ptr;
! 417: if (**ptr != 'm' && **ptr != 'M') {
! 418: return TIMELIB_UNSET;
! 419: }
! 420: ++*ptr;
! 421: if (**ptr != '.' ) {
! 422: return TIMELIB_UNSET;
! 423: }
! 424: ++*ptr;
! 425: } else if (**ptr == 'm' || **ptr == 'M') {
! 426: ++*ptr;
! 427: } else {
! 428: return TIMELIB_UNSET;
! 429: }
! 430: return retval;
! 431: }
! 432:
! 433: static char *timelib_string(Scanner *s)
! 434: {
! 435: char *tmp = calloc(1, s->cur - s->tok + 1);
! 436: memcpy(tmp, s->tok, s->cur - s->tok);
! 437:
! 438: return tmp;
! 439: }
! 440:
! 441: static timelib_sll timelib_get_nr_ex(char **ptr, int max_length, int *scanned_length)
! 442: {
! 443: char *begin, *end, *str;
! 444: timelib_sll tmp_nr = TIMELIB_UNSET;
! 445: int len = 0;
! 446:
! 447: while ((**ptr < '0') || (**ptr > '9')) {
! 448: if (**ptr == '\0') {
! 449: return TIMELIB_UNSET;
! 450: }
! 451: ++*ptr;
! 452: }
! 453: begin = *ptr;
! 454: while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) {
! 455: ++*ptr;
! 456: ++len;
! 457: }
! 458: end = *ptr;
! 459: if (scanned_length) {
! 460: *scanned_length = end - begin;
! 461: }
! 462: str = calloc(1, end - begin + 1);
! 463: memcpy(str, begin, end - begin);
! 464: tmp_nr = strtoll(str, NULL, 10);
! 465: free(str);
! 466: return tmp_nr;
! 467: }
! 468:
! 469: static timelib_sll timelib_get_nr(char **ptr, int max_length)
! 470: {
! 471: return timelib_get_nr_ex(ptr, max_length, NULL);
! 472: }
! 473:
! 474: static void timelib_skip_day_suffix(char **ptr)
! 475: {
! 476: if (isspace(**ptr)) {
! 477: return;
! 478: }
! 479: if (!strncasecmp(*ptr, "nd", 2) || !strncasecmp(*ptr, "rd", 2) ||!strncasecmp(*ptr, "st", 2) || !strncasecmp(*ptr, "th", 2)) {
! 480: *ptr += 2;
! 481: }
! 482: }
! 483:
! 484: static double timelib_get_frac_nr(char **ptr, int max_length)
! 485: {
! 486: char *begin, *end, *str;
! 487: double tmp_nr = TIMELIB_UNSET;
! 488: int len = 0;
! 489:
! 490: while ((**ptr != '.') && (**ptr != ':') && ((**ptr < '0') || (**ptr > '9'))) {
! 491: if (**ptr == '\0') {
! 492: return TIMELIB_UNSET;
! 493: }
! 494: ++*ptr;
! 495: }
! 496: begin = *ptr;
! 497: while (((**ptr == '.') || (**ptr == ':') || ((**ptr >= '0') && (**ptr <= '9'))) && len < max_length) {
! 498: ++*ptr;
! 499: ++len;
! 500: }
! 501: end = *ptr;
! 502: str = calloc(1, end - begin + 1);
! 503: memcpy(str, begin, end - begin);
! 504: if (str[0] == ':') {
! 505: str[0] = '.';
! 506: }
! 507: tmp_nr = strtod(str, NULL);
! 508: free(str);
! 509: return tmp_nr;
! 510: }
! 511:
! 512: static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
! 513: {
! 514: timelib_ull dir = 1;
! 515:
! 516: while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) {
! 517: if (**ptr == '\0') {
! 518: return TIMELIB_UNSET;
! 519: }
! 520: ++*ptr;
! 521: }
! 522:
! 523: while (**ptr == '+' || **ptr == '-')
! 524: {
! 525: if (**ptr == '-') {
! 526: dir *= -1;
! 527: }
! 528: ++*ptr;
! 529: }
! 530: return dir * timelib_get_nr(ptr, max_length);
! 531: }
! 532:
! 533: static long timelib_parse_tz_cor(char **ptr)
! 534: {
! 535: char *begin = *ptr, *end;
! 536: long tmp;
! 537:
! 538: while (isdigit(**ptr) || **ptr == ':') {
! 539: ++*ptr;
! 540: }
! 541: end = *ptr;
! 542: switch (end - begin) {
! 543: case 1:
! 544: case 2:
! 545: return HOUR(strtol(begin, NULL, 10));
! 546: break;
! 547: case 3:
! 548: case 4:
! 549: if (begin[1] == ':') {
! 550: tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
! 551: return tmp;
! 552: } else if (begin[2] == ':') {
! 553: tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
! 554: return tmp;
! 555: } else {
! 556: tmp = strtol(begin, NULL, 10);
! 557: return HOUR(tmp / 100) + tmp % 100;
! 558: }
! 559: case 5:
! 560: tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
! 561: return tmp;
! 562: }
! 563: return 0;
! 564: }
! 565:
! 566: static timelib_sll timelib_lookup_relative_text(char **ptr, int *behavior)
! 567: {
! 568: char *word;
! 569: char *begin = *ptr, *end;
! 570: timelib_sll value = 0;
! 571: const timelib_lookup_table *tp;
! 572:
! 573: while ((**ptr >= 'A' && **ptr <= 'Z') || (**ptr >= 'a' && **ptr <= 'z')) {
! 574: ++*ptr;
! 575: }
! 576: end = *ptr;
! 577: word = calloc(1, end - begin + 1);
! 578: memcpy(word, begin, end - begin);
! 579:
! 580: for (tp = timelib_reltext_lookup; tp->name; tp++) {
! 581: if (strcasecmp(word, tp->name) == 0) {
! 582: value = tp->value;
! 583: *behavior = tp->type;
! 584: }
! 585: }
! 586:
! 587: free(word);
! 588: return value;
! 589: }
! 590:
! 591: static timelib_sll timelib_get_relative_text(char **ptr, int *behavior)
! 592: {
! 593: while (**ptr == ' ' || **ptr == '\t' || **ptr == '-' || **ptr == '/') {
! 594: ++*ptr;
! 595: }
! 596: return timelib_lookup_relative_text(ptr, behavior);
! 597: }
! 598:
! 599: static long timelib_lookup_month(char **ptr)
! 600: {
! 601: char *word;
! 602: char *begin = *ptr, *end;
! 603: long value = 0;
! 604: const timelib_lookup_table *tp;
! 605:
! 606: while ((**ptr >= 'A' && **ptr <= 'Z') || (**ptr >= 'a' && **ptr <= 'z')) {
! 607: ++*ptr;
! 608: }
! 609: end = *ptr;
! 610: word = calloc(1, end - begin + 1);
! 611: memcpy(word, begin, end - begin);
! 612:
! 613: for (tp = timelib_month_lookup; tp->name; tp++) {
! 614: if (strcasecmp(word, tp->name) == 0) {
! 615: value = tp->value;
! 616: }
! 617: }
! 618:
! 619: free(word);
! 620: return value;
! 621: }
! 622:
! 623: static long timelib_get_month(char **ptr)
! 624: {
! 625: while (**ptr == ' ' || **ptr == '\t' || **ptr == '-' || **ptr == '.' || **ptr == '/') {
! 626: ++*ptr;
! 627: }
! 628: return timelib_lookup_month(ptr);
! 629: }
! 630:
! 631: static void timelib_eat_spaces(char **ptr)
! 632: {
! 633: while (**ptr == ' ' || **ptr == '\t') {
! 634: ++*ptr;
! 635: }
! 636: }
! 637:
! 638: static void timelib_eat_until_separator(char **ptr)
! 639: {
! 640: ++*ptr;
! 641: while (strchr(" \t.,:;/-0123456789", **ptr) == NULL) {
! 642: ++*ptr;
! 643: }
! 644: }
! 645:
! 646: static const timelib_relunit* timelib_lookup_relunit(char **ptr)
! 647: {
! 648: char *word;
! 649: char *begin = *ptr, *end;
! 650: const timelib_relunit *tp, *value = NULL;
! 651:
! 652: while (**ptr != '\0' && **ptr != ' ' && **ptr != ',' && **ptr != '\t') {
! 653: ++*ptr;
! 654: }
! 655: end = *ptr;
! 656: word = calloc(1, end - begin + 1);
! 657: memcpy(word, begin, end - begin);
! 658:
! 659: for (tp = timelib_relunit_lookup; tp->name; tp++) {
! 660: if (strcasecmp(word, tp->name) == 0) {
! 661: value = tp;
! 662: break;
! 663: }
! 664: }
! 665:
! 666: free(word);
! 667: return value;
! 668: }
! 669:
! 670: static void timelib_set_relative(char **ptr, timelib_sll amount, int behavior, Scanner *s)
! 671: {
! 672: const timelib_relunit* relunit;
! 673:
! 674: if (!(relunit = timelib_lookup_relunit(ptr))) {
! 675: return;
! 676: }
! 677:
! 678: switch (relunit->unit) {
! 679: case TIMELIB_SECOND: s->time->relative.s += amount * relunit->multiplier; break;
! 680: case TIMELIB_MINUTE: s->time->relative.i += amount * relunit->multiplier; break;
! 681: case TIMELIB_HOUR: s->time->relative.h += amount * relunit->multiplier; break;
! 682: case TIMELIB_DAY: s->time->relative.d += amount * relunit->multiplier; break;
! 683: case TIMELIB_MONTH: s->time->relative.m += amount * relunit->multiplier; break;
! 684: case TIMELIB_YEAR: s->time->relative.y += amount * relunit->multiplier; break;
! 685:
! 686: case TIMELIB_WEEKDAY:
! 687: TIMELIB_HAVE_WEEKDAY_RELATIVE();
! 688: TIMELIB_UNHAVE_TIME();
! 689: s->time->relative.d += (amount > 0 ? amount - 1 : amount) * 7;
! 690: s->time->relative.weekday = relunit->multiplier;
! 691: s->time->relative.weekday_behavior = behavior;
! 692: break;
! 693:
! 694: case TIMELIB_SPECIAL:
! 695: TIMELIB_HAVE_SPECIAL_RELATIVE();
! 696: TIMELIB_UNHAVE_TIME();
! 697: s->time->relative.special.type = relunit->multiplier;
! 698: s->time->relative.special.amount = amount;
! 699: }
! 700: }
! 701:
! 702: const static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffset, int isdst)
! 703: {
! 704: int first_found = 0;
! 705: const timelib_tz_lookup_table *tp, *first_found_elem = NULL;
! 706: const timelib_tz_lookup_table *fmp;
! 707:
! 708: if (strcasecmp("utc", word) == 0 || strcasecmp("gmt", word) == 0) {
! 709: return timelib_timezone_utc;
! 710: }
! 711:
! 712: for (tp = timelib_timezone_lookup; tp->name; tp++) {
! 713: if (strcasecmp(word, tp->name) == 0) {
! 714: if (!first_found) {
! 715: first_found = 1;
! 716: first_found_elem = tp;
! 717: if (gmtoffset == -1) {
! 718: return tp;
! 719: }
! 720: }
! 721: if (tp->gmtoffset == gmtoffset) {
! 722: return tp;
! 723: }
! 724: }
! 725: }
! 726: if (first_found) {
! 727: return first_found_elem;
! 728: }
! 729:
! 730: for (tp = timelib_timezone_lookup; tp->name; tp++) {
! 731: if (tp->full_tz_name && strcasecmp(word, tp->full_tz_name) == 0) {
! 732: if (!first_found) {
! 733: first_found = 1;
! 734: first_found_elem = tp;
! 735: if (gmtoffset == -1) {
! 736: return tp;
! 737: }
! 738: }
! 739: if (tp->gmtoffset == gmtoffset) {
! 740: return tp;
! 741: }
! 742: }
! 743: }
! 744: if (first_found) {
! 745: return first_found_elem;
! 746: }
! 747:
! 748:
! 749: /* Still didn't find anything, let's find the zone solely based on
! 750: * offset/isdst then */
! 751: for (fmp = timelib_timezone_fallbackmap; fmp->name; fmp++) {
! 752: if ((fmp->gmtoffset * 3600) == gmtoffset && fmp->type == isdst) {
! 753: return fmp;
! 754: }
! 755: }
! 756: return NULL;
! 757: }
! 758:
! 759: static long timelib_lookup_zone(char **ptr, int *dst, char **tz_abbr, int *found)
! 760: {
! 761: char *word;
! 762: char *begin = *ptr, *end;
! 763: long value = 0;
! 764: const timelib_tz_lookup_table *tp;
! 765:
! 766: while (**ptr != '\0' && **ptr != ')' && **ptr != ' ') {
! 767: ++*ptr;
! 768: }
! 769: end = *ptr;
! 770: word = calloc(1, end - begin + 1);
! 771: memcpy(word, begin, end - begin);
! 772:
! 773: if ((tp = zone_search(word, -1, 0))) {
! 774: value = -tp->gmtoffset / 60;
! 775: *dst = tp->type;
! 776: value += tp->type * 60;
! 777: *found = 1;
! 778: } else {
! 779: *found = 0;
! 780: }
! 781:
! 782: *tz_abbr = word;
! 783: return value;
! 784: }
! 785:
! 786: 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)
! 787: {
! 788: timelib_tzinfo *res;
! 789: long retval = 0;
! 790:
! 791: *tz_not_found = 0;
! 792:
! 793: while (**ptr == ' ' || **ptr == '\t' || **ptr == '(') {
! 794: ++*ptr;
! 795: }
! 796: if ((*ptr)[0] == 'G' && (*ptr)[1] == 'M' && (*ptr)[2] == 'T' && ((*ptr)[3] == '+' || (*ptr)[3] == '-')) {
! 797: *ptr += 3;
! 798: }
! 799: if (**ptr == '+') {
! 800: ++*ptr;
! 801: t->is_localtime = 1;
! 802: t->zone_type = TIMELIB_ZONETYPE_OFFSET;
! 803: *tz_not_found = 0;
! 804: t->dst = 0;
! 805:
! 806: retval = -1 * timelib_parse_tz_cor(ptr);
! 807: } else if (**ptr == '-') {
! 808: ++*ptr;
! 809: t->is_localtime = 1;
! 810: t->zone_type = TIMELIB_ZONETYPE_OFFSET;
! 811: *tz_not_found = 0;
! 812: t->dst = 0;
! 813:
! 814: retval = timelib_parse_tz_cor(ptr);
! 815: } else {
! 816: int found = 0;
! 817: long offset;
! 818: char *tz_abbr;
! 819:
! 820: t->is_localtime = 1;
! 821:
! 822: offset = timelib_lookup_zone(ptr, dst, &tz_abbr, &found);
! 823: if (found) {
! 824: t->zone_type = TIMELIB_ZONETYPE_ABBR;
! 825: }
! 826: #if 0
! 827: /* If we found a TimeZone identifier, use it */
! 828: if (tz_name) {
! 829: t->tz_info = timelib_parse_tzfile(tz_name);
! 830: t->zone_type = TIMELIB_ZONETYPE_ID;
! 831: }
! 832: #endif
! 833: /* If we have a TimeZone identifier to start with, use it */
! 834: if (strstr(tz_abbr, "/") || strcmp(tz_abbr, "UTC") == 0) {
! 835: if ((res = tz_wrapper(tz_abbr, tzdb)) != NULL) {
! 836: t->tz_info = res;
! 837: t->zone_type = TIMELIB_ZONETYPE_ID;
! 838: found++;
! 839: }
! 840: }
! 841: if (found && t->zone_type != TIMELIB_ZONETYPE_ID) {
! 842: timelib_time_tz_abbr_update(t, tz_abbr);
! 843: }
! 844: free(tz_abbr);
! 845: *tz_not_found = (found == 0);
! 846: retval = offset;
! 847: }
! 848: while (**ptr == ')') {
! 849: ++*ptr;
! 850: }
! 851: return retval;
! 852: }
! 853:
! 854: #define timelib_split_free(arg) { \
! 855: int i; \
! 856: for (i = 0; i < arg.c; i++) { \
! 857: free(arg.v[i]); \
! 858: } \
! 859: if (arg.v) { \
! 860: free(arg.v); \
! 861: } \
! 862: }
! 863:
! 864: static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper)
! 865: {
! 866: uchar *cursor = s->cur;
! 867: char *str, *ptr = NULL;
! 868:
! 869: std:
! 870: s->tok = cursor;
! 871: s->len = 0;
! 872: /*!re2c
! 873: any = [\000-\377];
! 874:
! 875: space = [ \t]+;
! 876: frac = "."[0-9]+;
! 877:
! 878: ago = 'ago';
! 879:
! 880: hour24 = [01]?[0-9] | "2"[0-4];
! 881: hour24lz = [01][0-9] | "2"[0-4];
! 882: hour12 = "0"?[1-9] | "1"[0-2];
! 883: minute = [0-5]?[0-9];
! 884: minutelz = [0-5][0-9];
! 885: second = minute | "60";
! 886: secondlz = minutelz | "60";
! 887: meridian = ([AaPp] "."? [Mm] "."?) [\000\t ];
! 888: tz = "("? [A-Za-z]{1,6} ")"? | [A-Z][a-z]+([_/-][A-Za-z]+)+;
! 889: tzcorrection = "GMT"? [+-] hour24 ":"? minute?;
! 890:
! 891: daysuf = "st" | "nd" | "rd" | "th";
! 892:
! 893: month = "0"? [0-9] | "1"[0-2];
! 894: day = (([0-2]?[0-9]) | ("3"[01])) daysuf?;
! 895: year = [0-9]{1,4};
! 896: year2 = [0-9]{2};
! 897: year4 = [0-9]{4};
! 898: year4withsign = [+-]? [0-9]{4};
! 899:
! 900: dayofyear = "00"[1-9] | "0"[1-9][0-9] | [1-2][0-9][0-9] | "3"[0-5][0-9] | "36"[0-6];
! 901: weekofyear = "0"[1-9] | [1-4][0-9] | "5"[0-3];
! 902:
! 903: monthlz = "0" [0-9] | "1" [0-2];
! 904: daylz = "0" [0-9] | [1-2][0-9] | "3" [01];
! 905:
! 906: dayfull = 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday';
! 907: dayabbr = 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun';
! 908: dayspecial = 'weekday' | 'weekdays';
! 909: daytext = dayfull | dayabbr | dayspecial;
! 910:
! 911: monthfull = 'january' | 'february' | 'march' | 'april' | 'may' | 'june' | 'july' | 'august' | 'september' | 'october' | 'november' | 'december';
! 912: monthabbr = 'jan' | 'feb' | 'mar' | 'apr' | 'may' | 'jun' | 'jul' | 'aug' | 'sep' | 'sept' | 'oct' | 'nov' | 'dec';
! 913: monthroman = "I" | "II" | "III" | "IV" | "V" | "VI" | "VII" | "VIII" | "IX" | "X" | "XI" | "XII";
! 914: monthtext = monthfull | monthabbr | monthroman;
! 915:
! 916: /* Time formats */
! 917: timetiny12 = hour12 space? meridian;
! 918: timeshort12 = hour12[:.]minutelz space? meridian;
! 919: timelong12 = hour12[:.]minute[:.]secondlz space? meridian;
! 920:
! 921: timeshort24 = 't'? hour24[:.]minute;
! 922: timelong24 = 't'? hour24[:.]minute[:.]second;
! 923: iso8601long = 't'? hour24 [:.] minute [:.] second frac;
! 924:
! 925: /* iso8601shorttz = hour24 [:] minutelz space? (tzcorrection | tz); */
! 926: iso8601normtz = 't'? hour24 [:.] minute [:.] secondlz space? (tzcorrection | tz);
! 927: /* iso8601longtz = hour24 [:] minute [:] secondlz frac space? (tzcorrection | tz); */
! 928:
! 929: gnunocolon = 't'? hour24lz minutelz;
! 930: /* gnunocolontz = hour24lz minutelz space? (tzcorrection | tz); */
! 931: iso8601nocolon = 't'? hour24lz minutelz secondlz;
! 932: /* iso8601nocolontz = hour24lz minutelz secondlz space? (tzcorrection | tz); */
! 933:
! 934: /* Date formats */
! 935: americanshort = month "/" day;
! 936: american = month "/" day "/" year;
! 937: iso8601dateslash = year4 "/" monthlz "/" daylz "/"?;
! 938: dateslash = year4 "/" month "/" day;
! 939: iso8601date4 = year4withsign "-" monthlz "-" daylz;
! 940: iso8601date2 = year2 "-" monthlz "-" daylz;
! 941: gnudateshorter = year4 "-" month;
! 942: gnudateshort = year "-" month "-" day;
! 943: pointeddate4 = day [.\t-] month [.-] year4;
! 944: pointeddate2 = day [.\t] month "." year2;
! 945: datefull = day ([ \t.-])* monthtext ([ \t.-])* year;
! 946: datenoday = monthtext ([ .\t-])* year4;
! 947: datenodayrev = year4 ([ .\t-])* monthtext;
! 948: datetextual = monthtext ([ .\t-])* day [,.stndrh\t ]+ year;
! 949: datenoyear = monthtext ([ .\t-])* day [,.stndrh\t ]*;
! 950: datenoyearrev = day ([ .\t-])* monthtext;
! 951: datenocolon = year4 monthlz daylz;
! 952:
! 953: /* Special formats */
! 954: soap = year4 "-" monthlz "-" daylz "T" hour24lz ":" minutelz ":" secondlz frac tzcorrection?;
! 955: xmlrpc = year4 monthlz daylz "T" hour24 ":" minutelz ":" secondlz;
! 956: xmlrpcnocolon = year4 monthlz daylz 't' hour24 minutelz secondlz;
! 957: wddx = year4 "-" month "-" day "T" hour24 ":" minute ":" second;
! 958: pgydotd = year4 "."? dayofyear;
! 959: pgtextshort = monthabbr "-" daylz "-" year;
! 960: pgtextreverse = year "-" monthabbr "-" daylz;
! 961: mssqltime = hour12 ":" minutelz ":" secondlz [:.] [0-9]+ meridian;
! 962: isoweekday = year4 "-"? "W" weekofyear "-"? [0-7];
! 963: isoweek = year4 "-"? "W" weekofyear;
! 964: exif = year4 ":" monthlz ":" daylz " " hour24lz ":" minutelz ":" secondlz;
! 965: firstdayof = 'first day of'?;
! 966: lastdayof = 'last day of'?;
! 967: backof = 'back of ' hour24 space? meridian?;
! 968: frontof = 'front of ' hour24 space? meridian?;
! 969:
! 970: /* Common Log Format: 10/Oct/2000:13:55:36 -0700 */
! 971: clf = day "/" monthabbr "/" year4 ":" hour24lz ":" minutelz ":" secondlz space tzcorrection;
! 972:
! 973: /* Timestamp format: @1126396800 */
! 974: timestamp = "@" "-"? [0-9]+;
! 975:
! 976: /* To fix some ambiguities */
! 977: dateshortwithtimeshort12 = datenoyear timeshort12;
! 978: dateshortwithtimelong12 = datenoyear timelong12;
! 979: dateshortwithtimeshort = datenoyear timeshort24;
! 980: dateshortwithtimelong = datenoyear timelong24;
! 981: dateshortwithtimelongtz = datenoyear iso8601normtz;
! 982:
! 983: /*
! 984: * Relative regexps
! 985: */
! 986: reltextnumber = 'first'|'second'|'third'|'fourth'|'fifth'|'sixth'|'seventh'|'eight'|'eighth'|'ninth'|'tenth'|'eleventh'|'twelfth';
! 987: reltexttext = 'next'|'last'|'previous'|'this';
! 988: reltextunit = (('sec'|'second'|'min'|'minute'|'hour'|'day'|'fortnight'|'forthnight'|'month'|'year') 's'?) | 'weeks' | daytext;
! 989:
! 990: relnumber = ([+-]*[ \t]*[0-9]+);
! 991: relative = relnumber space? (reltextunit | 'week' );
! 992: relativetext = (reltextnumber|reltexttext) space reltextunit;
! 993: relativetextweek = reltexttext space 'week';
! 994:
! 995: weekdayof = (reltextnumber|reltexttext) space (dayfull|dayabbr) space 'of';
! 996:
! 997: */
! 998:
! 999: /*!re2c
! 1000: /* so that vim highlights correctly */
! 1001: 'yesterday'
! 1002: {
! 1003: DEBUG_OUTPUT("yesterday");
! 1004: TIMELIB_INIT;
! 1005: TIMELIB_HAVE_RELATIVE();
! 1006: TIMELIB_UNHAVE_TIME();
! 1007:
! 1008: s->time->relative.d = -1;
! 1009: TIMELIB_DEINIT;
! 1010: return TIMELIB_RELATIVE;
! 1011: }
! 1012:
! 1013: 'now'
! 1014: {
! 1015: DEBUG_OUTPUT("now");
! 1016: TIMELIB_INIT;
! 1017:
! 1018: TIMELIB_DEINIT;
! 1019: return TIMELIB_RELATIVE;
! 1020: }
! 1021:
! 1022: 'noon'
! 1023: {
! 1024: DEBUG_OUTPUT("noon");
! 1025: TIMELIB_INIT;
! 1026: TIMELIB_UNHAVE_TIME();
! 1027: TIMELIB_HAVE_TIME();
! 1028: s->time->h = 12;
! 1029:
! 1030: TIMELIB_DEINIT;
! 1031: return TIMELIB_RELATIVE;
! 1032: }
! 1033:
! 1034: 'midnight' | 'today'
! 1035: {
! 1036: DEBUG_OUTPUT("midnight | today");
! 1037: TIMELIB_INIT;
! 1038: TIMELIB_UNHAVE_TIME();
! 1039:
! 1040: TIMELIB_DEINIT;
! 1041: return TIMELIB_RELATIVE;
! 1042: }
! 1043:
! 1044: 'tomorrow'
! 1045: {
! 1046: DEBUG_OUTPUT("tomorrow");
! 1047: TIMELIB_INIT;
! 1048: TIMELIB_HAVE_RELATIVE();
! 1049: TIMELIB_UNHAVE_TIME();
! 1050:
! 1051: s->time->relative.d = 1;
! 1052: TIMELIB_DEINIT;
! 1053: return TIMELIB_RELATIVE;
! 1054: }
! 1055:
! 1056: timestamp
! 1057: {
! 1058: timelib_ull i;
! 1059:
! 1060: TIMELIB_INIT;
! 1061: TIMELIB_HAVE_RELATIVE();
! 1062: TIMELIB_UNHAVE_DATE();
! 1063: TIMELIB_UNHAVE_TIME();
! 1064: TIMELIB_HAVE_TZ();
! 1065:
! 1066: i = timelib_get_unsigned_nr((char **) &ptr, 24);
! 1067: s->time->y = 1970;
! 1068: s->time->m = 1;
! 1069: s->time->d = 1;
! 1070: s->time->h = s->time->i = s->time->s = 0;
! 1071: s->time->f = 0.0;
! 1072: s->time->relative.s += i;
! 1073: s->time->is_localtime = 1;
! 1074: s->time->zone_type = TIMELIB_ZONETYPE_OFFSET;
! 1075: s->time->z = 0;
! 1076:
! 1077: TIMELIB_DEINIT;
! 1078: return TIMELIB_RELATIVE;
! 1079: }
! 1080:
! 1081: firstdayof | lastdayof
! 1082: {
! 1083: DEBUG_OUTPUT("firstdayof | lastdayof");
! 1084: TIMELIB_INIT;
! 1085: TIMELIB_HAVE_RELATIVE();
! 1086:
! 1087: /* skip "last day of" or "first day of" */
! 1088: if (*ptr == 'l') {
! 1089: s->time->relative.first_last_day_of = 2;
! 1090: } else {
! 1091: s->time->relative.first_last_day_of = 1;
! 1092: }
! 1093:
! 1094: TIMELIB_DEINIT;
! 1095: return TIMELIB_LF_DAY_OF_MONTH;
! 1096: }
! 1097:
! 1098: backof | frontof
! 1099: {
! 1100: DEBUG_OUTPUT("backof | frontof");
! 1101: TIMELIB_INIT;
! 1102: TIMELIB_UNHAVE_TIME();
! 1103: TIMELIB_HAVE_TIME();
! 1104:
! 1105: if (*ptr == 'b') {
! 1106: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1107: s->time->i = 15;
! 1108: } else {
! 1109: s->time->h = timelib_get_nr((char **) &ptr, 2) - 1;
! 1110: s->time->i = 45;
! 1111: }
! 1112: if (*ptr != '\0' ) {
! 1113: timelib_eat_spaces((char **) &ptr);
! 1114: s->time->h += timelib_meridian((char **) &ptr, s->time->h);
! 1115: }
! 1116:
! 1117: TIMELIB_DEINIT;
! 1118: return TIMELIB_LF_DAY_OF_MONTH;
! 1119: }
! 1120:
! 1121: weekdayof
! 1122: {
! 1123: timelib_sll i;
! 1124: int behavior = 0;
! 1125: DEBUG_OUTPUT("weekdayof");
! 1126: TIMELIB_INIT;
! 1127: TIMELIB_HAVE_RELATIVE();
! 1128: TIMELIB_HAVE_SPECIAL_RELATIVE();
! 1129:
! 1130: i = timelib_get_relative_text((char **) &ptr, &behavior);
! 1131: timelib_eat_spaces((char **) &ptr);
! 1132: if (i > 0) { /* first, second... etc */
! 1133: s->time->relative.special.type = TIMELIB_SPECIAL_DAY_OF_WEEK_IN_MONTH;
! 1134: timelib_set_relative((char **) &ptr, i, 1, s);
! 1135: } else { /* last */
! 1136: s->time->relative.special.type = TIMELIB_SPECIAL_LAST_DAY_OF_WEEK_IN_MONTH;
! 1137: timelib_set_relative((char **) &ptr, i, behavior, s);
! 1138: }
! 1139: TIMELIB_DEINIT;
! 1140: return TIMELIB_WEEK_DAY_OF_MONTH;
! 1141: }
! 1142:
! 1143: timetiny12 | timeshort12 | timelong12
! 1144: {
! 1145: DEBUG_OUTPUT("timetiny12 | timeshort12 | timelong12");
! 1146: TIMELIB_INIT;
! 1147: TIMELIB_HAVE_TIME();
! 1148: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1149: if (*ptr == ':' || *ptr == '.') {
! 1150: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1151: if (*ptr == ':' || *ptr == '.') {
! 1152: s->time->s = timelib_get_nr((char **) &ptr, 2);
! 1153: }
! 1154: }
! 1155: s->time->h += timelib_meridian((char **) &ptr, s->time->h);
! 1156: TIMELIB_DEINIT;
! 1157: return TIMELIB_TIME12;
! 1158: }
! 1159:
! 1160: mssqltime
! 1161: {
! 1162: DEBUG_OUTPUT("mssqltime");
! 1163: TIMELIB_INIT;
! 1164: TIMELIB_HAVE_TIME();
! 1165: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1166: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1167: if (*ptr == ':' || *ptr == '.') {
! 1168: s->time->s = timelib_get_nr((char **) &ptr, 2);
! 1169:
! 1170: if (*ptr == ':' || *ptr == '.') {
! 1171: s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
! 1172: }
! 1173: }
! 1174: timelib_eat_spaces((char **) &ptr);
! 1175: s->time->h += timelib_meridian((char **) &ptr, s->time->h);
! 1176: TIMELIB_DEINIT;
! 1177: return TIMELIB_TIME24_WITH_ZONE;
! 1178: }
! 1179:
! 1180: timeshort24 | timelong24 /* | iso8601short | iso8601norm */ | iso8601long /*| iso8601shorttz | iso8601normtz | iso8601longtz*/
! 1181: {
! 1182: int tz_not_found;
! 1183: DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long");
! 1184: TIMELIB_INIT;
! 1185: TIMELIB_HAVE_TIME();
! 1186: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1187: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1188: if (*ptr == ':' || *ptr == '.') {
! 1189: s->time->s = timelib_get_nr((char **) &ptr, 2);
! 1190:
! 1191: if (*ptr == '.') {
! 1192: s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
! 1193: }
! 1194: }
! 1195:
! 1196: if (*ptr != '\0') {
! 1197: s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
! 1198: if (tz_not_found) {
! 1199: add_error(s, "The timezone could not be found in the database");
! 1200: }
! 1201: }
! 1202: TIMELIB_DEINIT;
! 1203: return TIMELIB_TIME24_WITH_ZONE;
! 1204: }
! 1205:
! 1206: gnunocolon
! 1207: {
! 1208: DEBUG_OUTPUT("gnunocolon");
! 1209: TIMELIB_INIT;
! 1210: switch (s->time->have_time) {
! 1211: case 0:
! 1212: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1213: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1214: s->time->s = 0;
! 1215: break;
! 1216: case 1:
! 1217: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1218: break;
! 1219: default:
! 1220: TIMELIB_DEINIT;
! 1221: add_error(s, "Double time specification");
! 1222: return TIMELIB_ERROR;
! 1223: }
! 1224: s->time->have_time++;
! 1225: TIMELIB_DEINIT;
! 1226: return TIMELIB_GNU_NOCOLON;
! 1227: }
! 1228: /*
! 1229: gnunocolontz
! 1230: {
! 1231: DEBUG_OUTPUT("gnunocolontz");
! 1232: TIMELIB_INIT;
! 1233: switch (s->time->have_time) {
! 1234: case 0:
! 1235: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1236: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1237: s->time->s = 0;
! 1238: s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, s->tzdb, tz_get_wrapper);
! 1239: break;
! 1240: case 1:
! 1241: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1242: break;
! 1243: default:
! 1244: TIMELIB_DEINIT;
! 1245: return TIMELIB_ERROR;
! 1246: }
! 1247: s->time->have_time++;
! 1248: TIMELIB_DEINIT;
! 1249: return TIMELIB_GNU_NOCOLON_TZ;
! 1250: }
! 1251: */
! 1252: iso8601nocolon /*| iso8601nocolontz*/
! 1253: {
! 1254: int tz_not_found;
! 1255: DEBUG_OUTPUT("iso8601nocolon");
! 1256: TIMELIB_INIT;
! 1257: TIMELIB_HAVE_TIME();
! 1258: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1259: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1260: s->time->s = timelib_get_nr((char **) &ptr, 2);
! 1261:
! 1262: if (*ptr != '\0') {
! 1263: s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
! 1264: if (tz_not_found) {
! 1265: add_error(s, "The timezone could not be found in the database");
! 1266: }
! 1267: }
! 1268: TIMELIB_DEINIT;
! 1269: return TIMELIB_ISO_NOCOLON;
! 1270: }
! 1271:
! 1272: americanshort | american
! 1273: {
! 1274: int length = 0;
! 1275: DEBUG_OUTPUT("americanshort | american");
! 1276: TIMELIB_INIT;
! 1277: TIMELIB_HAVE_DATE();
! 1278: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1279: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1280: if (*ptr == '/') {
! 1281: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1282: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1283: }
! 1284: TIMELIB_DEINIT;
! 1285: return TIMELIB_AMERICAN;
! 1286: }
! 1287:
! 1288: iso8601date4 | iso8601dateslash | dateslash
! 1289: {
! 1290: DEBUG_OUTPUT("iso8601date4 | iso8601date2 | iso8601dateslash | dateslash");
! 1291: TIMELIB_INIT;
! 1292: TIMELIB_HAVE_DATE();
! 1293: s->time->y = timelib_get_unsigned_nr((char **) &ptr, 4);
! 1294: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1295: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1296: TIMELIB_DEINIT;
! 1297: return TIMELIB_ISO_DATE;
! 1298: }
! 1299:
! 1300: iso8601date2
! 1301: {
! 1302: int length = 0;
! 1303: DEBUG_OUTPUT("iso8601date2");
! 1304: TIMELIB_INIT;
! 1305: TIMELIB_HAVE_DATE();
! 1306: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1307: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1308: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1309: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1310: TIMELIB_DEINIT;
! 1311: return TIMELIB_ISO_DATE;
! 1312: }
! 1313:
! 1314: gnudateshorter
! 1315: {
! 1316: int length = 0;
! 1317: DEBUG_OUTPUT("gnudateshorter");
! 1318: TIMELIB_INIT;
! 1319: TIMELIB_HAVE_DATE();
! 1320: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1321: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1322: s->time->d = 1;
! 1323: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1324: TIMELIB_DEINIT;
! 1325: return TIMELIB_ISO_DATE;
! 1326: }
! 1327:
! 1328: gnudateshort
! 1329: {
! 1330: int length = 0;
! 1331: DEBUG_OUTPUT("gnudateshort");
! 1332: TIMELIB_INIT;
! 1333: TIMELIB_HAVE_DATE();
! 1334: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1335: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1336: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1337: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1338: TIMELIB_DEINIT;
! 1339: return TIMELIB_ISO_DATE;
! 1340: }
! 1341:
! 1342: datefull
! 1343: {
! 1344: int length = 0;
! 1345: DEBUG_OUTPUT("datefull");
! 1346: TIMELIB_INIT;
! 1347: TIMELIB_HAVE_DATE();
! 1348: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1349: timelib_skip_day_suffix((char **) &ptr);
! 1350: s->time->m = timelib_get_month((char **) &ptr);
! 1351: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1352: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1353: TIMELIB_DEINIT;
! 1354: return TIMELIB_DATE_FULL;
! 1355: }
! 1356:
! 1357: pointeddate4
! 1358: {
! 1359: DEBUG_OUTPUT("pointed date YYYY");
! 1360: TIMELIB_INIT;
! 1361: TIMELIB_HAVE_DATE();
! 1362: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1363: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1364: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1365: TIMELIB_DEINIT;
! 1366: return TIMELIB_DATE_FULL_POINTED;
! 1367: }
! 1368:
! 1369: pointeddate2
! 1370: {
! 1371: int length = 0;
! 1372: DEBUG_OUTPUT("pointed date YY");
! 1373: TIMELIB_INIT;
! 1374: TIMELIB_HAVE_DATE();
! 1375: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1376: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1377: s->time->y = timelib_get_nr_ex((char **) &ptr, 2, &length);
! 1378: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1379: TIMELIB_DEINIT;
! 1380: return TIMELIB_DATE_FULL_POINTED;
! 1381: }
! 1382:
! 1383: datenoday
! 1384: {
! 1385: int length = 0;
! 1386: DEBUG_OUTPUT("datenoday");
! 1387: TIMELIB_INIT;
! 1388: TIMELIB_HAVE_DATE();
! 1389: s->time->m = timelib_get_month((char **) &ptr);
! 1390: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1391: s->time->d = 1;
! 1392: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1393: TIMELIB_DEINIT;
! 1394: return TIMELIB_DATE_NO_DAY;
! 1395: }
! 1396:
! 1397: datenodayrev
! 1398: {
! 1399: int length = 0;
! 1400: DEBUG_OUTPUT("datenodayrev");
! 1401: TIMELIB_INIT;
! 1402: TIMELIB_HAVE_DATE();
! 1403: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1404: s->time->m = timelib_get_month((char **) &ptr);
! 1405: s->time->d = 1;
! 1406: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1407: TIMELIB_DEINIT;
! 1408: return TIMELIB_DATE_NO_DAY;
! 1409: }
! 1410:
! 1411: datetextual | datenoyear
! 1412: {
! 1413: int length = 0;
! 1414: DEBUG_OUTPUT("datetextual | datenoyear");
! 1415: TIMELIB_INIT;
! 1416: TIMELIB_HAVE_DATE();
! 1417: s->time->m = timelib_get_month((char **) &ptr);
! 1418: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1419: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1420: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1421: TIMELIB_DEINIT;
! 1422: return TIMELIB_DATE_TEXT;
! 1423: }
! 1424:
! 1425: datenoyearrev
! 1426: {
! 1427: DEBUG_OUTPUT("datenoyearrev");
! 1428: TIMELIB_INIT;
! 1429: TIMELIB_HAVE_DATE();
! 1430: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1431: timelib_skip_day_suffix((char **) &ptr);
! 1432: s->time->m = timelib_get_month((char **) &ptr);
! 1433: TIMELIB_DEINIT;
! 1434: return TIMELIB_DATE_TEXT;
! 1435: }
! 1436:
! 1437: datenocolon
! 1438: {
! 1439: DEBUG_OUTPUT("datenocolon");
! 1440: TIMELIB_INIT;
! 1441: TIMELIB_HAVE_DATE();
! 1442: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1443: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1444: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1445: TIMELIB_DEINIT;
! 1446: return TIMELIB_DATE_NOCOLON;
! 1447: }
! 1448:
! 1449: xmlrpc | xmlrpcnocolon | soap | wddx | exif
! 1450: {
! 1451: int tz_not_found;
! 1452: DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx | exif");
! 1453: TIMELIB_INIT;
! 1454: TIMELIB_HAVE_TIME();
! 1455: TIMELIB_HAVE_DATE();
! 1456: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1457: s->time->m = timelib_get_nr((char **) &ptr, 2);
! 1458: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1459: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1460: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1461: s->time->s = timelib_get_nr((char **) &ptr, 2);
! 1462: if (*ptr == '.') {
! 1463: s->time->f = timelib_get_frac_nr((char **) &ptr, 9);
! 1464: if (*ptr) { /* timezone is optional */
! 1465: s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
! 1466: if (tz_not_found) {
! 1467: add_error(s, "The timezone could not be found in the database");
! 1468: }
! 1469: }
! 1470: }
! 1471: TIMELIB_DEINIT;
! 1472: return TIMELIB_XMLRPC_SOAP;
! 1473: }
! 1474:
! 1475: pgydotd
! 1476: {
! 1477: int length = 0;
! 1478: DEBUG_OUTPUT("pgydotd");
! 1479: TIMELIB_INIT;
! 1480: TIMELIB_HAVE_DATE();
! 1481: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1482: s->time->d = timelib_get_nr((char **) &ptr, 3);
! 1483: s->time->m = 1;
! 1484: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1485: TIMELIB_DEINIT;
! 1486: return TIMELIB_PG_YEARDAY;
! 1487: }
! 1488:
! 1489: isoweekday
! 1490: {
! 1491: timelib_sll w, d;
! 1492: DEBUG_OUTPUT("isoweekday");
! 1493: TIMELIB_INIT;
! 1494: TIMELIB_HAVE_DATE();
! 1495: TIMELIB_HAVE_RELATIVE();
! 1496:
! 1497: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1498: w = timelib_get_nr((char **) &ptr, 2);
! 1499: d = timelib_get_nr((char **) &ptr, 1);
! 1500: s->time->m = 1;
! 1501: s->time->d = 1;
! 1502: s->time->relative.d = timelib_daynr_from_weeknr(s->time->y, w, d);
! 1503:
! 1504: TIMELIB_DEINIT;
! 1505: return TIMELIB_ISO_WEEK;
! 1506: }
! 1507:
! 1508: isoweek
! 1509: {
! 1510: timelib_sll w, d;
! 1511: DEBUG_OUTPUT("isoweek");
! 1512: TIMELIB_INIT;
! 1513: TIMELIB_HAVE_DATE();
! 1514: TIMELIB_HAVE_RELATIVE();
! 1515:
! 1516: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1517: w = timelib_get_nr((char **) &ptr, 2);
! 1518: d = 1;
! 1519: s->time->m = 1;
! 1520: s->time->d = 1;
! 1521: s->time->relative.d = timelib_daynr_from_weeknr(s->time->y, w, d);
! 1522:
! 1523: TIMELIB_DEINIT;
! 1524: return TIMELIB_ISO_WEEK;
! 1525: }
! 1526:
! 1527: pgtextshort
! 1528: {
! 1529: int length = 0;
! 1530: DEBUG_OUTPUT("pgtextshort");
! 1531: TIMELIB_INIT;
! 1532: TIMELIB_HAVE_DATE();
! 1533: s->time->m = timelib_get_month((char **) &ptr);
! 1534: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1535: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1536: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1537: TIMELIB_DEINIT;
! 1538: return TIMELIB_PG_TEXT;
! 1539: }
! 1540:
! 1541: pgtextreverse
! 1542: {
! 1543: int length = 0;
! 1544: DEBUG_OUTPUT("pgtextreverse");
! 1545: TIMELIB_INIT;
! 1546: TIMELIB_HAVE_DATE();
! 1547: s->time->y = timelib_get_nr_ex((char **) &ptr, 4, &length);
! 1548: s->time->m = timelib_get_month((char **) &ptr);
! 1549: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1550: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1551: TIMELIB_DEINIT;
! 1552: return TIMELIB_PG_TEXT;
! 1553: }
! 1554:
! 1555: clf
! 1556: {
! 1557: int tz_not_found;
! 1558: DEBUG_OUTPUT("clf");
! 1559: TIMELIB_INIT;
! 1560: TIMELIB_HAVE_TIME();
! 1561: TIMELIB_HAVE_DATE();
! 1562: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1563: s->time->m = timelib_get_month((char **) &ptr);
! 1564: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1565: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1566: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1567: s->time->s = timelib_get_nr((char **) &ptr, 2);
! 1568: s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
! 1569: if (tz_not_found) {
! 1570: add_error(s, "The timezone could not be found in the database");
! 1571: }
! 1572: TIMELIB_DEINIT;
! 1573: return TIMELIB_CLF;
! 1574: }
! 1575:
! 1576: year4
! 1577: {
! 1578: DEBUG_OUTPUT("year4");
! 1579: TIMELIB_INIT;
! 1580: s->time->y = timelib_get_nr((char **) &ptr, 4);
! 1581: TIMELIB_DEINIT;
! 1582: return TIMELIB_CLF;
! 1583: }
! 1584:
! 1585: ago
! 1586: {
! 1587: DEBUG_OUTPUT("ago");
! 1588: TIMELIB_INIT;
! 1589: s->time->relative.y = 0 - s->time->relative.y;
! 1590: s->time->relative.m = 0 - s->time->relative.m;
! 1591: s->time->relative.d = 0 - s->time->relative.d;
! 1592: s->time->relative.h = 0 - s->time->relative.h;
! 1593: s->time->relative.i = 0 - s->time->relative.i;
! 1594: s->time->relative.s = 0 - s->time->relative.s;
! 1595: s->time->relative.weekday = 0 - s->time->relative.weekday;
! 1596: if (s->time->relative.weekday == 0) {
! 1597: s->time->relative.weekday = -7;
! 1598: }
! 1599: if (s->time->relative.have_special_relative && s->time->relative.special.type == TIMELIB_SPECIAL_WEEKDAY) {
! 1600: s->time->relative.special.amount = 0 - s->time->relative.special.amount;
! 1601: }
! 1602: TIMELIB_DEINIT;
! 1603: return TIMELIB_AGO;
! 1604: }
! 1605:
! 1606: daytext
! 1607: {
! 1608: const timelib_relunit* relunit;
! 1609: DEBUG_OUTPUT("daytext");
! 1610: TIMELIB_INIT;
! 1611: TIMELIB_HAVE_RELATIVE();
! 1612: TIMELIB_HAVE_WEEKDAY_RELATIVE();
! 1613: TIMELIB_UNHAVE_TIME();
! 1614: relunit = timelib_lookup_relunit((char**) &ptr);
! 1615: s->time->relative.weekday = relunit->multiplier;
! 1616: if (s->time->relative.weekday_behavior != 2) {
! 1617: s->time->relative.weekday_behavior = 1;
! 1618: }
! 1619:
! 1620: TIMELIB_DEINIT;
! 1621: return TIMELIB_WEEKDAY;
! 1622: }
! 1623:
! 1624: relativetextweek
! 1625: {
! 1626: timelib_sll i;
! 1627: int behavior = 0;
! 1628: DEBUG_OUTPUT("relativetextweek");
! 1629: TIMELIB_INIT;
! 1630: TIMELIB_HAVE_RELATIVE();
! 1631:
! 1632: while(*ptr) {
! 1633: i = timelib_get_relative_text((char **) &ptr, &behavior);
! 1634: timelib_eat_spaces((char **) &ptr);
! 1635: timelib_set_relative((char **) &ptr, i, behavior, s);
! 1636: s->time->relative.weekday_behavior = 2;
! 1637:
! 1638: /* to handle the format weekday + last/this/next week */
! 1639: if (s->time->relative.have_weekday_relative == 0) {
! 1640: TIMELIB_HAVE_WEEKDAY_RELATIVE();
! 1641: s->time->relative.weekday = 1;
! 1642: }
! 1643: }
! 1644: TIMELIB_DEINIT;
! 1645: return TIMELIB_RELATIVE;
! 1646: }
! 1647:
! 1648: relativetext
! 1649: {
! 1650: timelib_sll i;
! 1651: int behavior = 0;
! 1652: DEBUG_OUTPUT("relativetext");
! 1653: TIMELIB_INIT;
! 1654: TIMELIB_HAVE_RELATIVE();
! 1655:
! 1656: while(*ptr) {
! 1657: i = timelib_get_relative_text((char **) &ptr, &behavior);
! 1658: timelib_eat_spaces((char **) &ptr);
! 1659: timelib_set_relative((char **) &ptr, i, behavior, s);
! 1660: }
! 1661: TIMELIB_DEINIT;
! 1662: return TIMELIB_RELATIVE;
! 1663: }
! 1664:
! 1665: monthfull | monthabbr
! 1666: {
! 1667: DEBUG_OUTPUT("monthtext");
! 1668: TIMELIB_INIT;
! 1669: TIMELIB_HAVE_DATE();
! 1670: s->time->m = timelib_lookup_month((char **) &ptr);
! 1671: TIMELIB_DEINIT;
! 1672: return TIMELIB_DATE_TEXT;
! 1673: }
! 1674:
! 1675: tzcorrection | tz
! 1676: {
! 1677: int tz_not_found;
! 1678: DEBUG_OUTPUT("tzcorrection | tz");
! 1679: TIMELIB_INIT;
! 1680: TIMELIB_HAVE_TZ();
! 1681: s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
! 1682: if (tz_not_found) {
! 1683: add_error(s, "The timezone could not be found in the database");
! 1684: }
! 1685: TIMELIB_DEINIT;
! 1686: return TIMELIB_TIMEZONE;
! 1687: }
! 1688:
! 1689: dateshortwithtimeshort12 | dateshortwithtimelong12
! 1690: {
! 1691: DEBUG_OUTPUT("dateshortwithtimeshort12 | dateshortwithtimelong12");
! 1692: TIMELIB_INIT;
! 1693: TIMELIB_HAVE_DATE();
! 1694: s->time->m = timelib_get_month((char **) &ptr);
! 1695: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1696:
! 1697: TIMELIB_HAVE_TIME();
! 1698: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1699: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1700: if (*ptr == ':' || *ptr == '.') {
! 1701: s->time->s = timelib_get_nr((char **) &ptr, 2);
! 1702:
! 1703: if (*ptr == '.') {
! 1704: s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
! 1705: }
! 1706: }
! 1707:
! 1708: s->time->h += timelib_meridian((char **) &ptr, s->time->h);
! 1709: TIMELIB_DEINIT;
! 1710: return TIMELIB_SHORTDATE_WITH_TIME;
! 1711: }
! 1712:
! 1713: dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz
! 1714: {
! 1715: int tz_not_found;
! 1716: DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz");
! 1717: TIMELIB_INIT;
! 1718: TIMELIB_HAVE_DATE();
! 1719: s->time->m = timelib_get_month((char **) &ptr);
! 1720: s->time->d = timelib_get_nr((char **) &ptr, 2);
! 1721:
! 1722: TIMELIB_HAVE_TIME();
! 1723: s->time->h = timelib_get_nr((char **) &ptr, 2);
! 1724: s->time->i = timelib_get_nr((char **) &ptr, 2);
! 1725: if (*ptr == ':') {
! 1726: s->time->s = timelib_get_nr((char **) &ptr, 2);
! 1727:
! 1728: if (*ptr == '.') {
! 1729: s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
! 1730: }
! 1731: }
! 1732:
! 1733: if (*ptr != '\0') {
! 1734: s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
! 1735: if (tz_not_found) {
! 1736: add_error(s, "The timezone could not be found in the database");
! 1737: }
! 1738: }
! 1739: TIMELIB_DEINIT;
! 1740: return TIMELIB_SHORTDATE_WITH_TIME;
! 1741: }
! 1742:
! 1743: relative
! 1744: {
! 1745: timelib_ull i;
! 1746: DEBUG_OUTPUT("relative");
! 1747: TIMELIB_INIT;
! 1748: TIMELIB_HAVE_RELATIVE();
! 1749:
! 1750: while(*ptr) {
! 1751: i = timelib_get_unsigned_nr((char **) &ptr, 24);
! 1752: timelib_eat_spaces((char **) &ptr);
! 1753: timelib_set_relative((char **) &ptr, i, 1, s);
! 1754: }
! 1755: TIMELIB_DEINIT;
! 1756: return TIMELIB_RELATIVE;
! 1757: }
! 1758:
! 1759: [ .,\t]
! 1760: {
! 1761: goto std;
! 1762: }
! 1763:
! 1764: "\000"|"\n"
! 1765: {
! 1766: s->pos = cursor; s->line++;
! 1767: goto std;
! 1768: }
! 1769:
! 1770: any
! 1771: {
! 1772: add_error(s, "Unexpected character");
! 1773: goto std;
! 1774: }
! 1775: */
! 1776: }
! 1777:
! 1778: /*!max:re2c */
! 1779:
! 1780: timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper)
! 1781: {
! 1782: Scanner in;
! 1783: int t;
! 1784: char *e = s + len - 1;
! 1785:
! 1786: memset(&in, 0, sizeof(in));
! 1787: in.errors = malloc(sizeof(struct timelib_error_container));
! 1788: in.errors->warning_count = 0;
! 1789: in.errors->warning_messages = NULL;
! 1790: in.errors->error_count = 0;
! 1791: in.errors->error_messages = NULL;
! 1792:
! 1793: if (len > 0) {
! 1794: while (isspace(*s) && s < e) {
! 1795: s++;
! 1796: }
! 1797: while (isspace(*e) && e > s) {
! 1798: e--;
! 1799: }
! 1800: }
! 1801: if (e - s < 0) {
! 1802: in.time = timelib_time_ctor();
! 1803: add_error(&in, "Empty string");
! 1804: if (errors) {
! 1805: *errors = in.errors;
! 1806: } else {
! 1807: timelib_error_container_dtor(in.errors);
! 1808: }
! 1809: in.time->y = in.time->d = in.time->m = in.time->h = in.time->i = in.time->s = in.time->f = in.time->dst = in.time->z = TIMELIB_UNSET;
! 1810: in.time->is_localtime = in.time->zone_type = 0;
! 1811: return in.time;
! 1812: }
! 1813: e++;
! 1814:
! 1815: in.str = malloc((e - s) + YYMAXFILL);
! 1816: memset(in.str, 0, (e - s) + YYMAXFILL);
! 1817: memcpy(in.str, s, (e - s));
! 1818: in.lim = in.str + (e - s) + YYMAXFILL;
! 1819: in.cur = in.str;
! 1820: in.time = timelib_time_ctor();
! 1821: in.time->y = TIMELIB_UNSET;
! 1822: in.time->d = TIMELIB_UNSET;
! 1823: in.time->m = TIMELIB_UNSET;
! 1824: in.time->h = TIMELIB_UNSET;
! 1825: in.time->i = TIMELIB_UNSET;
! 1826: in.time->s = TIMELIB_UNSET;
! 1827: in.time->f = TIMELIB_UNSET;
! 1828: in.time->z = TIMELIB_UNSET;
! 1829: in.time->dst = TIMELIB_UNSET;
! 1830: in.tzdb = tzdb;
! 1831: in.time->is_localtime = 0;
! 1832: in.time->zone_type = 0;
! 1833:
! 1834: do {
! 1835: t = scan(&in, tz_get_wrapper);
! 1836: #ifdef DEBUG_PARSER
! 1837: printf("%d\n", t);
! 1838: #endif
! 1839: } while(t != EOI);
! 1840:
! 1841: /* do funky checking whether the parsed time was valid time */
! 1842: if (in.time->have_time && !timelib_valid_time( in.time->h, in.time->i, in.time->s)) {
! 1843: add_warning(&in, "The parsed time was invalid");
! 1844: }
! 1845: /* do funky checking whether the parsed date was valid date */
! 1846: if (in.time->have_date && !timelib_valid_date( in.time->y, in.time->m, in.time->d)) {
! 1847: add_warning(&in, "The parsed date was invalid");
! 1848: }
! 1849:
! 1850: free(in.str);
! 1851: if (errors) {
! 1852: *errors = in.errors;
! 1853: } else {
! 1854: timelib_error_container_dtor(in.errors);
! 1855: }
! 1856: return in.time;
! 1857: }
! 1858:
! 1859: #define TIMELIB_CHECK_NUMBER \
! 1860: if (strchr("0123456789", *ptr) == NULL) \
! 1861: { \
! 1862: add_pbf_error(s, "Unexpected data found.", string, begin); \
! 1863: }
! 1864:
! 1865: static void timelib_time_reset_fields(timelib_time *time)
! 1866: {
! 1867: assert(time != NULL);
! 1868:
! 1869: time->y = 1970;
! 1870: time->m = 1;
! 1871: time->d = 1;
! 1872: time->h = time->i = time->s = 0;
! 1873: time->f = 0.0;
! 1874: time->tz_info = NULL;
! 1875: }
! 1876:
! 1877: static void timelib_time_reset_unset_fields(timelib_time *time)
! 1878: {
! 1879: assert(time != NULL);
! 1880:
! 1881: if (time->y == TIMELIB_UNSET ) time->y = 1970;
! 1882: if (time->m == TIMELIB_UNSET ) time->m = 1;
! 1883: if (time->d == TIMELIB_UNSET ) time->d = 1;
! 1884: if (time->h == TIMELIB_UNSET ) time->h = 0;
! 1885: if (time->i == TIMELIB_UNSET ) time->i = 0;
! 1886: if (time->s == TIMELIB_UNSET ) time->s = 0;
! 1887: if (time->f == TIMELIB_UNSET ) time->f = 0.0;
! 1888: }
! 1889:
! 1890: 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)
! 1891: {
! 1892: char *fptr = format;
! 1893: char *ptr = string;
! 1894: char *begin;
! 1895: timelib_sll tmp;
! 1896: Scanner in;
! 1897: Scanner *s = ∈
! 1898: int allow_extra = 0;
! 1899:
! 1900: memset(&in, 0, sizeof(in));
! 1901: in.errors = malloc(sizeof(struct timelib_error_container));
! 1902: in.errors->warning_count = 0;
! 1903: in.errors->warning_messages = NULL;
! 1904: in.errors->error_count = 0;
! 1905: in.errors->error_messages = NULL;
! 1906:
! 1907: in.time = timelib_time_ctor();
! 1908: in.time->y = TIMELIB_UNSET;
! 1909: in.time->d = TIMELIB_UNSET;
! 1910: in.time->m = TIMELIB_UNSET;
! 1911: in.time->h = TIMELIB_UNSET;
! 1912: in.time->i = TIMELIB_UNSET;
! 1913: in.time->s = TIMELIB_UNSET;
! 1914: in.time->f = TIMELIB_UNSET;
! 1915: in.time->z = TIMELIB_UNSET;
! 1916: in.time->dst = TIMELIB_UNSET;
! 1917: in.tzdb = tzdb;
! 1918: in.time->is_localtime = 0;
! 1919: in.time->zone_type = 0;
! 1920:
! 1921: /* Loop over the format string */
! 1922: while (*fptr && *ptr) {
! 1923: begin = ptr;
! 1924: switch (*fptr) {
! 1925: case 'D': /* three letter day */
! 1926: case 'l': /* full day */
! 1927: {
! 1928: const timelib_relunit* tmprel = 0;
! 1929:
! 1930: tmprel = timelib_lookup_relunit((char **) &ptr);
! 1931: if (!tmprel) {
! 1932: add_pbf_error(s, "A textual day could not be found", string, begin);
! 1933: break;
! 1934: } else {
! 1935: in.time->have_relative = 1;
! 1936: in.time->relative.have_weekday_relative = 1;
! 1937: in.time->relative.weekday = tmprel->multiplier;
! 1938: in.time->relative.weekday_behavior = 1;
! 1939: }
! 1940: }
! 1941: break;
! 1942: case 'd': /* two digit day, with leading zero */
! 1943: case 'j': /* two digit day, without leading zero */
! 1944: TIMELIB_CHECK_NUMBER;
! 1945: if ((s->time->d = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
! 1946: add_pbf_error(s, "A two digit day could not be found", string, begin);
! 1947: }
! 1948: break;
! 1949: case 'S': /* day suffix, ignored, nor checked */
! 1950: timelib_skip_day_suffix((char **) &ptr);
! 1951: break;
! 1952: case 'z': /* day of year - resets month (0 based) - also initializes everything else to !TIMELIB_UNSET */
! 1953: TIMELIB_CHECK_NUMBER;
! 1954: if ((tmp = timelib_get_nr((char **) &ptr, 3)) == TIMELIB_UNSET) {
! 1955: add_pbf_error(s, "A three digit day-of-year could not be found", string, begin);
! 1956: } else {
! 1957: s->time->m = 1;
! 1958: s->time->d = tmp + 1;
! 1959: timelib_do_normalize(s->time);
! 1960: }
! 1961: break;
! 1962:
! 1963: case 'm': /* two digit month, with leading zero */
! 1964: case 'n': /* two digit month, without leading zero */
! 1965: TIMELIB_CHECK_NUMBER;
! 1966: if ((s->time->m = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
! 1967: add_pbf_error(s, "A two digit month could not be found", string, begin);
! 1968: }
! 1969: break;
! 1970: case 'M': /* three letter month */
! 1971: case 'F': /* full month */
! 1972: tmp = timelib_lookup_month((char **) &ptr);
! 1973: if (!tmp) {
! 1974: add_pbf_error(s, "A textual month could not be found", string, begin);
! 1975: } else {
! 1976: s->time->m = tmp;
! 1977: }
! 1978: break;
! 1979: case 'y': /* two digit year */
! 1980: {
! 1981: int length = 0;
! 1982: TIMELIB_CHECK_NUMBER;
! 1983: if ((s->time->y = timelib_get_nr_ex((char **) &ptr, 2, &length)) == TIMELIB_UNSET) {
! 1984: add_pbf_error(s, "A two digit year could not be found", string, begin);
! 1985: }
! 1986: TIMELIB_PROCESS_YEAR(s->time->y, length);
! 1987: }
! 1988: break;
! 1989: case 'Y': /* four digit year */
! 1990: TIMELIB_CHECK_NUMBER;
! 1991: if ((s->time->y = timelib_get_nr((char **) &ptr, 4)) == TIMELIB_UNSET) {
! 1992: add_pbf_error(s, "A four digit year could not be found", string, begin);
! 1993: }
! 1994: break;
! 1995: case 'g': /* two digit hour, with leading zero */
! 1996: case 'h': /* two digit hour, without leading zero */
! 1997: TIMELIB_CHECK_NUMBER;
! 1998: if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
! 1999: add_pbf_error(s, "A two digit hour could not be found", string, begin);
! 2000: }
! 2001: if (s->time->h > 12) {
! 2002: add_pbf_error(s, "Hour can not be higher than 12", string, begin);
! 2003: }
! 2004: break;
! 2005: case 'G': /* two digit hour, with leading zero */
! 2006: case 'H': /* two digit hour, without leading zero */
! 2007: TIMELIB_CHECK_NUMBER;
! 2008: if ((s->time->h = timelib_get_nr((char **) &ptr, 2)) == TIMELIB_UNSET) {
! 2009: add_pbf_error(s, "A two digit hour could not be found", string, begin);
! 2010: }
! 2011: break;
! 2012: case 'a': /* am/pm/a.m./p.m. */
! 2013: case 'A': /* AM/PM/A.M./P.M. */
! 2014: if (s->time->h == TIMELIB_UNSET) {
! 2015: add_pbf_error(s, "Meridian can only come after an hour has been found", string, begin);
! 2016: } else if ((tmp = timelib_meridian_with_check((char **) &ptr, s->time->h)) == TIMELIB_UNSET) {
! 2017: add_pbf_error(s, "A meridian could not be found", string, begin);
! 2018: } else {
! 2019: s->time->h += tmp;
! 2020: }
! 2021: break;
! 2022: case 'i': /* two digit minute, with leading zero */
! 2023: {
! 2024: int length;
! 2025: timelib_sll min;
! 2026:
! 2027: TIMELIB_CHECK_NUMBER;
! 2028: min = timelib_get_nr_ex((char **) &ptr, 2, &length);
! 2029: if (min == TIMELIB_UNSET || length != 2) {
! 2030: add_pbf_error(s, "A two digit minute could not be found", string, begin);
! 2031: } else {
! 2032: s->time->i = min;
! 2033: }
! 2034: }
! 2035: break;
! 2036: case 's': /* two digit second, with leading zero */
! 2037: {
! 2038: int length;
! 2039: timelib_sll sec;
! 2040:
! 2041: TIMELIB_CHECK_NUMBER;
! 2042: sec = timelib_get_nr_ex((char **) &ptr, 2, &length);
! 2043: if (sec == TIMELIB_UNSET || length != 2) {
! 2044: add_pbf_error(s, "A two second minute could not be found", string, begin);
! 2045: } else {
! 2046: s->time->s = sec;
! 2047: }
! 2048: }
! 2049: break;
! 2050: case 'u': /* up to six digit millisecond */
! 2051: {
! 2052: double f;
! 2053: char *tptr;
! 2054:
! 2055: TIMELIB_CHECK_NUMBER;
! 2056: tptr = ptr;
! 2057: if ((f = timelib_get_nr((char **) &ptr, 6)) == TIMELIB_UNSET || (ptr - tptr < 1)) {
! 2058: add_pbf_error(s, "A six digit millisecond could not be found", string, begin);
! 2059: } else {
! 2060: s->time->f = (f / pow(10, (ptr - tptr)));
! 2061: }
! 2062: }
! 2063: break;
! 2064: case ' ': /* any sort of whitespace (' ' and \t) */
! 2065: timelib_eat_spaces((char **) &ptr);
! 2066: break;
! 2067: case 'U': /* epoch seconds */
! 2068: TIMELIB_CHECK_NUMBER;
! 2069: TIMELIB_HAVE_RELATIVE();
! 2070: tmp = timelib_get_unsigned_nr((char **) &ptr, 24);
! 2071: s->time->y = 1970;
! 2072: s->time->m = 1;
! 2073: s->time->d = 1;
! 2074: s->time->h = s->time->i = s->time->s = 0;
! 2075: s->time->f = 0.0;
! 2076: s->time->relative.s += tmp;
! 2077: s->time->is_localtime = 1;
! 2078: s->time->zone_type = TIMELIB_ZONETYPE_OFFSET;
! 2079: s->time->z = 0;
! 2080: break;
! 2081:
! 2082: case 'e': /* timezone */
! 2083: case 'P': /* timezone */
! 2084: case 'T': /* timezone */
! 2085: case 'O': /* timezone */
! 2086: {
! 2087: int tz_not_found;
! 2088: s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
! 2089: if (tz_not_found) {
! 2090: add_pbf_error(s, "The timezone could not be found in the database", string, begin);
! 2091: }
! 2092: }
! 2093: break;
! 2094:
! 2095: case '#': /* separation symbol */
! 2096: if (*ptr == ';' || *ptr == ':' || *ptr == '/' || *ptr == '.' || *ptr == ',' || *ptr == '-' || *ptr == '(' || *ptr == ')') {
! 2097: ++ptr;
! 2098: } else {
! 2099: add_pbf_error(s, "The separation symbol ([;:/.,-]) could not be found", string, begin);
! 2100: }
! 2101: break;
! 2102:
! 2103: case ';':
! 2104: case ':':
! 2105: case '/':
! 2106: case '.':
! 2107: case ',':
! 2108: case '-':
! 2109: case '(':
! 2110: case ')':
! 2111: if (*ptr == *fptr) {
! 2112: ++ptr;
! 2113: } else {
! 2114: add_pbf_error(s, "The separation symbol could not be found", string, begin);
! 2115: }
! 2116: break;
! 2117:
! 2118: case '!': /* reset all fields to default */
! 2119: timelib_time_reset_fields(s->time);
! 2120: break; /* break intentionally not missing */
! 2121:
! 2122: case '|': /* reset all fields to default when not set */
! 2123: timelib_time_reset_unset_fields(s->time);
! 2124: break; /* break intentionally not missing */
! 2125:
! 2126: case '?': /* random char */
! 2127: ++ptr;
! 2128: break;
! 2129:
! 2130: case '\\': /* escaped char */
! 2131: *fptr++;
! 2132: if (*ptr == *fptr) {
! 2133: ++ptr;
! 2134: } else {
! 2135: add_pbf_error(s, "The escaped character could not be found", string, begin);
! 2136: }
! 2137: break;
! 2138:
! 2139: case '*': /* random chars until a separator or number ([ \t.,:;/-0123456789]) */
! 2140: timelib_eat_until_separator((char **) &ptr);
! 2141: break;
! 2142:
! 2143: case '+': /* allow extra chars in the format */
! 2144: allow_extra = 1;
! 2145: break;
! 2146:
! 2147: default:
! 2148: if (*fptr != *ptr) {
! 2149: add_pbf_error(s, "The format separator does not match", string, begin);
! 2150: }
! 2151: ptr++;
! 2152: }
! 2153: fptr++;
! 2154: }
! 2155: if (*ptr) {
! 2156: if (allow_extra) {
! 2157: add_pbf_warning(s, "Trailing data", string, ptr);
! 2158: } else {
! 2159: add_pbf_error(s, "Trailing data", string, ptr);
! 2160: }
! 2161: }
! 2162: /* ignore trailing +'s */
! 2163: while (*fptr == '+') {
! 2164: fptr++;
! 2165: }
! 2166: if (*fptr) {
! 2167: /* Trailing | and ! specifiers are valid. */
! 2168: int done = 0;
! 2169: while (*fptr && !done) {
! 2170: switch (*fptr++) {
! 2171: case '!': /* reset all fields to default */
! 2172: timelib_time_reset_fields(s->time);
! 2173: break;
! 2174:
! 2175: case '|': /* reset all fields to default when not set */
! 2176: timelib_time_reset_unset_fields(s->time);
! 2177: break;
! 2178:
! 2179: default:
! 2180: add_pbf_error(s, "Data missing", string, ptr);
! 2181: done = 1;
! 2182: }
! 2183: }
! 2184: }
! 2185:
! 2186: /* clean up a bit */
! 2187: if (s->time->h != TIMELIB_UNSET || s->time->i != TIMELIB_UNSET || s->time->s != TIMELIB_UNSET) {
! 2188: if (s->time->h == TIMELIB_UNSET ) {
! 2189: s->time->h = 0;
! 2190: }
! 2191: if (s->time->i == TIMELIB_UNSET ) {
! 2192: s->time->i = 0;
! 2193: }
! 2194: if (s->time->s == TIMELIB_UNSET ) {
! 2195: s->time->s = 0;
! 2196: }
! 2197: }
! 2198:
! 2199: /* do funky checking whether the parsed time was valid time */
! 2200: if (s->time->h != TIMELIB_UNSET && s->time->i != TIMELIB_UNSET &&
! 2201: s->time->s != TIMELIB_UNSET &&
! 2202: !timelib_valid_time( s->time->h, s->time->i, s->time->s)) {
! 2203: add_pbf_warning(s, "The parsed time was invalid", string, ptr);
! 2204: }
! 2205: /* do funky checking whether the parsed date was valid date */
! 2206: if (s->time->y != TIMELIB_UNSET && s->time->m != TIMELIB_UNSET &&
! 2207: s->time->d != TIMELIB_UNSET &&
! 2208: !timelib_valid_date( s->time->y, s->time->m, s->time->d)) {
! 2209: add_pbf_warning(s, "The parsed date was invalid", string, ptr);
! 2210: }
! 2211:
! 2212: if (errors) {
! 2213: *errors = in.errors;
! 2214: } else {
! 2215: timelib_error_container_dtor(in.errors);
! 2216: }
! 2217: return in.time;
! 2218: }
! 2219:
! 2220: void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options)
! 2221: {
! 2222: if (!(options & TIMELIB_OVERRIDE_TIME) && parsed->have_date && !parsed->have_time) {
! 2223: parsed->h = 0;
! 2224: parsed->i = 0;
! 2225: parsed->s = 0;
! 2226: parsed->f = 0;
! 2227: }
! 2228: if (parsed->y == TIMELIB_UNSET) parsed->y = now->y != TIMELIB_UNSET ? now->y : 0;
! 2229: if (parsed->d == TIMELIB_UNSET) parsed->d = now->d != TIMELIB_UNSET ? now->d : 0;
! 2230: if (parsed->m == TIMELIB_UNSET) parsed->m = now->m != TIMELIB_UNSET ? now->m : 0;
! 2231: if (parsed->h == TIMELIB_UNSET) parsed->h = now->h != TIMELIB_UNSET ? now->h : 0;
! 2232: if (parsed->i == TIMELIB_UNSET) parsed->i = now->i != TIMELIB_UNSET ? now->i : 0;
! 2233: if (parsed->s == TIMELIB_UNSET) parsed->s = now->s != TIMELIB_UNSET ? now->s : 0;
! 2234: if (parsed->f == TIMELIB_UNSET) parsed->f = now->f != TIMELIB_UNSET ? now->f : 0;
! 2235: if (parsed->z == TIMELIB_UNSET) parsed->z = now->z != TIMELIB_UNSET ? now->z : 0;
! 2236: if (parsed->dst == TIMELIB_UNSET) parsed->dst = now->dst != TIMELIB_UNSET ? now->dst : 0;
! 2237:
! 2238: if (!parsed->tz_abbr) {
! 2239: parsed->tz_abbr = now->tz_abbr ? strdup(now->tz_abbr) : NULL;
! 2240: }
! 2241: if (!parsed->tz_info) {
! 2242: parsed->tz_info = now->tz_info ? (!(options & TIMELIB_NO_CLONE) ? timelib_tzinfo_clone(now->tz_info) : now->tz_info) : NULL;
! 2243: }
! 2244: if (parsed->zone_type == 0 && now->zone_type != 0) {
! 2245: parsed->zone_type = now->zone_type;
! 2246: /* parsed->tz_abbr = now->tz_abbr ? strdup(now->tz_abbr) : NULL;
! 2247: parsed->tz_info = now->tz_info ? timelib_tzinfo_clone(now->tz_info) : NULL;
! 2248: */ parsed->is_localtime = 1;
! 2249: }
! 2250: /* timelib_dump_date(parsed, 2);
! 2251: timelib_dump_date(now, 2);
! 2252: */
! 2253: }
! 2254:
! 2255: char *timelib_timezone_id_from_abbr(const char *abbr, long gmtoffset, int isdst)
! 2256: {
! 2257: const timelib_tz_lookup_table *tp;
! 2258:
! 2259: tp = zone_search(abbr, gmtoffset, isdst);
! 2260: if (tp) {
! 2261: return (tp->full_tz_name);
! 2262: } else {
! 2263: return NULL;
! 2264: }
! 2265: }
! 2266:
! 2267: const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void)
! 2268: {
! 2269: return timelib_timezone_lookup;
! 2270: }
! 2271:
! 2272: #ifdef DEBUG_PARSER_STUB
! 2273: int main(void)
! 2274: {
! 2275: timelib_time time = timelib_strtotime("May 12");
! 2276:
! 2277: printf ("%04d-%02d-%02d %02d:%02d:%02d.%-5d %+04d %1d",
! 2278: time.y, time.m, time.d, time.h, time.i, time.s, time.f, time.z, time.dst);
! 2279: if (time.have_relative) {
! 2280: printf ("%3dY %3dM %3dD / %3dH %3dM %3dS",
! 2281: time.relative.y, time.relative.m, time.relative.d, time.relative.h, time.relative.i, time.relative.s);
! 2282: }
! 2283: if (time.have_weekday_relative) {
! 2284: printf (" / %d", time.relative.weekday);
! 2285: }
! 2286: if (time.have_weeknr_day) {
! 2287: printf(" / %dW%d", time.relative.weeknr_day.weeknr, time.relative.weeknr_day.dayofweek);
! 2288: }
! 2289: return 0;
! 2290: }
! 2291: #endif
! 2292:
! 2293: /*
! 2294: * vim: syntax=c
! 2295: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>