aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPaul Eggert <[email protected]>2011-04-19 23:24:51 -0700
committerPaul Eggert <[email protected]>2011-04-19 23:24:51 -0700
commit8b9587d73b579fb2fdd0eaaa1ed5fd608653e522 (patch)
tree2f0c598b1d7bfe1e08fdf7b36fce973d7cbd657e /src/data.c
parent602ea69dc7a93969742958ee6af3feae23cd1e02 (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.c42
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);
}