aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPaul Eggert2011-04-19 23:24:51 -0700
committerPaul Eggert2011-04-19 23:24:51 -0700
commit8b9587d73b579fb2fdd0eaaa1ed5fd608653e522 (patch)
tree2f0c598b1d7bfe1e08fdf7b36fce973d7cbd657e /src/data.c
parent602ea69dc7a93969742958ee6af3feae23cd1e02 (diff)
downloademacs-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.c42
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)
52extern double atof (const char *);
53#endif /* !atof */
54
55Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; 51Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
56static Lisp_Object Qsubr; 52static Lisp_Object Qsubr;
57Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; 53Lisp_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