diff options
| author | Paul Eggert | 2016-04-25 10:41:29 -0700 |
|---|---|---|
| committer | Paul Eggert | 2016-04-25 10:42:48 -0700 |
| commit | 86d083438dba60dc00e9e96414bf7e832720c05a (patch) | |
| tree | 9ca5fac163acf4b1a3bca0e1e8b5c87af26e5a89 /src | |
| parent | f069d854508946bcc03e4c77ceb430748e3ab6d7 (diff) | |
| download | emacs-86d083438dba60dc00e9e96414bf7e832720c05a.tar.gz emacs-86d083438dba60dc00e9e96414bf7e832720c05a.zip | |
New function ‘char-from-name’
This also fixes the mishandling of "\N{CJK COMPATIBILITY
IDEOGRAPH-F900}", "\N{VARIATION SELECTOR-1}", etc.
Problem reported by Eli Zaretskii in:
http://lists.gnu.org/archive/html/emacs-devel/2016-04/msg00614.html
* doc/lispref/nonascii.texi (Character Codes), etc/NEWS: Document this.
* lisp/international/mule-cmds.el (char-from-name): New function.
(read-char-by-name): Use it. Document that "BED" is treated as
a name, not as a hexadecimal number. Reject out-of-range integers,
floating-point numbers, and strings with trailing junk.
* src/lread.c (character_name_to_code): Call char-from-name
instead of inspecting ucs-names directly, so that we handle
computed names like "VARIATION SELECTOR-1". Do not use an auto
string, since char-from-name might GC.
* test/src/lread-tests.el: Add tests for new behavior, and
fix some old tests that were wrong.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/src/lread.c b/src/lread.c index a42c1f60c95..6e97e079650 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2155,26 +2155,15 @@ grow_read_buffer (void) | |||
| 2155 | static int | 2155 | static int |
| 2156 | character_name_to_code (char const *name, ptrdiff_t name_len) | 2156 | character_name_to_code (char const *name, ptrdiff_t name_len) |
| 2157 | { | 2157 | { |
| 2158 | Lisp_Object code; | 2158 | /* For "U+XXXX", pass the leading '+' to string_to_number to reject |
| 2159 | 2159 | monstrosities like "U+-0000". */ | |
| 2160 | /* Code point as U+XXXX.... */ | 2160 | Lisp_Object code |
| 2161 | if (name[0] == 'U' && name[1] == '+') | 2161 | = (name[0] == 'U' && name[1] == '+' |
| 2162 | { | 2162 | ? string_to_number (name + 1, 16, false) |
| 2163 | /* Pass the leading '+' to string_to_number, so that it | 2163 | : call2 (Qchar_from_name, make_unibyte_string (name, name_len), Qt)); |
| 2164 | rejects monstrosities such as negative values. */ | 2164 | |
| 2165 | code = string_to_number (name + 1, 16, false); | 2165 | if (! RANGED_INTEGERP (0, code, MAX_UNICODE_CHAR) |
| 2166 | } | 2166 | || char_surrogate_p (XINT (code))) |
| 2167 | else | ||
| 2168 | { | ||
| 2169 | /* Look up the name in the table returned by 'ucs-names'. */ | ||
| 2170 | AUTO_STRING_WITH_LEN (namestr, name, name_len); | ||
| 2171 | Lisp_Object names = call0 (Qucs_names); | ||
| 2172 | code = CDR (Fassoc (namestr, names)); | ||
| 2173 | } | ||
| 2174 | |||
| 2175 | if (! (INTEGERP (code) | ||
| 2176 | && 0 <= XINT (code) && XINT (code) <= MAX_UNICODE_CHAR | ||
| 2177 | && ! char_surrogate_p (XINT (code)))) | ||
| 2178 | { | 2167 | { |
| 2179 | AUTO_STRING (format, "\\N{%s}"); | 2168 | AUTO_STRING (format, "\\N{%s}"); |
| 2180 | AUTO_STRING_WITH_LEN (namestr, name, name_len); | 2169 | AUTO_STRING_WITH_LEN (namestr, name, name_len); |
| @@ -4829,5 +4818,5 @@ that are loaded before your customizations are read! */); | |||
| 4829 | DEFSYM (Qrehash_size, "rehash-size"); | 4818 | DEFSYM (Qrehash_size, "rehash-size"); |
| 4830 | DEFSYM (Qrehash_threshold, "rehash-threshold"); | 4819 | DEFSYM (Qrehash_threshold, "rehash-threshold"); |
| 4831 | 4820 | ||
| 4832 | DEFSYM (Qucs_names, "ucs-names"); | 4821 | DEFSYM (Qchar_from_name, "char-from-name"); |
| 4833 | } | 4822 | } |