.
[gnulib.git] / lib / getdate.y
index bff1a9b..f3014fb 100644 (file)
@@ -1,29 +1,52 @@
 %{
-/* $Revision: 2.1 $
-**
+/*
 **  Originally written by Steven M. Bellovin <smb@research.att.com> while
 **  at the University of North Carolina at Chapel Hill.  Later tweaked by
 **  a couple of people on Usenet.  Completely overhauled by Rich $alz
 **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
 **  send any email to Rich.
 **
-**  This grammar has eight shift/reduce conflicts.
+**  This grammar has 10 shift/reduce conflicts.
 **
 **  This code is in the public domain and has no copyright.
 */
-/* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
+/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
 /* SUPPRESS 288 on yyerrlab *//* Label unused */
 
+#ifdef HAVE_CONFIG_H
+#if defined (emacs) || defined (CONFIG_BROKETS)
+#include <config.h>
+#else
+#include "config.h"
+#endif
+#endif
+
+/* Since the code of getdate.y is not included in the Emacs executable
+   itself, there is no need to #define static in this file.  Even if
+   the code were included in the Emacs executable, it probably
+   wouldn't do any harm to #undef it here; this will only cause
+   problems if we try to write to a static variable, which I don't
+   think this code needs to do.  */
+#ifdef emacs
+#undef static
+#endif
+
+/* The following block of alloca-related preprocessor directives is here
+   solely to allow compilation by non GNU-C compilers of the C parser
+   produced from this file by old versions of bison.  Newer versions of
+   bison include a block similar to this one in bison.simple.  */
+
 #ifdef __GNUC__
+#undef alloca
 #define alloca __builtin_alloca
 #else
-#ifdef sparc
+#ifdef HAVE_ALLOCA_H
 #include <alloca.h>
 #else
 #ifdef _AIX /* for Bison */
  #pragma alloca
 #else
-char *alloca ();
+void *alloca ();
 #endif
 #endif
 #endif
@@ -36,10 +59,6 @@ char *alloca ();
    tricks are need, but defaults to using the gettimeofday system call.
    Include <sys/time.h> if that will be used.  */
 
-#if !defined (USG) && !defined (sgi) && !defined (__386BSD__)
-#include <sys/time.h>
-#endif
-
 #if    defined(vms)
 
 #include <types.h>
@@ -49,32 +68,36 @@ char *alloca ();
 
 #include <sys/types.h>
 
-#if    defined(USG) || !defined(HAVE_FTIME)
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+
+#ifdef timezone
+#undef timezone /* needed for sgi */
+#endif
+
+#if defined(HAVE_SYS_TIMEB_H)
+#include <sys/timeb.h>
+#else
 /*
-**  If you need to do a tzset() call to set the
-**  timezone, and don't have ftime().
+** 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 {
     time_t             time;           /* Seconds since the epoch      */
     unsigned short     millitm;        /* Field not used               */
-    short              timezone;
+    short              timezone;       /* Minutes west of GMT          */
     short              dstflag;        /* Field not used               */
 };
-
-#else
-
-#include <sys/timeb.h>
-
-#endif /* defined(USG) && !defined(HAVE_FTIME) */
-
-#if    defined(BSD4_2) || defined(BSD4_1C) || (defined (hp9000) && !defined (hpux))
-#include <sys/time.h>
-#else
-#if defined(_AIX)
-#include <sys/time.h>
-#endif
-#include <time.h>
-#endif /* defined(BSD4_2) */
+#endif /* defined(HAVE_SYS_TIMEB_H) */
 
 #endif /* defined(vms) */
 
