diff options
| author | Kenichi Handa | 1999-08-13 12:54:36 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1999-08-13 12:54:36 +0000 |
| commit | 164d590d5c570746fd0f29985ad0dc7a2d94b259 (patch) | |
| tree | 66c57ce02c2a5ddcf2404b104c2c81d86bd7d5de /src | |
| parent | 6662e69b7f96b9e760f3bbcff760d9a79e0dba3b (diff) | |
| download | emacs-164d590d5c570746fd0f29985ad0dc7a2d94b259.tar.gz emacs-164d590d5c570746fd0f29985ad0dc7a2d94b259.zip | |
(read_escape): For Control modifier, pay attention to
multibyte character.
(read1): Likewise. Singal error or a multibyte character which
has a modifer bit. Check validity of Shift modifer.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/src/lread.c b/src/lread.c index fce29ee874c..fcc3eb4146c 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -1492,8 +1492,10 @@ read_escape (readcharfun, stringp) | |||
| 1492 | c = READCHAR; | 1492 | c = READCHAR; |
| 1493 | if (c == '\\') | 1493 | if (c == '\\') |
| 1494 | c = read_escape (readcharfun, 0); | 1494 | c = read_escape (readcharfun, 0); |
| 1495 | if ((c & 0177) == '?') | 1495 | if ((c & ~CHAR_MODIFIER_MASK) == '?') |
| 1496 | return 0177 | c; | 1496 | return 0177 | (c & CHAR_MODIFIER_MASK); |
| 1497 | else if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK))) | ||
| 1498 | return c | ctrl_modifier; | ||
| 1497 | /* ASCII control chars are made from letters (both cases), | 1499 | /* ASCII control chars are made from letters (both cases), |
| 1498 | as well as the non-letters within 0100...0137. */ | 1500 | as well as the non-letters within 0100...0137. */ |
| 1499 | else if ((c & 0137) >= 0101 && (c & 0137) <= 0132) | 1501 | else if ((c & 0137) >= 0101 && (c & 0137) <= 0132) |
| @@ -1949,17 +1951,20 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1949 | 1951 | ||
| 1950 | /* If an escape specifies a non-ASCII single-byte character, | 1952 | /* If an escape specifies a non-ASCII single-byte character, |
| 1951 | this must be a unibyte string. */ | 1953 | this must be a unibyte string. */ |
| 1952 | if (SINGLE_BYTE_CHAR_P ((c & ~CHAR_META)) | 1954 | if (SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK)) |
| 1953 | && ! ASCII_BYTE_P (c)) | 1955 | && ! ASCII_BYTE_P ((c & ~CHAR_MODIFIER_MASK))) |
| 1954 | force_singlebyte = 1; | 1956 | force_singlebyte = 1; |
| 1955 | } | 1957 | } |
| 1956 | 1958 | ||
| 1957 | if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_META))) | 1959 | if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK))) |
| 1958 | { | 1960 | { |
| 1959 | unsigned char workbuf[4]; | 1961 | unsigned char workbuf[4]; |
| 1960 | unsigned char *str = workbuf; | 1962 | unsigned char *str = workbuf; |
| 1961 | int length; | 1963 | int length; |
| 1962 | 1964 | ||
| 1965 | /* Any modifiers for a multibyte character are invalid. */ | ||
| 1966 | if (c & CHAR_MODIFIER_MASK) | ||
| 1967 | error ("Invalid modifier in string"); | ||
| 1963 | length = non_ascii_char_to_string (c, workbuf, &str); | 1968 | length = non_ascii_char_to_string (c, workbuf, &str); |
| 1964 | if (length > 1) | 1969 | if (length > 1) |
| 1965 | force_multibyte = 1; | 1970 | force_multibyte = 1; |
| @@ -1975,6 +1980,15 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1975 | else if (c == (CHAR_CTL | '?')) | 1980 | else if (c == (CHAR_CTL | '?')) |
| 1976 | c = 127; | 1981 | c = 127; |
| 1977 | 1982 | ||
| 1983 | if (c & CHAR_SHIFT) | ||
| 1984 | { | ||
| 1985 | /* Shift modifier is valid only with [A-Za-z]. */ | ||
| 1986 | if ((c & 0377) >= 'A' && (c & 0377) <= 'Z') | ||
| 1987 | c &= ~CHAR_SHIFT; | ||
| 1988 | else if ((c & 0377) >= 'a' && (c & 0377) <= 'z') | ||
| 1989 | c = (c & ~CHAR_SHIFT) - ('a' - 'A'); | ||
| 1990 | } | ||
| 1991 | |||
| 1978 | if (c & CHAR_META) | 1992 | if (c & CHAR_META) |
| 1979 | /* Move the meta bit to the right place for a string. */ | 1993 | /* Move the meta bit to the right place for a string. */ |
| 1980 | c = (c & ~CHAR_META) | 0x80; | 1994 | c = (c & ~CHAR_META) | 0x80; |