about summary refs log tree commit diff
path: root/timezone/private.h
diff options
context:
space:
mode:
Diffstat (limited to 'timezone/private.h')
-rw-r--r--timezone/private.h236
1 files changed, 173 insertions, 63 deletions
diff --git a/timezone/private.h b/timezone/private.h
index e2f23f5f40..1ead14793b 100644
--- a/timezone/private.h
+++ b/timezone/private.h
@@ -1,3 +1,5 @@
+/* Private header for tzdb code.  */
+
 #ifndef PRIVATE_H
 
 #define PRIVATE_H
@@ -15,6 +17,16 @@
 ** Thank you!
 */
 
+/*
+** zdump has been made independent of the rest of the time
+** conversion package to increase confidence in the verification it provides.
+** You can use zdump to help in verifying other implementations.
+** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
+*/
+#ifndef USE_LTZ
+# define USE_LTZ 1
+#endif
+
 /* This string was in the Factory zone through version 2016f.  */
 #define GRANDPARENTED	"Local time zone must be set--see zic manual page"
 
@@ -27,13 +39,28 @@
 #define HAVE_DECL_ASCTIME_R 1
 #endif
 
+#if !defined HAVE_GENERIC && defined __has_extension
+# if __has_extension(c_generic_selections)
+#  define HAVE_GENERIC 1
+# else
+#  define HAVE_GENERIC 0
+# endif
+#endif
+/* _Generic is buggy in pre-4.9 GCC.  */
+#if !defined HAVE_GENERIC && defined __GNUC__
+# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
+#endif
+#ifndef HAVE_GENERIC
+# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
+#endif
+
 #ifndef HAVE_GETTEXT
 #define HAVE_GETTEXT		0
 #endif /* !defined HAVE_GETTEXT */
 
 #ifndef HAVE_INCOMPATIBLE_CTIME_R
 #define HAVE_INCOMPATIBLE_CTIME_R	0
-#endif /* !defined INCOMPATIBLE_CTIME_R */
+#endif
 
 #ifndef HAVE_LINK
 #define HAVE_LINK		1
@@ -43,10 +70,18 @@
 #define HAVE_POSIX_DECLS 1
 #endif
 
+#ifndef HAVE_STDBOOL_H
+#define HAVE_STDBOOL_H (199901 <= __STDC_VERSION__)
+#endif
+
 #ifndef HAVE_STRDUP
 #define HAVE_STRDUP 1
 #endif
 
+#ifndef HAVE_STRTOLL
+#define HAVE_STRTOLL 1
+#endif
+
 #ifndef HAVE_SYMLINK
 #define HAVE_SYMLINK		1
 #endif /* !defined HAVE_SYMLINK */
@@ -76,13 +111,23 @@
 #define ctime_r _incompatible_ctime_r
 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
 
-/* Enable tm_gmtoff and tm_zone on GNUish systems.  */
+/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems.  */
 #define _GNU_SOURCE 1
 /* Fix asctime_r on Solaris 11.  */
 #define _POSIX_PTHREAD_SEMANTICS 1
 /* Enable strtoimax on pre-C99 Solaris 11.  */
 #define __EXTENSIONS__ 1
 
+/* To avoid having 'stat' fail unnecessarily with errno == EOVERFLOW,
+   enable large files on GNUish systems ...  */
+#ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+#endif
+/* ... and on AIX ...  */
+#define _LARGE_FILES 1
+/* ... and enable large inode numbers on Mac OS X 10.5 and later.  */
+#define _DARWIN_USE_64_BIT_INODE 1
+
 /*
 ** Nested includes
 */
@@ -105,7 +150,6 @@
 #undef tzfree
 
 #include <sys/types.h>	/* for time_t */
-#include <stdio.h>
 #include <string.h>
 #include <limits.h>	/* for CHAR_BIT et al. */
 #include <stdlib.h>
