#ifndef lint
#ifndef NOID
-static char privatehid[] = "@(#)private.h 7.33";
+static char privatehid[] = "@(#)private.h 7.39";
#endif /* !defined NOID */
#endif /* !defined lint */
#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 */
#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 */
#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.
*/
#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 */
/*
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)zic.c 7.50";
+static char elsieid[] = "@(#)zic.c 7.59";
#endif /* !defined NOID */
#endif /* !defined lint */
#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;
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;
static const char * progname;
static int timecnt;
static int typecnt;
-static int tt_signed;
/*
** Line codes.
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
while (fields[nfields] != NULL) {
static char nada;
- if (ciequal(fields[nfields], "-"))
+ if (strcmp(fields[nfields], "-") == 0)
fields[nfields] = &nada;
++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;
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,
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;
static int
lowerit(a)
-const int a;
+int a;
{
+ a = (unsigned char) a;
return (isascii(a) && isupper(a)) ? tolower(a) : a;
}
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;
}
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;
++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';
}
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;
(void) exit(EXIT_FAILURE);
}
}
- if (dayoff < 0 && !tt_signed)
+ if (dayoff < 0 && !TYPE_SIGNED(time_t))
return min_time;
t = (time_t) dayoff * SECSPERDAY;
/*
/*
** 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;
}