]> code.delx.au - gnu-emacs/blobdiff - src/character.c
(re_match_2_internal): Correct matching of eight bit
[gnu-emacs] / src / character.c
index 630eac9fc3b9dd91eb694955a5509535ced23090..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.
-   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
 
@@ -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
-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,
@@ -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
-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.  */
@@ -95,6 +96,54 @@ char unibyte_has_multibyte_table[256];
 
 \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.  */
 
@@ -107,41 +156,7 @@ char_string (c, p)
 
   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;
     }
@@ -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.  */
 
-int
+EMACS_INT
 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
@@ -585,10 +600,10 @@ chars_in_text (ptr, nbytes)
    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;
-     int nbytes;
+     EMACS_INT nbytes;
 {
   const unsigned char *endp = ptr + nbytes;
   int chars = 0;
@@ -932,7 +947,8 @@ usage: (string &rest CHARACTERS)  */)
 }
 
 DEFUN ("unibyte-string", Funibyte_string, Sunibyte_string, 0, MANY, 0,
-       doc: /* Concatenate all the argument bytes and make the result a unibyte string.  */)
+       doc: /* Concatenate all the argument bytes and make the result a unibyte string.
+usage: (unibyte-string &rest BYTES)  */)
      (n, args)
      int n;
      Lisp_Object *args;
@@ -954,6 +970,22 @@ DEFUN ("unibyte-string", Funibyte_string, Sunibyte_string, 0, MANY, 0,
   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 ()
 {
@@ -980,6 +1012,7 @@ syms_of_character ()
   defsubr (&Schar_direction);
   defsubr (&Sstring);
   defsubr (&Sunibyte_string);
+  defsubr (&Schar_resolve_modifiers);
 
   DEFVAR_LISP ("translation-table-vector",  &Vtranslation_table_vector,
               doc: /*