xref: /netbsd-src/lib/libc/time/private.h (revision 53d1339bf7f9c7367b35a9e1ebe693f9b047a47b)
1 /* Private header for tzdb code.  */
2 
3 /*	$NetBSD: private.h,v 1.56 2020/05/25 14:52:48 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_POSIX_DECLS
82 #define HAVE_POSIX_DECLS 1
83 #endif
84 
85 #ifndef HAVE_STDBOOL_H
86 #define HAVE_STDBOOL_H (199901 <= __STDC_VERSION__)
87 #endif
88 
89 #ifndef HAVE_STRDUP
90 #define HAVE_STRDUP 1
91 #endif
92 
93 #ifndef HAVE_STRTOLL
94 #define HAVE_STRTOLL 1
95 #endif
96 
97 #ifndef HAVE_SYMLINK
98 #define HAVE_SYMLINK		1
99 #endif /* !defined HAVE_SYMLINK */
100 
101 #ifndef HAVE_SYS_STAT_H
102 #define HAVE_SYS_STAT_H		1
103 #endif /* !defined HAVE_SYS_STAT_H */
104 
105 #ifndef HAVE_SYS_WAIT_H
106 #define HAVE_SYS_WAIT_H		1
107 #endif /* !defined HAVE_SYS_WAIT_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 ENAMETOOLONG
184 # define ENAMETOOLONG EINVAL
185 #endif
186 #ifndef ENOTSUP
187 # define ENOTSUP EINVAL
188 #endif
189 #ifndef EOVERFLOW
190 # define EOVERFLOW EINVAL
191 #endif
192 
193 #if HAVE_GETTEXT
194 #include <libintl.h>
195 #endif /* HAVE_GETTEXT */
196 
197 #if HAVE_UNISTD_H
198 #include <unistd.h>	/* for R_OK, and other POSIX goodness */
199 #endif /* HAVE_UNISTD_H */
200 
201 #ifndef HAVE_STRFTIME_L
202 # if _POSIX_VERSION < 200809
203 #  define HAVE_STRFTIME_L 0
204 # else
205 #  define HAVE_STRFTIME_L 1
206 # endif
207 #endif
208 
209 #ifndef USG_COMPAT
210 # ifndef _XOPEN_VERSION
211 #  define USG_COMPAT 0
212 # else
213 #  define USG_COMPAT 1
214 # endif
215 #endif
216 
217 #ifndef HAVE_TZNAME
218 # if _POSIX_VERSION < 198808 && !USG_COMPAT
219 #  define HAVE_TZNAME 0
220 # else
221 #  define HAVE_TZNAME 1
222 # endif
223 #endif
224 
225 #ifndef ALTZONE
226 # if defined __sun || defined _M_XENIX
227 #  define ALTZONE 1
228 # else
229 #  define ALTZONE 0
230 # endif
231 #endif
232 
233 #ifndef R_OK
234 #define R_OK	4
235 #endif /* !defined R_OK */
236 
237 /* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
238 #define is_digit(c) ((unsigned)(c) - '0' <= 9)
239 
240 /*
241 ** Define HAVE_STDINT_H's default value here, rather than at the
242 ** start, since __GLIBC__ and INTMAX_MAX's values depend on
243 ** previously-included files.  glibc 2.1 and Solaris 10 and later have
244 ** stdint.h, even with pre-C99 compilers.
245 */
246 #ifndef HAVE_STDINT_H
247 #define HAVE_STDINT_H \
248    (199901 <= __STDC_VERSION__ \
249     || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__)	\
250     || __CYGWIN__ || INTMAX_MAX)
251 #endif /* !defined HAVE_STDINT_H */
252 
253 #if HAVE_STDINT_H
254 #include <stdint.h>
255 #endif /* !HAVE_STDINT_H */
256 
257 #ifndef HAVE_INTTYPES_H
258 # define HAVE_INTTYPES_H HAVE_STDINT_H
259 #endif
260 #if HAVE_INTTYPES_H
261 # include <inttypes.h>
262 #endif
263 
264 /* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX.  */
265 #ifdef __LONG_LONG_MAX__
266 # ifndef LLONG_MAX
267 #  define LLONG_MAX __LONG_LONG_MAX__
268 # endif
269 # ifndef LLONG_MIN
270 #  define LLONG_MIN (-1 - LLONG_MAX)
271 # endif
272 #endif
273 
274 #ifndef INT_FAST64_MAX
275 # ifdef LLONG_MAX
276 typedef long long	int_fast64_t;
277 #  define INT_FAST64_MIN LLONG_MIN
278 #  define INT_FAST64_MAX LLONG_MAX
279 # else
280 #  if LONG_MAX >> 31 < 0xffffffff
281 Please use a compiler that supports a 64-bit integer type (or wider);
282 you may need to compile with "-DHAVE_STDINT_H".
283 #  endif
284 typedef long		int_fast64_t;
285 #  define INT_FAST64_MIN LONG_MIN
286 #  define INT_FAST64_MAX LONG_MAX
287 # endif
288 #endif
289 
290 #ifndef PRIdFAST64
291 # if INT_FAST64_MAX == LLONG_MAX
292 #  define PRIdFAST64 "lld"
293 # else
294 #  define PRIdFAST64 "ld"
295 # endif
296 #endif
297 
298 #ifndef SCNdFAST64
299 # define SCNdFAST64 PRIdFAST64
300 #endif
301 
302 #ifndef INT_FAST32_MAX
303 # if INT_MAX >> 31 == 0
304 typedef long int_fast32_t;
305 #  define INT_FAST32_MAX LONG_MAX
306 #  define INT_FAST32_MIN LONG_MIN
307 # else
308 typedef int int_fast32_t;
309 #  define INT_FAST32_MAX INT_MAX
310 #  define INT_FAST32_MIN INT_MIN
311 # endif
312 #endif
313 
314 #ifndef INTMAX_MAX
315 # ifdef LLONG_MAX
316 typedef long long intmax_t;
317 #  if HAVE_STRTOLL
318 #   define strtoimax strtoll
319 #  endif
320 #  define INTMAX_MAX LLONG_MAX
321 #  define INTMAX_MIN LLONG_MIN
322 # else
323 typedef long intmax_t;
324 #  define INTMAX_MAX LONG_MAX
325 #  define INTMAX_MIN LONG_MIN
326 # endif
327 # ifndef strtoimax
328 #  define strtoimax strtol
329 # endif
330 #endif
331 
332 #ifndef PRIdMAX
333 # if INTMAX_MAX == LLONG_MAX
334 #  define PRIdMAX "lld"
335 # else
336 #  define PRIdMAX "ld"
337 # endif
338 #endif
339 
340 #ifndef UINT_FAST64_MAX
341 # if defined ULLONG_MAX || defined __LONG_LONG_MAX__
342 typedef unsigned long long uint_fast64_t;
343 # else
344 #  if ULONG_MAX >> 31 >> 1 < 0xffffffff
345 Please use a compiler that supports a 64-bit integer type (or wider);
346 you may need to compile with "-DHAVE_STDINT_H".
347 #  endif
348 typedef unsigned long	uint_fast64_t;
349 # endif
350 #endif
351 
352 #ifndef UINTMAX_MAX
353 # if defined ULLONG_MAX || defined __LONG_LONG_MAX__
354 typedef unsigned long long uintmax_t;
355 # else
356 typedef unsigned long uintmax_t;
357 # endif
358 #endif
359 
360 #ifndef PRIuMAX
361 # if defined ULLONG_MAX || defined __LONG_LONG_MAX__
362 #  define PRIuMAX "llu"
363 # else
364 #  define PRIuMAX "lu"
365 # endif
366 #endif
367 
368 #ifndef INT32_MAX
369 #define INT32_MAX 0x7fffffff
370 #endif /* !defined INT32_MAX */
371 #ifndef INT32_MIN
372 #define INT32_MIN (-1 - INT32_MAX)
373 #endif /* !defined INT32_MIN */
374 
375 #ifndef SIZE_MAX
376 #define SIZE_MAX ((size_t) -1)
377 #endif
378 
379 #if 3 <= __GNUC__
380 # define ATTRIBUTE_CONST __attribute__ ((__const__))
381 # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
382 # define ATTRIBUTE_PURE __attribute__ ((__pure__))
383 # define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
384 #else
385 # define ATTRIBUTE_CONST /* empty */
386 # define ATTRIBUTE_MALLOC /* empty */
387 # define ATTRIBUTE_PURE /* empty */
388 # define ATTRIBUTE_FORMAT(spec) /* empty */
389 #endif
390 
391 #if !defined _Noreturn && __STDC_VERSION__ < 201112
392 # if 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
393 #  define _Noreturn __attribute__ ((__noreturn__))
394 # else
395 #  define _Noreturn
396 # endif
397 #endif
398 
399 #if __STDC_VERSION__ < 199901 && !defined restrict
400 # define restrict /* empty */
401 #endif
402 
403 /*
404 ** Workarounds for compilers/systems.
405 */
406 
407 #ifndef EPOCH_LOCAL
408 # define EPOCH_LOCAL 0
409 #endif
410 #ifndef EPOCH_OFFSET
411 # define EPOCH_OFFSET 0
412 #endif
413 #ifndef RESERVE_STD_EXT_IDS
414 # define RESERVE_STD_EXT_IDS 0
415 #endif
416 
417 /* If standard C identifiers with external linkage (e.g., localtime)
418    are reserved and are not already being renamed anyway, rename them
419    as if compiling with '-Dtime_tz=time_t'.  */
420 #if !defined time_tz && RESERVE_STD_EXT_IDS && USE_LTZ
421 # define time_tz time_t
422 #endif
423 
424 /*
425 ** Compile with -Dtime_tz=T to build the tz package with a private
426 ** time_t type equivalent to T rather than the system-supplied time_t.
427 ** This debugging feature can test unusual design decisions
428 ** (e.g., time_t wider than 'long', or unsigned time_t) even on
429 ** typical platforms.
430 */
431 #if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
432 # define TZ_TIME_T 1
433 #else
434 # define TZ_TIME_T 0
435 #endif
436 
437 #if TZ_TIME_T
438 # ifdef LOCALTIME_IMPLEMENTATION
439 static time_t sys_time(time_t *x) { return time(x); }
440 # endif
441 
442 typedef time_tz tz_time_t;
443 
444 # undef  asctime
445 # define asctime tz_asctime
446 # undef  asctime_r
447 # define asctime_r tz_asctime_r
448 # undef  ctime
449 # define ctime tz_ctime
450 # undef  ctime_r
451 # define ctime_r tz_ctime_r
452 # undef  difftime
453 # define difftime tz_difftime
454 # undef  gmtime
455 # define gmtime tz_gmtime
456 # undef  gmtime_r
457 # define gmtime_r tz_gmtime_r
458 # undef  localtime
459 # define localtime tz_localtime
460 # undef  localtime_r
461 # define localtime_r tz_localtime_r
462 # undef  localtime_rz
463 # define localtime_rz tz_localtime_rz
464 # undef  mktime
465 # define mktime tz_mktime
466 # undef  mktime_z
467 # define mktime_z tz_mktime_z
468 # undef  offtime
469 # define offtime tz_offtime
470 # undef  posix2time
471 # define posix2time tz_posix2time
472 # undef  posix2time_z
473 # define posix2time_z tz_posix2time_z
474 # undef  strftime
475 # define strftime tz_strftime
476 # undef  time
477 # define time tz_time
478 # undef  time2posix
479 # define time2posix tz_time2posix
480 # undef  time2posix_z
481 # define time2posix_z tz_time2posix_z
482 # undef  time_t
483 # define time_t tz_time_t
484 # undef  timegm
485 # define timegm tz_timegm
486 # undef  timelocal
487 # define timelocal tz_timelocal
488 # undef  timeoff
489 # define timeoff tz_timeoff
490 # undef  tzalloc
491 # define tzalloc tz_tzalloc
492 # undef  tzfree
493 # define tzfree tz_tzfree
494 # undef  tzset
495 # define tzset tz_tzset
496 # undef  tzsetwall
497 # define tzsetwall tz_tzsetwall
498 # if HAVE_STRFTIME_L
499 #  undef  strftime_l
500 #  define strftime_l tz_strftime_l
501 # endif
502 # if HAVE_TZNAME
503 #  undef  tzname
504 #  define tzname tz_tzname
505 # endif
506 # if USG_COMPAT
507 #  undef  daylight
508 #  define daylight tz_daylight
509 #  undef  timezone
510 #  define timezone tz_timezone
511 # endif
512 # if ALTZONE
513 #  undef  altzone
514 #  define altzone tz_altzone
515 # endif
516 
517 char *asctime(struct tm const *);
518 char *asctime_r(struct tm const *restrict, char *restrict);
519 char *ctime(time_t const *);
520 char *ctime_r(time_t const *, char *);
521 double difftime(time_t, time_t) ATTRIBUTE_CONST;
522 size_t strftime(char *restrict, size_t, char const *restrict,
523 		struct tm const *restrict);
524 # if HAVE_STRFTIME_L
525 size_t strftime_l(char *restrict, size_t, char const *restrict,
526 		  struct tm const *restrict, locale_t);
527 # endif
528 struct tm *gmtime(time_t const *);
529 struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
530 struct tm *localtime(time_t const *);
531 struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
532 time_t mktime(struct tm *);
533 time_t time(time_t *);
534 void tzset(void);
535 #endif
536 
537 #if !HAVE_DECL_ASCTIME_R && !defined asctime_r
538 extern char *asctime_r(struct tm const *restrict, char *restrict);
539 #endif
540 
541 #ifndef HAVE_DECL_ENVIRON
542 # if defined environ || defined __USE_GNU
543 #  define HAVE_DECL_ENVIRON 1
544 # else
545 #  define HAVE_DECL_ENVIRON 0
546 # endif
547 #endif
548 
549 #if !HAVE_DECL_ENVIRON
550 extern char **environ;
551 #endif
552 
553 #if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS)
554 extern char *tzname[];
555 #endif
556 #if 2 <= USG_COMPAT + (TZ_TIME_T || !HAVE_POSIX_DECLS)
557 extern long timezone;
558 extern int daylight;
559 #endif
560 #if 2 <= ALTZONE + (TZ_TIME_T || !HAVE_POSIX_DECLS)
561 extern long altzone;
562 #endif
563 
564 /*
565 ** The STD_INSPIRED functions are similar, but most also need
566 ** declarations if time_tz is defined.
567 */
568 
569 #ifdef STD_INSPIRED
570 # if TZ_TIME_T || !defined tzsetwall
571 void tzsetwall(void);
572 # endif
573 # if TZ_TIME_T || !defined offtime
574 struct tm *offtime(time_t const *, long);
575 # endif
576 # if TZ_TIME_T || !defined timegm
577 time_t timegm(struct tm *);
578 # endif
579 # if TZ_TIME_T || !defined timelocal
580 time_t timelocal(struct tm *);
581 # endif
582 # if TZ_TIME_T || !defined timeoff
583 time_t timeoff(struct tm *, long);
584 # endif
585 # if TZ_TIME_T || !defined time2posix
586 time_t time2posix(time_t);
587 # endif
588 # if TZ_TIME_T || !defined posix2time
589 time_t posix2time(time_t);
590 # endif
591 #endif
592 
593 /* Infer TM_ZONE on systems where this information is known, but suppress
594    guessing if NO_TM_ZONE is defined.  Similarly for TM_GMTOFF.  */
595 #if (defined __GLIBC__ \
596      || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
597      || (defined __APPLE__ && defined __MACH__))
598 # if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
599 #  define TM_GMTOFF tm_gmtoff
600 # endif
601 # if !defined TM_ZONE && !defined NO_TM_ZONE
602 #  define TM_ZONE tm_zone
603 # endif
604 #endif
605 
606 /*
607 ** Define functions that are ABI compatible with NetBSD but have
608 ** better prototypes.  NetBSD 6.1.4 defines a pointer type timezone_t
609 ** and labors under the misconception that 'const timezone_t' is a
610 ** pointer to a constant.  This use of 'const' is ineffective, so it
611 ** is not done here.  What we call 'struct state' NetBSD calls
612 ** 'struct __state', but this is a private name so it doesn't matter.
613 */
614 #ifndef __NetBSD__
615 #if NETBSD_INSPIRED
616 typedef struct state *timezone_t;
617 struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
618 			struct tm *restrict);
619 time_t mktime_z(timezone_t restrict, struct tm *restrict);
620 timezone_t tzalloc(char const *);
621 void tzfree(timezone_t);
622 # ifdef STD_INSPIRED
623 #  if TZ_TIME_T || !defined posix2time_z
624 time_t posix2time_z(timezone_t __restrict, time_t) ATTRIBUTE_PURE;
625 #  endif
626 #  if TZ_TIME_T || !defined time2posix_z
627 time_t time2posix_z(timezone_t __restrict, time_t) ATTRIBUTE_PURE;
628 #  endif
629 # endif
630 #endif
631 #endif
632 
633 /*
634 ** Finally, some convenience items.
635 */
636 
637 #if HAVE_STDBOOL_H
638 # include <stdbool.h>
639 #else
640 # define true 1
641 # define false 0
642 # define bool int
643 #endif
644 
645 #define TYPE_BIT(type)	(sizeof (type) * CHAR_BIT)
646 #define TYPE_SIGNED(type) (/*CONSTCOND*/((type) -1) < 0)
647 #define TWOS_COMPLEMENT(t) (/*CONSTCOND*/(t) ~ (t) 0 < 0)
648 
649 /* Max and min values of the integer type T, of which only the bottom
650    B bits are used, and where the highest-order used bit is considered
651    to be a sign bit if T is signed.  */
652 #define MAXVAL(t, b) /*LINTED*/					\
653   ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))			\
654 	- 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
655 #define MINVAL(t, b)						\
656   ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
657 
658 /* The extreme time values, assuming no padding.  */
659 #define TIME_T_MIN_NO_PADDING MINVAL(time_t, TYPE_BIT(time_t))
660 #define TIME_T_MAX_NO_PADDING MAXVAL(time_t, TYPE_BIT(time_t))
661 
662 /* The extreme time values.  These are macros, not constants, so that
663    any portability problem occur only when compiling .c files that use
664    the macros, which is safer for applications that need only zdump and zic.
665    This implementation assumes no padding if time_t is signed and
666    either the compiler lacks support for _Generic or time_t is not one
667    of the standard signed integer types.  */
668 #if HAVE_GENERIC
669 # define TIME_T_MIN \
670     _Generic((time_t) 0, \
671 	     signed char: SCHAR_MIN, short: SHRT_MIN, \
672 	     int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \
673 	     default: TIME_T_MIN_NO_PADDING)
674 # define TIME_T_MAX \
675     (TYPE_SIGNED(time_t) \
676      ? _Generic((time_t) 0, \
677 		signed char: SCHAR_MAX, short: SHRT_MAX, \
678 		int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
679 		default: TIME_T_MAX_NO_PADDING)			    \
680      : (time_t) -1)
681 #else
682 # define TIME_T_MIN TIME_T_MIN_NO_PADDING
683 # define TIME_T_MAX TIME_T_MAX_NO_PADDING
684 #endif
685 
686 /*
687 ** 302 / 1000 is log10(2.0) rounded up.
688 ** Subtract one for the sign bit if the type is signed;
689 ** add one for integer division truncation;
690 ** add one more for a minus sign if the type is signed.
691 */
692 #define INT_STRLEN_MAXIMUM(type) \
693 	((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
694 	1 + TYPE_SIGNED(type))
695 
696 /*
697 ** INITIALIZE(x)
698 */
699 
700 #if defined(__GNUC__) || defined(__lint__)
701 # define INITIALIZE(x)	((x) = 0)
702 #else
703 # define INITIALIZE(x)
704 #endif
705 
706 #ifndef UNINIT_TRAP
707 # define UNINIT_TRAP 0
708 #endif
709 
710 /*
711 ** For the benefit of GNU folk...
712 ** '_(MSGID)' uses the current locale's message library string for MSGID.
713 ** The default is to use gettext if available, and use MSGID otherwise.
714 */
715 
716 #if HAVE_GETTEXT
717 #define _(msgid) gettext(msgid)
718 #else /* !HAVE_GETTEXT */
719 #define _(msgid) msgid
720 #endif /* !HAVE_GETTEXT */
721 
722 #if !defined TZ_DOMAIN && defined HAVE_GETTEXT
723 # define TZ_DOMAIN "tz"
724 #endif
725 
726 #if HAVE_INCOMPATIBLE_CTIME_R
727 #undef asctime_r
728 #undef ctime_r
729 char *asctime_r(struct tm const *, char *);
730 char *ctime_r(time_t const *, char *);
731 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
732 
733 /* Handy macros that are independent of tzfile implementation.  */
734 
735 #define YEARSPERREPEAT		400	/* years before a Gregorian repeat */
736 
737 #define SECSPERMIN	60
738 #define MINSPERHOUR	60
739 #define HOURSPERDAY	24
740 #define DAYSPERWEEK	7
741 #define DAYSPERNYEAR	365
742 #define DAYSPERLYEAR	366
743 #define SECSPERHOUR	(SECSPERMIN * MINSPERHOUR)
744 #define SECSPERDAY	((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
745 #define MONSPERYEAR	12
746 
747 #define TM_SUNDAY	0
748 #define TM_MONDAY	1
749 #define TM_TUESDAY	2
750 #define TM_WEDNESDAY	3
751 #define TM_THURSDAY	4
752 #define TM_FRIDAY	5
753 #define TM_SATURDAY	6
754 
755 #define TM_JANUARY	0
756 #define TM_FEBRUARY	1
757 #define TM_MARCH	2
758 #define TM_APRIL	3
759 #define TM_MAY		4
760 #define TM_JUNE		5
761 #define TM_JULY		6
762 #define TM_AUGUST	7
763 #define TM_SEPTEMBER	8
764 #define TM_OCTOBER	9
765 #define TM_NOVEMBER	10
766 #define TM_DECEMBER	11
767 
768 #define TM_YEAR_BASE	1900
769 
770 #define EPOCH_YEAR	1970
771 #define EPOCH_WDAY	TM_THURSDAY
772 
773 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
774 
775 /*
776 ** Since everything in isleap is modulo 400 (or a factor of 400), we know that
777 **	isleap(y) == isleap(y % 400)
778 ** and so
779 **	isleap(a + b) == isleap((a + b) % 400)
780 ** or
781 **	isleap(a + b) == isleap(a % 400 + b % 400)
782 ** This is true even if % means modulo rather than Fortran remainder
783 ** (which is allowed by C89 but not by C99 or later).
784 ** We use this to avoid addition overflow problems.
785 */
786 
787 #define isleap_sum(a, b)	isleap((a) % 400 + (b) % 400)
788 
789 
790 /*
791 ** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
792 */
793 
794 #define AVGSECSPERYEAR		31556952L
795 #define SECSPERREPEAT \
796   ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
797 #define SECSPERREPEAT_BITS	34	/* ceil(log2(SECSPERREPEAT)) */
798 
799 #ifdef _LIBC
800 #include "reentrant.h"
801 extern struct __state *__lclptr;
802 #if defined(__LIBC12_SOURCE__)
803 #define tzset_unlocked __tzset_unlocked
804 #else
805 #define tzset_unlocked __tzset_unlocked50
806 #endif
807 
808 void tzset_unlocked(void);
809 #ifdef _REENTRANT
810 extern rwlock_t __lcl_lock;
811 #endif
812 #endif
813 
814 #endif /* !defined PRIVATE_H */
815