diff options
| author | Paul Eggert | 2019-04-30 09:44:38 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-04-30 09:45:08 -0700 |
| commit | 46b434a62cea06bdcb3c8d9ee18284ab59e9b012 (patch) | |
| tree | b14b9963adc009ecbf2f380630bf443a57f2ee87 /lib | |
| parent | 826f1e260121edc5185e0ed3fa20a781fbddc9a2 (diff) | |
| download | emacs-46b434a62cea06bdcb3c8d9ee18284ab59e9b012.tar.gz emacs-46b434a62cea06bdcb3c8d9ee18284ab59e9b012.zip | |
Update from Gnulib
* build-aux/config.guess, doc/misc/texinfo.tex:
* lib/mktime-internal.h, lib/mktime.c, lib/timegm.c:
Copy from Gnulib.
* lib/gnulib.mk.in: Regenerate.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/gnulib.mk.in | 1 | ||||
| -rw-r--r-- | lib/mktime-internal.h | 60 | ||||
| -rw-r--r-- | lib/mktime.c | 71 | ||||
| -rw-r--r-- | lib/timegm.c | 32 |
4 files changed, 116 insertions, 48 deletions
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index ade4ff8ebdb..1cbbff212bb 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in | |||
| @@ -1046,6 +1046,7 @@ datadir = @datadir@ | |||
| 1046 | datarootdir = @datarootdir@ | 1046 | datarootdir = @datarootdir@ |
| 1047 | docdir = @docdir@ | 1047 | docdir = @docdir@ |
| 1048 | dvidir = @dvidir@ | 1048 | dvidir = @dvidir@ |
| 1049 | emacs_major_version = @emacs_major_version@ | ||
| 1049 | etcdir = @etcdir@ | 1050 | etcdir = @etcdir@ |
| 1050 | etcdocdir = @etcdocdir@ | 1051 | etcdocdir = @etcdocdir@ |
| 1051 | exec_prefix = @exec_prefix@ | 1052 | exec_prefix = @exec_prefix@ |
diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h index d13d89cfae7..52ab7814429 100644 --- a/lib/mktime-internal.h +++ b/lib/mktime-internal.h | |||
| @@ -1,40 +1,56 @@ | |||
| 1 | /* mktime variant that also uses an offset guess | 1 | /* Internals of mktime and related functions |
| 2 | |||
| 3 | Copyright 2016-2019 Free Software Foundation, Inc. | 2 | Copyright 2016-2019 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | ||
| 4 | Contributed by Paul Eggert <eggert@cs.ucla.edu>. | ||
| 4 | 5 | ||
| 5 | This program is free software; you can redistribute it and/or | 6 | The GNU C Library is free software; you can redistribute it and/or |
| 6 | modify it under the terms of the GNU General Public | 7 | modify it under the terms of the GNU General Public |
| 7 | License as published by the Free Software Foundation; either | 8 | License as published by the Free Software Foundation; either |
| 8 | version 3 of the License, or (at your option) any later version. | 9 | version 3 of the License, or (at your option) any later version. |
| 9 | 10 | ||
| 10 | This program is distributed in the hope that it will be useful, | 11 | The GNU C Library is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | General Public License for more details. | 14 | General Public License for more details. |
| 14 | 15 | ||
| 15 | You should have received a copy of the GNU General Public | 16 | You should have received a copy of the GNU General Public |
| 16 | License along with this program; if not, see | 17 | License along with the GNU C Library; if not, see |
| 17 | <https://www.gnu.org/licenses/>. */ | 18 | <https://www.gnu.org/licenses/>. */ |
| 18 | 19 | ||
| 19 | #include <time.h> | 20 | #ifndef _LIBC |
| 21 | # include <time.h> | ||
| 22 | #endif | ||
| 20 | 23 | ||
| 21 | /* mktime_offset_t is a signed type wide enough to hold a UTC offset | 24 | /* mktime_offset_t is a signed type wide enough to hold a UTC offset |
| 22 | in seconds, and used as part of the type of the offset-guess | 25 | in seconds, and used as part of the type of the offset-guess |
| 23 | argument to mktime_internal. Use time_t on platforms where time_t | 26 | argument to mktime_internal. In Glibc, it is always long int. |
| 27 | When in Gnulib, use time_t on platforms where time_t | ||
| 24 | is signed, to be compatible with platforms like BeOS that export | 28 | is signed, to be compatible with platforms like BeOS that export |
| 25 | this implementation detail of mktime. On platforms where time_t is | 29 | this implementation detail of mktime. On platforms where time_t is |
| 26 | unsigned, GNU and POSIX code can assume 'int' is at least 32 bits | 30 | unsigned, GNU and POSIX code can assume 'int' is at least 32 bits |
| 27 | which is wide enough for a UTC offset. */ | 31 | which is wide enough for a UTC offset. */ |
| 28 | 32 | #ifdef _LIBC | |
| 29 | #if TIME_T_IS_SIGNED | 33 | typedef long int mktime_offset_t; |
| 34 | #elif defined TIME_T_IS_SIGNED | ||
| 30 | typedef time_t mktime_offset_t; | 35 | typedef time_t mktime_offset_t; |
| 31 | #else | 36 | #else |
| 32 | typedef int mktime_offset_t; | 37 | typedef int mktime_offset_t; |
| 33 | #endif | 38 | #endif |
| 34 | 39 | ||
| 35 | time_t mktime_internal (struct tm *, | 40 | /* The source code uses identifiers like __time64_t for glibc |
| 36 | struct tm * (*) (time_t const *, struct tm *), | 41 | timestamps that can contain 64-bit values even when time_t is only |
| 37 | mktime_offset_t *); | 42 | 32 bits. These are just macros for the ordinary identifiers unless |
| 43 | compiling within glibc when time_t is 32 bits. */ | ||
| 44 | #if ! (defined _LIBC && __TIMESIZE != 64) | ||
| 45 | # undef __time64_t | ||
| 46 | # define __time64_t time_t | ||
| 47 | # define __gmtime64_r __gmtime_r | ||
| 48 | # define __localtime64_r __localtime_r | ||
| 49 | # define __mktime64 mktime | ||
| 50 | # define __timegm64 timegm | ||
| 51 | #endif | ||
| 52 | |||
| 53 | #ifndef _LIBC | ||
| 38 | 54 | ||
| 39 | /* Although glibc source code uses leading underscores, Gnulib wants | 55 | /* Although glibc source code uses leading underscores, Gnulib wants |
| 40 | ordinary names. | 56 | ordinary names. |
| @@ -45,9 +61,19 @@ time_t mktime_internal (struct tm *, | |||
| 45 | Similarly for gmtime_r. See the gnulib time_r module for one way | 61 | Similarly for gmtime_r. See the gnulib time_r module for one way |
| 46 | to implement this. */ | 62 | to implement this. */ |
| 47 | 63 | ||
| 48 | #undef __gmtime_r | 64 | # undef __gmtime_r |
| 49 | #undef __localtime_r | 65 | # undef __localtime_r |
| 50 | #define __gmtime_r gmtime_r | 66 | # define __gmtime_r gmtime_r |
| 51 | #define __localtime_r localtime_r | 67 | # define __localtime_r localtime_r |
| 68 | |||
| 69 | # define __mktime_internal mktime_internal | ||
| 70 | |||
| 71 | #endif | ||
| 52 | 72 | ||
| 53 | #define __mktime_internal mktime_internal | 73 | /* Subroutine of mktime. Return the time_t representation of TP and |
| 74 | normalize TP, given that a struct tm * maps to a time_t as performed | ||
| 75 | by FUNC. Record next guess for localtime-gmtime offset in *OFFSET. */ | ||
| 76 | extern __time64_t __mktime_internal (struct tm *tp, | ||
| 77 | struct tm *(*func) (__time64_t const *, | ||
| 78 | struct tm *), | ||
| 79 | mktime_offset_t *offset) attribute_hidden; | ||
diff --git a/lib/mktime.c b/lib/mktime.c index e3783d7a95e..b00af96c8c4 100644 --- a/lib/mktime.c +++ b/lib/mktime.c | |||
| @@ -112,11 +112,11 @@ my_tzset (void) | |||
| 112 | added to them, and then with another timestamp added, without | 112 | added to them, and then with another timestamp added, without |
| 113 | worrying about overflow. | 113 | worrying about overflow. |
| 114 | 114 | ||
| 115 | Much of the code uses long_int to represent time_t values, to | 115 | Much of the code uses long_int to represent __time64_t values, to |
| 116 | lessen the hassle of dealing with platforms where time_t is | 116 | lessen the hassle of dealing with platforms where __time64_t is |
| 117 | unsigned, and because long_int should suffice to represent all | 117 | unsigned, and because long_int should suffice to represent all |
| 118 | time_t values that mktime can generate even on platforms where | 118 | __time64_t values that mktime can generate even on platforms where |
| 119 | time_t is excessively wide. */ | 119 | __time64_t is wider than the int components of struct tm. */ |
| 120 | 120 | ||
| 121 | #if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60 | 121 | #if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60 |
| 122 | typedef long int long_int; | 122 | typedef long int long_int; |
| @@ -144,16 +144,15 @@ shr (long_int a, int b) | |||
| 144 | : a / (one << b) - (a % (one << b) < 0)); | 144 | : a / (one << b) - (a % (one << b) < 0)); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | /* Bounds for the intersection of time_t and long_int. */ | 147 | /* Bounds for the intersection of __time64_t and long_int. */ |
| 148 | 148 | ||
| 149 | static long_int const mktime_min | 149 | static long_int const mktime_min |
| 150 | = ((TYPE_SIGNED (time_t) && TYPE_MINIMUM (time_t) < TYPE_MINIMUM (long_int)) | 150 | = ((TYPE_SIGNED (__time64_t) |
| 151 | ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (time_t)); | 151 | && TYPE_MINIMUM (__time64_t) < TYPE_MINIMUM (long_int)) |
| 152 | ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (__time64_t)); | ||
| 152 | static long_int const mktime_max | 153 | static long_int const mktime_max |
| 153 | = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (time_t) | 154 | = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t) |
| 154 | ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (time_t)); | 155 | ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t)); |
| 155 | |||
| 156 | verify (TYPE_IS_INTEGER (time_t)); | ||
| 157 | 156 | ||
| 158 | #define EPOCH_YEAR 1970 | 157 | #define EPOCH_YEAR 1970 |
| 159 | #define TM_YEAR_BASE 1900 | 158 | #define TM_YEAR_BASE 1900 |
| @@ -252,23 +251,23 @@ tm_diff (long_int year, long_int yday, int hour, int min, int sec, | |||
| 252 | } | 251 | } |
| 253 | 252 | ||
| 254 | /* Use CONVERT to convert T to a struct tm value in *TM. T must be in | 253 | /* Use CONVERT to convert T to a struct tm value in *TM. T must be in |
| 255 | range for time_t. Return TM if successful, NULL (setting errno) on | 254 | range for __time64_t. Return TM if successful, NULL (setting errno) on |
| 256 | failure. */ | 255 | failure. */ |
| 257 | static struct tm * | 256 | static struct tm * |
| 258 | convert_time (struct tm *(*convert) (const time_t *, struct tm *), | 257 | convert_time (struct tm *(*convert) (const __time64_t *, struct tm *), |
| 259 | long_int t, struct tm *tm) | 258 | long_int t, struct tm *tm) |
| 260 | { | 259 | { |
| 261 | time_t x = t; | 260 | __time64_t x = t; |
| 262 | return convert (&x, tm); | 261 | return convert (&x, tm); |
| 263 | } | 262 | } |
| 264 | 263 | ||
| 265 | /* Use CONVERT to convert *T to a broken down time in *TP. | 264 | /* Use CONVERT to convert *T to a broken down time in *TP. |
| 266 | If *T is out of range for conversion, adjust it so that | 265 | If *T is out of range for conversion, adjust it so that |
| 267 | it is the nearest in-range value and then convert that. | 266 | it is the nearest in-range value and then convert that. |
| 268 | A value is in range if it fits in both time_t and long_int. | 267 | A value is in range if it fits in both __time64_t and long_int. |
| 269 | Return TP on success, NULL (setting errno) on failure. */ | 268 | Return TP on success, NULL (setting errno) on failure. */ |
| 270 | static struct tm * | 269 | static struct tm * |
| 271 | ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), | 270 | ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *), |
| 272 | long_int *t, struct tm *tp) | 271 | long_int *t, struct tm *tp) |
| 273 | { | 272 | { |
| 274 | long_int t1 = (*t < mktime_min ? mktime_min | 273 | long_int t1 = (*t < mktime_min ? mktime_min |
| @@ -310,7 +309,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), | |||
| 310 | } | 309 | } |
| 311 | 310 | ||
| 312 | 311 | ||
| 313 | /* Convert *TP to a time_t value, inverting | 312 | /* Convert *TP to a __time64_t value, inverting |
| 314 | the monotonic and mostly-unit-linear conversion function CONVERT. | 313 | the monotonic and mostly-unit-linear conversion function CONVERT. |
| 315 | Use *OFFSET to keep track of a guess at the offset of the result, | 314 | Use *OFFSET to keep track of a guess at the offset of the result, |
| 316 | compared to what the result would be for UTC without leap seconds. | 315 | compared to what the result would be for UTC without leap seconds. |
| @@ -318,9 +317,9 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), | |||
| 318 | If successful, set *TP to the canonicalized struct tm; | 317 | If successful, set *TP to the canonicalized struct tm; |
| 319 | otherwise leave *TP alone, return ((time_t) -1) and set errno. | 318 | otherwise leave *TP alone, return ((time_t) -1) and set errno. |
| 320 | This function is external because it is used also by timegm.c. */ | 319 | This function is external because it is used also by timegm.c. */ |
| 321 | time_t | 320 | __time64_t |
| 322 | __mktime_internal (struct tm *tp, | 321 | __mktime_internal (struct tm *tp, |
| 323 | struct tm *(*convert) (const time_t *, struct tm *), | 322 | struct tm *(*convert) (const __time64_t *, struct tm *), |
| 324 | mktime_offset_t *offset) | 323 | mktime_offset_t *offset) |
| 325 | { | 324 | { |
| 326 | struct tm tm; | 325 | struct tm tm; |
| @@ -520,9 +519,9 @@ __mktime_internal (struct tm *tp, | |||
| 520 | 519 | ||
| 521 | #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS | 520 | #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS |
| 522 | 521 | ||
| 523 | /* Convert *TP to a time_t value. */ | 522 | /* Convert *TP to a __time64_t value. */ |
| 524 | time_t | 523 | __time64_t |
| 525 | mktime (struct tm *tp) | 524 | __mktime64 (struct tm *tp) |
| 526 | { | 525 | { |
| 527 | /* POSIX.1 8.1.1 requires that whenever mktime() is called, the | 526 | /* POSIX.1 8.1.1 requires that whenever mktime() is called, the |
| 528 | time zone names contained in the external variable 'tzname' shall | 527 | time zone names contained in the external variable 'tzname' shall |
| @@ -531,7 +530,7 @@ mktime (struct tm *tp) | |||
| 531 | 530 | ||
| 532 | # if defined _LIBC || NEED_MKTIME_WORKING | 531 | # if defined _LIBC || NEED_MKTIME_WORKING |
| 533 | static mktime_offset_t localtime_offset; | 532 | static mktime_offset_t localtime_offset; |
| 534 | return __mktime_internal (tp, __localtime_r, &localtime_offset); | 533 | return __mktime_internal (tp, __localtime64_r, &localtime_offset); |
| 535 | # else | 534 | # else |
| 536 | # undef mktime | 535 | # undef mktime |
| 537 | return mktime (tp); | 536 | return mktime (tp); |
| @@ -539,11 +538,29 @@ mktime (struct tm *tp) | |||
| 539 | } | 538 | } |
| 540 | #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */ | 539 | #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */ |
| 541 | 540 | ||
| 542 | #ifdef weak_alias | 541 | #if defined _LIBC && __TIMESIZE != 64 |
| 543 | weak_alias (mktime, timelocal) | 542 | |
| 543 | libc_hidden_def (__mktime64) | ||
| 544 | |||
| 545 | time_t | ||
| 546 | mktime (struct tm *tp) | ||
| 547 | { | ||
| 548 | struct tm tm = *tp; | ||
| 549 | __time64_t t = __mktime64 (&tm); | ||
| 550 | if (in_time_t_range (t)) | ||
| 551 | { | ||
| 552 | *tp = tm; | ||
| 553 | return t; | ||
| 554 | } | ||
| 555 | else | ||
| 556 | { | ||
| 557 | __set_errno (EOVERFLOW); | ||
| 558 | return -1; | ||
| 559 | } | ||
| 560 | } | ||
| 561 | |||
| 544 | #endif | 562 | #endif |
| 545 | 563 | ||
| 546 | #ifdef _LIBC | 564 | weak_alias (mktime, timelocal) |
| 547 | libc_hidden_def (mktime) | 565 | libc_hidden_def (mktime) |
| 548 | libc_hidden_weak (timelocal) | 566 | libc_hidden_weak (timelocal) |
| 549 | #endif | ||
diff --git a/lib/timegm.c b/lib/timegm.c index 2ca57444d43..c440480cb2d 100644 --- a/lib/timegm.c +++ b/lib/timegm.c | |||
| @@ -18,17 +18,41 @@ | |||
| 18 | <http://www.gnu.org/licenses/>. */ | 18 | <http://www.gnu.org/licenses/>. */ |
| 19 | 19 | ||
| 20 | #ifndef _LIBC | 20 | #ifndef _LIBC |
| 21 | # include <config.h> | 21 | # include <libc-config.h> |
| 22 | #endif | 22 | #endif |
| 23 | 23 | ||
| 24 | #include <time.h> | 24 | #include <time.h> |
| 25 | #include <errno.h> | ||
| 25 | 26 | ||
| 26 | #include "mktime-internal.h" | 27 | #include "mktime-internal.h" |
| 27 | 28 | ||
| 28 | time_t | 29 | __time64_t |
| 29 | timegm (struct tm *tmp) | 30 | __timegm64 (struct tm *tmp) |
| 30 | { | 31 | { |
| 31 | static mktime_offset_t gmtime_offset; | 32 | static mktime_offset_t gmtime_offset; |
| 32 | tmp->tm_isdst = 0; | 33 | tmp->tm_isdst = 0; |
| 33 | return __mktime_internal (tmp, __gmtime_r, &gmtime_offset); | 34 | return __mktime_internal (tmp, __gmtime64_r, &gmtime_offset); |
| 34 | } | 35 | } |
| 36 | |||
| 37 | #if defined _LIBC && __TIMESIZE != 64 | ||
| 38 | |||
| 39 | libc_hidden_def (__timegm64) | ||
| 40 | |||
| 41 | time_t | ||
| 42 | timegm (struct tm *tmp) | ||
| 43 | { | ||
| 44 | struct tm tm = *tmp; | ||
| 45 | __time64_t t = __timegm64 (&tm); | ||
| 46 | if (in_time_t_range (t)) | ||
| 47 | { | ||
| 48 | *tmp = tm; | ||
| 49 | return t; | ||
| 50 | } | ||
| 51 | else | ||
| 52 | { | ||
| 53 | __set_errno (EOVERFLOW); | ||
| 54 | return -1; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | #endif | ||