X-Git-Url: https://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fgetdate.y;h=94160b266b2cc887d6f56bdc93be2ce101354b15;hb=298d8b4a29e66da0b046b64b822f97d1c8fef74b;hp=f9cd86c3a3054226351d16e4a24ce5474dede70d;hpb=ec560ef5cab3aec7a68fb2da6b2dbbbd7415caf1;p=gnulib.git diff --git a/lib/getdate.y b/lib/getdate.y index f9cd86c3a..94160b266 100644 --- a/lib/getdate.y +++ b/lib/getdate.y @@ -1,7 +1,7 @@ %{ /* Parse a string into an internal time stamp. - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -78,16 +78,6 @@ of `digit' even when the host does not conform to POSIX. */ #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -#endif - -#ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif - /* Shift A right by B bits portably, by dividing A by 2**B and truncating towards minus infinity. A and B should be free of side effects, and B should be in the range 0 <= B <= INT_BITS - 2, where @@ -108,12 +98,21 @@ #define HOUR(x) ((x) * 60) -/* Lots of this code assumes time_t and time_t-like values fit into - long int. It also assumes that signed integer overflow silently - wraps around, but there's no portable way to check for that at - compile-time. */ +/* long_time_t is a signed integer type that contains all time_t values. */ verify (TYPE_IS_INTEGER (time_t)); -verify (LONG_MIN <= TYPE_MINIMUM (time_t) && TYPE_MAXIMUM (time_t) <= LONG_MAX); +#if TIME_T_FITS_IN_LONG_INT +typedef long int long_time_t; +#else +typedef time_t long_time_t; +#endif + +/* Lots of this code assumes time_t and time_t-like values fit into + long_time_t. */ +verify (TYPE_MINIMUM (long_time_t) <= TYPE_MINIMUM (time_t) + && TYPE_MAXIMUM (time_t) <= TYPE_MAXIMUM (long_time_t)); + +/* FIXME: It also assumes that signed integer overflow silently wraps around, + but this is not true any more with recent versions of GCC 4. */ /* An integer value, and the number of digits in its textual representation. */ @@ -146,7 +145,7 @@ typedef struct long int day; long int hour; long int minutes; - long int seconds; + long_time_t seconds; long int ns; } relative_time; @@ -293,7 +292,7 @@ set_hhmmss (parser_control *pc, long int hour, long int minutes, %token tAGO tDST %token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT -%token tDAY_UNIT +%token tDAY_UNIT tDAY_SHIFT %token tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN %token tMONTH tORDINAL tZONE @@ -304,7 +303,7 @@ set_hhmmss (parser_control *pc, long int hour, long int minutes, %type o_colon_minutes o_merid %type seconds signed_seconds unsigned_seconds -%type relunit relunit_snumber +%type relunit relunit_snumber dayshift %% @@ -404,12 +403,12 @@ zone: day: tDAY { - pc->day_ordinal = 1; + pc->day_ordinal = 0; pc->day_number = $1; } | tDAY ',' { - pc->day_ordinal = 1; + pc->day_ordinal = 0; pc->day_number = $1; } | tORDINAL tDAY @@ -502,6 +501,8 @@ rel: { apply_relative_time (pc, $1, -1); } | relunit { apply_relative_time (pc, $1, 1); } + | dayshift + { apply_relative_time (pc, $1, 1); } ; relunit: @@ -563,6 +564,11 @@ relunit_snumber: { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; } ; +dayshift: + tDAY_SHIFT + { $$ = RELATIVE_TIME_0; $$.day = $1; } + ; + seconds: signed_seconds | unsigned_seconds; signed_seconds: @@ -669,10 +675,10 @@ static table const time_units_table[] = /* Assorted relative-time words. */ static table const relative_time_table[] = { - { "TOMORROW", tDAY_UNIT, 1 }, - { "YESTERDAY",tDAY_UNIT, -1 }, - { "TODAY", tDAY_UNIT, 0 }, - { "NOW", tDAY_UNIT, 0 }, + { "TOMORROW", tDAY_SHIFT, 1 }, + { "YESTERDAY",tDAY_SHIFT, -1 }, + { "TODAY", tDAY_SHIFT, 0 }, + { "NOW", tDAY_SHIFT, 0 }, { "LAST", tORDINAL, -1 }, { "THIS", tORDINAL, 0 }, { "NEXT", tORDINAL, 1 }, @@ -1139,8 +1145,8 @@ yylex (YYSTYPE *lvalp, parser_control *pc) /* Do nothing if the parser reports an error. */ static int -yyerror (parser_control const *pc ATTRIBUTE_UNUSED, - char const *s ATTRIBUTE_UNUSED) +yyerror (parser_control const *pc _UNUSED_PARAMETER_, + char const *s _UNUSED_PARAMETER_) { return 0; } @@ -1428,7 +1434,9 @@ get_date (struct timespec *result, char const *p, struct timespec const *now) if (pc.days_seen && ! pc.dates_seen) { tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7 - + 7 * (pc.day_ordinal - (0 < pc.day_ordinal))); + + 7 * (pc.day_ordinal + - (0 < pc.day_ordinal + && tm.tm_wday != pc.day_number))); tm.tm_isdst = -1; Start = mktime (&tm); if (Start == (time_t) -1) @@ -1493,20 +1501,22 @@ get_date (struct timespec *result, char const *p, struct timespec const *now) time_t t1 = t0 + d1; long int d2 = 60 * pc.rel.minutes; time_t t2 = t1 + d2; - long int d3 = pc.rel.seconds; - time_t t3 = t2 + d3; + long_time_t d3 = pc.rel.seconds; + long_time_t t3 = t2 + d3; long int d4 = (sum_ns - normalized_ns) / BILLION; - time_t t4 = t3 + d4; + long_time_t t4 = t3 + d4; + time_t t5 = t4; if ((d1 / (60 * 60) ^ pc.rel.hour) | (d2 / 60 ^ pc.rel.minutes) | ((t1 < t0) ^ (d1 < 0)) | ((t2 < t1) ^ (d2 < 0)) | ((t3 < t2) ^ (d3 < 0)) - | ((t4 < t3) ^ (d4 < 0))) + | ((t4 < t3) ^ (d4 < 0)) + | (t5 != t4)) goto fail; - result->tv_sec = t4; + result->tv_sec = t5; result->tv_nsec = normalized_ns; } }