aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2016-04-25 10:41:29 -0700
committerPaul Eggert2016-04-25 10:42:48 -0700
commit86d083438dba60dc00e9e96414bf7e832720c05a (patch)
tree9ca5fac163acf4b1a3bca0e1e8b5c87af26e5a89 /src
parentf069d854508946bcc03e4c77ceb430748e3ab6d7 (diff)
downloademacs-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.c31
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)
2155static int 2155static int
2156character_name_to_code (char const *name, ptrdiff_t name_len) 2156character_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}