Mon Feb 19 18:31:59 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
authorroland <roland>
Mon, 19 Feb 1996 23:34:18 +0000 (23:34 +0000)
committerroland <roland>
Mon, 19 Feb 1996 23:34:18 +0000 (23:34 +0000)
* time/zic.c, time/scheck.c, time/private.h, time/tzfile.h:
Updated from ADO 96d.

time/private.h
time/scheck.c
time/tzfile.h
time/zic.c

index 651a6f1..6ab33c0 100644 (file)
@@ -16,7 +16,7 @@
 
 #ifndef lint
 #ifndef NOID
-static char    privatehid[] = "@(#)private.h   7.33";
+static char    privatehid[] = "@(#)private.h   7.39";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -37,6 +37,10 @@ static char  privatehid[] = "@(#)private.h   7.33";
 #define HAVE_UNISTD_H          1
 #endif /* !defined HAVE_UNISTD_H */
 
+#ifndef HAVE_UTMPX_H
+#define HAVE_UTMPX_H           0
+#endif /* !defined HAVE_UTMPX_H */
+
 #ifndef LOCALE_HOME
 #define LOCALE_HOME            "/usr/lib/locale"
 #endif /* !defined LOCALE_HOME */
@@ -47,7 +51,6 @@ static char   privatehid[] = "@(#)private.h   7.33";
 
 #include "sys/types.h" /* for time_t */
 #include "stdio.h"
-#include "ctype.h"
 #include "errno.h"
 #include "string.h"
 #include "limits.h"    /* for CHAR_BIT */
@@ -67,6 +70,9 @@ static char   privatehid[] = "@(#)private.h   7.33";
 #endif /* !defined R_OK */
 #endif /* !(HAVE_UNISTD_H - 0) */
 
+/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX.  */
+#define is_digit(c) ((unsigned)(c) - '0' <= 9)
+
 /*
 ** Workarounds for compilers/systems.
 */
@@ -152,15 +158,23 @@ extern int        unlink P((const char * filename));
 #define FALSE  0
 #endif /* !defined FALSE */
 
+#ifndef TYPE_BIT
+#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
+#endif /* !defined TYPE_BIT */
+
+#ifndef TYPE_SIGNED
+#define TYPE_SIGNED(type) (((type) -1) < 0)
+#endif /* !defined TYPE_SIGNED */
+
 #ifndef INT_STRLEN_MAXIMUM
 /*
 ** 302 / 1000 is log10(2.0) rounded up.
-** Subtract one for the sign bit;
+** Subtract one for the sign bit if the type is signed;
 ** add one for integer division truncation;
-** add one more for a minus sign.
+** add one more for a minus sign if the type is signed.
 */
 #define INT_STRLEN_MAXIMUM(type) \
-       ((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2)
+    ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 100 + 1 + TYPE_SIGNED(type))
 #endif /* !defined INT_STRLEN_MAXIMUM */
 
 /*
index 404c6b2..64f2507 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef lint
 #ifndef NOID
-static char    elsieid[] = "@(#)scheck.c       8.12";
+static char    elsieid[] = "@(#)scheck.c       8.13";
 #endif /* !defined lint */
 #endif /* !defined NOID */
 
@@ -42,7 +42,7 @@ char * const          format;
                *tp++ = '*';
                if (*fp == '*')
                        ++fp;
-               while (isascii(*fp) && isdigit(*fp))
+               while (is_digit(*fp))
                        *tp++ = *fp++;
                if (*fp == 'l' || *fp == 'h')
                        *tp++ = *fp++;
index 9c74041..f08134c 100644 (file)
@@ -16,7 +16,7 @@
 
 #ifndef lint
 #ifndef NOID
