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