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