diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2019-01-01 11:33:10 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2019-01-01 11:33:37 -0800 |
commit | 227343947f083e1094ebd3770f774b480beb2590 (patch) | |
tree | 54c05f6690abbe94c80426c36ebe64231b275da7 | |
parent | 355b1c3cb91a226d1f58098944542142eddccb60 (diff) | |
download | emacs-227343947f083e1094ebd3770f774b480beb2590.tar.gz |
decode-time: allow bignum years
* src/timefns.c (TM_YEAR_BASE):
Now a constant as it need not be a macro.
(Fdecode_time): Do not signal an overflow merely because the
Gregorian year number does not fix in a fixnum (which can
happen on hosts with 64-bit time_t and with 32-bit int and
EMACS_INT).
-rw-r--r-- | src/timefns.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/timefns.c b/src/timefns.c index 437b5b22131..4c99fe58061 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -44,7 +44,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ # define HAVE_TZALLOC_BUG false #endif -#define TM_YEAR_BASE 1900 +enum { TM_YEAR_BASE = 1900 }; #ifndef HAVE_TM_GMTOFF # define HAVE_TM_GMTOFF false @@ -1336,12 +1336,22 @@ usage: (decode-time &optional TIME ZONE) */) if (!tm) time_error (localtime_errno); - if (! (MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year - && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)) - time_overflow (); - /* Avoid overflow when INT_MAX < EMACS_INT_MAX. */ - EMACS_INT tm_year_base = TM_YEAR_BASE; + Lisp_Object year; + if (FASTER_TIMEFNS + && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year + && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE) + { + /* Avoid overflow when INT_MAX - TM_YEAR_BASE < local_tm.tm_year. */ + EMACS_INT tm_year_base = TM_YEAR_BASE; + year = make_fixnum (local_tm.tm_year + tm_year_base); + } + else + { + mpz_set_si (mpz[0], local_tm.tm_year); + mpz_add_ui (mpz[0], mpz[0], TM_YEAR_BASE); + year = make_integer_mpz (); + } return CALLN (Flist, make_fixnum (local_tm.tm_sec), @@ -1349,7 +1359,7 @@ usage: (decode-time &optional TIME ZONE) */) make_fixnum (local_tm.tm_hour), make_fixnum (local_tm.tm_mday), make_fixnum (local_tm.tm_mon + 1), - make_fixnum (local_tm.tm_year + tm_year_base), + year, make_fixnum (local_tm.tm_wday), (local_tm.tm_isdst < 0 ? make_fixnum (-1) : local_tm.tm_isdst == 0 ? Qnil : Qt), @@ -1360,7 +1370,7 @@ usage: (decode-time &optional TIME ZONE) */) : Qnil)); } -/* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that +/* Return OBJ - OFFSET, checking that OBJ is a valid integer and that the result is representable as an int. 0 <= OFFSET <= TM_YEAR_BASE. */ static int check_tm_member (Lisp_Object obj, int offset) |