@@ -126,19 +170,8 @@
 #include <libintl.h>
 #endif /* HAVE_GETTEXT */
 
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h>	/* for WIFEXITED and WEXITSTATUS */
-#endif /* HAVE_SYS_WAIT_H */
-
-#ifndef WIFEXITED
-#define WIFEXITED(status)	(((status) & 0xff) == 0)
-#endif /* !defined WIFEXITED */
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(status)	(((status) >> 8) & 0xff)
-#endif /* !defined WEXITSTATUS */
-
 #if HAVE_UNISTD_H
-#include <unistd.h>	/* for F_OK, R_OK, and other POSIX goodness */
+#include <unistd.h>	/* for R_OK, and other POSIX goodness */
 #endif /* HAVE_UNISTD_H */
 
 #ifndef HAVE_STRFTIME_L
@@ -149,9 +182,22 @@
 # endif
 #endif
 
-#ifndef F_OK
-#define F_OK	0
-#endif /* !defined F_OK */
+#ifndef USG_COMPAT
+# ifndef _XOPEN_VERSION
+#  define USG_COMPAT 0
+# else
+#  define USG_COMPAT 1
+# endif
+#endif
+
+#ifndef HAVE_TZNAME
+# if _POSIX_VERSION < 198808 && !USG_COMPAT
+#  define HAVE_TZNAME 0
+# else
+#  define HAVE_TZNAME 1
+# endif
+#endif
+
 #ifndef R_OK
 #define R_OK	4
 #endif /* !defined R_OK */
@@ -236,15 +282,19 @@ typedef int int_fast32_t;
 #ifndef INTMAX_MAX
 # ifdef LLONG_MAX
 typedef long long intmax_t;
-#  define strtoimax strtoll
+#  if HAVE_STRTOLL
+#   define strtoimax strtoll
+#  endif
 #  define INTMAX_MAX LLONG_MAX
 #  define INTMAX_MIN LLONG_MIN
 # else
 typedef long intmax_t;
-#  define strtoimax strtol
 #  define INTMAX_MAX LONG_MAX
 #  define INTMAX_MIN LONG_MIN
 # endif
+# ifndef strtoimax
+#  define strtoimax strtol
+# endif
 #endif
 
 #ifndef PRIdMAX
@@ -294,12 +344,14 @@ typedef unsigned long uintmax_t;
 #define SIZE_MAX ((size_t) -1)
 #endif
 
-#if 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+#if 3 <= __GNUC__
 # define ATTRIBUTE_CONST __attribute__ ((const))
+# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
 # define ATTRIBUTE_PURE __attribute__ ((__pure__))
 # define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
 #else
 # define ATTRIBUTE_CONST /* empty */
+# define ATTRIBUTE_MALLOC /* empty */
 # define ATTRIBUTE_PURE /* empty */
 # define ATTRIBUTE_FORMAT(spec) /* empty */
 #endif
@@ -326,6 +378,16 @@ typedef unsigned long uintmax_t;
 #ifndef EPOCH_OFFSET
 # define EPOCH_OFFSET 0
 #endif
+#ifndef RESERVE_STD_EXT_IDS
+# define RESERVE_STD_EXT_IDS 0
+#endif
+
+/* If standard C identifiers with external linkage (e.g., localtime)
+   are reserved and are not already being renamed anyway, rename them
+   as if compiling with '-Dtime_tz=time_t'.  */
+#if !defined time_tz && RESERVE_STD_EXT_IDS && USE_LTZ
+# define time_tz time_t
+#endif
 
 /*
 ** Compile with -Dtime_tz=T to build the tz package with a private
@@ -335,6 +397,12 @@ typedef unsigned long uintmax_t;
 ** typical platforms.
 */
 #if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
+# define TZ_TIME_T 1
+#else
+# define TZ_TIME_T 0
+#endif
+
+#if TZ_TIME_T
 # ifdef LOCALTIME_IMPLEMENTATION
 static time_t sys_time(time_t *x) { return time(x); }
 # endif
