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