diff options
Diffstat (limited to 'timezone/private.h')
-rw-r--r-- | timezone/private.h | 114 |
1 files changed, 69 insertions, 45 deletions
diff --git a/timezone/private.h b/timezone/private.h index 0dac6af4e3..c33041049f 100644 --- a/timezone/private.h +++ b/timezone/private.h @@ -19,19 +19,22 @@ /* PORT_TO_C89 means the code should work even if the underlying compiler and library support only C89 plus C99's 'long long' - and perhaps a few other extensions to C89. SUPPORT_C89 means the - tzcode library should support C89 callers in addition to the usual - support for C99-and-later callers; however, C89 support can trigger - latent bugs in C99-and-later callers. These macros are obsolescent, - and the plan is to remove them along with any code needed only when - they are nonzero. A good time to do that might be in the year 2029 + and perhaps a few other extensions to C89. + + This macro is obsolescent, and the plan is to remove it along with + associated code. A good time to do that might be in the year 2029 because RHEL 7 (whose GCC defaults to C89) extended life cycle support (ELS) is scheduled to end on 2028-06-30. */ #ifndef PORT_TO_C89 # define PORT_TO_C89 0 #endif + +/* SUPPORT_C89 means the tzcode library should support C89 callers + in addition to the usual support for C99-and-later callers. + This defaults to 1 as POSIX requires, even though that can trigger + latent bugs in callers. */ #ifndef SUPPORT_C89 -# define SUPPORT_C89 0 +# define SUPPORT_C89 1 #endif #ifndef __STDC_VERSION__ @@ -69,10 +72,6 @@ ** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'. */ -#ifndef HAVE_DECL_ASCTIME_R -# define HAVE_DECL_ASCTIME_R 1 -#endif - #if !defined HAVE__GENERIC && defined __has_extension # if !__has_extension(c_generic_selections) # define HAVE__GENERIC 0 @@ -236,6 +235,31 @@ # include <unistd.h> /* for R_OK, and other POSIX goodness */ #endif /* HAVE_UNISTD_H */ +/* SUPPORT_POSIX2008 means the tzcode library should support + POSIX.1-2017-and-earlier callers in addition to the usual support for + POSIX.1-2024-and-later callers; however, this can be + incompatible with POSIX.1-2024-and-later callers. + This macro is obsolescent, and the plan is to remove it + along with any code needed only when it is nonzero. + A good time to do that might be in the year 2034. + This macro's name is SUPPORT_POSIX2008 because _POSIX_VERSION == 200809 + in POSIX.1-2017, a minor revision of POSIX.1-2008. */ +#ifndef SUPPORT_POSIX2008 +# if defined _POSIX_VERSION && _POSIX_VERSION <= 200809 +# define SUPPORT_POSIX2008 1 +# else +# define SUPPORT_POSIX2008 0 +# endif +#endif + +#ifndef HAVE_DECL_ASCTIME_R +# if SUPPORT_POSIX2008 +# define HAVE_DECL_ASCTIME_R 1 +# else +# define HAVE_DECL_ASCTIME_R 0 +# endif +#endif + #ifndef HAVE_STRFTIME_L # if _POSIX_VERSION < 200809 # define HAVE_STRFTIME_L 0 @@ -460,14 +484,6 @@ typedef unsigned long uintmax_t; # define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r) #endif -#if 3 <= __GNUC__ -# define ATTRIBUTE_MALLOC __attribute__((malloc)) -# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec)) -#else -# define ATTRIBUTE_MALLOC /* empty */ -# define ATTRIBUTE_FORMAT(spec) /* empty */ -#endif - #if (defined __has_c_attribute \ && (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__)) # define HAVE___HAS_C_ATTRIBUTE true @@ -535,24 +551,27 @@ typedef unsigned long uintmax_t; # endif #endif #ifndef ATTRIBUTE_REPRODUCIBLE -# if 3 <= __GNUC__ -# define ATTRIBUTE_REPRODUCIBLE __attribute__((pure)) -# else -# define ATTRIBUTE_REPRODUCIBLE /* empty */ -# endif +# define ATTRIBUTE_REPRODUCIBLE /* empty */ #endif -#if HAVE___HAS_C_ATTRIBUTE -# if __has_c_attribute(unsequenced) -# define ATTRIBUTE_UNSEQUENCED [[unsequenced]] -# endif +/* GCC attributes that are useful in tzcode. + __attribute__((pure)) is stricter than [[reproducible]], + so the latter is an adequate substitute in non-GCC C23 platforms. */ +#if __GNUC__ < 3 +# define ATTRIBUTE_FORMAT(spec) /* empty */ +# define ATTRIBUTE_PURE ATTRIBUTE_REPRODUCIBLE +#else +# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec)) +# define ATTRIBUTE_PURE __attribute__((pure)) #endif -#ifndef ATTRIBUTE_UNSEQUENCED -# if 3 <= __GNUC__ -# define ATTRIBUTE_UNSEQUENCED __attribute__((const)) -# else -# define ATTRIBUTE_UNSEQUENCED /* empty */ -# endif + +/* Avoid GCC bug 114833 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114833>. + Remove this macro and its uses when the bug is fixed in a GCC release, + because only the latest GCC matters for $(GCC_DEBUG_FLAGS). */ +#ifdef GCC_LINT +# define ATTRIBUTE_PURE_114833 ATTRIBUTE_PURE +#else +# define ATTRIBUTE_PURE_114833 /* empty */ #endif #if (__STDC_VERSION__ < 199901 && !defined restrict \ @@ -604,12 +623,8 @@ typedef time_tz tz_time_t; # undef asctime # define asctime tz_asctime -# undef asctime_r -# define asctime_r tz_asctime_r # undef ctime # define ctime tz_ctime -# undef ctime_r -# define ctime_r tz_ctime_r # undef difftime # define difftime tz_difftime # undef gmtime @@ -654,6 +669,12 @@ typedef time_tz tz_time_t; # define tzfree tz_tzfree # undef tzset # define tzset tz_tzset +# if SUPPORT_POSIX2008 +# undef asctime_r +# define asctime_r tz_asctime_r +# undef ctime_r +# define ctime_r tz_ctime_r +# endif # if HAVE_STRFTIME_L # undef strftime_l # define strftime_l tz_strftime_l @@ -679,10 +700,12 @@ typedef time_tz tz_time_t; # define DEPRECATED_IN_C23 ATTRIBUTE_DEPRECATED # endif DEPRECATED_IN_C23 char *asctime(struct tm const *); -char *asctime_r(struct tm const *restrict, char *restrict); DEPRECATED_IN_C23 char *ctime(time_t const *); +#if SUPPORT_POSIX2008 +char *asctime_r(struct tm const *restrict, char *restrict); char *ctime_r(time_t const *, char *); -ATTRIBUTE_UNSEQUENCED double difftime(time_t, time_t); +#endif +double difftime(time_t, time_t); size_t strftime(char *restrict, size_t, char const *restrict, struct tm const *restrict); # if HAVE_STRFTIME_L @@ -713,7 +736,7 @@ void tzset(void); time_t timegm(struct tm *); #endif -#if !HAVE_DECL_ASCTIME_R && !defined asctime_r +#if !HAVE_DECL_ASCTIME_R && !defined asctime_r && SUPPORT_POSIX2008 extern char *asctime_r(struct tm const *restrict, char *restrict); #endif @@ -798,10 +821,10 @@ timezone_t tzalloc(char const *); void tzfree(timezone_t); # if STD_INSPIRED # if TZ_TIME_T || !defined posix2time_z -ATTRIBUTE_REPRODUCIBLE time_t posix2time_z(timezone_t, time_t); +ATTRIBUTE_PURE time_t posix2time_z(timezone_t, time_t); # endif # if TZ_TIME_T || !defined time2posix_z -ATTRIBUTE_REPRODUCIBLE time_t time2posix_z(timezone_t, time_t); +ATTRIBUTE_PURE time_t time2posix_z(timezone_t, time_t); # endif # endif #endif @@ -973,8 +996,9 @@ enum { /* How many years to generate (in zic.c) or search through (in localtime.c). This is two years larger than the obvious 400, to avoid edge cases. - E.g., suppose a non-POSIX.1-2017 rule applies from 2012 on with transitions - in March and September, plus one-off transitions in November 2013. + E.g., suppose a rule applies from 2012 on with transitions + in March and September, plus one-off transitions in November 2013, + and suppose the rule cannot be expressed as a proleptic TZ string. If zic looked only at the last 400 years, it would set max_year=2413, with the intent that the 400 years 2014 through 2413 will be repeated. The last transition listed in the tzfile would be in 2413-09, |