1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2006 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 271468 2008-12-18 14:57:04Z derick $ */
20 :
21 : #include "timelib.h"
22 :
23 : #include <stdio.h>
24 : #include <ctype.h>
25 :
26 : #ifdef HAVE_STDLIB_H
27 : #include <stdlib.h>
28 : #endif
29 : #ifdef HAVE_STRING_H
30 : #include <string.h>
31 : #else
32 : #include <strings.h>
33 : #endif
34 :
35 : #if defined(_MSC_VER)
36 : # define strtoll(s, f, b) _atoi64(s)
37 : #elif !defined(HAVE_STRTOLL)
38 : # if defined(HAVE_ATOLL)
39 : # define strtoll(s, f, b) atoll(s)
40 : # else
41 : # define strtoll(s, f, b) strtol(s, f, b)
42 : # endif
43 : #endif
44 :
45 : #define TIMELIB_UNSET -99999
46 :
47 : #define TIMELIB_SECOND 1
48 : #define TIMELIB_MINUTE 2
49 : #define TIMELIB_HOUR 3
50 : #define TIMELIB_DAY 4
51 : #define TIMELIB_MONTH 5
52 : #define TIMELIB_YEAR 6
53 : #define TIMELIB_WEEKDAY 7
54 : #define TIMELIB_SPECIAL 8
55 :
56 : #define EOI 257
57 : #define TIME 258
58 : #define DATE 259
59 :
60 : #define TIMELIB_XMLRPC_SOAP 260
61 : #define TIMELIB_TIME12 261
62 : #define TIMELIB_TIME24 262
63 : #define TIMELIB_GNU_NOCOLON 263
64 : #define TIMELIB_GNU_NOCOLON_TZ 264
65 : #define TIMELIB_ISO_NOCOLON 265
66 :
67 : #define TIMELIB_AMERICAN 266
68 : #define TIMELIB_ISO_DATE 267
69 : #define TIMELIB_DATE_FULL 268
70 : #define TIMELIB_DATE_TEXT 269
71 : #define TIMELIB_DATE_NOCOLON 270
72 : #define TIMELIB_PG_YEARDAY 271
73 : #define TIMELIB_PG_TEXT 272
74 : #define TIMELIB_PG_REVERSE 273
75 : #define TIMELIB_CLF 274
76 : #define TIMELIB_DATE_NO_DAY 275
77 : #define TIMELIB_SHORTDATE_WITH_TIME 276
78 : #define TIMELIB_DATE_FULL_POINTED 277
79 : #define TIMELIB_TIME24_WITH_ZONE 278
80 : #define TIMELIB_ISO_WEEK 279
81 :
82 : #define TIMELIB_TIMEZONE 300
83 : #define TIMELIB_AGO 301
84 :
85 : #define TIMELIB_RELATIVE 310
86 :
87 : #define TIMELIB_ERROR 999
88 :
89 : typedef unsigned char uchar;
90 :
91 : #define BSIZE 8192
92 :
93 : #define YYCTYPE uchar
94 : #define YYCURSOR cursor
95 : #define YYLIMIT s->lim
96 : #define YYMARKER s->ptr
97 : #define YYFILL(n) return EOI;
98 :
99 : #define RET(i) {s->cur = cursor; return i;}
100 :
101 : #define timelib_string_free free
102 :
103 : #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; } }
104 : #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; }
105 : #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; } }
106 : #define TIMELIB_UNHAVE_DATE() { s->time->have_date = 0; s->time->d = 0; s->time->m = 0; s->time->y = 0; }
107 : #define TIMELIB_HAVE_RELATIVE() { s->time->have_relative = 1; s->time->relative.weekday_behavior = 1; }
108 : #define TIMELIB_HAVE_WEEKDAY_RELATIVE() { s->time->have_weekday_relative = 1; }
109 : #define TIMELIB_HAVE_SPECIAL_RELATIVE() { s->time->have_special_relative = 1; }
110 : #define TIMELIB_HAVE_TZ() { s->cur = cursor; if (s->time->have_zone) { add_warning(s, "Double timezone specification"); timelib_string_free(str); return TIMELIB_ERROR; } else { s->time->have_zone = 1; } }
111 :
112 : #define TIMELIB_INIT s->cur = cursor; str = timelib_string(s); ptr = str
113 : #define TIMELIB_DEINIT timelib_string_free(str)
114 : #define TIMELIB_ADJUST_RELATIVE_WEEKDAY() if (in->time.have_weekday_relative && (in.rel.d > 0)) { in.rel.d -= 7; }
115 :
116 : #define TIMELIB_PROCESS_YEAR(x) { \
117 : if ((x) == TIMELIB_UNSET) { \
118 : /* (x) = 0; */ \
119 : } else if ((x) < 100) { \
120 : if ((x) < 70) { \
121 : (x) += 2000; \
122 : } else { \
123 : (x) += 1900; \
124 : } \
125 : } \
126 : }
127 :
128 : #ifdef DEBUG_PARSER
129 : #define DEBUG_OUTPUT(s) printf("%s\n", s);
130 : #define YYDEBUG(s,c) { if (s != -1) { printf("state: %d ", s); printf("[%c]\n", c); } }
131 : #else
132 : #define DEBUG_OUTPUT(s)
133 : #define YYDEBUG(s,c)
134 : #endif
135 :
136 : #include "timelib_structs.h"
137 :
138 : typedef struct timelib_elems {
139 : unsigned int c; /* Number of elements */
140 : char **v; /* Values */
141 : } timelib_elems;
142 :
143 : typedef struct Scanner {
144 : int fd;
145 : uchar *lim, *str, *ptr, *cur, *tok, *pos;
146 : unsigned int line, len;
147 : struct timelib_error_container *errors;
148 :
149 : struct timelib_time *time;
150 : const timelib_tzdb *tzdb;
151 : } Scanner;
152 :
153 : typedef struct _timelib_lookup_table {
154 : const char *name;
155 : int type;
156 : int value;
157 : } timelib_lookup_table;
158 :
159 : typedef struct _timelib_relunit {
160 : const char *name;
161 : int unit;
162 : int multiplier;
163 : } timelib_relunit;
164 :
165 : #define HOUR(a) (int)(a * 60)
166 :
167 : /* The timezone table. */
168 : const static timelib_tz_lookup_table timelib_timezone_lookup[] = {
169 : #include "timezonemap.h"
170 : { NULL, 0, 0, NULL },
171 : };
172 :
173 : const static timelib_tz_lookup_table timelib_timezone_fallbackmap[] = {
174 : #include "fallbackmap.h"
175 : { NULL, 0, 0, NULL },
176 : };
177 :
178 : const static timelib_tz_lookup_table timelib_timezone_utc[] = {
179 : { "utc", 0, 0, "UTC" },
180 : };
181 :
182 : static timelib_relunit const timelib_relunit_lookup[] = {
183 : { "sec", TIMELIB_SECOND, 1 },
184 : { "secs", TIMELIB_SECOND, 1 },
185 : { "second", TIMELIB_SECOND, 1 },
186 : { "seconds", TIMELIB_SECOND, 1 },
187 : { "min", TIMELIB_MINUTE, 1 },
188 : { "mins", TIMELIB_MINUTE, 1 },
189 : { "minute", TIMELIB_MINUTE, 1 },
190 : { "minutes", TIMELIB_MINUTE, 1 },
191 : { "hour", TIMELIB_HOUR, 1 },
192 : { "hours", TIMELIB_HOUR, 1 },
193 : { "day", TIMELIB_DAY, 1 },
194 : { "days", TIMELIB_DAY, 1 },
195 : { "week", TIMELIB_DAY, 7 },
196 : { "weeks", TIMELIB_DAY, 7 },
197 : { "fortnight", TIMELIB_DAY, 14 },
198 : { "fortnights", TIMELIB_DAY, 14 },
199 : { "forthnight", TIMELIB_DAY, 14 },
200 : { "forthnights", TIMELIB_DAY, 14 },
201 : { "month", TIMELIB_MONTH, 1 },
202 : { "months", TIMELIB_MONTH, 1 },
203 : { "year", TIMELIB_YEAR, 1 },
204 : { "years", TIMELIB_YEAR, 1 },
205 :
206 : { "monday", TIMELIB_WEEKDAY, 1 },
207 : { "mon", TIMELIB_WEEKDAY, 1 },
208 : { "tuesday", TIMELIB_WEEKDAY, 2 },
209 : { "tue", TIMELIB_WEEKDAY, 2 },
210 : { "wednesday", TIMELIB_WEEKDAY, 3 },
211 : { "wed", TIMELIB_WEEKDAY, 3 },
212 : { "thursday", TIMELIB_WEEKDAY, 4 },
213 : { "thu", TIMELIB_WEEKDAY, 4 },
214 : { "friday", TIMELIB_WEEKDAY, 5 },
215 : { "fri", TIMELIB_WEEKDAY, 5 },
216 : { "saturday", TIMELIB_WEEKDAY, 6 },
217 : { "sat", TIMELIB_WEEKDAY, 6 },
218 : { "sunday", TIMELIB_WEEKDAY, 0 },
219 : { "sun", TIMELIB_WEEKDAY, 0 },
220 :
221 : { "weekday", TIMELIB_SPECIAL, TIMELIB_SPECIAL_WEEKDAY },
222 : { "weekdays", TIMELIB_SPECIAL, TIMELIB_SPECIAL_WEEKDAY },
223 : { NULL, 0, 0 }
224 : };
225 :
226 : /* The relative text table. */
227 : static timelib_lookup_table const timelib_reltext_lookup[] = {
228 : { "first", 0, 1 },
229 : { "next", 0, 1 },
230 : { "second", 0, 2 },
231 : { "third", 0, 3 },
232 : { "fourth", 0, 4 },
233 : { "fifth", 0, 5 },
234 : { "sixth", 0, 6 },
235 : { "seventh", 0, 7 },
236 : { "eight", 0, 8 },
237 : { "ninth", 0, 9 },
238 : { "tenth", 0, 10 },
239 : { "eleventh", 0, 11 },
240 : { "twelfth", 0, 12 },
241 : { "last", 0, -1 },
242 : { "previous", 0, -1 },
243 : { "this", 1, 0 },
244 : { NULL, 1, 0 }
245 : };
246 :
247 : /* The month table. */
248 : static timelib_lookup_table const timelib_month_lookup[] = {
249 : { "jan", 0, 1 },
250 : { "feb", 0, 2 },
251 : { "mar", 0, 3 },
252 : { "apr", 0, 4 },
253 : { "may", 0, 5 },
254 : { "jun", 0, 6 },
255 : { "jul", 0, 7 },
256 : { "aug", 0, 8 },
257 : { "sep", 0, 9 },
258 : { "sept", 0, 9 },
259 : { "oct", 0, 10 },
260 : { "nov", 0, 11 },
261 : { "dec", 0, 12 },
262 : { "i", 0, 1 },
263 : { "ii", 0, 2 },
264 : { "iii", 0, 3 },
265 : { "iv", 0, 4 },
266 : { "v", 0, 5 },
267 : { "vi", 0, 6 },
268 : { "vii", 0, 7 },
269 : { "viii", 0, 8 },
270 : { "ix", 0, 9 },
271 : { "x", 0, 10 },
272 : { "xi", 0, 11 },
273 : { "xii", 0, 12 },
274 :
275 : { "january", 0, 1 },
276 : { "february", 0, 2 },
277 : { "march", 0, 3 },
278 : { "april", 0, 4 },
279 : { "may", 0, 5 },
280 : { "june", 0, 6 },
281 : { "july", 0, 7 },
282 : { "august", 0, 8 },
283 : { "september", 0, 9 },
284 : { "october", 0, 10 },
285 : { "november", 0, 11 },
286 : { "december", 0, 12 },
287 : { NULL, 0, 0 }
288 : };
289 :
290 : #if 0
291 : static char* timelib_ltrim(char *s)
292 : {
293 : char *ptr = s;
294 : while (ptr[0] == ' ' || ptr[0] == '\t') {
295 : ptr++;
296 : }
297 : return ptr;
298 : }
299 : #endif
300 :
301 : #if 0
302 : uchar *fill(Scanner *s, uchar *cursor){
303 : if(!s->eof){
304 : unsigned int cnt = s->tok - s->bot;
305 : if(cnt){
306 : memcpy(s->bot, s->tok, s->lim - s->tok);
307 : s->tok = s->bot;
308 : s->ptr -= cnt;
309 : cursor -= cnt;
310 : s->pos -= cnt;
311 : s->lim -= cnt;
312 : }
313 : if((s->top - s->lim) < BSIZE){
314 : uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
315 : memcpy(buf, s->tok, s->lim - s->tok);
316 : s->tok = buf;
317 : s->ptr = &buf[s->ptr - s->bot];
318 : cursor = &buf[cursor - s->bot];
319 : s->pos = &buf[s->pos - s->bot];
320 : s->lim = &buf[s->lim - s->bot];
321 : s->top = &s->lim[BSIZE];
322 : free(s->bot);
323 : s->bot = buf;
324 : }
325 : if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
326 : s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
327 : }
328 : s->lim += cnt;
329 : }
330 : return cursor;
331 : }
332 : #endif
333 :
334 : static void add_warning(Scanner *s, char *error)
335 41 : {
336 41 : s->errors->warning_count++;
337 41 : s->errors->warning_messages = realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message));
338 41 : s->errors->warning_messages[s->errors->warning_count - 1].position = s->tok ? s->tok - s->str : 0;
339 41 : s->errors->warning_messages[s->errors->warning_count - 1].character = s->tok ? *s->tok : 0;
340 41 : s->errors->warning_messages[s->errors->warning_count - 1].message = strdup(error);
341 41 : }
342 :
343 : static void add_error(Scanner *s, char *error)
344 155 : {
345 155 : s->errors->error_count++;
346 155 : s->errors->error_messages = realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
347 155 : s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0;
348 155 : s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0;
349 155 : s->errors->error_messages[s->errors->error_count - 1].message = strdup(error);
350 155 : }
351 :
352 : static timelib_sll timelib_meridian(char **ptr, timelib_sll h)
353 24 : {
354 24 : timelib_sll retval = 0;
355 :
356 55 : while (!strchr("AaPp", **ptr)) {
357 7 : ++*ptr;
358 : }
359 40 : if (**ptr == 'a' || **ptr == 'A') {
360 16 : if (h == 12) {
361 4 : retval = -12;
362 : }
363 8 : } else if (h != 12) {
364 8 : retval = 12;
365 : }
366 24 : ++*ptr;
367 24 : if (**ptr == '.') {
368 6 : *ptr += 3;
369 : } else {
370 18 : ++*ptr;
371 : }
372 24 : return retval;
373 : }
374 :
375 : static char *timelib_string(Scanner *s)
376 4127 : {
377 4127 : char *tmp = calloc(1, s->cur - s->tok + 1);
378 4127 : memcpy(tmp, s->tok, s->cur - s->tok);
379 :
380 4127 : return tmp;
381 : }
382 :
383 : static timelib_sll timelib_get_nr(char **ptr, int max_length)
384 9333 : {
385 : char *begin, *end, *str;
386 9333 : timelib_sll tmp_nr = TIMELIB_UNSET;
387 9333 : int len = 0;
388 :
389 24553 : while ((**ptr < '0') || (**ptr > '9')) {
390 5890 : if (**ptr == '\0') {
391 3 : return TIMELIB_UNSET;
392 : }
393 5887 : ++*ptr;
394 : }
395 9330 : begin = *ptr;
396 42414 : while ((**ptr >= '0') && (**ptr <= '9') && len < max_length) {
397 23754 : ++*ptr;
398 23754 : ++len;
399 : }
400 9330 : end = *ptr;
401 9330 : str = calloc(1, end - begin + 1);
402 9330 : memcpy(str, begin, end - begin);
403 9330 : tmp_nr = strtoll(str, NULL, 10);
404 9330 : free(str);
405 9330 : return tmp_nr;
406 : }
407 :
408 : static void timelib_skip_day_suffix(char **ptr)
409 82 : {
410 82 : if (isspace(**ptr)) {
411 75 : return;
412 : }
413 7 : if (!strncasecmp(*ptr, "nd", 2) || !strncasecmp(*ptr, "rd", 2) ||!strncasecmp(*ptr, "st", 2) || !strncasecmp(*ptr, "th", 2)) {
414 2 : *ptr += 2;
415 : }
416 : }
417 :
418 : static double timelib_get_frac_nr(char **ptr, int max_length)
419 20 : {
420 : char *begin, *end, *str;
421 20 : double tmp_nr = TIMELIB_UNSET;
422 20 : int len = 0;
423 :
424 40 : while ((**ptr != '.') && ((**ptr < '0') || (**ptr > '9'))) {
425 0 : if (**ptr == '\0') {
426 0 : return TIMELIB_UNSET;
427 : }
428 0 : ++*ptr;
429 : }
430 20 : begin = *ptr;
431 154 : while (((**ptr == '.') || ((**ptr >= '0') && (**ptr <= '9'))) && len < max_length) {
432 114 : ++*ptr;
433 114 : ++len;
434 : }
435 20 : end = *ptr;
436 20 : str = calloc(1, end - begin + 1);
437 20 : memcpy(str, begin, end - begin);
438 20 : tmp_nr = strtod(str, NULL);
439 20 : free(str);
440 20 : return tmp_nr;
441 : }
442 :
443 : static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
444 1849 : {
445 1849 : timelib_ull dir = 1;
446 :
447 3916 : while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) {
448 218 : if (**ptr == '\0') {
449 0 : return TIMELIB_UNSET;
450 : }
451 218 : ++*ptr;
452 : }
453 :
454 3955 : while (**ptr == '+' || **ptr == '-')
455 : {
456 257 : if (**ptr == '-') {
457 84 : dir *= -1;
458 : }
459 257 : ++*ptr;
460 : }
461 1849 : return dir * timelib_get_nr(ptr, max_length);
462 : }
463 :
464 : static long timelib_parse_tz_cor(char **ptr)
465 103 : {
466 103 : char *begin = *ptr, *end;
467 : long tmp;
468 :
469 576 : while (**ptr != '\0') {
470 370 : ++*ptr;
471 : }
472 103 : end = *ptr;
473 103 : switch (end - begin) {
474 : case 1:
475 : case 2:
476 27 : return HOUR(strtol(begin, NULL, 10));
477 : break;
478 : case 3:
479 : case 4:
480 58 : if (begin[1] == ':') {
481 1 : tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
482 1 : return tmp;
483 57 : } else if (begin[2] == ':') {
484 0 : tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
485 0 : return tmp;
486 : } else {
487 57 : tmp = strtol(begin, NULL, 10);
488 57 : return HOUR(tmp / 100) + tmp % 100;
489 : }
490 : case 5:
491 18 : tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
492 18 : return tmp;
493 : }
494 0 : return 0;
495 : }
496 :
497 : static timelib_sll timelib_lookup_relative_text(char **ptr, int *behavior)
498 102 : {
499 : char *word;
500 102 : char *begin = *ptr, *end;
501 102 : timelib_sll value = 0;
502 : const timelib_lookup_table *tp;
503 :
504 649 : while ((**ptr >= 'A' && **ptr <= 'Z') || (**ptr >= 'a' && **ptr <= 'z')) {
505 445 : ++*ptr;
506 : }
507 102 : end = *ptr;
508 102 : word = calloc(1, end - begin + 1);
509 102 : memcpy(word, begin, end - begin);
510 :
511 1734 : for (tp = timelib_reltext_lookup; tp->name; tp++) {
512 1632 : if (strcasecmp(word, tp->name) == 0) {
513 102 : value = tp->value;
514 102 : *behavior = tp->type;
515 : }
516 : }
517 :
518 102 : free(word);
519 102 : return value;
520 : }
521 :
522 : static timelib_sll timelib_get_relative_text(char **ptr, int *behavior)
523 102 : {
524 204 : while (**ptr == ' ' || **ptr == '\t' || **ptr == '-' || **ptr == '/') {
525 0 : ++*ptr;
526 : }
527 102 : return timelib_lookup_relative_text(ptr, behavior);
528 : }
529 :
530 : static long timelib_lookup_month(char **ptr)
531 149 : {
532 : char *word;
533 149 : char *begin = *ptr, *end;
534 149 : long value = 0;
535 : const timelib_lookup_table *tp;
536 :
537 806 : while ((**ptr >= 'A' && **ptr <= 'Z') || (**ptr >= 'a' && **ptr <= 'z')) {
538 508 : ++*ptr;
539 : }
540 149 : end = *ptr;
541 149 : word = calloc(1, end - begin + 1);
542 149 : memcpy(word, begin, end - begin);
543 :
544 5662 : for (tp = timelib_month_lookup; tp->name; tp++) {
545 5513 : if (strcasecmp(word, tp->name) == 0) {
546 157 : value = tp->value;
547 : }
548 : }
549 :
550 149 : free(word);
551 149 : return value;
552 : }
553 :
554 : static long timelib_get_month(char **ptr)
555 147 : {
556 377 : while (**ptr == ' ' || **ptr == '\t' || **ptr == '-' || **ptr == '.' || **ptr == '/') {
557 83 : ++*ptr;
558 : }
559 147 : return timelib_lookup_month(ptr);
560 : }
561 :
562 : static void timelib_eat_spaces(char **ptr)
563 380 : {
564 1135 : while (**ptr == ' ' || **ptr == '\t') {
565 375 : ++*ptr;
566 : }
567 380 : }
568 :
569 : static const timelib_relunit* timelib_lookup_relunit(char **ptr)
570 434 : {
571 : char *word;
572 434 : char *begin = *ptr, *end;
573 434 : const timelib_relunit *tp, *value = NULL;
574 :
575 3213 : while (**ptr != '\0' && **ptr != ' ' && **ptr != '\t') {
576 2345 : ++*ptr;
577 : }
578 434 : end = *ptr;
579 434 : word = calloc(1, end - begin + 1);
580 434 : memcpy(word, begin, end - begin);
581 :
582 7837 : for (tp = timelib_relunit_lookup; tp->name; tp++) {
583 7837 : if (strcasecmp(word, tp->name) == 0) {
584 434 : value = tp;
585 434 : break;
586 : }
587 : }
588 :
589 434 : free(word);
590 434 : return value;
591 : }
592 :
593 : static void timelib_set_relative(char **ptr, timelib_sll amount, int behavior, Scanner *s)
594 380 : {
595 : const timelib_relunit* relunit;
596 :
597 380 : if (!(relunit = timelib_lookup_relunit(ptr))) {
598 0 : return;
599 : }
600 :
601 380 : switch (relunit->unit) {
602 33 : case TIMELIB_SECOND: s->time->relative.s += amount * relunit->multiplier; break;
603 22 : case TIMELIB_MINUTE: s->time->relative.i += amount * relunit->multiplier; break;
604 56 : case TIMELIB_HOUR: s->time->relative.h += amount * relunit->multiplier; break;
605 99 : case TIMELIB_DAY: s->time->relative.d += amount * relunit->multiplier; break;
606 31 : case TIMELIB_MONTH: s->time->relative.m += amount * relunit->multiplier; break;
607 31 : case TIMELIB_YEAR: s->time->relative.y += amount * relunit->multiplier; break;
608 :
609 : case TIMELIB_WEEKDAY:
610 108 : TIMELIB_HAVE_WEEKDAY_RELATIVE();
611 108 : TIMELIB_UNHAVE_TIME();
612 108 : s->time->relative.d += (amount > 0 ? amount - 1 : amount) * 7;
613 108 : s->time->relative.weekday = relunit->multiplier;
614 108 : s->time->relative.weekday_behavior = behavior;
615 108 : break;
616 :
617 : case TIMELIB_SPECIAL:
618 0 : TIMELIB_HAVE_SPECIAL_RELATIVE();
619 0 : TIMELIB_UNHAVE_TIME();
620 0 : s->time->special.type = relunit->multiplier;
621 0 : s->time->special.amount = amount;
622 : }
623 : }
624 :
625 : const static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffset, int isdst)
626 492 : {
627 492 : int first_found = 0;
628 492 : const timelib_tz_lookup_table *tp, *first_found_elem = NULL;
629 : const timelib_tz_lookup_table *fmp;
630 :
631 492 : if (strcasecmp("utc", word) == 0 || strcasecmp("gmt", word) == 0) {
632 266 : return timelib_timezone_utc;
633 : }
634 :
635 356396 : for (tp = timelib_timezone_lookup; tp->name; tp++) {
636 356208 : if (strcasecmp(word, tp->name) == 0) {
637 62 : if (!first_found) {
638 39 : first_found = 1;
639 39 : first_found_elem = tp;
640 39 : if (gmtoffset == -1) {
641 31 : return tp;
642 : }
643 : }
644 31 : if (tp->gmtoffset == gmtoffset) {
645 7 : return tp;
646 : }
647 : }
648 : }
649 188 : if (first_found) {
650 1 : return first_found_elem;
651 : }
652 :
653 : /* Still didn't find anything, let's find the zone solely based on
654 : * offset/isdst then */
655 7103 : for (fmp = timelib_timezone_fallbackmap; fmp->name; fmp++) {
656 6942 : if ((fmp->gmtoffset * 3600) == gmtoffset && fmp->type == isdst) {
657 26 : return fmp;
658 : }
659 : }
660 161 : return NULL;
661 : }
662 :
663 : static long timelib_lookup_zone(char **ptr, int *dst, char **tz_abbr, int *found)
664 310 : {
665 : char *word;
666 310 : char *begin = *ptr, *end;
667 310 : long value = 0;
668 : const timelib_tz_lookup_table *tp;
669 :
670 1786 : while (**ptr != '\0' && **ptr != ')' && **ptr != ' ') {
671 1166 : ++*ptr;
672 : }
673 310 : end = *ptr;
674 310 : word = calloc(1, end - begin + 1);
675 310 : memcpy(word, begin, end - begin);
676 :
677 310 : if ((tp = zone_search(word, -1, 0))) {
678 249 : value = -tp->gmtoffset / 60;
679 249 : *dst = tp->type;
680 249 : value += tp->type * 60;
681 249 : *found = 1;
682 : } else {
683 61 : *found = 0;
684 : }
685 :
686 310 : *tz_abbr = word;
687 310 : return value;
688 : }
689 :
690 : static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, const timelib_tzdb *tzdb)
691 413 : {
692 : timelib_tzinfo *res;
693 413 : long retval = 0;
694 :
695 413 : *tz_not_found = 0;
696 :
697 828 : while (**ptr == ' ' || **ptr == '\t' || **ptr == '(') {
698 2 : ++*ptr;
699 : }
700 413 : if (**ptr == '+') {
701 62 : ++*ptr;
702 62 : t->is_localtime = 1;
703 62 : t->zone_type = TIMELIB_ZONETYPE_OFFSET;
704 62 : *tz_not_found = 0;
705 62 : t->dst = 0;
706 :
707 62 : retval = -1 * timelib_parse_tz_cor(ptr);
708 351 : } else if (**ptr == '-') {
709 41 : ++*ptr;
710 41 : t->is_localtime = 1;
711 41 : t->zone_type = TIMELIB_ZONETYPE_OFFSET;
712 41 : *tz_not_found = 0;
713 41 : t->dst = 0;
714 :
715 41 : retval = timelib_parse_tz_cor(ptr);
716 : } else {
717 310 : int found = 0;
718 : long offset;
719 : char *tz_abbr;
720 :
721 310 : t->is_localtime = 1;
722 :
723 310 : offset = timelib_lookup_zone(ptr, dst, &tz_abbr, &found);
724 310 : if (found) {
725 249 : t->zone_type = TIMELIB_ZONETYPE_ABBR;
726 : }
727 : #if 0
728 : /* If we found a TimeZone identifier, use it */
729 : if (tz_name) {
730 : t->tz_info = timelib_parse_tzfile(tz_name);
731 : t->zone_type = TIMELIB_ZONETYPE_ID;
732 : }
733 : #endif
734 : /* If we have a TimeZone identifier to start with, use it */
735 310 : if (strstr(tz_abbr, "/") || strcmp(tz_abbr, "UTC") == 0) {
736 205 : if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) {
737 205 : t->tz_info = res;
738 205 : t->zone_type = TIMELIB_ZONETYPE_ID;
739 205 : found++;
740 : }
741 : }
742 310 : if (found && t->zone_type != TIMELIB_ZONETYPE_ID) {
743 56 : timelib_time_tz_abbr_update(t, tz_abbr);
744 : }
745 310 : free(tz_abbr);
746 310 : *tz_not_found = (found == 0);
747 310 : retval = offset;
748 : }
749 826 : while (**ptr == ')') {
750 0 : ++*ptr;
751 : }
752 413 : return retval;
753 : }
754 :
755 : #define timelib_split_free(arg) { \
756 : int i; \
757 : for (i = 0; i < arg.c; i++) { \
758 : free(arg.v[i]); \
759 : } \
760 : if (arg.v) { \
761 : free(arg.v); \
762 : } \
763 : }
764 :
765 : static int scan(Scanner *s)
766 7310 : {
767 7310 : uchar *cursor = s->cur;
768 7310 : char *str, *ptr = NULL;
769 :
770 11434 : std:
771 11434 : s->tok = cursor;
772 11434 : s->len = 0;
773 : /*!re2c
774 : any = [\000-\377];
775 :
776 : space = [ \t]+;
777 : frac = "."[0-9]+;
778 :
779 : ago = 'ago';
780 :
781 : hour24 = [01]?[0-9] | "2"[0-3];
782 : hour24lz = [01][0-9] | "2"[0-3];
783 : hour12 = "0"?[1-9] | "1"[0-2];
784 : minute = [0-5]?[0-9];
785 : minutelz = [0-5][0-9];
786 : second = minute | "60";
787 : secondlz = minutelz | "60";
788 : meridian = ([AaPp] "."? [Mm] "."?) [\000\t ];
789 : tz = "("? [A-Za-z]{1,6} ")"? | [A-Z][a-z]+([_/][A-Z][a-z]+)+;
790 : tzcorrection = [+-] hour24 ":"? minute?;
791 :
792 : daysuf = "st" | "nd" | "rd" | "th";
793 :
794 : month = "0"? [0-9] | "1"[0-2];
795 : day = (([0-2]?[0-9]) | ("3"[01])) daysuf?;
796 : year = [0-9]{1,4};
797 : year2 = [0-9]{2};
798 : year4 = [0-9]{4};
799 : year4withsign = [+-]? [0-9]{4};
800 :
801 : dayofyear = "00"[1-9] | "0"[1-9][0-9] | [1-2][0-9][0-9] | "3"[0-5][0-9] | "36"[0-6];
802 : weekofyear = "0"[1-9] | [1-4][0-9] | "5"[0-3];
803 :
804 : monthlz = "0" [0-9] | "1" [0-2];
805 : daylz = "0" [0-9] | [1-2][0-9] | "3" [01];
806 :
807 : dayfull = 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday';
808 : dayabbr = 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun';
809 : dayspecial = 'weekday' | 'weekdays';
810 : daytext = dayfull | dayabbr | dayspecial;
811 :
812 : monthfull = 'january' | 'february' | 'march' | 'april' | 'may' | 'june' | 'july' | 'august' | 'september' | 'october' | 'november' | 'december';
813 : monthabbr = 'jan' | 'feb' | 'mar' | 'apr' | 'may' | 'jun' | 'jul' | 'aug' | 'sep' | 'sept' | 'oct' | 'nov' | 'dec';
814 : monthroman = "I" | "II" | "III" | "IV" | "V" | "VI" | "VII" | "VIII" | "IX" | "X" | "XI" | "XII";
815 : monthtext = monthfull | monthabbr | monthroman;
816 :
817 : /* Time formats */
818 : timetiny12 = hour12 space? meridian;
819 : timeshort12 = hour12[:.]minutelz space? meridian;
820 : timelong12 = hour12[:.]minute[:.]secondlz space? meridian;
821 :
822 : timeshort24 = 't'? hour24[:.]minute;
823 : timelong24 = 't'? hour24[:.]minute[:.]second;
824 : iso8601long = 't'? hour24 [:.] minute [:.] second frac;
825 :
826 : /* iso8601shorttz = hour24 [:] minutelz space? (tzcorrection | tz); */
827 : iso8601normtz = 't'? hour24 [:.] minute [:.] secondlz space? (tzcorrection | tz);
828 : /* iso8601longtz = hour24 [:] minute [:] secondlz frac space? (tzcorrection | tz); */
829 :
830 : gnunocolon = 't'? hour24lz minutelz;
831 : /* gnunocolontz = hour24lz minutelz space? (tzcorrection | tz); */
832 : iso8601nocolon = 't'? hour24lz minutelz secondlz;
833 : /* iso8601nocolontz = hour24lz minutelz secondlz space? (tzcorrection | tz); */
834 :
835 : /* Date formats */
836 : americanshort = month "/" day;
837 : american = month "/" day "/" year;
838 : iso8601dateslash = year4 "/" monthlz "/" daylz "/"?;
839 : dateslash = year4 "/" month "/" day;
840 : iso8601date4 = year4withsign "-" monthlz "-" daylz;
841 : iso8601date2 = year2 "-" monthlz "-" daylz;
842 : gnudateshorter = year4 "-" month;
843 : gnudateshort = year "-" month "-" day;
844 : pointeddate4 = day [.\t-] month [.-] year4;
845 : pointeddate2 = day [.\t] month "." year2;
846 : datefull = day ([ \t.-])* monthtext ([ \t.-])* year;
847 : datenoday = monthtext ([ .\t-])* year4;
848 : datenodayrev = year4 ([ .\t-])* monthtext;
849 : datetextual = monthtext ([ .\t-])* day [,.stndrh\t ]+ year;
850 : datenoyear = monthtext ([ .\t-])* day [,.stndrh\t ]*;
851 : datenoyearrev = day ([ .\t-])* monthtext;
852 : datenocolon = year4 monthlz daylz;
853 :
854 : /* Special formats */
855 : soap = year4 "-" monthlz "-" daylz "T" hour24lz ":" minutelz ":" secondlz frac tzcorrection?;
856 : xmlrpc = year4 monthlz daylz "T" hour24 ":" minutelz ":" secondlz;
857 : xmlrpcnocolon = year4 monthlz daylz 't' hour24 minutelz secondlz;
858 : wddx = year4 "-" month "-" day "T" hour24 ":" minute ":" second;
859 : pgydotd = year4 "."? dayofyear;
860 : pgtextshort = monthabbr "-" daylz "-" year;
861 : pgtextreverse = year "-" monthabbr "-" daylz;
862 : isoweekday = year4 "-"? "W" weekofyear "-"? [0-7];
863 : isoweek = year4 "-"? "W" weekofyear;
864 : exif = year4 ":" monthlz ":" daylz " " hour24lz ":" minutelz ":" secondlz;
865 :
866 : /* Common Log Format: 10/Oct/2000:13:55:36 -0700 */
867 : clf = day "/" monthabbr "/" year4 ":" hour24lz ":" minutelz ":" secondlz space tzcorrection;
868 :
869 : /* Timestamp format: @1126396800 */
870 : timestamp = "@" "-"? [0-9]+;
871 :
872 : /* To fix some ambiguities */
873 : dateshortwithtimeshort12 = datenoyear timeshort12;
874 : dateshortwithtimelong12 = datenoyear timelong12;
875 : dateshortwithtimeshort = datenoyear timeshort24;
876 : dateshortwithtimelong = datenoyear timelong24;
877 : dateshortwithtimelongtz = datenoyear iso8601normtz;
878 :
879 : /*
880 : * Relative regexps
881 : */
882 : reltextnumber = 'first'|'next'|'second'|'third'|'fourth'|'fifth'|'sixth'|'seventh'|'eight'|'ninth'|'tenth'|'eleventh'|'twelfth'|'last'|'previous'|'this';
883 : reltextunit = (('sec'|'second'|'min'|'minute'|'hour'|'day'|'week'|'fortnight'|'forthnight'|'month'|'year') 's'?) | daytext;
884 :
885 : relnumber = ([+-]*[ \t]*[0-9]+);
886 : relative = relnumber space? reltextunit;
887 : relativetext = reltextnumber space reltextunit;
888 :
889 : */
890 :
891 : /*!re2c
892 : /* so that vim highlights correctly */
893 : 'yesterday'
894 : {
895 : DEBUG_OUTPUT("yesterday");
896 1 : TIMELIB_INIT;
897 1 : TIMELIB_HAVE_RELATIVE();
898 1 : TIMELIB_UNHAVE_TIME();
899 :
900 1 : s->time->relative.d = -1;
901 1 : TIMELIB_DEINIT;
902 1 : return TIMELIB_RELATIVE;
903 : }
904 :
905 : 'now'
906 : {
907 : DEBUG_OUTPUT("now");
908 37 : TIMELIB_INIT;
909 :
910 37 : TIMELIB_DEINIT;
911 37 : return TIMELIB_RELATIVE;
912 : }
913 :
914 : 'noon'
915 : {
916 : DEBUG_OUTPUT("noon");
917 1 : TIMELIB_INIT;
918 1 : TIMELIB_UNHAVE_TIME();
919 1 : TIMELIB_HAVE_TIME();
920 1 : s->time->h = 12;
921 :
922 1 : TIMELIB_DEINIT;
923 1 : return TIMELIB_RELATIVE;
924 : }
925 :
926 : 'midnight' | 'today'
927 : {
928 : DEBUG_OUTPUT("midnight | today");
929 1 : TIMELIB_INIT;
930 1 : TIMELIB_UNHAVE_TIME();
931 :
932 1 : TIMELIB_DEINIT;
933 1 : return TIMELIB_RELATIVE;
934 : }
935 :
936 : 'tomorrow'
937 : {
938 : DEBUG_OUTPUT("tomorrow");
939 1 : TIMELIB_INIT;
940 1 : TIMELIB_HAVE_RELATIVE();
941 1 : TIMELIB_UNHAVE_TIME();
942 :
943 1 : s->time->relative.d = 1;
944 1 : TIMELIB_DEINIT;
945 1 : return TIMELIB_RELATIVE;
946 : }
947 :
948 : timestamp
949 : {
950 : timelib_ull i;
951 :
952 201 : TIMELIB_INIT;
953 201 : TIMELIB_HAVE_RELATIVE();
954 201 : TIMELIB_UNHAVE_DATE();
955 201 : TIMELIB_UNHAVE_TIME();
956 :
957 201 : i = timelib_get_unsigned_nr((char **) &ptr, 24);
958 201 : s->time->y = 1970;
959 201 : s->time->m = 1;
960 201 : s->time->d = 1;
961 201 : s->time->h = s->time->i = s->time->s = 0;
962 201 : s->time->f = 0.0;
963 201 : s->time->relative.s += i;
964 201 : s->time->is_localtime = 1;
965 201 : s->time->zone_type = TIMELIB_ZONETYPE_OFFSET;
966 201 : s->time->z = 0;
967 :
968 201 : TIMELIB_DEINIT;
969 201 : return TIMELIB_RELATIVE;
970 : }
971 :
972 : timetiny12 | timeshort12 | timelong12
973 : {
974 : DEBUG_OUTPUT("timetiny12 | timeshort12 | timelong12");
975 20 : TIMELIB_INIT;
976 20 : TIMELIB_HAVE_TIME();
977 20 : s->time->h = timelib_get_nr((char **) &ptr, 2);
978 20 : if (*ptr == ':' || *ptr == '.') {
979 12 : s->time->i = timelib_get_nr((char **) &ptr, 2);
980 12 : if (*ptr == ':' || *ptr == '.') {
981 3 : s->time->s = timelib_get_nr((char **) &ptr, 2);
982 : }
983 : }
984 20 : s->time->h += timelib_meridian((char **) &ptr, s->time->h);
985 20 : TIMELIB_DEINIT;
986 20 : return TIMELIB_TIME12;
987 : }
988 :
989 : timeshort24 | timelong24 /* | iso8601short | iso8601norm */ | iso8601long /*| iso8601shorttz | iso8601normtz | iso8601longtz*/
990 : {
991 : int tz_not_found;
992 : DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long");
993 343 : TIMELIB_INIT;
994 343 : TIMELIB_HAVE_TIME();
995 342 : s->time->h = timelib_get_nr((char **) &ptr, 2);
996 342 : s->time->i = timelib_get_nr((char **) &ptr, 2);
997 342 : if (*ptr == ':' || *ptr == '.') {
998 315 : s->time->s = timelib_get_nr((char **) &ptr, 2);
999 :
1000 315 : if (*ptr == '.') {
1001 19 : s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
1002 : }
1003 : }
1004 :
1005 342 : if (*ptr != '\0') {
1006 0 : s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb);
1007 0 : if (tz_not_found) {
1008 0 : add_error(s, "The timezone could not be found in the database");
1009 : }
1010 : }
1011 342 : TIMELIB_DEINIT;
1012 342 : return TIMELIB_TIME24_WITH_ZONE;
1013 : }
1014 :
1015 : gnunocolon
1016 : {
1017 : DEBUG_OUTPUT("gnunocolon");
1018 18 : TIMELIB_INIT;
1019 18 : switch (s->time->have_time) {
1020 : case 0:
1021 12 : s->time->h = timelib_get_nr((char **) &ptr, 2);
1022 12 : s->time->i = timelib_get_nr((char **) &ptr, 2);
1023 12 : s->time->s = 0;
1024 12 : break;
1025 : case 1:
1026 6 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1027 6 : break;
1028 : default:
1029 0 : TIMELIB_DEINIT;
1030 0 : add_error(s, "Double time specification");
1031 0 : return TIMELIB_ERROR;
1032 : }
1033 18 : s->time->have_time++;
1034 18 : TIMELIB_DEINIT;
1035 18 : return TIMELIB_GNU_NOCOLON;
1036 : }
1037 : /*
1038 : gnunocolontz
1039 : {
1040 : DEBUG_OUTPUT("gnunocolontz");
1041 : TIMELIB_INIT;
1042 : switch (s->time->have_time) {
1043 : case 0:
1044 : s->time->h = timelib_get_nr((char **) &ptr, 2);
1045 : s->time->i = timelib_get_nr((char **) &ptr, 2);
1046 : s->time->s = 0;
1047 : s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, s->tzdb);
1048 : break;
1049 : case 1:
1050 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1051 : break;
1052 : default:
1053 : TIMELIB_DEINIT;
1054 : return TIMELIB_ERROR;
1055 : }
1056 : s->time->have_time++;
1057 : TIMELIB_DEINIT;
1058 : return TIMELIB_GNU_NOCOLON_TZ;
1059 : }
1060 : */
1061 : iso8601nocolon /*| iso8601nocolontz*/
1062 : {
1063 : int tz_not_found;
1064 : DEBUG_OUTPUT("iso8601nocolon");
1065 8 : TIMELIB_INIT;
1066 8 : TIMELIB_HAVE_TIME();
1067 8 : s->time->h = timelib_get_nr((char **) &ptr, 2);
1068 8 : s->time->i = timelib_get_nr((char **) &ptr, 2);
1069 8 : s->time->s = timelib_get_nr((char **) &ptr, 2);
1070 :
1071 8 : if (*ptr != '\0') {
1072 0 : s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb);
1073 0 : if (tz_not_found) {
1074 0 : add_error(s, "The timezone could not be found in the database");
1075 : }
1076 : }
1077 8 : TIMELIB_DEINIT;
1078 8 : return TIMELIB_ISO_NOCOLON;
1079 : }
1080 :
1081 : americanshort | american
1082 : {
1083 : DEBUG_OUTPUT("americanshort | american");
1084 4 : TIMELIB_INIT;
1085 4 : TIMELIB_HAVE_DATE();
1086 4 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1087 4 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1088 4 : if (*ptr == '/') {
1089 4 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1090 4 : TIMELIB_PROCESS_YEAR(s->time->y);
1091 : }
1092 4 : TIMELIB_DEINIT;
1093 4 : return TIMELIB_AMERICAN;
1094 : }
1095 :
1096 : iso8601date4 | iso8601dateslash | dateslash
1097 : {
1098 : DEBUG_OUTPUT("iso8601date4 | iso8601date2 | iso8601dateslash | dateslash");
1099 1370 : TIMELIB_INIT;
1100 1370 : TIMELIB_HAVE_DATE();
1101 1370 : s->time->y = timelib_get_unsigned_nr((char **) &ptr, 4);
1102 1370 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1103 1370 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1104 1370 : TIMELIB_DEINIT;
1105 1370 : return TIMELIB_ISO_DATE;
1106 : }
1107 :
1108 : iso8601date2
1109 : {
1110 : DEBUG_OUTPUT("iso8601date2");
1111 0 : TIMELIB_INIT;
1112 0 : TIMELIB_HAVE_DATE();
1113 0 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1114 0 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1115 0 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1116 0 : TIMELIB_PROCESS_YEAR(s->time->y);
1117 0 : TIMELIB_DEINIT;
1118 0 : return TIMELIB_ISO_DATE;
1119 : }
1120 :
1121 : gnudateshorter
1122 : {
1123 : DEBUG_OUTPUT("gnudateshorter");
1124 5 : TIMELIB_INIT;
1125 5 : TIMELIB_HAVE_DATE();
1126 5 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1127 5 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1128 5 : s->time->d = 1;
1129 5 : TIMELIB_PROCESS_YEAR(s->time->y);
1130 5 : TIMELIB_DEINIT;
1131 5 : return TIMELIB_ISO_DATE;
1132 : }
1133 :
1134 : gnudateshort
1135 : {
1136 : DEBUG_OUTPUT("gnudateshort");
1137 1019 : TIMELIB_INIT;
1138 1019 : TIMELIB_HAVE_DATE();
1139 1019 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1140 1019 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1141 1019 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1142 1019 : TIMELIB_PROCESS_YEAR(s->time->y);
1143 1019 : TIMELIB_DEINIT;
1144 1019 : return TIMELIB_ISO_DATE;
1145 : }
1146 :
1147 : datefull
1148 : {
1149 : DEBUG_OUTPUT("datefull");
1150 79 : TIMELIB_INIT;
1151 79 : TIMELIB_HAVE_DATE();
1152 79 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1153 79 : timelib_skip_day_suffix((char **) &ptr);
1154 79 : s->time->m = timelib_get_month((char **) &ptr);
1155 79 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1156 79 : TIMELIB_PROCESS_YEAR(s->time->y);
1157 79 : TIMELIB_DEINIT;
1158 79 : return TIMELIB_DATE_FULL;
1159 : }
1160 :
1161 : pointeddate4
1162 : {
1163 : DEBUG_OUTPUT("pointed date YYYY");
1164 3 : TIMELIB_INIT;
1165 3 : TIMELIB_HAVE_DATE();
1166 3 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1167 3 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1168 3 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1169 3 : TIMELIB_DEINIT;
1170 3 : return TIMELIB_DATE_FULL_POINTED;
1171 : }
1172 :
1173 : pointeddate2
1174 : {
1175 : DEBUG_OUTPUT("pointed date YY");
1176 0 : TIMELIB_INIT;
1177 0 : TIMELIB_HAVE_DATE();
1178 0 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1179 0 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1180 0 : s->time->y = timelib_get_nr((char **) &ptr, 2);
1181 0 : TIMELIB_PROCESS_YEAR(s->time->y);
1182 0 : TIMELIB_DEINIT;
1183 0 : return TIMELIB_DATE_FULL_POINTED;
1184 : }
1185 :
1186 : datenoday
1187 : {
1188 : DEBUG_OUTPUT("datenoday");
1189 23 : TIMELIB_INIT;
1190 23 : TIMELIB_HAVE_DATE();
1191 23 : s->time->m = timelib_get_month((char **) &ptr);
1192 23 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1193 23 : s->time->d = 1;
1194 23 : TIMELIB_PROCESS_YEAR(s->time->y);
1195 23 : TIMELIB_DEINIT;
1196 23 : return TIMELIB_DATE_NO_DAY;
1197 : }
1198 :
1199 : datenodayrev
1200 : {
1201 : DEBUG_OUTPUT("datenodayrev");
1202 1 : TIMELIB_INIT;
1203 1 : TIMELIB_HAVE_DATE();
1204 1 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1205 1 : s->time->m = timelib_get_month((char **) &ptr);
1206 1 : s->time->d = 1;
1207 1 : TIMELIB_PROCESS_YEAR(s->time->y);
1208 1 : TIMELIB_DEINIT;
1209 1 : return TIMELIB_DATE_NO_DAY;
1210 : }
1211 :
1212 : datetextual | datenoyear
1213 : {
1214 : DEBUG_OUTPUT("datetextual | datenoyear");
1215 26 : TIMELIB_INIT;
1216 26 : TIMELIB_HAVE_DATE();
1217 26 : s->time->m = timelib_get_month((char **) &ptr);
1218 26 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1219 26 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1220 26 : TIMELIB_PROCESS_YEAR(s->time->y);
1221 26 : TIMELIB_DEINIT;
1222 26 : return TIMELIB_DATE_TEXT;
1223 : }
1224 :
1225 : datenoyearrev
1226 : {
1227 : DEBUG_OUTPUT("datenoyearrev");
1228 3 : TIMELIB_INIT;
1229 3 : TIMELIB_HAVE_DATE();
1230 3 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1231 3 : timelib_skip_day_suffix((char **) &ptr);
1232 3 : s->time->m = timelib_get_month((char **) &ptr);
1233 3 : TIMELIB_DEINIT;
1234 3 : return TIMELIB_DATE_TEXT;
1235 : }
1236 :
1237 : datenocolon
1238 : {
1239 : DEBUG_OUTPUT("datenocolon");
1240 6 : TIMELIB_INIT;
1241 6 : TIMELIB_HAVE_DATE();
1242 6 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1243 6 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1244 6 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1245 6 : TIMELIB_DEINIT;
1246 6 : return TIMELIB_DATE_NOCOLON;
1247 : }
1248 :
1249 : xmlrpc | xmlrpcnocolon | soap | wddx | exif
1250 : {
1251 : int tz_not_found;
1252 : DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx | exif");
1253 41 : TIMELIB_INIT;
1254 41 : TIMELIB_HAVE_TIME();
1255 41 : TIMELIB_HAVE_DATE();
1256 41 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1257 41 : s->time->m = timelib_get_nr((char **) &ptr, 2);
1258 41 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1259 41 : s->time->h = timelib_get_nr((char **) &ptr, 2);
1260 41 : s->time->i = timelib_get_nr((char **) &ptr, 2);
1261 41 : s->time->s = timelib_get_nr((char **) &ptr, 2);
1262 41 : if (*ptr == '.') {
1263 1 : s->time->f = timelib_get_frac_nr((char **) &ptr, 9);
1264 1 : if (*ptr) { /* timezone is optional */
1265 0 : s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb);
1266 0 : if (tz_not_found) {
1267 0 : add_error(s, "The timezone could not be found in the database");
1268 : }
1269 : }
1270 : }
1271 41 : TIMELIB_DEINIT;
1272 41 : return TIMELIB_XMLRPC_SOAP;
1273 : }
1274 :
1275 : pgydotd
1276 : {
1277 : DEBUG_OUTPUT("pgydotd");
1278 1 : TIMELIB_INIT;
1279 1 : TIMELIB_HAVE_DATE();
1280 1 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1281 1 : s->time->d = timelib_get_nr((char **) &ptr, 3);
1282 1 : s->time->m = 1;
1283 1 : TIMELIB_PROCESS_YEAR(s->time->y);
1284 1 : TIMELIB_DEINIT;
1285 1 : return TIMELIB_PG_YEARDAY;
1286 : }
1287 :
1288 : isoweekday
1289 : {
1290 : timelib_sll w, d;
1291 : DEBUG_OUTPUT("isoweekday");
1292 4 : TIMELIB_INIT;
1293 4 : TIMELIB_HAVE_DATE();
1294 4 : TIMELIB_HAVE_RELATIVE();
1295 :
1296 4 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1297 4 : w = timelib_get_nr((char **) &ptr, 2);
1298 4 : d = timelib_get_nr((char **) &ptr, 1);
1299 4 : s->time->m = 1;
1300 4 : s->time->d = 1;
1301 4 : s->time->relative.d = timelib_daynr_from_weeknr(s->time->y, w, d);
1302 :
1303 4 : TIMELIB_DEINIT;
1304 4 : return TIMELIB_ISO_WEEK;
1305 : }
1306 :
1307 : isoweek
1308 : {
1309 : timelib_sll w, d;
1310 : DEBUG_OUTPUT("isoweek");
1311 1 : TIMELIB_INIT;
1312 1 : TIMELIB_HAVE_DATE();
1313 1 : TIMELIB_HAVE_RELATIVE();
1314 :
1315 1 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1316 1 : w = timelib_get_nr((char **) &ptr, 2);
1317 1 : d = 1;
1318 1 : s->time->m = 1;
1319 1 : s->time->d = 1;
1320 1 : s->time->relative.d = timelib_daynr_from_weeknr(s->time->y, w, d);
1321 :
1322 1 : TIMELIB_DEINIT;
1323 1 : return TIMELIB_ISO_WEEK;
1324 : }
1325 :
1326 : pgtextshort
1327 : {
1328 : DEBUG_OUTPUT("pgtextshort");
1329 1 : TIMELIB_INIT;
1330 1 : TIMELIB_HAVE_DATE();
1331 1 : s->time->m = timelib_get_month((char **) &ptr);
1332 1 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1333 1 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1334 1 : TIMELIB_PROCESS_YEAR(s->time->y);
1335 1 : TIMELIB_DEINIT;
1336 1 : return TIMELIB_PG_TEXT;
1337 : }
1338 :
1339 : pgtextreverse
1340 : {
1341 : DEBUG_OUTPUT("pgtextreverse");
1342 1 : TIMELIB_INIT;
1343 1 : TIMELIB_HAVE_DATE();
1344 1 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1345 1 : s->time->m = timelib_get_month((char **) &ptr);
1346 1 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1347 1 : TIMELIB_PROCESS_YEAR(s->time->y);
1348 1 : TIMELIB_DEINIT;
1349 1 : return TIMELIB_PG_TEXT;
1350 : }
1351 :
1352 : clf
1353 : {
1354 : int tz_not_found;
1355 : DEBUG_OUTPUT("clf");
1356 2 : TIMELIB_INIT;
1357 2 : TIMELIB_HAVE_TIME();
1358 2 : TIMELIB_HAVE_DATE();
1359 2 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1360 2 : s->time->m = timelib_get_month((char **) &ptr);
1361 2 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1362 2 : s->time->h = timelib_get_nr((char **) &ptr, 2);
1363 2 : s->time->i = timelib_get_nr((char **) &ptr, 2);
1364 2 : s->time->s = timelib_get_nr((char **) &ptr, 2);
1365 2 : s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb);
1366 2 : if (tz_not_found) {
1367 0 : add_error(s, "The timezone could not be found in the database");
1368 : }
1369 2 : TIMELIB_DEINIT;
1370 2 : return TIMELIB_CLF;
1371 : }
1372 :
1373 : year4
1374 : {
1375 : DEBUG_OUTPUT("year4");
1376 1 : TIMELIB_INIT;
1377 1 : s->time->y = timelib_get_nr((char **) &ptr, 4);
1378 1 : TIMELIB_DEINIT;
1379 1 : return TIMELIB_CLF;
1380 : }
1381 :
1382 : ago
1383 : {
1384 : DEBUG_OUTPUT("ago");
1385 6 : TIMELIB_INIT;
1386 6 : s->time->relative.y = 0 - s->time->relative.y;
1387 6 : s->time->relative.m = 0 - s->time->relative.m;
1388 6 : s->time->relative.d = 0 - s->time->relative.d;
1389 6 : s->time->relative.h = 0 - s->time->relative.h;
1390 6 : s->time->relative.i = 0 - s->time->relative.i;
1391 6 : s->time->relative.s = 0 - s->time->relative.s;
1392 6 : s->time->relative.weekday = 0 - s->time->relative.weekday;
1393 6 : if (s->time->have_special_relative && s->time->special.type == TIMELIB_SPECIAL_WEEKDAY) {
1394 0 : s->time->special.amount = 0 - s->time->special.amount;
1395 : }
1396 6 : TIMELIB_DEINIT;
1397 6 : return TIMELIB_AGO;
1398 : }
1399 :
1400 : daytext
1401 : {
1402 : const timelib_relunit* relunit;
1403 : DEBUG_OUTPUT("daytext");
1404 54 : TIMELIB_INIT;
1405 54 : TIMELIB_HAVE_RELATIVE();
1406 54 : TIMELIB_HAVE_WEEKDAY_RELATIVE();
1407 54 : TIMELIB_UNHAVE_TIME();
1408 54 : relunit = timelib_lookup_relunit((char**) &ptr);
1409 54 : s->time->relative.weekday = relunit->multiplier;
1410 54 : if (s->time->relative.weekday_behavior != 2) {
1411 54 : s->time->relative.weekday_behavior = 1;
1412 : }
1413 :
1414 54 : TIMELIB_DEINIT;
1415 54 : return TIMELIB_WEEKDAY;
1416 : }
1417 :
1418 : relativetext
1419 : {
1420 : timelib_sll i;
1421 102 : int behavior = 0;
1422 : DEBUG_OUTPUT("relativetext");
1423 102 : TIMELIB_INIT;
1424 102 : TIMELIB_HAVE_RELATIVE();
1425 :
1426 306 : while(*ptr) {
1427 102 : i = timelib_get_relative_text((char **) &ptr, &behavior);
1428 102 : timelib_eat_spaces((char **) &ptr);
1429 102 : timelib_set_relative((char **) &ptr, i, behavior, s);
1430 : }
1431 102 : TIMELIB_DEINIT;
1432 102 : return TIMELIB_RELATIVE;
1433 : }
1434 :
1435 : monthfull | monthabbr
1436 : {
1437 : DEBUG_OUTPUT("monthtext");
1438 2 : TIMELIB_INIT;
1439 2 : TIMELIB_HAVE_DATE();
1440 2 : s->time->m = timelib_lookup_month((char **) &ptr);
1441 2 : TIMELIB_DEINIT;
1442 2 : return TIMELIB_DATE_TEXT;
1443 : }
1444 :
1445 : tzcorrection | tz
1446 : {
1447 : int tz_not_found;
1448 : DEBUG_OUTPUT("tzcorrection | tz");
1449 452 : TIMELIB_INIT;
1450 452 : TIMELIB_HAVE_TZ();
1451 411 : s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb);
1452 411 : if (tz_not_found) {
1453 49 : add_error(s, "The timezone could not be found in the database");
1454 : }
1455 411 : TIMELIB_DEINIT;
1456 411 : return TIMELIB_TIMEZONE;
1457 : }
1458 :
1459 : dateshortwithtimeshort12 | dateshortwithtimelong12
1460 : {
1461 : DEBUG_OUTPUT("dateshortwithtimeshort12 | dateshortwithtimelong12");
1462 4 : TIMELIB_INIT;
1463 4 : TIMELIB_HAVE_DATE();
1464 4 : s->time->m = timelib_get_month((char **) &ptr);
1465 4 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1466 :
1467 4 : TIMELIB_HAVE_TIME();
1468 4 : s->time->h = timelib_get_nr((char **) &ptr, 2);
1469 4 : s->time->i = timelib_get_nr((char **) &ptr, 2);
1470 4 : if (*ptr == ':' || *ptr == '.') {
1471 0 : s->time->s = timelib_get_nr((char **) &ptr, 2);
1472 :
1473 0 : if (*ptr == '.') {
1474 0 : s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
1475 : }
1476 : }
1477 :
1478 4 : s->time->h += timelib_meridian((char **) &ptr, s->time->h);
1479 4 : TIMELIB_DEINIT;
1480 4 : return TIMELIB_SHORTDATE_WITH_TIME;
1481 : }
1482 :
1483 : dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz
1484 : {
1485 : int tz_not_found;
1486 : DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz");
1487 7 : TIMELIB_INIT;
1488 7 : TIMELIB_HAVE_DATE();
1489 7 : s->time->m = timelib_get_month((char **) &ptr);
1490 7 : s->time->d = timelib_get_nr((char **) &ptr, 2);
1491 :
1492 7 : TIMELIB_HAVE_TIME();
1493 7 : s->time->h = timelib_get_nr((char **) &ptr, 2);
1494 7 : s->time->i = timelib_get_nr((char **) &ptr, 2);
1495 7 : if (*ptr == ':') {
1496 3 : s->time->s = timelib_get_nr((char **) &ptr, 2);
1497 :
1498 3 : if (*ptr == '.') {
1499 0 : s->time->f = timelib_get_frac_nr((char **) &ptr, 8);
1500 : }
1501 : }
1502 :
1503 7 : if (*ptr != '\0') {
1504 0 : s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb);
1505 0 : if (tz_not_found) {
1506 0 : add_error(s, "The timezone could not be found in the database");
1507 : }
1508 : }
1509 7 : TIMELIB_DEINIT;
1510 7 : return TIMELIB_SHORTDATE_WITH_TIME;
1511 : }
1512 :
1513 : relative
1514 : {
1515 : timelib_ull i;
1516 : DEBUG_OUTPUT("relative");
1517 278 : TIMELIB_INIT;
1518 278 : TIMELIB_HAVE_RELATIVE();
1519 :
1520 834 : while(*ptr) {
1521 278 : i = timelib_get_unsigned_nr((char **) &ptr, 24);
1522 278 : timelib_eat_spaces((char **) &ptr);
1523 278 : timelib_set_relative((char **) &ptr, i, 1, s);
1524 : }
1525 278 : TIMELIB_DEINIT;
1526 278 : return TIMELIB_RELATIVE;
1527 : }
1528 :
1529 : [ .,\t]
1530 : {
1531 880 : goto std;
1532 : }
1533 :
1534 : "\000"|"\n"
1535 : {
1536 3164 : s->pos = cursor; s->line++;
1537 3164 : goto std;
1538 : }
1539 :
1540 : any
1541 : {
1542 80 : add_error(s, "Unexpected character");
1543 80 : goto std;
1544 : }
1545 : */
1546 : }
1547 :
1548 : /*!max:re2c */
1549 :
1550 : timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container **errors, const timelib_tzdb *tzdb)
1551 3208 : {
1552 : Scanner in;
1553 : int t;
1554 3208 : char *e = s + len - 1;
1555 :
1556 3208 : memset(&in, 0, sizeof(in));
1557 3208 : in.errors = malloc(sizeof(struct timelib_error_container));
1558 3208 : in.errors->warning_count = 0;
1559 3208 : in.errors->warning_messages = NULL;
1560 3208 : in.errors->error_count = 0;
1561 3208 : in.errors->error_messages = NULL;
1562 :
1563 3208 : if (len > 0) {
1564 6375 : while (isspace(*s) && s < e) {
1565 9 : s++;
1566 : }
1567 6375 : while (isspace(*e) && e > s) {
1568 9 : e--;
1569 : }
1570 : }
1571 3208 : if (e - s < 0) {
1572 25 : in.time = timelib_time_ctor();
1573 25 : add_error(&in, "Empty string");
1574 25 : if (errors) {
1575 9 : *errors = in.errors;
1576 : } else {
1577 16 : timelib_error_container_dtor(in.errors);
1578 : }
1579 25 : 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;
1580 25 : in.time->is_localtime = in.time->zone_type = 0;
1581 25 : return in.time;
1582 : }
1583 3183 : e++;
1584 :
1585 3183 : in.str = malloc((e - s) + YYMAXFILL);
1586 3183 : memset(in.str, 0, (e - s) + YYMAXFILL);
1587 3183 : memcpy(in.str, s, (e - s));
1588 3183 : in.lim = in.str + (e - s) + YYMAXFILL;
1589 3183 : in.cur = in.str;
1590 3183 : in.time = timelib_time_ctor();
1591 3183 : in.time->y = TIMELIB_UNSET;
1592 3183 : in.time->d = TIMELIB_UNSET;
1593 3183 : in.time->m = TIMELIB_UNSET;
1594 3183 : in.time->h = TIMELIB_UNSET;
1595 3183 : in.time->i = TIMELIB_UNSET;
1596 3183 : in.time->s = TIMELIB_UNSET;
1597 3183 : in.time->f = TIMELIB_UNSET;
1598 3183 : in.time->z = TIMELIB_UNSET;
1599 3183 : in.time->dst = TIMELIB_UNSET;
1600 3183 : in.tzdb = tzdb;
1601 3183 : in.time->is_localtime = 0;
1602 3183 : in.time->zone_type = 0;
1603 :
1604 : do {
1605 7310 : t = scan(&in);
1606 : #ifdef DEBUG_PARSER
1607 : printf("%d\n", t);
1608 : #endif
1609 7310 : } while(t != EOI);
1610 :
1611 3183 : free(in.str);
1612 3183 : if (errors) {
1613 2931 : *errors = in.errors;
1614 : } else {
1615 252 : timelib_error_container_dtor(in.errors);
1616 : }
1617 3183 : return in.time;
1618 : }
1619 :
1620 : void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options)
1621 2844 : {
1622 2844 : if (!(options & TIMELIB_OVERRIDE_TIME) && parsed->have_date && !parsed->have_time) {
1623 2193 : parsed->h = 0;
1624 2193 : parsed->i = 0;
1625 2193 : parsed->s = 0;
1626 2193 : parsed->f = 0;
1627 : }
1628 2844 : if (parsed->y == TIMELIB_UNSET) parsed->y = now->y != TIMELIB_UNSET ? now->y : 0;
1629 2844 : if (parsed->d == TIMELIB_UNSET) parsed->d = now->d != TIMELIB_UNSET ? now->d : 0;
1630 2844 : if (parsed->m == TIMELIB_UNSET) parsed->m = now->m != TIMELIB_UNSET ? now->m : 0;
1631 2844 : if (parsed->h == TIMELIB_UNSET) parsed->h = now->h != TIMELIB_UNSET ? now->h : 0;
1632 2844 : if (parsed->i == TIMELIB_UNSET) parsed->i = now->i != TIMELIB_UNSET ? now->i : 0;
1633 2844 : if (parsed->s == TIMELIB_UNSET) parsed->s = now->s != TIMELIB_UNSET ? now->s : 0;
1634 2844 : if (parsed->f == TIMELIB_UNSET) parsed->f = now->f != TIMELIB_UNSET ? now->f : 0;
1635 2844 : if (parsed->z == TIMELIB_UNSET) parsed->z = now->z != TIMELIB_UNSET ? now->z : 0;
1636 2844 : if (parsed->dst == TIMELIB_UNSET) parsed->dst = now->dst != TIMELIB_UNSET ? now->dst : 0;
1637 :
1638 2844 : if (!parsed->tz_abbr) {
1639 2796 : parsed->tz_abbr = now->tz_abbr ? strdup(now->tz_abbr) : NULL;
1640 : }
1641 2844 : if (!parsed->tz_info) {
1642 2828 : parsed->tz_info = now->tz_info ? (!(options & TIMELIB_NO_CLONE) ? timelib_tzinfo_clone(now->tz_info) : now->tz_info) : NULL;
1643 : }
1644 2844 : if (parsed->zone_type == 0 && now->zone_type != 0) {
1645 2689 : parsed->zone_type = now->zone_type;
1646 : /* parsed->tz_abbr = now->tz_abbr ? strdup(now->tz_abbr) : NULL;
1647 : parsed->tz_info = now->tz_info ? timelib_tzinfo_clone(now->tz_info) : NULL;
1648 2689 : */ parsed->is_localtime = 1;
1649 : }
1650 : /* timelib_dump_date(parsed, 2);
1651 : timelib_dump_date(now, 2);
1652 : */
1653 2844 : }
1654 :
1655 : char *timelib_timezone_id_from_abbr(const char *abbr, long gmtoffset, int isdst)
1656 182 : {
1657 : const timelib_tz_lookup_table *tp;
1658 :
1659 182 : tp = zone_search(abbr, gmtoffset, isdst);
1660 182 : if (tp) {
1661 82 : return (tp->full_tz_name);
1662 : } else {
1663 100 : return NULL;
1664 : }
1665 : }
1666 :
1667 : const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void)
1668 3 : {
1669 3 : return timelib_timezone_lookup;
1670 : }
1671 :
1672 : #ifdef DEBUG_PARSER_STUB
1673 : int main(void)
1674 : {
1675 : timelib_time time = timelib_strtotime("May 12");
1676 :
1677 : printf ("%04d-%02d-%02d %02d:%02d:%02d.%-5d %+04d %1d",
1678 : time.y, time.m, time.d, time.h, time.i, time.s, time.f, time.z, time.dst);
1679 : if (time.have_relative) {
1680 : printf ("%3dY %3dM %3dD / %3dH %3dM %3dS",
1681 : time.relative.y, time.relative.m, time.relative.d, time.relative.h, time.relative.i, time.relative.s);
1682 : }
1683 : if (time.have_weekday_relative) {
1684 : printf (" / %d", time.relative.weekday);
1685 : }
1686 : if (time.have_weeknr_day) {
1687 : printf(" / %dW%d", time.relative.weeknr_day.weeknr, time.relative.weeknr_day.dayofweek);
1688 : }
1689 : return 0;
1690 : }
1691 : #endif
1692 :
1693 : /*
1694 : * vim: syntax=c
1695 : */
|