X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/2b42d458a45eaf9767da327f76a40a1cf9c77c23..0e2501ed344f5c8e251bcdca981f5d81dd78f663:/src/character.c diff --git a/src/character.c b/src/character.c index 15a2c45fdf..457d57f925 100644 --- a/src/character.c +++ b/src/character.c @@ -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]; +/* 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; @@ -955,6 +970,22 @@ usage: (unibyte-string &rest BYTES) */) 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 () { @@ -981,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: /*