Mercurial > hg > xemacs-beta
diff src/print.c @ 5904:ee27ca517e90
Revise print_symbol(), never calling is{float,ratio}_string().
src/ChangeLog addition:
2015-05-08 Aidan Kehoe <kehoea@parhasard.net>
* print.c (print_symbol):
Revise this. No longer call isfloat_string() and isratio_string()
on practically every symbol seen; check explicitly for the known
float format in this function, which turns out to be a more
limited and cheap job than you would think.
Also check for integer and ratio syntax in passing.
Use Vdigit_fixnum_map when working out whether a given character
is a digit.
* lisp.h:
Make Vdigit_fixnum_map available generally.
tests/ChangeLog addition:
2015-05-08 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-reader-tests.el:
Check read and print handling of symbols that look like
numbers. In passing, check the read and print handling of the
associated numbers.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Fri, 08 May 2015 14:33:46 +0100 |
parents | acf1c26e3019 |
children |
line wrap: on
line diff
--- a/src/print.c Fri May 08 13:58:22 2015 +0100 +++ b/src/print.c Fri May 08 14:33:46 2015 +0100 @@ -2563,51 +2563,97 @@ return; } + if (0 == size) + { + /* Compatible with GNU, but not with Common Lisp, where the syntax + for this symbol is ||. */ + write_ascstring (printcharfun, + (print_gensym && !IN_OBARRAY (obj)) ? "#:" : "##"); + return; + } + GCPRO2 (obj, printcharfun); if (print_gensym && !IN_OBARRAY (obj)) { write_ascstring (printcharfun, "#:"); } - else if (0 == size) - { - /* Compatible with GNU, but not with Common Lisp, where the syntax for - this symbol is ||. */ - write_ascstring (printcharfun, "##"); - } - - /* Does it look like an integer or a float? */ + + /* Does it look like a rational or a float? */ { - Ibyte *data = XSTRING_DATA (name); - Bytecount confusing = 0; - - if (size == 0) - goto not_yet_confused; /* Really confusing */ - else if (isdigit (data[0])) - confusing = 0; - else if (size == 1) - goto not_yet_confused; - else if (data[0] == '-' || data[0] == '+') - confusing = 1; - else - goto not_yet_confused; - - for (; confusing < size; confusing++) + Ibyte *data = XSTRING_DATA (name), *pend = data + XSTRING_LENGTH (name); + Fixnum nondigits = 0, fixval = -1; + Boolint confusing = 1; + Ichar cc = itext_ichar (data); + Lisp_Object got = Qnil; + + if (cc == '-' || cc == '+') { - if (!isdigit (data[confusing]) && '/' != data[confusing]) + INC_IBYTEPTR (data); + if (data == pend) { confusing = 0; - break; } } - not_yet_confused: - - if (!confusing) - /* #### Ugh, this is needlessly complex and slow for what we - need here. It might be a good idea to copy equivalent code - from FSF. --hniksic */ - confusing = isfloat_string ((char *) data) - || isratio_string ((char *) data); + + /* No need to check for '.' when working out whether the symbol looks like + a number, '.' will get a backslash on printing no matter what, + disqualifying it from being a number when read. */ + while (confusing && data < pend) + { + cc = itext_ichar (data); + + switch (cc) + { + /* A symbol like 2e10 cound be confused with a float: */ + case 'e': + case 'E': + /* As can one like 123/456: */ + case '/': + nondigits++; + confusing = nondigits < 2 + /* If it starts with an E or a slash, that's fine, it can't be a + float. */ + && data != XSTRING_DATA (name) + /* And if it ends with an e or a slash that's fine too. */ + && (data + itext_ichar_len (data)) != pend; + break; + + /* There can be a sign in the exponent. Such a sign needs to be + directly after an e and to have trailing digits after it to be + valid float syntax. */ + case '+': + case '-': + confusing = (1 == nondigits) + && data != XSTRING_DATA (name) + && (data + itext_ichar_len (data)); + if (confusing) + { + Ibyte *lastp = data; + Ichar clast; + + DEC_IBYTEPTR (lastp); + clast = itext_ichar (lastp); + + confusing = clast == 'E' || clast == 'e'; + } + break; + + /* A symbol that is all decimal digits could be confused with an + integer: */ + default: + got = get_char_table (cc, Vdigit_fixnum_map); + fixval = FIXNUMP (got) ? XREALFIXNUM (got) : -1; + if (fixval < 0 || fixval > 9) + { + confusing = 0; + } + break; + } + + INC_IBYTEPTR (data); + } + if (confusing) write_ascstring (printcharfun, "\\"); } @@ -2618,6 +2664,9 @@ for (i = 0; i < size; i++) { + /* In the event that we adopt a non-ASCII-compatible internal format, + this will no longer be Mule-safe. As of May 2015, that is very, + very unlikely. */ switch (string_byte (name, i)) { case 0: case 1: case 2: case 3: