Update timezone to C99
authorPeter Eisentraut <peter@eisentraut.org>
Fri, 21 Nov 2025 12:01:30 +0000 (13:01 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Fri, 21 Nov 2025 12:07:40 +0000 (13:07 +0100)
This reverts changes done in PostgreSQL over the upstream code to
avoid relying on C99 <stdint.h> and <inttypes.h>.

In passing, there were a few other minor and cosmetic changes that I
left in to improve alignment with upstream, including some C11 feature
use (_Noreturn).

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/9ad2749f-77ab-4ecb-a321-1ca915480b05%40eisentraut.org

src/timezone/README
src/timezone/localtime.c
src/timezone/pgtz.h
src/timezone/private.h
src/timezone/zic.c
src/tools/pgindent/typedefs.list

index dd5d5f9892ad2e7b9376f84ee0147f7dfc1ff373..1857f03e3ddcfa78e4d5a516c336944d78db389a 100644 (file)
@@ -79,13 +79,6 @@ fixed that.)
 includes relying on configure's results rather than hand-hacked
 #defines (see private.h in particular).
 
-* Similarly, avoid relying on <stdint.h> features that may not exist on old
-systems.  In particular this means using Postgres' definitions of the int32
-and int64 typedefs, not int_fast32_t/int_fast64_t.  Likewise we use
-PG_INT32_MIN/MAX not INT32_MIN/MAX.  (Once we desupport all PG versions
-that don't require C99, it'd be practical to rely on <stdint.h> and remove
-this set of diffs; but that day is not yet.)
-
 * Since Postgres is typically built on a system that has its own copy
 of the <time.h> functions, we must avoid conflicting with those.  This
 mandates renaming typedef time_t to pg_time_t, and similarly for most
@@ -119,13 +112,6 @@ to first run the tzcode source files through a sed filter like this:
         -e 's|^\*/| */|' \
         -e 's/\bregister[ \t]//g' \
         -e 's/\bATTRIBUTE_PURE[ \t]//g' \
-        -e 's/int_fast32_t/int32/g' \
-        -e 's/int_fast64_t/int64/g' \
-        -e 's/intmax_t/int64/g' \
-        -e 's/INT32_MIN/PG_INT32_MIN/g' \
-        -e 's/INT32_MAX/PG_INT32_MAX/g' \
-        -e 's/INTMAX_MIN/PG_INT64_MIN/g' \
-        -e 's/INTMAX_MAX/PG_INT64_MAX/g' \
         -e 's/struct[ \t]+tm\b/struct pg_tm/g' \
         -e 's/\btime_t\b/pg_time_t/g' \
         -e 's/lineno/lineno_t/g' \
index 450d54ffd494da77d89152530c03987cf8e22191..20147f1a2c21b85b872c1682f1bedbf8b83f4c2c 100644 (file)
@@ -66,7 +66,7 @@ enum r_type
 {
    JULIAN_DAY,                 /* Jn = Julian day */
    DAY_OF_YEAR,                /* n = day of year */
-   MONTH_NTH_DAY_OF_WEEK,      /* Mm.n.d = month, week, day of week */
+   MONTH_NTH_DAY_OF_WEEK       /* Mm.n.d = month, week, day of week */
 };
 
 struct rule
@@ -75,20 +75,20 @@ struct rule
    int         r_day;          /* day number of rule */
    int         r_week;         /* week number of rule */
    int         r_mon;          /* month number of rule */
-   int32       r_time;         /* transition time of rule */
+   int_fast32_t r_time;        /* transition time of rule */
 };
 
 /*
  * Prototypes for static functions.
  */
 
-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 int64 leapcorr(struct state const *sp, pg_time_t t);
+static bool increment_overflow_time(pg_time_t *tp, int_fast32_t j);
+static int_fast64_t leapcorr(struct state const *sp, pg_time_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);
 
@@ -105,7 +105,7 @@ static struct pg_tm tm;
 
 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX.  */
 static void
-init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
+init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
 {
    s->tt_utoff = utoff;
    s->tt_isdst = isdst;
@@ -114,15 +114,15 @@ init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
    s->tt_ttisut = false;
 }
 
