diff options
author | Paul Eggert <[email protected]> | 2011-04-19 23:24:51 -0700 |
---|---|---|
committer | Paul Eggert <[email protected]> | 2011-04-19 23:24:51 -0700 |
commit | 8b9587d73b579fb2fdd0eaaa1ed5fd608653e522 (patch) | |
tree | 2f0c598b1d7bfe1e08fdf7b36fce973d7cbd657e /src/data.c | |
parent | 602ea69dc7a93969742958ee6af3feae23cd1e02 (diff) |
Make the Lisp reader and string-to-float more consistent.
* data.c (atof): Remove decl; no longer used or needed.
(Fstring_to_number): Use new string_to_float function, to be
consistent with how the Lisp reader treats infinities and NaNs.
Do not assume that floating-point numbers represent EMACS_INT
without losing information; this is not true on most 64-bit hosts.
Avoid double-rounding errors, by insisting on integers when
parsing non-base-10 numbers, as the documentation specifies.
Report integer overflow instead of silently converting to
integers.
* lisp.h (string_to_float): New decl, replacing ...
(isfloat_string): Remove.
* lread.c (read1): Do not accept +. and -. as integers; this
appears to have been a coding error. Similarly, do not accept
strings like +-1e0 as floating point numbers. Do not report
overflow for some integer overflows and not others; instead,
report them all. Break out the floating-point parsing into a new
function string_to_float, so that Fstring_to_number parses
floating point numbers consistently with the Lisp reader.
(string_to_float): New function, replacing isfloat_string.
This function checks for valid syntax and produces the resulting
Lisp float number too.
Diffstat (limited to 'src/data.c')
-rw-r--r-- | src/data.c | 42 |
1 files changed, 11 insertions, 31 deletions
diff --git a/src/data.c b/src/data.c index c9250a67bf..c3ee3e3993 100644 --- a/src/data.c +++ b/src/data.c @@ -48,10 +48,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <math.h> -#if !defined (atof) -extern double atof (const char *); -#endif /* !atof */ - Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; static Lisp_Object Qsubr; Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; @@ -2415,8 +2411,7 @@ If the base used is not 10, STRING is always parsed as integer. */) { register char *p; register int b; - int sign = 1; - Lisp_Object val; + EMACS_INT n; CHECK_STRING (string); @@ -2430,38 +2425,23 @@ If the base used is not 10, STRING is always parsed as integer. */) xsignal1 (Qargs_out_of_range, base); } - /* Skip any whitespace at the front of the number. Some versions of - atoi do this anyway, so we might as well make Emacs lisp consistent. */ + /* Skip any whitespace at the front of the number. Typically strtol does + this anyway, so we might as well be consistent. */ p = SSDATA (string); while (*p == ' ' || *p == '\t') p++; - if (*p == '-') - { - sign = -1; - p++; - } - else if (*p == '+') - p++; - - if (isfloat_string (p, 1) && b == 10) - val = make_float (sign * atof (p)); - else + if (b == 10) { - double v = 0; - - while (1) - { - int digit = digit_to_number (*p++, b); - if (digit < 0) - break; - v = v * b + digit; - } - - val = make_fixnum_or_float (sign * v); + Lisp_Object val = string_to_float (p, 1); + if (FLOATP (val)) + return val; } - return val; + n = strtol (p, NULL, b); + if (FIXNUM_OVERFLOW_P (n)) + xsignal (Qoverflow_error, list1 (string)); + return make_number (n); } |