]> code.delx.au - gnu-emacs/blobdiff - src/character.c
(re_match_2_internal): Correct matching of eight bit
[gnu-emacs] / src / character.c
index 15a2c45fdf8b50183401b45ef3eecafe381ab257..457d57f9251ce53320b5193daf7f0919cd869c5f 100644 (file)
@@ -1,8 +1,9 @@
 /* Basic character support.
    Copyright (C) 1995, 1997, 1998, 2001 Electrotechnical Laboratory, JAPAN.
      Licensed to the Free Software Foundation.
 /* Basic character support.
    Copyright (C) 1995, 1997, 1998, 2001 Electrotechnical Laboratory, JAPAN.
      Licensed to the Free Software Foundation.
-   Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc.
-   Copyright (C) 2003, 2006
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+     Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
 
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
 
@@ -10,7 +11,7 @@ This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -19,9 +20,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GNU Emacs; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 /* At first, see the document in `character.h' to understand the code
    in this file.  */
 
 /* At first, see the document in `character.h' to understand the code
    in this file.  */
@@ -95,6 +96,54 @@ char unibyte_has_multibyte_table[256];
 
 \f
 
 
 \f
 
+/* If character code C has modifier masks, reflect them to the
+   character code if possible.  Return the resulting code.  */
+
+int
+char_resolve_modifier_mask (c)
+     int c;
+{
+  /* A non-ASCII character can't reflect modifier bits to the code.  */
+  if (! ASCII_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
+    return c;
+
+  /* For Meta, Shift, and Control modifiers, we need special care.  */
+  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');
+      /* Shift modifier for control characters and SPC is ignored.  */
+      else if ((c & ~CHAR_MODIFIER_MASK) <= 0x20)
+       c &= ~CHAR_SHIFT;
+    }
+  if (c & CHAR_CTL)
+    {
+      /* Simulate the code in lread.c.  */
+      /* Allow `\C- ' and `\C-?'.  */
+      if ((c & 0377) == ' ')
+       c &= ~0177 & ~ CHAR_CTL;
+      else if ((c & 0377) == '?')
+       c = 0177 | (c & ~0177 & ~CHAR_CTL);
+      /* 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)
+       c &= (037 | (~0177 & ~CHAR_CTL));
+      else if ((c & 0177) >= 0100 && (c & 0177) <= 0137)
+       c &= (037 | (~0177 & ~CHAR_CTL));
+    }
+  if (c & CHAR_META)
+    {
+      /* Move the meta bit to the right place for a string.  */
+      c = (c & ~CHAR_META) | 0x80;
+    }
+
+  return c;
+}
+
+
 /* Store multibyte form of character C at P.  If C has modifier bits,
    handle them appropriately.  */
 
 /* Store multibyte form of character C at P.  If C has modifier bits,
    handle them appropriately.  */
 
@@ -107,41 +156,7 @@ char_string (c, p)
 
   if (c & CHAR_MODIFIER_MASK)
     {
 
   if (c & CHAR_MODIFIER_MASK)
     {
-      /* As an non-ASCII character can't have modifier bits, we just
-        ignore the bits.  */
-      if (ASCII_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
-       {
-         /* For Meta, Shift, and Control modifiers, we need special care.  */
-         if (c & CHAR_META)
-           {
-             /* Move the meta bit to the right place for a string.  */
-             c = (c & ~CHAR_META) | 0x80;
-           }
-         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_CTL)
-           {
-             /* Simulate the code in lread.c.  */
-             /* Allow `\C- ' and `\C-?'.  */
-             if (c == (CHAR_CTL | ' '))
-               c = 0;
-             else if (c == (CHAR_CTL | '?'))
-               c = 127;
-             /* 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)
-               c &= (037 | (~0177 & ~CHAR_CTL));
-             else if ((c & 0177) >= 0100 && (c & 0177) <= 0137)
-               c &= (037 | (~0177 & ~CHAR_CTL));
-           }
-       }
-
+      c = (unsigned) char_resolve_modifier_mask ((int) c);
       /* If C still has any modifier bits, just ignore it.  */
       c &= ~CHAR_MODIFIER_MASK;
     }
       /* If C still has any modifier bits, just ignore it.  */
       c &= ~CHAR_MODIFIER_MASK;
     }
@@ -567,10 +582,10 @@ The returned value is 0 for left-to-right and 1 for right-to-left.  */)
    However, if the current buffer has enable-multibyte-characters =
    nil, we treat each byte as a character.  */
 
    However, if the current buffer has enable-multibyte-characters =
    nil, we treat each byte as a character.  */
 
-int
+EMACS_INT
 chars_in_text (ptr, nbytes)
      const unsigned char *ptr;
 chars_in_text (ptr, nbytes)
      const unsigned char *ptr;
-     int nbytes;
+     EMACS_INT nbytes;
 {
   /* current_buffer is null at early stages of Emacs initialization.  */
   if (current_buffer == 0
 {
   /* current_buffer is null at early stages of Emacs initialization.  */
   if (current_buffer == 0
@@ -585,10 +600,10 @@ chars_in_text (ptr, nbytes)
    sequences while assuming that there's no invalid sequence.  It
    ignores enable-multibyte-characters.  */
 
    sequences while assuming that there's no invalid sequence.  It
    ignores enable-multibyte-characters.  */
 
-int
+EMACS_INT
 multibyte_chars_in_text (ptr, nbytes)
      const unsigned char *ptr;
 multibyte_chars_in_text (ptr, nbytes)
      const unsigned char *ptr;
-     int nbytes;
+     EMACS_INT nbytes;
 {
   const unsigned char *endp = ptr + nbytes;
   int chars = 0;
 {
   const unsigned char *endp = ptr + nbytes;
   int chars = 0;
@@ -955,6 +970,22 @@ usage: (unibyte-string &rest BYTES)  */)
   return make_string_from_bytes ((char *) buf, n, p - buf);
 }
 
   return make_string_from_bytes ((char *) buf, n, p - buf);
 }
 
+DEFUN ("char-resolve-modifers", Fchar_resolve_modifiers,
+       Schar_resolve_modifiers, 1, 1, 0,
+       doc: /* Resolve modifiers in the character CHAR.
+The value is a character with modifiers resolved into the character
+code.  Unresolved modifiers are kept in the value.
+usage: (char-resolve-modifers CHAR)  */)
+     (character)
+     Lisp_Object character;
+{
+  int c;
+
+  CHECK_NUMBER (character);
+  c = XINT (character);
+  return make_number (char_resolve_modifier_mask (c));
+}
+
 void
 init_character_once ()
 {
 void
 init_character_once ()
 {
@@ -981,6 +1012,7 @@ syms_of_character ()
   defsubr (&Schar_direction);
   defsubr (&Sstring);
   defsubr (&Sunibyte_string);
   defsubr (&Schar_direction);
   defsubr (&Sstring);
   defsubr (&Sunibyte_string);
+  defsubr (&Schar_resolve_modifiers);
 
   DEFVAR_LISP ("translation-table-vector",  &Vtranslation_table_vector,
               doc: /*
 
   DEFVAR_LISP ("translation-table-vector",  &Vtranslation_table_vector,
               doc: /*