Merge from emacs-24; up to 2012-12-26T16:22:18Z!michael.albinus@gmx.de
[bpt/emacs.git] / src / character.c
index 3517dbb..5a06c7f 100644 (file)
@@ -1,6 +1,6 @@
 /* Basic character support.
 
-Copyright (C) 2001-201 Free Software Foundation, Inc.
+Copyright (C) 2001-2013 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
@@ -29,12 +29,13 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 #endif
 
+#define CHARACTER_INLINE EXTERN_INLINE
+
 #include <stdio.h>
 
 #ifdef emacs
 
 #include <sys/types.h>
-#include <setjmp.h>
 #include <intprops.h>
 #include "lisp.h"
 #include "character.h"
@@ -57,9 +58,6 @@ static Lisp_Object Qauto_fill_chars;
    Unicode character.  Mainly used by the macro MAYBE_UNIFY_CHAR.  */
 Lisp_Object Vchar_unify_table;
 
-/* Variable used locally in the macro FETCH_MULTIBYTE_CHAR.  */
-unsigned char *_fetch_multibyte_char_p;
-
 static Lisp_Object Qchar_script_table;
 
 \f
@@ -128,8 +126,6 @@ char_string (unsigned int c, unsigned char *p)
       c &= ~CHAR_MODIFIER_MASK;
     }
 
-  MAYBE_UNIFY_CHAR (c);
-
   if (c <= MAX_3_BYTE_CHAR)
     {
       bytes = CHAR_STRING (c, p);
@@ -197,8 +193,6 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
       p += 5;
     }
 
-  MAYBE_UNIFY_CHAR (c);
-
   if (len)
     *len = p - saved_p;
   if (advanced)
@@ -259,6 +253,9 @@ multibyte_char_to_unibyte_safe (int c)
 
 DEFUN ("characterp", Fcharacterp, Scharacterp, 1, 2, 0,
        doc: /* Return non-nil if OBJECT is a character.
+In Emacs Lisp, characters are represented by character codes, which
+are non-negative integers.  The function `max-char' returns the
+maximum character code.
 usage: (characterp OBJECT)  */)
   (Lisp_Object object, Lisp_Object ignore)
 {
@@ -308,6 +305,36 @@ If the multibyte character does not represent a byte, return -1.  */)
     }
 }
 
+
+/* Return width (columns) of C considering the buffer display table DP. */
+
+static ptrdiff_t
+char_width (int c, struct Lisp_Char_Table *dp)
+{
+  ptrdiff_t width = CHAR_WIDTH (c);
+
+  if (dp)
+    {
+      Lisp_Object disp = DISP_CHAR_VECTOR (dp, c), ch;
+      int i;
+
+      if (VECTORP (disp))
+       for (i = 0, width = 0; i < ASIZE (disp); i++)
+         {
+           ch = AREF (disp, i);
+           if (CHARACTERP (ch))
+             {
+               int w = CHAR_WIDTH (XFASTINT (ch));
+               if (INT_ADD_OVERFLOW (width, w))
+                 string_overflow ();
+               width += w;
+             }
+         }
+    }
+  return width;
+}
+
+
 DEFUN ("char-width", Fchar_width, Schar_width, 1, 1, 0,
        doc: /* Return width of CHAR when displayed in the current buffer.
 The width is measured by how many columns it occupies on the screen.
@@ -315,21 +342,12 @@ Tab is taken to occupy `tab-width' columns.
 usage: (char-width CHAR)  */)
   (Lisp_Object ch)
 {
-  Lisp_Object disp;
-  int c, width;
-  struct Lisp_Char_Table *dp = buffer_display_table ();
+  int c;
+  ptrdiff_t width;
 
   CHECK_CHARACTER (ch);
   c = XINT (ch);
-
-  /* Get the way the display table would display it.  */
-  disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil;
-
-  if (VECTORP (disp))
-    width = sanitize_char_width (ASIZE (disp));
-  else
-    width = CHAR_WIDTH (c);
-
+  width = char_width (c, buffer_display_table ());
   return make_number (width);
 }
 
@@ -350,25 +368,16 @@ c_string_width (const unsigned char *str, ptrdiff_t len, int precision,
 
   while (i_byte < len)
     {
-      int bytes, thiswidth;
-      Lisp_Object val;
+      int bytes;
       int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes);
+      ptrdiff_t thiswidth = char_width (c, dp);
 
-      if (dp)
-       {
-         val = DISP_CHAR_VECTOR (dp, c);
-         if (VECTORP (val))
-           thiswidth = sanitize_char_width (ASIZE (val));
-         else
-           thiswidth = CHAR_WIDTH (c);
-       }
-      else
+      if (precision <= 0)
        {
-         thiswidth = CHAR_WIDTH (c);
+         if (INT_ADD_OVERFLOW (width, thiswidth))
+           string_overflow ();
        }
-
-      if (precision > 0
-         && (width + thiswidth > precision))
+      else if (precision - width < thiswidth)
        {
          *nchars = i;
          *nbytes = i_byte;
@@ -413,7 +422,7 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision,
   /* This set multibyte to 0 even if STRING is multibyte when it
      contains only ascii and eight-bit-graphic, but that's
      intentional.  */
-  int multibyte = len < SBYTES (string);
+  bool multibyte = len < SBYTES (string);
   unsigned char *str = SDATA (string);
   ptrdiff_t i = 0, i_byte = 0;
   ptrdiff_t width = 0;
@@ -447,18 +456,7 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision,
          else
            c = str[i_byte], bytes = 1;
          chars = 1;
-         if (dp)
-           {
-             val = DISP_CHAR_VECTOR (dp, c);
-             if (VECTORP (val))
-               thiswidth = sanitize_char_width (ASIZE (val));
-             else
-               thiswidth = CHAR_WIDTH (c);
-           }
-         else
-           {
-             thiswidth = CHAR_WIDTH (c);
-           }
+         thiswidth = char_width (c, dp);
        }
 
       if (precision <= 0)
@@ -538,7 +536,7 @@ multibyte_chars_in_text (const unsigned char *ptr, ptrdiff_t nbytes)
       int len = MULTIBYTE_LENGTH (ptr, endp);
 
       if (len == 0)
-       abort ();
+       emacs_abort ();
       ptr += len;
       chars++;
     }
@@ -589,7 +587,7 @@ parse_str_as_multibyte (const unsigned char *str, ptrdiff_t len,
 }
 
 /* Arrange unibyte text at STR of NBYTES bytes as a multibyte text.
-   It actually converts only such 8-bit characters that don't contruct
+   It actually converts only such 8-bit characters that don't construct
    a multibyte sequence to multibyte forms of Latin-1 characters.  If
    NCHARS is nonzero, set *NCHARS to the number of characters in the
    text.  It is assured that we can use LEN bytes at STR as a work
@@ -670,7 +668,7 @@ str_as_multibyte (unsigned char *str, ptrdiff_t len, ptrdiff_t nbytes,
 }
 
 /* Parse unibyte string at STR of LEN bytes, and return the number of
-   bytes it may ocupy when converted to multibyte string by
+   bytes it may occupy when converted to multibyte string by
    `str_to_multibyte'.  */
 
 ptrdiff_t
