2005-06-14 21:32:29 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| PHP Version 5 |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 12:26:08 +00:00
| Copyright ( c ) 1997 - 2006 The PHP Group |
2005-06-14 21:32:29 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 12:26:08 +00:00
| This source file is subject to version 3 . 01 of the PHP license , |
2005-06-14 21:32:29 +00:00
| that is bundled with this package in the file LICENSE , and is |
| available through the world - wide - web at the following url : |
2006-01-01 12:26:08 +00:00
| http : //www.php.net/license/3_01.txt |
2005-06-14 21:32:29 +00:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2005-06-17 14:54:00 +00:00
| Authors : Derick Rethans < derick @ derickrethans . nl > |
2005-06-14 21:32:29 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* /
/* $Id$ */
2005-06-29 19:07:06 +00:00
# include " timelib.h "
2005-06-16 23:12:10 +00:00
2005-06-14 21:32:29 +00:00
# include < stdio . h >
2005-12-02 13:15:58 +00:00
# include < ctype . h >
2005-06-16 23:12:10 +00:00
# ifdef HAVE_STDLIB_H
# include < stdlib . h >
# endif
# ifdef HAVE_STRING_H
2005-06-14 21:32:29 +00:00
# include < string . h >
2005-06-16 23:12:10 +00:00
# else
# include < strings . h >
# endif
2005-06-15 09:02:28 +00:00
# if defined ( _ MSC_VER )
2005-06-28 18:05:59 +00:00
# define strtoll ( s , f , b ) _ atoi64 ( s )
# elif ! defined ( HAVE_STRTOLL )
# if defined ( HAVE_ATOLL )
# define strtoll ( s , f , b ) atoll ( s )
# else
# define strtoll ( s , f , b ) strtol ( s , f , b )
# endif
2005-06-15 00:11:29 +00:00
# endif
2007-07-12 18:58:00 +00:00
# define TIMELIB_UNSET - 99999
2005-06-14 21:32:29 +00:00
# define TIMELIB_SECOND 1
# define TIMELIB_MINUTE 2
# define TIMELIB_HOUR 3
# define TIMELIB_DAY 4
# define TIMELIB_MONTH 5
# define TIMELIB_YEAR 6
# define TIMELIB_WEEKDAY 7
2006-05-14 17:36:05 +00:00
# define TIMELIB_SPECIAL 8
2005-06-14 21:32:29 +00:00
# define EOI 257
# define TIME 258
# define DATE 259
# define TIMELIB_XMLRPC_SOAP 260
# define TIMELIB_TIME12 261
# define TIMELIB_TIME24 262
# define TIMELIB_GNU_NOCOLON 263
# define TIMELIB_GNU_NOCOLON_TZ 264
# define TIMELIB_ISO_NOCOLON 265
# define TIMELIB_AMERICAN 266
# define TIMELIB_ISO_DATE 267
# define TIMELIB_DATE_FULL 268
# define TIMELIB_DATE_TEXT 269
# define TIMELIB_DATE_NOCOLON 270
# define TIMELIB_PG_YEARDAY 271
# define TIMELIB_PG_TEXT 272
# define TIMELIB_PG_REVERSE 273
# define TIMELIB_CLF 274
# define TIMELIB_DATE_NO_DAY 275
# define TIMELIB_SHORTDATE_WITH_TIME 276
# define TIMELIB_DATE_FULL_POINTED 277
# define TIMELIB_TIME24_WITH_ZONE 278
# define TIMELIB_ISO_WEEK 279
2008-02-03 14:15:07 +00:00
# define TIMELIB_LF_DAY_OF_MONTH 280
2008-05-04 20:52:56 +00:00
# define TIMELIB_WEEK_DAY_OF_MONTH 281
2005-06-14 21:32:29 +00:00
# define TIMELIB_TIMEZONE 300
# define TIMELIB_AGO 301
# define TIMELIB_RELATIVE 310
2005-06-15 11:01:07 +00:00
# define TIMELIB_ERROR 999
2005-06-14 21:32:29 +00:00
typedef unsigned char uchar ;
# define BSIZE 8192
# define YYCTYPE uchar
# define YYCURSOR cursor
# define YYLIMIT s - > lim
# define YYMARKER s - > ptr
# define YYFILL ( n ) return EOI ;
# define RET ( i ) { s - > cur = cursor ; return i ; }
# define timelib_string_free free
2006-04-11 18:03:52 +00:00
# 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 ; } }
2005-06-14 21:32:29 +00:00
# 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 ; }
2006-04-11 18:03:52 +00:00
# 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 ; } }
2005-06-14 21:32:29 +00:00
# define TIMELIB_UNHAVE_DATE () { s - > time - > have_date = 0 ; s - > time - > d = 0 ; s - > time - > m = 0 ; s - > time - > y = 0 ; }
2008-04-27 19:14:33 +00:00
# define TIMELIB_HAVE_RELATIVE () { s - > time - > have_relative = 1 ; }
2008-05-01 16:15:45 +00:00
# define TIMELIB_HAVE_WEEKDAY_RELATIVE () { s - > time - > have_relative = 1 ; s - > time - > relative . have_weekday_relative = 1 ; }
# define TIMELIB_HAVE_SPECIAL_RELATIVE () { s - > time - > have_relative = 1 ; s - > time - > relative . have_special_relative = 1 ; }
2008-01-29 20:10:24 +00:00
# define TIMELIB_HAVE_TZ () { s - > cur = cursor ; if ( s - > time - > have_zone ) { s - > time - > have_zone > 1 ? add_error ( s , " Double timezone specification " ) : add_warning ( s , " Double timezone specification " ) ; timelib_string_free ( str ) ; s - > time - > have_zone + + ; return TIMELIB_ERROR ; } else { s - > time - > have_zone + + ; } }
2005-06-14 21:32:29 +00:00
# define TIMELIB_INIT s - > cur = cursor ; str = timelib_string ( s ) ; ptr = str
# define TIMELIB_DEINIT timelib_string_free ( str )
# define TIMELIB_ADJUST_RELATIVE_WEEKDAY () if ( in - > time . have_weekday_relative && ( in . rel . d > 0 ) ) { in . rel . d - = 7 ; }
# define TIMELIB_PROCESS_YEAR ( x ) { \
2007-07-12 18:58:00 +00:00
if ( ( x ) = = TIMELIB_UNSET ) { \
2005-06-14 21:32:29 +00:00
/* (x) = 0; */ \
} else if ( ( x ) < 100 ) { \
if ( ( x ) < 70 ) { \
( x ) + = 2000 ; \
} else { \
( x ) + = 1900 ; \
} \
} \
}
# ifdef DEBUG_PARSER
# define DEBUG_OUTPUT ( s ) printf ( " %s \n " , s ) ;
# define YYDEBUG ( s , c ) { if ( s != - 1 ) { printf ( " state: %d " , s ) ; printf ( " [%c] \n " , c ) ; } }
# else
# define DEBUG_OUTPUT ( s )
# define YYDEBUG ( s , c )
# endif
# include " timelib_structs.h "
typedef struct timelib_elems {
2005-06-15 07:23:27 +00:00
unsigned int c ; /* Number of elements */
char * * v ; /* Values */
2005-06-14 21:32:29 +00:00
} timelib_elems ;
typedef struct Scanner {
2005-06-15 07:23:27 +00:00
int fd ;
uchar * lim , * str , * ptr , * cur , * tok , * pos ;
unsigned int line , len ;
2006-04-11 18:03:52 +00:00
struct timelib_error_container * errors ;
2005-06-14 21:32:29 +00:00
struct timelib_time * time ;
2006-05-14 17:36:05 +00:00
const timelib_tzdb * tzdb ;
2005-06-14 21:32:29 +00:00
} Scanner ;
typedef struct _ timelib_lookup_table {
const char * name ;
int type ;
int value ;
} timelib_lookup_table ;
typedef struct _ timelib_relunit {
const char * name ;
int unit ;
int multiplier ;
} timelib_relunit ;
2005-06-15 11:01:07 +00:00
# define HOUR ( a ) ( int ) ( a * 60 )
2005-06-14 21:32:29 +00:00
/* The timezone table. */
2006-05-14 17:36:05 +00:00
const static timelib_tz_lookup_table timelib_timezone_lookup [] = {
2005-10-01 15:04:07 +00:00
# include " timezonemap.h "
{ NULL , 0 , 0 , NULL } ,
} ;
2006-05-14 17:36:05 +00:00
const static timelib_tz_lookup_table timelib_timezone_fallbackmap [] = {
2005-10-01 15:04:07 +00:00
# include " fallbackmap.h "
{ NULL , 0 , 0 , NULL } ,
2005-06-14 21:32:29 +00:00
} ;
2006-05-14 17:36:05 +00:00
const static timelib_tz_lookup_table timelib_timezone_utc [] = {
2005-12-19 13:00:37 +00:00
{ " utc " , 0 , 0 , " UTC " } ,
} ;
2005-06-14 21:32:29 +00:00
static timelib_relunit const timelib_relunit_lookup [] = {
{ " sec " , TIMELIB_SECOND , 1 } ,
{ " secs " , TIMELIB_SECOND , 1 } ,
{ " second " , TIMELIB_SECOND , 1 } ,
{ " seconds " , TIMELIB_SECOND , 1 } ,
{ " min " , TIMELIB_MINUTE , 1 } ,
{ " mins " , TIMELIB_MINUTE , 1 } ,
{ " minute " , TIMELIB_MINUTE , 1 } ,
{ " minutes " , TIMELIB_MINUTE , 1 } ,
{ " hour " , TIMELIB_HOUR , 1 } ,
{ " hours " , TIMELIB_HOUR , 1 } ,
{ " day " , TIMELIB_DAY , 1 } ,
{ " days " , TIMELIB_DAY , 1 } ,
{ " week " , TIMELIB_DAY , 7 } ,
{ " weeks " , TIMELIB_DAY , 7 } ,
{ " fortnight " , TIMELIB_DAY , 14 } ,
{ " fortnights " , TIMELIB_DAY , 14 } ,
{ " forthnight " , TIMELIB_DAY , 14 } ,
{ " forthnights " , TIMELIB_DAY , 14 } ,
{ " month " , TIMELIB_MONTH , 1 } ,
{ " months " , TIMELIB_MONTH , 1 } ,
{ " year " , TIMELIB_YEAR , 1 } ,
{ " years " , TIMELIB_YEAR , 1 } ,
{ " monday " , TIMELIB_WEEKDAY , 1 } ,
2005-12-11 22:35:40 +00:00
{ " mon " , TIMELIB_WEEKDAY , 1 } ,
2005-06-14 21:32:29 +00:00
{ " tuesday " , TIMELIB_WEEKDAY , 2 } ,
2005-12-11 22:35:40 +00:00
{ " tue " , TIMELIB_WEEKDAY , 2 } ,
2005-06-14 21:32:29 +00:00
{ " wednesday " , TIMELIB_WEEKDAY , 3 } ,
2005-12-11 22:35:40 +00:00
{ " wed " , TIMELIB_WEEKDAY , 3 } ,
2005-06-14 21:32:29 +00:00
{ " thursday " , TIMELIB_WEEKDAY , 4 } ,
2005-12-11 22:35:40 +00:00
{ " thu " , TIMELIB_WEEKDAY , 4 } ,
2005-06-14 21:32:29 +00:00
{ " friday " , TIMELIB_WEEKDAY , 5 } ,
2005-12-11 22:35:40 +00:00
{ " fri " , TIMELIB_WEEKDAY , 5 } ,
2005-06-14 21:32:29 +00:00
{ " saturday " , TIMELIB_WEEKDAY , 6 } ,
2005-12-11 22:35:40 +00:00
{ " sat " , TIMELIB_WEEKDAY , 6 } ,
2005-06-14 21:32:29 +00:00
{ " sunday " , TIMELIB_WEEKDAY , 0 } ,
2005-12-11 22:35:40 +00:00
{ " sun " , TIMELIB_WEEKDAY , 0 } ,
2005-06-14 21:32:29 +00:00
2006-05-14 17:36:05 +00:00
{ " weekday " , TIMELIB_SPECIAL , TIMELIB_SPECIAL_WEEKDAY } ,
{ " weekdays " , TIMELIB_SPECIAL , TIMELIB_SPECIAL_WEEKDAY } ,
2005-06-14 21:32:29 +00:00
{ NULL , 0 , 0 }
} ;
/* The relative text table. */
static timelib_lookup_table const timelib_reltext_lookup [] = {
{ " first " , 0 , 1 } ,
{ " next " , 0 , 1 } ,
{ " second " , 0 , 2 } ,
{ " third " , 0 , 3 } ,
{ " fourth " , 0 , 4 } ,
{ " fifth " , 0 , 5 } ,
{ " sixth " , 0 , 6 } ,
{ " seventh " , 0 , 7 } ,
{ " eight " , 0 , 8 } ,
{ " ninth " , 0 , 9 } ,
{ " tenth " , 0 , 10 } ,
{ " eleventh " , 0 , 11 } ,
{ " twelfth " , 0 , 12 } ,
{ " last " , 0 , - 1 } ,
{ " previous " , 0 , - 1 } ,
2005-10-19 21:08:35 +00:00
{ " this " , 1 , 0 } ,
{ NULL , 1 , 0 }
2005-06-14 21:32:29 +00:00
} ;
/* The month table. */
static timelib_lookup_table const timelib_month_lookup [] = {
{ " jan " , 0 , 1 } ,
{ " feb " , 0 , 2 } ,
{ " mar " , 0 , 3 } ,
{ " apr " , 0 , 4 } ,
{ " may " , 0 , 5 } ,
{ " jun " , 0 , 6 } ,
{ " jul " , 0 , 7 } ,
{ " aug " , 0 , 8 } ,
{ " sep " , 0 , 9 } ,
{ " sept " , 0 , 9 } ,
{ " oct " , 0 , 10 } ,
{ " nov " , 0 , 11 } ,
{ " dec " , 0 , 12 } ,
{ " i " , 0 , 1 } ,
{ " ii " , 0 , 2 } ,
{ " iii " , 0 , 3 } ,
{ " iv " , 0 , 4 } ,
{ " v " , 0 , 5 } ,
{ " vi " , 0 , 6 } ,
{ " vii " , 0 , 7 } ,
{ " viii " , 0 , 8 } ,
{ " ix " , 0 , 9 } ,
{ " x " , 0 , 10 } ,
{ " xi " , 0 , 11 } ,
{ " xii " , 0 , 12 } ,
{ " january " , 0 , 1 } ,
{ " february " , 0 , 2 } ,
{ " march " , 0 , 3 } ,
{ " april " , 0 , 4 } ,
{ " may " , 0 , 5 } ,
{ " june " , 0 , 6 } ,
{ " july " , 0 , 7 } ,
{ " august " , 0 , 8 } ,
{ " september " , 0 , 9 } ,
{ " october " , 0 , 10 } ,
{ " november " , 0 , 11 } ,
{ " december " , 0 , 12 } ,
{ NULL , 0 , 0 }
} ;
# if 0
static char * timelib_ltrim ( char * s )
{
char * ptr = s ;
2006-02-27 19:41:33 +00:00
while ( ptr [ 0 ] = = ' ' | | ptr [ 0 ] = = '\t' ) {
2005-06-14 21:32:29 +00:00
ptr + + ;
}
return ptr ;
}
# endif
# if 0
uchar * fill ( Scanner * s , uchar * cursor ) {
if ( ! s - > eof ) {
2005-06-15 00:11:29 +00:00
unsigned int cnt = s - > tok - s - > bot ;
2005-06-14 21:32:29 +00:00
if ( cnt ) {
memcpy ( s - > bot , s - > tok , s - > lim - s - > tok ) ;
s - > tok = s - > bot ;
s - > ptr - = cnt ;
cursor - = cnt ;
s - > pos - = cnt ;
s - > lim - = cnt ;
}
if ( ( s - > top - s - > lim ) < BSIZE ) {
uchar * buf = ( uchar * ) malloc ( ( ( s - > lim - s - > bot ) + BSIZE ) * sizeof ( uchar ) ) ;
memcpy ( buf , s - > tok , s - > lim - s - > tok ) ;
s - > tok = buf ;
s - > ptr = & buf [ s - > ptr - s - > bot ] ;
cursor = & buf [ cursor - s - > bot ] ;
s - > pos = & buf [ s - > pos - s - > bot ] ;
s - > lim = & buf [ s - > lim - s - > bot ] ;
s - > top = & s - > lim [ BSIZE ] ;
free ( s - > bot ) ;
s - > bot = buf ;
}
if ( ( cnt = read ( s - > fd , ( char * ) s - > lim , BSIZE ) ) != BSIZE ) {
s - > eof = & s - > lim [ cnt ] ; * ( s - > eof ) + + = '\n' ;
}
s - > lim + = cnt ;
}
return cursor ;
}
# endif
2006-04-11 18:03:52 +00:00
static void add_warning ( Scanner * s , char * error )
{
s - > errors - > warning_count + + ;
s - > errors - > warning_messages = realloc ( s - > errors - > warning_messages , s - > errors - > warning_count * sizeof ( timelib_error_message ) ) ;
s - > errors - > warning_messages [ s - > errors - > warning_count - 1 ] . position = s - > tok ? s - > tok - s - > str : 0 ;
s - > errors - > warning_messages [ s - > errors - > warning_count - 1 ] . character = s - > tok ? * s - > tok : 0 ;
s - > errors - > warning_messages [ s - > errors - > warning_count - 1 ] . message = strdup ( error ) ;
}
static void add_error ( Scanner * s , char * error )
{
s - > errors - > error_count + + ;
s - > errors - > error_messages = realloc ( s - > errors - > error_messages , s - > errors - > error_count * sizeof ( timelib_error_message ) ) ;
s - > errors - > error_messages [ s - > errors - > error_count - 1 ] . position = s - > tok ? s - > tok - s - > str : 0 ;
s - > errors - > error_messages [ s - > errors - > error_count - 1 ] . character = s - > tok ? * s - > tok : 0 ;
s - > errors - > error_messages [ s - > errors - > error_count - 1 ] . message = strdup ( error ) ;
}
2008-01-13 15:16:02 +00:00
static void add_pbf_warning ( Scanner * s , char * error , char * sptr , char * cptr )
{
s - > errors - > warning_count + + ;
s - > errors - > warning_messages = realloc ( s - > errors - > warning_messages , s - > errors - > warning_count * sizeof ( timelib_error_message ) ) ;
s - > errors - > warning_messages [ s - > errors - > warning_count - 1 ] . position = cptr - sptr ;
s - > errors - > warning_messages [ s - > errors - > warning_count - 1 ] . character = * cptr ;
s - > errors - > warning_messages [ s - > errors - > warning_count - 1 ] . message = strdup ( error ) ;
}
static void add_pbf_error ( Scanner * s , char * error , char * sptr , char * cptr )
{
s - > errors - > error_count + + ;
s - > errors - > error_messages = realloc ( s - > errors - > error_messages , s - > errors - > error_count * sizeof ( timelib_error_message ) ) ;
s - > errors - > error_messages [ s - > errors - > error_count - 1 ] . position = cptr - sptr ;
s - > errors - > error_messages [ s - > errors - > error_count - 1 ] . character = * cptr ;
s - > errors - > error_messages [ s - > errors - > error_count - 1 ] . message = strdup ( error ) ;
}
2005-06-15 11:01:07 +00:00
static timelib_sll timelib_meridian ( char * * ptr , timelib_sll h )
2005-06-14 21:32:29 +00:00
{
2005-06-15 11:01:07 +00:00
timelib_sll retval = 0 ;
2005-06-14 21:32:29 +00:00
while ( ! strchr ( " AaPp " , * * ptr ) ) {
+ + * ptr ;
}
if ( * * ptr = = 'a' | | * * ptr = = 'A' ) {
if ( h = = 12 ) {
retval = - 12 ;
}
} else if ( h != 12 ) {
retval = 12 ;
}
+ + * ptr ;
if ( * * ptr = = '.' ) {
* ptr + = 3 ;
} else {
+ + * ptr ;
}
return retval ;
}
2008-01-13 15:16:02 +00:00
static timelib_sll timelib_meridian_with_check ( char * * ptr , timelib_sll h )
{
timelib_sll retval = 0 ;
while ( ! strchr ( " AaPp " , * * ptr ) ) {
+ + * ptr ;
}
if ( * * ptr = = 'a' | | * * ptr = = 'A' ) {
if ( h = = 12 ) {
retval = - 12 ;
}
} else if ( h != 12 ) {
retval = 12 ;
}
+ + * ptr ;
if ( * * ptr = = '.' ) {
+ + * ptr ;
if ( * * ptr != 'm' && * * ptr != 'M' ) {
return TIMELIB_UNSET ;
}
+ + * ptr ;
if ( * * ptr != '.' ) {
return TIMELIB_UNSET ;
}
+ + * ptr ;
} else if ( * * ptr = = 'm' | | * * ptr = = 'M' ) {
+ + * ptr ;
} else {
return TIMELIB_UNSET ;
}
return retval ;
}
2005-06-14 21:32:29 +00:00
static char * timelib_string ( Scanner * s )
{
char * tmp = calloc ( 1 , s - > cur - s - > tok + 1 ) ;
memcpy ( tmp , s - > tok , s - > cur - s - > tok ) ;
return tmp ;
}
static timelib_sll timelib_get_nr ( char * * ptr , int max_length )
{
char * begin , * end , * str ;
2007-07-12 18:58:00 +00:00
timelib_sll tmp_nr = TIMELIB_UNSET ;
2005-06-14 21:32:29 +00:00
int len = 0 ;
while ( ( * * ptr < '0' ) | | ( * * ptr > '9' ) ) {
if ( * * ptr = = ' \ 0' ) {
2007-07-12 18:58:00 +00:00
return TIMELIB_UNSET ;
2005-06-14 21:32:29 +00:00
}
+ + * ptr ;
}
begin = * ptr ;
while ( ( * * ptr > = '0' ) && ( * * ptr < = '9' ) && len < max_length ) {
+ + * ptr ;
+ + len ;
}
end = * ptr ;
str = calloc ( 1 , end - begin + 1 ) ;
memcpy ( str , begin , end - begin ) ;
tmp_nr = strtoll ( str , NULL , 10 ) ;
free ( str ) ;
return tmp_nr ;
}
2005-12-11 22:35:40 +00:00
static void timelib_skip_day_suffix ( char * * ptr )
{
if ( isspace ( * * ptr ) ) {
return ;
}
if ( ! strncasecmp ( * ptr , " nd " , 2 ) | | ! strncasecmp ( * ptr , " rd " , 2 ) | | ! strncasecmp ( * ptr , " st " , 2 ) | | ! strncasecmp ( * ptr , " th " , 2 ) ) {
* ptr + = 2 ;
}
}
2005-06-15 11:01:07 +00:00
static double timelib_get_frac_nr ( char * * ptr , int max_length )
2005-06-14 21:32:29 +00:00
{
char * begin , * end , * str ;
2007-07-12 18:58:00 +00:00
double tmp_nr = TIMELIB_UNSET ;
2005-06-14 21:32:29 +00:00
int len = 0 ;
2008-03-13 15:54:25 +00:00
while ( ( * * ptr != '.' ) && ( * * ptr != ':' ) && ( ( * * ptr < '0' ) | | ( * * ptr > '9' ) ) ) {
2005-06-14 21:32:29 +00:00
if ( * * ptr = = ' \ 0' ) {
2007-07-12 18:58:00 +00:00
return TIMELIB_UNSET ;
2005-06-14 21:32:29 +00:00
}
+ + * ptr ;
}
begin = * ptr ;
2008-03-13 15:54:25 +00:00
while ( ( ( * * ptr = = '.' ) | | ( * * ptr = = ':' ) | | ( ( * * ptr > = '0' ) && ( * * ptr < = '9' ) ) ) && len < max_length ) {
2005-06-14 21:32:29 +00:00
+ + * ptr ;
+ + len ;
}
end = * ptr ;
str = calloc ( 1 , end - begin + 1 ) ;
memcpy ( str , begin , end - begin ) ;
2008-03-13 15:54:25 +00:00
if ( str [ 0 ] = = ':' ) {
str [ 0 ] = '.' ;
}
2005-06-14 21:32:29 +00:00
tmp_nr = strtod ( str , NULL ) ;
free ( str ) ;
return tmp_nr ;
}
static timelib_ull timelib_get_unsigned_nr ( char * * ptr , int max_length )
{
timelib_ull dir = 1 ;
while ( ( ( * * ptr < '0' ) | | ( * * ptr > '9' ) ) && ( * * ptr != '+' ) && ( * * ptr != '-' ) ) {
if ( * * ptr = = ' \ 0' ) {
2007-07-12 18:58:00 +00:00
return TIMELIB_UNSET ;
2005-06-14 21:32:29 +00:00
}
+ + * ptr ;
}
2007-04-11 14:37:42 +00:00
while ( * * ptr = = '+' | | * * ptr = = '-' )
{
if ( * * ptr = = '-' ) {
dir * = - 1 ;
}
2005-06-14 21:32:29 +00:00
+ + * ptr ;
}
return dir * timelib_get_nr ( ptr , max_length ) ;
}
static long timelib_parse_tz_cor ( char * * ptr )
{
char * begin = * ptr , * end ;
long tmp ;
while ( * * ptr != ' \ 0' ) {
+ + * ptr ;
}
end = * ptr ;
switch ( end - begin ) {
case 1 :
case 2 :
return HOUR ( strtol ( begin , NULL , 10 ) ) ;
break ;
case 3 :
case 4 :
2006-01-04 21:31:35 +00:00
if ( begin [ 1 ] = = ':' ) {
tmp = HOUR ( strtol ( begin , NULL , 10 ) ) + strtol ( begin + 2 , NULL , 10 ) ;
return tmp ;
} else if ( begin [ 2 ] = = ':' ) {
tmp = HOUR ( strtol ( begin , NULL , 10 ) ) + strtol ( begin + 3 , NULL , 10 ) ;
return tmp ;
} else {
tmp = strtol ( begin , NULL , 10 ) ;
return HOUR ( tmp / 100 ) + tmp % 100 ;
}
2005-06-14 21:32:29 +00:00
case 5 :
2006-01-04 21:31:35 +00:00
tmp = HOUR ( strtol ( begin , NULL , 10 ) ) + strtol ( begin + 3 , NULL , 10 ) ;
2005-06-14 21:32:29 +00:00
return tmp ;
}
return 0 ;
}
2005-10-19 21:08:35 +00:00
static timelib_sll timelib_lookup_relative_text ( char * * ptr , int * behavior )
2005-06-14 21:32:29 +00:00
{
char * word ;
char * begin = * ptr , * end ;
2005-06-16 13:30:26 +00:00
timelib_sll value = 0 ;
2005-06-14 21:32:29 +00:00
const timelib_lookup_table * tp ;
while ( ( * * ptr > = 'A' && * * ptr < = 'Z' ) | | ( * * ptr > = 'a' && * * ptr < = 'z' ) ) {
+ + * ptr ;
}
end = * ptr ;
word = calloc ( 1 , end - begin + 1 ) ;
memcpy ( word , begin , end - begin ) ;
for ( tp = timelib_reltext_lookup ; tp - > name ; tp + + ) {
if ( strcasecmp ( word , tp - > name ) = = 0 ) {
value = tp - > value ;
2005-10-19 21:08:35 +00:00
* behavior = tp - > type ;
2005-06-14 21:32:29 +00:00
}
}
free ( word ) ;
return value ;
}
2005-10-19 21:08:35 +00:00
static timelib_sll timelib_get_relative_text ( char * * ptr , int * behavior )
2005-06-14 21:32:29 +00:00
{
2006-02-27 19:41:33 +00:00
while ( * * ptr = = ' ' | | * * ptr = = '\t' | | * * ptr = = '-' | | * * ptr = = '/' ) {
2005-06-14 21:32:29 +00:00
+ + * ptr ;
}
2005-10-19 21:08:35 +00:00
return timelib_lookup_relative_text ( ptr , behavior ) ;
2005-06-14 21:32:29 +00:00
}
static long timelib_lookup_month ( char * * ptr )
{
char * word ;
char * begin = * ptr , * end ;
long value = 0 ;
const timelib_lookup_table * tp ;
while ( ( * * ptr > = 'A' && * * ptr < = 'Z' ) | | ( * * ptr > = 'a' && * * ptr < = 'z' ) ) {
+ + * ptr ;
}
end = * ptr ;
word = calloc ( 1 , end - begin + 1 ) ;
memcpy ( word , begin , end - begin ) ;
for ( tp = timelib_month_lookup ; tp - > name ; tp + + ) {
if ( strcasecmp ( word , tp - > name ) = = 0 ) {
value = tp - > value ;
}
}
free ( word ) ;
return value ;
}
static long timelib_get_month ( char * * ptr )
{
2006-02-27 19:41:33 +00:00
while ( * * ptr = = ' ' | | * * ptr = = '\t' | | * * ptr = = '-' | | * * ptr = = '.' | | * * ptr = = '/' ) {
2005-06-14 21:32:29 +00:00
+ + * ptr ;
}
return timelib_lookup_month ( ptr ) ;
}
static void timelib_eat_spaces ( char * * ptr )
{
2006-02-27 19:41:33 +00:00
while ( * * ptr = = ' ' | | * * ptr = = '\t' ) {
2005-06-14 21:32:29 +00:00
+ + * ptr ;
}
}
2008-02-17 18:17:45 +00:00
static void timelib_eat_until_separator ( char * * ptr )
2008-01-13 15:16:02 +00:00
{
while ( strchr ( " \t .,:;/-0123456789 " , * * ptr ) = = NULL ) {
+ + * ptr ;
}
}
2005-06-14 21:32:29 +00:00
static const timelib_relunit * timelib_lookup_relunit ( char * * ptr )
{
char * word ;
char * begin = * ptr , * end ;
const timelib_relunit * tp , * value = NULL ;
2008-07-08 20:25:28 +00:00
while ( * * ptr != ' \ 0' && * * ptr != ' ' && * * ptr != ',' && * * ptr != '\t' ) {
2005-06-14 21:32:29 +00:00
+ + * ptr ;
}
end = * ptr ;
word = calloc ( 1 , end - begin + 1 ) ;
memcpy ( word , begin , end - begin ) ;
for ( tp = timelib_relunit_lookup ; tp - > name ; tp + + ) {
if ( strcasecmp ( word , tp - > name ) = = 0 ) {
value = tp ;
break ;
}
}
free ( word ) ;
return value ;
}
2005-10-19 21:08:35 +00:00
static void timelib_set_relative ( char * * ptr , timelib_sll amount , int behavior , Scanner * s )
2005-06-14 21:32:29 +00:00
{
const timelib_relunit * relunit ;
2006-12-11 05:04:36 +00:00
if ( ! ( relunit = timelib_lookup_relunit ( ptr ) ) ) {
return ;
}
2005-06-14 21:32:29 +00:00
switch ( relunit - > unit ) {
case TIMELIB_SECOND : s - > time - > relative . s + = amount * relunit - > multiplier ; break ;
case TIMELIB_MINUTE : s - > time - > relative . i + = amount * relunit - > multiplier ; break ;
case TIMELIB_HOUR : s - > time - > relative . h + = amount * relunit - > multiplier ; break ;
case TIMELIB_DAY : s - > time - > relative . d + = amount * relunit - > multiplier ; break ;
case TIMELIB_MONTH : s - > time - > relative . m + = amount * relunit - > multiplier ; break ;
case TIMELIB_YEAR : s - > time - > relative . y + = amount * relunit - > multiplier ; break ;
case TIMELIB_WEEKDAY :
TIMELIB_HAVE_WEEKDAY_RELATIVE () ;
TIMELIB_UNHAVE_TIME () ;
s - > time - > relative . d + = ( amount > 0 ? amount - 1 : amount ) * 7 ;
s - > time - > relative . weekday = relunit - > multiplier ;
2005-10-19 21:08:35 +00:00
s - > time - > relative . weekday_behavior = behavior ;
2005-06-14 21:32:29 +00:00
break ;
2006-05-14 17:36:05 +00:00
case TIMELIB_SPECIAL :
TIMELIB_HAVE_SPECIAL_RELATIVE () ;
TIMELIB_UNHAVE_TIME () ;
2008-05-01 16:15:45 +00:00
s - > time - > relative . special . type = relunit - > multiplier ;
s - > time - > relative . special . amount = amount ;
2005-06-14 21:32:29 +00:00
}
}
2006-05-14 17:36:05 +00:00
const static timelib_tz_lookup_table * zone_search ( const char * word , long gmtoffset , int isdst )
2005-06-28 17:56:47 +00:00
{
2005-10-01 15:04:07 +00:00
int first_found = 0 ;
2006-05-14 17:36:05 +00:00
const timelib_tz_lookup_table * tp , * first_found_elem = NULL ;
const timelib_tz_lookup_table * fmp ;
2005-12-19 13:00:37 +00:00
2006-01-04 21:31:35 +00:00
if ( strcasecmp ( " utc " , word ) = = 0 | | strcasecmp ( " gmt " , word ) = = 0 ) {
2005-12-19 13:00:37 +00:00
return timelib_timezone_utc ;
2005-12-18 16:15:45 +00:00
}
2005-12-19 13:00:37 +00:00
2005-10-01 15:04:07 +00:00
for ( tp = timelib_timezone_lookup ; tp - > name ; tp + + ) {
if ( strcasecmp ( word , tp - > name ) = = 0 ) {
if ( ! first_found ) {
first_found = 1 ;
first_found_elem = tp ;
if ( gmtoffset = = - 1 ) {
return tp ;
}
}
if ( tp - > gmtoffset = = gmtoffset ) {
return tp ;
}
}
}
if ( first_found ) {
return first_found_elem ;
}
2005-12-19 13:00:37 +00:00
2005-10-01 15:04:07 +00:00
/* Still didn't find anything, let's find the zone solely based on
* offset / isdst then * /
for ( fmp = timelib_timezone_fallbackmap ; fmp - > name ; fmp + + ) {
if ( ( fmp - > gmtoffset * 3600 ) = = gmtoffset && fmp - > type = = isdst ) {
return fmp ;
}
2005-06-28 17:56:47 +00:00
}
2005-10-01 15:04:07 +00:00
return NULL ;
2005-06-28 17:56:47 +00:00
}
2005-07-03 21:38:54 +00:00
static long timelib_lookup_zone ( char * * ptr , int * dst , char * * tz_abbr , int * found )
2005-06-14 21:32:29 +00:00
{
char * word ;
char * begin = * ptr , * end ;
long value = 0 ;
2006-05-14 17:36:05 +00:00
const timelib_tz_lookup_table * tp ;
2005-06-14 21:32:29 +00:00
2008-02-25 18:26:33 +00:00
while ( * * ptr != ' \ 0' && * * ptr != ')' && * * ptr != ' ' ) {
2005-06-14 21:32:29 +00:00
+ + * ptr ;
}
end = * ptr ;
word = calloc ( 1 , end - begin + 1 ) ;
memcpy ( word , begin , end - begin ) ;
2005-10-01 15:04:07 +00:00
if ( ( tp = zone_search ( word , - 1 , 0 ) ) ) {
value = - tp - > gmtoffset / 60 ;
2005-06-28 17:56:47 +00:00
* dst = tp - > type ;
2005-10-01 15:04:07 +00:00
value + = tp - > type * 60 ;
2005-07-03 21:38:54 +00:00
* found = 1 ;
} else {
* found = 0 ;
2005-06-14 21:32:29 +00:00
}
* tz_abbr = word ;
return value ;
}
2006-05-14 17:36:05 +00:00
static long timelib_get_zone ( char * * ptr , int * dst , timelib_time * t , int * tz_not_found , const timelib_tzdb * tzdb )
2005-06-14 21:32:29 +00:00
{
timelib_tzinfo * res ;
2005-11-17 13:04:31 +00:00
long retval = 0 ;
2005-06-14 21:32:29 +00:00
2005-07-03 21:38:54 +00:00
* tz_not_found = 0 ;
2006-02-27 19:41:33 +00:00
while ( * * ptr = = ' ' | | * * ptr = = '\t' | | * * ptr = = '(' ) {
2005-06-14 21:32:29 +00:00
+ + * ptr ;
}
2008-01-29 20:14:18 +00:00
if ( ( * ptr ) [ 0 ] = = 'G' && ( * ptr ) [ 1 ] = = 'M' && ( * ptr ) [ 2 ] = = 'T' && ( ( * ptr ) [ 3 ] = = '+' | | ( * ptr ) [ 3 ] = = '-' ) ) {
2008-01-29 20:10:24 +00:00
* ptr + = 3 ;
}
2005-06-14 21:32:29 +00:00
if ( * * ptr = = '+' ) {
+ + * ptr ;
t - > is_localtime = 1 ;
t - > zone_type = TIMELIB_ZONETYPE_OFFSET ;
2005-07-03 21:38:54 +00:00
* tz_not_found = 0 ;
2005-08-09 21:10:22 +00:00
t - > dst = 0 ;
2005-06-14 21:32:29 +00:00
2005-11-17 13:04:31 +00:00
retval = - 1 * timelib_parse_tz_cor ( ptr ) ;
2005-06-14 21:32:29 +00:00
} else if ( * * ptr = = '-' ) {
+ + * ptr ;
t - > is_localtime = 1 ;
t - > zone_type = TIMELIB_ZONETYPE_OFFSET ;
2005-07-03 21:38:54 +00:00
* tz_not_found = 0 ;
2005-08-09 21:10:22 +00:00
t - > dst = 0 ;
2005-06-14 21:32:29 +00:00
2005-11-17 13:04:31 +00:00
retval = timelib_parse_tz_cor ( ptr ) ;
2005-06-14 21:32:29 +00:00
} else {
2005-07-03 21:38:54 +00:00
int found = 0 ;
2005-06-14 21:32:29 +00:00
long offset ;
2005-07-03 21:38:54 +00:00
char * tz_abbr ;
2005-06-14 21:32:29 +00:00
t - > is_localtime = 1 ;
2005-11-17 13:04:31 +00:00
2005-07-03 21:38:54 +00:00
offset = timelib_lookup_zone ( ptr , dst , & tz_abbr , & found ) ;
2006-04-11 18:03:52 +00:00
if ( found ) {
t - > zone_type = TIMELIB_ZONETYPE_ABBR ;
}
2005-07-03 21:38:54 +00:00
# if 0
2005-06-14 21:32:29 +00:00
/* If we found a TimeZone identifier, use it */
if ( tz_name ) {
t - > tz_info = timelib_parse_tzfile ( tz_name ) ;
t - > zone_type = TIMELIB_ZONETYPE_ID ;
}
2005-07-03 21:38:54 +00:00
# endif
2005-06-14 21:32:29 +00:00
/* If we have a TimeZone identifier to start with, use it */
2008-07-16 15:41:01 +00:00
if ( strstr ( tz_abbr , " / " ) | | strcmp ( tz_abbr , " UTC " ) = = 0 ) {
2005-10-03 11:17:28 +00:00
if ( ( res = timelib_parse_tzfile ( tz_abbr , tzdb ) ) != NULL ) {
2005-06-14 21:32:29 +00:00
t - > tz_info = res ;
t - > zone_type = TIMELIB_ZONETYPE_ID ;
2005-07-03 21:38:54 +00:00
found + + ;
2005-06-14 21:32:29 +00:00
}
}
2006-04-11 18:03:52 +00:00
if ( found && t - > zone_type != TIMELIB_ZONETYPE_ID ) {
2005-06-14 21:32:29 +00:00
timelib_time_tz_abbr_update ( t , tz_abbr ) ;
}
free ( tz_abbr ) ;
2005-07-03 21:38:54 +00:00
* tz_not_found = ( found = = 0 ) ;
2005-11-17 13:04:31 +00:00
retval = offset ;
2005-06-14 21:32:29 +00:00
}
2005-11-17 13:04:31 +00:00
while ( * * ptr = = ')' ) {
+ + * ptr ;
}
return retval ;
2005-06-14 21:32:29 +00:00
}
# define timelib_split_free ( arg ) { \
int i ; \
for ( i = 0 ; i < arg . c ; i + + ) { \
free ( arg . v [ i ] ) ; \
} \
if ( arg . v ) { \
free ( arg . v ) ; \
} \
}
static int scan ( Scanner * s )
{
uchar * cursor = s - > cur ;
char * str , * ptr = NULL ;
std :
s - > tok = cursor ;
s - > len = 0 ;
/* !re2c
any = [ \ 000 - \ 377 ] ;
2006-02-27 19:41:33 +00:00
space = [ \ t ] + ;
2005-06-14 21:32:29 +00:00
frac = " . " [ 0 - 9 ] + ;
ago = ' ago' ;
2008-01-17 20:45:08 +00:00
hour24 = [ 01 ] ? [ 0 - 9 ] | " 2 " [ 0 - 4 ] ;
hour24lz = [ 01 ] [ 0 - 9 ] | " 2 " [ 0 - 4 ] ;
2005-06-14 21:32:29 +00:00
hour12 = " 0 " ? [ 1 - 9 ] | " 1 " [ 0 - 2 ] ;
minute = [ 0 - 5 ] ? [ 0 - 9 ] ;
minutelz = [ 0 - 5 ] [ 0 - 9 ] ;
second = minute | " 60 " ;
secondlz = minutelz | " 60 " ;
2006-04-11 18:03:52 +00:00
meridian = ( [ AaPp ] " . " ? [ Mm ] " . " ? ) [ \ 000 \ t ] ;
tz = " ( " ? [ A - Za - z ] { 1 , 6 } " ) " ? | [ A - Z ] [ a - z ] + ( [ _ / ] [ A - Z ] [ a - z ] + ) + ;
2008-01-29 20:10:24 +00:00
tzcorrection = " GMT " ? [ + - ] hour24 " : " ? minute ? ;
2005-06-14 21:32:29 +00:00
2005-12-18 16:06:57 +00:00
daysuf = " st " | " nd " | " rd " | " th " ;
2005-12-11 22:35:40 +00:00
2005-06-14 21:32:29 +00:00
month = " 0 " ? [ 0 - 9 ] | " 1 " [ 0 - 2 ] ;
2008-07-08 18:28:49 +00:00
day = ( ( [ 0 - 2 ] ? [ 0 - 9 ] ) | ( " 3 " [ 01 ] ) ) daysuf ? ;
2005-06-14 21:32:29 +00:00
year = [ 0 - 9 ] { 1 , 4 } ;
year2 = [ 0 - 9 ] { 2 } ;
year4 = [ 0 - 9 ] { 4 } ;
2007-07-12 18:58:00 +00:00
year4withsign = [ + - ] ? [ 0 - 9 ] { 4 } ;
2005-06-14 21:32:29 +00:00
dayofyear = " 00 " [ 1 - 9 ] | " 0 " [ 1 - 9 ] [ 0 - 9 ] | [ 1 - 2 ] [ 0 - 9 ] [ 0 - 9 ] | " 3 " [ 0 - 5 ] [ 0 - 9 ] | " 36 " [ 0 - 6 ] ;
weekofyear = " 0 " [ 1 - 9 ] | [ 1 - 4 ] [ 0 - 9 ] | " 5 " [ 0 - 3 ] ;
2007-07-12 18:58:00 +00:00
monthlz = " 0 " [ 0 - 9 ] | " 1 " [ 0 - 2 ] ;
daylz = " 0 " [ 0 - 9 ] | [ 1 - 2 ] [ 0 - 9 ] | " 3 " [ 01 ] ;
2005-06-14 21:32:29 +00:00
dayfull = ' sunday' | ' monday' | ' tuesday' | ' wednesday' | ' thursday' | ' friday' | ' saturday' ;
dayabbr = ' sun' | ' mon' | ' tue' | ' wed' | ' thu' | ' fri' | ' sat' | ' sun' ;
2006-05-14 17:36:05 +00:00
dayspecial = ' weekday' | ' weekdays' ;
daytext = dayfull | dayabbr | dayspecial ;
2005-06-14 21:32:29 +00:00
monthfull = ' january' | ' february' | ' march' | ' april' | ' may' | ' june' | ' july' | ' august' | ' september' | ' october' | ' november' | ' december' ;
monthabbr = ' jan' | ' feb' | ' mar' | ' apr' | ' may' | ' jun' | ' jul' | ' aug' | ' sep' | ' sept' | ' oct' | ' nov' | ' dec' ;
monthroman = " I " | " II " | " III " | " IV " | " V " | " VI " | " VII " | " VIII " | " IX " | " X " | " XI " | " XII " ;
monthtext = monthfull | monthabbr | monthroman ;
/* Time formats */
2005-10-07 08:09:01 +00:00
timetiny12 = hour12 space ? meridian ;
2005-08-24 13:39:34 +00:00
timeshort12 = hour12 [ : . ] minutelz space ? meridian ;
timelong12 = hour12 [ : . ] minute [ : . ] secondlz space ? meridian ;
2005-06-14 21:32:29 +00:00
2006-04-11 18:03:52 +00:00
timeshort24 = 't' ? hour24 [ : . ] minute ;
timelong24 = 't' ? hour24 [ : . ] minute [ : . ] second ;
iso8601long = 't' ? hour24 [ : . ] minute [ : . ] second frac ;
2005-06-14 21:32:29 +00:00
/* iso8601shorttz = hour24 [:] minutelz space? (tzcorrection | tz); */
2006-04-11 18:03:52 +00:00
iso8601normtz = 't' ? hour24 [ : . ] minute [ : . ] secondlz space ? ( tzcorrection | tz ) ;
2005-06-14 21:32:29 +00:00
/* iso8601longtz = hour24 [:] minute [:] secondlz frac space? (tzcorrection | tz); */
2006-04-11 18:03:52 +00:00
gnunocolon = 't' ? hour24lz minutelz ;
2005-06-14 21:32:29 +00:00
/* gnunocolontz = hour24lz minutelz space? (tzcorrection | tz); */
2006-04-11 18:03:52 +00:00
iso8601nocolon = 't' ? hour24lz minutelz secondlz ;
2005-06-14 21:32:29 +00:00
/* iso8601nocolontz = hour24lz minutelz secondlz space? (tzcorrection | tz); */
/* Date formats */
americanshort = month " / " day ;
american = month " / " day " / " year ;
2005-08-25 09:47:28 +00:00
iso8601dateslash = year4 " / " monthlz " / " daylz " / " ? ;
dateslash = year4 " / " month " / " day ;
2007-07-12 18:58:00 +00:00
iso8601date4 = year4withsign " - " monthlz " - " daylz ;
iso8601date2 = year2 " - " monthlz " - " daylz ;
2006-07-27 13:00:00 +00:00
gnudateshorter = year4 " - " month ;
2005-06-14 21:32:29 +00:00
gnudateshort = year " - " month " - " day ;
2007-07-12 18:58:00 +00:00
pointeddate4 = day [ . \ t - ] month [ . - ] year4 ;
2008-07-08 18:28:49 +00:00
pointeddate2 = day [ . \ t ] month " . " year2 ;
2006-02-27 19:41:33 +00:00
datefull = day ( [ \ t . - ] ) * monthtext ( [ \ t . - ] ) * year ;
datenoday = monthtext ( [ . \ t - ] ) * year4 ;
datenodayrev = year4 ( [ . \ t - ] ) * monthtext ;
2008-07-08 18:28:49 +00:00
datetextual = monthtext ( [ . \ t - ] ) * day [ , . stndrh \ t ] + year ;
2006-02-27 19:41:33 +00:00
datenoyear = monthtext ( [ . \ t - ] ) * day [ , . stndrh \ t ] * ;
datenoyearrev = day ( [ . \ t - ] ) * monthtext ;
2005-06-14 21:32:29 +00:00
datenocolon = year4 monthlz daylz ;
/* Special formats */
2005-12-16 22:36:46 +00:00
soap = year4 " - " monthlz " - " daylz " T " hour24lz " : " minutelz " : " secondlz frac tzcorrection ? ;
2005-06-14 21:32:29 +00:00
xmlrpc = year4 monthlz daylz " T " hour24 " : " minutelz " : " secondlz ;
xmlrpcnocolon = year4 monthlz daylz 't' hour24 minutelz secondlz ;
2006-01-04 21:31:35 +00:00
wddx = year4 " - " month " - " day " T " hour24 " : " minute " : " second ;
2005-06-14 21:32:29 +00:00
pgydotd = year4 " . " ? dayofyear ;
pgtextshort = monthabbr " - " daylz " - " year ;
pgtextreverse = year " - " monthabbr " - " daylz ;
2008-03-13 15:54:25 +00:00
mssqltime = hour12 " : " minutelz " : " secondlz [ : . ] [ 0 - 9 ] + meridian ;
2006-09-06 07:34:51 +00:00
isoweekday = year4 " - " ? " W " weekofyear " - " ? [ 0 - 7 ] ;
isoweek = year4 " - " ? " W " weekofyear ;
2006-02-24 09:44:56 +00:00
exif = year4 " : " monthlz " : " daylz " " hour24lz " : " minutelz " : " secondlz ;
2008-02-03 14:15:07 +00:00
firstdayof = ' first day' ' of ' ? ;
lastdayof = ' last day' ' of ' ? ;
2005-06-14 21:32:29 +00:00
/* Common Log Format: 10 / Oct / 2000:13:55:36 -0700 */
clf = day " / " monthabbr " / " year4 " : " hour24lz " : " minutelz " : " secondlz space tzcorrection ;
/* Timestamp format: @1126396800 */
2006-03-06 21:44:58 +00:00
timestamp = " @ " " - " ? [ 0 - 9 ] + ;
2005-06-14 21:32:29 +00:00
/* To fix some ambiguities */
2006-05-19 14:52:30 +00:00
dateshortwithtimeshort12 = datenoyear timeshort12 ;
dateshortwithtimelong12 = datenoyear timelong12 ;
2005-06-14 21:32:29 +00:00
dateshortwithtimeshort = datenoyear timeshort24 ;
dateshortwithtimelong = datenoyear timelong24 ;
dateshortwithtimelongtz = datenoyear iso8601normtz ;
/*
* Relative regexps
* /
2008-04-27 19:14:33 +00:00
reltextnumber = ' first' | ' second' | ' third' | ' fourth' | ' fifth' | ' sixth' | ' seventh' | ' eight' | ' ninth' | ' tenth' | ' eleventh' | ' twelfth' ;
reltexttext = ' next' | ' last' | ' previous' | ' this' ;
reltextunit = ( ( ' sec' | ' second' | ' min' | ' minute' | ' hour' | ' day' | ' fortnight' | ' forthnight' | ' month' | ' year' ) 's' ? ) | ' weeks' | daytext ;
2005-06-14 21:32:29 +00:00
2007-04-11 14:37:42 +00:00
relnumber = ( [ + - ] * [ \ t ] * [ 0 - 9 ] + ) ;
2008-04-27 19:14:33 +00:00
relative = relnumber space ? ( reltextunit | ' week' ) ;
relativetext = ( reltextnumber | reltexttext ) space reltextunit ;
relativetextweek = reltexttext space ' week' ;
2005-06-14 21:32:29 +00:00
2008-05-04 20:52:56 +00:00
weekdayof = ( reltextnumber | reltexttext ) space ( dayfull | dayabbr ) ' of ' ;
2005-06-14 21:32:29 +00:00
* /
/* !re2c
/* so that vim highlights correctly */
2006-01-04 21:31:35 +00:00
' yesterday'
2005-06-14 21:32:29 +00:00
{
DEBUG_OUTPUT ( " yesterday " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
TIMELIB_UNHAVE_TIME () ;
s - > time - > relative . d = - 1 ;
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
2006-01-04 21:31:35 +00:00
' now'
2005-06-14 21:32:29 +00:00
{
DEBUG_OUTPUT ( " now " ) ;
TIMELIB_INIT ;
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
2006-01-04 21:31:35 +00:00
' noon'
2005-06-14 21:32:29 +00:00
{
2005-10-08 14:31:17 +00:00
DEBUG_OUTPUT ( " noon " ) ;
TIMELIB_INIT ;
TIMELIB_UNHAVE_TIME () ;
TIMELIB_HAVE_TIME () ;
s - > time - > h = 12 ;
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
2006-01-04 21:31:35 +00:00
' midnight' | ' today'
2005-10-08 14:31:17 +00:00
{
DEBUG_OUTPUT ( " midnight | today " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_UNHAVE_TIME () ;
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
2006-01-04 21:31:35 +00:00
' tomorrow'
2005-06-14 21:32:29 +00:00
{
DEBUG_OUTPUT ( " tomorrow " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
TIMELIB_UNHAVE_TIME () ;
s - > time - > relative . d = 1 ;
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
timestamp
{
timelib_ull i ;
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
TIMELIB_UNHAVE_DATE () ;
TIMELIB_UNHAVE_TIME () ;
2008-01-27 22:16:48 +00:00
TIMELIB_HAVE_TZ () ;
2005-06-14 21:32:29 +00:00
i = timelib_get_unsigned_nr ( ( char * * ) & ptr , 24 ) ;
s - > time - > y = 1970 ;
s - > time - > m = 1 ;
s - > time - > d = 1 ;
2005-06-15 11:01:07 +00:00
s - > time - > h = s - > time - > i = s - > time - > s = 0 ;
s - > time - > f = 0 . 0 ;
2005-06-14 21:32:29 +00:00
s - > time - > relative . s + = i ;
s - > time - > is_localtime = 1 ;
s - > time - > zone_type = TIMELIB_ZONETYPE_OFFSET ;
s - > time - > z = 0 ;
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
2008-02-03 14:15:07 +00:00
firstdayof | lastdayof
{
DEBUG_OUTPUT ( " firstdayof | lastdayof " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
2008-07-08 17:55:59 +00:00
/* skip "last day of" or "first day of" */
2008-02-03 14:15:07 +00:00
if ( * ptr = = 'l' ) {
s - > time - > relative . first_last_day_of = 2 ;
} else {
s - > time - > relative . first_last_day_of = 1 ;
}
TIMELIB_DEINIT ;
return TIMELIB_LF_DAY_OF_MONTH ;
}
2008-05-04 20:52:56 +00:00
weekdayof
{
timelib_sll i ;
int behavior = 0 ;
DEBUG_OUTPUT ( " weekdayof " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
TIMELIB_HAVE_SPECIAL_RELATIVE () ;
i = timelib_get_relative_text ( ( char * * ) & ptr , & behavior ) ;
timelib_eat_spaces ( ( char * * ) & ptr ) ;
timelib_set_relative ( ( char * * ) & ptr , i , behavior , s ) ;
if ( i > 0 ) { /* first, second... etc */
s - > time - > relative . special . type = TIMELIB_SPECIAL_DAY_OF_WEEK_IN_MONTH ;
timelib_set_relative ( ( char * * ) & ptr , i , behavior , s ) ;
} else { /* last */
s - > time - > relative . special . type = TIMELIB_SPECIAL_LAST_DAY_OF_WEEK_IN_MONTH ;
timelib_set_relative ( ( char * * ) & ptr , - i , behavior , s ) ;
}
TIMELIB_DEINIT ;
return TIMELIB_WEEK_DAY_OF_MONTH ;
}
2005-10-07 08:09:01 +00:00
timetiny12 | timeshort12 | timelong12
2005-06-14 21:32:29 +00:00
{
2005-10-07 08:09:01 +00:00
DEBUG_OUTPUT ( " timetiny12 | timeshort12 | timelong12 " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_TIME () ;
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
2005-10-07 08:09:01 +00:00
if ( * ptr = = ':' | | * ptr = = '.' ) {
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = ':' | | * ptr = = '.' ) {
s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
}
2005-06-14 21:32:29 +00:00
}
s - > time - > h + = timelib_meridian ( ( char * * ) & ptr , s - > time - > h ) ;
TIMELIB_DEINIT ;
return TIMELIB_TIME12 ;
}
2008-03-13 15:54:25 +00:00
mssqltime
{
DEBUG_OUTPUT ( " mssqltime " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_TIME () ;
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = ':' | | * ptr = = '.' ) {
s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = ':' | | * ptr = = '.' ) {
s - > time - > f = timelib_get_frac_nr ( ( char * * ) & ptr , 8 ) ;
}
}
timelib_eat_spaces ( ( char * * ) & ptr ) ;
s - > time - > h + = timelib_meridian ( ( char * * ) & ptr , s - > time - > h ) ;
TIMELIB_DEINIT ;
return TIMELIB_TIME24_WITH_ZONE ;
}
2005-06-14 21:32:29 +00:00
timeshort24 | timelong24 /* | iso8601short | iso8601norm */ | iso8601long /* | iso8601shorttz | iso8601normtz | iso8601longtz */
{
2005-07-03 21:38:54 +00:00
int tz_not_found ;
2005-06-14 21:32:29 +00:00
DEBUG_OUTPUT ( " timeshort24 | timelong24 | iso8601long " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_TIME () ;
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
2005-08-24 13:39:34 +00:00
if ( * ptr = = ':' | | * ptr = = '.' ) {
2005-06-14 21:32:29 +00:00
s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = '.' ) {
s - > time - > f = timelib_get_frac_nr ( ( char * * ) & ptr , 8 ) ;
}
}
if ( * ptr != ' \ 0' ) {
2005-10-03 11:17:28 +00:00
s - > time - > z = timelib_get_zone ( ( char * * ) & ptr , & s - > time - > dst , s - > time , & tz_not_found , s - > tzdb ) ;
2006-04-11 18:03:52 +00:00
if ( tz_not_found ) {
add_error ( s , " The timezone could not be found in the database " ) ;
}
2005-06-14 21:32:29 +00:00
}
TIMELIB_DEINIT ;
return TIMELIB_TIME24_WITH_ZONE ;
}
gnunocolon
{
DEBUG_OUTPUT ( " gnunocolon " ) ;
TIMELIB_INIT ;
switch ( s - > time - > have_time ) {
case 0 :
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > s = 0 ;
break ;
case 1 :
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
break ;
default :
TIMELIB_DEINIT ;
2006-04-11 18:03:52 +00:00
add_error ( s , " Double time specification " ) ;
2005-06-15 11:01:07 +00:00
return TIMELIB_ERROR ;
2005-06-14 21:32:29 +00:00
}
s - > time - > have_time + + ;
TIMELIB_DEINIT ;
return TIMELIB_GNU_NOCOLON ;
}
/*
gnunocolontz
{
DEBUG_OUTPUT ( " gnunocolontz " ) ;
TIMELIB_INIT ;
switch ( s - > time - > have_time ) {
case 0 :
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > s = 0 ;
2005-10-03 11:17:28 +00:00
s - > time - > z = timelib_get_zone ( ( char * * ) & ptr , & s - > time - > dst , s - > time , s - > tzdb ) ;
2005-06-14 21:32:29 +00:00
break ;
case 1 :
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
break ;
default :
TIMELIB_DEINIT ;
2005-06-15 11:01:07 +00:00
return TIMELIB_ERROR ;
2005-06-14 21:32:29 +00:00
}
s - > time - > have_time + + ;
TIMELIB_DEINIT ;
return TIMELIB_GNU_NOCOLON_TZ ;
}
* /
iso8601nocolon /* | iso8601nocolontz */
{
2005-07-03 21:38:54 +00:00
int tz_not_found ;
2005-06-14 21:32:29 +00:00
DEBUG_OUTPUT ( " iso8601nocolon " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_TIME () ;
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr != ' \ 0' ) {
2005-10-03 11:17:28 +00:00
s - > time - > z = timelib_get_zone ( ( char * * ) & ptr , & s - > time - > dst , s - > time , & tz_not_found , s - > tzdb ) ;
2006-04-11 18:03:52 +00:00
if ( tz_not_found ) {
add_error ( s , " The timezone could not be found in the database " ) ;
}
2005-06-14 21:32:29 +00:00
}
TIMELIB_DEINIT ;
return TIMELIB_ISO_NOCOLON ;
}
americanshort | american
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " americanshort | american " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = '/' ) {
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
}
TIMELIB_DEINIT ;
return TIMELIB_AMERICAN ;
}
2007-07-12 18:58:00 +00:00
iso8601date4 | iso8601dateslash | dateslash
{
DEBUG_OUTPUT ( " iso8601date4 | iso8601date2 | iso8601dateslash | dateslash " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_unsigned_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
TIMELIB_DEINIT ;
return TIMELIB_ISO_DATE ;
}
iso8601date2
2005-06-14 21:32:29 +00:00
{
2007-07-12 18:58:00 +00:00
DEBUG_OUTPUT ( " iso8601date2 " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
2007-07-12 18:58:00 +00:00
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_DEINIT ;
return TIMELIB_ISO_DATE ;
}
2006-07-27 13:00:00 +00:00
gnudateshorter
{
DEBUG_OUTPUT ( " gnudateshorter " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_ISO_DATE ;
}
2005-06-14 21:32:29 +00:00
gnudateshort
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " gnudateshort " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_ISO_DATE ;
}
datefull
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " datefull " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
2005-12-11 22:35:40 +00:00
timelib_skip_day_suffix ( ( char * * ) & ptr ) ;
2005-06-14 21:32:29 +00:00
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_DATE_FULL ;
}
2007-07-12 18:58:00 +00:00
pointeddate4
2005-06-14 21:32:29 +00:00
{
2007-07-12 18:58:00 +00:00
DEBUG_OUTPUT ( " pointed date YYYY " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
2007-07-12 18:58:00 +00:00
TIMELIB_DEINIT ;
return TIMELIB_DATE_FULL_POINTED ;
}
pointeddate2
{
DEBUG_OUTPUT ( " pointed date YY " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_DATE_FULL_POINTED ;
}
datenoday
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " datenoday " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > d = 1 ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_DATE_NO_DAY ;
}
datenodayrev
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " datenodayrev " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > d = 1 ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_DATE_NO_DAY ;
}
datetextual | datenoyear
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " datetextual | datenoyear " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_DATE_TEXT ;
}
2005-07-05 21:33:33 +00:00
datenoyearrev
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " datenoyearrev " ) ;
2005-07-05 21:33:33 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
2005-12-11 22:35:40 +00:00
timelib_skip_day_suffix ( ( char * * ) & ptr ) ;
2005-07-05 21:33:33 +00:00
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
TIMELIB_DEINIT ;
return TIMELIB_DATE_TEXT ;
}
2005-06-14 21:32:29 +00:00
datenocolon
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " datenocolon " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
TIMELIB_DEINIT ;
return TIMELIB_DATE_NOCOLON ;
}
2006-02-24 09:44:56 +00:00
xmlrpc | xmlrpcnocolon | soap | wddx | exif
2005-06-14 21:32:29 +00:00
{
2005-07-03 21:38:54 +00:00
int tz_not_found ;
2006-02-24 09:44:56 +00:00
DEBUG_OUTPUT ( " xmlrpc | xmlrpcnocolon | soap | wddx | exif " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_TIME () ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = '.' ) {
s - > time - > f = timelib_get_frac_nr ( ( char * * ) & ptr , 9 ) ;
2005-12-16 22:36:46 +00:00
if ( * ptr ) { /* timezone is optional */
s - > time - > z = timelib_get_zone ( ( char * * ) & ptr , & s - > time - > dst , s - > time , & tz_not_found , s - > tzdb ) ;
2006-04-11 18:03:52 +00:00
if ( tz_not_found ) {
add_error ( s , " The timezone could not be found in the database " ) ;
}
2005-12-16 22:36:46 +00:00
}
2005-06-14 21:32:29 +00:00
}
TIMELIB_DEINIT ;
return TIMELIB_XMLRPC_SOAP ;
}
pgydotd
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " pgydotd " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 3 ) ;
s - > time - > m = 1 ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_PG_YEARDAY ;
}
isoweekday
{
2005-06-15 11:01:07 +00:00
timelib_sll w , d ;
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " isoweekday " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
TIMELIB_HAVE_RELATIVE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
w = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
d = timelib_get_nr ( ( char * * ) & ptr , 1 ) ;
s - > time - > m = 1 ;
s - > time - > d = 1 ;
s - > time - > relative . d = timelib_daynr_from_weeknr ( s - > time - > y , w , d ) ;
TIMELIB_DEINIT ;
return TIMELIB_ISO_WEEK ;
}
2005-06-20 08:46:09 +00:00
isoweek
{
timelib_sll w , d ;
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " isoweek " ) ;
2005-06-20 08:46:09 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
TIMELIB_HAVE_RELATIVE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
w = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
d = 1 ;
s - > time - > m = 1 ;
s - > time - > d = 1 ;
s - > time - > relative . d = timelib_daynr_from_weeknr ( s - > time - > y , w , d ) ;
TIMELIB_DEINIT ;
return TIMELIB_ISO_WEEK ;
}
2005-06-14 21:32:29 +00:00
pgtextshort
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " pgtextshort " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_PG_TEXT ;
}
pgtextreverse
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " pgtextreverse " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
TIMELIB_DEINIT ;
return TIMELIB_PG_TEXT ;
}
clf
{
2005-07-03 21:38:54 +00:00
int tz_not_found ;
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " clf " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_TIME () ;
TIMELIB_HAVE_DATE () ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
2005-10-03 11:17:28 +00:00
s - > time - > z = timelib_get_zone ( ( char * * ) & ptr , & s - > time - > dst , s - > time , & tz_not_found , s - > tzdb ) ;
2006-04-11 18:03:52 +00:00
if ( tz_not_found ) {
add_error ( s , " The timezone could not be found in the database " ) ;
}
2005-06-14 21:32:29 +00:00
TIMELIB_DEINIT ;
return TIMELIB_CLF ;
}
2005-07-20 08:31:02 +00:00
year4
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " year4 " ) ;
2005-07-20 08:31:02 +00:00
TIMELIB_INIT ;
s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ;
TIMELIB_DEINIT ;
return TIMELIB_CLF ;
}
2005-06-14 21:32:29 +00:00
ago
{
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " ago " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
s - > time - > relative . y = 0 - s - > time - > relative . y ;
s - > time - > relative . m = 0 - s - > time - > relative . m ;
s - > time - > relative . d = 0 - s - > time - > relative . d ;
s - > time - > relative . h = 0 - s - > time - > relative . h ;
s - > time - > relative . i = 0 - s - > time - > relative . i ;
s - > time - > relative . s = 0 - s - > time - > relative . s ;
s - > time - > relative . weekday = 0 - s - > time - > relative . weekday ;
2008-04-27 19:14:33 +00:00
if ( s - > time - > relative . weekday = = 0 ) {
s - > time - > relative . weekday = - 7 ;
}
2008-05-01 16:15:45 +00:00
if ( s - > time - > relative . have_special_relative && s - > time - > relative . special . type = = TIMELIB_SPECIAL_WEEKDAY ) {
s - > time - > relative . special . amount = 0 - s - > time - > relative . special . amount ;
2006-05-14 17:36:05 +00:00
}
2005-06-14 21:32:29 +00:00
TIMELIB_DEINIT ;
return TIMELIB_AGO ;
}
2005-12-11 22:35:40 +00:00
daytext
{
const timelib_relunit * relunit ;
DEBUG_OUTPUT ( " daytext " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
TIMELIB_HAVE_WEEKDAY_RELATIVE () ;
TIMELIB_UNHAVE_TIME () ;
relunit = timelib_lookup_relunit ( ( char * * ) & ptr ) ;
s - > time - > relative . weekday = relunit - > multiplier ;
2008-04-27 19:14:33 +00:00
if ( s - > time - > relative . weekday_behavior != 2 ) {
s - > time - > relative . weekday_behavior = 1 ;
}
2005-12-11 22:35:40 +00:00
TIMELIB_DEINIT ;
return TIMELIB_WEEKDAY ;
}
2008-04-27 19:14:33 +00:00
relativetextweek
{
timelib_sll i ;
int behavior = 0 ;
DEBUG_OUTPUT ( " relativetextweek " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
while ( * ptr ) {
i = timelib_get_relative_text ( ( char * * ) & ptr , & behavior ) ;
timelib_eat_spaces ( ( char * * ) & ptr ) ;
timelib_set_relative ( ( char * * ) & ptr , i , behavior , s ) ;
s - > time - > relative . weekday_behavior = 2 ;
/* to handle the format weekday + last / this / next week */
2008-05-01 16:15:45 +00:00
if ( s - > time - > relative . have_weekday_relative = = 0 ) {
2008-04-27 19:14:33 +00:00
TIMELIB_HAVE_WEEKDAY_RELATIVE () ;
s - > time - > relative . weekday = 1 ;
}
}
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
2005-06-14 21:32:29 +00:00
relativetext
{
2005-06-16 13:30:26 +00:00
timelib_sll i ;
2006-02-24 09:44:56 +00:00
int behavior = 0 ;
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " relativetext " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
2007-03-21 09:40:33 +00:00
2005-06-14 21:32:29 +00:00
while ( * ptr ) {
2005-10-19 21:08:35 +00:00
i = timelib_get_relative_text ( ( char * * ) & ptr , & behavior ) ;
2005-06-14 21:32:29 +00:00
timelib_eat_spaces ( ( char * * ) & ptr ) ;
2005-10-19 21:08:35 +00:00
timelib_set_relative ( ( char * * ) & ptr , i , behavior , s ) ;
2005-06-14 21:32:29 +00:00
}
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
2006-05-14 17:36:05 +00:00
monthfull | monthabbr
{
DEBUG_OUTPUT ( " monthtext " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > m = timelib_lookup_month ( ( char * * ) & ptr ) ;
TIMELIB_DEINIT ;
return TIMELIB_DATE_TEXT ;
}
2005-06-14 21:32:29 +00:00
tzcorrection | tz
{
2005-07-03 21:38:54 +00:00
int tz_not_found ;
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " tzcorrection | tz " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
2006-04-11 18:03:52 +00:00
TIMELIB_HAVE_TZ () ;
2005-10-03 11:17:28 +00:00
s - > time - > z = timelib_get_zone ( ( char * * ) & ptr , & s - > time - > dst , s - > time , & tz_not_found , s - > tzdb ) ;
2006-04-11 18:03:52 +00:00
if ( tz_not_found ) {
add_error ( s , " The timezone could not be found in the database " ) ;
}
2005-06-14 21:32:29 +00:00
TIMELIB_DEINIT ;
return TIMELIB_TIMEZONE ;
}
2006-05-19 14:52:30 +00:00
dateshortwithtimeshort12 | dateshortwithtimelong12
{
DEBUG_OUTPUT ( " dateshortwithtimeshort12 | dateshortwithtimelong12 " ) ;
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
TIMELIB_HAVE_TIME () ;
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = ':' | | * ptr = = '.' ) {
s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = '.' ) {
s - > time - > f = timelib_get_frac_nr ( ( char * * ) & ptr , 8 ) ;
}
}
s - > time - > h + = timelib_meridian ( ( char * * ) & ptr , s - > time - > h ) ;
TIMELIB_DEINIT ;
return TIMELIB_SHORTDATE_WITH_TIME ;
}
2005-06-14 21:32:29 +00:00
dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz
{
2005-07-03 21:38:54 +00:00
int tz_not_found ;
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_DATE () ;
s - > time - > m = timelib_get_month ( ( char * * ) & ptr ) ;
s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
TIMELIB_HAVE_TIME () ;
s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = ':' ) {
s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ;
if ( * ptr = = '.' ) {
s - > time - > f = timelib_get_frac_nr ( ( char * * ) & ptr , 8 ) ;
}
}
if ( * ptr != ' \ 0' ) {
2005-10-03 11:17:28 +00:00
s - > time - > z = timelib_get_zone ( ( char * * ) & ptr , & s - > time - > dst , s - > time , & tz_not_found , s - > tzdb ) ;
2006-04-11 18:03:52 +00:00
if ( tz_not_found ) {
add_error ( s , " The timezone could not be found in the database " ) ;
}
2005-06-14 21:32:29 +00:00
}
TIMELIB_DEINIT ;
return TIMELIB_SHORTDATE_WITH_TIME ;
}
relative
{
timelib_ull i ;
2005-08-24 13:39:34 +00:00
DEBUG_OUTPUT ( " relative " ) ;
2005-06-14 21:32:29 +00:00
TIMELIB_INIT ;
TIMELIB_HAVE_RELATIVE () ;
while ( * ptr ) {
i = timelib_get_unsigned_nr ( ( char * * ) & ptr , 24 ) ;
timelib_eat_spaces ( ( char * * ) & ptr ) ;
2005-10-19 21:08:35 +00:00
timelib_set_relative ( ( char * * ) & ptr , i , 0 , s ) ;
2005-06-14 21:32:29 +00:00
}
TIMELIB_DEINIT ;
return TIMELIB_RELATIVE ;
}
2006-02-27 19:41:33 +00:00
[ . , \ t ]
2005-06-14 21:32:29 +00:00
{
goto std ;
}
2005-07-10 14:04:20 +00:00
" \000 " | " \n "
2005-06-14 21:32:29 +00:00
{
s - > pos = cursor ; s - > line + + ;
goto std ;
}
any
{
2006-04-11 18:03:52 +00:00
add_error ( s , " Unexpected character " ) ;
2005-06-14 21:32:29 +00:00
goto std ;
}
* /
}
/* !max:re2c */
2006-05-14 17:36:05 +00:00
timelib_time * timelib_strtotime ( char * s , int len , struct timelib_error_container * * errors , const timelib_tzdb * tzdb )
2005-06-14 21:32:29 +00:00
{
Scanner in ;
int t ;
2005-12-01 16:24:52 +00:00
char * e = s + len - 1 ;
2006-04-11 18:03:52 +00:00
memset ( & in , 0 , sizeof ( in ) ) ;
in . errors = malloc ( sizeof ( struct timelib_error_container ) ) ;
in . errors - > warning_count = 0 ;
in . errors - > warning_messages = NULL ;
in . errors - > error_count = 0 ;
in . errors - > error_messages = NULL ;
2006-09-09 12:26:33 +00:00
if ( len > 0 ) {
while ( isspace ( * s ) && s < e ) {
s + + ;
}
while ( isspace ( * e ) && e > s ) {
e - - ;
}
2005-12-01 16:24:52 +00:00
}
2007-07-12 18:58:00 +00:00
if ( e - s < 0 ) {
2005-12-01 16:24:52 +00:00
in . time = timelib_time_ctor () ;
2006-04-11 18:03:52 +00:00
add_error ( & in , " Empty string " ) ;
if ( errors ) {
* errors = in . errors ;
} else {
timelib_error_container_dtor ( in . errors ) ;
}
2007-07-12 18:58:00 +00:00
in . time - > y = in . time - > d = in . time - > m = in . time - > h = in . time - > i = in . time - > s = in . time - > f = in . time - > dst = in . time - > z = TIMELIB_UNSET ;
2005-12-01 16:24:52 +00:00
in . time - > is_localtime = in . time - > zone_type = 0 ;
return in . time ;
}
e + + ;
2005-06-14 21:32:29 +00:00
2005-12-01 16:24:52 +00:00
in . str = malloc ( ( e - s ) + YYMAXFILL ) ;
memset ( in . str , 0 , ( e - s ) + YYMAXFILL ) ;
memcpy ( in . str , s , ( e - s ) ) ;
in . lim = in . str + ( e - s ) + YYMAXFILL ;
2005-06-14 21:32:29 +00:00
in . cur = in . str ;
in . time = timelib_time_ctor () ;
2007-07-12 18:58:00 +00:00
in . time - > y = TIMELIB_UNSET ;
in . time - > d = TIMELIB_UNSET ;
in . time - > m = TIMELIB_UNSET ;
in . time - > h = TIMELIB_UNSET ;
in . time - > i = TIMELIB_UNSET ;
in . time - > s = TIMELIB_UNSET ;
in . time - > f = TIMELIB_UNSET ;
in . time - > z = TIMELIB_UNSET ;
in . time - > dst = TIMELIB_UNSET ;
2005-10-03 11:17:28 +00:00
in . tzdb = tzdb ;
2005-11-17 13:04:31 +00:00
in . time - > is_localtime = 0 ;
in . time - > zone_type = 0 ;
2005-06-14 21:32:29 +00:00
do {
t = scan ( & in ) ;
2005-08-24 13:39:34 +00:00
# ifdef DEBUG_PARSER
printf ( " %d \n " , t ) ;
# endif
2005-06-14 21:32:29 +00:00
} while ( t != EOI ) ;
2008-07-14 17:36:12 +00:00
/* do funky checking whether the parsed date was valid date */
if ( in . time - > have_date && ! timelib_valid_date ( in . time - > y , in . time - > m , in . time - > d ) ) {
add_warning ( & in , " The parsed date was invalid " ) ;
}
2005-06-14 21:32:29 +00:00
free ( in . str ) ;
2006-04-11 18:03:52 +00:00
if ( errors ) {
* errors = in . errors ;
} else {
timelib_error_container_dtor ( in . errors ) ;
}
2005-06-14 21:32:29 +00:00
return in . time ;
}
2008-01-13 15:16:02 +00:00
# define TIMELIB_CHECK_NUMBER \
if ( strchr ( " 0123456789 " , * ptr ) = = NULL ) \
{ \
add_pbf_error ( s , " Unexpected data found. " , string , begin ) ; \
}
timelib_time * timelib_parse_from_format ( char * format , char * string , int len , timelib_error_container * * errors , const timelib_tzdb * tzdb )
{
char * fptr = format ;
char * ptr = string ;
char * begin ;
timelib_sll tmp ;
Scanner in ;
Scanner * s = & in ;
memset ( & in , 0 , sizeof ( in ) ) ;
in . errors = malloc ( sizeof ( struct timelib_error_container ) ) ;
in . errors - > warning_count = 0 ;
in . errors - > warning_messages = NULL ;
in . errors - > error_count = 0 ;
in . errors - > error_messages = NULL ;
in . time = timelib_time_ctor () ;
in . time - > y = TIMELIB_UNSET ;
in . time - > d = TIMELIB_UNSET ;
in . time - > m = TIMELIB_UNSET ;
in . time - > h = TIMELIB_UNSET ;
in . time - > i = TIMELIB_UNSET ;
in . time - > s = TIMELIB_UNSET ;
in . time - > f = TIMELIB_UNSET ;
in . time - > z = TIMELIB_UNSET ;
in . time - > dst = TIMELIB_UNSET ;
in . tzdb = tzdb ;
in . time - > is_localtime = 0 ;
in . time - > zone_type = 0 ;
/* Loop over the format string */
while ( * fptr && * ptr ) {
begin = ptr ;
switch ( * fptr ) {
2008-07-08 20:25:28 +00:00
case 'D' : /* three letter day */
case 'l' : /* full day */
2008-07-11 08:42:54 +00:00
if ( ! timelib_lookup_relunit ( ( char * * ) & ptr ) ) {
2008-07-08 20:25:28 +00:00
add_pbf_error ( s , " A textual day could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'd' : /* two digit day, with leading zero */
case 'j' : /* two digit day, without leading zero */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > d = timelib_get_nr ( ( char * * ) & ptr , 2 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A two digit day could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'S' : /* day suffix, ignored, nor checked */
2008-01-13 15:16:02 +00:00
timelib_skip_day_suffix ( ( char * * ) & ptr ) ;
break ;
2008-07-08 17:55:59 +00:00
case 'z' : /* day of year - resets month (0 based) */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( tmp = timelib_get_nr ( ( char * * ) & ptr , 3 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A three digit day-of-year could not be found " , string , begin ) ;
} else {
s - > time - > m = 1 ;
s - > time - > d = tmp + 1 ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'm' : /* two digit month, with leading zero */
case 'n' : /* two digit month, without leading zero */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > m = timelib_get_nr ( ( char * * ) & ptr , 2 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A two digit month could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'M' : /* three letter month */
case 'F' : /* full month */
2008-01-13 15:16:02 +00:00
tmp = timelib_lookup_month ( ( char * * ) & ptr ) ;
if ( ! tmp ) {
add_pbf_error ( s , " A textual month could not be found " , string , begin ) ;
} else {
s - > time - > m = tmp ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'y' : /* two digit year */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 2 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A two digit year could not be found " , string , begin ) ;
}
TIMELIB_PROCESS_YEAR ( s - > time - > y ) ;
break ;
2008-07-08 17:55:59 +00:00
case 'Y' : /* four digit year */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > y = timelib_get_nr ( ( char * * ) & ptr , 4 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A four digit year could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'g' : /* two digit hour, with leading zero */
case 'h' : /* two digit hour, without leading zero */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A two digit hour could not be found " , string , begin ) ;
}
if ( s - > time - > h > 12 ) {
add_pbf_error ( s , " Hour can not be higher than 12 " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'G' : /* two digit hour, with leading zero */
case 'H' : /* two digit hour, without leading zero */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > h = timelib_get_nr ( ( char * * ) & ptr , 2 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A two digit hour could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'a' : /* am / pm / a.m. / p.m. */
case 'A' : /* AM / PM / A.M. / P.M. */
2008-01-13 15:16:02 +00:00
if ( s - > time - > h = = TIMELIB_UNSET ) {
add_pbf_error ( s , " Meridian can only come after an hour has been found " , string , begin ) ;
} else if ( ( tmp = timelib_meridian_with_check ( ( char * * ) & ptr , s - > time - > h ) ) = = TIMELIB_UNSET ) {
2008-02-17 18:17:45 +00:00
add_pbf_error ( s , " A meridian could not be found " , string , begin ) ;
2008-01-13 15:16:02 +00:00
} else {
s - > time - > h + = tmp ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'i' : /* two digit minute, with leading zero */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > i = timelib_get_nr ( ( char * * ) & ptr , 2 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A two digit minute could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case 's' : /* two digit second, with leading zero */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > s = timelib_get_nr ( ( char * * ) & ptr , 2 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A two digit second could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case 'u' : /* five digit millisecond, with leading zero */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
if ( ( s - > time - > f = timelib_get_nr ( ( char * * ) & ptr , 5 ) ) = = TIMELIB_UNSET ) {
add_pbf_error ( s , " A five digit millisecond could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case ' ' : /* any sort of whitespace (' ' and \t) */
2008-01-13 15:16:02 +00:00
timelib_eat_spaces ( ( char * * ) & ptr ) ;
break ;
2008-07-08 17:55:59 +00:00
case 'U' : /* epoch seconds */
2008-01-13 15:16:02 +00:00
TIMELIB_CHECK_NUMBER ;
TIMELIB_HAVE_RELATIVE () ;
tmp = timelib_get_unsigned_nr ( ( char * * ) & ptr , 24 ) ;
s - > time - > y = 1970 ;
s - > time - > m = 1 ;
s - > time - > d = 1 ;
s - > time - > h = s - > time - > i = s - > time - > s = 0 ;
s - > time - > f = 0 . 0 ;
s - > time - > relative . s + = tmp ;
s - > time - > is_localtime = 1 ;
s - > time - > zone_type = TIMELIB_ZONETYPE_OFFSET ;
s - > time - > z = 0 ;
break ;
2008-07-08 17:55:59 +00:00
case 'e' : /* timezone */
2008-07-08 20:25:28 +00:00
case 'P' : /* timezone */
case 'T' : /* timezone */
case 'O' : /* timezone */
2008-01-13 15:16:02 +00:00
{
int tz_not_found ;
s - > time - > z = timelib_get_zone ( ( char * * ) & ptr , & s - > time - > dst , s - > time , & tz_not_found , s - > tzdb ) ;
if ( tz_not_found ) {
add_pbf_error ( s , " The timezone could not be found in the database " , string , begin ) ;
}
}
break ;
2008-07-08 17:55:59 +00:00
case '#' : /* separation symbol */
2008-01-13 15:16:02 +00:00
if ( * ptr = = ';' | | * ptr = = ':' | | * ptr = = '/' | | * ptr = = '.' | | * ptr = = ',' | | * ptr = = '-' ) {
+ + ptr ;
} else {
2008-02-17 18:17:45 +00:00
add_pbf_error ( s , " The separation symbol ([;:/.,-]) could not be found " , string , begin ) ;
2008-01-13 15:16:02 +00:00
}
break ;
2008-02-25 18:26:33 +00:00
case ';' :
case ':' :
case '/' :
case '.' :
case ',' :
case '-' :
if ( * ptr = = * fptr ) {
+ + ptr ;
} else {
add_pbf_error ( s , " The separation symbol could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case '!' : /* reset all fields to default */
2008-02-25 18:26:33 +00:00
s - > time - > y = 1970 ;
s - > time - > m = 1 ;
s - > time - > d = 1 ;
s - > time - > h = s - > time - > i = s - > time - > s = 0 ;
s - > time - > f = 0 . 0 ;
s - > time - > tz_info = NULL ;
2008-07-08 17:55:59 +00:00
break ; /* break intentionally not missing */
2008-02-25 18:26:33 +00:00
2008-07-08 17:55:59 +00:00
case '|' : /* reset all fields to default when not set */
2008-02-25 18:26:33 +00:00
if ( s - > time - > y = = TIMELIB_UNSET ) s - > time - > y = 1970 ;
if ( s - > time - > m = = TIMELIB_UNSET ) s - > time - > m = 1 ;
if ( s - > time - > d = = TIMELIB_UNSET ) s - > time - > d = 1 ;
if ( s - > time - > h = = TIMELIB_UNSET ) s - > time - > h = 0 ;
if ( s - > time - > i = = TIMELIB_UNSET ) s - > time - > i = 0 ;
if ( s - > time - > s = = TIMELIB_UNSET ) s - > time - > s = 0 ;
if ( s - > time - > f = = TIMELIB_UNSET ) s - > time - > f = 0 . 0 ;
2008-07-08 17:55:59 +00:00
break ; /* break intentionally not missing */
2008-02-25 18:26:33 +00:00
2008-07-08 17:55:59 +00:00
case '?' : /* random char */
2008-01-13 15:16:02 +00:00
+ + ptr ;
break ;
2008-07-08 20:25:28 +00:00
case '\\' : /* escaped char */
* fptr + + ;
if ( * ptr = = * fptr ) {
+ + ptr ;
} else {
add_pbf_error ( s , " The escaped character could not be found " , string , begin ) ;
}
break ;
2008-07-08 17:55:59 +00:00
case '*' : /* random chars until a separator or number ([ \t.,:; / -0123456789]) */
2008-02-17 18:17:45 +00:00
timelib_eat_until_separator ( ( char * * ) & ptr ) ;
2008-01-13 15:16:02 +00:00
break ;
default :
if ( * fptr != * ptr ) {
2008-02-17 18:17:45 +00:00
add_pbf_error ( s , " The format separator does not match " , string , begin ) ;
2008-01-13 15:16:02 +00:00
}
ptr + + ;
}
fptr + + ;
}
if ( * ptr ) {
add_pbf_error ( s , " Trailing data " , string , ptr ) ;
}
if ( * fptr ) {
add_pbf_error ( s , " Data missing " , string , ptr ) ;
}
2008-07-08 17:55:59 +00:00
/* clean up a bit */
2008-02-25 18:26:33 +00:00
if ( s - > time - > h != TIMELIB_UNSET | | s - > time - > i != TIMELIB_UNSET | | s - > time - > s != TIMELIB_UNSET ) {
if ( s - > time - > h = = TIMELIB_UNSET ) {
s - > time - > h = 0 ;
}
if ( s - > time - > i = = TIMELIB_UNSET ) {
s - > time - > i = 0 ;
}
if ( s - > time - > s = = TIMELIB_UNSET ) {
s - > time - > s = 0 ;
}
}
2008-07-15 17:38:27 +00:00
/* do funky checking whether the parsed time was valid time */
if ( s - > time - > h != TIMELIB_UNSET && s - > time - > i != TIMELIB_UNSET &&
s - > time - > s != TIMELIB_UNSET &&
! timelib_valid_time ( s - > time - > h , s - > time - > i , s - > time - > s ) ) {
add_pbf_warning ( s , " The parsed time was invalid " , string , ptr ) ;
}
2008-07-14 17:36:12 +00:00
/* do funky checking whether the parsed date was valid date */
if ( s - > time - > y != TIMELIB_UNSET && s - > time - > m != TIMELIB_UNSET &&
s - > time - > d != TIMELIB_UNSET &&
! timelib_valid_date ( s - > time - > y , s - > time - > m , s - > time - > d ) ) {
add_pbf_warning ( s , " The parsed date was invalid " , string , ptr ) ;
}
2008-02-25 18:26:33 +00:00
2008-01-13 15:16:02 +00:00
if ( errors ) {
* errors = in . errors ;
} else {
timelib_error_container_dtor ( in . errors ) ;
}
return in . time ;
}
2005-06-14 21:32:29 +00:00
void timelib_fill_holes ( timelib_time * parsed , timelib_time * now , int options )
{
if ( ! ( options && TIMELIB_OVERRIDE_TIME ) && parsed - > have_date && ! parsed - > have_time ) {
parsed - > h = 0 ;
parsed - > i = 0 ;
parsed - > s = 0 ;
parsed - > f = 0 ;
}
2007-07-12 18:58:00 +00:00
if ( parsed - > y = = TIMELIB_UNSET ) parsed - > y = now - > y != TIMELIB_UNSET ? now - > y : 0 ;
if ( parsed - > d = = TIMELIB_UNSET ) parsed - > d = now - > d != TIMELIB_UNSET ? now - > d : 0 ;
if ( parsed - > m = = TIMELIB_UNSET ) parsed - > m = now - > m != TIMELIB_UNSET ? now - > m : 0 ;
if ( parsed - > h = = TIMELIB_UNSET ) parsed - > h = now - > h != TIMELIB_UNSET ? now - > h : 0 ;
if ( parsed - > i = = TIMELIB_UNSET ) parsed - > i = now - > i != TIMELIB_UNSET ? now - > i : 0 ;
if ( parsed - > s = = TIMELIB_UNSET ) parsed - > s = now - > s != TIMELIB_UNSET ? now - > s : 0 ;
if ( parsed - > f = = TIMELIB_UNSET ) parsed - > f = now - > f != TIMELIB_UNSET ? now - > f : 0 ;
if ( parsed - > z = = TIMELIB_UNSET ) parsed - > z = now - > z != TIMELIB_UNSET ? now - > z : 0 ;
if ( parsed - > dst = = TIMELIB_UNSET ) parsed - > dst = now - > dst != TIMELIB_UNSET ? now - > dst : 0 ;
2005-06-14 21:32:29 +00:00
if ( ! parsed - > tz_abbr ) {
parsed - > tz_abbr = now - > tz_abbr ? strdup ( now - > tz_abbr ) : NULL ;
}
if ( ! parsed - > tz_info ) {
parsed - > tz_info = now - > tz_info ? timelib_tzinfo_clone ( now - > tz_info ) : NULL ;
}
if ( parsed - > zone_type = = 0 && now - > zone_type != 0 ) {
parsed - > zone_type = now - > zone_type ;
/* parsed->tz_abbr = now->tz_abbr ? strdup(now->tz_abbr) : NULL;
parsed - > tz_info = now - > tz_info ? timelib_tzinfo_clone ( now - > tz_info ) : NULL ;
* / parsed - > is_localtime = 1 ;
}
/* timelib_dump_date(parsed, 2);
timelib_dump_date ( now , 2 ) ;
* /
}
2005-10-01 15:04:07 +00:00
char * timelib_timezone_id_from_abbr ( const char * abbr , long gmtoffset , int isdst )
2005-07-03 15:01:29 +00:00
{
2006-05-14 17:36:05 +00:00
const timelib_tz_lookup_table * tp ;
2005-07-03 15:01:29 +00:00
2005-10-01 15:04:07 +00:00
tp = zone_search ( abbr , gmtoffset , isdst ) ;
2005-07-04 07:16:09 +00:00
if ( tp ) {
return ( tp - > full_tz_name ) ;
} else {
return NULL ;
}
2005-07-03 15:01:29 +00:00
}
2005-06-14 21:32:29 +00:00
2006-05-14 17:36:05 +00:00
const timelib_tz_lookup_table * timelib_timezone_abbreviations_list ( void )
2005-07-20 08:31:02 +00:00
{
return timelib_timezone_lookup ;
}
2005-06-14 21:32:29 +00:00
# ifdef DEBUG_PARSER_STUB
int main ( void )
{
timelib_time time = timelib_strtotime ( " May 12 " ) ;
printf ( " %04d-%02d-%02d %02d:%02d:%02d.%-5d %+04d %1d " ,
time . y , time . m , time . d , time . h , time . i , time . s , time . f , time . z , time . dst ) ;
if ( time . have_relative ) {
printf ( " %3dY %3dM %3dD / %3dH %3dM %3dS " ,
time . relative . y , time . relative . m , time . relative . d , time . relative . h , time . relative . i , time . relative . s ) ;
}
if ( time . have_weekday_relative ) {
printf ( " / %d " , time . relative . weekday ) ;
}
if ( time . have_weeknr_day ) {
printf ( " / %dW%d " , time . relative . weeknr_day . weeknr , time . relative . weeknr_day . dayofweek ) ;
}
return 0 ;
}
# endif
/*
* vim : syntax = c
* /