xref: /freebsd/contrib/tzcode/private.h (revision 8a271827e7b5d5310e06df1f9f49ba0ef9efd263)
1 /* Private header for tzdb code.  */
2 
3 #ifndef PRIVATE_H
4 
5 #define PRIVATE_H
6 
7 /*
8 ** This file is in the public domain, so clarified as of
9 ** 1996-06-05 by Arthur David Olson.
10 */
11 
12 /*
13 ** This header is for use ONLY with the time conversion code.
14 ** There is no guarantee that it will remain unchanged,
15 ** or that it will remain at all.
16 ** Do NOT copy it to any system include directory.
17 ** Thank you!
18 */
19 
20 #ifndef __STDC_VERSION__
21 # define __STDC_VERSION__ 0
22 #endif
23 
24 /* Define true, false and bool if they don't work out of the box.  */
25 #if __STDC_VERSION__ < 199901
26 # define true 1
27 # define false 0
28 # define bool int
29 #elif __STDC_VERSION__ < 202311
30 # include <stdbool.h>
31 #endif
32 
33 /*
34 ** zdump has been made independent of the rest of the time
35 ** conversion package to increase confidence in the verification it provides.
36 ** You can use zdump to help in verifying other implementations.
37 ** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
38 */
39 #ifndef USE_LTZ
40 # define USE_LTZ 1
41 #endif
42 
43 /* This string was in the Factory zone through version 2016f.  */
44 #define GRANDPARENTED	"Local time zone must be set--use tzsetup"
45 
46 /*
47 ** Defaults for preprocessor symbols.
48 ** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
49 */
50 
51 #ifndef HAVE_DECL_ASCTIME_R
52 # define HAVE_DECL_ASCTIME_R 1
53 #endif
54 
55 #if !defined HAVE_GENERIC && defined __has_extension
56 # if __has_extension(c_generic_selections)
57 #  define HAVE_GENERIC 1
58 # else
59 #  define HAVE_GENERIC 0
60 # endif
61 #endif
62 /* _Generic is buggy in pre-4.9 GCC.  */
63 #if !defined HAVE_GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
64 # define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
65 #endif
66 #ifndef HAVE_GENERIC
67 # define HAVE_GENERIC (201112 <= __STDC_VERSION__)
68 #endif
69 
70 #if !defined HAVE_GETTEXT && defined __has_include
71 # if __has_include(<libintl.h>)
72 #  define HAVE_GETTEXT true
73 # endif
74 #endif
75 #ifndef HAVE_GETTEXT
76 # define HAVE_GETTEXT false
77 #endif
78 
79 #ifndef HAVE_INCOMPATIBLE_CTIME_R
80 # define HAVE_INCOMPATIBLE_CTIME_R 0
81 #endif
82 
83 #ifndef HAVE_LINK
84 # define HAVE_LINK 1
85 #endif /* !defined HAVE_LINK */
86 
87 #ifndef HAVE_MALLOC_ERRNO
88 # define HAVE_MALLOC_ERRNO 1
89 #endif
90 
91 #ifndef HAVE_POSIX_DECLS
92 # define HAVE_POSIX_DECLS 1
93 #endif
94 
95 #ifndef HAVE_SETENV
96 # define HAVE_SETENV 1
97 #endif
98 
99 #ifndef HAVE_STRDUP
100 # define HAVE_STRDUP 1
101 #endif
102 
103 #ifndef HAVE_STRTOLL
104 # define HAVE_STRTOLL 1
105 #endif
106 
107 #ifndef HAVE_SYMLINK
108 # define HAVE_SYMLINK 1
109 #endif /* !defined HAVE_SYMLINK */
110 
111 #if !defined HAVE_SYS_STAT_H && defined __has_include
112 # if !__has_include(<sys/stat.h>)
113 #  define HAVE_SYS_STAT_H false
114 # endif
115 #endif
116 #ifndef HAVE_SYS_STAT_H
117 # define HAVE_SYS_STAT_H true
118 #endif
119 
120 #if !defined HAVE_UNISTD_H && defined __has_include
121 # if !__has_include(<unistd.h>)
122 #  define HAVE_UNISTD_H false
123 # endif
124 #endif
125 #ifndef HAVE_UNISTD_H
126 # define HAVE_UNISTD_H true
127 #endif
128 
129 #ifndef NETBSD_INSPIRED
130 # define NETBSD_INSPIRED 1
131 #endif
132 
133 #if HAVE_INCOMPATIBLE_CTIME_R
134 # define asctime_r _incompatible_asctime_r
135 # define ctime_r _incompatible_ctime_r
136 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
137 
138 /* Enable tm_gmtoff, tm_zone, and environ on GNUish systems.  */
139 #define _GNU_SOURCE 1
140 /* Fix asctime_r on Solaris 11.  */
141 #define _POSIX_PTHREAD_SEMANTICS 1
142 /* Enable strtoimax on pre-C99 Solaris 11.  */
143 #define __EXTENSIONS__ 1
144 
145 /* On GNUish systems where time_t might be 32 or 64 bits, use 64.
146    On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
147    setting _TIME_BITS to 64 does not work.  The code does not
148    otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
149    use off_t or functions like 'stat' that depend on off_t.  */
150 #ifndef _FILE_OFFSET_BITS
151 # define _FILE_OFFSET_BITS 64
152 #endif
153 #if !defined _TIME_BITS && _FILE_OFFSET_BITS == 64
154 # define _TIME_BITS 64
155 #endif
156 
157 /*
158 ** Nested includes
159 */
160 
161 /* Avoid clashes with NetBSD by renaming NetBSD's declarations.
162    If defining the 'timezone' variable, avoid a clash with FreeBSD's
163    'timezone' function by renaming its declaration.  */
164 #define localtime_rz sys_localtime_rz
165 #define mktime_z sys_mktime_z
166 #define posix2time_z sys_posix2time_z
167 #define time2posix_z sys_time2posix_z
168 #if defined USG_COMPAT && USG_COMPAT == 2
169 # define timezone sys_timezone
170 #endif
171 #define timezone_t sys_timezone_t
172 #define tzalloc sys_tzalloc
173 #define tzfree sys_tzfree
174 #include <time.h>
175 #undef localtime_rz
176 #undef mktime_z
177 #undef posix2time_z
178 #undef time2posix_z
179 #if defined USG_COMPAT && USG_COMPAT == 2
180 # undef timezone
181 #endif
182 #undef timezone_t
183 #undef tzalloc
184 #undef tzfree
185 
186 #include <stddef.h>
187 #include <string.h>
188 #include <limits.h>	/* for CHAR_BIT et al. */
189 #include <stdlib.h>
190 
191 #include <errno.h>
192 
193 #ifndef EINVAL
194 # define EINVAL ERANGE
195 #endif
196 
197 #ifndef ELOOP
198 # define ELOOP EINVAL
199 #endif
200 #ifndef ENAMETOOLONG
201 # define ENAMETOOLONG EINVAL
202 #endif
203 #ifndef ENOMEM
204 # define ENOMEM EINVAL
205 #endif
206 #ifndef ENOTSUP
207 # define ENOTSUP EINVAL
208 #endif
209 #ifndef EOVERFLOW
210 # define EOVERFLOW EINVAL
211 #endif
212 
213 #if HAVE_GETTEXT
214 # include <libintl.h>
215 #endif /* HAVE_GETTEXT */
216 
217 #if HAVE_UNISTD_H
218 # include <unistd.h> /* for R_OK, and other POSIX goodness */
219 #endif /* HAVE_UNISTD_H */
220 
221 #ifndef HAVE_STRFTIME_L
222 # if _POSIX_VERSION < 200809
223 #  define HAVE_STRFTIME_L 0
224 # else
225 #  define HAVE_STRFTIME_L 1
226 # endif
227 #endif
228 
229 #ifndef USG_COMPAT
230 # ifndef _XOPEN_VERSION
231 #  define USG_COMPAT 0
232 # else
233 #  define USG_COMPAT 1
234 # endif
235 #endif
236 
237 #ifndef HAVE_TZNAME
238 # if _POSIX_VERSION < 198808 && !USG_COMPAT
239 #  define HAVE_TZNAME 0
240 # else
241 #  define HAVE_TZNAME 1
242 # endif
243 #endif
244 
245 #ifndef ALTZONE
246 # if defined __sun || defined _M_XENIX
247 #  define ALTZONE 1
248 # else
249 #  define ALTZONE 0
250 # endif
251 #endif
252 
253 #ifndef R_OK
254 # define R_OK 4
255 #endif /* !defined R_OK */
256 
257 /*
258 ** Define HAVE_STDINT_H's default value here, rather than at the
259 ** start, since __GLIBC__ and INTMAX_MAX's values depend on
260 ** previously-included files.  glibc 2.1 and Solaris 10 and later have
261 ** stdint.h, even with pre-C99 compilers.
262 */
263 #if !defined HAVE_STDINT_H && defined __has_include
264 # define HAVE_STDINT_H true /* C23 __has_include implies C99 stdint.h.  */
265 #endif
266 #ifndef HAVE_STDINT_H
267 # define HAVE_STDINT_H \
268    (199901 <= __STDC_VERSION__ \
269     || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
270     || __CYGWIN__ || INTMAX_MAX)
271 #endif /* !defined HAVE_STDINT_H */
272 
273 #if HAVE_STDINT_H
274 # include <stdint.h>
275 #endif /* !HAVE_STDINT_H */
276 
277 #ifndef HAVE_INTTYPES_H
278 # define HAVE_INTTYPES_H HAVE_STDINT_H
279 #endif
280 #if HAVE_INTTYPES_H
281 # include <inttypes.h>
282 #endif
283 
284 /* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX.  */
285 #if defined __LONG_LONG_MAX__ && !defined __STRICT_ANSI__
286 # ifndef LLONG_MAX
287 #  define LLONG_MAX __LONG_LONG_MAX__
288 # endif
289 # ifndef LLONG_MIN
290 #  define LLONG_MIN (-1 - LLONG_MAX)
291 # endif
292 # ifndef ULLONG_MAX
293 #  define ULLONG_MAX (LLONG_MAX * 2ull + 1)
294 # endif
295 #endif
296 
297 #ifndef INT_FAST64_MAX
298 # if 1 <= LONG_MAX >> 31 >> 31
299 typedef long int_fast64_t;
300 #  define INT_FAST64_MIN LONG_MIN
301 #  define INT_FAST64_MAX LONG_MAX
302 # else
303 /* If this fails, compile with -DHAVE_STDINT_H or with a better compiler.  */
304 typedef long long int_fast64_t;
305 #  define INT_FAST64_MIN LLONG_MIN
306 #  define INT_FAST64_MAX LLONG_MAX
307 # endif
308 #endif
309 
310 #ifndef PRIdFAST64
311 # if INT_FAST64_MAX == LONG_MAX
312 #  define PRIdFAST64 "ld"
313 # else
314 #  define PRIdFAST64 "lld"
315 # endif
316 #endif
317 
318 #ifndef SCNdFAST64
319 # define SCNdFAST64 PRIdFAST64
320 #endif
321 
322 #ifndef INT_FAST32_MAX
323 # if INT_MAX >> 31 == 0
324 typedef long int_fast32_t;
325 #  define INT_FAST32_MAX LONG_MAX
326 #  define INT_FAST32_MIN LONG_MIN
327 # else
328 typedef int int_fast32_t;
329 #  define INT_FAST32_MAX INT_MAX
330 #  define INT_FAST32_MIN INT_MIN
331 # endif
332 #endif
333 
334 #ifndef INTMAX_MAX
335 # ifdef LLONG_MAX
336 typedef long long intmax_t;
337 #  if HAVE_STRTOLL
338 #   define strtoimax strtoll
339 #  endif
340 #  define INTMAX_MAX LLONG_MAX
341 #  define INTMAX_MIN LLONG_MIN
342 # else
343 typedef long intmax_t;
344 #  define INTMAX_MAX LONG_MAX
345 #  define INTMAX_MIN LONG_MIN
346 # endif
347 # ifndef strtoimax
348 #  define strtoimax strtol
349 # endif
350 #endif
351 
352 #ifndef PRIdMAX
353 # if INTMAX_MAX == LLONG_MAX
354 #  define PRIdMAX "lld"
355 # else
356 #  define PRIdMAX "ld"
357 # endif
358 #endif
359 
360 #ifndef PTRDIFF_MAX
361 # define PTRDIFF_MAX MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
362 #endif
363 
364 #ifndef UINT_FAST32_MAX
365 typedef unsigned long uint_fast32_t;
366 #endif
367 
368 #ifndef UINT_FAST64_MAX
369 # if 3 <= ULONG_MAX >> 31 >> 31
370 typedef unsigned long uint_fast64_t;
371 #  define UINT_FAST64_MAX ULONG_MAX
372 # else
373 /* If this fails, compile with -DHAVE_STDINT_H or with a better compiler.  */
374 typedef unsigned long long uint_fast64_t;
375 #  define UINT_FAST64_MAX ULLONG_MAX
376 # endif
377 #endif
378 
379 #ifndef UINTMAX_MAX
380 # ifdef ULLONG_MAX
381 typedef unsigned long long uintmax_t;
382 # else
383 typedef unsigned long uintmax_t;
384 # endif
385 #endif
386 
387 #ifndef PRIuMAX
388 # ifdef ULLONG_MAX
389 #  define PRIuMAX "llu"
390 # else
391 #  define PRIuMAX "lu"
392 # endif
393 #endif
394 
395 #ifndef SIZE_MAX
396 # define SIZE_MAX ((size_t) -1)
397 #endif
398 
399 /* Support ckd_add, ckd_sub, ckd_mul on C23 or recent-enough GCC-like
400    hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG.  */
401 #if !defined HAVE_STDCKDINT_H && defined __has_include
402 # if __has_include(<stdckdint.h>)
403 #  define HAVE_STDCKDINT_H true
404 # endif
405 #endif
406 #ifdef HAVE_STDCKDINT_H
407 # if HAVE_STDCKDINT_H
408 #  include <stdckdint.h>
409 # endif
410 #elif defined __EDG__
411 /* Do nothing, to work around EDG bug <https://bugs.gnu.org/53256>.  */
412 #elif defined __has_builtin
413 # if __has_builtin(__builtin_add_overflow)
414 #  define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
415 # endif
416 # if __has_builtin(__builtin_sub_overflow)
417 #  define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
418 # endif
419 # if __has_builtin(__builtin_mul_overflow)
420 #  define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
421 # endif
422 #elif 7 <= __GNUC__
423 # define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
424 # define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
425 # define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
426 #endif
427 
428 #if 3 <= __GNUC__
429 # define ATTRIBUTE_MALLOC __attribute__((malloc))
430 # define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
431 #else
432 # define ATTRIBUTE_MALLOC /* empty */
433 # define ATTRIBUTE_FORMAT(spec) /* empty */
434 #endif
435 
436 #if (defined __has_c_attribute \
437      && (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
438 # define HAVE_HAS_C_ATTRIBUTE true
439 #else
440 # define HAVE_HAS_C_ATTRIBUTE false
441 #endif
442 
443 #if HAVE_HAS_C_ATTRIBUTE
444 # if __has_c_attribute(fallthrough)
445 #  define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
446 # endif
447 #endif
448 #ifndef ATTRIBUTE_FALLTHROUGH
449 # if 7 <= __GNUC__
450 #  define ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
451 # else
452 #  define ATTRIBUTE_FALLTHROUGH ((void) 0)
453 # endif
454 #endif
455 
456 #if HAVE_HAS_C_ATTRIBUTE
457 # if __has_c_attribute(maybe_unused)
458 #  define ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
459 # endif
460 #endif
461 #ifndef ATTRIBUTE_MAYBE_UNUSED
462 # if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
463 #  define ATTRIBUTE_MAYBE_UNUSED __attribute__((unused))
464 # else
465 #  define ATTRIBUTE_MAYBE_UNUSED /* empty */
466 # endif
467 #endif
468 
469 #if HAVE_HAS_C_ATTRIBUTE
470 # if __has_c_attribute(noreturn)
471 #  define ATTRIBUTE_NORETURN [[noreturn]]
472 # endif
473 #endif
474 #ifndef ATTRIBUTE_NORETURN
475 # if 201112 <= __STDC_VERSION__
476 #  define ATTRIBUTE_NORETURN _Noreturn
477 # elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
478 #  define ATTRIBUTE_NORETURN __attribute__((noreturn))
479 # else
480 #  define ATTRIBUTE_NORETURN /* empty */
481 # endif
482 #endif
483 
484 #if HAVE_HAS_C_ATTRIBUTE
485 # if __has_c_attribute(reproducible)
486 #  define ATTRIBUTE_REPRODUCIBLE [[reproducible]]
487 # endif
488 #endif
489 #ifndef ATTRIBUTE_REPRODUCIBLE
490 # if 3 <= __GNUC__
491 #  define ATTRIBUTE_REPRODUCIBLE __attribute__((pure))
492 # else
493 #  define ATTRIBUTE_REPRODUCIBLE /* empty */
494 # endif
495 #endif
496 
497 #if HAVE_HAS_C_ATTRIBUTE
498 # if __has_c_attribute(unsequenced)
499 #  define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
500 # endif
501 #endif
502 #ifndef ATTRIBUTE_UNSEQUENCED
503 # if 3 <= __GNUC__
504 #  define ATTRIBUTE_UNSEQUENCED __attribute__((const))
505 # else
506 #  define ATTRIBUTE_UNSEQUENCED /* empty */
507 # endif
508 #endif
509 
510 #if __STDC_VERSION__ < 199901 && !defined restrict
511 # define restrict /* empty */
512 #endif
513 
514 /*
515 ** Workarounds for compilers/systems.
516 */
517 
518 #ifndef EPOCH_LOCAL
519 # define EPOCH_LOCAL 0
520 #endif
521 #ifndef EPOCH_OFFSET
522 # define EPOCH_OFFSET 0
523 #endif
524 #ifndef RESERVE_STD_EXT_IDS
525 # define RESERVE_STD_EXT_IDS 0
526 #endif
527 
528 /* If standard C identifiers with external linkage (e.g., localtime)
529    are reserved and are not already being renamed anyway, rename them
530    as if compiling with '-Dtime_tz=time_t'.  */
531 #if !defined time_tz && RESERVE_STD_EXT_IDS && USE_LTZ
532 # define time_tz time_t
533 #endif
534 
535 /*
536 ** Compile with -Dtime_tz=T to build the tz package with a private
537 ** time_t type equivalent to T rather than the system-supplied time_t.
538 ** This debugging feature can test unusual design decisions
539 ** (e.g., time_t wider than 'long', or unsigned time_t) even on
540 ** typical platforms.
541 */
542 #if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
543 # define TZ_TIME_T 1
544 #else
545 # define TZ_TIME_T 0
546 #endif
547 
548 #if defined LOCALTIME_IMPLEMENTATION && TZ_TIME_T
549 static time_t sys_time(time_t *x) { return time(x); }
550 #endif
551 
552 #if TZ_TIME_T
553 
554 typedef time_tz tz_time_t;
555 
556 # undef  asctime
557 # define asctime tz_asctime
558 # undef  asctime_r
559 # define asctime_r tz_asctime_r
560 # undef  ctime
561 # define ctime tz_ctime
562 # undef  ctime_r
563 # define ctime_r tz_ctime_r
564 # undef  difftime
565 # define difftime tz_difftime
566 # undef  gmtime
567 # define gmtime tz_gmtime
568 # undef  gmtime_r
569 # define gmtime_r tz_gmtime_r
570 # undef  localtime
571 # define localtime tz_localtime
572 # undef  localtime_r
573 # define localtime_r tz_localtime_r
574 # undef  localtime_rz
575 # define localtime_rz tz_localtime_rz
576 # undef  mktime
577 # define mktime tz_mktime
578 # undef  mktime_z
579 # define mktime_z tz_mktime_z
580 # undef  offtime
581 # define offtime tz_offtime
582 # undef  posix2time
583 # define posix2time tz_posix2time
584 # undef  posix2time_z
585 # define posix2time_z tz_posix2time_z
586 # undef  strftime
587 # define strftime tz_strftime
588 # undef  time
589 # define time tz_time
590 # undef  time2posix
591 # define time2posix tz_time2posix
592 # undef  time2posix_z
593 # define time2posix_z tz_time2posix_z
594 # undef  time_t
595 # define time_t tz_time_t
596 # undef  timegm
597 # define timegm tz_timegm
598 # undef  timelocal
599 # define timelocal tz_timelocal
600 # undef  timeoff
601 # define timeoff tz_timeoff
602 # undef  tzalloc
603 # define tzalloc tz_tzalloc
604 # undef  tzfree
605 # define tzfree tz_tzfree
606 # undef  tzset
607 # define tzset tz_tzset
608 # if HAVE_STRFTIME_L
609 #  undef  strftime_l
610 #  define strftime_l tz_strftime_l
611 # endif
612 # if HAVE_TZNAME
613 #  undef  tzname
614 #  define tzname tz_tzname
615 # endif
616 # if USG_COMPAT
617 #  undef  daylight
618 #  define daylight tz_daylight
619 #  undef  timezone
620 #  define timezone tz_timezone
621 # endif
622 # if ALTZONE
623 #  undef  altzone
624 #  define altzone tz_altzone
625 # endif
626 
627 char *asctime(struct tm const *);
628 char *asctime_r(struct tm const *restrict, char *restrict);
629 char *ctime(time_t const *);
630 char *ctime_r(time_t const *, char *);
631 double difftime(time_t, time_t) ATTRIBUTE_UNSEQUENCED;
632 size_t strftime(char *restrict, size_t, char const *restrict,
633 		struct tm const *restrict);
634 # if HAVE_STRFTIME_L
635 size_t strftime_l(char *restrict, size_t, char const *restrict,
636 		  struct tm const *restrict, locale_t);
637 # endif
638 struct tm *gmtime(time_t const *);
639 struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
640 struct tm *localtime(time_t const *);
641 struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
642 time_t mktime(struct tm *);
643 time_t time(time_t *);
644 time_t timegm(struct tm *);
645 void tzset(void);
646 #endif
647 
648 #ifndef HAVE_DECL_TIMEGM
649 # if (202311 <= __STDC_VERSION__ \
650       || defined __GLIBC__ || defined __tm_zone /* musl */ \
651       || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
652       || (defined __APPLE__ && defined __MACH__))
653 #  define HAVE_DECL_TIMEGM true
654 # else
655 #  define HAVE_DECL_TIMEGM false
656 # endif
657 #endif
658 #if !HAVE_DECL_TIMEGM && !defined timegm
659 time_t timegm(struct tm *);
660 #endif
661 
662 #if !HAVE_DECL_ASCTIME_R && !defined asctime_r
663 extern char *asctime_r(struct tm const *restrict, char *restrict);
664 #endif
665 
666 #ifndef HAVE_DECL_ENVIRON
667 # if defined environ || defined __USE_GNU
668 #  define HAVE_DECL_ENVIRON 1
669 # else
670 #  define HAVE_DECL_ENVIRON 0
671 # endif
672 #endif
673 
674 #if !HAVE_DECL_ENVIRON
675 extern char **environ;
676 #endif
677 
678 #if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS)
679 extern char *tzname[];
680 #endif
681 #if 2 <= USG_COMPAT + (TZ_TIME_T || !HAVE_POSIX_DECLS)
682 extern long timezone;
683 extern int daylight;
684 #endif
685 #if 2 <= ALTZONE + (TZ_TIME_T || !HAVE_POSIX_DECLS)
686 extern long altzone;
687 #endif
688 
689 /*
690 ** The STD_INSPIRED functions are similar, but most also need
691 ** declarations if time_tz is defined.
692 */
693 
694 #ifdef STD_INSPIRED
695 # if TZ_TIME_T || !defined offtime
696 struct tm *offtime(time_t const *, long);
697 # endif
698 # if TZ_TIME_T || !defined timelocal
699 time_t timelocal(struct tm *);
700 # endif
701 # if TZ_TIME_T || !defined timeoff
702 time_t timeoff(struct tm *, long);
703 # endif
704 # if TZ_TIME_T || !defined time2posix
705 time_t time2posix(time_t);
706 # endif
707 # if TZ_TIME_T || !defined posix2time
708 time_t posix2time(time_t);
709 # endif
710 #endif
711 
712 /* Infer TM_ZONE on systems where this information is known, but suppress
713    guessing if NO_TM_ZONE is defined.  Similarly for TM_GMTOFF.  */
714 #if (defined __GLIBC__ \
715      || defined __tm_zone /* musl */ \
716      || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
717      || (defined __APPLE__ && defined __MACH__))
718 # if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
719 #  define TM_GMTOFF tm_gmtoff
720 # endif
721 # if !defined TM_ZONE && !defined NO_TM_ZONE
722 #  define TM_ZONE tm_zone
723 # endif
724 #endif
725 
726 /*
727 ** Define functions that are ABI compatible with NetBSD but have
728 ** better prototypes.  NetBSD 6.1.4 defines a pointer type timezone_t
729 ** and labors under the misconception that 'const timezone_t' is a
730 ** pointer to a constant.  This use of 'const' is ineffective, so it
731 ** is not done here.  What we call 'struct state' NetBSD calls
732 ** 'struct __state', but this is a private name so it doesn't matter.
733 */
734 #if NETBSD_INSPIRED
735 typedef struct state *timezone_t;
736 struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
737 			struct tm *restrict);
738 time_t mktime_z(timezone_t restrict, struct tm *restrict);
739 timezone_t tzalloc(char const *);
740 void tzfree(timezone_t);
741 # ifdef STD_INSPIRED
742 #  if TZ_TIME_T || !defined posix2time_z
743 time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
744 #  endif
745 #  if TZ_TIME_T || !defined time2posix_z
746 time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
747 #  endif
748 # endif
749 #endif
750 
751 /*
752 ** Finally, some convenience items.
753 */
754 
755 #define TYPE_BIT(type)	(sizeof(type) * CHAR_BIT)
756 #define TYPE_SIGNED(type) (((type) -1) < 0)
757 #define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
758 
759 /* Minimum and maximum of two values.  Use lower case to avoid
760    naming clashes with standard include files.  */
761 #define max(a, b) ((a) > (b) ? (a) : (b))
762 #define min(a, b) ((a) < (b) ? (a) : (b))
763 
764 /* Max and min values of the integer type T, of which only the bottom
765    B bits are used, and where the highest-order used bit is considered
766    to be a sign bit if T is signed.  */
767 #define MAXVAL(t, b)						\
768   ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))			\
769 	- 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
770 #define MINVAL(t, b)						\
771   ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
772 
773 /* The extreme time values, assuming no padding.  */
774 #define TIME_T_MIN_NO_PADDING MINVAL(time_t, TYPE_BIT(time_t))
775 #define TIME_T_MAX_NO_PADDING MAXVAL(time_t, TYPE_BIT(time_t))
776 
777 /* The extreme time values.  These are macros, not constants, so that
778    any portability problems occur only when compiling .c files that use
779    the macros, which is safer for applications that need only zdump and zic.
780    This implementation assumes no padding if time_t is signed and
781    either the compiler lacks support for _Generic or time_t is not one
782    of the standard signed integer types.  */
783 #if HAVE_GENERIC
784 # define TIME_T_MIN \
785     _Generic((time_t) 0, \
786 	     signed char: SCHAR_MIN, short: SHRT_MIN, \
787 	     int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \
788 	     default: TIME_T_MIN_NO_PADDING)
789 # define TIME_T_MAX \
790     (TYPE_SIGNED(time_t) \
791      ? _Generic((time_t) 0, \
792 		signed char: SCHAR_MAX, short: SHRT_MAX, \
793 		int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
794 		default: TIME_T_MAX_NO_PADDING)			    \
795      : (time_t) -1)
796 #else
797 # define TIME_T_MIN TIME_T_MIN_NO_PADDING
798 # define TIME_T_MAX TIME_T_MAX_NO_PADDING
799 #endif
800 
801 /*
802 ** 302 / 1000 is log10(2.0) rounded up.
803 ** Subtract one for the sign bit if the type is signed;
804 ** add one for integer division truncation;
805 ** add one more for a minus sign if the type is signed.
806 */
807 #define INT_STRLEN_MAXIMUM(type) \
808 	((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
809 	1 + TYPE_SIGNED(type))
810 
811 /*
812 ** INITIALIZE(x)
813 */
814 
815 #ifdef GCC_LINT
816 # define INITIALIZE(x)	((x) = 0)
817 #else
818 # define INITIALIZE(x)
819 #endif
820 
821 /* Whether memory access must strictly follow the C standard.
822    If 0, it's OK to read uninitialized storage so long as the value is
823    not relied upon.  Defining it to 0 lets mktime access parts of
824    struct tm that might be uninitialized, as a heuristic when the
825    standard doesn't say what to return and when tm_gmtoff can help
826    mktime likely infer a better value.  */
827 #ifndef UNINIT_TRAP
828 # define UNINIT_TRAP 0
829 #endif
830 
831 #ifdef DEBUG
832 # undef unreachable
833 # define unreachable() abort()
834 #elif !defined unreachable
835 # ifdef __has_builtin
836 #  if __has_builtin(__builtin_unreachable)
837 #   define unreachable() __builtin_unreachable()
838 #  endif
839 # elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
840 #  define unreachable() __builtin_unreachable()
841 # endif
842 # ifndef unreachable
843 #  define unreachable() ((void) 0)
844 # endif
845 #endif
846 
847 /*
848 ** For the benefit of GNU folk...
849 ** '_(MSGID)' uses the current locale's message library string for MSGID.
850 ** The default is to use gettext if available, and use MSGID otherwise.
851 */
852 
853 #if HAVE_GETTEXT
854 #define _(msgid) gettext(msgid)
855 #else /* !HAVE_GETTEXT */
856 #define _(msgid) msgid
857 #endif /* !HAVE_GETTEXT */
858 
859 #if !defined TZ_DOMAIN && defined HAVE_GETTEXT
860 # define TZ_DOMAIN "tz"
861 #endif
862 
863 #if HAVE_INCOMPATIBLE_CTIME_R
864 #undef asctime_r
865 #undef ctime_r
866 char *asctime_r(struct tm const *, char *);
867 char *ctime_r(time_t const *, char *);
868 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
869 
870 /* Handy macros that are independent of tzfile implementation.  */
871 
872 enum {
873   SECSPERMIN = 60,
874   MINSPERHOUR = 60,
875   SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
876   HOURSPERDAY = 24,
877   DAYSPERWEEK = 7,
878   DAYSPERNYEAR = 365,
879   DAYSPERLYEAR = DAYSPERNYEAR + 1,
880   MONSPERYEAR = 12,
881   YEARSPERREPEAT = 400	/* years before a Gregorian repeat */
882 };
883 
884 #define SECSPERDAY	((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
885 
886 #define DAYSPERREPEAT		((int_fast32_t) 400 * 365 + 100 - 4 + 1)
887 #define SECSPERREPEAT		((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
888 #define AVGSECSPERYEAR		(SECSPERREPEAT / YEARSPERREPEAT)
889 
890 enum {
891   TM_SUNDAY,
892   TM_MONDAY,
893   TM_TUESDAY,
894   TM_WEDNESDAY,
895   TM_THURSDAY,
896   TM_FRIDAY,
897   TM_SATURDAY
898 };
899 
900 enum {
901   TM_JANUARY,
902   TM_FEBRUARY,
903   TM_MARCH,
904   TM_APRIL,
905   TM_MAY,
906   TM_JUNE,
907   TM_JULY,
908   TM_AUGUST,
909   TM_SEPTEMBER,
910   TM_OCTOBER,
911   TM_NOVEMBER,
912   TM_DECEMBER
913 };
914 
915 enum {
916   TM_YEAR_BASE = 1900,
917   TM_WDAY_BASE = TM_MONDAY,
918   EPOCH_YEAR = 1970,
919   EPOCH_WDAY = TM_THURSDAY
920 };
921 
922 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
923 
924 /*
925 ** Since everything in isleap is modulo 400 (or a factor of 400), we know that
926 **	isleap(y) == isleap(y % 400)
927 ** and so
928 **	isleap(a + b) == isleap((a + b) % 400)
929 ** or
930 **	isleap(a + b) == isleap(a % 400 + b % 400)
931 ** This is true even if % means modulo rather than Fortran remainder
932 ** (which is allowed by C89 but not by C99 or later).
933 ** We use this to avoid addition overflow problems.
934 */
935 
936 #define isleap_sum(a, b)	isleap((a) % 400 + (b) % 400)
937 
938 #endif /* !defined PRIVATE_H */
939