LTP GCOV extension - code coverage report
Current view: directory - home/mike/build/php-5.2-gcov/lcov_data/ext/date/lib - parse_date.re
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 674
Code covered: 29.8 % Executed lines: 201
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5