Mercurial > hg > xemacs-beta
comparison 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 |
comparison
equal
deleted
inserted
replaced
5903:5afddd952c46 | 5904:ee27ca517e90 |
---|---|
2561 /* This deals with GC-relocation */ | 2561 /* This deals with GC-relocation */ |
2562 output_string (printcharfun, 0, name, 0, size); | 2562 output_string (printcharfun, 0, name, 0, size); |
2563 return; | 2563 return; |
2564 } | 2564 } |
2565 | 2565 |
2566 if (0 == size) | |
2567 { | |
2568 /* Compatible with GNU, but not with Common Lisp, where the syntax | |
2569 for this symbol is ||. */ | |
2570 write_ascstring (printcharfun, | |
2571 (print_gensym && !IN_OBARRAY (obj)) ? "#:" : "##"); | |
2572 return; | |
2573 } | |
2574 | |
2566 GCPRO2 (obj, printcharfun); | 2575 GCPRO2 (obj, printcharfun); |
2567 | 2576 |
2568 if (print_gensym && !IN_OBARRAY (obj)) | 2577 if (print_gensym && !IN_OBARRAY (obj)) |
2569 { | 2578 { |
2570 write_ascstring (printcharfun, "#:"); | 2579 write_ascstring (printcharfun, "#:"); |
2571 } | 2580 } |
2572 else if (0 == size) | 2581 |
2573 { | 2582 /* Does it look like a rational or a float? */ |
2574 /* Compatible with GNU, but not with Common Lisp, where the syntax for | |
2575 this symbol is ||. */ | |
2576 write_ascstring (printcharfun, "##"); | |
2577 } | |
2578 | |
2579 /* Does it look like an integer or a float? */ | |
2580 { | 2583 { |
2581 Ibyte *data = XSTRING_DATA (name); | 2584 Ibyte *data = XSTRING_DATA (name), *pend = data + XSTRING_LENGTH (name); |
2582 Bytecount confusing = 0; | 2585 Fixnum nondigits = 0, fixval = -1; |
2583 | 2586 Boolint confusing = 1; |
2584 if (size == 0) | 2587 Ichar cc = itext_ichar (data); |
2585 goto not_yet_confused; /* Really confusing */ | 2588 Lisp_Object got = Qnil; |
2586 else if (isdigit (data[0])) | 2589 |
2587 confusing = 0; | 2590 if (cc == '-' || cc == '+') |
2588 else if (size == 1) | |
2589 goto not_yet_confused; | |
2590 else if (data[0] == '-' || data[0] == '+') | |
2591 confusing = 1; | |
2592 else | |
2593 goto not_yet_confused; | |
2594 | |
2595 for (; confusing < size; confusing++) | |
2596 { | 2591 { |
2597 if (!isdigit (data[confusing]) && '/' != data[confusing]) | 2592 INC_IBYTEPTR (data); |
2593 if (data == pend) | |
2598 { | 2594 { |
2599 confusing = 0; | 2595 confusing = 0; |
2596 } | |
2597 } | |
2598 | |
2599 /* No need to check for '.' when working out whether the symbol looks like | |
2600 a number, '.' will get a backslash on printing no matter what, | |
2601 disqualifying it from being a number when read. */ | |
2602 while (confusing && data < pend) | |
2603 { | |
2604 cc = itext_ichar (data); | |
2605 | |
2606 switch (cc) | |
2607 { | |
2608 /* A symbol like 2e10 cound be confused with a float: */ | |
2609 case 'e': | |
2610 case 'E': | |
2611 /* As can one like 123/456: */ | |
2612 case '/': | |
2613 nondigits++; | |
2614 confusing = nondigits < 2 | |
2615 /* If it starts with an E or a slash, that's fine, it can't be a | |
2616 float. */ | |
2617 && data != XSTRING_DATA (name) | |
2618 /* And if it ends with an e or a slash that's fine too. */ | |
2619 && (data + itext_ichar_len (data)) != pend; | |
2620 break; | |
2621 | |
2622 /* There can be a sign in the exponent. Such a sign needs to be | |
2623 directly after an e and to have trailing digits after it to be | |
2624 valid float syntax. */ | |
2625 case '+': | |
2626 case '-': | |
2627 confusing = (1 == nondigits) | |
2628 && data != XSTRING_DATA (name) | |
2629 && (data + itext_ichar_len (data)); | |
2630 if (confusing) | |
2631 { | |
2632 Ibyte *lastp = data; | |
2633 Ichar clast; | |
2634 | |
2635 DEC_IBYTEPTR (lastp); | |
2636 clast = itext_ichar (lastp); | |
2637 | |
2638 confusing = clast == 'E' || clast == 'e'; | |
2639 } | |
2640 break; | |
2641 | |
2642 /* A symbol that is all decimal digits could be confused with an | |
2643 integer: */ | |
2644 default: | |
2645 got = get_char_table (cc, Vdigit_fixnum_map); | |
2646 fixval = FIXNUMP (got) ? XREALFIXNUM (got) : -1; | |
2647 if (fixval < 0 || fixval > 9) | |
2648 { | |
2649 confusing = 0; | |
2650 } | |
2600 break; | 2651 break; |
2601 } | 2652 } |
2653 | |
2654 INC_IBYTEPTR (data); | |
2602 } | 2655 } |
2603 not_yet_confused: | 2656 |
2604 | |
2605 if (!confusing) | |
2606 /* #### Ugh, this is needlessly complex and slow for what we | |
2607 need here. It might be a good idea to copy equivalent code | |
2608 from FSF. --hniksic */ | |
2609 confusing = isfloat_string ((char *) data) | |
2610 || isratio_string ((char *) data); | |
2611 if (confusing) | 2657 if (confusing) |
2612 write_ascstring (printcharfun, "\\"); | 2658 write_ascstring (printcharfun, "\\"); |
2613 } | 2659 } |
2614 | 2660 |
2615 { | 2661 { |
2616 Bytecount i; | 2662 Bytecount i; |
2617 Bytecount last = 0; | 2663 Bytecount last = 0; |
2618 | 2664 |
2619 for (i = 0; i < size; i++) | 2665 for (i = 0; i < size; i++) |
2620 { | 2666 { |
2667 /* In the event that we adopt a non-ASCII-compatible internal format, | |
2668 this will no longer be Mule-safe. As of May 2015, that is very, | |
2669 very unlikely. */ | |
2621 switch (string_byte (name, i)) | 2670 switch (string_byte (name, i)) |
2622 { | 2671 { |
2623 case 0: case 1: case 2: case 3: | 2672 case 0: case 1: case 2: case 3: |
2624 case 4: case 5: case 6: case 7: | 2673 case 4: case 5: case 6: case 7: |
2625 case 8: case 9: case 10: case 11: | 2674 case 8: case 9: case 10: case 11: |