aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2023-07-13 14:26:29 -0700
committerPaul Eggert2023-07-13 14:43:03 -0700
commit0cd519971d199836ba0a6e9f0e36af9b9accaf0d (patch)
treeadf49dde9f863b4e1ce00a9c37dfd1a761a98a7a /src
parentb94e7e6334718061879c32025941f00913078230 (diff)
downloademacs-0cd519971d199836ba0a6e9f0e36af9b9accaf0d.tar.gz
emacs-0cd519971d199836ba0a6e9f0e36af9b9accaf0d.zip
Port NaN, infinity handling better to VAX
Nowadays .elc files routinely contain tokens like 1.0e+INF and 0.0e+NaN that do not work on antiques like the VAX that lack IEEE fp. Port Emacs to these platforms, by treating infinities as extreme values and NaNs as strings that trap if used numerically. * src/lread.c (INFINITY): Default to HUGE_VAL if non-IEEE. (not_a_number) [!IEEE_FLOATING_POINT]: New static array. (syms_of_lread) [!IEEE_FLOATING_POINT]: Initialize it. (read0): Report invalid syntax for +0.0e+NaN on platforms that lack NaNs. (string_to_number): On non-IEEE platforms, return HUGE_VAL for infinity and a string for NaN. All callers changed.
Diffstat (limited to 'src')
-rw-r--r--src/data.c3
-rw-r--r--src/lread.c29
-rw-r--r--src/process.c3
3 files changed, 30 insertions, 5 deletions
diff --git a/src/data.c b/src/data.c
index 6de8e0cf1a1..5a31462d8ca 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3033,7 +3033,8 @@ If the base used is not 10, STRING is always parsed as an integer. */)
3033 p++; 3033 p++;
3034 3034
3035 Lisp_Object val = string_to_number (p, b, 0); 3035 Lisp_Object val = string_to_number (p, b, 0);
3036 return NILP (val) ? make_fixnum (0) : val; 3036 return ((IEEE_FLOATING_POINT ? NILP (val) : !NUMBERP (val))
3037 ? make_fixnum (0) : val);
3037} 3038}
3038 3039
3039enum arithop 3040enum arithop
diff --git a/src/lread.c b/src/lread.c
index 51d0d2a3c24..6792ef27206 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -75,6 +75,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
75# ifndef INFINITY 75# ifndef INFINITY
76# define INFINITY ((union ieee754_double) {.ieee = {.exponent = -1}}.d) 76# define INFINITY ((union ieee754_double) {.ieee = {.exponent = -1}}.d)
77# endif 77# endif
78#else
79# ifndef INFINITY
80# define INFINITY HUGE_VAL
81# endif
78#endif 82#endif
79 83
80/* The objects or placeholders read with the #n=object form. 84/* The objects or placeholders read with the #n=object form.
@@ -4477,10 +4481,17 @@ substitute_in_interval (INTERVAL interval, void *arg)
4477} 4481}
4478 4482
4479 4483
4484#if !IEEE_FLOATING_POINT
4485/* Strings that stand in for +NaN, -NaN, respectively. */
4486static Lisp_Object not_a_number[2];
4487#endif
4488
4480/* Convert the initial prefix of STRING to a number, assuming base BASE. 4489/* Convert the initial prefix of STRING to a number, assuming base BASE.
4481 If the prefix has floating point syntax and BASE is 10, return a 4490 If the prefix has floating point syntax and BASE is 10, return a
4482 nearest float; otherwise, if the prefix has integer syntax, return 4491 nearest float; otherwise, if the prefix has integer syntax, return
4483 the integer; otherwise, return nil. If PLEN, set *PLEN to the 4492 the integer; otherwise, return nil. (On antique platforms that lack
4493 support for NaNs, if the prefix has NaN syntax return a Lisp object that
4494 will provoke an error if used as a number.) If PLEN, set *PLEN to the
4484 length of the numeric prefix if there is one, otherwise *PLEN is 4495 length of the numeric prefix if there is one, otherwise *PLEN is
4485 unspecified. */ 4496 unspecified. */
4486 4497
@@ -4545,7 +4556,6 @@ string_to_number (char const *string, int base, ptrdiff_t *plen)
4545 cp++; 4556 cp++;
4546 while ('0' <= *cp && *cp <= '9'); 4557 while ('0' <= *cp && *cp <= '9');
4547 } 4558 }
4548#if IEEE_FLOATING_POINT
4549 else if (cp[-1] == '+' 4559 else if (cp[-1] == '+'
4550 && cp[0] == 'I' && cp[1] == 'N' && cp[2] == 'F') 4560 && cp[0] == 'I' && cp[1] == 'N' && cp[2] == 'F')
4551 { 4561 {
@@ -4558,12 +4568,17 @@ string_to_number (char const *string, int base, ptrdiff_t *plen)
4558 { 4568 {
4559 state |= E_EXP; 4569 state |= E_EXP;
4560 cp += 3; 4570 cp += 3;
4571#if IEEE_FLOATING_POINT
4561 union ieee754_double u 4572 union ieee754_double u
4562 = { .ieee_nan = { .exponent = 0x7ff, .quiet_nan = 1, 4573 = { .ieee_nan = { .exponent = 0x7ff, .quiet_nan = 1,
4563 .mantissa0 = n >> 31 >> 1, .mantissa1 = n }}; 4574 .mantissa0 = n >> 31 >> 1, .mantissa1 = n }};
4564 value = u.d; 4575 value = u.d;
4565 } 4576#else
4577 if (plen)
4578 *plen = cp - string;
4579 return not_a_number[negative];
4566#endif 4580#endif
4581 }
4567 else 4582 else
4568 cp = ecp; 4583 cp = ecp;
4569 } 4584 }
@@ -5707,6 +5722,14 @@ that are loaded before your customizations are read! */);
5707 DEFSYM (Qcomma, ","); 5722 DEFSYM (Qcomma, ",");
5708 DEFSYM (Qcomma_at, ",@"); 5723 DEFSYM (Qcomma_at, ",@");
5709 5724
5725#if !IEEE_FLOATING_POINT
5726 for (int negative = 0; negative < 2; negative++)
5727 {
5728 not_a_number[negative] = build_pure_c_string (&"-0.0e+NaN"[!negative]);
5729 staticpro (&not_a_number[negative]);
5730 }
5731#endif
5732
5710 DEFSYM (Qinhibit_file_name_operation, "inhibit-file-name-operation"); 5733 DEFSYM (Qinhibit_file_name_operation, "inhibit-file-name-operation");
5711 DEFSYM (Qascii_character, "ascii-character"); 5734 DEFSYM (Qascii_character, "ascii-character");
5712 DEFSYM (Qfunction, "function"); 5735 DEFSYM (Qfunction, "function");
diff --git a/src/process.c b/src/process.c
index 67d1d3e425f..2d6e08f16b5 100644
--- a/src/process.c
+++ b/src/process.c
@@ -7130,7 +7130,8 @@ See function `signal-process' for more details on usage. */)
7130 { 7130 {
7131 ptrdiff_t len; 7131 ptrdiff_t len;
7132 tem = string_to_number (SSDATA (process), 10, &len); 7132 tem = string_to_number (SSDATA (process), 10, &len);
7133 if (NILP (tem) || len != SBYTES (process)) 7133 if ((IEEE_FLOATING_POINT ? NILP (tem) : !NUMBERP (tem))
7134 || len != SBYTES (process))
7134 return Qnil; 7135 return Qnil;
7135 } 7136 }
7136 process = tem; 7137 process = tem;