@@ -762,13 +760,10 @@ str_as_unibyte (unsigned char *str, ptrdiff_t 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 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.  */
+   contains a non-ASCII, non-eight-bit character.  */
 
 ptrdiff_t
-str_to_unibyte (const unsigned char *src, unsigned char *dst, ptrdiff_t chars, int accept_latin_1)
+str_to_unibyte (const unsigned char *src, unsigned char *dst, ptrdiff_t chars)
 {
   ptrdiff_t i;
 
@@ -778,8 +773,7 @@ str_to_unibyte (const unsigned char *src, unsigned char *dst, ptrdiff_t chars, i
 
       if (CHAR_BYTE8_P (c))
        c = CHAR_TO_BYTE8 (c);
-      else if (! ASCII_CHAR_P (c)
-              && (! accept_latin_1 || c >= 0x100))
+      else if (! ASCII_CHAR_P (c))
        return i;
       *dst++ = c;
     }
@@ -790,7 +784,7 @@ str_to_unibyte (const unsigned char *src, unsigned char *dst, ptrdiff_t chars, i
 static ptrdiff_t
 string_count_byte8 (Lisp_Object string)
 {
-  int multibyte = STRING_MULTIBYTE (string);
+  bool multibyte = STRING_MULTIBYTE (string);
   ptrdiff_t nbytes = SBYTES (string);
   unsigned char *p = SDATA (string);
   unsigned char *pend = p + nbytes;
@@ -822,7 +816,7 @@ string_escape_byte8 (Lisp_Object string)
 {
   ptrdiff_t nchars = SCHARS (string);
   ptrdiff_t nbytes = SBYTES (string);
-  int multibyte = STRING_MULTIBYTE (string);
+  bool multibyte = STRING_MULTIBYTE (string);
   ptrdiff_t byte8_count;
   const unsigned char *src, *src_end;
   unsigned char *dst;
@@ -839,8 +833,8 @@ string_escape_byte8 (Lisp_Object string)
 
   if (multibyte)
     {
-      if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count
-         || (STRING_BYTES_BOUND - nbytes) / 2 < byte8_count)
+      if (byte8_count > (MOST_POSITIVE_FIXNUM - nchars) / 3
+         || byte8_count > (STRING_BYTES_BOUND - nbytes) / 2)
        string_overflow ();
 
       /* Convert 2-byte sequence of byte8 chars to 4-byte octal.  */
@@ -849,7 +843,7 @@ string_escape_byte8 (Lisp_Object string)
     }
   else
     {
-      if ((STRING_BYTES_BOUND - nbytes) / 3 < byte8_count)
+      if (byte8_count > (STRING_BYTES_BOUND - nbytes) / 3)
        string_overflow ();
 
       /* Convert 1-byte sequence of byte8 chars to 4-byte octal.  */
@@ -869,8 +863,7 @@ string_escape_byte8 (Lisp_Object string)
          {
            c = STRING_CHAR_ADVANCE (src);
            c = CHAR_TO_BYTE8 (c);
-           sprintf ((char *) dst, "\\%03o", c);
-           dst += 4;
+           dst += sprintf ((char *) dst, "\\%03o", c);
          }
        else
          while (len--) *dst++ = *src++;
@@ -880,10 +873,7 @@ string_escape_byte8 (Lisp_Object string)
       {
        c = *src++;
        if (c >= 0x80)
-         {
-           sprintf ((char *) dst, "\\%03o", c);
-           dst += 4;
-         }
+         dst += sprintf ((char *) dst, "\\%03o", c);
        else
          *dst++ = c;
       }
@@ -924,16 +914,14 @@ usage: (unibyte-string &rest BYTES)  */)
   (ptrdiff_t n, Lisp_Object *args)
 {
   ptrdiff_t i;
-  unsigned char *buf, *p;
   Lisp_Object str;
   USE_SAFE_ALLOCA;
-
-  SAFE_ALLOCA (buf, unsigned char *, n);
-  p = buf;
+  unsigned char *buf = SAFE_ALLOCA (n);
+  unsigned char *p = buf;
 
   for (i = 0; i < n; i++)
     {
-      CHECK_RANGED_INTEGER (0, args[i], 255);
+      CHECK_RANGED_INTEGER (args[i], 0, 255);
       *p++ = XINT (args[i]);
     }
 
@@ -966,7 +954,7 @@ character is a target to get a byte value.  In this case, POSITION, if
 non-nil, is an index of a target character in the string.
 
 If the current buffer (or STRING) is multibyte, and the target
-character is not ASCII nor 8-bit character, an error is signalled.  */)
+character is not ASCII nor 8-bit character, an error is signaled.  */)
   (Lisp_Object position, Lisp_Object string)
 {
   int c;
@@ -1016,12 +1004,6 @@ character is not ASCII nor 8-bit character, an error is signalled.  */)
   return make_number (c);
 }
 
-
-void
-init_character_once (void)
-{
-}
-
 #ifdef emacs
 
 void