-static int32
+static int_fast32_t
 detzcode(const char *const codep)
 {
-   int32       result;
+   int_fast32_t result;
    int         i;
-   int32       one = 1;
-   int32       halfmaxval = one << (32 - 2);
-   int32       maxval = halfmaxval - 1 + halfmaxval;
-   int32       minval = -1 - maxval;
+   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;
 
    result = codep[0] & 0x7f;
    for (i = 1; i < 4; ++i)
@@ -134,21 +134,21 @@ detzcode(const char *const codep)
         * Do two's-complement negation even on non-two's-complement machines.
         * If the result would be minval - 1, return minval.
         */
-       result -= !TWOS_COMPLEMENT(int32) && result != 0;
+       result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
        result += minval;
    }
    return result;
 }
 
-static int64
+static int_fast64_t
 detzcode64(const char *const codep)
 {
-   uint64      result;
+   uint_fast64_t result;
    int         i;
-   int64       one = 1;
-   int64       halfmaxval = one << (64 - 2);
-   int64       maxval = halfmaxval - 1 + halfmaxval;
-   int64       minval = -TWOS_COMPLEMENT(int64) - maxval;
+   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;
 
    result = codep[0] & 0x7f;
    for (i = 1; i < 8; ++i)
@@ -160,7 +160,7 @@ detzcode64(const char *const codep)
         * Do two's-complement negation even on non-two's-complement machines.
         * If the result would be minval - 1, return minval.
         */
-       result -= !TWOS_COMPLEMENT(int64) && result != 0;
+       result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
        result += minval;
    }
    return result;
@@ -246,14 +246,14 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
        return errno;
    for (stored = 4; stored <= 8; stored *= 2)
    {
-       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);
+       int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
+       int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
+       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);
+       int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
        char const *p = up->buf + tzheadsize;
 
        /*
@@ -291,7 +291,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
        timecnt = 0;
        for (i = 0; i < sp->timecnt; ++i)
        {
-           int64       at
+           int_fast64_t at
            = stored == 4 ? detzcode(p) : detzcode64(p);
 
            sp->types[i] = at <= TIME_T_MAX;
@@ -350,8 +350,8 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
        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);
 
            p += stored + 4;
            /* Leap seconds cannot occur before the Epoch.  */
