diff src/lread.c @ 104658:7b5e19f7e726

(read_integer): Use doubles (and potentially return a float number) as we do in string-to-number. (read1): Use strtol to read integers, signal errors on strtol's overflow and use floats if strtol's output is too large for Elisp integers.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Thu, 27 Aug 2009 21:10:17 +0000
parents d4c5482e3aa4
children 51dc0c10fa2c
line wrap: on
line diff
--- a/src/lread.c	Thu Aug 27 20:10:56 2009 +0000
+++ b/src/lread.c	Thu Aug 27 21:10:17 2009 +0000
@@ -2258,7 +2258,8 @@
      int radix;
 {
   int ndigits = 0, invalid_p, c, sign = 0;
-  EMACS_INT number = 0;
+  /* We use a floating point number because  */
+  double number = 0;
 
   if (radix < 2 || radix > 36)
     invalid_p = 1;
@@ -2308,7 +2309,7 @@
       invalid_syntax (buf, 0);
     }
 
-  return make_number (sign * number);
+  return make_fixnum_or_float (sign * number);
 }
 
 
@@ -2372,7 +2373,6 @@
 	      Lisp_Object ht;
 	      Lisp_Object key = Qnil;
 	      int param_count = 0;
-	      int i;
 	      
 	      if (!EQ (head, Qhash_table))
 		error ("Invalid extended read marker at head of #s list "
@@ -3002,7 +3002,6 @@
 	if (!quoted && !uninterned_symbol)
 	  {
 	    register char *p1;
-	    register Lisp_Object val;
 	    p1 = read_buffer;
 	    if (*p1 == '+' || *p1 == '-') p1++;
 	    /* Is it an integer? */
@@ -3016,15 +3015,21 @@
 		  {
 		    if (p1[-1] == '.')
 		      p1[-1] = '\0';
-		    /* Fixme: if we have strtol, use that, and check
-		       for overflow.  */
-		    if (sizeof (int) == sizeof (EMACS_INT))
-		      XSETINT (val, atoi (read_buffer));
-		    else if (sizeof (long) == sizeof (EMACS_INT))
-		      XSETINT (val, atol (read_buffer));
-		    else
-		      abort ();
-		    return val;
+		    {
+		      /* EMACS_INT n = atol (read_buffer); */
+		      char *endptr = NULL;
+		      EMACS_INT n = (errno = 0,
+				     strtol (read_buffer, &endptr, 10));
+		      if (errno == ERANGE && endptr)
+			{
+			  Lisp_Object args
+			    = Fcons (make_string (read_buffer,
+						  endptr - read_buffer),
+				     Qnil);
+			  xsignal (Qoverflow_error, args);
+			}
+		      return make_fixnum_or_float (n);
+		    }
 		  }
 	      }
 	    if (isfloat_string (read_buffer))