diff options
Diffstat (limited to 'time')
-rw-r--r-- | time/private.h | 24 | ||||
-rw-r--r-- | time/scheck.c | 4 | ||||
-rw-r--r-- | time/tzfile.h | 4 | ||||
-rw-r--r-- | time/zic.c | 108 |
4 files changed, 86 insertions, 54 deletions
diff --git a/time/private.h b/time/private.h index 651a6f1..6ab33c0 100644 --- a/time/private.h +++ b/time/private.h @@ -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 */ /* diff --git a/time/scheck.c b/time/scheck.c index 404c6b2..64f2507 100644 --- a/time/scheck.c +++ b/time/scheck.c @@ -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++; diff --git a/time/tzfile.h b/time/tzfile.h index 9c74041..f08134c 100644 --- a/time/tzfile.h +++ b/time/tzfile.h @@ -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 @@ -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; } |