Home | History | Annotate | Line # | Download | only in time
      1 /* Private header for tzdb code.  */
      2 
      3 /*	$NetBSD: private.h,v 1.71 2025/01/23 22:44:22 christos Exp $	*/
      4 
      5 #ifndef PRIVATE_H
      6 #define PRIVATE_H
      7 
      8 /* NetBSD defaults */
      9 #define TM_GMTOFF	tm_gmtoff
     10 #define TM_ZONE		tm_zone
     11 #define STD_INSPIRED	1
     12 #define HAVE_LONG_DOUBLE 1
     13 
     14 /* For when we build zic as a host tool. */
     15 #if HAVE_NBTOOL_CONFIG_H
     16 #include "nbtool_config.h"
     17 #endif
     18 
     19 /*
     20 ** This file is in the public domain, so clarified as of
     21 ** 1996-06-05 by Arthur David Olson.
     22 */
     23 
     24 /*
     25 ** This header is for use ONLY with the time conversion code.
     26 ** There is no guarantee that it will remain unchanged,
     27 ** or that it will remain at all.
     28 ** Do NOT copy it to any system include directory.
     29 ** Thank you!
     30 */
     31 
     32 /* PORT_TO_C89 means the code should work even if the underlying
     33    compiler and library support only C89 plus C99's 'long long'
     34    and perhaps a few other extensions to C89.
     35 
     36    This macro is obsolescent, and the plan is to remove it along with
     37    associated code.  A good time to do that might be in the year 2029
     38    because RHEL 7 (whose GCC defaults to C89) extended life cycle
     39    support (ELS) is scheduled to end on 2028-06-30.  */
     40 #ifndef PORT_TO_C89
     41 # define PORT_TO_C89 0
     42 #endif
     43 
     44 /* SUPPORT_C89 means the tzcode library should support C89 callers
     45    in addition to the usual support for C99-and-later callers.
     46    This defaults to 1 as POSIX requires, even though that can trigger
     47    latent bugs in callers.  */
     48 #ifndef SUPPORT_C89
     49 # define SUPPORT_C89 1
     50 #endif
     51 
     52 
     53 /* The following feature-test macros should be defined before
     54    any #include of a system header.  */
     55 
     56 /* Enable tm_gmtoff, tm_zone, and environ on GNUish systems.  */
     57 #define _GNU_SOURCE 1
     58 /* Fix asctime_r on Solaris 11.  */
     59 #define _POSIX_PTHREAD_SEMANTICS 1
     60 /* Enable strtoimax on pre-C99 Solaris 11.  */
     61 #define __EXTENSIONS__ 1
     62 /* Cause MS-Windows headers to define POSIX names.  */
     63 #define _CRT_DECLARE_NONSTDC_NAMES 1
     64 /* Prevent MS-Windows headers from defining min and max.  */
     65 #define NOMINMAX 1
     66 
     67 /* On GNUish systems where time_t might be 32 or 64 bits, use 64.
     68    On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
     69    setting _TIME_BITS to 64 does not work.  The code does not
     70    otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
     71    use off_t or functions like 'stat' that depend on off_t.  */
     72 #ifndef _TIME_BITS
     73 # ifndef _FILE_OFFSET_BITS
     74 #  define _FILE_OFFSET_BITS 64
     75 # endif
     76 # if _FILE_OFFSET_BITS == 64
     77 #  define _TIME_BITS 64
     78 # endif
     79 #endif
     80 
     81 /* End of feature-test macro definitions.  */
     82 
     83 
     84 #ifndef __STDC_VERSION__
     85 # define __STDC_VERSION__ 0
     86 #endif
     87 
     88 /* Define true, false and bool if they don't work out of the box.  */
     89 #if PORT_TO_C89 && __STDC_VERSION__ < 199901
     90 # define true 1
     91 # define false 0
     92 # define bool int
     93 #elif __STDC_VERSION__ < 202311
     94 # include <stdbool.h>
     95 #endif
     96 
     97 #if __STDC_VERSION__ < 202311
     98 # undef static_assert
     99 # define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
    100 #endif
    101 
    102 /*
    103 ** zdump has been made independent of the rest of the time
    104 ** conversion package to increase confidence in the verification it provides.
    105 ** You can use zdump to help in verifying other implementations.
    106 ** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
    107 */
    108 #ifndef USE_LTZ
    109 # define USE_LTZ 1
    110 #endif
    111 
    112 /* This string was in the Factory zone through version 2016f.  */
    113 #define GRANDPARENTED	"Local time zone must be set--see zic manual page"
    114 
    115 /*
    116 ** Defaults for preprocessor symbols.
    117 ** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
    118 */
    119 
    120 #if !defined HAVE__GENERIC && defined __has_extension
    121 # if !__has_extension(c_generic_selections)
    122 #  define HAVE__GENERIC 0
    123 # endif
    124 #endif
    125 /* _Generic is buggy in pre-4.9 GCC.  */
    126 #if !defined HAVE__GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
    127 # define HAVE__GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
    128 #endif
    129 #ifndef HAVE__GENERIC
    130 # define HAVE__GENERIC (201112 <= __STDC_VERSION__)
    131 #endif
    132 
    133 #if !defined HAVE_GETTEXT && defined __has_include
    134 # if __has_include(<libintl.h>)
    135 #  define HAVE_GETTEXT 1
    136 # endif
    137 #endif
    138 #ifndef HAVE_GETTEXT
    139 # define HAVE_GETTEXT 0
    140 #endif
    141 
    142 #ifndef HAVE_INCOMPATIBLE_CTIME_R
    143 # define HAVE_INCOMPATIBLE_CTIME_R 0
    144 #endif
    145 
    146 #ifndef HAVE_LINK
    147 # define HAVE_LINK 1
    148 #endif /* !defined HAVE_LINK */
    149 
    150 #ifndef HAVE_MALLOC_ERRNO
    151 # define HAVE_MALLOC_ERRNO 1
    152 #endif
    153 
    154 #ifndef HAVE_POSIX_DECLS
    155 # define HAVE_POSIX_DECLS 1
    156 #endif
    157 
    158 #ifndef HAVE_SETENV
    159 # define HAVE_SETENV 1
    160 #endif
    161 
    162 #ifndef HAVE_STRDUP
    163 # define HAVE_STRDUP 1
    164 #endif
    165 
    166 #ifndef HAVE_SYMLINK
    167 # define HAVE_SYMLINK 1
    168 #endif /* !defined HAVE_SYMLINK */
    169 
    170 #if !defined HAVE_SYS_STAT_H && defined __has_include
    171 # if !__has_include(<sys/stat.h>)
    172 #  define HAVE_SYS_STAT_H 0
    173 # endif
    174 #endif
    175 #ifndef HAVE_SYS_STAT_H
    176 # define HAVE_SYS_STAT_H 1
    177 #endif
    178 
    179 #if !defined HAVE_UNISTD_H && defined __has_include
    180 # if !__has_include(<unistd.h>)
    181 #  define HAVE_UNISTD_H 0
    182 # endif
    183 #endif
    184 #ifndef HAVE_UNISTD_H
    185 # define HAVE_UNISTD_H 1
    186 #endif
    187 
    188 #ifndef NETBSD_INSPIRED
    189 # define NETBSD_INSPIRED 1
    190 #endif
    191 
    192 #if HAVE_INCOMPATIBLE_CTIME_R
    193 # define asctime_r _incompatible_asctime_r
    194 # define ctime_r _incompatible_ctime_r
    195 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
    196 
    197 /*
    198 ** Nested includes
    199 */
    200 
    201 #ifndef __NetBSD__
    202 /* Avoid clashes with NetBSD by renaming NetBSD's declarations.
    203    If defining the 'timezone' variable, avoid a clash with FreeBSD's
    204    'timezone' function by renaming its declaration.  */
    205 #define localtime_rz sys_localtime_rz
    206 #define mktime_z sys_mktime_z
    207 #define posix2time_z sys_posix2time_z
    208 #define time2posix_z sys_time2posix_z
    209 #if defined USG_COMPAT && USG_COMPAT == 2
    210 # define timezone sys_timezone
    211 #endif
    212 #define timezone_t sys_timezone_t
    213 #define tzalloc sys_tzalloc
    214 #define tzfree sys_tzfree
    215 #include <time.h>
    216 #undef localtime_rz
    217 #undef mktime_z
    218 #undef posix2time_z
    219 #undef time2posix_z
    220 #if defined USG_COMPAT && USG_COMPAT == 2
    221 # undef timezone
    222 #endif
    223 #undef timezone_t
    224 #undef tzalloc
    225 #undef tzfree
    226 #else
    227 #include "time.h"
    228 #endif
    229 
    230 #include <stddef.h>
    231 #include <string.h>
    232 #if !PORT_TO_C89
    233 # include <inttypes.h>
    234 #endif
    235 #include <limits.h>	/* for CHAR_BIT et al. */
    236 #include <stdlib.h>
    237 
    238 #include <errno.h>
    239 
    240 #ifndef EINVAL
    241 # define EINVAL ERANGE
    242 #endif
    243 
    244 #ifndef ELOOP
    245 # define ELOOP EINVAL
    246 #endif
    247 #ifndef ENAMETOOLONG
    248 # define ENAMETOOLONG EINVAL
    249 #endif
    250 #ifndef ENOMEM
    251 # define ENOMEM EINVAL
    252 #endif
    253 #ifndef ENOTSUP
    254 # define ENOTSUP EINVAL
    255 #endif
    256 #ifndef EOVERFLOW
    257 # define EOVERFLOW EINVAL
    258 #endif
    259 
    260 #if HAVE_GETTEXT
    261 # include <libintl.h>
    262 #endif /* HAVE_GETTEXT */
    263 
    264 #if HAVE_UNISTD_H
    265 # include <unistd.h> /* for R_OK, and other POSIX goodness */
    266 #endif /* HAVE_UNISTD_H */
    267 
    268 /* SUPPORT_POSIX2008 means the tzcode library should support
    269    POSIX.1-2017-and-earlier callers in addition to the usual support for
    270    POSIX.1-2024-and-later callers; however, this can be
    271    incompatible with POSIX.1-2024-and-later callers.
    272    This macro is obsolescent, and the plan is to remove it
    273    along with any code needed only when it is nonzero.
    274    A good time to do that might be in the year 2034.
    275    This macro's name is SUPPORT_POSIX2008 because _POSIX_VERSION == 200809
    276    in POSIX.1-2017, a minor revision of POSIX.1-2008.  */
    277 #ifndef SUPPORT_POSIX2008
    278 # if defined _POSIX_VERSION && _POSIX_VERSION <= 200809
    279 #  define SUPPORT_POSIX2008 1
    280 # else
    281 #  define SUPPORT_POSIX2008 0
    282 # endif
    283 #endif
    284 
    285 #ifndef HAVE_DECL_ASCTIME_R
    286 # if SUPPORT_POSIX2008
    287 #  define HAVE_DECL_ASCTIME_R 1
    288 # else
    289 #  define HAVE_DECL_ASCTIME_R 0
    290 # endif
    291 #endif
    292 
    293 #ifndef HAVE_SNPRINTF
    294 # define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
    295 #endif
    296 
    297 #ifndef HAVE_STRFTIME_L
    298 # if _POSIX_VERSION < 200809
    299 #  define HAVE_STRFTIME_L 0
    300 # else
    301 #  define HAVE_STRFTIME_L 1
    302 # endif
    303 #endif
    304 
    305 #ifndef USG_COMPAT
    306 # ifndef _XOPEN_VERSION
    307 #  define USG_COMPAT 0
    308 # else
    309 #  define USG_COMPAT 1
    310 # endif
    311 #endif
    312 
    313 #ifndef HAVE_TZNAME
    314 # if _POSIX_VERSION < 198808 && !USG_COMPAT
    315 #  define HAVE_TZNAME 0
    316 # else
    317 #  define HAVE_TZNAME 1
    318 # endif
    319 #endif
    320 
    321 #ifndef ALTZONE
    322 # if defined __sun || defined _M_XENIX
    323 #  define ALTZONE 1
    324 # else
    325 #  define ALTZONE 0
    326 # endif
    327 #endif
    328 
    329 #ifndef R_OK
    330 # define R_OK 4
    331 #endif /* !defined R_OK */
    332 
    333 #if PORT_TO_C89
    334 
    335 /*
    336 ** Define HAVE_STDINT_H's default value here, rather than at the
    337 ** start, since __GLIBC__ and INTMAX_MAX's values depend on
    338 ** previously included files.  glibc 2.1 and Solaris 10 and later have
    339 ** stdint.h, even with pre-C99 compilers.
    340 */
    341 #if !defined HAVE_STDINT_H && defined __has_include
    342 # define HAVE_STDINT_H 1 /* C23 __has_include implies C99 stdint.h.  */
    343 #endif
    344 #ifndef HAVE_STDINT_H
    345 # define HAVE_STDINT_H \
    346    (199901 <= __STDC_VERSION__ \
    347     || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
    348     || __CYGWIN__ || INTMAX_MAX)
    349 #endif /* !defined HAVE_STDINT_H */
    350 
    351 #if HAVE_STDINT_H
    352 # include <stdint.h>
    353 #endif /* !HAVE_STDINT_H */
    354 
    355 #ifndef HAVE_INTTYPES_H
    356 # define HAVE_INTTYPES_H HAVE_STDINT_H
    357 #endif
    358 #if HAVE_INTTYPES_H
    359 # include <inttypes.h>
    360 #endif
    361 
    362 /* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX.  */
    363 #if defined __LONG_LONG_MAX__ && !defined __STRICT_ANSI__
    364 # ifndef LLONG_MAX
    365 #  define LLONG_MAX __LONG_LONG_MAX__
    366 # endif
    367 # ifndef LLONG_MIN
    368 #  define LLONG_MIN (-1 - LLONG_MAX)
    369 # endif
    370 # ifndef ULLONG_MAX
    371 #  define ULLONG_MAX (LLONG_MAX * 2ull + 1)
    372 # endif
    373 #endif
    374 
    375 #ifndef INT_FAST64_MAX
    376 # if 1 <= LONG_MAX >> 31 >> 31
    377 typedef long int_fast64_t;
    378 #  define INT_FAST64_MIN LONG_MIN
    379 #  define INT_FAST64_MAX LONG_MAX
    380 # else
    381 /* If this fails, compile with -DHAVE_STDINT_H or with a better compiler.  */
    382 typedef long long int_fast64_t;
    383 #  define INT_FAST64_MIN LLONG_MIN
    384 #  define INT_FAST64_MAX LLONG_MAX
    385 # endif
    386 #endif
    387 
    388 #ifndef PRIdFAST64
    389 # if INT_FAST64_MAX == LONG_MAX
    390 #  define PRIdFAST64 "ld"
    391 # else
    392 #  define PRIdFAST64 "lld"
    393 # endif
    394 #endif
    395 
    396 #ifndef SCNdFAST64
    397 # define SCNdFAST64 PRIdFAST64
    398 #endif
    399 
    400 #ifndef INT_FAST32_MAX
    401 # if INT_MAX >> 31 == 0
    402 typedef long int_fast32_t;
    403 #  define INT_FAST32_MAX LONG_MAX
    404 #  define INT_FAST32_MIN LONG_MIN
    405 # else
    406 typedef int int_fast32_t;
    407 #  define INT_FAST32_MAX INT_MAX
    408 #  define INT_FAST32_MIN INT_MIN
    409 # endif
    410 #endif
    411 
    412 #ifndef INT_LEAST32_MAX
    413 typedef int_fast32_t int_least32_t;
    414 #endif
    415 
    416 #ifndef INTMAX_MAX
    417 # ifdef LLONG_MAX
    418 typedef long long intmax_t;
    419 #  ifndef HAVE_STRTOLL
    420 #   define HAVE_STRTOLL 1
    421 #  endif
    422 #  if HAVE_STRTOLL
    423 #   define strtoimax strtoll
    424 #  endif
    425 #  define INTMAX_MAX LLONG_MAX
    426 #  define INTMAX_MIN LLONG_MIN
    427 # else
    428 typedef long intmax_t;
    429 #  define INTMAX_MAX LONG_MAX
    430 #  define INTMAX_MIN LONG_MIN
    431 # endif
    432 # ifndef strtoimax
    433 #  define strtoimax strtol
    434 # endif
    435 #endif
    436 
    437 #ifndef PRIdMAX
    438 # if INTMAX_MAX == LLONG_MAX
    439 #  define PRIdMAX "lld"
    440 # else
    441 #  define PRIdMAX "ld"
    442 # endif
    443 #endif
    444 
    445 #ifndef PTRDIFF_MAX
    446 # define PTRDIFF_MAX MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
    447 #endif
    448 
    449 #ifndef UINT_FAST32_MAX
    450 typedef unsigned long uint_fast32_t;
    451 #endif
    452 
    453 #ifndef UINT_FAST64_MAX
    454 # if 3 <= ULONG_MAX >> 31 >> 31
    455 typedef unsigned long uint_fast64_t;
    456 #  define UINT_FAST64_MAX ULONG_MAX
    457 # else
    458 /* If this fails, compile with -DHAVE_STDINT_H or with a better compiler.  */
    459 typedef unsigned long long uint_fast64_t;
    460 #  define UINT_FAST64_MAX ULLONG_MAX
    461 # endif
    462 #endif
    463 
    464 #ifndef UINTMAX_MAX
    465 # ifdef ULLONG_MAX
    466 typedef unsigned long long uintmax_t;
    467 #  define UINTMAX_MAX ULLONG_MAX
    468 # else
    469 typedef unsigned long uintmax_t;
    470 #  define UINTMAX_MAX ULONG_MAX
    471 # endif
    472 #endif
    473 
    474 #ifndef PRIuMAX
    475 # ifdef ULLONG_MAX
    476 #  define PRIuMAX "llu"
    477 # else
    478 #  define PRIuMAX "lu"
    479 # endif
    480 #endif
    481 
    482 #ifndef SIZE_MAX
    483 # define SIZE_MAX ((size_t) -1)
    484 #endif
    485 
    486 #endif /* PORT_TO_C89 */
    487 
    488 /* The maximum size of any created object, as a signed integer.
    489    Although the C standard does not outright prohibit larger objects,
    490    behavior is undefined if the result of pointer subtraction does not
    491    fit into ptrdiff_t, and the code assumes in several places that
    492    pointer subtraction works.  As a practical matter it's OK to not
    493    support objects larger than this.  */
    494 #define INDEX_MAX ((ptrdiff_t) min(PTRDIFF_MAX, SIZE_MAX))
    495 
    496 /* Support ckd_add, ckd_sub, ckd_mul on C23 or recent-enough GCC-like
    497    hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG.  */
    498 #if !defined HAVE_STDCKDINT_H && defined __has_include
    499 # if __has_include(<stdckdint.h>)
    500 #  define HAVE_STDCKDINT_H 1
    501 # endif
    502 #endif
    503 #ifdef HAVE_STDCKDINT_H
    504 # if HAVE_STDCKDINT_H
    505 #  include <stdckdint.h>
    506 # endif
    507 #elif defined __EDG__
    508 /* Do nothing, to work around EDG bug <https://bugs.gnu.org/53256>.  */
    509 #elif defined __has_builtin
    510 # if __has_builtin(__builtin_add_overflow)
    511 #  define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
    512 # endif
    513 # if __has_builtin(__builtin_sub_overflow)
    514 #  define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
    515 # endif
    516 # if __has_builtin(__builtin_mul_overflow)
    517 #  define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
    518 # endif
    519 #elif 7 <= __GNUC__
    520 # define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
    521 # define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
    522 # define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
    523 #endif
    524 
    525 #if (defined __has_c_attribute \
    526      && (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
    527 # define HAVE___HAS_C_ATTRIBUTE true
    528 #else
    529 # define HAVE___HAS_C_ATTRIBUTE false
    530 #endif
    531 
    532 #if HAVE___HAS_C_ATTRIBUTE
    533 # if __has_c_attribute(deprecated)
    534 #  define ATTRIBUTE_DEPRECATED [[deprecated]]
    535 # endif
    536 #endif
    537 #ifndef ATTRIBUTE_DEPRECATED
    538 # if 3 < __GNUC__ + (2 <= __GNUC_MINOR__)
    539 #  define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
    540 # else
    541 #  define ATTRIBUTE_DEPRECATED /* empty */
    542 # endif
    543 #endif
    544 
    545 #if HAVE___HAS_C_ATTRIBUTE
    546 # if __has_c_attribute(fallthrough)
    547 #  define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
    548 # endif
    549 #endif
    550 #ifndef ATTRIBUTE_FALLTHROUGH
    551 # if 7 <= __GNUC__
    552 #  define ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
    553 # else
    554 #  define ATTRIBUTE_FALLTHROUGH ((void) 0)
    555 # endif
    556 #endif
    557 
    558 #if HAVE___HAS_C_ATTRIBUTE
    559 # if __has_c_attribute(maybe_unused)
    560 #  define ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
    561 # endif
    562 #endif
    563 #ifndef ATTRIBUTE_MAYBE_UNUSED
    564 # if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
    565 #  define ATTRIBUTE_MAYBE_UNUSED __attribute__((unused))
    566 # else
    567 #  define ATTRIBUTE_MAYBE_UNUSED /* empty */
    568 # endif
    569 #endif
    570 
    571 #if HAVE___HAS_C_ATTRIBUTE
    572 # if __has_c_attribute(noreturn)
    573 #  define ATTRIBUTE_NORETURN [[noreturn]]
    574 # endif
    575 #endif
    576 #ifndef ATTRIBUTE_NORETURN
    577 # if 201112 <= __STDC_VERSION__
    578 #  define ATTRIBUTE_NORETURN _Noreturn
    579 # elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
    580 #  define ATTRIBUTE_NORETURN __attribute__((noreturn))
    581 # else
    582 #  define ATTRIBUTE_NORETURN /* empty */
    583 # endif
    584 #endif
    585 
    586 #if HAVE___HAS_C_ATTRIBUTE
    587 # if __has_c_attribute(reproducible)
    588 #  define ATTRIBUTE_REPRODUCIBLE [[reproducible]]
    589 # endif
    590 #endif
    591 #ifndef ATTRIBUTE_REPRODUCIBLE
    592 # define ATTRIBUTE_REPRODUCIBLE /* empty */
    593 #endif
    594 
    595 #if HAVE___HAS_C_ATTRIBUTE
    596 # if __has_c_attribute(unsequenced)
    597 #  define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
    598 # endif
    599 #endif
    600 #ifndef ATTRIBUTE_UNSEQUENCED
    601 # define ATTRIBUTE_UNSEQUENCED /* empty */
    602 #endif
    603 
    604 /* GCC attributes that are useful in tzcode.
    605    __attribute__((const)) is stricter than [[unsequenced]],
    606    so the latter is an adequate substitute in non-GCC C23 platforms.
    607    __attribute__((pure)) is stricter than [[reproducible]],
    608    so the latter is an adequate substitute in non-GCC C23 platforms.  */
    609 #if __GNUC__ < 3
    610 # define ATTRIBUTE_CONST ATTRIBUTE_UNSEQUENCED
    611 # define ATTRIBUTE_FORMAT(spec) /* empty */
    612 # define ATTRIBUTE_PURE ATTRIBUTE_REPRODUCIBLE
    613 #else
    614 # define ATTRIBUTE_CONST __attribute__((const))
    615 # define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
    616 # define ATTRIBUTE_PURE __attribute__((pure))
    617 #endif
    618 
    619 /* Avoid GCC bug 114833 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114833>.
    620    Remove this macro and its uses when the bug is fixed in a GCC release,
    621    because only the latest GCC matters for $(GCC_DEBUG_FLAGS).  */
    622 #ifdef GCC_LINT
    623 # define ATTRIBUTE_PURE_114833 ATTRIBUTE_PURE
    624 #else
    625 # define ATTRIBUTE_PURE_114833 /* empty */
    626 #endif
    627 
    628 #if (__STDC_VERSION__ < 199901 && !defined restrict \
    629      && (PORT_TO_C89 || defined _MSC_VER))
    630 # define restrict /* empty */
    631 #endif
    632 
    633 /*
    634 ** Workarounds for compilers/systems.
    635 */
    636 
    637 #ifndef EPOCH_LOCAL
    638 # define EPOCH_LOCAL 0
    639 #endif
    640 #ifndef EPOCH_OFFSET
    641 # define EPOCH_OFFSET 0
    642 #endif
    643 #ifndef RESERVE_STD_EXT_IDS
    644 # define RESERVE_STD_EXT_IDS 0
    645 #endif
    646 
    647 #ifdef time_tz
    648 # define defined_time_tz true
    649 #else
    650 # define defined_time_tz false
    651 #endif
    652 
    653 /* If standard C identifiers with external linkage (e.g., localtime)
    654    are reserved and are not already being renamed anyway, rename them
    655    as if compiling with '-Dtime_tz=time_t'.  */
    656 #if !defined time_tz && RESERVE_STD_EXT_IDS && USE_LTZ
    657 # define time_tz time_t
    658 #endif
    659 
    660 /*
    661 ** Compile with -Dtime_tz=T to build the tz package with a private
    662 ** time_t type equivalent to T rather than the system-supplied time_t.
    663 ** This debugging feature can test unusual design decisions
    664 ** (e.g., time_t wider than 'long', or unsigned time_t) even on
    665 ** typical platforms.
    666 */
    667 #if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
    668 # define TZ_TIME_T true
    669 #else
    670 # define TZ_TIME_T false
    671 #endif
    672 
    673 #if defined LOCALTIME_IMPLEMENTATION && TZ_TIME_T
    674 static time_t sys_time(time_t *x) { return time(x); }
    675 #endif
    676 
    677 #if TZ_TIME_T
    678 
    679 typedef time_tz tz_time_t;
    680 
    681 # undef  asctime
    682 # define asctime tz_asctime
    683 # undef  ctime
    684 # define ctime tz_ctime
    685 # undef  difftime
    686 # define difftime tz_difftime
    687 # undef  gmtime
    688 # define gmtime tz_gmtime
    689 # undef  gmtime_r
    690 # define gmtime_r tz_gmtime_r
    691 # undef  localtime
    692 # define localtime tz_localtime
    693 # undef  localtime_r
    694 # define localtime_r tz_localtime_r
    695 # undef  localtime_rz
    696 # define localtime_rz tz_localtime_rz
    697 # undef  mktime
    698 # define mktime tz_mktime
    699 # undef  mktime_z
    700 # define mktime_z tz_mktime_z
    701 # undef  offtime
    702 # define offtime tz_offtime
    703 # undef  posix2time
    704 # define posix2time tz_posix2time
    705 # undef  posix2time_z
    706 # define posix2time_z tz_posix2time_z
    707 # undef  strftime
    708 # define strftime tz_strftime
    709 # undef  time
    710 # define time tz_time
    711 # undef  time2posix
    712 # define time2posix tz_time2posix
    713 # undef  time2posix_z
    714 # define time2posix_z tz_time2posix_z
    715 # undef  time_t
    716 # define time_t tz_time_t
    717 # undef  timegm
    718 # define timegm tz_timegm
    719 # undef  timelocal
    720 # define timelocal tz_timelocal
    721 # undef  timeoff
    722 # define timeoff tz_timeoff
    723 # undef  tzalloc
    724 # define tzalloc tz_tzalloc
    725 # undef  tzfree
    726 # define tzfree tz_tzfree
    727 # undef  tzset
    728 # define tzset tz_tzset
    729 # undef  tzsetwall
    730 # define tzsetwall tz_tzsetwall
    731 # if SUPPORT_POSIX2008
    732 #  undef  asctime_r
    733 #  define asctime_r tz_asctime_r
    734 #  undef  ctime_r
    735 #  define ctime_r tz_ctime_r
    736 # endif
    737 # if HAVE_STRFTIME_L
    738 #  undef  strftime_l
    739 #  define strftime_l tz_strftime_l
    740 # endif
    741 # if HAVE_TZNAME
    742 #  undef  tzname
    743 #  define tzname tz_tzname
    744 # endif
    745 # if USG_COMPAT
    746 #  undef  daylight
    747 #  define daylight tz_daylight
    748 #  undef  timezone
    749 #  define timezone tz_timezone
    750 # endif
    751 # if ALTZONE
    752 #  undef  altzone
    753 #  define altzone tz_altzone
    754 # endif
    755 
    756 # if __STDC_VERSION__ < 202311
    757 #  define DEPRECATED_IN_C23 /* empty */
    758 # else
    759 #  define DEPRECATED_IN_C23 ATTRIBUTE_DEPRECATED
    760 # endif
    761 DEPRECATED_IN_C23 char *asctime(struct tm const *);
    762 DEPRECATED_IN_C23 char *ctime(time_t const *);
    763 #if SUPPORT_POSIX2008
    764 char *asctime_r(struct tm const *restrict, char *restrict);
    765 char *ctime_r(time_t const *, char *);
    766 #endif
    767 ATTRIBUTE_CONST double difftime(time_t, time_t);
    768 size_t strftime(char *restrict, size_t, char const *restrict,
    769 		struct tm const *restrict);
    770 # if HAVE_STRFTIME_L
    771 size_t strftime_l(char *restrict, size_t, char const *restrict,
    772 		  struct tm const *restrict, locale_t);
    773 # endif
    774 struct tm *gmtime(time_t const *);
    775 struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
    776 struct tm *localtime(time_t const *);
    777 struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
    778 time_t mktime(struct tm *);
    779 time_t time(time_t *);
    780 time_t timegm(struct tm *);
    781 void tzset(void);
    782 #endif
    783 
    784 #ifndef HAVE_DECL_TIMEGM
    785 # if (202311 <= __STDC_VERSION__ \
    786       || defined __GLIBC__ || defined __tm_zone /* musl */ \
    787       || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
    788       || (defined __APPLE__ && defined __MACH__))
    789 #  define HAVE_DECL_TIMEGM 1
    790 # else
    791 #  define HAVE_DECL_TIMEGM 0
    792 # endif
    793 #endif
    794 #if !HAVE_DECL_TIMEGM && !defined timegm
    795 time_t timegm(struct tm *);
    796 #endif
    797 
    798 #if !HAVE_DECL_ASCTIME_R && !defined asctime_r && SUPPORT_POSIX2008
    799 extern char *asctime_r(struct tm const *restrict, char *restrict);
    800 #endif
    801 
    802 #ifndef HAVE_DECL_ENVIRON
    803 # if defined environ || defined __USE_GNU
    804 #  define HAVE_DECL_ENVIRON 1
    805 # else
    806 #  define HAVE_DECL_ENVIRON 0
    807 # endif
    808 #endif
    809 
    810 #if !HAVE_DECL_ENVIRON
    811 extern char **environ;
    812 #endif
    813 
    814 #if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS)
    815 extern char *tzname[];
    816 #endif
    817 #if 2 <= USG_COMPAT + (TZ_TIME_T || !HAVE_POSIX_DECLS)
    818 extern long timezone;
    819 extern int daylight;
    820 #endif
    821 #if 2 <= ALTZONE + (TZ_TIME_T || !HAVE_POSIX_DECLS)
    822 extern long altzone;
    823 #endif
    824 
    825 /*
    826 ** The STD_INSPIRED functions are similar, but most also need
    827 ** declarations if time_tz is defined.
    828 */
    829 
    830 #ifndef STD_INSPIRED
    831 # ifdef __NetBSD__
    832 #  define STD_INSPIRED 1
    833 # else
    834 #  define STD_INSPIRED 0
    835 # endif
    836 #endif
    837 #if STD_INSPIRED
    838 # if TZ_TIME_T || !defined tzsetwall
    839 void tzsetwall(void);
    840 # endif
    841 # if TZ_TIME_T || !defined offtime
    842 struct tm *offtime(time_t const *, long);
    843 # endif
    844 # if TZ_TIME_T || !defined timelocal
    845 time_t timelocal(struct tm *);
    846 # endif
    847 # if TZ_TIME_T || !defined timeoff
    848 #  define EXTERN_TIMEOFF
    849 # endif
    850 # if TZ_TIME_T || !defined time2posix
    851 time_t time2posix(time_t);
    852 # endif
    853 # if TZ_TIME_T || !defined posix2time
    854 time_t posix2time(time_t);
    855 # endif
    856 #endif
    857 
    858 /* Infer TM_ZONE on systems where this information is known, but suppress
    859    guessing if NO_TM_ZONE is defined.  Similarly for TM_GMTOFF.  */
    860 #if (200809 < _POSIX_VERSION \
    861      || defined __GLIBC__ \
    862      || defined __tm_zone /* musl */ \
    863      || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
    864      || (defined __APPLE__ && defined __MACH__))
    865 # if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
    866 #  define TM_GMTOFF tm_gmtoff
    867 # endif
    868 # if !defined TM_ZONE && !defined NO_TM_ZONE
    869 #  define TM_ZONE tm_zone
    870 # endif
    871 #endif
    872 
    873 /*
    874 ** Define functions that are ABI compatible with NetBSD but have
    875 ** better prototypes.  NetBSD 6.1.4 defines a pointer type timezone_t
    876 ** and labors under the misconception that 'const timezone_t' is a
    877 ** pointer to a constant.  This use of 'const' is ineffective, so it
    878 ** is not done here.  What we call 'struct state' NetBSD calls
    879 ** 'struct __state', but this is a private name so it doesn't matter.
    880 */
    881 #ifndef __NetBSD__
    882 #if NETBSD_INSPIRED
    883 typedef struct state *timezone_t;
    884 struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
    885 			struct tm *restrict);
    886 time_t mktime_z(timezone_t restrict, struct tm *restrict);
    887 timezone_t tzalloc(char const *);
    888 void tzfree(timezone_t);
    889 # if STD_INSPIRED
    890 #  if TZ_TIME_T || !defined posix2time_z
    891 ATTRIBUTE_PURE time_t posix2time_z(timezone_t __restrict, time_t);
    892 #  endif
    893 #  if TZ_TIME_T || !defined time2posix_z
    894 ATTRIBUTE_PURE time_t time2posix_z(timezone_t __restrict, time_t);
    895 #  endif
    896 # endif
    897 #endif
    898 #endif
    899 
    900 /*
    901 ** Finally, some convenience items.
    902 */
    903 
    904 #define TYPE_BIT(type) (CHAR_BIT * (ptrdiff_t) sizeof(type))
    905 #define TYPE_SIGNED(type) (/*CONSTCOND*/((type) -1) < 0)
    906 #define TWOS_COMPLEMENT(t) (/*CONSTCOND*/(t) ~ (t) 0 < 0)
    907 
    908 /* Minimum and maximum of two values.  Use lower case to avoid
    909    naming clashes with standard include files.  */
    910 #define max(a, b) ((a) > (b) ? (a) : (b))
    911 #define min(a, b) ((a) < (b) ? (a) : (b))
    912 
    913 /* Max and min values of the integer type T, of which only the bottom
    914    B bits are used, and where the highest-order used bit is considered
    915    to be a sign bit if T is signed.  */
    916 #define MAXVAL(t, b) /*LINTED*/					\
    917   ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))			\
    918 	- 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
    919 #define MINVAL(t, b)						\
    920   ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
    921 
    922 /* The extreme time values, assuming no padding.  */
    923 #define TIME_T_MIN_NO_PADDING MINVAL(time_t, TYPE_BIT(time_t))
    924 #define TIME_T_MAX_NO_PADDING MAXVAL(time_t, TYPE_BIT(time_t))
    925 
    926 /* The extreme time values.  These are macros, not constants, so that
    927    any portability problems occur only when compiling .c files that use
    928    the macros, which is safer for applications that need only zdump and zic.
    929    This implementation assumes no padding if time_t is signed and
    930    either the compiler lacks support for _Generic or time_t is not one
    931    of the standard signed integer types.  */
    932 #if HAVE__GENERIC
    933 # define TIME_T_MIN \
    934     _Generic((time_t) 0, \
    935 	     signed char: SCHAR_MIN, short: SHRT_MIN, \
    936 	     int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \
    937 	     default: TIME_T_MIN_NO_PADDING)
    938 # define TIME_T_MAX \
    939     (TYPE_SIGNED(time_t) \
    940      ? _Generic((time_t) 0, \
    941 		signed char: SCHAR_MAX, short: SHRT_MAX, \
    942 		int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
    943 		default: TIME_T_MAX_NO_PADDING)			    \
    944      : (time_t) -1)
    945 enum { SIGNED_PADDING_CHECK_NEEDED
    946 	 = _Generic((time_t) 0,
    947 		    signed char: false, short: false,
    948 		    int: false, long: false, long long: false,
    949 		    default: true) };
    950 #else
    951 # define TIME_T_MIN TIME_T_MIN_NO_PADDING
    952 # define TIME_T_MAX TIME_T_MAX_NO_PADDING
    953 enum { SIGNED_PADDING_CHECK_NEEDED = true };
    954 #endif
    955 /* Try to check the padding assumptions.  Although TIME_T_MAX and the
    956    following check can both have undefined behavior on oddball
    957    platforms due to shifts exceeding widths of signed integers, these
    958    platforms' compilers are likely to diagnose these issues in integer
    959    constant expressions, so it shouldn't hurt to check statically.  */
    960 static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
    961 	      || TIME_T_MAX >> (TYPE_BIT(time_t) - 2) == 1);
    962 
    963 /*
    964 ** 302 / 1000 is log10(2.0) rounded up.
    965 ** Subtract one for the sign bit if the type is signed;
    966 ** add one for integer division truncation;
    967 ** add one more for a minus sign if the type is signed.
    968 */
    969 #define INT_STRLEN_MAXIMUM(type) \
    970 	((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
    971 	1 + TYPE_SIGNED(type))
    972 
    973 /*
    974 ** INITIALIZE(x)
    975 */
    976 
    977 #if defined(__GNUC__) || defined(__lint__)
    978 # define INITIALIZE(x)	((x) = 0)
    979 #else
    980 # define INITIALIZE(x)
    981 #endif
    982 
    983 /* Whether memory access must strictly follow the C standard.
    984    If 0, it's OK to read uninitialized storage so long as the value is
    985    not relied upon.  Defining it to 0 lets mktime access parts of
    986    struct tm that might be uninitialized, as a heuristic when the
    987    standard doesn't say what to return and when tm_gmtoff can help
    988    mktime likely infer a better value.  */
    989 #ifndef UNINIT_TRAP
    990 # define UNINIT_TRAP 0
    991 #endif
    992 
    993 /* strftime.c sometimes needs access to timeoff if it is not already public.
    994    tz_private_timeoff should be used only by localtime.c and strftime.c.  */
    995 #if (!defined EXTERN_TIMEOFF \
    996      && defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP))
    997 # ifndef timeoff
    998 #  define timeoff tz_private_timeoff
    999 # endif
   1000 # define EXTERN_TIMEOFF
   1001 #endif
   1002 #ifdef EXTERN_TIMEOFF
   1003 time_t timeoff(struct tm *, long);
   1004 #endif
   1005 
   1006 #ifdef DEBUG
   1007 # undef unreachable
   1008 # define unreachable() abort()
   1009 #elif !defined unreachable
   1010 # ifdef __has_builtin
   1011 #  if __has_builtin(__builtin_unreachable)
   1012 #   define unreachable() __builtin_unreachable()
   1013 #  endif
   1014 # elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
   1015 #  define unreachable() __builtin_unreachable()
   1016 # endif
   1017 # ifndef unreachable
   1018 #  define unreachable() ((void) 0)
   1019 # endif
   1020 #endif
   1021 
   1022 /*
   1023 ** For the benefit of GNU folk...
   1024 ** '_(MSGID)' uses the current locale's message library string for MSGID.
   1025 ** The default is to use gettext if available, and use MSGID otherwise.
   1026 */
   1027 
   1028 #if HAVE_GETTEXT
   1029 #define _(msgid) gettext(msgid)
   1030 #else /* !HAVE_GETTEXT */
   1031 #define _(msgid) msgid
   1032 #endif /* !HAVE_GETTEXT */
   1033 
   1034 #if !defined TZ_DOMAIN && defined HAVE_GETTEXT
   1035 # define TZ_DOMAIN "tz"
   1036 #endif
   1037 
   1038 #if HAVE_INCOMPATIBLE_CTIME_R
   1039 #undef asctime_r
   1040 #undef ctime_r
   1041 char *asctime_r(struct tm const *restrict, char *restrict);
   1042 char *ctime_r(time_t const *, char *);
   1043 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
   1044 
   1045 /* Handy macros that are independent of tzfile implementation.  */
   1046 
   1047 #ifndef SECSPERMIN
   1048 enum {
   1049   SECSPERMIN = 60,
   1050   MINSPERHOUR = 60,
   1051   SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
   1052   HOURSPERDAY = 24,
   1053   DAYSPERWEEK = 7,
   1054   DAYSPERNYEAR = 365,
   1055   DAYSPERLYEAR = DAYSPERNYEAR + 1,
   1056   MONSPERYEAR = 12,
   1057   YEARSPERREPEAT = 400	/* years before a Gregorian repeat */
   1058 };
   1059 #endif
   1060 
   1061 #define SECSPERDAY	((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
   1062 
   1063 #define DAYSPERREPEAT		((int_fast32_t) 400 * 365 + 100 - 4 + 1)
   1064 #define SECSPERREPEAT		((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
   1065 #define AVGSECSPERYEAR		(SECSPERREPEAT / YEARSPERREPEAT)
   1066 
   1067 /* How many years to generate (in zic.c) or search through (in localtime.c).
   1068    This is two years larger than the obvious 400, to avoid edge cases.
   1069    E.g., suppose a rule applies from 2012 on with transitions
   1070    in March and September, plus one-off transitions in November 2013,
   1071    and suppose the rule cannot be expressed as a proleptic TZ string.
   1072    If zic looked only at the last 400 years, it would set max_year=2413,
   1073    with the intent that the 400 years 2014 through 2413 will be repeated.
   1074    The last transition listed in the tzfile would be in 2413-09,
   1075    less than 400 years after the last one-off transition in 2013-11.
   1076    Two years is not overkill for localtime.c, as a one-year bump
   1077    would mishandle 2023d's America/Ciudad_Juarez for November 2422.  */
   1078 enum { years_of_observations = YEARSPERREPEAT + 2 };
   1079 
   1080 #ifndef TM_SUNDAY
   1081 enum {
   1082   TM_SUNDAY,
   1083   TM_MONDAY,
   1084   TM_TUESDAY,
   1085   TM_WEDNESDAY,
   1086   TM_THURSDAY,
   1087   TM_FRIDAY,
   1088   TM_SATURDAY
   1089 };
   1090 #endif
   1091 
   1092 #ifndef TM_JANUARY
   1093 enum {
   1094   TM_JANUARY,
   1095   TM_FEBRUARY,
   1096   TM_MARCH,
   1097   TM_APRIL,
   1098   TM_MAY,
   1099   TM_JUNE,
   1100   TM_JULY,
   1101   TM_AUGUST,
   1102   TM_SEPTEMBER,
   1103   TM_OCTOBER,
   1104   TM_NOVEMBER,
   1105   TM_DECEMBER
   1106 };
   1107 #endif
   1108 
   1109 #ifndef TM_YEAR_BASE
   1110 enum {
   1111   TM_YEAR_BASE = 1900,
   1112   TM_WDAY_BASE = TM_MONDAY,
   1113   EPOCH_YEAR = 1970,
   1114   EPOCH_WDAY = TM_THURSDAY
   1115 };
   1116 #endif
   1117 
   1118 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
   1119 
   1120 /*
   1121 ** Since everything in isleap is modulo 400 (or a factor of 400), we know that
   1122 **	isleap(y) == isleap(y % 400)
   1123 ** and so
   1124 **	isleap(a + b) == isleap((a + b) % 400)
   1125 ** or
   1126 **	isleap(a + b) == isleap(a % 400 + b % 400)
   1127 ** This is true even if % means modulo rather than Fortran remainder
   1128 ** (which is allowed by C89 but not by C99 or later).
   1129 ** We use this to avoid addition overflow problems.
   1130 */
   1131 
   1132 #define isleap_sum(a, b)	isleap((a) % 400 + (b) % 400)
   1133 
   1134 #ifdef _LIBC
   1135 #include "reentrant.h"
   1136 extern struct __state *__lclptr;
   1137 #if defined(__LIBC12_SOURCE__)
   1138 #define tzset_unlocked __tzset_unlocked
   1139 #else
   1140 #define tzset_unlocked __tzset_unlocked50
   1141 #endif
   1142 
   1143 void tzset_unlocked(void);
   1144 #ifdef _REENTRANT
   1145 extern rwlock_t __lcl_lock;
   1146 #endif
   1147 #endif
   1148 
   1149 #endif /* !defined PRIVATE_H */
   1150