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