aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Tromey2018-07-07 15:32:52 -0600
committerTom Tromey2018-07-12 22:12:27 -0600
commit1e8ae6ca237e22e11b3db63a01e558ad5a3d6ef3 (patch)
treea8fabadc647288ce253d2813b8074c5b903b52b8
parent580d173b9a7db78f6d62972ef8e943d31dde5c9d (diff)
downloademacs-1e8ae6ca237e22e11b3db63a01e558ad5a3d6ef3.tar.gz
emacs-1e8ae6ca237e22e11b3db63a01e558ad5a3d6ef3.zip
Make the reader accept bignums
* src/data.c (Fstring_to_number): Update. * src/lisp.h (S2N_OVERFLOW_TO_FLOAT): Remove. * src/lread.c (free_contents): New function. (read_integer): Handle bignums. (read1): Update. (string_to_number): Handle bignums. (syms_of_lread): Remove read-integer-overflow-as-float. * src/process.c (Fsignal_process): Update.
-rw-r--r--src/data.c3
-rw-r--r--src/lisp.h2
-rw-r--r--src/lread.c66
-rw-r--r--src/process.c2
4 files changed, 35 insertions, 38 deletions
diff --git a/src/data.c b/src/data.c
index efcffbbf6ab..8ffed8bbb52 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2727,8 +2727,7 @@ If the base used is not 10, STRING is always parsed as an integer. */)
2727 while (*p == ' ' || *p == '\t') 2727 while (*p == ' ' || *p == '\t')
2728 p++; 2728 p++;
2729 2729
2730 int flags = S2N_IGNORE_TRAILING | S2N_OVERFLOW_TO_FLOAT; 2730 Lisp_Object val = string_to_number (p, b, S2N_IGNORE_TRAILING);
2731 Lisp_Object val = string_to_number (p, b, flags);
2732 return NILP (val) ? make_fixnum (0) : val; 2731 return NILP (val) ? make_fixnum (0) : val;
2733} 2732}
2734 2733
diff --git a/src/lisp.h b/src/lisp.h
index 6a3db24949a..be679320494 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3858,7 +3858,7 @@ LOADHIST_ATTACH (Lisp_Object x)
3858} 3858}
3859extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, 3859extern int openp (Lisp_Object, Lisp_Object, Lisp_Object,
3860 Lisp_Object *, Lisp_Object, bool); 3860 Lisp_Object *, Lisp_Object, bool);
3861enum { S2N_IGNORE_TRAILING = 1, S2N_OVERFLOW_TO_FLOAT = 2 }; 3861enum { S2N_IGNORE_TRAILING = 1 };
3862extern Lisp_Object string_to_number (char const *, int, int); 3862extern Lisp_Object string_to_number (char const *, int, int);
3863extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object), 3863extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object),
3864 Lisp_Object); 3864 Lisp_Object);
diff --git a/src/lread.c b/src/lread.c
index 49fa51d1a80..ff86c96c9b5 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2631,6 +2631,13 @@ digit_to_number (int character, int base)
2631 return digit < base ? digit : -1; 2631 return digit < base ? digit : -1;
2632} 2632}
2633 2633
2634static void
2635free_contents (void *p)
2636{
2637 void **ptr = (void **) p;
2638 xfree (*ptr);
2639}
2640
2634/* Read an integer in radix RADIX using READCHARFUN to read 2641/* Read an integer in radix RADIX using READCHARFUN to read
2635 characters. RADIX must be in the interval [2..36]; if it isn't, a 2642 characters. RADIX must be in the interval [2..36]; if it isn't, a
2636 read error is signaled . Value is the integer read. Signals an 2643 read error is signaled . Value is the integer read. Signals an
@@ -2642,17 +2649,24 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
2642{ 2649{
2643 /* Room for sign, leading 0, other digits, trailing null byte. 2650 /* Room for sign, leading 0, other digits, trailing null byte.
2644 Also, room for invalid syntax diagnostic. */ 2651 Also, room for invalid syntax diagnostic. */
2645 char buf[max (1 + 1 + UINTMAX_WIDTH + 1, 2652 size_t len = max (1 + 1 + UINTMAX_WIDTH + 1,
2646 sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))]; 2653 sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT));
2654 char *buf = NULL;
2647 char *p = buf; 2655 char *p = buf;
2648 int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ 2656 int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */
2649 2657
2658 ptrdiff_t count = SPECPDL_INDEX ();
2659
2650 if (radix < 2 || radix > 36) 2660 if (radix < 2 || radix > 36)
2651 valid = 0; 2661 valid = 0;
2652 else 2662 else
2653 { 2663 {
2654 int c, digit; 2664 int c, digit;
2655 2665
2666 buf = xmalloc (len);
2667 record_unwind_protect_ptr (free_contents, &buf);
2668 p = buf;
2669
2656 c = READCHAR; 2670 c = READCHAR;
2657 if (c == '-' || c == '+') 2671 if (c == '-' || c == '+')
2658 { 2672 {
@@ -2678,8 +2692,15 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
2678 valid = 0; 2692 valid = 0;
2679 if (valid < 0) 2693 if (valid < 0)
2680 valid = 1; 2694 valid = 1;
2681 if (p < buf + sizeof buf) 2695 /* Allow 1 extra byte for the \0. */
2682 *p++ = c; 2696 if (p + 1 == buf + len)
2697 {
2698 ptrdiff_t where = p - buf;
2699 len *= 2;
2700 buf = xrealloc (buf, len);
2701 p = buf + where;
2702 }
2703 *p++ = c;
2683 c = READCHAR; 2704 c = READCHAR;
2684 } 2705 }
2685 2706
@@ -2692,14 +2713,8 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
2692 invalid_syntax (buf); 2713 invalid_syntax (buf);
2693 } 2714 }
2694 2715
2695 if (p == buf + sizeof buf)
2696 {
2697 memset (p - 3, '.', 3);
2698 xsignal1 (Qoverflow_error, make_unibyte_string (buf, sizeof buf));
2699 }
2700
2701 *p = '\0'; 2716 *p = '\0';
2702 return string_to_number (buf, radix, 0); 2717 return unbind_to (count, string_to_number (buf, radix, 0));
2703} 2718}
2704 2719
2705 2720
@@ -3508,9 +3523,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
3508 3523
3509 if (!quoted && !uninterned_symbol) 3524 if (!quoted && !uninterned_symbol)
3510 { 3525 {
3511 int flags = (read_integer_overflow_as_float 3526 Lisp_Object result = string_to_number (read_buffer, 10, 0);
3512 ? S2N_OVERFLOW_TO_FLOAT : 0);
3513 Lisp_Object result = string_to_number (read_buffer, 10, flags);
3514 if (! NILP (result)) 3527 if (! NILP (result))
3515 return unbind_to (count, result); 3528 return unbind_to (count, result);
3516 } 3529 }
@@ -3677,12 +3690,10 @@ substitute_in_interval (INTERVAL interval, void *arg)
3677 3690
3678/* Convert STRING to a number, assuming base BASE. When STRING has 3691/* Convert STRING to a number, assuming base BASE. When STRING has
3679 floating point syntax and BASE is 10, return a nearest float. When 3692 floating point syntax and BASE is 10, return a nearest float. When
3680 STRING has integer syntax, return a fixnum if the integer fits, and 3693 STRING has integer syntax, return a fixnum if the integer fits, or
3681 signal an overflow otherwise (unless BASE is 10 and STRING ends in 3694 else a bignum. Otherwise, return nil. If FLAGS &
3682 period or FLAGS & S2N_OVERFLOW_TO_FLOAT is nonzero; in this case, 3695 S2N_IGNORE_TRAILING is nonzero, consider just the longest prefix of
3683 return a nearest float instead). Otherwise, return nil. If FLAGS 3696 STRING that has valid syntax. */
3684 & S2N_IGNORE_TRAILING is nonzero, consider just the longest prefix
3685 of STRING that has valid syntax. */
3686 3697
3687Lisp_Object 3698Lisp_Object
3688string_to_number (char const *string, int base, int flags) 3699string_to_number (char const *string, int base, int flags)
@@ -3796,13 +3807,7 @@ string_to_number (char const *string, int base, int flags)
3796 else 3807 else
3797 value = n; 3808 value = n;
3798 3809
3799 if (! (state & DOT_CHAR) && ! (flags & S2N_OVERFLOW_TO_FLOAT)) 3810 return make_bignum_str (string, base);
3800 {
3801 AUTO_STRING (fmt, ("%s is out of fixnum range; "
3802 "maybe set `read-integer-overflow-as-float'?"));
3803 AUTO_STRING_WITH_LEN (arg, string, cp - string);
3804 xsignal1 (Qoverflow_error, CALLN (Fformat_message, fmt, arg));
3805 }
3806 } 3811 }
3807 3812
3808 /* Either the number uses float syntax, or it does not fit into a fixnum. 3813 /* Either the number uses float syntax, or it does not fit into a fixnum.
@@ -4845,13 +4850,6 @@ were read in. */);
4845 doc: /* Non-nil means read recursive structures using #N= and #N# syntax. */); 4850 doc: /* Non-nil means read recursive structures using #N= and #N# syntax. */);
4846 Vread_circle = Qt; 4851 Vread_circle = Qt;
4847 4852
4848 DEFVAR_BOOL ("read-integer-overflow-as-float",
4849 read_integer_overflow_as_float,
4850 doc: /* Non-nil means `read' quietly treats an out-of-range integer as floating point.
4851Nil (the default) means signal an overflow unless the integer ends in `.'.
4852This variable is experimental; email 30408@debbugs.gnu.org if you need it. */);
4853 read_integer_overflow_as_float = false;
4854
4855 DEFVAR_LISP ("load-path", Vload_path, 4853 DEFVAR_LISP ("load-path", Vload_path,
4856 doc: /* List of directories to search for files to load. 4854 doc: /* List of directories to search for files to load.
4857Each element is a string (directory file name) or nil (meaning 4855Each element is a string (directory file name) or nil (meaning
diff --git a/src/process.c b/src/process.c
index 10af79a0155..350cfe0f80b 100644
--- a/src/process.c
+++ b/src/process.c
@@ -6842,7 +6842,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */)
6842 { 6842 {
6843 Lisp_Object tem = Fget_process (process); 6843 Lisp_Object tem = Fget_process (process);
6844 if (NILP (tem)) 6844 if (NILP (tem))
6845 tem = string_to_number (SSDATA (process), 10, S2N_OVERFLOW_TO_FLOAT); 6845 tem = string_to_number (SSDATA (process), 10, 0);
6846 process = tem; 6846 process = tem;
6847 } 6847 }
6848 else if (!FIXED_OR_FLOATP (process)) 6848 else if (!FIXED_OR_FLOATP (process))