From 1e8ae6ca237e22e11b3db63a01e558ad5a3d6ef3 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 7 Jul 2018 15:32:52 -0600 Subject: [PATCH] Make the reader accept bignums * src/data.c (Fstring_to_number): Update. * src/lisp.h (S2N_OVERFLOW_TO_FLOAT): Remove. * src/lread.c (free_contents): New function. (read_integer): Handle bignums. (read1): Update. (string_to_number): Handle bignums. (syms_of_lread): Remove read-integer-overflow-as-float. * src/process.c (Fsignal_process): Update. --- src/data.c | 3 +-- src/lisp.h | 2 +- src/lread.c | 66 +++++++++++++++++++++++++-------------------------- src/process.c | 2 +- 4 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/data.c b/src/data.c index efcffbbf6ab..8ffed8bbb52 100644 --- a/src/data.c +++ b/src/data.c @@ -2727,8 +2727,7 @@ If the base used is not 10, STRING is always parsed as an integer. */) while (*p == ' ' || *p == '\t') p++; - int flags = S2N_IGNORE_TRAILING | S2N_OVERFLOW_TO_FLOAT; - Lisp_Object val = string_to_number (p, b, flags); + Lisp_Object val = string_to_number (p, b, S2N_IGNORE_TRAILING); return NILP (val) ? make_fixnum (0) : val; } diff --git a/src/lisp.h b/src/lisp.h index 6a3db24949a..be679320494 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3858,7 +3858,7 @@ LOADHIST_ATTACH (Lisp_Object x) } extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object *, Lisp_Object, bool); -enum { S2N_IGNORE_TRAILING = 1, S2N_OVERFLOW_TO_FLOAT = 2 }; +enum { S2N_IGNORE_TRAILING = 1 }; extern Lisp_Object string_to_number (char const *, int, int); extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object), Lisp_Object); diff --git a/src/lread.c b/src/lread.c index 49fa51d1a80..ff86c96c9b5 100644 --- a/src/lread.c +++ b/src/lread.c @@ -2631,6 +2631,13 @@ digit_to_number (int character, int base) return digit < base ? digit : -1; } +static void +free_contents (void *p) +{ + void **ptr = (void **) p; + xfree (*ptr); +} + /* Read an integer in radix RADIX using READCHARFUN to read characters. RADIX must be in the interval [2..36]; if it isn't, a read error is signaled . Value is the integer read. Signals an @@ -2642,17 +2649,24 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) { /* Room for sign, leading 0, other digits, trailing null byte. Also, room for invalid syntax diagnostic. */ - char buf[max (1 + 1 + UINTMAX_WIDTH + 1, - sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))]; + size_t len = max (1 + 1 + UINTMAX_WIDTH + 1, + sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT)); + char *buf = NULL; char *p = buf; int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ + ptrdiff_t count = SPECPDL_INDEX (); + if (radix < 2 || radix > 36) valid = 0; else { int c, digit; + buf = xmalloc (len); + record_unwind_protect_ptr (free_contents, &buf); + p = buf; + c = READCHAR; if (c == '-' || c == '+') { @@ -2678,8 +2692,15 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) valid = 0; if (valid < 0) valid = 1; - if (p < buf + sizeof buf) - *p++ = c; + /* Allow 1 extra byte for the \0. */ + if (p + 1 == buf + len) + { + ptrdiff_t where = p - buf; + len *= 2; + buf = xrealloc (buf, len); + p = buf + where; + } + *p++ = c; c = READCHAR; } @@ -2692,14 +2713,8 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) invalid_syntax (buf); } - if (p == buf + sizeof buf) - { - memset (p - 3, '.', 3); - xsignal1 (Qoverflow_error, make_unibyte_string (buf, sizeof buf)); - } - *p = '\0'; - return string_to_number (buf, radix, 0); + return unbind_to (count, string_to_number (buf, radix, 0)); } @@ -3508,9 +3523,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) if (!quoted && !uninterned_symbol) { - int flags = (read_integer_overflow_as_float - ? S2N_OVERFLOW_TO_FLOAT : 0); - Lisp_Object result = string_to_number (read_buffer, 10, flags); + Lisp_Object result = string_to_number (read_buffer, 10, 0); if (! NILP (result)) return unbind_to (count, result); } @@ -3677,12 +3690,10 @@ substitute_in_interval (INTERVAL interval, void *arg) /* Convert STRING to a number, assuming base BASE. When STRING has floating point syntax and BASE is 10, return a nearest float. When - STRING has integer syntax, return a fixnum if the integer fits, and - signal an overflow otherwise (unless BASE is 10 and STRING ends in - period or FLAGS & S2N_OVERFLOW_TO_FLOAT is nonzero; in this case, - return a nearest float instead). Otherwise, return nil. If FLAGS - & S2N_IGNORE_TRAILING is nonzero, consider just the longest prefix - of STRING that has valid syntax. */ + STRING has integer syntax, return a fixnum if the integer fits, or + else a bignum. Otherwise, return nil. If FLAGS & + S2N_IGNORE_TRAILING is nonzero, consider just the longest prefix of + STRING that has valid syntax. */ Lisp_Object string_to_number (char const *string, int base, int flags) @@ -3796,13 +3807,7 @@ string_to_number (char const *string, int base, int flags) else value = n; - if (! (state & DOT_CHAR) && ! (flags & S2N_OVERFLOW_TO_FLOAT)) - { - AUTO_STRING (fmt, ("%s is out of fixnum range; " - "maybe set `read-integer-overflow-as-float'?")); - AUTO_STRING_WITH_LEN (arg, string, cp - string); - xsignal1 (Qoverflow_error, CALLN (Fformat_message, fmt, arg)); - } + return make_bignum_str (string, base); } /* Either the number uses float syntax, or it does not fit into a fixnum. @@ -4845,13 +4850,6 @@ were read in. */); doc: /* Non-nil means read recursive structures using #N= and #N# syntax. */); Vread_circle = Qt; - DEFVAR_BOOL ("read-integer-overflow-as-float", - read_integer_overflow_as_float, - doc: /* Non-nil means `read' quietly treats an out-of-range integer as floating point. -Nil (the default) means signal an overflow unless the integer ends in `.'. -This variable is experimental; email 30408@debbugs.gnu.org if you need it. */); - read_integer_overflow_as_float = false; - DEFVAR_LISP ("load-path", Vload_path, doc: /* List of directories to search for files to load. Each element is a string (directory file name) or nil (meaning diff --git a/src/process.c b/src/process.c index 10af79a0155..350cfe0f80b 100644 --- a/src/process.c +++ b/src/process.c @@ -6842,7 +6842,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) { Lisp_Object tem = Fget_process (process); if (NILP (tem)) - tem = string_to_number (SSDATA (process), 10, S2N_OVERFLOW_TO_FLOAT); + tem = string_to_number (SSDATA (process), 10, 0); process = tem; } else if (!FIXED_OR_FLOATP (process)) -- 2.39.2