]> code.delx.au - gnu-emacs/blobdiff - src/character.c
Move some window-related functions from frame.c to window.c.
[gnu-emacs] / src / character.c
index c9088a3a258316fecb165bfa7a06bc7e77a63cd4..34e69da9cc53b60e1b9129b3c362190a6c40e2f9 100644 (file)
@@ -1,11 +1,11 @@
 /* Basic character support.
-   Copyright (C) 1995, 1997, 1998, 2001 Electrotechnical Laboratory, JAPAN.
-     Licensed to the Free Software Foundation.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-     Free Software Foundation, Inc.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-     National Institute of Advanced Industrial Science and Technology (AIST)
-     Registration Number H13PRO009
+
+Copyright (C) 2001-2011  Free Software Foundation, Inc.
+Copyright (C) 1995, 1997, 1998, 2001 Electrotechnical Laboratory, JAPAN.
+  Licensed to the Free Software Foundation.
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+  National Institute of Advanced Industrial Science and Technology (AIST)
+  Registration Number H13PRO009
 
 This file is part of GNU Emacs.
 
@@ -35,6 +35,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <sys/types.h>
 #include <setjmp.h>
+#include <intprops.h>
 #include "lisp.h"
 #include "character.h"
 #include "buffer.h"
@@ -50,43 +51,17 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 Lisp_Object Qcharacterp;
 
-/* Vector of translation table ever defined.
-   ID of a translation table is used to index this vector.  */
-Lisp_Object Vtranslation_table_vector;
-
-/* A char-table for characters which may invoke auto-filling.  */
-Lisp_Object Vauto_fill_chars;
-
-Lisp_Object Qauto_fill_chars;
+static Lisp_Object Qauto_fill_chars;
 
 /* Char-table of information about which character to unify to which
    Unicode character.  Mainly used by the macro MAYBE_UNIFY_CHAR.  */
 Lisp_Object Vchar_unify_table;
 
-/* A char-table.  An element is non-nil iff the corresponding
-   character has a printable glyph.  */
-Lisp_Object Vprintable_chars;
-
-/* A char-table.  An elemnent is a column-width of the corresponding
-   character.  */
-Lisp_Object Vchar_width_table;
-
-/* A char-table.  An element is a symbol indicating the direction
-   property of corresponding character.  */
-Lisp_Object Vchar_direction_table;
-
 /* Variable used locally in the macro FETCH_MULTIBYTE_CHAR.  */
 unsigned char *_fetch_multibyte_char_p;
 
-/* Char table of scripts.  */
-Lisp_Object Vchar_script_table;
-
-/* Alist of scripts vs representative characters.  */
-Lisp_Object Vscript_representative_chars;
-
 static Lisp_Object Qchar_script_table;
 
-Lisp_Object Vunicode_category_table;
 \f
 
 /* If character code C has modifier masks, reflect them to the
@@ -182,17 +157,17 @@ char_string (unsigned int c, unsigned char *p)
       bytes = BYTE8_STRING (c, p);
     }
   else
-    error ("Invalid character: %d", c);
+    error ("Invalid character: %x", c);
 
   return bytes;
 }
 
 
-/* Return a character whose multibyte form is at P.  Set LEN is not
+/* Return a character whose multibyte form is at P.  If LEN is not
    NULL, it must be a pointer to integer.  In that case, set *LEN to
-   the byte length of the multibyte form.  If ADVANCED is not NULL, is
+   the byte length of the multibyte form.  If ADVANCED is not NULL, it
    must be a pointer to unsigned char.  In that case, set *ADVANCED to
-   the ending address (i.e. the starting address of the next
+   the ending address (i.e., the starting address of the next
    character) of the multibyte form.  */
 
 int
@@ -232,11 +207,10 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
 }
 
 
-/* Translate character C by translation table TABLE.  If C is
-   negative, translate a character specified by CHARSET and CODE.  If
-   no translation is found in TABLE, return the untranslated
-   character.  If TABLE is a list, elements are char tables.  In this
-   case, translace C by all tables.  */
+/* Translate character C by translation table TABLE.  If no translation is
+   found in TABLE, return the untranslated character.  If TABLE is a list,
+   elements are char tables.  In that case, recursively translate C by all the
+   tables in the list.  */
 
 int
 translate_char (Lisp_Object table, int c)
