(read_escape): For Control modifier, pay attention to
authorKenichi Handa <handa@m17n.org>
Fri, 13 Aug 1999 12:54:36 +0000 (12:54 +0000)
committerKenichi Handa <handa@m17n.org>
Fri, 13 Aug 1999 12:54:36 +0000 (12:54 +0000)
multibyte character.
(read1): Likewise.  Singal error or a multibyte character which
has a modifer bit.  Check validity of Shift modifer.

src/lread.c

index fce29ee..fcc3eb4 100644 (file)
@@ -1492,8 +1492,10 @@ read_escape (readcharfun, stringp)
       c = READCHAR;
       if (c == '\\')
        c = read_escape (readcharfun, 0);
-      if ((c & 0177) == '?')
-       return 0177 | c;
+      if ((c & ~CHAR_MODIFIER_MASK) == '?')
+       return 0177 | (c & CHAR_MODIFIER_MASK);
+      else if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
+       return c | ctrl_modifier;
       /* ASCII control chars are made from letters (both cases),
         as well as the non-letters within 0100...0137.  */
       else if ((c & 0137) >= 0101 && (c & 0137) <= 0132)
@@ -1949,17 +1951,20 @@ read1 (readcharfun, pch, first_in_list)
 
                /* If an escape specifies a non-ASCII single-byte character,
                   this must be a unibyte string.  */
-               if (SINGLE_BYTE_CHAR_P ((c & ~CHAR_META))
-                   && ! ASCII_BYTE_P (c))
+               if (SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK))
+                   && ! ASCII_BYTE_P ((c & ~CHAR_MODIFIER_MASK)))
                  force_singlebyte = 1;
              }
 
-           if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_META)))
+           if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
              {
                unsigned char workbuf[4];
                unsigned char *str = workbuf;
                int length;
 
+               /* Any modifiers for a multibyte character are invalid.  */
+               if (c & CHAR_MODIFIER_MASK)
+                 error ("Invalid modifier in string");
                length = non_ascii_char_to_string (c, workbuf, &str);
                if (length > 1)
                  force_multibyte = 1;
@@ -1975,6 +1980,15 @@ read1 (readcharfun, pch, first_in_list)
                else if (c == (CHAR_CTL | '?'))
                  c = 127;
 
+               if (c & CHAR_SHIFT)
+                 {
+                   /* Shift modifier is valid only with [A-Za-z].  */
+                   if ((c & 0377) >= 'A' && (c & 0377) <= 'Z')
+                     c &= ~CHAR_SHIFT;
+                   else if ((c & 0377) >= 'a' && (c & 0377) <= 'z')
+                     c = (c & ~CHAR_SHIFT) - ('a' - 'A');
+                 }
+
                if (c & CHAR_META)
                  /* Move the meta bit to the right place for a string.  */
                  c = (c & ~CHAR_META) | 0x80;