.
[gnulib.git] / lib / getdate.y
index 851bd9a..cc53fde 100644 (file)
 /* SUPPRESS 288 on yyerrlab *//* Label unused */
 
 #ifdef HAVE_CONFIG_H
-#if defined (emacs) || defined (CONFIG_BROKETS)
 #include <config.h>
-#else
-#include "config.h"
+
+#ifdef FORCE_ALLOCA_H
+#include <alloca.h>
 #endif
 #endif
 
 #include <stdio.h>
 #include <ctype.h>
 
-/* The code at the top of get_date which figures out the offset of the
-   current time zone checks various CPP symbols to see if special
-   tricks are need, but defaults to using the gettimeofday system call.
-   Include <sys/time.h> if that will be used.  */
-
 #if    defined (vms)
-
 #include <types.h>
 #include <time.h>
-
 #else
-
 #include <sys/types.h>
-
 #ifdef TIME_WITH_SYS_TIME
 #include <sys/time.h>
 #include <time.h>
 #if defined (HAVE_SYS_TIMEB_H)
 #include <sys/timeb.h>
 #else
-/*
-** We use the obsolete `struct timeb' as part of our interface!
-** Since the system doesn't have it, we define it here;
-** our callers must do likewise.
-*/
-struct timeb {
+
+/* get_date uses the obsolete `struct timeb' in its interface!  FIXME.
+   Since some systems don't have it, we define it here;
+   callers must do likewise.  */
+struct timeb
+  {
     time_t             time;           /* Seconds since the epoch      */
     unsigned short     millitm;        /* Field not used               */
     short              timezone;       /* Minutes west of GMT          */
@@ -103,6 +94,7 @@ static int yylex ();
 static int yyerror ();
 
 #define EPOCH          1970
+#define DOOMSDAY       2038
 #define HOUR(x)                ((time_t)(x) * 60)
 #define SECSPERDAY     (24L * 60L * 60L)
 
@@ -589,10 +581,14 @@ ToSeconds (Hours, Minutes, Seconds, Meridian)
   case MERam:
     if (Hours < 1 || Hours > 12)
       return -1;
+    if (Hours == 12)
+      Hours = 0;
     return (Hours * 60L + Minutes) * 60L + Seconds;
   case MERpm:
     if (Hours < 1 || Hours > 12)
       return -1;
+    if (Hours == 12)
+      Hours = 0;
     return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
   default:
     abort ();
@@ -621,11 +617,13 @@ Convert (Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
 
   if (Year < 0)
     Year = -Year;
-  if (Year < 100)
+  if (Year < DOOMSDAY-2000)
+    Year += 2000;
+  else if (Year < 100)
     Year += 1900;
   DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
     ? 29 : 28;
-  if (Year < EPOCH || Year > 1999
+  if (Year < EPOCH || Year >= DOOMSDAY
       || Month < 1 || Month > 12
       /* Lint fluff:  "conversion from long may lose accuracy" */
       || Day < 1 || Day > DaysInMonth[(int)--Month])
@@ -690,7 +688,7 @@ RelativeMonth (Start, RelMonth)
   if (RelMonth == 0)
     return 0;
   tm = localtime (&Start);
-  Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
+  Month = 12 * (1900 + tm->tm_year) + tm->tm_mon + RelMonth;
   Year = Month / 12;
   Month = Month % 12 + 1;
   return DSTcorrect (Start,
@@ -753,7 +751,7 @@ LookupWord (buff)
       return tp->type;
     }
 
-  if (strcmp (buff, "dst") == 0) 
+  if (strcmp (buff, "dst") == 0)
     return tDST;
 
   for (tp = UnitsTable; tp->name; tp++)
@@ -904,7 +902,7 @@ get_date (p, now)
 
     if (! (tm = localtime (&ftz.time)))
       return -1;
-       
+
     ftz.timezone = difftm (&gmt, tm) / 60;
     if (tm->tm_isdst)
       ftz.timezone += 60;
@@ -966,11 +964,13 @@ main (ac, av)
     int                ac;
     char       *av[];
 {
-  char buff[128];
-  time_t       d;
+  char buff[MAX_BUFF_LEN + 1];
+  time_t d;
 
   (void)printf ("Enter date, or blank line to exit.\n\t> ");
   (void)fflush (stdout);
+
+  buff[MAX_BUFF_LEN] = 0;
   while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0]) {
     d = get_date (buff, (struct timeb *)NULL);
     if (d == -1)