@@ -258,13 +232,10 @@ translate_char (Lisp_Object table, int c)
 }
 
 /* Convert ASCII or 8-bit character C to unibyte.  If C is none of
-   them, return (C & 0xFF).
-
-   The argument REV_TBL is now ignored.  It will be removed in the
-   future.  */
+   them, return (C & 0xFF).  */
 
 int
-multibyte_char_to_unibyte (int c, Lisp_Object rev_tbl)
+multibyte_char_to_unibyte (int c)
 {
   if (c < 0x80)
     return c;
@@ -386,7 +357,7 @@ c_string_width (const unsigned char *str, EMACS_INT len, int precision,
        {
          val = DISP_CHAR_VECTOR (dp, c);
          if (VECTORP (val))
-           thiswidth = XVECTOR (val)->size;
+           thiswidth = ASIZE (val);
          else
            thiswidth = CHAR_WIDTH (c);
        }
@@ -421,9 +392,9 @@ c_string_width (const unsigned char *str, EMACS_INT len, int precision,
    occupies on the screen.  */
 
 EMACS_INT
-strwidth (const unsigned char *str, EMACS_INT len)
+strwidth (const char *str, EMACS_INT len)
 {
-  return c_string_width (str, len, -1, NULL, NULL);
+  return c_string_width ((const unsigned char *) str, len, -1, NULL, NULL);
 }
 
 /* Return width of Lisp string STRING when displayed in the current
@@ -434,7 +405,7 @@ strwidth (const unsigned char *str, EMACS_INT len)
    in *NCHARS and *NBYTES respectively.  */
 
 EMACS_INT
-lisp_string_width (Lisp_Object string, int precision,
+lisp_string_width (Lisp_Object string, EMACS_INT precision,
                   EMACS_INT *nchars, EMACS_INT *nbytes)
 {
   EMACS_INT len = SCHARS (string);
@@ -449,7 +420,7 @@ lisp_string_width (Lisp_Object string, int precision,
 
   while (i < len)
     {
-      int chars, bytes, thiswidth;
+      EMACS_INT chars, bytes, thiswidth;
       Lisp_Object val;
       int cmp_id;
       EMACS_INT ignore, end;
@@ -467,7 +438,11 @@ lisp_string_width (Lisp_Object string, int precision,
          int c;
 
          if (multibyte)
-           c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes);
+           {
+             int cbytes;
+             c = STRING_CHAR_AND_LENGTH (str + i_byte, cbytes);
+             bytes = cbytes;
+           }
          else
            c = str[i_byte], bytes = 1;
          chars = 1;
@@ -475,7 +450,7 @@ lisp_string_width (Lisp_Object string, int precision,
            {
              val = DISP_CHAR_VECTOR (dp, c);
              if (VECTORP (val))
-               thiswidth = XVECTOR (val)->size;
+               thiswidth = ASIZE (val);
              else
                thiswidth = CHAR_WIDTH (c);
            }
@@ -485,8 +460,14 @@ lisp_string_width (Lisp_Object string, int precision,
            }
        }
 
-      if (precision > 0
-         && (width + thiswidth > precision))
+      if (precision <= 0)
+       {
+#ifdef emacs
+         if (INT_ADD_OVERFLOW (width, thiswidth))
+           string_overflow ();
+#endif
+       }
+      else if (precision - width < thiswidth)
        {
          *nchars = i;
          *nbytes = i_byte;
@@ -495,7 +476,7 @@ lisp_string_width (Lisp_Object string, int precision,
       i += chars;
       i_byte += bytes;
       width += thiswidth;
-  }
+    }
 
   if (precision > 0)
     {
@@ -523,19 +504,6 @@ usage: (string-width STRING)  */)
   return val;
 }
 
-DEFUN ("char-direction", Fchar_direction, Schar_direction, 1, 1, 0,
-       doc: /* Return the direction of CHAR.
-The returned value is 0 for left-to-right and 1 for right-to-left.
-usage: (char-direction CHAR)  */)
-  (Lisp_Object ch)
-{
-  int c;
-
-  CHECK_CHARACTER (ch);
-  c = XINT (ch);
-  return CHAR_TABLE_REF (Vchar_direction_table, c);
-}
-
 /* Return the number of characters in the NBYTES bytes at PTR.
    This works by looking at the contents and checking for multibyte
    sequences while assuming that there's no invalid sequence.
@@ -547,7 +515,7 @@ chars_in_text (const unsigned char *ptr, EMACS_INT nbytes)
 {
   /* current_buffer is null at early stages of Emacs initialization.  */
   if (current_buffer == 0
-      || NILP (current_buffer->enable_multibyte_characters))
+      || NILP (BVAR (current_buffer, enable_multibyte_characters)))
     return nbytes;
 
   return multibyte_chars_in_text (ptr, nbytes);
@@ -704,18 +672,23 @@ str_as_multibyte (unsigned char *str, EMACS_INT len, EMACS_INT nbytes,
    `str_to_multibyte'.  */
 
 EMACS_INT
-parse_str_to_multibyte (const unsigned char *str, EMACS_INT len)
+count_size_as_multibyte (const unsigned char *str, EMACS_INT len)
 {
   const unsigned char *endp = str + len;
   EMACS_INT bytes;
 
   for (bytes = 0; str < endp; str++)
-    bytes += (*str < 0x80) ? 1 : 2;
+    {
+      int n = *str < 0x80 ? 1 : 2;
+      if (INT_ADD_OVERFLOW (bytes, n))
+        string_overflow ();
+      bytes += n;
+    }
   return bytes;
 }
 
 
-/* Convert unibyte text at STR of NBYTES bytes to a multibyte text
+/* Convert unibyte text at STR of BYTES bytes to a multibyte text
    that contains the same single-byte characters.  It actually
    converts all 8-bit characters to multibyte forms.  It is assured
    that we can use LEN bytes at STR as a work area and that is
@@ -787,7 +760,7 @@ str_as_unibyte (unsigned char *str, EMACS_INT bytes)
    corresponding byte and store in DST.  CHARS is the number of
    characters in SRC.  The value is the number of bytes stored in DST.
    Usually, the value is the same as CHARS, but is less than it if SRC
-   contains a non-ASCII, non-eight-bit characater.  If ACCEPT_LATIN_1
+   contains a non-ASCII, non-eight-bit character.  If ACCEPT_LATIN_1
    is nonzero, a Latin-1 character is accepted and converted to a byte
    of that character code.
    Note: Currently the arg ACCEPT_LATIN_1 is not used.  */
@@ -812,7 +785,7 @@ str_to_unibyte (const unsigned char *src, unsigned char *dst, EMACS_INT chars, i
 }
 
 
-EMACS_INT
+static EMACS_INT
 string_count_byte8 (Lisp_Object string)
 {
   int multibyte = STRING_MULTIBYTE (string);
@@ -866,7 +839,7 @@ string_escape_byte8 (Lisp_Object string)
     {
       if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count
          || (MOST_POSITIVE_FIXNUM - nbytes) / 2 < byte8_count)
-       error ("Maximum string size exceeded");
+       string_overflow ();
 
       /* Convert 2-byte sequence of byte8 chars to 4-byte octal.  */
       val = make_uninit_multibyte_string (nchars + byte8_count * 3,
@@ -875,7 +848,8 @@ string_escape_byte8 (Lisp_Object string)
   else
     {
       if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count)
-       error ("Maximum string size exceeded");
+       string_overflow ();
+
       /* Convert 1-byte sequence of byte8 chars to 4-byte octal.  */
       val = make_uninit_string (nbytes + byte8_count * 3);
     }
@@ -919,9 +893,10 @@ DEFUN ("string", Fstring, Sstring, 0, MANY, 0,
        doc: /*
 Concatenate all the argument characters and make the result a string.
 usage: (string &rest CHARACTERS)  */)
-  (int n, Lisp_Object *args)
+  (size_t n, Lisp_Object *args)
 {
-  int i, c;
+  size_t i;
+  int c;
   unsigned char *buf, *p;
   Lisp_Object str;
   USE_SAFE_ALLOCA;
@@ -944,9 +919,10 @@ 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.
 usage: (unibyte-string &rest BYTES)  */)
-  (int n, Lisp_Object *args)
+  (size_t n, Lisp_Object *args)
 {
-  int i, c;
+  size_t i;
+  int c;
   unsigned char *buf, *p;
   Lisp_Object str;
   USE_SAFE_ALLOCA;
@@ -1013,7 +989,7 @@ character is not ASCII nor 8-bit character, an error is signalled.  */)
          pos = XFASTINT (position);
          p = CHAR_POS_ADDR (pos);
        }
-      if (NILP (current_buffer->enable_multibyte_characters))
+      if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
        return make_number (*p);
     }
   else
@@ -1065,20 +1041,19 @@ syms_of_character (void)
   defsubr (&Smultibyte_char_to_unibyte);
   defsubr (&Schar_width);
   defsubr (&Sstring_width);
-  defsubr (&Schar_direction);
   defsubr (&Sstring);
   defsubr (&Sunibyte_string);
   defsubr (&Schar_resolve_modifiers);
   defsubr (&Sget_byte);
 
-  DEFVAR_LISP ("translation-table-vector",  &Vtranslation_table_vector,
+  DEFVAR_LISP ("translation-table-vector",  Vtranslation_table_vector,
               doc: /*
 Vector recording all translation tables ever defined.
 Each element is a pair (SYMBOL . TABLE) relating the table to the
 symbol naming it.  The ID of a translation table is an index into this vector.  */);
   Vtranslation_table_vector = Fmake_vector (make_number (16), Qnil);
 
-  DEFVAR_LISP ("auto-fill-chars", &Vauto_fill_chars,
+  DEFVAR_LISP ("auto-fill-chars", Vauto_fill_chars,
               doc: /*
 A char-table for characters which invoke auto-filling.
 Such characters have value t in this table.  */);
@@ -1086,7 +1061,7 @@ Such characters have value t in this table.  */);
   CHAR_TABLE_SET (Vauto_fill_chars, ' ', Qt);
   CHAR_TABLE_SET (Vauto_fill_chars, '\n', Qt);
 
-  DEFVAR_LISP ("char-width-table", &Vchar_width_table,
+  DEFVAR_LISP ("char-width-table", Vchar_width_table,
               doc: /*
 A char-table for width (columns) of each character.  */);
   Vchar_width_table = Fmake_char_table (Qnil, make_number (1));
@@ -1094,11 +1069,7 @@ A char-table for width (columns) of each character.  */);
   char_table_set_range (Vchar_width_table, MAX_5_BYTE_CHAR + 1, MAX_CHAR,
                        make_number (4));
 
-  DEFVAR_LISP ("char-direction-table", &Vchar_direction_table,
-              doc: /* A char-table for direction of each character.  */);
-  Vchar_direction_table = Fmake_char_table (Qnil, make_number (1));
-
-  DEFVAR_LISP ("printable-chars", &Vprintable_chars,
+  DEFVAR_LISP ("printable-chars", Vprintable_chars,
               doc: /* A char-table for each printable character.  */);
   Vprintable_chars = Fmake_char_table (Qnil, Qnil);
   Fset_char_table_range (Vprintable_chars,
@@ -1107,7 +1078,7 @@ A char-table for width (columns) of each character.  */);
                         Fcons (make_number (160),
                                make_number (MAX_5_BYTE_CHAR)), Qt);
 
-  DEFVAR_LISP ("char-script-table", &Vchar_script_table,
+  DEFVAR_LISP ("char-script-table", Vchar_script_table,
               doc: /* Char table of script symbols.
 It has one extra slot whose value is a list of script symbols.  */);
 
@@ -1119,7 +1090,7 @@ It has one extra slot whose value is a list of script symbols.  */);
   Fput (Qchar_script_table, Qchar_table_extra_slots, make_number (1));
   Vchar_script_table = Fmake_char_table (Qchar_script_table, Qnil);
 
-  DEFVAR_LISP ("script-representative-chars", &Vscript_representative_chars,
+  DEFVAR_LISP ("script-representative-chars", Vscript_representative_chars,
               doc: /* Alist of scripts vs the representative characters.
 Each element is a cons (SCRIPT . CHARS).
 SCRIPT is a symbol representing a script or a subgroup of a script.
@@ -1129,7 +1100,7 @@ If it is a vector, one of the characters in the vector is necessary.
 This variable is used to find a font for a specific script.  */);
   Vscript_representative_chars = Qnil;
 
-  DEFVAR_LISP ("unicode-category-table", &Vunicode_category_table,
+  DEFVAR_LISP ("unicode-category-table", Vunicode_category_table,
               doc: /* Char table of Unicode's "General Category".
 All Unicode characters have one of the following values (symbol):
   Lu, Ll, Lt, Lm, Lo, Mn, Mc, Me, Nd, Nl, No, Pc, Pd, Ps, Pe, Pi, Pf, Po,
@@ -1140,4 +1111,3 @@ See The Unicode Standard for the meaning of those values.  */);
 }
 
 #endif /* emacs */
-