-static char    tzfilehid[] = "@(#)tzfile.h     7.6";
+static char    tzfilehid[] = "@(#)tzfile.h     7.7";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -153,7 +153,7 @@ struct tzhead {
 ** that will probably do.
 */
 
-#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
 
 #ifndef USG
 
index 5ac24bc..09e73c9 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef lint
 #ifndef NOID
-static char    elsieid[] = "@(#)zic.c  7.50";
+static char    elsieid[] = "@(#)zic.c  7.59";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -10,6 +10,19 @@ static char  elsieid[] = "@(#)zic.c  7.50";
 #include "sys/stat.h"                  /* for umask manifest constants */
 #endif /* defined unix */
 
+/*
+** On some ancient hosts, predicates like `isspace(C)' are defined
+** only if isascii(C) || C == EOF.  Modern hosts obey the C Standard,
+** which says they are defined only if C == ((unsigned char) C) || C == EOF.
+** Neither the C Standard nor Posix require that `isascii' exist.
+** For portability, we check both ancient and modern requirements.
+** If isascii is not defined, the isascii check succeeds trivially.
+*/
+#include "ctype.h"
+#ifndef isascii
+#define isascii(x) 1
+#endif
+
 struct rule {
        const char *    r_filename;
        int             r_linenum;
@@ -127,10 +140,8 @@ static int         errors;
 static const char *    filename;
 static int             leapcnt;
 static int             linenum;
-static int             max_int;
 static time_t          max_time;
 static int             max_year;
-static int             min_int;
 static time_t          min_time;
 static int             min_year;
 static int             noise;
@@ -139,7 +150,6 @@ static int          rlinenum;
 static const char *    progname;
 static int             timecnt;
 static int             typecnt;
-static int             tt_signed;
 
 /*
 ** Line codes.
@@ -567,36 +577,42 @@ const char * const        tofile;
        ifree(toname);
 }
 
+#ifndef INT_MAX
+#define INT_MAX        ((int) (((unsigned)~0)>>1))
+#endif /* !defined INT_MAX */
+
+#ifndef INT_MIN
+#define INT_MIN        ((int) ~(((unsigned)~0)>>1))
+#endif /* !defined INT_MIN */
+
+/*
+** The tz file format currently allows at most 32-bit quantities.
+** This restriction should be removed before signed 32-bit values
+** wrap around in 2038, but unfortunately this will require a
+** change to the tz file format.
+*/
+
+#define MAX_BITS_IN_FILE       32
+#define TIME_T_BITS_IN_FILE    ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? \
+                                       TYPE_BIT(time_t) : MAX_BITS_IN_FILE)
+
 static void
 setboundaries P((void))
 {
-       register time_t bit;
-       register int bii;
-
-       for (bit = 1; bit > 0; bit <<= 1)
-               continue;
-       if (bit == 0) {         /* time_t is an unsigned type */
-               tt_signed = FALSE;
-               min_time = 0;
-               max_time = ~(time_t) 0;
-               if (sflag)
-                       max_time >>= 1;
-       } else {
-               tt_signed = TRUE;
-               min_time = bit;
-               max_time = bit;
-               ++max_time;
-               max_time = -max_time;
+       if (TYPE_SIGNED(time_t)) {
+               min_time = ~ (time_t) 0;
+               min_time <<= TIME_T_BITS_IN_FILE - 1;
+               max_time = ~ (time_t) 0 - min_time;
                if (sflag)
                        min_time = 0;
+       } else {
+               min_time = 0;
+               max_time = 2 - sflag;
+               max_time <<= TIME_T_BITS_IN_FILE - 1;
+               --max_time;
        }
        min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;
        max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;
-
-       for (bii = 1; bii > 0; bii <<= 1)
-               continue;
-       min_int = bii;
-       max_int = -1 - bii;
 }
 
 static int
@@ -716,7 +732,7 @@ const char *        name;
                while (fields[nfields] != NULL) {
                        static char     nada;
 
-                       if (ciequal(fields[nfields], "-"))
+                       if (strcmp(fields[nfields], "-") == 0)
                                fields[nfields] = &nada;
                        ++nfields;
                }
@@ -1031,8 +1047,8 @@ const int         nfields;
                        return;
        }
        dayoff = oadd(dayoff, eitol(day - 1));
-       if (dayoff < 0 && !tt_signed) {
-               error(_("time before zero"));
+       if (dayoff < 0 && !TYPE_SIGNED(time_t)) {
+               error("time before zero");
                return;
        }
        t = (time_t) dayoff * SECSPERDAY;
@@ -1154,10 +1170,10 @@ const char * const              timep;
        lp = byword(cp, begin_years);
        if (lp != NULL) switch ((int) lp->l_value) {
                case YR_MINIMUM:
-                       rp->r_loyear = min_int;
+                       rp->r_loyear = INT_MIN;
                        break;
                case YR_MAXIMUM:
-                       rp->r_loyear = max_int;
+                       rp->r_loyear = INT_MAX;
                        break;
                default:        /* "cannot happen" */
                        (void) fprintf(stderr,
@@ -1171,10 +1187,10 @@ const char * const              timep;
        cp = hiyearp;
        if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) {
                case YR_MINIMUM:
-                       rp->r_hiyear = min_int;
+                       rp->r_hiyear = INT_MIN;
                        break;
                case YR_MAXIMUM:
-                       rp->r_hiyear = max_int;
+                       rp->r_hiyear = INT_MAX;
                        break;
                case YR_ONLY:
                        rp->r_hiyear = rp->r_loyear;
@@ -1698,8 +1714,9 @@ const char * const        type;
 
 static int
 lowerit(a)
-const int      a;
+int    a;
 {
+       a = (unsigned char) a;
        return (isascii(a) && isupper(a)) ? tolower(a) : a;
 }
 
@@ -1723,9 +1740,10 @@ register const char *    word;
                return FALSE;
        ++word;
        while (*++abbr != '\0')
-               do if (*word == '\0')
-                       return FALSE;
-                               while (lowerit(*word++) != lowerit(*abbr));
+               do {
+                       if (*word == '\0')
+                               return FALSE;
+               } while (lowerit(*word++) != lowerit(*abbr));
        return TRUE;
 }
 
@@ -1771,7 +1789,7 @@ register char *   cp;
                emalloc((int) ((strlen(cp) + 1) * sizeof *array));
        nsubs = 0;
        for ( ; ; ) {
-               while (isascii(*cp) && isspace(*cp))
+               while (isascii(*cp) && isspace((unsigned char) *cp))
                        ++cp;
                if (*cp == '\0' || *cp == '#')
                        break;
@@ -1784,8 +1802,8 @@ register char *   cp;
                                        ++dp;
                                else    error(_("Odd number of quotation marks"));
                } while (*cp != '\0' && *cp != '#' &&
-                       (!isascii(*cp) || !isspace(*cp)));
-               if (isascii(*cp) && isspace(*cp))
+                       (!isascii(*cp) || !isspace((unsigned char) *cp)));
+               if (isascii(*cp) && isspace((unsigned char) *cp))
                        ++cp;
                *dp = '\0';
        }
@@ -1841,9 +1859,9 @@ register const int                        wantedy;
        register long   dayoff;                 /* with a nod to Margaret O. */
        register time_t t;
 
-       if (wantedy == min_int)
+       if (wantedy == INT_MIN)
                return min_time;
-       if (wantedy == max_int)
+       if (wantedy == INT_MAX)
                return max_time;
        dayoff = 0;
        m = TM_JANUARY;
@@ -1906,7 +1924,7 @@ register const int                        wantedy;
                        (void) exit(EXIT_FAILURE);
                }
        }
-       if (dayoff < 0 && !tt_signed)
+       if (dayoff < 0 && !TYPE_SIGNED(time_t))
                return min_time;
        t = (time_t) dayoff * SECSPERDAY;
        /*
@@ -1948,8 +1966,8 @@ char * const      argname;
                /*
                ** DOS drive specifier?
                */
-               if (strlen(name) == 2 && isascii(name[0]) &&
-                       isalpha(name[0]) && name[1] == ':') {
+               if (isalpha((unsigned char) name[0]) &&
+                       name[1] == ':' && name[2] == '\0') {
                                *cp = '/';
                                continue;
                }