stat: fix compilation on AIX
[gnulib.git] / lib / getdate.y
index f9cd86c..94160b2 100644 (file)
@@ -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
    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
 
 #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 <intval> tDAY_UNIT
+%token <intval> tDAY_UNIT tDAY_SHIFT
 
 %token <intval> tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN
 %token <intval> tMONTH tORDINAL tZONE
@@ -304,7 +303,7 @@ set_hhmmss (parser_control *pc, long int hour, long int minutes,
 %type <intval> o_colon_minutes o_merid
 %type <timespec> seconds signed_seconds unsigned_seconds
 
-%type <rel> relunit relunit_snumber
+%type <rel> 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;
       }
     }