--- zic.c-master-vs-upstream.diff 2024-07-04 14:38:42.919508000 +1200 +++ zic.c-patched-vs-upstream.diff 2024-07-04 14:37:23.663247000 +1200 @@ -1,6 +1,6 @@ --- zic.filtered.c 2024-07-04 12:24:07.383657000 +1200 -+++ zic.c 2024-07-04 14:38:19.086696000 +1200 -@@ -3,104 +3,66 @@ ++++ zic.c 2024-07-04 14:17:36.438520000 +1200 +@@ -3,104 +3,72 @@ /* * This file is in the public domain, so clarified as of * 2006-07-17 by Arthur David Olson. @@ -19,6 +19,8 @@ -#include "version.h" +#include ++#include ++#include +#include +#include + @@ -36,20 +38,18 @@ +#define ZIC_VERSION_PRE_2013 '2' +#define ZIC_VERSION '3' --typedef int_fast64_t zic_t; --static zic_t const -- ZIC_MIN = INT_FAST64_MIN, -- ZIC_MAX = INT_FAST64_MAX, + typedef int_fast64_t zic_t; + static zic_t const + ZIC_MIN = INT_FAST64_MIN, + ZIC_MAX = INT_FAST64_MAX, - ZIC32_MIN = -1 - (zic_t) 0x7fffffff, - ZIC32_MAX = 0x7fffffff; --#define SCNdZIC SCNdFAST64 -+typedef int64 zic_t; -+#define ZIC_MIN PG_INT64_MIN -+#define ZIC_MAX PG_INT64_MAX ++ ZIC32_MIN = INT32_MIN, ++ ZIC32_MAX = INT32_MAX; + #define SCNdZIC SCNdFAST64 #ifndef ZIC_MAX_ABBR_LEN_WO_WARN --#define ZIC_MAX_ABBR_LEN_WO_WARN 6 -+#define ZIC_MAX_ABBR_LEN_WO_WARN 6 + #define ZIC_MAX_ABBR_LEN_WO_WARN 6 #endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */ -/* Minimum and maximum years, assuming signed 32-bit pg_time_t. */ @@ -137,7 +137,7 @@ bool r_hiwasnum; int r_month; /* 0..11 */ -@@ -121,18 +83,16 @@ +@@ -121,18 +89,16 @@ }; /* @@ -162,7 +162,7 @@ lineno_t z_linenum; const char *z_name; -@@ -151,59 +111,46 @@ +@@ -151,59 +117,46 @@ zic_t z_untiltime; }; @@ -245,7 +245,7 @@ const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep); -@@ -214,10 +161,21 @@ +@@ -214,10 +167,21 @@ { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1}; @@ -268,7 +268,7 @@ static int leapcnt; static bool leapseen; static zic_t leapminyear; -@@ -228,132 +186,99 @@ +@@ -228,132 +192,99 @@ static zic_t max_year; static zic_t min_year; static bool noise; @@ -453,7 +453,7 @@ static struct rule *rules; static ptrdiff_t nrules; /* number of rules */ -@@ -365,7 +290,7 @@ +@@ -365,7 +296,7 @@ struct link { @@ -462,7 +462,7 @@ lineno_t l_linenum; const char *l_target; const char *l_linkname; -@@ -381,8 +306,8 @@ +@@ -381,8 +312,8 @@ const int l_value; }; @@ -473,7 +473,7 @@ static struct lookup const zi_line_codes[] = { {"Rule", LC_RULE}, -@@ -436,10 +361,12 @@ +@@ -436,10 +367,12 @@ static struct lookup const begin_years[] = { {"minimum", YR_MINIMUM}, @@ -486,7 +486,7 @@ {"maximum", YR_MAXIMUM}, {"only", YR_ONLY}, {NULL, 0} -@@ -480,79 +407,30 @@ +@@ -480,79 +413,30 @@ * Memory allocation. */ @@ -574,7 +574,7 @@ emalloc(size_t size) { return memcheck(malloc(size)); -@@ -564,100 +442,66 @@ +@@ -564,100 +448,66 @@ return memcheck(realloc(ptr, size)); } @@ -703,7 +703,7 @@ { va_list args; -@@ -667,8 +511,8 @@ +@@ -667,8 +517,8 @@ errors = true; } @@ -714,7 +714,7 @@ { va_list args; -@@ -679,11 +523,8 @@ +@@ -679,11 +529,8 @@ warnings = true; } @@ -727,7 +727,7 @@ { char const *e = (ferror(stream) ? _("I/O error") : fclose(stream) != 0 ? strerror(errno) : NULL); -@@ -694,26 +535,23 @@ +@@ -694,26 +541,23 @@ dir ? dir : "", dir ? "/" : "", name ? name : "", name ? ": " : "", e); @@ -759,7 +759,7 @@ exit(status); } -@@ -741,221 +579,8 @@ +@@ -741,221 +585,8 @@ } } @@ -982,7 +982,7 @@ /* The minimum and maximum values representable in a TZif file. */ static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE); static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE); -@@ -965,19 +590,18 @@ +@@ -965,13 +596,12 @@ static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE); static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE); @@ -999,32 +999,8 @@ /* Set the time range of the output to TIMERANGE. Return true if successful. */ static bool - timerange_option(char *timerange) - { -- intmax_t lo = min_time, -+ int64 lo = min_time, - hi = max_time; - char *lo_end = timerange, - *hi_end; -@@ -986,7 +610,7 @@ - { - errno = 0; - lo = strtoimax(timerange + 1, &lo_end, 10); -- if (lo_end == timerange + 1 || (lo == INTMAX_MAX && errno == ERANGE)) -+ if (lo_end == timerange + 1 || (lo == PG_INT64_MAX && errno == ERANGE)) - return false; +@@ -1000,33 +630,15 @@ } - hi_end = lo_end; -@@ -994,39 +618,21 @@ - { - errno = 0; - hi = strtoimax(lo_end + 2, &hi_end, 10); -- if (hi_end == lo_end + 2 || hi == INTMAX_MIN) -+ if (hi_end == lo_end + 2 || hi == PG_INT64_MIN) - return false; -- hi -= !(hi == INTMAX_MAX && errno == ERANGE); -+ hi -= !(hi == PG_INT64_MAX && errno == ERANGE); - } if (*hi_end || hi < lo || max_time < lo || hi < min_time) return false; - lo_time = max(lo, min_time); @@ -1060,7 +1036,7 @@ static const char *tzdefault; /* -1 if the TZif output file should be slim, 0 if default, 1 if the -@@ -1053,18 +659,10 @@ +@@ -1053,18 +665,10 @@ j; bool timerange_given = false; @@ -1081,7 +1057,7 @@ if (TYPE_BIT(zic_t) < 64) { fprintf(stderr, "%s: %s\n", progname, -@@ -1074,16 +672,15 @@ +@@ -1074,16 +678,15 @@ for (k = 1; k < argc; k++) if (strcmp(argv[k], "--version") == 0) { @@ -1101,7 +1077,7 @@ switch (c) { default: -@@ -1106,36 +703,33 @@ +@@ -1106,36 +709,33 @@ break; case 'd': if (directory == NULL) @@ -1144,7 +1120,7 @@ progname); return EXIT_FAILURE; } -@@ -1156,12 +750,11 @@ +@@ -1156,12 +756,11 @@ break; case 'L': if (leapsec == NULL) @@ -1159,7 +1135,7 @@ progname); return EXIT_FAILURE; } -@@ -1169,12 +762,15 @@ +@@ -1169,12 +768,15 @@ case 'v': noise = true; break; @@ -1177,7 +1153,7 @@ progname); return EXIT_FAILURE; } -@@ -1187,27 +783,12 @@ +@@ -1187,27 +789,12 @@ } timerange_given = true; break; @@ -1205,7 +1181,7 @@ if (bloat == 0) { static char const bloat_default[] = ZIC_BLOAT_DEFAULT; -@@ -1220,23 +801,22 @@ +@@ -1220,23 +807,22 @@ abort(); /* Configuration error. */ } if (directory == NULL) @@ -1232,7 +1208,7 @@ for (i = 0; i < nzones; i = j) { /* -@@ -1246,15 +826,28 @@ +@@ -1246,15 +832,28 @@ continue; outzone(&zones[i], j - i); } @@ -1264,7 +1240,7 @@ dolink(psxrules, TZDEFRULES, true); } if (warnings && (ferror(stderr) || fclose(stderr) != 0)) -@@ -1347,211 +940,22 @@ +@@ -1347,211 +946,22 @@ return componentcheck(name, component, cp); } @@ -1487,7 +1463,7 @@ char const *f = target; char *result = NULL; -@@ -1559,14 +963,13 @@ +@@ -1559,14 +969,13 @@ { /* Make F absolute too. */ size_t len = strlen(directory); @@ -1506,7 +1482,7 @@ } for (i = 0; f[i] && f[i] == linkname[i]; i++) if (f[i] == '/') -@@ -1574,7 +977,7 @@ +@@ -1574,7 +983,7 @@ for (; linkname[i]; i++) dotdots += linkname[i] == '/' && linkname[i - 1] != '/'; taillen = strlen(f + dir_len); @@ -1515,7 +1491,7 @@ if (dotdotetcsize <= linksize) { if (!result) -@@ -1585,133 +988,80 @@ +@@ -1585,133 +994,80 @@ } return result; } @@ -1693,7 +1669,7 @@ { FILE *fp, *tp; -@@ -1726,37 +1076,69 @@ +@@ -1726,37 +1082,69 @@ progname, directory, target, e); exit(EXIT_FAILURE); } @@ -1776,7 +1752,7 @@ /* * Associate sets of rules with zones. */ -@@ -1768,10 +1150,8 @@ +@@ -1768,10 +1156,8 @@ static int rcomp(const void *cp1, const void *cp2) { @@ -1789,7 +1765,7 @@ } static void -@@ -1784,7 +1164,7 @@ +@@ -1784,7 +1170,7 @@ base, out; @@ -1798,7 +1774,7 @@ { qsort(rules, nrules, sizeof *rules, rcomp); for (i = 0; i < nrules - 1; ++i) -@@ -1792,21 +1172,23 @@ +@@ -1792,21 +1178,23 @@ if (strcmp(rules[i].r_name, rules[i + 1].r_name) != 0) continue; @@ -1828,7 +1804,7 @@ continue; break; } -@@ -1842,7 +1224,7 @@ +@@ -1842,7 +1230,7 @@ /* * Maybe we have a local standard time offset. */ @@ -1837,7 +1813,7 @@ zp->z_save = getsave(zp->z_rule, &zp->z_isdst); /* -@@ -1857,85 +1239,71 @@ +@@ -1857,85 +1245,60 @@ exit(EXIT_FAILURE); } @@ -1947,23 +1923,12 @@ - /* nothing to do */ + if (name == leapsec && *buf == '#') + { -+ /* -+ * PG: INT64_FORMAT isn't portable for sscanf, so be content -+ * with scanning a "long". Once we are requiring C99 in all -+ * live branches, it'd be sensible to adopt upstream's -+ * practice of using the macros. But for now, we -+ * don't actually use this code, and it won't overflow before -+ * 2038 anyway. -+ */ -+ long cl_tmp; -+ -+ sscanf(buf, "#expires %ld", &cl_tmp); -+ comment_leapexpires = cl_tmp; ++ sscanf(buf, "#expires %" SCNdZIC, &comment_leapexpires); + } } else if (wantcont) { -@@ -1944,7 +1312,7 @@ +@@ -1944,7 +1307,7 @@ else { struct lookup const *line_codes @@ -1972,7 +1937,7 @@ lp = byword(fields[0], line_codes); if (lp == NULL) -@@ -1971,12 +1339,16 @@ +@@ -1971,12 +1334,16 @@ inexpires(fields, nfields); wantcont = false; break; @@ -1992,26 +1957,7 @@ if (wantcont) error(_("expected continuation line not found")); } -@@ -1992,7 +1364,8 @@ - static zic_t - gethms(char const *string, char const *errstring) - { -- zic_t hh; -+ /* PG: make hh be int not zic_t to avoid sscanf portability issues */ -+ int hh; - int sign, - mm = 0, - ss = 0; -@@ -2014,7 +1387,7 @@ - else - sign = 1; - switch (sscanf(string, -- "%" SCNdZIC "%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c", -+ "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c", - &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs)) - { - default: -@@ -2022,19 +1395,19 @@ +@@ -2022,19 +1389,19 @@ break; case 8: ok = '0' <= xr && xr <= '9'; @@ -2035,12 +1981,12 @@ case 1: break; } -@@ -2050,16 +1423,19 @@ +@@ -2050,16 +1417,19 @@ error("%s", errstring); return 0; } + /* Some compilers warn that this test is unsatisfiable for 32-bit ints */ -+#if INT_MAX > PG_INT32_MAX ++#if INT_MAX > INT32_MAX if (ZIC_MAX / SECSPERHOUR < hh) { error(_("time overflow")); @@ -2056,7 +2002,7 @@ sign * (mm * SECSPERMIN + ss)); } -@@ -2068,7 +1444,7 @@ +@@ -2068,7 +1438,7 @@ { int dst = -1; zic_t save; @@ -2065,7 +2011,7 @@ if (fieldlen != 0) { -@@ -2094,7 +1470,7 @@ +@@ -2094,7 +1464,7 @@ static void inrule(char **fields, int nfields) { @@ -2074,7 +2020,7 @@ if (nfields != RULE_FIELDS) { -@@ -2125,15 +1501,13 @@ +@@ -2125,15 +1495,13 @@ error(_("Invalid rule name \"%s\""), fields[RF_NAME]); return; } @@ -2095,7 +2041,7 @@ if (max_abbrvar_len < strlen(r.r_abbrvar)) max_abbrvar_len = strlen(r.r_abbrvar); rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc); -@@ -2152,13 +1526,15 @@ +@@ -2152,13 +1520,15 @@ } if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0) { @@ -2113,7 +2059,7 @@ TZDEFRULES); return false; } -@@ -2167,9 +1543,9 @@ +@@ -2167,9 +1537,9 @@ strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) { error(_("duplicate zone name %s" @@ -2125,7 +2071,7 @@ zones[i].z_linenum); return false; } -@@ -2192,8 +1568,7 @@ +@@ -2192,8 +1562,7 @@ { char *cp; char *cp1; @@ -2135,7 +2081,7 @@ int i_stdoff, i_rule, i_format; -@@ -2212,6 +1587,7 @@ +@@ -2212,6 +1581,7 @@ i_untilmonth = ZFC_TILMONTH; i_untilday = ZFC_TILDAY; i_untiltime = ZFC_TILTIME; @@ -2143,7 +2089,7 @@ } else if (!namecheck(fields[ZF_NAME])) return false; -@@ -2224,11 +1600,12 @@ +@@ -2224,11 +1594,12 @@ i_untilmonth = ZF_TILMONTH; i_untilday = ZF_TILDAY; i_untiltime = ZF_TILTIME; @@ -2158,7 +2104,7 @@ { if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%') || strchr(fields[i_format], '/')) -@@ -2237,25 +1614,31 @@ +@@ -2237,25 +1608,31 @@ return false; } } @@ -2204,7 +2150,7 @@ z.z_untiltime = rpytime(&z.z_untilrule, z.z_untilrule.r_loyear); if (iscont && nzones > 0 && -@@ -2265,21 +1648,10 @@ +@@ -2265,21 +1642,10 @@ zones[nzones - 1].z_untiltime < max_time && zones[nzones - 1].z_untiltime >= z.z_untiltime) { @@ -2227,7 +2173,7 @@ zones = growalloc(zones, sizeof *zones, nzones, &nzones_alloc); zones[nzones++] = z; -@@ -2291,13 +1663,15 @@ +@@ -2291,12 +1657,13 @@ } static zic_t @@ -2238,23 +2184,11 @@ const struct lookup *lp; zic_t i, j; -- zic_t year; + -+ /* PG: make year be int not zic_t to avoid sscanf portability issues */ -+ int year; + zic_t year; int month, day; - zic_t dayoff, -@@ -2307,7 +1681,7 @@ - - dayoff = 0; - cp = fields[LP_YEAR]; -- if (sscanf(cp, "%" SCNdZIC "%c", &year, &xs) != 1) -+ if (sscanf(cp, "%d%c", &year, &xs) != 1) - { - /* - * Leapin' Lizards! -@@ -2384,7 +1758,7 @@ +@@ -2384,7 +1751,7 @@ error(_("wrong number of fields on Leap line")); else { @@ -2263,7 +2197,7 @@ if (0 <= t) { -@@ -2417,7 +1791,7 @@ +@@ -2417,7 +1784,7 @@ else if (0 <= leapexpires) error(_("multiple Expires lines")); else @@ -2272,7 +2206,7 @@ } static void -@@ -2437,15 +1811,15 @@ +@@ -2437,15 +1804,15 @@ } if (!namecheck(fields[LF_LINKNAME])) return; @@ -2292,13 +2226,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep) -@@ -2456,15 +1830,18 @@ - char *ep; - char xs; - -+ /* PG: year_tmp is to avoid sscanf portability issues */ -+ int year_tmp; -+ +@@ -2459,12 +1826,12 @@ if ((lp = byword(monthp, mon_names)) == NULL) { error(_("invalid month name")); @@ -2313,7 +2241,7 @@ if (*dp != '\0') { ep = dp + strlen(dp) - 1; -@@ -2497,22 +1874,28 @@ +@@ -2497,22 +1864,26 @@ */ cp = loyearp; lp = byword(cp, begin_years); @@ -2340,10 +2268,7 @@ + progname, lp->l_value); + exit(EXIT_FAILURE); } -- else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_loyear, &xs) != 1) -+ else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1) -+ rp->r_loyear = year_tmp; -+ else + else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_loyear, &xs) != 1) { error(_("invalid starting year")); - return false; @@ -2351,7 +2276,7 @@ } cp = hiyearp; lp = byword(cp, end_years); -@@ -2520,37 +1903,45 @@ +@@ -2520,37 +1891,43 @@ if (!rp->r_hiwasnum) switch (lp->l_value) { @@ -2372,10 +2297,7 @@ + progname, lp->l_value); + exit(EXIT_FAILURE); } -- else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_hiyear, &xs) != 1) -+ else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1) -+ rp->r_hiyear = year_tmp; -+ else + else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_hiyear, &xs) != 1) { error(_("invalid ending year")); - return false; @@ -2404,7 +2326,7 @@ if ((lp = byword(dp, lasts)) != NULL) { rp->r_dycode = DC_DOWLEQ; -@@ -2559,9 +1950,9 @@ +@@ -2559,9 +1936,9 @@ } else { @@ -2416,7 +2338,7 @@ rp->r_dycode = DC_DOWGEQ; else { -@@ -2575,13 +1966,13 @@ +@@ -2575,13 +1952,13 @@ { error(_("invalid day of month")); free(dp); @@ -2432,7 +2354,7 @@ } rp->r_wday = lp->l_value; } -@@ -2591,37 +1982,36 @@ +@@ -2591,37 +1968,36 @@ { error(_("invalid day of month")); free(dp); @@ -2446,7 +2368,7 @@ static void -convert(uint_fast32_t val, char *buf) -+convert(const int32 val, char *const buf) ++convert(const int_fast32_t val, char *const buf) { int i; int shift; @@ -2459,7 +2381,7 @@ static void -convert64(uint_fast64_t val, char *buf) -+convert64(const zic_t val, char *const buf) ++convert64(uint_fast64_t val, char *const buf) { int i; int shift; @@ -2472,11 +2394,11 @@ static void -puttzcode(zic_t val, FILE *fp) -+puttzcode(const int32 val, FILE *const fp) ++puttzcode(zic_t val, FILE *const fp) { char buf[4]; -@@ -2646,12 +2036,10 @@ +@@ -2646,12 +2022,10 @@ static int atcomp(const void *avp, const void *bvp) { @@ -2492,7 +2414,7 @@ } struct timerange -@@ -2661,44 +2049,25 @@ +@@ -2661,44 +2035,25 @@ count; int leapbase, leapcount; @@ -2539,7 +2461,7 @@ { while (0 < r.count && hi + 1 < ats[r.base + r.count - 1]) r.count--; -@@ -2706,9 +2075,6 @@ +@@ -2706,9 +2061,6 @@ r.leapcount--; } @@ -2549,7 +2471,7 @@ return r; } -@@ -2720,20 +2086,23 @@ +@@ -2720,20 +2072,23 @@ ptrdiff_t i, j; int pass; @@ -2582,7 +2504,7 @@ /* * Sort. -@@ -2810,49 +2179,61 @@ +@@ -2810,49 +2165,61 @@ } } @@ -2611,9 +2533,8 @@ - max(hi_time, - redundant_time - (ZIC_MIN < redundant_time)), - ats, types); -- range32 = limitrange(range64, ZIC32_MIN, ZIC32_MAX, ats, types); + range64 = limitrange(rangeall, lo_time, hi_time, ats, types); -+ range32 = limitrange(range64, PG_INT32_MIN, PG_INT32_MAX, ats, types); + range32 = limitrange(range64, ZIC32_MIN, ZIC32_MAX, ats, types); /* - * TZif version 4 is needed if a no-op transition is appended to indicate @@ -2674,7 +2595,7 @@ for (pass = 1; pass <= 2; ++pass) { ptrdiff_t thistimei, -@@ -2861,15 +2242,11 @@ +@@ -2861,15 +2228,11 @@ int thisleapi, thisleapcnt, thisleaplim; @@ -2693,7 +2614,7 @@ int old0; char omittype[TZ_MAX_TYPES]; int typemap[TZ_MAX_TYPES]; -@@ -2883,15 +2260,28 @@ +@@ -2883,15 +2246,28 @@ if (pass == 1) { @@ -2701,7 +2622,7 @@ + /* + * Arguably the default time type in the 32-bit data should be + * range32.defaulttype, which is suited for timestamps just before -+ * PG_INT32_MIN. However, zic traditionally used the time type of ++ * INT32_MIN. However, zic traditionally used the time type of + * the indefinite past instead. Internet RFC 8532 says readers + * should ignore 32-bit data, so this discrepancy matters only to + * obsolete readers where the traditional type might be more @@ -2709,7 +2630,7 @@ + * value, unless -r specifies a low cutoff that excludes some + * 32-bit timestamps. + */ -+ thisdefaulttype = (lo_time <= PG_INT32_MIN ++ thisdefaulttype = (lo_time <= INT32_MIN + ? range64.defaulttype + : range32.defaulttype); + @@ -2721,12 +2642,12 @@ - thisleapexpiry = range32.leapexpiry; - thismin = ZIC32_MIN; - thismax = ZIC32_MAX; -+ locut = PG_INT32_MIN < lo_time; -+ hicut = hi_time < PG_INT32_MAX; ++ locut = INT32_MIN < lo_time; ++ hicut = hi_time < INT32_MAX; } else { -@@ -2901,52 +2291,40 @@ +@@ -2901,52 +2277,40 @@ toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0; thisleapi = range64.leapbase; thisleapcnt = range64.leapcount; @@ -2801,7 +2722,7 @@ /* * Reorder types to make THISDEFAULTTYPE type 0. Use TYPEMAP to swap -@@ -2972,14 +2350,7 @@ +@@ -2972,14 +2336,7 @@ type; hidst = histd = mrudst = mrustd = -1; @@ -2817,7 +2738,7 @@ if (isdsts[types[i]]) mrudst = types[i]; else -@@ -3059,20 +2430,19 @@ +@@ -3059,20 +2416,19 @@ } if (pass == 1 && !want_bloat()) { @@ -2844,11 +2765,16 @@ convert(thistypecnt, tzh.tzh_typecnt); convert(thischarcnt, tzh.tzh_charcnt); DO(tzh_magic); -@@ -3095,26 +2465,62 @@ - continue; +@@ -3096,25 +2452,67 @@ } -+ /* PG: print current timezone abbreviations if requested */ + /* ++ * PG: print current timezone abbreviations if requested. Note that ++ * we cast to int64_t, because int_fast64_t is not required to be ++ * compatible with INT64_FORMAT. We can't use PRIdFAST64 here because ++ * we override fprintf with our own implementation that might not ++ * understand it. ++ */ + if (print_abbrevs && pass == 2) + { + /* Print "type" data for periods ending after print_cutoff */ @@ -2861,7 +2787,7 @@ + + fprintf(stdout, "%s\t" INT64_FORMAT "%s\n", + thisabbrev, -+ utoffs[tm], ++ (int64_t) utoffs[tm], + isdsts[tm] ? "\tD" : ""); + } + } @@ -2873,17 +2799,16 @@ + + fprintf(stdout, "%s\t" INT64_FORMAT "%s\n", + thisabbrev, -+ utoffs[tm], ++ (int64_t) utoffs[tm], + isdsts[tm] ? "\tD" : ""); + } + } + - /* ++ /* * Output a LO_TIME transition if needed; see limitrange. But do not * go below the minimum representable value for this pass. */ -- lo = pass == 1 && lo_time < ZIC32_MIN ? ZIC32_MIN : lo_time; -+ lo = pass == 1 && lo_time < PG_INT32_MIN ? PG_INT32_MIN : lo_time; + lo = pass == 1 && lo_time < ZIC32_MIN ? ZIC32_MIN : lo_time; - if (0 <= pretranstype) + if (locut) @@ -2915,7 +2840,7 @@ for (i = old0; i < typecnt; i++) { -@@ -3131,7 +2537,6 @@ +@@ -3131,7 +2529,6 @@ if (thischarcnt != 0) fwrite(thischars, sizeof thischars[0], thischarcnt, fp); @@ -2923,7 +2848,7 @@ for (i = thisleapi; i < thisleaplim; ++i) { zic_t todo; -@@ -3163,17 +2568,6 @@ +@@ -3163,17 +2560,6 @@ puttzcodepass(todo, fp, pass); puttzcode(corr[i], fp); } @@ -2941,7 +2866,7 @@ if (stdcnt != 0) for (i = old0; i < typecnt; i++) if (!omittype[i]) -@@ -3184,8 +2578,7 @@ +@@ -3184,8 +2570,7 @@ putc(ttisuts[i], fp); } fprintf(fp, "\n%s\n", string); @@ -2951,7 +2876,7 @@ free(ats); } -@@ -3233,15 +2626,13 @@ +@@ -3233,15 +2618,13 @@ } } @@ -2969,7 +2894,7 @@ char const *format = zp->z_format; slashp = strchr(format, '/'); -@@ -3253,8 +2644,6 @@ +@@ -3253,8 +2636,6 @@ letters = abbroffset(letterbuf, zp->z_stdoff + save); else if (!letters) letters = "%s"; @@ -2978,7 +2903,7 @@ sprintf(abbr, format, letters); } else if (isdst) -@@ -3413,17 +2802,11 @@ +@@ -3413,17 +2794,11 @@ return 1; if (a->r_hiyear != b->r_hiyear) return a->r_hiyear < b->r_hiyear ? -1 : 1; @@ -2996,7 +2921,7 @@ static int stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) { -@@ -3432,17 +2815,13 @@ +@@ -3432,17 +2807,13 @@ struct rule *stdrp; struct rule *dstrp; ptrdiff_t i; @@ -3016,7 +2941,7 @@ result[0] = '\0'; -@@ -3454,74 +2833,72 @@ +@@ -3454,74 +2825,72 @@ return -1; zp = zpfirst + zonecount - 1; @@ -3146,7 +3071,7 @@ if (!offsetlen) { result[0] = '\0'; -@@ -3530,12 +2907,12 @@ +@@ -3530,12 +2899,12 @@ len += offsetlen; if (dstrp == NULL) return compat; @@ -3161,7 +3086,7 @@ if (!offsetlen) { result[0] = '\0'; -@@ -3544,7 +2921,7 @@ +@@ -3544,7 +2913,7 @@ len += offsetlen; } result[len++] = ','; @@ -3170,7 +3095,7 @@ if (c < 0) { result[0] = '\0'; -@@ -3554,7 +2931,7 @@ +@@ -3554,7 +2923,7 @@ compat = c; len += strlen(result + len); result[len++] = ','; @@ -3179,7 +3104,7 @@ if (c < 0) { result[0] = '\0'; -@@ -3568,31 +2945,38 @@ +@@ -3568,31 +2937,38 @@ static void outzone(const struct zone *zpfirst, ptrdiff_t zonecount) { @@ -3224,7 +3149,7 @@ startbuf = emalloc(max_abbr_len + 1); ab = emalloc(max_abbr_len + 1); envvar = emalloc(max_envvar_len + 1); -@@ -3605,6 +2989,7 @@ +@@ -3605,6 +2981,7 @@ timecnt = 0; typecnt = 0; charcnt = 0; @@ -3232,7 +3157,7 @@ /* * Thanks to Earl Chew for noting the need to unconditionally initialize -@@ -3620,17 +3005,18 @@ +@@ -3620,17 +2997,18 @@ } for (i = 0; i < zonecount; ++i) { @@ -3256,7 +3181,7 @@ } } -@@ -3638,14 +3024,13 @@ +@@ -3638,14 +3016,13 @@ * Generate lots of data if a rule can't cover all future times. */ compat = stringzone(envvar, zpfirst, zonecount); @@ -3273,7 +3198,7 @@ zpfirst->z_name); else if (compat != 0) { -@@ -3660,6 +3045,22 @@ +@@ -3660,6 +3037,22 @@ } if (do_extend) { @@ -3296,7 +3221,7 @@ if (min_year >= ZIC_MIN + years_of_observations) min_year -= years_of_observations; else -@@ -3668,9 +3069,18 @@ +@@ -3668,9 +3061,18 @@ max_year += years_of_observations; else max_year = ZIC_MAX; @@ -3317,7 +3242,7 @@ max_year0 = max_year; if (want_bloat()) { -@@ -3678,35 +3088,31 @@ +@@ -3678,35 +3080,31 @@ * For the benefit of older systems, generate data from 1900 through * 2038. */ @@ -3366,7 +3291,7 @@ save = zp->z_save; doabbr(startbuf, zp, NULL, zp->z_isdst, save, false); type = addtype(oadd(zp->z_stdoff, save), -@@ -3715,20 +3121,12 @@ +@@ -3715,20 +3113,12 @@ if (usestart) { addtt(starttime, type); @@ -3387,7 +3312,7 @@ for (year = min_year; year <= max_year; ++year) { if (useuntil && year > zp->z_untilrule.r_hiyear) -@@ -3741,12 +3139,9 @@ +@@ -3741,12 +3131,9 @@ */ for (j = 0; j < zp->z_nrules; ++j) { @@ -3403,7 +3328,7 @@ rp->r_todo = year >= rp->r_loyear && year <= rp->r_hiyear; if (rp->r_todo) -@@ -3763,8 +3158,6 @@ +@@ -3763,8 +3150,6 @@ zic_t jtime, ktime; zic_t offset; @@ -3412,7 +3337,7 @@ INITIALIZE(ktime); if (useuntil) -@@ -3789,16 +3182,15 @@ +@@ -3789,16 +3174,15 @@ k = -1; for (j = 0; j < zp->z_nrules; ++j) { @@ -3436,7 +3361,7 @@ if (jtime == min_time || jtime == max_time) continue; -@@ -3813,12 +3205,12 @@ +@@ -3813,12 +3197,12 @@ char const *dup_rules_msg = _("two rules for same instant"); @@ -3454,7 +3379,7 @@ error("%s", dup_rules_msg); } } -@@ -3827,15 +3219,7 @@ +@@ -3827,15 +3211,7 @@ rp = &zp->z_rules[k]; rp->r_todo = false; if (useuntil && ktime >= untiltime) @@ -3470,7 +3395,7 @@ save = rp->r_save; if (usestart && ktime == starttime) usestart = false; -@@ -3864,41 +3248,44 @@ +@@ -3864,41 +3240,44 @@ false); } } @@ -3534,7 +3459,7 @@ if (defaulttype < 0 && !isdst) defaulttype = type; addtt(starttime, type); -@@ -3921,50 +3308,17 @@ +@@ -3921,50 +3300,17 @@ } if (defaulttype < 0) defaulttype = 0; @@ -3592,7 +3517,7 @@ * transitions up to that point. */ struct rule xr; -@@ -4055,11 +3409,6 @@ +@@ -4055,11 +3401,6 @@ error(_("too many leap seconds")); exit(EXIT_FAILURE); } @@ -3604,7 +3529,7 @@ for (i = 0; i < leapcnt; ++i) if (t <= trans[i]) break; -@@ -4094,6 +3443,13 @@ +@@ -4094,6 +3435,13 @@ last = corr[i] += last; } @@ -3618,7 +3543,7 @@ if (0 <= leapexpires) { leapexpires = oadd(leapexpires, last); -@@ -4102,6 +3458,8 @@ +@@ -4102,6 +3450,8 @@ error(_("last Leap time does not precede Expires time")); exit(EXIT_FAILURE); } @@ -3627,7 +3552,7 @@ } } -@@ -4252,7 +3610,7 @@ +@@ -4252,7 +3602,7 @@ } /* case-insensitive equality */ @@ -3636,7 +3561,7 @@ ciequal(const char *ap, const char *bp) { while (lowerit(*ap) == lowerit(*bp++)) -@@ -4261,7 +3619,7 @@ +@@ -4261,7 +3611,7 @@ return false; } @@ -3645,7 +3570,7 @@ itsabbr(const char *abbr, const char *word) { if (lowerit(*abbr) != lowerit(*word)) -@@ -4278,7 +3636,7 @@ +@@ -4278,7 +3628,7 @@ /* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */ @@ -3654,7 +3579,7 @@ ciprefix(char const *abbr, char const *word) { do -@@ -4355,22 +3713,24 @@ +@@ -4355,22 +3705,24 @@ return foundlp; } @@ -3684,7 +3609,7 @@ do { if ((*dp = *cp++) != '"') -@@ -4388,53 +3748,48 @@ +@@ -4388,53 +3740,48 @@ if (is_space(*cp)) ++cp; *dp = '\0'; @@ -3765,7 +3690,7 @@ } /* -@@ -4450,31 +3805,39 @@ +@@ -4450,31 +3797,39 @@ zic_t dayoff; /* with a nod to Margaret O. */ zic_t t, y; @@ -3820,7 +3745,7 @@ } while (m != rp->r_month) { -@@ -4497,17 +3860,27 @@ +@@ -4497,17 +3852,27 @@ dayoff = oadd(dayoff, i); if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) { @@ -3852,7 +3777,7 @@ wday = 0; ++i; } -@@ -4515,7 +3888,7 @@ +@@ -4515,7 +3880,7 @@ { dayoff = oadd(dayoff, -1); if (--wday < 0) @@ -3861,7 +3786,7 @@ --i; } if (i < 0 || i >= len_months[isleap(y)][m]) -@@ -4570,13 +3943,15 @@ +@@ -4570,13 +3935,15 @@ /* Ensure that the directories of ARGNAME exist, by making any missing ones. If ANCESTORS, do this only for ARGNAME's ancestors; otherwise, do it for ARGNAME too. Exit with failure if there is trouble. @@ -3880,7 +3805,7 @@ /* * On MS-Windows systems, do not worry about drive letters or backslashes, * as this should suffice in practice. Time zone names do not use drive -@@ -4603,20 +3978,15 @@ +@@ -4603,20 +3970,15 @@ if (mkdir(name, MKDIR_UMASK) != 0) { /* @@ -3906,7 +3831,7 @@ progname, name, strerror(err)); exit(EXIT_FAILURE); } -@@ -4626,3 +3996,20 @@ +@@ -4626,3 +3988,20 @@ } free(name); } --- localtime.c-master-vs-upstream.diff 2024-07-04 14:38:31.386232000 +1200 +++ localtime.c-patched-vs-upstream.diff 2024-07-04 14:37:46.783150000 +1200 @@ -1,6 +1,6 @@ --- localtime.filtered.c 2024-07-04 13:04:23.744118000 +1200 -+++ localtime.c 2024-07-04 14:38:19.086065000 +1200 -@@ -3,64 +3,28 @@ ++++ localtime.c 2024-07-04 14:17:36.438049000 +1200 +@@ -3,64 +3,29 @@ /* * This file is in the public domain, so clarified as of * 1996-06-05 by Arthur David Olson. @@ -25,6 +25,7 @@ -#include "tzdir.h" -#include "tzfile.h" #include ++#include -#if defined THREAD_SAFE && THREAD_SAFE -#include @@ -75,7 +76,7 @@ #ifndef WILDABBR /* * Someone might make incorrect use of a time zone abbreviation: -@@ -72,7 +36,7 @@ +@@ -72,7 +37,7 @@ * in which Daylight Saving Time is never observed. * 4. They might reference tzname[0] after setting to a time zone * in which Standard Time is never observed. @@ -84,7 +85,7 @@ * What's best to do in the above cases is open to debate; * for now, we just set things up so that in any of the five cases * WILDABBR is used. Another possibility: initialize tzname[0] to the -@@ -81,89 +45,28 @@ +@@ -81,89 +46,28 @@ * manual page of what this "time zone abbreviation" means (doing this so * that tzname[0] has the "normal" length of three characters). */ @@ -179,12 +180,8 @@ }; struct rule -@@ -172,70 +75,37 @@ - int r_day; /* day number of rule */ - int r_week; /* week number of rule */ - int r_mon; /* month number of rule */ -- int_fast32_t r_time; /* transition time of rule */ -+ int32 r_time; /* transition time of rule */ +@@ -175,64 +79,31 @@ + int_fast32_t r_time; /* transition time of rule */ }; -static struct pg_tm *gmtsub(struct state const *, pg_time_t const *, int_fast32_t, @@ -204,13 +201,13 @@ -static struct state *lclptr; -static struct state *gmtptr; -#endif /* defined ALL_STATE */ -+static struct pg_tm *gmtsub(pg_time_t const *timep, int32 offset, ++static struct pg_tm *gmtsub(pg_time_t const *timep, int_fast32_t offset, + struct pg_tm *tmp); +static bool increment_overflow(int *ip, int j); -+static bool increment_overflow_time(pg_time_t *tp, int32 j); ++static bool increment_overflow_time(pg_time_t *tp, int_fast32_t j); +static int64 leapcorr(struct state const *sp, pg_time_t t); +static struct pg_tm *timesub(pg_time_t const *timep, -+ int32 offset, struct state const *sp, ++ int_fast32_t offset, struct state const *sp, + struct pg_tm *tmp); +static bool typesequiv(struct state const *sp, int a, int b); @@ -259,12 +256,8 @@ - /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ static void --init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx) -+init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx) - { - s->tt_utoff = utoff; - s->tt_isdst = isdst; -@@ -244,25 +114,15 @@ + init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx) +@@ -244,16 +115,6 @@ s->tt_ttisut = false; } @@ -278,64 +271,13 @@ - return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0; -} - --static int_fast32_t -+static int32 + static int_fast32_t detzcode(const char *const codep) { -- int_fast32_t result; -+ int32 result; - int i; -- int_fast32_t one = 1; -- int_fast32_t halfmaxval = one << (32 - 2); -- int_fast32_t maxval = halfmaxval - 1 + halfmaxval; -- int_fast32_t minval = -1 - maxval; -+ int32 one = 1; -+ int32 halfmaxval = one << (32 - 2); -+ int32 maxval = halfmaxval - 1 + halfmaxval; -+ int32 minval = -1 - maxval; - - result = codep[0] & 0x7f; - for (i = 1; i < 4; ++i) -@@ -274,21 +134,21 @@ - * Do two's-complement negation even on non-two's-complement machines. - * If the result would be minval - 1, return minval. - */ -- result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0; -+ result -= !TWOS_COMPLEMENT(int32) && result != 0; - result += minval; - } +@@ -306,125 +167,25 @@ return result; } --static int_fast64_t -+static int64 - detzcode64(const char *const codep) - { -- int_fast64_t result; -+ uint64 result; - int i; -- int_fast64_t one = 1; -- int_fast64_t halfmaxval = one << (64 - 2); -- int_fast64_t maxval = halfmaxval - 1 + halfmaxval; -- int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval; -+ int64 one = 1; -+ int64 halfmaxval = one << (64 - 2); -+ int64 maxval = halfmaxval - 1 + halfmaxval; -+ int64 minval = -TWOS_COMPLEMENT(int64) - maxval; - - result = codep[0] & 0x7f; - for (i = 1; i < 8; ++i) -@@ -300,131 +160,31 @@ - * Do two's-complement negation even on non-two's-complement machines. - * If the result would be minval - 1, return minval. - */ -- result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0; -+ result -= !TWOS_COMPLEMENT(int64) && result != 0; - result += minval; - } - return result; - } - -static void -update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp) +static bool @@ -464,7 +406,7 @@ /* Local storage needed for 'tzloadbody'. */ union local_storage { -@@ -438,28 +198,23 @@ +@@ -438,28 +199,23 @@ struct state st; } u; @@ -500,7 +442,7 @@ union input_buffer *up = &lsp->u.u; int tzheadsize = sizeof(struct tzhead); -@@ -474,50 +229,10 @@ +@@ -474,50 +230,10 @@ if (name[0] == ':') ++name; @@ -553,33 +495,23 @@ nread = read(fid, up->buf, sizeof up->buf); if (nread < tzheadsize) -@@ -531,17 +246,14 @@ +@@ -531,13 +247,10 @@ return errno; for (stored = 4; stored <= 8; stored *= 2) { - char version = up->tzhead.tzh_version[0]; - bool skip_datablock = stored == 4 && version; - int_fast32_t datablock_size; -- int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); -- int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); + int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); + int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); - int_fast64_t prevtr = -1; - int_fast32_t prevcorr; -- int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt); -- int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt); -- int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt); -- int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt); -+ int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); -+ int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); -+ int64 prevtr = 0; -+ int32 prevcorr = 0; -+ int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt); -+ int32 timecnt = detzcode(up->tzhead.tzh_timecnt); -+ int32 typecnt = detzcode(up->tzhead.tzh_typecnt); -+ int32 charcnt = detzcode(up->tzhead.tzh_charcnt); - char const *p = up->buf + tzheadsize; - - /* -@@ -553,177 +265,152 @@ ++ int_fast64_t prevtr = 0; ++ int_fast32_t prevcorr = 0; + int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt); + int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt); + int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt); +@@ -553,177 +266,152 @@ && 0 <= typecnt && typecnt < TZ_MAX_TYPES && 0 <= timecnt && timecnt < TZ_MAX_TIMES && 0 <= charcnt && charcnt < TZ_MAX_CHARS @@ -743,8 +675,8 @@ + leapcnt = 0; + for (i = 0; i < sp->leapcnt; ++i) + { -+ int64 tr = stored == 4 ? detzcode(p) : detzcode64(p); -+ int32 corr = detzcode(p + stored); ++ int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); ++ int_fast32_t corr = detzcode(p + stored); - /* Read leap seconds, discarding those out of pg_time_t range. */ - leapcnt = 0; @@ -764,7 +696,7 @@ - * Leap seconds cannot occur before the Epoch, or out of - * order. + * Leap seconds cannot occur more than once per UTC month, and -+ * UTC months are at least 28 days long (minus 1 second for a ++ * UTC months are at least 2 days long (minus 1 second for a + * negative leap second). Each leap second's correction must + * differ from the previous one's by 1 second. */ @@ -870,7 +802,7 @@ } if (doextend && nread > 2 && up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && -@@ -732,9 +419,8 @@ +@@ -732,9 +420,8 @@ struct state *ts = &lsp->u.st; up->buf[nread - 1] = '\0'; @@ -881,7 +813,7 @@ /* * Attempt to reuse existing abbreviations. Without this, * America/Anchorage would be right on the edge after 2037 when -@@ -785,25 +471,20 @@ +@@ -785,25 +472,20 @@ == sp->types[sp->timecnt - 2])) sp->timecnt--; @@ -916,7 +848,7 @@ } for (i = 0; i < ts->typecnt; i++) sp->ttis[sp->typecnt++] = ts->ttis[i]; -@@ -812,6 +493,25 @@ +@@ -812,6 +494,25 @@ } if (sp->typecnt == 0) return EINVAL; @@ -942,7 +874,7 @@ /* * Infer sp->defaulttype from the data. Although this default type is -@@ -826,13 +526,13 @@ +@@ -826,13 +527,13 @@ */ /* @@ -959,7 +891,7 @@ /* * Absent the above, if there are transition times and the first -@@ -878,29 +578,49 @@ +@@ -878,29 +579,49 @@ } /* Load tz data from the file named NAME into *SP. Read extended @@ -1021,7 +953,7 @@ } static const int mon_lengths[2][MONSPERYEAR] = { -@@ -912,20 +632,13 @@ +@@ -912,20 +633,13 @@ DAYSPERNYEAR, DAYSPERLYEAR }; @@ -1043,7 +975,7 @@ getzname(const char *strp) { char c; -@@ -946,7 +659,7 @@ +@@ -946,7 +660,7 @@ * We don't do any checking here; checking is done later in common-case code. */ @@ -1052,16 +984,9 @@ getqzname(const char *strp, const int delim) { int c; -@@ -994,20 +707,19 @@ - */ +@@ -1000,8 +714,8 @@ + int_fast32_t secsperhour = SECSPERHOUR; - static const char * --getsecs(const char *strp, int_fast32_t * const secsp) -+getsecs(const char *strp, int32 *const secsp) - { - int num; -- int_fast32_t secsperhour = SECSPERHOUR; - /* - * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like - * "M10.4.6/26", which does not conform to POSIX, but which specifies the @@ -1070,24 +995,8 @@ * equivalent of "02:00 on the first Sunday on or after 23 Oct". */ strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); - if (strp == NULL) - return NULL; -- *secsp = num * secsperhour; -+ *secsp = num * (int32) SECSPERHOUR; - if (*strp == ':') - { - ++strp; -@@ -1036,7 +748,7 @@ - */ +@@ -1057,8 +771,7 @@ - static const char * --getoffset(const char *strp, int_fast32_t * const offsetp) -+getoffset(const char *strp, int32 *const offsetp) - { - bool neg = false; - -@@ -1057,8 +769,7 @@ - /* * Given a pointer into a timezone string, extract a rule in the form - * date[/time]. See POSIX Base Definitions section 8.3 variable TZ @@ -1096,23 +1005,7 @@ * If a valid rule is not found, return NULL. * Otherwise, return a pointer to the first character not part of the rule. */ -@@ -1124,12 +835,12 @@ - * effect, calculate the year-relative time that rule takes effect. - */ - --static int_fast32_t -+static int32 - transtime(const int year, const struct rule *const rulep, -- const int_fast32_t offset) -+ const int32 offset) - { - bool leapyear; -- int_fast32_t value; -+ int32 value; - int i; - int d, - m1, -@@ -1138,6 +849,7 @@ +@@ -1138,6 +851,7 @@ yy2, dow; @@ -1120,7 +1013,7 @@ leapyear = isleap(year); switch (rulep->r_type) { -@@ -1193,7 +905,7 @@ +@@ -1193,7 +907,7 @@ for (i = 1; i < rulep->r_week; ++i) { if (d + DAYSPERWEEK >= @@ -1129,7 +1022,7 @@ break; d += DAYSPERWEEK; } -@@ -1203,11 +915,8 @@ +@@ -1203,11 +917,8 @@ */ value = d * SECSPERDAY; for (i = 0; i < rulep->r_mon - 1; ++i) @@ -1142,7 +1035,7 @@ } /* -@@ -1219,64 +928,71 @@ +@@ -1219,64 +930,71 @@ } /* @@ -1159,14 +1052,12 @@ { const char *stdname; - const char *dstname; -- int_fast32_t stdoffset; -- int_fast32_t dstoffset; + const char *dstname = NULL; + size_t stdlen; + size_t dstlen; + size_t charcnt; -+ int32 stdoffset; -+ int32 dstoffset; + int_fast32_t stdoffset; + int_fast32_t dstoffset; char *cp; bool load_ok; - ptrdiff_t stdlen, @@ -1258,7 +1149,7 @@ if (*name != '\0') { if (*name == '<') -@@ -1294,9 +1010,11 @@ +@@ -1294,9 +1012,11 @@ name = getzname(name); dstlen = name - dstname; /* length of DST abbr. */ } @@ -1271,22 +1162,21 @@ if (*name != '\0' && *name != ',' && *name != ';') { name = getoffset(name, &dstoffset); -@@ -1312,11 +1030,11 @@ +@@ -1312,11 +1032,11 @@ struct rule start; struct rule end; int year; + int yearlim; int timecnt; pg_time_t janfirst; -- int_fast32_t janoffset = 0; + int_fast32_t janoffset = 0; - int yearbeg, - yearlim; -+ int32 janoffset = 0; + int yearbeg; ++name; if ((name = getrule(name, &start)) == NULL) -@@ -1334,13 +1052,14 @@ +@@ -1334,6 +1054,7 @@ */ init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); @@ -1294,15 +1184,7 @@ timecnt = 0; janfirst = 0; yearbeg = EPOCH_YEAR; - - do - { -- int_fast32_t yearsecs -+ int32 yearsecs - = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; - - yearbeg--; -@@ -1349,72 +1068,48 @@ +@@ -1349,27 +1070,9 @@ janoffset = -yearsecs; break; } @@ -1331,27 +1213,8 @@ + yearlim = yearbeg + YEARSPERREPEAT + 1; for (year = yearbeg; year < yearlim; year++) { -- int_fast32_t -- starttime = transtime(year, &start, stdoffset), -- endtime = transtime(year, &end, dstoffset); -- int_fast32_t -- yearsecs = (year_lengths[isleap(year)] -- * SECSPERDAY); -+ int32 -+ starttime = transtime(year, &start, stdoffset), -+ endtime = transtime(year, &end, dstoffset); -+ int32 -+ yearsecs = (year_lengths[isleap(year)] -+ * SECSPERDAY); - bool reversed = endtime < starttime; - - if (reversed) - { -- int_fast32_t swap = starttime; -+ int32 swap = starttime; - - starttime = endtime; - endtime = swap; + int_fast32_t +@@ -1389,32 +1092,26 @@ } if (reversed || (starttime < endtime @@ -1390,7 +1253,7 @@ if (increment_overflow_time (&janfirst, janoffset + yearsecs)) break; -@@ -1426,14 +1121,14 @@ +@@ -1426,7 +1123,7 @@ sp->ttis[0] = sp->ttis[1]; sp->typecnt = 1; /* Perpetual DST. */ } @@ -1399,17 +1262,7 @@ sp->goback = sp->goahead = true; } else - { -- int_fast32_t theirstdoffset; -- int_fast32_t theirdstoffset; -- int_fast32_t theiroffset; -+ int32 theirstdoffset; -+ int32 theirdstoffset; -+ int32 theiroffset; - bool isdst; - int i; - int j; -@@ -1471,6 +1166,7 @@ +@@ -1471,6 +1168,7 @@ * Initially we're assumed to be in standard time. */ isdst = false; @@ -1417,7 +1270,7 @@ /* * Now juggle transition times and types tracking offsets as you -@@ -1495,7 +1191,7 @@ +@@ -1495,7 +1193,7 @@ */ /* * Transitions from DST to DDST will effectively disappear @@ -1426,7 +1279,7 @@ */ if (isdst && !sp->ttis[j].tt_ttisstd) { -@@ -1521,6 +1217,7 @@ +@@ -1521,6 +1219,7 @@ init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); sp->typecnt = 2; @@ -1434,7 +1287,7 @@ } } else -@@ -1529,8 +1226,8 @@ +@@ -1529,8 +1228,8 @@ sp->typecnt = 1; /* only standard time */ sp->timecnt = 0; init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); @@ -1444,7 +1297,7 @@ sp->charcnt = charcnt; cp = sp->chars; memcpy(cp, stdname, stdlen); -@@ -1547,155 +1244,19 @@ +@@ -1547,155 +1246,19 @@ static void gmtload(struct state *const sp) { @@ -1603,7 +1456,7 @@ struct pg_tm *const tmp) { const struct ttinfo *ttisp; -@@ -1704,14 +1265,11 @@ +@@ -1704,14 +1267,11 @@ const pg_time_t t = *timep; if (sp == NULL) @@ -1620,7 +1473,7 @@ pg_time_t seconds; pg_time_t years; -@@ -1720,34 +1278,19 @@ +@@ -1720,33 +1280,18 @@ else seconds = t - sp->ats[sp->timecnt - 1]; --seconds; @@ -1655,12 +1508,10 @@ - result->tm_year, years)) - return NULL; -#else -- int_fast64_t newy; -+ int64 newy; + int_fast64_t newy; newy = result->tm_year; - if (t < sp->ats[0]) -@@ -1757,7 +1300,6 @@ +@@ -1757,7 +1302,6 @@ if (!(INT_MIN <= newy && newy <= INT_MAX)) return NULL; result->tm_year = newy; @@ -1668,7 +1519,7 @@ } return result; } -@@ -1779,7 +1321,7 @@ +@@ -1779,7 +1323,7 @@ else lo = mid + 1; } @@ -1677,7 +1528,7 @@ } ttisp = &sp->ttis[i]; -@@ -1792,132 +1334,76 @@ +@@ -1792,132 +1336,76 @@ if (result) { result->tm_isdst = ttisp->tt_isdst; @@ -1745,7 +1596,7 @@ static struct pg_tm * -gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, pg_time_t const *timep, - int_fast32_t offset, struct pg_tm *tmp) -+gmtsub(pg_time_t const *timep, int32 offset, ++gmtsub(pg_time_t const *timep, int_fast32_t offset, + struct pg_tm *tmp) { struct pg_tm *result; @@ -1840,13 +1691,7 @@ { return (y < 0 ? -1 - leaps_thru_end_of_nonneg(-1 - y) -@@ -1925,28 +1411,21 @@ - } - - static struct pg_tm * --timesub(const pg_time_t *timep, int_fast32_t offset, -+timesub(const pg_time_t *timep, int32 offset, - const struct state *sp, struct pg_tm *tmp) +@@ -1930,23 +1418,16 @@ { const struct lsinfo *lp; pg_time_t tdays; @@ -1876,7 +1721,7 @@ i = (sp == NULL) ? 0 : sp->leapcnt; while (--i >= 0) { -@@ -1954,175 +1433,134 @@ +@@ -1954,175 +1435,134 @@ if (*timep >= lp->ls_trans) { corr = lp->ls_corr; @@ -2092,8 +1937,7 @@ static bool -increment_overflow32(int_fast32_t * const lp, int const m) -+increment_overflow_time(pg_time_t *tp, int32 j) - { +-{ -#ifdef ckd_add - return ckd_add(lp, *lp, m); -#else @@ -2107,8 +1951,8 @@ -} - -static bool --increment_overflow_time(pg_time_t *tp, int_fast32_t j) --{ + increment_overflow_time(pg_time_t *tp, int_fast32_t j) + { -#ifdef ckd_add - return ckd_add(tp, *tp, j); -#else @@ -2124,7 +1968,7 @@ */ if (!(j < 0 ? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) -@@ -2130,637 +1568,339 @@ +@@ -2130,637 +1570,339 @@ return true; *tp += j; return false;