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