diff options
Diffstat (limited to 'timezone/zic.c')
-rw-r--r-- | timezone/zic.c | 988 |
1 files changed, 265 insertions, 723 deletions
diff --git a/timezone/zic.c b/timezone/zic.c index f7393ea7ba..9bb8662e55 100644 --- a/timezone/zic.c +++ b/timezone/zic.c @@ -1,22 +1,9 @@ -/* -** This file is in the public domain, so clarified as of -** 2006-07-17 by Arthur David Olson. -*/ - -static char elsieid[] = "@(#)zic.c 8.7"; +static char elsieid[] = "@(#)zic.c 7.116"; #include "private.h" #include "locale.h" #include "tzfile.h" -#define ZIC_VERSION '2' - -typedef int_fast64_t zic_t; - -#ifndef ZIC_MAX_ABBR_LEN_WO_WARN -#define ZIC_MAX_ABBR_LEN_WO_WARN 6 -#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */ - #if HAVE_SYS_STAT_H #include "sys/stat.h" #endif @@ -28,7 +15,7 @@ typedef int_fast64_t zic_t; /* ** On some ancient hosts, predicates like `isspace(C)' are defined -** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, +** 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. @@ -39,11 +26,6 @@ typedef int_fast64_t zic_t; #define isascii(x) 1 #endif -#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long)) -#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */ - -#define end(cp) (strchr((cp), '\0')) - struct rule { const char * r_filename; int r_linenum; @@ -52,8 +34,6 @@ struct rule { int r_loyear; /* for example, 1986 */ int r_hiyear; /* for example, 1986 */ const char * r_yrtype; - int r_lowasnum; - int r_hiwasnum; int r_month; /* 0..11 */ @@ -70,7 +50,7 @@ struct rule { const char * r_abbrvar; /* variable part of abbreviation */ int r_todo; /* a rule to do (used in outzone) */ - zic_t r_temp; /* used in outzone */ + time_t r_temp; /* used in outzone */ }; /* @@ -96,7 +76,7 @@ struct zone { int z_nrules; struct rule z_untilrule; - zic_t z_untiltime; + time_t z_untiltime; }; extern int getopt P((int argc, char * const argv[], @@ -105,18 +85,17 @@ extern int link P((const char * fromname, const char * toname)); extern char * optarg; extern int optind; -static void addtt P((zic_t starttime, int type)); +static void addtt P((time_t starttime, int type)); static int addtype P((long gmtoff, const char * abbr, int isdst, int ttisstd, int ttisgmt)); -static void leapadd P((zic_t t, int positive, int rolling, int count)); +static void leapadd P((time_t t, int positive, int rolling, int count)); static void adjleap P((void)); static void associate P((void)); static int ciequal P((const char * ap, const char * bp)); static void convert P((long val, char * buf)); -static void convert64 P((zic_t val, char * buf)); static void dolink P((const char * fromfile, const char * tofile)); static void doabbr P((char * abbr, const char * format, - const char * letters, int isdst, int doquotes)); + const char * letters, int isdst)); static void eat P((const char * name, int num)); static void eats P((const char * name, int num, const char * rname, int rnum)); @@ -132,7 +111,6 @@ static void inrule P((char ** fields, int nfields)); static int inzcont P((char ** fields, int nfields)); static int inzone P((char ** fields, int nfields)); static int inzsub P((char ** fields, int nfields, int iscont)); -static int is32 P((zic_t x)); static int itsabbr P((const char * abbr, const char * word)); static int itsdir P((const char * name)); static int lowerit P((int c)); @@ -142,42 +120,33 @@ static void newabbr P((const char * abbr)); static long oadd P((long t1, long t2)); static void outzone P((const struct zone * zp, int ntzones)); static void puttzcode P((long code, FILE * fp)); -static void puttzcode64 P((zic_t code, FILE * fp)); static int rcomp P((const void * leftp, const void * rightp)); -static zic_t rpytime P((const struct rule * rp, int wantedy)); +static time_t rpytime P((const struct rule * rp, int wantedy)); static void rulesub P((struct rule * rp, const char * loyearp, const char * hiyearp, const char * typep, const char * monthp, const char * dayp, const char * timep)); -static int stringoffset P((char * result, long offset)); -static int stringrule P((char * result, const struct rule * rp, - long dstoff, long gmtoff)); -static void stringzone P((char * result, - const struct zone * zp, int ntzones)); static void setboundaries P((void)); -static zic_t tadd P((zic_t t1, long t2)); +static time_t tadd P((time_t t1, long t2)); static void usage P((void)); -static void writezone P((const char * name, const char * string)); +static void writezone P((const char * name)); static int yearistype P((int year, const char * type)); -#if !HAVE_STRERROR +#if !(HAVE_STRERROR - 0) static char * strerror P((int)); -#endif /* !HAVE_STRERROR */ +#endif /* !(HAVE_STRERROR - 0) */ static int charcnt; static int errors; static const char * filename; static int leapcnt; -static int leapseen; -static int leapminyear; -static int leapmaxyear; static int linenum; -static int max_abbrvar_len; -static int max_format_len; -static zic_t max_time; +static time_t max_time; static int max_year; -static zic_t min_time; +static int max_year_representable; +static time_t min_time; static int min_year; +static int min_year_representable; static int noise; static const char * rfilename; static int rlinenum; @@ -365,7 +334,7 @@ static const int len_years[2] = { }; static struct attype { - zic_t at; + time_t at; unsigned char type; } attypes[TZ_MAX_TIMES]; static long gmtoffs[TZ_MAX_TYPES]; @@ -374,7 +343,7 @@ static unsigned char abbrinds[TZ_MAX_TYPES]; static char ttisstds[TZ_MAX_TYPES]; static char ttisgmts[TZ_MAX_TYPES]; static char chars[TZ_MAX_CHARS]; -static zic_t trans[TZ_MAX_LEAPS]; +static time_t trans[TZ_MAX_LEAPS]; static long corr[TZ_MAX_LEAPS]; static char roll[TZ_MAX_LEAPS]; @@ -391,7 +360,7 @@ char * const ptr; (void) fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, e); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } return ptr; } @@ -405,7 +374,7 @@ char * const ptr; ** Error handling. */ -#if !HAVE_STRERROR +#if !(HAVE_STRERROR - 0) static char * strerror(errnum) int errnum; @@ -416,7 +385,7 @@ int errnum; return (errnum > 0 && errnum <= sys_nerr) ? sys_errlist[errnum] : _("Unknown system error"); } -#endif /* !HAVE_STRERROR */ +#endif /* !(HAVE_STRERROR - 0) */ static void eats(name, num, rname, rnum) @@ -473,11 +442,9 @@ const char * const string; static void usage P((void)) { - (void) fprintf(stderr, _("%s: usage is %s \ -[ --version ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\ -\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"), + (void) fprintf(stderr, _("%s: usage is %s [ --version ] [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"), progname, progname); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } static const char * psxrules; @@ -485,6 +452,7 @@ static const char * lcltime; static const char * directory; static const char * leapsec; static const char * yitcommand; +static int sflag = FALSE; int main(argc, argv) @@ -498,23 +466,19 @@ char * argv[]; #ifdef unix (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); #endif /* defined unix */ -#if HAVE_GETTEXT - (void) setlocale(LC_ALL, ""); +#if HAVE_GETTEXT - 0 + (void) setlocale(LC_CTYPE, ""); + (void) setlocale(LC_MESSAGES, ""); #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); #endif /* defined TEXTDOMAINDIR */ (void) textdomain(TZ_DOMAIN); -#endif /* HAVE_GETTEXT */ +#endif /* HAVE_GETTEXT - 0 */ progname = argv[0]; - if (TYPE_BIT(zic_t) < 64) { - (void) fprintf(stderr, "%s: %s\n", progname, - _("wild compilation-time specification of zic_t")); - exit(EXIT_FAILURE); - } for (i = 1; i < argc; ++i) if (strcmp(argv[i], "--version") == 0) { (void) printf("%s\n", elsieid); - exit(EXIT_SUCCESS); + (void) exit(EXIT_SUCCESS); } while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1) switch (c) { @@ -527,7 +491,7 @@ char * argv[]; (void) fprintf(stderr, _("%s: More than one -d option specified\n"), progname); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } break; case 'l': @@ -537,7 +501,7 @@ _("%s: More than one -d option specified\n"), (void) fprintf(stderr, _("%s: More than one -l option specified\n"), progname); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } break; case 'p': @@ -547,7 +511,7 @@ _("%s: More than one -l option specified\n"), (void) fprintf(stderr, _("%s: More than one -p option specified\n"), progname); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } break; case 'y': @@ -557,7 +521,7 @@ _("%s: More than one -p option specified\n"), (void) fprintf(stderr, _("%s: More than one -y option specified\n"), progname); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } break; case 'L': @@ -567,14 +531,14 @@ _("%s: More than one -y option specified\n"), (void) fprintf(stderr, _("%s: More than one -L option specified\n"), progname); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } break; case 'v': noise = TRUE; break; case 's': - (void) printf("%s: -s ignored\n", progname); + sflag = TRUE; break; } if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) @@ -594,7 +558,7 @@ _("%s: More than one -L option specified\n"), for (i = optind; i < argc; ++i) infile(argv[i]); if (errors) - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); associate(); for (i = 0; i < nzones; i = j) { /* @@ -610,11 +574,6 @@ _("%s: More than one -L option specified\n"), for (i = 0; i < nlinks; ++i) { eat(links[i].l_filename, links[i].l_linenum); dolink(links[i].l_from, links[i].l_to); - if (noise) - for (j = 0; j < nlinks; ++j) - if (strcmp(links[i].l_to, - links[j].l_from) == 0) - warning(_("link to link")); } if (lcltime != NULL) { eat("command line", 1); @@ -659,54 +618,85 @@ const char * const tofile; int result; if (mkdirs(toname) != 0) - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); result = link(fromname, toname); -#if HAVE_SYMLINK +#if (HAVE_SYMLINK - 0) if (result != 0 && - access(fromname, F_OK) == 0 && - !itsdir(fromname)) { - const char *s = tofile; - register char * symlinkcontents = NULL; - - while ((s = strchr(s+1, '/')) != NULL) - symlinkcontents = - ecatalloc(symlinkcontents, - "../"); - symlinkcontents = - ecatalloc(symlinkcontents, - fromname); - result = symlink(symlinkcontents, - toname); - if (result == 0) + access(fromname, F_OK) == 0 && + !itsdir(fromname)) { + const char *s = tofile; + register char * symlinkcontents = NULL; + while ((s = strchr(s+1, '/')) != NULL) + symlinkcontents = ecatalloc(symlinkcontents, "../"); + symlinkcontents = ecatalloc(symlinkcontents, fromname); + + result = unlink(toname); + if (result != 0 && errno != ENOENT) { + const char *e = strerror(errno); + + (void) fprintf(stderr, + _("%s: Can't unlink %s: %s\n"), + progname, toname, e); + (void) exit(EXIT_FAILURE); + } + + result = symlink(symlinkcontents, toname); + if (result == 0) warning(_("hard link failed, symbolic link used")); - ifree(symlinkcontents); + ifree(symlinkcontents); } -#endif /* HAVE_SYMLINK */ +#endif if (result != 0) { const char *e = strerror(errno); (void) fprintf(stderr, _("%s: Can't link from %s to %s: %s\n"), progname, fromname, toname, e); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } } ifree(fromname); ifree(toname); } -#define TIME_T_BITS_IN_FILE 64 +#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 int i; - - min_time = -1; - for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i) - min_time *= 2; - max_time = -(min_time + 1); + 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; + min_year_representable = min_year; + max_year_representable = max_year; } static int @@ -803,7 +793,7 @@ associate P((void)) */ eat(zp->z_filename, zp->z_linenum); zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), - TRUE); + TRUE); /* ** Note, though, that if there's no rule, ** a '%s' in the format is a bad thing. @@ -813,7 +803,7 @@ associate P((void)) } } if (errors) - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } static void @@ -837,7 +827,7 @@ const char * name; (void) fprintf(stderr, _("%s: Can't open %s: %s\n"), progname, name, e); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } wantcont = FALSE; for (num = 1; ; ++num) { @@ -847,7 +837,7 @@ const char * name; cp = strchr(buf, '\n'); if (cp == NULL) { error(_("line too long")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } *cp = '\0'; fields = getfields(buf); @@ -891,7 +881,7 @@ _("%s: Leap line in non leap seconds file %s\n"), (void) fprintf(stderr, _("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } } ifree((char *) fields); @@ -899,14 +889,14 @@ _("%s: panic: Invalid l_value %d\n"), if (ferror(fp)) { (void) fprintf(stderr, _("%s: Error reading %s\n"), progname, filename); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } if (fp != stdin && fclose(fp)) { const char *e = strerror(errno); (void) fprintf(stderr, _("%s: Error closing %s: %s\n"), progname, filename, e); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } if (wantcont) error(_("expected continuation line not found")); @@ -981,8 +971,6 @@ const int nfields; fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); r.r_name = ecpyalloc(fields[RF_NAME]); r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]); - if (max_abbrvar_len < strlen(r.r_abbrvar)) - max_abbrvar_len = strlen(r.r_abbrvar); rules = (struct rule *) (void *) erealloc((char *) rules, (int) ((nrules + 1) * sizeof *rules)); rules[nrules++] = r; @@ -1088,8 +1076,6 @@ const int iscont; } z.z_rule = ecpyalloc(fields[i_rule]); z.z_format = ecpyalloc(fields[i_format]); - if (max_format_len < strlen(z.z_format)) - max_format_len = strlen(z.z_format); hasuntil = nfields > i_untilyear; if (hasuntil) { z.z_untilrule.r_filename = filename; @@ -1110,9 +1096,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; } } @@ -1136,7 +1120,7 @@ const int nfields; register int i, j; int year, month, day; long dayoff, tod; - zic_t t; + time_t t; if (nfields != LEAP_FIELDS) { error(_("wrong number of fields on Leap line")); @@ -1145,17 +1129,12 @@ const int nfields; dayoff = 0; cp = fields[LP_YEAR]; if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { - /* - ** Leapin' Lizards! - */ - error(_("invalid leaping year")); - return; + /* + * Leapin' Lizards! + */ + error(_("invalid leaping year")); + return; } - if (!leapseen || leapmaxyear < year) - leapmaxyear = year; - if (!leapseen || leapminyear > year) - leapminyear = year; - leapseen = TRUE; j = EPOCH_YEAR; while (j != year) { if (year > j) { @@ -1185,7 +1164,7 @@ const int nfields; return; } dayoff = oadd(dayoff, eitol(day - 1)); - if (dayoff < 0 && !TYPE_SIGNED(zic_t)) { + if (dayoff < 0 && !TYPE_SIGNED(time_t)) { error(_("time before zero")); return; } @@ -1197,7 +1176,7 @@ const int nfields; error(_("time too large")); return; } - t = (zic_t) dayoff * SECSPERDAY; + t = (time_t) dayoff * SECSPERDAY; tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE); cp = fields[LP_CORR]; { @@ -1221,9 +1200,7 @@ const int nfields; 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); @@ -1310,8 +1287,7 @@ const char * const timep; */ cp = loyearp; lp = byword(cp, begin_years); - rp->r_lowasnum = lp == NULL; - if (!rp->r_lowasnum) switch ((int) lp->l_value) { + if (lp != NULL) switch ((int) lp->l_value) { case YR_MINIMUM: rp->r_loyear = INT_MIN; break; @@ -1322,15 +1298,18 @@ const char * const timep; (void) fprintf(stderr, _("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { error(_("invalid starting year")); return; + } else if (noise) { + if (rp->r_loyear < min_year_representable) + warning(_("starting year too low to be represented")); + else if (rp->r_loyear > max_year_representable) + warning(_("starting year too high to be represented")); } cp = hiyearp; - lp = byword(cp, end_years); - rp->r_hiwasnum = lp == NULL; - if (!rp->r_hiwasnum) switch ((int) lp->l_value) { + if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) { case YR_MINIMUM: rp->r_hiyear = INT_MIN; break; @@ -1344,10 +1323,15 @@ const char * const timep; (void) fprintf(stderr, _("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { error(_("invalid ending year")); return; + } else if (noise) { + if (rp->r_loyear < min_year_representable) + warning(_("ending year too low to be represented")); + else if (rp->r_loyear > max_year_representable) + warning(_("ending year too high to be represented")); } if (rp->r_loyear > rp->r_hiyear) { error(_("starting year greater than ending year")); @@ -1362,6 +1346,8 @@ const char * const timep; } rp->r_yrtype = ecpyalloc(typep); } + if (rp->r_loyear < min_year && rp->r_loyear > 0) + min_year = rp->r_loyear; /* ** Day work. ** Accept things such as: @@ -1415,25 +1401,13 @@ const long val; char * const buf; { register int i; - register int shift; + register long shift; for (i = 0, shift = 24; i < 4; ++i, shift -= 8) buf[i] = val >> shift; } static void -convert64(val, buf) -const zic_t val; -char * const buf; -{ - register int i; - register int shift; - - for (i = 0, shift = 56; i < 8; ++i, shift -= 8) - buf[i] = val >> shift; -} - -static void puttzcode(val, fp) const long val; FILE * const fp; @@ -1444,50 +1418,28 @@ FILE * const fp; (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); } -static void -puttzcode64(val, fp) -const zic_t val; -FILE * const fp; -{ - char buf[8]; - - convert64(val, buf); - (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); -} - static int atcomp(avp, bvp) -const void * avp; -const void * bvp; +void * avp; +void * bvp; { - const zic_t a = ((const struct attype *) avp)->at; - const zic_t b = ((const struct attype *) bvp)->at; - - return (a < b) ? -1 : (a > b); -} - -static int -is32(x) -const zic_t x; -{ - return INT32_MIN <= x && x <= INT32_MAX; + 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, string) +writezone(name) const char * const name; -const char * const string; { - register FILE * fp; - register int i, j; - register int leapcnt32, leapi32; - register int timecnt32, timei32; - register int pass; - static char * fullname; - static const struct tzhead tzh0; - static struct tzhead tzh; - zic_t ats[TZ_MAX_TIMES]; - unsigned char types[TZ_MAX_TIMES]; + register FILE * fp; + register int i, j; + static char * fullname; + static struct tzhead tzh; + time_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; /* ** Sort. @@ -1510,13 +1462,14 @@ const char * const string; while (fromi < timecnt && 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[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) @@ -1531,36 +1484,6 @@ const char * const string; ats[i] = attypes[i].at; types[i] = attypes[i].type; } - /* - ** Correct for leap seconds. - */ - for (i = 0; i < timecnt; ++i) { - j = leapcnt; - while (--j >= 0) - if (ats[i] > trans[j] - corr[j]) { - ats[i] = tadd(ats[i], corr[j]); - break; - } - } - /* - ** Figure out 32-bit-limited starts and counts. - */ - timecnt32 = timecnt; - timei32 = 0; - leapcnt32 = leapcnt; - leapi32 = 0; - while (timecnt32 > 0 && !is32(ats[timecnt32 - 1])) - --timecnt32; - while (timecnt32 > 0 && !is32(ats[timei32])) { - --timecnt32; - ++timei32; - } - while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1])) - --leapcnt32; - while (leapcnt32 > 0 && !is32(trans[leapi32])) { - --leapcnt32; - ++leapi32; - } fullname = erealloc(fullname, (int) (strlen(directory) + 1 + strlen(name) + 1)); (void) sprintf(fullname, "%s/%s", directory, name); @@ -1572,388 +1495,102 @@ const char * const string; (void) fprintf(stderr, _("%s: Can't remove %s: %s\n"), progname, fullname, e); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } if ((fp = fopen(fullname, "wb")) == NULL) { if (mkdirs(fullname) != 0) - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); if ((fp = fopen(fullname, "wb")) == NULL) { const char *e = strerror(errno); (void) fprintf(stderr, _("%s: Can't create %s: %s\n"), progname, fullname, e); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } } - for (pass = 1; pass <= 2; ++pass) { - register int thistimei, thistimecnt; - register int thisleapi, thisleapcnt; - register int thistimelim, thisleaplim; - int writetype[TZ_MAX_TIMES]; - int typemap[TZ_MAX_TYPES]; - register int thistypecnt; - char thischars[TZ_MAX_CHARS]; - char thischarcnt; - int indmap[TZ_MAX_CHARS]; - - if (pass == 1) { - thistimei = timei32; - thistimecnt = timecnt32; - thisleapi = leapi32; - thisleapcnt = leapcnt32; - } else { - thistimei = 0; - thistimecnt = timecnt; - thisleapi = 0; - thisleapcnt = leapcnt; - } - thistimelim = thistimei + thistimecnt; - thisleaplim = thisleapi + thisleapcnt; - for (i = 0; i < typecnt; ++i) - writetype[i] = thistimecnt == timecnt; - if (thistimecnt == 0) { - /* - ** No transition times fall in the current - ** (32- or 64-bit) window. - */ - if (typecnt != 0) - writetype[typecnt - 1] = TRUE; - } else { - for (i = thistimei - 1; i < thistimelim; ++i) - if (i >= 0) - writetype[types[i]] = TRUE; - /* - ** For America/Godthab and Antarctica/Palmer - */ - if (thistimei == 0) - writetype[0] = TRUE; - } - thistypecnt = 0; - for (i = 0; i < typecnt; ++i) - typemap[i] = writetype[i] ? thistypecnt++ : -1; - for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i) - indmap[i] = -1; - thischarcnt = 0; - for (i = 0; i < typecnt; ++i) { - register char * thisabbr; - - if (!writetype[i]) - continue; - if (indmap[abbrinds[i]] >= 0) - continue; - thisabbr = &chars[abbrinds[i]]; - for (j = 0; j < thischarcnt; ++j) - if (strcmp(&thischars[j], thisabbr) == 0) - break; - if (j == thischarcnt) { - (void) strcpy(&thischars[(int) thischarcnt], - thisabbr); - thischarcnt += strlen(thisabbr) + 1; - } - indmap[abbrinds[i]] = j; - } -#define DO(field) (void) fwrite((void *) tzh.field, \ - (size_t) sizeof tzh.field, (size_t) 1, fp) - tzh = tzh0; - (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); - tzh.tzh_version[0] = ZIC_VERSION; - convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt); - convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt); - convert(eitol(thisleapcnt), tzh.tzh_leapcnt); - convert(eitol(thistimecnt), tzh.tzh_timecnt); - convert(eitol(thistypecnt), tzh.tzh_typecnt); - convert(eitol(thischarcnt), tzh.tzh_charcnt); - DO(tzh_magic); - DO(tzh_version); - DO(tzh_reserved); - DO(tzh_ttisgmtcnt); - DO(tzh_ttisstdcnt); - DO(tzh_leapcnt); - DO(tzh_timecnt); - DO(tzh_typecnt); - DO(tzh_charcnt); + convert(eitol(typecnt), tzh.tzh_ttisgmtcnt); + convert(eitol(typecnt), tzh.tzh_ttisstdcnt); + convert(eitol(leapcnt), tzh.tzh_leapcnt); + convert(eitol(timecnt), tzh.tzh_timecnt); + convert(eitol(typecnt), tzh.tzh_typecnt); + convert(eitol(charcnt), tzh.tzh_charcnt); + (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); +#define DO(field) (void) fwrite((void *) tzh.field, (size_t) sizeof tzh.field, (size_t) 1, fp) + DO(tzh_magic); + DO(tzh_reserved); + DO(tzh_ttisgmtcnt); + DO(tzh_ttisstdcnt); + DO(tzh_leapcnt); + DO(tzh_timecnt); + DO(tzh_typecnt); + DO(tzh_charcnt); #undef DO - for (i = thistimei; i < thistimelim; ++i) - if (pass == 1) - puttzcode((long) ats[i], fp); - else puttzcode64(ats[i], fp); - for (i = thistimei; i < thistimelim; ++i) { - unsigned char uc; - - uc = typemap[types[i]]; - (void) fwrite((void *) &uc, - (size_t) sizeof uc, - (size_t) 1, - fp); - } - for (i = 0; i < typecnt; ++i) - if (writetype[i]) { - puttzcode(gmtoffs[i], fp); - (void) putc(isdsts[i], fp); - (void) putc((unsigned char) indmap[abbrinds[i]], fp); + for (i = 0; i < timecnt; ++i) { + j = leapcnt; + while (--j >= 0) + if (ats[i] >= trans[j]) { + ats[i] = tadd(ats[i], corr[j]); + break; } - if (thischarcnt != 0) - (void) fwrite((void *) thischars, - (size_t) sizeof thischars[0], - (size_t) thischarcnt, fp); - for (i = thisleapi; i < thisleaplim; ++i) { - register zic_t todo; - - if (roll[i]) { - if (timecnt == 0 || trans[i] < ats[0]) { - j = 0; - while (isdsts[j]) - if (++j >= typecnt) { - j = 0; - break; - } - } else { - j = 1; - while (j < timecnt && - trans[i] >= ats[j]) - ++j; - j = types[j - 1]; - } - todo = tadd(trans[i], -gmtoffs[j]); - } else todo = trans[i]; - if (pass == 1) - puttzcode((long) todo, fp); - else puttzcode64(todo, fp); - puttzcode(corr[i], fp); - } - for (i = 0; i < typecnt; ++i) - if (writetype[i]) - (void) putc(ttisstds[i], fp); - for (i = 0; i < typecnt; ++i) - if (writetype[i]) - (void) putc(ttisgmts[i], fp); - } - (void) fprintf(fp, "\n%s\n", string); + puttzcode((long) ats[i], fp); + } + if (timecnt > 0) + (void) fwrite((void *) types, (size_t) sizeof types[0], + (size_t) timecnt, fp); + for (i = 0; i < typecnt; ++i) { + puttzcode((long) gmtoffs[i], fp); + (void) putc(isdsts[i], fp); + (void) putc(abbrinds[i], fp); + } + if (charcnt != 0) + (void) fwrite((void *) chars, (size_t) sizeof chars[0], + (size_t) charcnt, fp); + for (i = 0; i < leapcnt; ++i) { + if (roll[i]) { + if (timecnt == 0 || trans[i] < ats[0]) { + j = 0; + while (isdsts[j]) + if (++j >= typecnt) { + j = 0; + break; + } + } else { + j = 1; + while (j < timecnt && trans[i] >= ats[j]) + ++j; + j = types[j - 1]; + } + puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp); + } else puttzcode((long) trans[i], fp); + puttzcode((long) corr[i], fp); + } + for (i = 0; i < typecnt; ++i) + (void) putc(ttisstds[i], fp); + for (i = 0; i < typecnt; ++i) + (void) putc(ttisgmts[i], fp); if (ferror(fp) || fclose(fp)) { (void) fprintf(stderr, _("%s: Error writing %s\n"), progname, fullname); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } } static void -doabbr(abbr, format, letters, isdst, doquotes) +doabbr(abbr, format, letters, isdst) char * const abbr; const char * const format; const char * const letters; const int isdst; -const int doquotes; { - register char * cp; - register char * slashp; - register int len; - - slashp = strchr(format, '/'); - if (slashp == NULL) { + if (strchr(format, '/') == NULL) { if (letters == NULL) (void) strcpy(abbr, format); else (void) sprintf(abbr, format, letters); - } else if (isdst) { - (void) strcpy(abbr, slashp + 1); - } else { - if (slashp > format) - (void) strncpy(abbr, format, - (unsigned) (slashp - format)); - abbr[slashp - format] = '\0'; - } - if (!doquotes) - return; - for (cp = abbr; *cp != '\0'; ++cp) - if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL && - strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL) - break; - len = strlen(abbr); - if (len > 0 && *cp == '\0') - return; - abbr[len + 2] = '\0'; - abbr[len + 1] = '>'; - for ( ; len > 0; --len) - abbr[len] = abbr[len - 1]; - abbr[0] = '<'; -} - -static void -updateminmax(x) -const int x; -{ - if (min_year > x) - min_year = x; - if (max_year < x) - max_year = x; -} - -static int -stringoffset(result, offset) -char * result; -long offset; -{ - register int hours; - register int minutes; - register int seconds; - - result[0] = '\0'; - if (offset < 0) { - (void) strcpy(result, "-"); - offset = -offset; - } - seconds = offset % SECSPERMIN; - offset /= SECSPERMIN; - minutes = offset % MINSPERHOUR; - offset /= MINSPERHOUR; - hours = offset; - if (hours >= HOURSPERDAY) { - result[0] = '\0'; - return -1; - } - (void) sprintf(end(result), "%d", hours); - if (minutes != 0 || seconds != 0) { - (void) sprintf(end(result), ":%02d", minutes); - if (seconds != 0) - (void) sprintf(end(result), ":%02d", seconds); - } - return 0; -} - -static int -stringrule(result, rp, dstoff, gmtoff) -char * result; -const struct rule * const rp; -const long dstoff; -const long gmtoff; -{ - register long tod; - - result = end(result); - if (rp->r_dycode == DC_DOM) { - register int month, total; - - if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY) - return -1; - total = 0; - for (month = 0; month < rp->r_month; ++month) - total += len_months[0][month]; - (void) sprintf(result, "J%d", total + rp->r_dayofmonth); - } else { - register int week; - - if (rp->r_dycode == DC_DOWGEQ) { - week = 1 + rp->r_dayofmonth / DAYSPERWEEK; - if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth) - return -1; - } else if (rp->r_dycode == DC_DOWLEQ) { - if (rp->r_dayofmonth == len_months[1][rp->r_month]) - week = 5; - else { - week = 1 + rp->r_dayofmonth / DAYSPERWEEK; - if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth) - return -1; - } - } else return -1; /* "cannot happen" */ - (void) sprintf(result, "M%d.%d.%d", - rp->r_month + 1, week, rp->r_wday); - } - tod = rp->r_tod; - if (rp->r_todisgmt) - tod += gmtoff; - if (rp->r_todisstd && rp->r_stdoff == 0) - tod += dstoff; - if (tod < 0) { - result[0] = '\0'; - return -1; - } - if (tod != 2 * SECSPERMIN * MINSPERHOUR) { - (void) strcat(result, "/"); - if (stringoffset(end(result), tod) != 0) - return -1; - } - return 0; -} - -static void -stringzone(result, zpfirst, zonecount) -char * result; -const struct zone * const zpfirst; -const int zonecount; -{ - register const struct zone * zp; - register struct rule * rp; - register struct rule * stdrp; - register struct rule * dstrp; - register int i; - register const char * abbrvar; - - result[0] = '\0'; - zp = zpfirst + zonecount - 1; - stdrp = dstrp = NULL; - for (i = 0; i < zp->z_nrules; ++i) { - rp = &zp->z_rules[i]; - if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX) - continue; - if (rp->r_yrtype != NULL) - continue; - if (rp->r_stdoff == 0) { - if (stdrp == NULL) - stdrp = rp; - else return; - } else { - if (dstrp == NULL) - dstrp = rp; - else return; - } - } - if (stdrp == NULL && dstrp == NULL) { - /* - ** There are no rules running through "max". - ** Let's find the latest rule. - */ - for (i = 0; i < zp->z_nrules; ++i) { - rp = &zp->z_rules[i]; - if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear || - (rp->r_hiyear == stdrp->r_hiyear && - rp->r_month > stdrp->r_month)) - stdrp = rp; - } - if (stdrp != NULL && stdrp->r_stdoff != 0) - return; /* We end up in DST (a POSIX no-no). */ - /* - ** Horrid special case: if year is 2037, - ** presume this is a zone handled on a year-by-year basis; - ** do not try to apply a rule to the zone. - */ - if (stdrp != NULL && stdrp->r_hiyear == 2037) - return; - } - if (stdrp == NULL && zp->z_nrules != 0) - return; - abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar; - doabbr(result, zp->z_format, abbrvar, FALSE, TRUE); - if (stringoffset(end(result), -zp->z_gmtoff) != 0) { - result[0] = '\0'; - return; - } - if (dstrp == NULL) - return; - doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE); - if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) - if (stringoffset(end(result), - -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) { - result[0] = '\0'; - return; - } - (void) strcat(result, ","); - if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { - result[0] = '\0'; - return; - } - (void) strcat(result, ","); - if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { - result[0] = '\0'; - return; + } else if (isdst) + (void) strcpy(abbr, strchr(format, '/') + 1); + else { + (void) strcpy(abbr, format); + *strchr(abbr, '/') = '\0'; } } @@ -1966,7 +1603,7 @@ const int zonecount; register struct rule * rp; register int i, j; register int usestart, useuntil; - register zic_t starttime, untiltime; + register time_t starttime, untiltime; register long gmtoff; register long stdoff; register int year; @@ -1974,17 +1611,8 @@ const int zonecount; register int startttisstd; register int startttisgmt; register int type; - register char * startbuf; - register char * ab; - register char * envvar; - register int max_abbr_len; - register int max_envvar_len; - - max_abbr_len = 2 + max_format_len + max_abbrvar_len; - max_envvar_len = 2 * max_abbr_len + 5 * 9; - startbuf = emalloc(max_abbr_len + 1); - ab = emalloc(max_abbr_len + 1); - envvar = emalloc(max_envvar_len + 1); + char startbuf[BUFSIZ]; + INITIALIZE(untiltime); INITIALIZE(starttime); /* @@ -1994,53 +1622,11 @@ const int zonecount; typecnt = 0; charcnt = 0; /* - ** Thanks to Earl Chew + ** Thanks to Earl Chew (earl@dnd.icp.nec.com.au) ** for noting the need to unconditionally initialize startttisstd. */ startttisstd = FALSE; startttisgmt = FALSE; - min_year = max_year = EPOCH_YEAR; - if (leapseen) { - updateminmax(leapminyear); - updateminmax(leapmaxyear); - } - for (i = 0; i < zonecount; ++i) { - zp = &zpfirst[i]; - updateminmax(zp->z_untilrule.r_loyear); - for (j = 0; j < zp->z_nrules; ++j) { - rp = &zp->z_rules[j]; - if (rp->r_lowasnum) - updateminmax(rp->r_loyear); - if (rp->r_hiwasnum) - updateminmax(rp->r_hiyear); - } - } - /* - ** Generate lots of data if a rule can't cover all future times. - */ - stringzone(envvar, zpfirst, zonecount); - if (noise && envvar[0] == '\0') { - register char * wp; - -wp = ecpyalloc(_("no POSIX environment variable for zone")); - wp = ecatalloc(wp, " "); - wp = ecatalloc(wp, zpfirst->z_name); - warning(wp); - ifree(wp); - } - if (envvar[0] == '\0') { - if (min_year >= INT_MIN + YEARSPERREPEAT) - min_year -= YEARSPERREPEAT; - else min_year = INT_MIN; - if (max_year <= INT_MAX - YEARSPERREPEAT) - max_year += YEARSPERREPEAT; - else max_year = INT_MAX; - } - /* - ** For the benefit of older systems, generate data through 2037. - */ - if (max_year < 2037) - max_year = 2037; for (i = 0; i < zonecount; ++i) { /* ** A guess that may well be corrected later. @@ -2058,7 +1644,7 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); if (zp->z_nrules == 0) { stdoff = zp->z_stdoff; doabbr(startbuf, zp->z_format, - (char *) NULL, stdoff != 0, FALSE); + (char *) NULL, stdoff != 0); type = addtype(oadd(zp->z_gmtoff, stdoff), startbuf, stdoff != 0, startttisstd, startttisgmt); @@ -2086,8 +1672,9 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); } for ( ; ; ) { register int k; - register zic_t jtime, ktime; + register time_t jtime, ktime; register long offset; + char buf[BUFSIZ]; INITIALIZE(ktime); if (useuntil) { @@ -2143,27 +1730,23 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); stdoff); doabbr(startbuf, zp->z_format, rp->r_abbrvar, - rp->r_stdoff != 0, - FALSE); + 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, - FALSE); + startoff == oadd(zp->z_gmtoff, + stdoff)) { + doabbr(startbuf, zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != 0); } } eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); - doabbr(ab, zp->z_format, rp->r_abbrvar, - rp->r_stdoff != 0, FALSE); + doabbr(buf, zp->z_format, rp->r_abbrvar, + rp->r_stdoff != 0); offset = oadd(zp->z_gmtoff, rp->r_stdoff); - type = addtype(offset, ab, rp->r_stdoff != 0, + type = addtype(offset, buf, rp->r_stdoff != 0, rp->r_todisstd, rp->r_todisgmt); addtt(ktime, type); } @@ -2196,15 +1779,12 @@ error(_("can't determine time zone abbreviation to use just after until time")); starttime = tadd(starttime, -gmtoff); } } - writezone(zpfirst->z_name, envvar); - ifree(startbuf); - ifree(ab); - ifree(envvar); + writezone(zpfirst->z_name); } static void addtt(starttime, type) -const zic_t starttime; +const time_t starttime; int type; { if (starttime <= min_time || @@ -2223,7 +1803,7 @@ int type; } if (timecnt >= TZ_MAX_TIMES) { error(_("too many transitions?!")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } attypes[timecnt].at = starttime; attypes[timecnt].type = type; @@ -2242,15 +1822,15 @@ const int ttisgmt; if (isdst != TRUE && isdst != FALSE) { error(_("internal error - addtype called with bad isdst")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } if (ttisstd != TRUE && ttisstd != FALSE) { error(_("internal error - addtype called with bad ttisstd")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } if (ttisgmt != TRUE && ttisgmt != FALSE) { error(_("internal error - addtype called with bad ttisgmt")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } /* ** See if there's already an entry for this zone type. @@ -2269,7 +1849,7 @@ const int ttisgmt; */ if (typecnt >= TZ_MAX_TYPES) { error(_("too many local time types")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } gmtoffs[i] = gmtoff; isdsts[i] = isdst; @@ -2288,7 +1868,7 @@ const int ttisgmt; static void leapadd(t, positive, rolling, count) -const zic_t t; +const time_t t; const int positive; const int rolling; int count; @@ -2297,13 +1877,13 @@ int count; if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { error(_("too many leap seconds")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } for (i = 0; i < leapcnt; ++i) if (t <= trans[i]) { if (t == trans[i]) { error(_("repeated leap second moment")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } break; } @@ -2358,7 +1938,7 @@ const char * const type; (void) fprintf(stderr, _("%s: command was '%s', result was %d\n"), progname, buf, result); for ( ; ; ) - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } static int @@ -2439,9 +2019,8 @@ register char * cp; emalloc((int) ((strlen(cp) + 1) * sizeof *array)); nsubs = 0; for ( ; ; ) { - while (isascii((unsigned char) *cp) && - isspace((unsigned char) *cp)) - ++cp; + while (isascii(*cp) && isspace((unsigned char) *cp)) + ++cp; if (*cp == '\0' || *cp == '#') break; array[nsubs++] = dp = cp; @@ -2451,9 +2030,7 @@ 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((unsigned char) *cp))); if (isascii(*cp) && isspace((unsigned char) *cp)) @@ -2474,17 +2051,17 @@ const long t2; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { error(_("time overflow")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } return t; } -static zic_t +static time_t tadd(t1, t2) -const zic_t t1; +const time_t t1; const long t2; { - register zic_t t; + register time_t t; if (t1 == max_time && t2 > 0) return max_time; @@ -2493,7 +2070,7 @@ const long t2; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { error(_("time overflow")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } return t; } @@ -2503,14 +2080,14 @@ const long t2; ** 1970, 00:00 LOCAL time - in that year that the rule refers to. */ -static zic_t +static time_t rpytime(rp, wantedy) register const struct rule * const rp; register const int wantedy; { register int y, m, i; register long dayoff; /* with a nod to Margaret O. */ - register zic_t t; + register time_t t; if (wantedy == INT_MIN) return min_time; @@ -2540,7 +2117,7 @@ register const int wantedy; --i; else { error(_("use of 2/29 in non leap-year")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } } --i; @@ -2574,15 +2151,18 @@ register const int wantedy; } if (i < 0 || i >= len_months[isleap(y)][m]) { if (noise) - warning(_("rule goes past start/end of month--\ -will not work with pre-2004 versions of zic")); + warning(_("rule goes past start/end of month--will not work with pre-2004 versions of zic")); } } + if (dayoff < 0 && !TYPE_SIGNED(time_t)) + return min_time; if (dayoff < min_time / SECSPERDAY) return min_time; if (dayoff > max_time / SECSPERDAY) return max_time; - t = (zic_t) dayoff * SECSPERDAY; + t = (time_t) dayoff * SECSPERDAY; + if (t > 0 && max_time - t < rp->r_tod) + return max_time; return tadd(t, rp->r_tod); } @@ -2592,48 +2172,10 @@ const char * const string; { register int i; - if (strcmp(string, GRANDPARENTED) != 0) { - register const char * cp; - register char * wp; - - /* - ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics - ** optionally followed by a + or - and a number from 1 to 14. - */ - cp = string; - wp = NULL; - while (isascii((unsigned char) *cp) && - isalpha((unsigned char) *cp)) - ++cp; - if (cp - string == 0) -wp = _("time zone abbreviation lacks alphabetic at start"); - if (noise && cp - string > 3) -wp = _("time zone abbreviation has more than 3 alphabetics"); - if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN) -wp = _("time zone abbreviation has too many alphabetics"); - if (wp == NULL && (*cp == '+' || *cp == '-')) { - ++cp; - if (isascii((unsigned char) *cp) && - isdigit((unsigned char) *cp)) - if (*cp++ == '1' && - *cp >= '0' && *cp <= '4') - ++cp; - } - if (*cp != '\0') -wp = _("time zone abbreviation differs from POSIX standard"); - if (wp != NULL) { - wp = ecpyalloc(wp); - wp = ecatalloc(wp, " ("); - wp = ecatalloc(wp, string); - wp = ecatalloc(wp, ")"); - warning(wp); - ifree(wp); - } - } i = strlen(string) + 1; if (charcnt + i > TZ_MAX_CHARS) { error(_("too many, or too long, time zone abbreviations")); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } (void) strcpy(&chars[charcnt], string); charcnt += eitol(i); @@ -2697,7 +2239,7 @@ const int i; (void) fprintf(stderr, _("%s: %d did not sign extend correctly\n"), progname, i); - exit(EXIT_FAILURE); + (void) exit(EXIT_FAILURE); } return l; } |