@@ -367,6 +435,8 @@ typedef time_tz tz_time_t;
 # define posix2time tz_posix2time
 # undef  posix2time_z
 # define posix2time_z tz_posix2time_z
+# undef  strftime
+# define strftime tz_strftime
 # undef  time
 # define time tz_time
 # undef  time2posix
@@ -389,10 +459,34 @@ typedef time_tz tz_time_t;
 # define tzset tz_tzset
 # undef  tzsetwall
 # define tzsetwall tz_tzsetwall
+# if HAVE_STRFTIME_L
+#  undef  strftime_l
+#  define strftime_l tz_strftime_l
+# endif
+# if HAVE_TZNAME
+#  undef  tzname
+#  define tzname tz_tzname
+# endif
+# if USG_COMPAT
+#  undef  daylight
+#  define daylight tz_daylight
+#  undef  timezone
+#  define timezone tz_timezone
+# endif
+# ifdef ALTZONE
+#  undef  altzone
+#  define altzone tz_altzone
+# endif
 
 char *ctime(time_t const *);
 char *ctime_r(time_t const *, char *);
-double difftime(time_t, time_t);
+double difftime(time_t, time_t) ATTRIBUTE_CONST;
+size_t strftime(char *restrict, size_t, char const *restrict,
+		struct tm const *restrict);
+# if HAVE_STRFTIME_L
+size_t strftime_l(char *restrict, size_t, char const *restrict,
+		  struct tm const *restrict, locale_t);
+# endif
 struct tm *gmtime(time_t const *);
 struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
 struct tm *localtime(time_t const *);
@@ -406,18 +500,29 @@ void tzset(void);
 extern char *asctime_r(struct tm const *restrict, char *restrict);
 #endif
 
-#if !HAVE_POSIX_DECLS
-# ifdef USG_COMPAT
-#  ifndef timezone
+#ifndef HAVE_DECL_ENVIRON
+# if defined environ || defined __USE_GNU
+#  define HAVE_DECL_ENVIRON 1
+# else
+#  define HAVE_DECL_ENVIRON 0
+# endif
+#endif
+
+#if !HAVE_DECL_ENVIRON
+extern char **environ;
+#endif
+
+#if TZ_TIME_T || !HAVE_POSIX_DECLS
+# if HAVE_TZNAME
+extern char *tzname[];
+# endif
+# if USG_COMPAT
 extern long timezone;
-#  endif
-#  ifndef daylight
 extern int daylight;
-#  endif
 # endif
 #endif
 
-#if defined ALTZONE && !defined altzone
+#ifdef ALTZONE
 extern long altzone;
 #endif
 
@@ -427,25 +532,25 @@ extern long altzone;
 */
 
 #ifdef STD_INSPIRED
-# if !defined tzsetwall || defined time_tz
+# if TZ_TIME_T || !defined tzsetwall
 void tzsetwall(void);
 # endif
-# if !defined offtime || defined time_tz
+# if TZ_TIME_T || !defined offtime
 struct tm *offtime(time_t const *, long);
 # endif
-# if !defined timegm || defined time_tz
+# if TZ_TIME_T || !defined timegm
 time_t timegm(struct tm *);
 # endif
-# if !defined timelocal || defined time_tz
+# if TZ_TIME_T || !defined timelocal
 time_t timelocal(struct tm *);
 # endif
-# if !defined timeoff || defined time_tz
+# if TZ_TIME_T || !defined timeoff
 time_t timeoff(struct tm *, long);
 # endif
-# if !defined time2posix || defined time_tz
+# if TZ_TIME_T || !defined time2posix
 time_t time2posix(time_t);
 # endif
-# if !defined posix2time || defined time_tz
+# if TZ_TIME_T || !defined posix2time
 time_t posix2time(time_t);
 # endif
 #endif
