diff options
| -rw-r--r-- | etc/NEWS | 9 | ||||
| -rw-r--r-- | etc/NEWS.26 | 5 | ||||
| -rw-r--r-- | src/character.c | 26 | ||||
| -rw-r--r-- | src/character.h | 2 | ||||
| -rw-r--r-- | src/lread.c | 17 | ||||
| -rw-r--r-- | src/print.c | 3 | ||||
| -rw-r--r-- | test/src/print-tests.el | 4 |
7 files changed, 46 insertions, 20 deletions
| @@ -229,6 +229,15 @@ as new-style, bind the new variable 'force-new-style-backquotes' to t. | |||
| 229 | ** 'print-quoted' now defaults to t, so if you want to see | 229 | ** 'print-quoted' now defaults to t, so if you want to see |
| 230 | (quote x) instead of 'x you will have to bind it to nil where applicable. | 230 | (quote x) instead of 'x you will have to bind it to nil where applicable. |
| 231 | 231 | ||
| 232 | ** To avoid confusion caused by "smart quotes", the reader signals an | ||
| 233 | error when reading Lisp symbols which begin with one of the following | ||
| 234 | quotation characters: ‘’‛“”‟〞"'. A symbol beginning with such a | ||
| 235 | character can be written by escaping the quotation character with a | ||
| 236 | backslash. For example: | ||
| 237 | |||
| 238 | (read "‘smart") => (invalid-read-syntax "strange quote" "‘") | ||
| 239 | (read "\\‘smart") == (intern "‘smart") | ||
| 240 | |||
| 232 | ** Internal parsing commands now use syntax-ppss and disregard | 241 | ** Internal parsing commands now use syntax-ppss and disregard |
| 233 | open-paren-in-column-0-is-defun-start. This affects mostly things like | 242 | open-paren-in-column-0-is-defun-start. This affects mostly things like |
| 234 | forward-comment, scan-sexps, and forward-sexp when parsing backward. | 243 | forward-comment, scan-sexps, and forward-sexp when parsing backward. |
diff --git a/etc/NEWS.26 b/etc/NEWS.26 index 46762d65e18..76e6316ca2e 100644 --- a/etc/NEWS.26 +++ b/etc/NEWS.26 | |||
| @@ -1377,11 +1377,6 @@ second argument instead of its first. | |||
| 1377 | renamed to 'lread--old-style-backquotes'. No user code should use | 1377 | renamed to 'lread--old-style-backquotes'. No user code should use |
| 1378 | this variable. | 1378 | this variable. |
| 1379 | 1379 | ||
| 1380 | --- | ||
| 1381 | ** To avoid confusion caused by "smart quotes", the reader no longer | ||
| 1382 | accepts Lisp symbols which begin with the following quotation | ||
| 1383 | characters: ‘’‛“”‟〞"', unless they are escaped with backslash. | ||
| 1384 | |||
| 1385 | +++ | 1380 | +++ |
| 1386 | ** 'default-file-name-coding-system' now defaults to a coding system | 1381 | ** 'default-file-name-coding-system' now defaults to a coding system |
| 1387 | that does not process CRLF. For example, it defaults to 'utf-8-unix' | 1382 | that does not process CRLF. For example, it defaults to 'utf-8-unix' |
diff --git a/src/character.c b/src/character.c index fa817a50317..4a934c7801c 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -1050,6 +1050,32 @@ blankp (int c) | |||
| 1050 | return XINT (category) == UNICODE_CATEGORY_Zs; /* separator, space */ | 1050 | return XINT (category) == UNICODE_CATEGORY_Zs; /* separator, space */ |
| 1051 | } | 1051 | } |
| 1052 | 1052 | ||
| 1053 | |||
| 1054 | /* Return true for characters that would read as symbol characters, | ||
| 1055 | but graphically may be confused with some kind of punctuation. We | ||
| 1056 | require an escaping backslash, when such characters begin a | ||
| 1057 | symbol. */ | ||
| 1058 | bool | ||
| 1059 | confusable_symbol_character_p (int ch) | ||
| 1060 | { | ||
| 1061 | switch (ch) | ||
| 1062 | { | ||
| 1063 | case 0x2018: /* LEFT SINGLE QUOTATION MARK */ | ||
| 1064 | case 0x2019: /* RIGHT SINGLE QUOTATION MARK */ | ||
| 1065 | case 0x201B: /* SINGLE HIGH-REVERSED-9 QUOTATION MARK */ | ||
| 1066 | case 0x201C: /* LEFT DOUBLE QUOTATION MARK */ | ||
| 1067 | case 0x201D: /* RIGHT DOUBLE QUOTATION MARK */ | ||
| 1068 | case 0x201F: /* DOUBLE HIGH-REVERSED-9 QUOTATION MARK */ | ||
| 1069 | case 0x301E: /* DOUBLE PRIME QUOTATION MARK */ | ||
| 1070 | case 0xFF02: /* FULLWIDTH QUOTATION MARK */ | ||
| 1071 | case 0xFF07: /* FULLWIDTH APOSTROPHE */ | ||
| 1072 | return true; | ||
| 1073 | |||
| 1074 | default: | ||
| 1075 | return false; | ||
| 1076 | } | ||
| 1077 | } | ||
| 1078 | |||
| 1053 | signed char HEXDIGIT_CONST hexdigit[UCHAR_MAX + 1] = | 1079 | signed char HEXDIGIT_CONST hexdigit[UCHAR_MAX + 1] = |
| 1054 | { | 1080 | { |
| 1055 | #if HEXDIGIT_IS_CONST | 1081 | #if HEXDIGIT_IS_CONST |
diff --git a/src/character.h b/src/character.h index c716885d46b..d9e2d7bfc67 100644 --- a/src/character.h +++ b/src/character.h | |||
| @@ -682,6 +682,8 @@ extern bool graphicp (int); | |||
| 682 | extern bool printablep (int); | 682 | extern bool printablep (int); |
| 683 | extern bool blankp (int); | 683 | extern bool blankp (int); |
| 684 | 684 | ||
| 685 | extern bool confusable_symbol_character_p (int ch); | ||
| 686 | |||
| 685 | /* Return a translation table of id number ID. */ | 687 | /* Return a translation table of id number ID. */ |
| 686 | #define GET_TRANSLATION_TABLE(id) \ | 688 | #define GET_TRANSLATION_TABLE(id) \ |
| 687 | (XCDR (XVECTOR (Vtranslation_table_vector)->contents[(id)])) | 689 | (XCDR (XVECTOR (Vtranslation_table_vector)->contents[(id)])) |
diff --git a/src/lread.c b/src/lread.c index 28d4bf9a4fe..3b0a17c90be 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -3473,20 +3473,9 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 3473 | if (!quoted && multibyte) | 3473 | if (!quoted && multibyte) |
| 3474 | { | 3474 | { |
| 3475 | int ch = STRING_CHAR ((unsigned char *) read_buffer); | 3475 | int ch = STRING_CHAR ((unsigned char *) read_buffer); |
| 3476 | switch (ch) | 3476 | if (confusable_symbol_character_p (ch)) |
| 3477 | { | 3477 | xsignal2 (Qinvalid_read_syntax, build_string ("strange quote"), |
| 3478 | case 0x2018: /* LEFT SINGLE QUOTATION MARK */ | 3478 | CALLN (Fstring, make_number (ch))); |
| 3479 | case 0x2019: /* RIGHT SINGLE QUOTATION MARK */ | ||
| 3480 | case 0x201B: /* SINGLE HIGH-REVERSED-9 QUOTATION MARK */ | ||
| 3481 | case 0x201C: /* LEFT DOUBLE QUOTATION MARK */ | ||
| 3482 | case 0x201D: /* RIGHT DOUBLE QUOTATION MARK */ | ||
| 3483 | case 0x201F: /* DOUBLE HIGH-REVERSED-9 QUOTATION MARK */ | ||
| 3484 | case 0x301E: /* DOUBLE PRIME QUOTATION MARK */ | ||
| 3485 | case 0xFF02: /* FULLWIDTH QUOTATION MARK */ | ||
| 3486 | case 0xFF07: /* FULLWIDTH APOSTROPHE */ | ||
| 3487 | xsignal2 (Qinvalid_read_syntax, build_string ("strange quote"), | ||
| 3488 | CALLN (Fstring, make_number (ch))); | ||
| 3489 | } | ||
| 3490 | } | 3479 | } |
| 3491 | { | 3480 | { |
| 3492 | Lisp_Object result; | 3481 | Lisp_Object result; |
diff --git a/src/print.c b/src/print.c index 0e1980d84be..71579673248 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1971,7 +1971,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 1971 | || c == ';' || c == '#' || c == '(' || c == ')' | 1971 | || c == ';' || c == '#' || c == '(' || c == ')' |
| 1972 | || c == ',' || c == '.' || c == '`' | 1972 | || c == ',' || c == '.' || c == '`' |
| 1973 | || c == '[' || c == ']' || c == '?' || c <= 040 | 1973 | || c == '[' || c == ']' || c == '?' || c <= 040 |
| 1974 | || confusing) | 1974 | || confusing |
| 1975 | || (i == 1 && confusable_symbol_character_p (c))) | ||
| 1975 | { | 1976 | { |
| 1976 | printchar ('\\', printcharfun); | 1977 | printchar ('\\', printcharfun); |
| 1977 | confusing = false; | 1978 | confusing = false; |
diff --git a/test/src/print-tests.el b/test/src/print-tests.el index 46368c69ada..01e65028bc7 100644 --- a/test/src/print-tests.el +++ b/test/src/print-tests.el | |||
| @@ -58,5 +58,9 @@ | |||
| 58 | (buffer-string)) | 58 | (buffer-string)) |
| 59 | "--------\n")))) | 59 | "--------\n")))) |
| 60 | 60 | ||
| 61 | (ert-deftest print-read-roundtrip () | ||
| 62 | (let ((sym '\’bar)) | ||
| 63 | (should (eq (read (prin1-to-string sym)) sym)))) | ||
| 64 | |||
| 61 | (provide 'print-tests) | 65 | (provide 'print-tests) |
| 62 | ;;; print-tests.el ends here | 66 | ;;; print-tests.el ends here |