@@ -421,6 +421,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
        up->buf[nread - 1] = '\0';
        if (tzparse(&up->buf[1], ts, false))
        {
+
            /*
             * Attempt to reuse existing abbreviations. Without this,
             * America/Anchorage would be right on the edge after 2037 when
@@ -583,7 +584,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
  * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
  */
 int
-tzload(const char *name, char *canonname, struct state *sp, bool doextend)
+tzload(char const *name, char *canonname, struct state *sp, bool doextend)
 {
    union local_storage *lsp = malloc(sizeof *lsp);
 
@@ -707,7 +708,7 @@ getnum(const char *strp, int *const nump, const int min, const int max)
  */
 
 static const char *
-getsecs(const char *strp, int32 *const secsp)
+getsecs(const char *strp, int_fast32_t *const secsp)
 {
    int         num;
 
@@ -719,7 +720,7 @@ getsecs(const char *strp, int32 *const secsp)
    strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
    if (strp == NULL)
        return NULL;
-   *secsp = num * (int32) SECSPERHOUR;
+   *secsp = num * (int_fast32_t) SECSPERHOUR;
    if (*strp == ':')
    {
        ++strp;
@@ -748,7 +749,7 @@ getsecs(const char *strp, int32 *const secsp)
  */
 
 static const char *
-getoffset(const char *strp, int32 *const offsetp)
+getoffset(const char *strp, int_fast32_t *const offsetp)
 {
    bool        neg = false;
 
@@ -835,12 +836,12 @@ getrule(const char *strp, struct rule *const rulep)
  * effect, calculate the year-relative time that rule takes effect.
  */
 
-static int32
+static int_fast32_t
 transtime(const int year, const struct rule *const rulep,
-         const int32 offset)
+         const int_fast32_t offset)
 {
    bool        leapyear;
-   int32       value;
+   int_fast32_t value;
    int         i;
    int         d,
                m1,
@@ -940,8 +941,8 @@ tzparse(const char *name, struct state *sp, bool lastditch)
    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;
 
@@ -1033,7 +1034,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
            int         yearlim;
            int         timecnt;
            pg_time_t   janfirst;
-           int32       janoffset = 0;
+           int_fast32_t janoffset = 0;
            int         yearbeg;
 
            ++name;
@@ -1059,7 +1060,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
 
            do
            {
-               int32       yearsecs
+               int_fast32_t yearsecs
                = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
 
                yearbeg--;
@@ -1073,17 +1074,17 @@ tzparse(const char *name, struct state *sp, bool lastditch)
            yearlim = yearbeg + YEARSPERREPEAT + 1;
            for (year = yearbeg; year < yearlim; year++)
            {
-               int32
+               int_fast32_t
                            starttime = transtime(year, &start, stdoffset),
                            endtime = transtime(year, &end, dstoffset);
-               int32
+               int_fast32_t
                            yearsecs = (year_lengths[isleap(year)]
                                        * SECSPERDAY);
                bool        reversed = endtime < starttime;
 
                if (reversed)
                {
-                   int32       swap = starttime;
+                   int_fast32_t swap = starttime;
 
                    starttime = endtime;
                    endtime = swap;
@@ -1126,9 +1127,9 @@ tzparse(const char *name, struct state *sp, bool lastditch)
        }
        else
        {
-           int32       theirstdoffset;
-           int32       theirdstoffset;
-           int32       theiroffset;
+           int_fast32_t theirstdoffset;
+           int_fast32_t theirdstoffset;
+           int_fast32_t theiroffset;
            bool        isdst;
            int         i;
            int         j;
@@ -1290,7 +1291,7 @@ localsub(struct state const *sp, pg_time_t const *timep,
        result = localsub(sp, &newt, tmp);
        if (result)
        {
-           int64       newy;
+           int_fast64_t newy;
 
            newy = result->tm_year;
            if (t < sp->ats[0])
@@ -1354,7 +1355,7 @@ pg_localtime(const pg_time_t *timep, const pg_tz *tz)
  */
 
 static struct pg_tm *
-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;
@@ -1411,16 +1412,16 @@ leaps_thru_end_of(const int y)
 }
 
 static struct pg_tm *
-timesub(const pg_time_t *timep, int32 offset,
+timesub(const pg_time_t *timep, int_fast32_t offset,
        const struct state *sp, struct pg_tm *tmp)
 {
    const struct lsinfo *lp;
    pg_time_t   tdays;
    int         idays;          /* unsigned would be so 2003 */
-   int64       rem;
+   int_fast64_t rem;
    int         y;
    const int  *ip;
-   int64       corr;
+   int_fast64_t corr;
    bool        hit;
    int         i;
 
@@ -1554,7 +1555,7 @@ increment_overflow(int *ip, int j)
 }
 
 static bool
-increment_overflow_time(pg_time_t *tp, int32 j)
+increment_overflow_time(pg_time_t *tp, int_fast32_t j)
 {
    /*----------
     * This is like
@@ -1570,7 +1571,7 @@ increment_overflow_time(pg_time_t *tp, int32 j)
    return false;
 }
 
-static int64
+static int_fast64_t
 leapcorr(struct state const *sp, pg_time_t t)
 {
    struct lsinfo const *lp;
index 8caac631cab82351d6726db0bfac38837d6eaa6a..ff595ce974acfe307c922de43492953996914cdf 100644 (file)
@@ -25,7 +25,7 @@
 
 struct ttinfo
 {                              /* time type information */
-   int32       tt_utoff;       /* UT offset in seconds */
+   int_fast32_t tt_utoff;      /* UT offset in seconds */
    bool        tt_isdst;       /* used to set tm_isdst */
    int         tt_desigidx;    /* abbreviation list index */
    bool        tt_ttisstd;     /* transition is std time */
@@ -35,7 +35,7 @@ struct ttinfo
 struct lsinfo
 {                              /* leap second information */
    pg_time_t   ls_trans;       /* transition time */
-   int64       ls_corr;        /* correction to apply */
+   int_fast64_t ls_corr;       /* correction to apply */
 };
 
 struct state
index 39d40e43a9f70126ac79186fa6f2db79c7c1e9ed..ab89028f3e1fc71afb5c9842900f4d589f82d417 100644 (file)
 /* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
 #define is_digit(c) ((unsigned)(c) - '0' <= 9)
 
-/* PG doesn't currently rely on <inttypes.h>, so work around strtoimax() */
-#undef strtoimax
-#define strtoimax strtoll
-
 
 /*
  * Finally, some convenience items.
 #define YEARSPERREPEAT     400 /* years before a Gregorian repeat */
 
 #define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
+#define MINSPERHOUR    60
+#define HOURSPERDAY    24
+#define DAYSPERWEEK    7
 #define DAYSPERNYEAR   365
 #define DAYSPERLYEAR   366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((int32) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
+#define SECSPERHOUR    (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR    12
 
 #define TM_SUNDAY  0
 #define TM_MONDAY  1
 #define TM_TUESDAY 2
 #define TM_WEDNESDAY   3
-#define TM_THURSDAY 4
+#define TM_THURSDAY    4
 #define TM_FRIDAY  5
-#define TM_SATURDAY 6
+#define TM_SATURDAY    6
 
 #define TM_JANUARY 0
-#define TM_FEBRUARY 1
+#define TM_FEBRUARY    1
 #define TM_MARCH   2
 #define TM_APRIL   3
 #define TM_MAY     4
 #define TM_AUGUST  7
 #define TM_SEPTEMBER   8
 #define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
+#define TM_NOVEMBER    10
+#define TM_DECEMBER    11
 
 #define TM_YEAR_BASE   1900
 
 
 #define AVGSECSPERYEAR     31556952L
 #define SECSPERREPEAT \
-  ((int64) YEARSPERREPEAT * (int64) AVGSECSPERYEAR)
+  ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
 #define SECSPERREPEAT_BITS 34  /* ceil(log2(SECSPERREPEAT)) */
 
 #endif                         /* !defined PRIVATE_H */
index 3b70b8881805fd163cd9252cc861f76201b6704f..a8c1de9910db15ed5f904a3e9ef8dec4366800d1 100644 (file)
 #define    ZIC_VERSION_PRE_2013 '2'
 #define    ZIC_VERSION '3'
 
-typedef int64 zic_t;
-#define ZIC_MIN PG_INT64_MIN
-#define ZIC_MAX PG_INT64_MAX
+typedef int_fast64_t zic_t;
+#define ZIC_MIN INT_FAST64_MIN
+#define ZIC_MAX INT_FAST64_MAX
+#define PRIdZIC PRIdFAST64
+#define SCNdZIC SCNdFAST64
 
 #ifndef ZIC_MAX_ABBR_LEN_WO_WARN
 #define ZIC_MAX_ABBR_LEN_WO_WARN   6
@@ -47,12 +49,15 @@ typedef int64 zic_t;
 static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t));
 #endif
 
-/*
- * The type for line numbers.  In Postgres, use %d to format them; upstream
- * uses PRIdMAX but we prefer not to rely on that, not least because it
- * results in platform-dependent strings to be translated.
- */
-typedef int lineno_t;
+/* The minimum alignment of a type, for pre-C11 platforms.  */
+#if __STDC_VERSION__ < 201112
+#define _Alignof(type) offsetof(struct { char a; type b; }, b)
+#endif
+
+/* The type for line numbers.  Use PRIdMAX to format them; formerly
+   there was also "#define PRIdLINENO PRIdMAX" and formats used
+   PRIdLINENO, but xgettext cannot grok that.  */
+typedef intmax_t lineno_t;
 
 struct rule
 {
@@ -117,18 +122,16 @@ extern int    link(const char *target, const char *linkname);
    (itssymlink(target) ? (errno = ENOTSUP, -1) : link(target, linkname))
 #endif
 
-pg_noreturn static void memory_exhausted(const char *msg);
-static void verror(const char *string, va_list args) pg_attribute_printf(1, 0);
-static void error(const char *string,...) pg_attribute_printf(1, 2);
-static void warning(const char *string,...) pg_attribute_printf(1, 2);
-pg_noreturn static void usage(FILE *stream, int status);
+static void verror(const char *const string, va_list args) pg_attribute_printf(1, 0);
+static void error(const char *const string,...) pg_attribute_printf(1, 2);
+static void warning(const char *const string,...) pg_attribute_printf(1, 2);
 static void addtt(zic_t starttime, int type);
 static int addtype(zic_t utoff, char const *abbr,
                    bool isdst, bool ttisstd, bool ttisut);
 static void leapadd(zic_t t, int correction, int rolling);
 static void adjleap(void);
 static void associate(void);
-static void dolink(char const *target, char const *linkname,
+static void dolink(const char *target, const char *linkname,
                   bool staysymlink);
 static char **getfields(char *cp);
 static zic_t gethms(const char *string, const char *errstring);
@@ -407,7 +410,7 @@ static char roll[TZ_MAX_LEAPS];
  * Memory allocation.
  */
 
-static void
+static _Noreturn void
 memory_exhausted(const char *msg)
 {
    fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
@@ -422,6 +425,17 @@ size_product(size_t nitems, size_t itemsize)
    return nitems * itemsize;
 }
 
+static size_t
+align_to(size_t size, size_t alignment)
+{
+   size_t      aligned_size = size + alignment - 1;
+
+   aligned_size -= aligned_size % alignment;
+   if (aligned_size < size)
+       memory_exhausted(_("alignment overflow"));
+   return aligned_size;
+}
+
 static void *
 memcheck(void *ptr)
 {
@@ -485,23 +499,23 @@ eat(char const *name, lineno_t num)
 }
 
 static void
-verror(const char *string, va_list args)
+verror(const char *const string, va_list args)
 {
    /*
     * Match the format of "cc" to allow sh users to zic ... 2>&1 | error -t
     * "*" -v on BSD systems.
     */
    if (filename)
-       fprintf(stderr, _("\"%s\", line %d: "), filename, linenum);
+       fprintf(stderr, _("\"%s\", line %" PRIdMAX ": "), filename, linenum);
    vfprintf(stderr, string, args);
    if (rfilename != NULL)
-       fprintf(stderr, _(" (rule from \"%s\", line %d)"),
+       fprintf(stderr, _(" (rule from \"%s\", line %" PRIdMAX ")"),
                rfilename, rlinenum);
    fprintf(stderr, "\n");
 }
 
 static void
-error(const char *string,...)
+error(const char *const string,...)
 {
    va_list     args;
 
@@ -512,7 +526,7 @@ error(const char *string,...)
 }
 
 static void
-warning(const char *string,...)
+warning(const char *const string,...)
 {
    va_list     args;
 
@@ -539,7 +553,7 @@ close_file(FILE *stream, char const *dir, char const *name)
    }
 }
 
-static void
+static _Noreturn void
 usage(FILE *stream, int status)
 {
    fprintf(stream,
@@ -601,7 +615,7 @@ static zic_t comment_leapexpires = -1;
 static bool
 timerange_option(char *timerange)
 {
-   int64       lo = min_time,
+   intmax_t    lo = min_time,
                hi = max_time;
    char       *lo_end = timerange,
               *hi_end;
@@ -610,7 +624,7 @@ timerange_option(char *timerange)
    {
        errno = 0;
        lo = strtoimax(timerange + 1, &lo_end, 10);
-       if (lo_end == timerange + 1 || (lo == PG_INT64_MAX && errno == ERANGE))
+       if (lo_end == timerange + 1 || (lo == INTMAX_MAX && errno == ERANGE))
            return false;
    }
    hi_end = lo_end;
@@ -618,9 +632,9 @@ timerange_option(char *timerange)
    {
        errno = 0;
        hi = strtoimax(lo_end + 2, &hi_end, 10);
-       if (hi_end == lo_end + 2 || hi == PG_INT64_MIN)
+       if (hi_end == lo_end + 2 || hi == INTMAX_MIN)
            return false;
-       hi -= !(hi == PG_INT64_MAX && errno == ERANGE);
+       hi -= !(hi == INTMAX_MAX && errno == ERANGE);
    }
    if (*hi_end || hi < lo || max_time < lo || hi < min_time)
        return false;
@@ -1290,20 +1304,7 @@ infile(const char *name)
        if (nfields == 0)
        {
            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 <inttypes.h> 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)
        {
@@ -1364,8 +1365,7 @@ infile(const char *name)
 static zic_t
 gethms(char const *string, char const *errstring)
 {
-   /* PG: make hh be int not zic_t to avoid sscanf portability issues */
-   int         hh;
+   zic_t       hh;
    int         sign,
                mm = 0,
                ss = 0;
@@ -1387,7 +1387,7 @@ gethms(char const *string, char const *errstring)
    else
        sign = 1;
    switch (sscanf(string,
-                  "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
+                  "%" SCNdZIC "%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
                   &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs))
    {
        default:
@@ -1423,19 +1423,16 @@ gethms(char const *string, char const *errstring)
        error("%s", errstring);
        return 0;
    }
-   /* Some compilers warn that this test is unsatisfiable for 32-bit ints */
-#if INT_MAX > PG_INT32_MAX
    if (ZIC_MAX / SECSPERHOUR < hh)
    {
        error(_("time overflow"));
        return 0;
    }
-#endif
    ss += 5 + ((ss ^ 1) & (xr == '0')) <= tenths;   /* Round to even.  */
    if (noise && (hh > HOURSPERDAY ||
                  (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
        warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
-   return oadd(sign * (zic_t) hh * SECSPERHOUR,
+   return oadd(sign * hh * SECSPERHOUR,
                sign * (mm * SECSPERMIN + ss));
 }
 
@@ -1543,7 +1540,7 @@ inzone(char **fields, int nfields)
            strcmp(zones[i].z_name, fields[ZF_NAME]) == 0)
        {
            error(_("duplicate zone name %s"
-                   " (file \"%s\", line %d)"),
+                   " (file \"%s\", line %" PRIdMAX ")"),
                  fields[ZF_NAME],
                  zones[i].z_filename,
                  zones[i].z_linenum);
@@ -1669,9 +1666,7 @@ getleapdatetime(char **fields, int nfields, bool expire_line)
    const struct lookup *lp;
    zic_t       i,
                j;
-
-   /* PG: make year be int not zic_t to avoid sscanf portability issues */
-   int         year;
+   zic_t       year;
    int         month,
                day;
    zic_t       dayoff,
@@ -1681,7 +1676,7 @@ getleapdatetime(char **fields, int nfields, bool expire_line)
 
    dayoff = 0;
    cp = fields[LP_YEAR];
-   if (sscanf(cp, "%d%c", &year, &xs) != 1)
+   if (sscanf(cp, "%" SCNdZIC "%c", &year, &xs) != 1)
    {
        /*
         * Leapin' Lizards!
@@ -1830,9 +1825,6 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
    char       *ep;
    char        xs;
 
-   /* PG: year_tmp is to avoid sscanf portability issues */
-   int         year_tmp;
-
    if ((lp = byword(monthp, mon_names)) == NULL)
    {
        error(_("invalid month name"));
@@ -1890,9 +1882,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
                        progname, lp->l_value);
                exit(EXIT_FAILURE);
        }
-   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;
@@ -1918,9 +1908,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
                        progname, lp->l_value);
                exit(EXIT_FAILURE);
        }
-   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;
@@ -1989,7 +1977,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
 }
 
 static void
-convert(const int32 val, char *const buf)
+convert(const int_fast32_t val, char *const buf)
 {
    int         i;
    int         shift;
@@ -2011,7 +1999,7 @@ convert64(const zic_t val, char *const buf)
 }
 
 static void
-puttzcode(const int32 val, FILE *const fp)
+puttzcode(const int_fast32_t val, FILE *const fp)
 {
    char        buf[4];
 
@@ -2097,7 +2085,8 @@ writezone(const char *const name, const char *const string, char version,
     * Allocate the ATS and TYPES arrays via a single malloc, as this is a bit
     * faster.
     */
-   zic_t      *ats = emalloc(MAXALIGN(size_product(nats, sizeof *ats + 1)));
+   zic_t      *ats = emalloc(align_to(size_product(nats, sizeof *ats + 1),
+                                      _Alignof(zic_t)));
    void       *typesptr = ats + nats;
    unsigned char *types = typesptr;
    struct timerange rangeall,
@@ -2201,7 +2190,7 @@ writezone(const char *const name, const char *const string, char version,
    rangeall.count = timecnt;
    rangeall.leapcount = leapcnt;
    range64 = limitrange(rangeall, lo_time, hi_time, ats, types);
-   range32 = limitrange(range64, PG_INT32_MIN, PG_INT32_MAX, ats, types);
+   range32 = limitrange(range64, INT32_MIN, INT32_MAX, ats, types);
 
    /*
     * Remove old file, if any, to snap links.
@@ -2263,7 +2252,7 @@ writezone(const char *const name, const char *const string, char version,
            /*
             * 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
@@ -2271,7 +2260,7 @@ writezone(const char *const name, const char *const string, char version,
             * 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);
 
@@ -2280,8 +2269,8 @@ writezone(const char *const name, const char *const string, char version,
            toomanytimes = thistimecnt >> 31 >> 1 != 0;
            thisleapi = range32.leapbase;
            thisleapcnt = range32.leapcount;
-           locut = PG_INT32_MIN < lo_time;
-           hicut = hi_time < PG_INT32_MAX;
+           locut = INT32_MIN < lo_time;
+           hicut = hi_time < INT32_MAX;
        }
        else
        {
@@ -2476,7 +2465,7 @@ writezone(const char *const name, const char *const string, char version,
                    unsigned char tm = types[i];
                    char       *thisabbrev = &thischars[indmap[desigidx[tm]]];
 
-                   fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
+                   fprintf(stdout, "%s\t%" PRIdFAST64 "%s\n",
                            thisabbrev,
                            utoffs[tm],
                            isdsts[tm] ? "\tD" : "");
@@ -2488,7 +2477,7 @@ writezone(const char *const name, const char *const string, char version,
                unsigned char tm = defaulttype;
                char       *thisabbrev = &thischars[indmap[desigidx[tm]]];
 
-               fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
+               fprintf(stdout, "%s\t%" PRIdFAST64 "%s\n",
                        thisabbrev,
                        utoffs[tm],
                        isdsts[tm] ? "\tD" : "");
@@ -2499,7 +2488,7 @@ writezone(const char *const name, const char *const string, char version,
         * 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 < PG_INT32_MIN ? PG_INT32_MIN : lo_time;
+       lo = pass == 1 && lo_time < INT32_MIN ? INT32_MIN : lo_time;
 
        if (locut)
            puttzcodepass(lo, fp, pass);
@@ -3753,7 +3742,7 @@ getfields(char *cp)
    return array;
 }
 
-static void
+static _Noreturn void
 time_overflow(void)
 {
    error(_("time overflow"));
index c751c25a04d70a0523f5d44a4167f1b462a88db7..27a4d131897874b8212d1d92252ed16378dec2de 100644 (file)
@@ -3743,6 +3743,8 @@ int64_t
 int8
 int8_t
 int8x16_t
+int_fast32_t
+int_fast64_t
 internalPQconninfoOption
 intptr_t
 intset_internal_node
@@ -4197,6 +4199,7 @@ uint64x2_t
 uint8
 uint8_t
 uint8x16_t
+uint_fast64_t
 uintptr_t
 unicodeStyleBorderFormat
 unicodeStyleColumnFormat