diff options
author | wollman <wollman@FreeBSD.org> | 1996-07-18 19:59:09 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1996-07-18 19:59:09 +0000 |
commit | 36419ea6f4f0e22f84d11c7cf2c8c7150a95ca9f (patch) | |
tree | c87a6f4f8e7f4943f8dc430231accbf3c21432d9 | |
parent | 36fc966ce892d8926435297eb927a3101e7bfd0f (diff) | |
download | FreeBSD-src-36419ea6f4f0e22f84d11c7cf2c8c7150a95ca9f.zip FreeBSD-src-36419ea6f4f0e22f84d11c7cf2c8c7150a95ca9f.tar.gz |
Merge from vendor branch. We are now completely up-to-date with
respect to the ADO timezone code.
-rw-r--r-- | usr.sbin/zic/zdump.8 | 5 | ||||
-rw-r--r-- | usr.sbin/zic/zdump.c | 43 | ||||
-rw-r--r-- | usr.sbin/zic/zic.8 | 34 | ||||
-rw-r--r-- | usr.sbin/zic/zic.c | 502 | ||||
-rw-r--r-- | usr.sbin/zic/zic/Makefile | 3 |
5 files changed, 385 insertions, 202 deletions
diff --git a/usr.sbin/zic/zdump.8 b/usr.sbin/zic/zdump.8 index 60a1304..78b17cb 100644 --- a/usr.sbin/zic/zdump.8 +++ b/usr.sbin/zic/zdump.8 @@ -20,8 +20,7 @@ These options are available: For each .I zonename on the command line, -print the current time, -the time at the lowest possible time value, +print the time at the lowest possible time value, the time one day after the lowest possible time value, the times both one second before and exactly at each detected time discontinuity, @@ -37,4 +36,4 @@ otherwise. Cut off the verbose output near the start of the given year. .SH "SEE ALSO" ctime(3), tzfile(5), zic(8) -.\" @(#)zdump.8 7.2 +.\" @(#)zdump.8 7.3 diff --git a/usr.sbin/zic/zdump.c b/usr.sbin/zic/zdump.c index 3288211..1058a84 100644 --- a/usr.sbin/zic/zdump.c +++ b/usr.sbin/zic/zdump.c @@ -1,6 +1,6 @@ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)zdump.c 7.20"; +static char elsieid[] = "@(#)zdump.c 7.24"; #endif /* !defined NOID */ #endif /* !defined lint */ @@ -68,6 +68,11 @@ static char elsieid[] = "@(#)zdump.c 7.20"; #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) #endif /* !defined isleap */ +#if HAVE_GETTEXT - 0 +#include "locale.h" /* for setlocale */ +#include "libintl.h" +#endif /* HAVE_GETTEXT - 0 */ + #ifndef GNUC_or_lint #ifdef lint #define GNUC_or_lint @@ -88,6 +93,24 @@ static char elsieid[] = "@(#)zdump.c 7.20"; #endif /* !defined GNUC_or_lint */ #endif /* !defined INITIALIZE */ +/* +** For the benefit of GNU folk... +** `_(MSGID)' uses the current locale's message library string for MSGID. +** The default is to use gettext if available, and use MSGID otherwise. +*/ + +#ifndef _ +#if HAVE_GETTEXT - 0 +#define _(msgid) gettext(msgid) +#else /* !(HAVE_GETTEXT - 0) */ +#define _(msgid) msgid +#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !defined _ */ + +#ifndef TZ_DOMAIN +#define TZ_DOMAIN "tz" +#endif /* !defined TZ_DOMAIN */ + extern char ** environ; extern int getopt(); extern char * optarg; @@ -122,6 +145,13 @@ char * argv[]; struct tm newtm; INITIALIZE(cuttime); +#if HAVE_GETTEXT - 0 + (void) setlocale(LC_MESSAGES, ""); +#ifdef TZ_DOMAINDIR + (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); +#endif /* defined(TEXTDOMAINDIR) */ + (void) textdomain(TZ_DOMAIN); +#endif /* HAVE_GETTEXT - 0 */ progname = argv[0]; vflag = 0; cutoff = NULL; @@ -132,7 +162,7 @@ char * argv[]; if (c != EOF || (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) { (void) fprintf(stderr, -"%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n", +_("%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n"), argv[0], argv[0]); (void) exit(EXIT_FAILURE); } @@ -178,9 +208,10 @@ char * argv[]; static char buf[MAX_STRING_LENGTH]; (void) strcpy(&fakeenv[0][3], argv[i]); - show(argv[i], now, FALSE); - if (!vflag) + if (!vflag) { + show(argv[i], now, FALSE); continue; + } /* ** Get lowest value of t. */ @@ -224,9 +255,9 @@ char * argv[]; show(argv[i], t, TRUE); } if (fflush(stdout) || ferror(stdout)) { - (void) fprintf(stderr, "%s: Error writing standard output ", + (void) fprintf(stderr, _("%s: Error writing standard output "), argv[0]); - (void) perror("standard output"); + (void) perror(_("standard output")); (void) exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); diff --git a/usr.sbin/zic/zic.8 b/usr.sbin/zic/zic.8 index 8e4db1a..1cd773e 100644 --- a/usr.sbin/zic/zic.8 +++ b/usr.sbin/zic/zic.8 @@ -154,17 +154,7 @@ then the rule applies in all years between .B FROM and .B TO -inclusive; -if -.B TYPE -is -.BR uspres , -the rule applies in U.S. Presidential election years; -if -.B TYPE -is -.BR nonpres , -the rule applies in years other than U.S. Presidential election years. +inclusive. If .B TYPE is something else, then @@ -219,14 +209,18 @@ Any of these forms may be followed by the letter .B w if the given time is local .q "wall clock" -time or +time, .B s if the given time is local .q standard -time; in the absence of -.B w +time, or +.B u +(or +.B g or -.BR s , +.BR z ) +if the given time is universal time; +in the absence of an indicator, wall clock time is assumed. .TP .B SAVE @@ -300,6 +294,9 @@ The pair of characters is used to show where the .q "variable part" of the time zone abbreviation goes. +Alternately, +a slash (/) +separates standard and daylight abbreviations. .TP .B UNTIL The time at which the GMT offset or the rule(s) change for a location. @@ -326,14 +323,13 @@ A link line has the form .sp .nf .ti +.5i -.if t .ta \w'Link\0\0'u +\w'LINK-FROM\0\0'u -.if n .ta \w'Link\0\0'u +\w'US/Eastern\0\0'u +.ta \w'Link\0\0'u +\w'Europe/Istanbul\0\0'u Link LINK-FROM LINK-TO .sp For example: .sp .ti +.5i -Link US/Eastern EST5EDT +Link Europe/Istanbul Asia/Istanbul .sp .fi The @@ -409,4 +405,4 @@ the earliest transition time recorded in the compiled file is correct. /usr/share/zoneinfo standard directory used for created files .SH "SEE ALSO" ctime(3), tzfile(5), zdump(8) -.\" @(#)zic.8 7.7 +.\" @(#)zic.8 7.12 diff --git a/usr.sbin/zic/zic.c b/usr.sbin/zic/zic.c index 3959039..d1b7760 100644 --- a/usr.sbin/zic/zic.c +++ b/usr.sbin/zic/zic.c @@ -1,15 +1,29 @@ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)zic.c 7.50"; +static char elsieid[] = "@(#)zic.c 7.77"; #endif /* !defined NOID */ #endif /* !defined lint */ #include "private.h" +#include "locale.h" #include "tzfile.h" #include <sys/stat.h> /* for umask manifest constants */ #include <sys/types.h> #include <unistd.h> +/* +** 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; @@ -122,15 +136,17 @@ static void usage P((void)); static void writezone P((const char * name)); static int yearistype P((int year, const char * type)); +#if !HAVE_STRERROR +static char * strerror P((int)); +#endif /* !HAVE_STRERROR */ + static int charcnt; 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 +155,6 @@ static int rlinenum; static const char * progname; static int timecnt; static int typecnt; -static int tt_signed; /* ** Line codes. @@ -320,8 +335,10 @@ static const int len_years[2] = { DAYSPERNYEAR, DAYSPERLYEAR }; -static time_t ats[TZ_MAX_TIMES]; -static unsigned char types[TZ_MAX_TIMES]; +static struct attype { + time_t at; + unsigned char type; +} attypes[TZ_MAX_TIMES]; static long gmtoffs[TZ_MAX_TYPES]; static char isdsts[TZ_MAX_TYPES]; static unsigned char abbrinds[TZ_MAX_TYPES]; @@ -341,7 +358,9 @@ memcheck(ptr) char * const ptr; { if (ptr == NULL) { - (void) perror(progname); + const char *e = strerror(errno); + (void) fprintf(stderr, _("%s: Memory exhausted: %s\n"), + progname, e); (void) exit(EXIT_FAILURE); } return ptr; @@ -356,6 +375,20 @@ char * const ptr; ** Error handling. */ +#if ! HAVE_STRERROR +static char * +strerror(errnum) +int errnum; +{ + extern char *sys_errlist[]; + extern int sys_nerr; + + if (errnum > 0 && errnum <= sys_nerr) + return sys_errlist[errnum]; + return "Unknown system error"; +} +#endif /* ! HAVE_STRERROR */ + static void eats(name, num, rname, rnum) const char * const name; @@ -386,21 +419,32 @@ const char * const string; ** zic ... 2>&1 | error -t "*" -v ** on BSD systems. */ - (void) fprintf(stderr, "\"%s\", line %d: %s", + (void) fprintf(stderr, _("\"%s\", line %d: %s"), filename, linenum, string); if (rfilename != NULL) - (void) fprintf(stderr, " (rule from \"%s\", line %d)", + (void) fprintf(stderr, _(" (rule from \"%s\", line %d)"), rfilename, rlinenum); (void) fprintf(stderr, "\n"); ++errors; } static void +warning(string) +const char * const string; +{ + char * cp; + + cp = ecpyalloc("warning: "); + cp = ecatalloc(cp, string); + error(string); + ifree(cp); + --errors; +} + +static void usage P((void)) { - (void) fprintf(stderr, "%s: usage is %s \ -[ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ]\n\ -\t[ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n", + (void) fprintf(stderr, _("%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ]\n\t[ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"), progname, progname); (void) exit(EXIT_FAILURE); } @@ -424,6 +468,13 @@ char * argv[]; #ifdef unix (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); #endif /* defined unix */ +#if HAVE_GETTEXT - 0 + (void) setlocale(LC_MESSAGES, ""); +#ifdef TZ_DOMAINDIR + (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); +#endif /* defined TEXTDOMAINDIR */ + (void) textdomain(TZ_DOMAIN); +#endif /* HAVE_GETTEXT - 0 */ progname = argv[0]; while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF) switch (c) { @@ -434,7 +485,7 @@ char * argv[]; directory = optarg; else { (void) fprintf(stderr, -"%s: More than one -d option specified\n", +_("%s: More than one -d option specified\n"), progname); (void) exit(EXIT_FAILURE); } @@ -444,7 +495,7 @@ char * argv[]; lcltime = optarg; else { (void) fprintf(stderr, -"%s: More than one -l option specified\n", +_("%s: More than one -l option specified\n"), progname); (void) exit(EXIT_FAILURE); } @@ -454,7 +505,7 @@ char * argv[]; psxrules = optarg; else { (void) fprintf(stderr, -"%s: More than one -p option specified\n", +_("%s: More than one -p option specified\n"), progname); (void) exit(EXIT_FAILURE); } @@ -464,7 +515,7 @@ char * argv[]; yitcommand = optarg; else { (void) fprintf(stderr, -"%s: More than one -y option specified\n", +_("%s: More than one -y option specified\n"), progname); (void) exit(EXIT_FAILURE); } @@ -474,7 +525,7 @@ char * argv[]; leapsec = optarg; else { (void) fprintf(stderr, -"%s: More than one -L option specified\n", +_("%s: More than one -L option specified\n"), progname); (void) exit(EXIT_FAILURE); } @@ -557,9 +608,10 @@ const char * const tofile; if (mkdirs(toname) != 0) (void) exit(EXIT_FAILURE); if (link(fromname, toname) != 0) { - (void) fprintf(stderr, "%s: Can't link from %s to ", - progname, fromname); - (void) perror(toname); + const char *e = strerror(errno); + (void) fprintf(stderr, + _("%s: Can't link from %s to %s: %s\n"), + progname, fromname, toname, e); (void) exit(EXIT_FAILURE); } } @@ -567,36 +619,41 @@ 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 @@ -636,11 +693,37 @@ associate P((void)) register struct zone * zp; register struct rule * rp; register int base, out; - register int i; + register int i, j; - if (nrules != 0) + if (nrules != 0) { (void) qsort((void *) rules, (size_t) nrules, (size_t) sizeof *rules, rcomp); + for (i = 0; i < nrules - 1; ++i) { + if (strcmp(rules[i].r_name, + rules[i + 1].r_name) != 0) + continue; + if (strcmp(rules[i].r_filename, + rules[i + 1].r_filename) == 0) + continue; + eat(rules[i].r_filename, rules[i].r_linenum); + warning(_("same rule name in multiple files")); + eat(rules[i + 1].r_filename, rules[i + 1].r_linenum); + warning(_("same rule name in multiple files")); + for (j = i + 2; j < nrules; ++j) { + if (strcmp(rules[i].r_name, + rules[j].r_name) != 0) + break; + if (strcmp(rules[i].r_filename, + rules[j].r_filename) == 0) + continue; + if (strcmp(rules[i + 1].r_filename, + rules[j].r_filename) == 0) + continue; + break; + } + i = j - 1; + } + } for (i = 0; i < nzones; ++i) { zp = &zones[i]; zp->z_rules = NULL; @@ -666,13 +749,14 @@ associate P((void)) ** Maybe we have a local standard time offset. */ eat(zp->z_filename, zp->z_linenum); - zp->z_stdoff = gethms(zp->z_rule, "unruly zone", TRUE); + zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), + TRUE); /* ** Note, though, that if there's no rule, ** a '%s' in the format is a bad thing. */ if (strchr(zp->z_format, '%') != 0) - error("%s in ruleless zone"); + error(_("%s in ruleless zone")); } } if (errors) @@ -693,11 +777,12 @@ const char * name; char buf[BUFSIZ]; if (strcmp(name, "-") == 0) { - name = "standard input"; + name = _("standard input"); fp = stdin; } else if ((fp = fopen(name, "r")) == NULL) { - (void) fprintf(stderr, "%s: Can't open ", progname); - (void) perror(name); + const char *e = strerror(errno); + (void) fprintf(stderr, _("%s: Can't open %s: %s\n"), + progname, name, e); (void) exit(EXIT_FAILURE); } wantcont = FALSE; @@ -707,7 +792,7 @@ const char * name; break; cp = strchr(buf, '\n'); if (cp == NULL) { - error("line too long"); + error(_("line too long")); (void) exit(EXIT_FAILURE); } *cp = '\0'; @@ -716,7 +801,7 @@ const char * name; while (fields[nfields] != NULL) { static char nada; - if (ciequal(fields[nfields], "-")) + if (strcmp(fields[nfields], "-") == 0) fields[nfields] = &nada; ++nfields; } @@ -727,7 +812,7 @@ const char * name; } else { lp = byword(fields[0], line_codes); if (lp == NULL) - error("input line of unknown type"); + error(_("input line of unknown type")); else switch ((int) (lp->l_value)) { case LC_RULE: inrule(fields, nfields); @@ -743,14 +828,14 @@ const char * name; case LC_LEAP: if (name != leapsec) (void) fprintf(stderr, -"%s: Leap line in non leap seconds file %s\n", +_("%s: Leap line in non leap seconds file %s\n"), progname, name); else inleap(fields, nfields); wantcont = FALSE; break; default: /* "cannot happen" */ (void) fprintf(stderr, -"%s: panic: Invalid l_value %d\n", +_("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); (void) exit(EXIT_FAILURE); } @@ -758,17 +843,18 @@ const char * name; ifree((char *) fields); } if (ferror(fp)) { - (void) fprintf(stderr, "%s: Error reading ", progname); - (void) perror(filename); + (void) fprintf(stderr, _("%s: Error reading %s\n"), + progname, filename); (void) exit(EXIT_FAILURE); } if (fp != stdin && fclose(fp)) { - (void) fprintf(stderr, "%s: Error closing ", progname); - (void) perror(filename); + const char *e = strerror(errno); + (void) fprintf(stderr, _("%s: Error closing %s: %s\n"), + progname, filename, e); (void) exit(EXIT_FAILURE); } if (wantcont) - error("expected continuation line not found"); + error(_("expected continuation line not found")); } /* @@ -823,16 +909,16 @@ const int nfields; static struct rule r; if (nfields != RULE_FIELDS) { - error("wrong number of fields on Rule line"); + error(_("wrong number of fields on Rule line")); return; } if (*fields[RF_NAME] == '\0') { - error("nameless rule"); + error(_("nameless rule")); return; } r.r_filename = filename; r.r_linenum = linenum; - r.r_stdoff = gethms(fields[RF_STDOFF], "invalid saved time", TRUE); + r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), TRUE); rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND], fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); r.r_name = ecpyalloc(fields[RF_NAME]); @@ -851,13 +937,13 @@ const int nfields; static char * buf; if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) { - error("wrong number of fields on Zone line"); + error(_("wrong number of fields on Zone line")); return FALSE; } if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) { buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT))); (void) sprintf(buf, -"\"Zone %s\" line and -l option are mutually exclusive", +_("\"Zone %s\" line and -l option are mutually exclusive"), TZDEFAULT); error(buf); return FALSE; @@ -865,7 +951,7 @@ const int nfields; if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) { buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES))); (void) sprintf(buf, -"\"Zone %s\" line and -p option are mutually exclusive", +_("\"Zone %s\" line and -p option are mutually exclusive"), TZDEFRULES); error(buf); return FALSE; @@ -877,7 +963,7 @@ const int nfields; strlen(fields[ZF_NAME]) + strlen(zones[i].z_filename))); (void) sprintf(buf, -"duplicate zone name %s (file \"%s\", line %d)", +_("duplicate zone name %s (file \"%s\", line %d)"), fields[ZF_NAME], zones[i].z_filename, zones[i].z_linenum); @@ -893,7 +979,7 @@ register char ** const fields; const int nfields; { if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) { - error("wrong number of fields on Zone continuation line"); + error(_("wrong number of fields on Zone continuation line")); return FALSE; } return inzsub(fields, nfields, TRUE); @@ -933,10 +1019,10 @@ const int iscont; } z.z_filename = filename; z.z_linenum = linenum; - z.z_gmtoff = gethms(fields[i_gmtoff], "invalid GMT offset", TRUE); + z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid GMT offset"), TRUE); if ((cp = strchr(fields[i_format], '%')) != 0) { if (*++cp != 's' || strchr(cp, '%') != 0) { - error("invalid abbreviation format"); + error(_("invalid abbreviation format")); return FALSE; } } @@ -962,8 +1048,7 @@ const int iscont; zones[nzones - 1].z_untiltime > min_time && zones[nzones - 1].z_untiltime < max_time && zones[nzones - 1].z_untiltime >= z.z_untiltime) { - error("Zone continuation line end time is not \ -after end time of previous line"); + error(_("Zone continuation line end time is not after end time of previous line")); return FALSE; } } @@ -990,7 +1075,7 @@ const int nfields; time_t t; if (nfields != LEAP_FIELDS) { - error("wrong number of fields on Leap line"); + error(_("wrong number of fields on Leap line")); return; } dayoff = 0; @@ -999,7 +1084,7 @@ const int nfields; /* * Leapin' Lizards! */ - error("invalid leaping year"); + error(_("invalid leaping year")); return; } j = EPOCH_YEAR; @@ -1014,7 +1099,7 @@ const int nfields; dayoff = oadd(dayoff, eitol(i)); } if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) { - error("invalid month name"); + error(_("invalid month name")); return; } month = lp->l_value; @@ -1027,12 +1112,12 @@ const int nfields; cp = fields[LP_DAY]; if (sscanf(cp, scheck(cp, "%d"), &day) != 1 || day <= 0 || day > len_months[isleap(year)][month]) { - error("invalid day of month"); + error(_("invalid day of month")); 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; @@ -1040,10 +1125,10 @@ const int nfields; ** Cheap overflow check. */ if (t / SECSPERDAY != dayoff) { - error("time overflow"); + error(_("time overflow")); return; } - tod = gethms(fields[LP_TIME], "invalid time of day", FALSE); + tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE); cp = fields[LP_CORR]; { register int positive; @@ -1062,11 +1147,11 @@ const int nfields; positive = TRUE; count = 2; } else { - error("illegal CORRECTION field on Leap line"); + error(_("illegal CORRECTION field on Leap line")); return; } if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { - error("illegal Rolling/Stationary field on Leap line"); + error(_("illegal Rolling/Stationary field on Leap line")); return; } leapadd(tadd(t, tod), positive, lp->l_value, count); @@ -1081,15 +1166,15 @@ const int nfields; struct link l; if (nfields != LINK_FIELDS) { - error("wrong number of fields on Link line"); + error(_("wrong number of fields on Link line")); return; } if (*fields[LF_FROM] == '\0') { - error("blank FROM field on Link line"); + error(_("blank FROM field on Link line")); return; } if (*fields[LF_TO] == '\0') { - error("blank TO field on Link line"); + error(_("blank TO field on Link line")); return; } l.l_filename = filename; @@ -1117,7 +1202,7 @@ const char * const timep; register char * ep; if ((lp = byword(monthp, mon_names)) == NULL) { - error("invalid month name"); + error(_("invalid month name")); return; } rp->r_month = lp->l_value; @@ -1145,7 +1230,7 @@ const char * const timep; break; } } - rp->r_tod = gethms(dp, "invalid time of day", FALSE); + rp->r_tod = gethms(dp, _("invalid time of day"), FALSE); ifree(dp); /* ** Year work. @@ -1154,49 +1239,49 @@ 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, - "%s: panic: Invalid l_value %d\n", + _("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); (void) exit(EXIT_FAILURE); } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { - error("invalid starting year"); + error(_("invalid starting year")); return; } 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; break; default: /* "cannot happen" */ (void) fprintf(stderr, - "%s: panic: Invalid l_value %d\n", + _("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); (void) exit(EXIT_FAILURE); } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { - error("invalid ending year"); + error(_("invalid ending year")); return; } if (rp->r_loyear > rp->r_hiyear) { - error("starting year greater than ending year"); + error(_("starting year greater than ending year")); return; } if (*typep == '\0') rp->r_yrtype = NULL; else { if (rp->r_loyear == rp->r_hiyear) { - error("typed single year"); + error(_("typed single year")); return; } rp->r_yrtype = ecpyalloc(typep); @@ -1226,12 +1311,12 @@ const char * const timep; if (rp->r_dycode != DC_DOM) { *ep++ = 0; if (*ep++ != '=') { - error("invalid day of month"); + error(_("invalid day of month")); ifree(dp); return; } if ((lp = byword(dp, wday_names)) == NULL) { - error("invalid weekday name"); + error(_("invalid weekday name")); ifree(dp); return; } @@ -1240,7 +1325,7 @@ const char * const timep; if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 || rp->r_dayofmonth <= 0 || (rp->r_dayofmonth > len_months[1][rp->r_month])) { - error("invalid day of month"); + error(_("invalid day of month")); ifree(dp); return; } @@ -1271,6 +1356,18 @@ FILE * const fp; (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); } +static int +atcomp(avp, bvp) +void * avp; +void * bvp; +{ + if (((struct attype *) avp)->at < ((struct attype *) bvp)->at) + return -1; + else if (((struct attype *) avp)->at > ((struct attype *) bvp)->at) + return 1; + else return 0; +} + static void writezone(name) const char * const name; @@ -1279,7 +1376,50 @@ const char * const name; register int i, j; static char * fullname; static struct tzhead tzh; + time_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; + /* + ** Sort. + */ + if (timecnt > 1) + (void) qsort((void *) attypes, (size_t) timecnt, + (size_t) sizeof *attypes, atcomp); + /* + ** Optimize. + */ + { + int fromi; + int toi; + + toi = 0; + fromi = 0; + if (isdsts[0] == 0) + while (attypes[fromi].type == 0) + ++fromi; /* handled by default rule */ + for ( ; fromi < timecnt; ++fromi) { + if (toi != 0 + && ((attypes[fromi].at + + gmtoffs[attypes[toi - 1].type]) + <= (attypes[toi - 1].at + + gmtoffs[toi == 1 ? 0 + : attypes[toi - 2].type]))) { + attypes[toi - 1].type = attypes[fromi].type; + continue; + } + if (toi == 0 || + attypes[toi - 1].type != attypes[fromi].type) + attypes[toi++] = attypes[fromi]; + } + timecnt = toi; + } + /* + ** Transfer. + */ + for (i = 0; i < timecnt; ++i) { + ats[i] = attypes[i].at; + types[i] = attypes[i].type; + } fullname = erealloc(fullname, (int) (strlen(directory) + 1 + strlen(name) + 1)); (void) sprintf(fullname, "%s/%s", directory, name); @@ -1287,8 +1427,9 @@ const char * const name; if (mkdirs(fullname) != 0) (void) exit(EXIT_FAILURE); if ((fp = fopen(fullname, "wb")) == NULL) { - (void) fprintf(stderr, "%s: Can't create ", progname); - (void) perror(fullname); + const char *e = strerror(errno); + (void) fprintf(stderr, _("%s: Can't create %s: %s\n"), + progname, fullname, e); (void) exit(EXIT_FAILURE); } } @@ -1298,8 +1439,7 @@ const char * const name; convert(eitol(timecnt), tzh.tzh_timecnt); convert(eitol(typecnt), tzh.tzh_typecnt); convert(eitol(charcnt), tzh.tzh_charcnt); -#define DO(field) (void) fwrite((void *) tzh.field, \ - (size_t) sizeof tzh.field, (size_t) 1, fp) +#define DO(field) (void) fwrite((void *) tzh.field, (size_t) sizeof tzh.field, (size_t) 1, fp) DO(tzh_reserved); DO(tzh_ttisgmtcnt); DO(tzh_ttisstdcnt); @@ -1352,8 +1492,8 @@ const char * const name; for (i = 0; i < typecnt; ++i) (void) putc(ttisgmts[i], fp); if (ferror(fp) || fclose(fp)) { - (void) fprintf(stderr, "%s: Write error on ", progname); - (void) perror(fullname); + (void) fprintf(stderr, _("%s: Error writing %s\n"), + progname, fullname); (void) exit(EXIT_FAILURE); } } @@ -1391,7 +1531,6 @@ const int zonecount; register long stdoff; register int year; register long startoff; - register int startisdst; register int startttisstd; register int startttisgmt; register int type; @@ -1399,7 +1538,6 @@ const int zonecount; INITIALIZE(untiltime); INITIALIZE(starttime); - INITIALIZE(startoff); /* ** Now. . .finally. . .generate some useful data! */ @@ -1424,7 +1562,8 @@ const int zonecount; continue; gmtoff = zp->z_gmtoff; eat(zp->z_filename, zp->z_linenum); - startisdst = -1; + *startbuf = '\0'; + startoff = zp->z_gmtoff; if (zp->z_nrules == 0) { stdoff = zp->z_stdoff; doabbr(startbuf, zp->z_format, @@ -1432,8 +1571,10 @@ const int zonecount; type = addtype(oadd(zp->z_gmtoff, stdoff), startbuf, stdoff != 0, startttisstd, startttisgmt); - if (usestart) + if (usestart) { addtt(starttime, type); + usestart = FALSE; + } else if (stdoff != 0) addtt(min_time, type); } else for (year = min_year; year <= max_year; ++year) { @@ -1504,36 +1645,25 @@ const int zonecount; rp->r_todo = FALSE; if (useuntil && ktime >= untiltime) break; + stdoff = rp->r_stdoff; + if (usestart && ktime == starttime) + usestart = FALSE; if (usestart) { - if (ktime < starttime) { - stdoff = rp->r_stdoff; - startoff = oadd(zp->z_gmtoff, - rp->r_stdoff); - doabbr(startbuf, zp->z_format, - rp->r_abbrvar, - rp->r_stdoff != 0); - startisdst = rp->r_stdoff != 0; - continue; - } - usestart = FALSE; - if (ktime != starttime) { - if (startisdst < 0 && - zp->z_gmtoff != - (zp - 1)->z_gmtoff) { - type = (timecnt == 0) ? 0 : - types[timecnt - 1]; - startoff = oadd(gmtoffs[type], - -(zp - 1)->z_gmtoff); - startisdst = startoff != 0; - startoff = oadd(startoff, - zp->z_gmtoff); - (void) strcpy(startbuf, - &chars[abbrinds[type]]); + if (ktime < starttime) { + startoff = oadd(zp->z_gmtoff, + stdoff); + doabbr(startbuf, zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != 0); + continue; + } + if (*startbuf == '\0' && + startoff == oadd(zp->z_gmtoff, + stdoff)) { + doabbr(startbuf, zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != 0); } - if (startisdst >= 0) -addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd, - startttisgmt)); - } } eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); @@ -1543,18 +1673,34 @@ addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd, type = addtype(offset, buf, rp->r_stdoff != 0, rp->r_todisstd, rp->r_todisgmt); addtt(ktime, type); - stdoff = rp->r_stdoff; } } + if (usestart) { + if (*startbuf == '\0' && + zp->z_format != NULL && + strchr(zp->z_format, '%') == NULL && + strchr(zp->z_format, '/') == NULL) + (void) strcpy(startbuf, zp->z_format); + eat(zp->z_filename, zp->z_linenum); + if (*startbuf == '\0') +error(_("can't determine time zone abbrevation to use just after until time")); + else addtt(starttime, + addtype(startoff, startbuf, + startoff != zp->z_gmtoff, + startttisstd, + startttisgmt)); + } /* ** Now we may get to set starttime for the next zone line. */ if (useuntil) { - starttime = tadd(zp->z_untiltime, -gmtoff); startttisstd = zp->z_untilrule.r_todisstd; startttisgmt = zp->z_untilrule.r_todisgmt; + starttime = zp->z_untiltime; if (!startttisstd) starttime = tadd(starttime, -stdoff); + if (!startttisgmt) + starttime = tadd(starttime, -gmtoff); } } writezone(zpfirst->z_name); @@ -1565,16 +1711,12 @@ addtt(starttime, type) const time_t starttime; const int type; { - if (timecnt != 0 && type == types[timecnt - 1]) - return; /* easy enough! */ - if (timecnt == 0 && type == 0 && isdsts[0] == 0) - return; /* handled by default rule */ if (timecnt >= TZ_MAX_TIMES) { - error("too many transitions?!"); + error(_("too many transitions?!")); (void) exit(EXIT_FAILURE); } - ats[timecnt] = starttime; - types[timecnt] = type; + attypes[timecnt].at = starttime; + attypes[timecnt].type = type; ++timecnt; } @@ -1588,6 +1730,18 @@ const int ttisgmt; { register int i, j; + if (isdst != TRUE && isdst != FALSE) { + error(_("internal error - addtype called with bad isdst")); + (void) exit(EXIT_FAILURE); + } + if (ttisstd != TRUE && ttisstd != FALSE) { + error(_("internal error - addtype called with bad ttisstd")); + (void) exit(EXIT_FAILURE); + } + if (ttisgmt != TRUE && ttisgmt != FALSE) { + error(_("internal error - addtype called with bad ttisgmt")); + (void) exit(EXIT_FAILURE); + } /* ** See if there's already an entry for this zone type. ** If so, just return its index. @@ -1604,7 +1758,7 @@ const int ttisgmt; ** many. */ if (typecnt >= TZ_MAX_TYPES) { - error("too many local time types"); + error(_("too many local time types")); (void) exit(EXIT_FAILURE); } gmtoffs[i] = gmtoff; @@ -1632,13 +1786,13 @@ int count; register int i, j; if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { - error("too many leap seconds"); + error(_("too many leap seconds")); (void) exit(EXIT_FAILURE); } for (i = 0; i < leapcnt; ++i) if (t <= trans[i]) { if (t == trans[i]) { - error("repeated leap second moment"); + error(_("repeated leap second moment")); (void) exit(EXIT_FAILURE); } break; @@ -1688,8 +1842,8 @@ const char * const type; return TRUE; if (result == (1 << 8)) return FALSE; - error("Wild result from command execution"); - (void) fprintf(stderr, "%s: command was '%s', result was %d\n", + error(_("Wild result from command execution")); + (void) fprintf(stderr, _("%s: command was '%s', result was %d\n"), progname, buf, result); for ( ; ; ) (void) exit(EXIT_FAILURE); @@ -1697,8 +1851,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; } @@ -1722,9 +1877,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; } @@ -1770,7 +1926,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; @@ -1781,10 +1937,10 @@ register char * cp; else while ((*dp = *cp++) != '"') if (*dp != '\0') ++dp; - else error("Odd number of quotation marks"); + 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'; } @@ -1801,7 +1957,7 @@ const long t2; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { - error("time overflow"); + error(_("time overflow")); (void) exit(EXIT_FAILURE); } return t; @@ -1820,7 +1976,7 @@ const long t2; return min_time; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { - error("time overflow"); + error(_("time overflow")); (void) exit(EXIT_FAILURE); } return t; @@ -1840,9 +1996,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; @@ -1867,7 +2023,7 @@ register const int wantedy; if (rp->r_dycode == DC_DOWLEQ) --i; else { - error("use of 2/29 in non leap-year"); + error(_("use of 2/29 in non leap-year")); (void) exit(EXIT_FAILURE); } } @@ -1901,11 +2057,11 @@ register const int wantedy; --i; } if (i < 0 || i >= len_months[isleap(y)][m]) { - error("no day in month matches rule"); + error(_("no day in month matches rule")); (void) exit(EXIT_FAILURE); } } - if (dayoff < 0 && !tt_signed) + if (dayoff < 0 && !TYPE_SIGNED(time_t)) return min_time; t = (time_t) dayoff * SECSPERDAY; /* @@ -1924,7 +2080,7 @@ const char * const string; i = strlen(string) + 1; if (charcnt + i > TZ_MAX_CHARS) { - error("too many, or too long, time zone abbreviations"); + error(_("too many, or too long, time zone abbreviations")); (void) exit(EXIT_FAILURE); } (void) strcpy(&chars[charcnt], string); @@ -1947,8 +2103,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; } @@ -1958,10 +2114,10 @@ char * const argname; ** It doesn't seem to exist, so we try to create it. */ if (mkdir(name, 0755) != 0) { + const char *e = strerror(errno); (void) fprintf(stderr, - "%s: Can't create directory ", - progname); - (void) perror(name); + _("%s: Can't create directory %s: %s\n"), + progname, name, e); ifree(name); return -1; } @@ -1981,7 +2137,7 @@ const int i; l = i; if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0)) { (void) fprintf(stderr, - "%s: %d did not sign extend correctly\n", + _("%s: %d did not sign extend correctly\n"), progname, i); (void) exit(EXIT_FAILURE); } diff --git a/usr.sbin/zic/zic/Makefile b/usr.sbin/zic/zic/Makefile index 5331112..98dbbc1 100644 --- a/usr.sbin/zic/zic/Makefile +++ b/usr.sbin/zic/zic/Makefile @@ -1,4 +1,4 @@ -# $Id$ +# $Id: Makefile,v 1.1 1994/09/13 03:36:16 wollman Exp $ .PATH: ${.CURDIR}/.. @@ -9,5 +9,6 @@ MAN8= ${.CURDIR}/../zic.8 CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir +CFLAGS+= -DHAVE_STRERROR -DHAVE_UNISTD_H .include <bsd.prog.mk> |