@@ -82,16 +105,23 @@ struct timeb {
 #include <string.h>
 #endif
 
-#if sgi
-#undef timezone
+/* Some old versions of bison generate parsers that use bcopy.
+   That loses on systems that don't provide the function, so we have
+   to redefine it here.  */
+#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
+#define bcopy(from, to, len) memcpy ((to), (from), (len))
 #endif
 
+extern struct tm       *gmtime();
 extern struct tm       *localtime();
 
 #define yyparse getdate_yyparse
 #define yylex getdate_yylex
 #define yyerror getdate_yyerror
 
+static int yylex ();
+static int yyerror ();
+
 #if    !defined(lint) && !defined(SABER)
 static char RCS[] =
        "$Header: str2date.y,v 2.1 90/09/06 08:15:06 cronan Exp $";
@@ -271,6 +301,12 @@ date       : tUNUMBER '/' tUNUMBER {
            yyMonth = -$2;
            yyDay = -$3;
        }
+       | tUNUMBER tMONTH tSNUMBER {
+           /* e.g. 17-JUN-1992.  */
+           yyDay = $1;
+           yyMonth = $2;
+           yyYear = -$3;
+       }
        | tMONTH tUNUMBER {
            yyMonth = $1;
            yyDay = $2;
@@ -332,25 +368,24 @@ number    : tUNUMBER {
                yyYear = $1;
            else {
                if($1>10000) {
-                   time_t date_part;
-
-                   date_part= $1/10000;
                    yyHaveDate++;
-                   yyDay= (date_part)%100;
-                   yyMonth= (date_part/100)%100;
-                   yyYear = date_part/10000;
-               } 
-               yyHaveTime++;
-               if ($1 < 100) {
-                   yyHour = $1;
-                   yyMinutes = 0;
+                   yyDay= ($1)%100;
+                   yyMonth= ($1/100)%100;
+                   yyYear = $1/10000;
                }
                else {
-                   yyHour = $1 / 100;
-                   yyMinutes = $1 % 100;
-               }
-               yySeconds = 0;
-               yyMeridian = MER24;
+                   yyHaveTime++;
+                   if ($1 < 100) {
+                       yyHour = $1;
+                       yyMinutes = 0;
+                   }
+                   else {
+                       yyHour = $1 / 100;
+                       yyMinutes = $1 % 100;
+                   }
+                   yySeconds = 0;
+                   yyMeridian = MER24;
+               }
            }
        }
        ;
@@ -366,7 +401,7 @@ o_merid     : /* NULL */ {
 %%
 
 /* Month and day table. */
-static TABLE   MonthDayTable[] = {
+static TABLE const MonthDayTable[] = {
     { "january",       tMONTH,  1 },
     { "february",      tMONTH,  2 },
     { "march",         tMONTH,  3 },
@@ -395,7 +430,7 @@ static TABLE        MonthDayTable[] = {
 };
 
 /* Time units table. */
-static TABLE   UnitsTable[] = {
+static TABLE const UnitsTable[] = {
     { "year",          tMONTH_UNIT,    12 },
     { "month",         tMONTH_UNIT,    1 },
     { "fortnight",     tMINUTE_UNIT,   14 * 24 * 60 },
@@ -410,7 +445,7 @@ static TABLE        UnitsTable[] = {
 };
 
 /* Assorted relative-time words. */
-static TABLE   OtherTable[] = {
+static TABLE const OtherTable[] = {
     { "tomorrow",      tMINUTE_UNIT,   1 * 24 * 60 },
     { "yesterday",     tMINUTE_UNIT,   -1 * 24 * 60 },
     { "today",         tMINUTE_UNIT,   0 },
@@ -436,7 +471,7 @@ static TABLE        OtherTable[] = {
 
 /* The timezone table. */
 /* Some of these are commented out because a time_t can't store a float. */
-static TABLE   TimezoneTable[] = {
+static TABLE const TimezoneTable[] = {
     { "gmt",   tZONE,     HOUR( 0) },  /* Greenwich Mean */
     { "ut",    tZONE,     HOUR( 0) },  /* Universal (Coordinated) */
     { "utc",   tZONE,     HOUR( 0) },
@@ -520,7 +555,7 @@ static TABLE        TimezoneTable[] = {
 };
 
 /* Military timezone table. */
-static TABLE   MilitaryTable[] = {
+static TABLE const MilitaryTable[] = {
     { "a",     tZONE,  HOUR(  1) },
     { "b",     tZONE,  HOUR(  2) },
     { "c",     tZONE,  HOUR(  3) },
@@ -553,7 +588,7 @@ static TABLE        MilitaryTable[] = {
 
 
 /* ARGSUSED */
-int
+static int
 yyerror(s)
     char       *s;
 {
@@ -583,6 +618,8 @@ ToSeconds(Hours, Minutes, Seconds, Meridian)
        if (Hours < 1 || Hours > 12)
            return -1;
        return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
+    default:
+       abort ();
     }
     /* NOTREACHED */
 }
@@ -599,7 +636,7 @@ Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
     MERIDIAN   Meridian;
     DSTMODE    DSTmode;
 {
-    static int DaysInMonth[12] = {
+    static int DaysInMonth[12] = {
        31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
     };
     time_t     tod;
@@ -693,7 +730,7 @@ LookupWord(buff)
 {
     register char      *p;
     register char      *q;
-    register TABLE     *tp;
+    register const TABLE       *tp;
     int                        i;
     int                        abbrev;
 
@@ -794,7 +831,7 @@ LookupWord(buff)
 }
 
 
-int
+static int
 yylex()
 {
     register char      c;
@@ -846,7 +883,6 @@ yylex()
     }
 }
 
-
 time_t
 get_date(p, now)
     char               *p;
@@ -858,37 +894,27 @@ get_date(p, now)
     time_t             tod;
 
     yyInput = p;
-    if (now == NULL) {
+    if (now == NULL)
+      {
+       int tz;
+       struct tm *tmp;
+       time_t epoch = 0;
+
         now = &ftz;
-#if    !defined(HAVE_FTIME)
        (void)time(&ftz.time);
-       /* Set the timezone global. */
-       tzset();
-       {
-#if sgi
-           ftz.timezone = (int) _timezone / 60;
-#else /* not sgi */
-#ifdef __386BSD__
-           ftz.timezone = 0;
-#else /* neither sgi nor 386BSD */
-#if defined (USG)
-           extern time_t timezone;
-
-           ftz.timezone = (int) timezone / 60;
-#else /* neither sgi nor 386BSD nor USG */
-           struct timeval tv;
-           struct timezone tz;
-
-           gettimeofday (&tv, &tz);
-           ftz.timezone = (int) tz.tz_minuteswest;
-#endif /* neither sgi nor 386BSD nor USG */
-#endif /* neither sgi nor 386BSD */
-#endif /* not sgi */
-       }
-#else /* HAVE_FTIME */
-       (void)ftime(&ftz);
-#endif /* HAVE_FTIME */
-    }
+
+       /* Compute local timezone.  Do *not* take daylight savings
+          into account here.  */
+       tmp = localtime (&epoch);
+       tz = tmp->tm_hour * 60 + tmp->tm_min;   /* Minutes east of UTC.  */
+       if (tz > 0)
+         {
+           tz = 24 * 60 - tz;                  /* Minutes west of UTC.  */
+           if (tmp->tm_year == 70)
+             tz -= 24 * 60;                    /* Account for date line.  */
+         }
+       ftz.timezone = tz;
+      }
 
     tm = localtime(&now->time);
     yyYear = tm->tm_year;