diff options
| author | Paul Eggert | 2011-04-19 23:24:51 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-04-19 23:24:51 -0700 |
| commit | 8b9587d73b579fb2fdd0eaaa1ed5fd608653e522 (patch) | |
| tree | 2f0c598b1d7bfe1e08fdf7b36fce973d7cbd657e /src/data.c | |
| parent | 602ea69dc7a93969742958ee6af3feae23cd1e02 (diff) | |
| download | emacs-8b9587d73b579fb2fdd0eaaa1ed5fd608653e522.tar.gz emacs-8b9587d73b579fb2fdd0eaaa1ed5fd608653e522.zip | |
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 c9250a67bf0..c3ee3e39939 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/>. */ | |||
| 48 | 48 | ||
| 49 | #include <math.h> | 49 | #include <math.h> |
| 50 | 50 | ||
| 51 | #if !defined (atof) | ||
| 52 | extern double atof (const char *); | ||
| 53 | #endif /* !atof */ | ||
| 54 | |||
| 55 | Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; | 51 | Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; |
| 56 | static Lisp_Object Qsubr; | 52 | static Lisp_Object Qsubr; |
| 57 | Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; | 53 | 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. */) | |||
| 2415 | { | 2411 | { |
| 2416 | register char *p; | 2412 | register char *p; |
| 2417 | register int b; | 2413 | register int b; |
| 2418 | int sign = 1; | 2414 | EMACS_INT n; |
| 2419 | Lisp_Object val; | ||
| 2420 | 2415 | ||
| 2421 | CHECK_STRING (string); | 2416 | CHECK_STRING (string); |
| 2422 | 2417 | ||
| @@ -2430,38 +2425,23 @@ If the base used is not 10, STRING is always parsed as integer. */) | |||
| 2430 | xsignal1 (Qargs_out_of_range, base); | 2425 | xsignal1 (Qargs_out_of_range, base); |
| 2431 | } | 2426 | } |
| 2432 | 2427 | ||
| 2433 | /* Skip any whitespace at the front of the number. Some versions of | 2428 | /* Skip any whitespace at the front of the number. Typically strtol does |
| 2434 | atoi do this anyway, so we might as well make Emacs lisp consistent. */ | 2429 | this anyway, so we might as well be consistent. */ |
| 2435 | p = SSDATA (string); | 2430 | p = SSDATA (string); |
| 2436 | while (*p == ' ' || *p == '\t') | 2431 | while (*p == ' ' || *p == '\t') |
| 2437 | p++; | 2432 | p++; |
| 2438 | 2433 | ||
| 2439 | if (*p == '-') | 2434 | if (b == 10) |
| 2440 | { | ||
| 2441 | sign = -1; | ||
| 2442 | p++; | ||
| 2443 | } | ||
| 2444 | else if (*p == '+') | ||
| 2445 | p++; | ||
| 2446 | |||
| 2447 | if (isfloat_string (p, 1) && b == 10) | ||
| 2448 | val = make_float (sign * atof (p)); | ||
| 2449 | else | ||
| 2450 | { | 2435 | { |
| 2451 | double v = 0; | 2436 | Lisp_Object val = string_to_float (p, 1); |
| 2452 | 2437 | if (FLOATP (val)) | |
| 2453 | while (1) | 2438 | return val; |
| 2454 | { | ||
| 2455 | int digit = digit_to_number (*p++, b); | ||
| 2456 | if (digit < 0) | ||
| 2457 | break; | ||
| 2458 | v = v * b + digit; | ||
| 2459 | } | ||
| 2460 | |||
| 2461 | val = make_fixnum_or_float (sign * v); | ||
| 2462 | } | 2439 | } |
| 2463 | 2440 | ||
| 2464 | return val; | 2441 | n = strtol (p, NULL, b); |
| 2442 | if (FIXNUM_OVERFLOW_P (n)) | ||
| 2443 | xsignal (Qoverflow_error, list1 (string)); | ||
| 2444 | return make_number (n); | ||
| 2465 | } | 2445 | } |
| 2466 | 2446 | ||
| 2467 | 2447 | ||