@@ -479,10 +584,10 @@ time_t mktime_z(timezone_t restrict, struct tm *restrict);
 timezone_t tzalloc(char const *);
 void tzfree(timezone_t);
 # ifdef STD_INSPIRED
-#  if !defined posix2time_z || defined time_tz
+#  if TZ_TIME_T || !defined posix2time_z
 time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_PURE;
 #  endif
-#  if !defined time2posix_z || defined time_tz
+#  if TZ_TIME_T || !defined time2posix_z
 time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
 #  endif
 # endif
@@ -492,12 +597,12 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
 ** Finally, some convenience items.
 */
 
-#if __STDC_VERSION__ < 199901
+#if HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
 # define true 1
 # define false 0
 # define bool int
-#else
-# include <stdbool.h>
 #endif
 
 #define TYPE_BIT(type)	(sizeof (type) * CHAR_BIT)
@@ -513,27 +618,32 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
 #define MINVAL(t, b)						\
   ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
 
-/* The minimum and maximum finite time values.  This implementation
-   assumes no padding if time_t is signed and either the compiler is
-   pre-C11 or time_t is not one of the standard signed integer types.  */
-#if 201112 <= __STDC_VERSION__
-static time_t const time_t_min
-  = (TYPE_SIGNED(time_t)
-     ? _Generic((time_t) 0,
-		signed char: SCHAR_MIN, short: SHRT_MIN,
-		int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN,
-		default: MINVAL(time_t, TYPE_BIT(time_t)))
-     : 0);
-static time_t const time_t_max
-  = (TYPE_SIGNED(time_t)
-     ? _Generic((time_t) 0,
-		signed char: SCHAR_MAX, short: SHRT_MAX,
-		int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX,
-		default: MAXVAL(time_t, TYPE_BIT(time_t)))
-     : -1);
+/* The extreme time values, assuming no padding.  */
+#define TIME_T_MIN_NO_PADDING MINVAL(time_t, TYPE_BIT(time_t))
+#define TIME_T_MAX_NO_PADDING MAXVAL(time_t, TYPE_BIT(time_t))
+
+/* The extreme time values.  These are macros, not constants, so that
+   any portability problem occur only when compiling .c files that use
+   the macros, which is safer for applications that need only zdump and zic.
+   This implementation assumes no padding if time_t is signed and
+   either the compiler lacks support for _Generic or time_t is not one
+   of the standard signed integer types.  */
+#if HAVE_GENERIC
+# define TIME_T_MIN \
+    _Generic((time_t) 0, \
+	     signed char: SCHAR_MIN, short: SHRT_MIN, \
+	     int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \
+	     default: TIME_T_MIN_NO_PADDING)
+# define TIME_T_MAX \
+    (TYPE_SIGNED(time_t) \
+     ? _Generic((time_t) 0, \
+		signed char: SCHAR_MAX, short: SHRT_MAX, \
+		int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
+		default: TIME_T_MAX_NO_PADDING)			    \
+     : (time_t) -1)
 #else
-static time_t const time_t_min = MINVAL(time_t, TYPE_BIT(time_t));
-static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
+# define TIME_T_MIN TIME_T_MIN_NO_PADDING
+# define TIME_T_MAX TIME_T_MAX_NO_PADDING
 #endif
 
 /*
@@ -550,7 +660,7 @@ static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
 ** INITIALIZE(x)
 */
 
-#ifdef lint
+#ifdef GCC_LINT
 # define INITIALIZE(x)	((x) = 0)
 #else
 # define INITIALIZE(x)
@@ -633,7 +743,7 @@ char *ctime_r(time_t const *, char *);
 ** or
 **	isleap(a + b) == isleap(a % 400 + b % 400)
 ** This is true even if % means modulo rather than Fortran remainder
-** (which is allowed by C89 but not C99).
+** (which is allowed by C89 but not by C99 or later).
 ** We use this to avoid addition overflow problems.
 */