]> Dogcows Code - chaz/tar/blobdiff - lib/getdate.y
Include stddef.h, for size_t.
[chaz/tar] / lib / getdate.y
index 4b7c2e9c8efb66ad84e1f560f5a0f29e0eb68d7d..3525295bb39854409c3dd3f4e5db46bd823f5711 100644 (file)
@@ -85,7 +85,7 @@
 #define TM_YEAR_BASE 1900
 
 #define HOUR(x) ((x) * 60)
+
 /* An integer value, and the number of digits in its textual
    representation.  */
 typedef struct
@@ -168,7 +168,7 @@ static int yylex ();
 
 /* This grammar has 13 shift/reduce conflicts. */
 %expect 13
+
 %union
 {
   int intval;
@@ -987,13 +987,11 @@ get_date (const char *p, const time_t *now)
     {
       tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
     }
-  tm.tm_hour += pc.rel_hour;
-  tm.tm_min += pc.rel_minutes;
-  tm.tm_sec += pc.rel_seconds;
 
   /* Let mktime deduce tm_isdst if we have an absolute time stamp,
      or if the relative time stamp mentions days, months, or years.  */
-  if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day | pc.rel_month | pc.rel_year)
+  if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
+      | pc.rel_month | pc.rel_year)
     tm.tm_isdst = -1;
 
   /* But if the input explicitly specifies local time with or without
@@ -1040,6 +1038,7 @@ get_date (const char *p, const time_t *now)
     {
       tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
                     + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
+      tm.tm_isdst = -1;
       Start = mktime (&tm);
       if (Start == (time_t) -1)
        return Start;
@@ -1061,6 +1060,29 @@ get_date (const char *p, const time_t *now)
       Start -= delta;
     }
 
+  /* Add relative hours, minutes, and seconds.  Ignore leap seconds;
+     i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
+     leap second.  Typically this is not what the user wants, but it's
+     too hard to do it the other way, because the time zone indicator
+     must be applied before relative times, and if mktime is applied
+     again the time zone will be lost.  */
+  {
+    time_t t0 = Start;
+    long d1 = 60 * 60 * (long) pc.rel_hour;
+    time_t t1 = t0 + d1;
+    long d2 = 60 * (long) pc.rel_minutes;
+    time_t t2 = t1 + d2;
+    int d3 = pc.rel_seconds;
+    time_t t3 = t2 + d3;
+    if ((d1 / (60 * 60) ^ pc.rel_hour)
+       | (d2 / 60 ^ pc.rel_minutes)
+       | ((t0 + d1 < t0) ^ (d1 < 0))
+       | ((t1 + d2 < t1) ^ (d2 < 0))
+       | ((t2 + d3 < t2) ^ (d3 < 0)))
+      return -1;
+    Start = t3;
+  }
+
   return Start;
 }
 
This page took 0.021712 seconds and 4 git commands to generate.