Replace `iff' in comments.
[bpt/emacs.git] / src / charset.c
index 191bef8..1a85cd3 100644 (file)
@@ -1,13 +1,16 @@
 /* Basic multilingual character support.
-   Copyright (C) 1995, 1997, 1998 Electrotechnical Laboratory, JAPAN.
-   Licensed to the Free Software Foundation.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005,
+                 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+     2005, 2006, 2007
+     National Institute of Advanced Industrial Science and Technology (AIST)
+     Registration Number H14PRO021
 
 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,
@@ -17,8 +20,8 @@ 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.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 /* At first, see the document in `charset.h' to understand the code in
    this file.  */
@@ -63,6 +66,9 @@ int charset_katakana_jisx0201;        /* JISX0201.Kana (Japanese Katakana) */
 int charset_latin_jisx0201;    /* JISX0201.Roman (Japanese Roman) */
 int charset_big5_1;            /* Big5 Level 1 (Chinese Traditional) */
 int charset_big5_2;            /* Big5 Level 2 (Chinese Traditional) */
+int charset_mule_unicode_0100_24ff;
+int charset_mule_unicode_2500_33ff;
+int charset_mule_unicode_e000_ffff;
 
 Lisp_Object Qcharset_table;
 
@@ -112,7 +118,7 @@ void
 invalid_character (c)
      int c;
 {
-  error ("Invalid character: 0%o, %d, 0x%x", c, c, c);
+  error ("Invalid character: %d, #o%o, #x%x", c, c, c);
 }
 
 /* Parse string STR of length LENGTH and fetch information of a
@@ -210,7 +216,7 @@ char_to_string_1 (c, str)
       /* If C still has any modifier bits, just ignore it.  */
       c &= ~CHAR_MODIFIER_MASK;
     }
-  
+
   if (SINGLE_BYTE_CHAR_P (c))
     {
       if (ASCII_BYTE_P (c) || c >= 0xA0)
@@ -331,7 +337,7 @@ split_string (str, len, charset, c1, c2)
   return 0;
 }
 
-/* Return 1 iff character C has valid printable glyph.
+/* Return 1 if character C has valid printable glyph.
    Use the macro CHAR_PRINTABLE_P instead.  */
 int
 char_printable_p (c)
@@ -345,7 +351,7 @@ char_printable_p (c)
     return 0;
   else if (c >= MAX_CHAR)
     return 0;
-  
+
   SPLIT_CHAR (c, charset, c1, c2);
   if (! CHARSET_DEFINED_P (charset))
     return 0;
@@ -730,7 +736,7 @@ It includes a generic character for a charset not yet defined.  */)
 
 DEFUN ("get-unused-iso-final-char", Fget_unused_iso_final_char,
        Sget_unused_iso_final_char, 2, 2, 0,
-       doc: /* Return an unsed ISO's final char for a charset of DIMENISION and CHARS.
+       doc: /* Return an unused ISO's final char for a charset of DIMENSION and CHARS.
 DIMENSION is the number of bytes to represent a character: 1 or 2.
 CHARS is the number of characters in a dimension: 94 or 96.
 
@@ -760,17 +766,20 @@ return nil.  */)
 
 DEFUN ("declare-equiv-charset", Fdeclare_equiv_charset, Sdeclare_equiv_charset,
        4, 4, 0,
-       doc: /* Declare a charset of DIMENSION, CHARS, FINAL-CHAR is the same as CHARSET.
-CHARSET should be defined by `defined-charset' in advance.  */)
-     (dimension, chars, final_char, charset_symbol)
-     Lisp_Object dimension, chars, final_char, charset_symbol;
+       doc: /* Declare an equivalent charset for ISO-2022 decoding.
+
+On decoding by an ISO-2022 base coding system, when a charset
+specified by DIMENSION, CHARS, and FINAL-CHAR is designated, behave as
+if CHARSET is designated instead.  */)
+     (dimension, chars, final_char, charset)
+     Lisp_Object dimension, chars, final_char, charset;
 {
-  int charset;
+  int charset_id;
 
   CHECK_NUMBER (dimension);
   CHECK_NUMBER (chars);
   CHECK_NUMBER (final_char);
-  CHECK_SYMBOL (charset_symbol);
+  CHECK_SYMBOL (charset);
 
   if (XINT (dimension) != 1 && XINT (dimension) != 2)
     error ("Invalid DIMENSION %d, it should be 1 or 2", XINT (dimension));
@@ -778,10 +787,10 @@ CHARSET should be defined by `defined-charset' in advance.  */)
     error ("Invalid CHARS %d, it should be 94 or 96", XINT (chars));
   if (XINT (final_char) < '0' || XFASTINT (final_char) > '~')
     error ("Invalid FINAL-CHAR %c, it should be `0'..`~'", XINT (chars));
-  if ((charset = get_charset_id (charset_symbol)) < 0)
-    error ("Invalid charset %s", SDATA (SYMBOL_NAME (charset_symbol)));
+  if ((charset_id = get_charset_id (charset)) < 0)
+    error ("Invalid charset %s", SDATA (SYMBOL_NAME (charset)));
 
-  ISO_CHARSET_TABLE (dimension, chars, final_char) = charset;
+  ISO_CHARSET_TABLE (dimension, chars, final_char) = charset_id;
   return Qnil;
 }
 
@@ -802,7 +811,7 @@ CHARSET should be defined by `defined-charset' in advance.  */)
 
 int
 find_charset_in_text (ptr, nchars, nbytes, charsets, table)
-     unsigned char *ptr;
+     const unsigned char *ptr;
      int nchars, nbytes, *charsets;
      Lisp_Object table;
 {
@@ -810,14 +819,14 @@ find_charset_in_text (ptr, nchars, nbytes, charsets, table)
     {
       if (charsets && nbytes > 0)
        {
-         unsigned char *endp = ptr + nbytes;
+         const unsigned char *endp = ptr + nbytes;
          int maskbits = 0;
 
          while (ptr < endp && maskbits != 7)
            {
              maskbits |= (*ptr < 0x80 ? 1 : *ptr < 0xA0 ? 2 : 4);
              ptr++;
-           }         
+           }
 
          if (maskbits & 1)
            charsets[CHARSET_ASCII] = 1;
@@ -1025,9 +1034,9 @@ Internal use only.  */)
 }
 
 DEFUN ("split-char", Fsplit_char, Ssplit_char, 1, 1, 0,
-       doc: /* Return list of charset and one or two position-codes of CHAR.
-If CHAR is invalid as a character code,
-return a list of symbol `unknown' and CHAR.  */)
+       doc: /* Return list of charset and one or two position-codes of CH.
+If CH is invalid as a character code,
+return a list of symbol `unknown' and CH.  */)
      (ch)
      Lisp_Object ch;
 {
@@ -1045,7 +1054,7 @@ return a list of symbol `unknown' and CHAR.  */)
 }
 
 DEFUN ("char-charset", Fchar_charset, Schar_charset, 1, 1, 0,
-       doc: /* Return charset of CHAR.  */)
+       doc: /* Return charset of CH.  */)
      (ch)
      Lisp_Object ch;
 {
@@ -1093,8 +1102,8 @@ DIMENSION, CHARS, and FINAL-CHAR.  */)
   return CHARSET_SYMBOL (charset);
 }
 
-/* If GENERICP is nonzero, return nonzero iff C is a valid normal or
-   generic character.  If GENERICP is zero, return nonzero iff C is a
+/* If GENERICP is nonzero, return nonzero if C is a valid normal or
+   generic character.  If GENERICP is zero, return nonzero if C is a
    valid normal character.  Do not call this function directly,
    instead use macro CHAR_VALID_P.  */
 int
@@ -1176,7 +1185,7 @@ The conversion is done based on `nonascii-translation-table' (which see)
 }
 
 DEFUN ("char-bytes", Fchar_bytes, Schar_bytes, 1, 1, 0,
-       doc: /* Return 1 regardless of the argument CHAR.  */)
+       doc: /* Return 1 regardless of the argument CH.  */)
      (ch)
      Lisp_Object ch;
 {
@@ -1220,7 +1229,7 @@ char_bytes (c)
            : 4))))
 
 DEFUN ("char-width", Fchar_width, Schar_width, 1, 1, 0,
-       doc: /* Return width of CHAR when displayed in the current buffer.
+       doc: /* Return width of CH when displayed in the current buffer.
 The width is measured by how many columns it occupies on the screen.
 Tab is taken to occupy `tab-width' columns.  */)
      (ch)
@@ -1271,8 +1280,8 @@ strwidth (str, len)
 
 int
 c_string_width (str, len, precision, nchars, nbytes)
-     unsigned char *str;
-     int precision, *nchars, *nbytes;
+     const unsigned char *str;
+     int len, precision, *nchars, *nbytes;
 {
   int i = 0, i_byte = 0;
   int width = 0;
@@ -1337,7 +1346,11 @@ lisp_string_width (string, precision, nchars, nbytes)
 {
   int len = SCHARS (string);
   int len_byte = SBYTES (string);
-  unsigned char *str = SDATA (string);
+  /* 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 < len_byte;
+  const unsigned char *str = SDATA (string);
   int i = 0, i_byte = 0;
   int width = 0;
   struct Lisp_Char_Table *dp = buffer_display_table ();
@@ -1359,8 +1372,12 @@ lisp_string_width (string, precision, nchars, nbytes)
        }
       else if (dp)
        {
-         int c = STRING_CHAR_AND_LENGTH (str + i_byte, len - i_byte, bytes);
+         int c;
 
+         if (multibyte)
+           c = STRING_CHAR_AND_LENGTH (str + i_byte, len - i_byte, bytes);
+         else
+           c = str[i_byte], bytes = 1;
          chars = 1;
          val = DISP_CHAR_VECTOR (dp, c);
          if (VECTORP (val))
@@ -1371,7 +1388,10 @@ lisp_string_width (string, precision, nchars, nbytes)
       else
        {
          chars = 1;
-         PARSE_MULTIBYTE_SEQ (str + i_byte, len_byte - i_byte, bytes);
+         if (multibyte)
+           PARSE_MULTIBYTE_SEQ (str + i_byte, len_byte - i_byte, bytes);
+         else
+           bytes = 1;
          thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]);
        }
 
@@ -1403,18 +1423,18 @@ When calculating width of a multibyte character in STRING,
 only the base leading-code is considered; the validity of
 the following bytes is not checked.  Tabs in STRING are always
 taken to occupy `tab-width' columns.  */)
-     (str)
-     Lisp_Object str;
+     (string)
+     Lisp_Object string;
 {
   Lisp_Object val;
 
-  CHECK_STRING (str);
-  XSETFASTINT (val, lisp_string_width (str, -1, NULL, NULL));
+  CHECK_STRING (string);
+  XSETFASTINT (val, lisp_string_width (string, -1, NULL, NULL));
   return val;
 }
 
 DEFUN ("char-direction", Fchar_direction, Schar_direction, 1, 1, 0,
-       doc: /* Return the direction of CHAR.
+       doc: /* Return the direction of CH.
 The returned value is 0 for left-to-right and 1 for right-to-left.  */)
      (ch)
      Lisp_Object ch;
@@ -1428,22 +1448,6 @@ The returned value is 0 for left-to-right and 1 for right-to-left.  */)
   return CHARSET_TABLE_INFO (charset, CHARSET_DIRECTION_IDX);
 }
 
-DEFUN ("chars-in-region", Fchars_in_region, Schars_in_region, 2, 2, 0,
-       doc: /* Return number of characters between BEG and END.  */)
-     (beg, end)
-     Lisp_Object beg, end;
-{
-  int from, to;
-
-  CHECK_NUMBER_COERCE_MARKER (beg);
-  CHECK_NUMBER_COERCE_MARKER (end);
-
-  from = min (XFASTINT (beg), XFASTINT (end));
-  to = max (XFASTINT (beg), XFASTINT (end));
-
-  return make_number (to - from);
-}
-
 /* Return the number of characters in the NBYTES bytes at PTR.
    This works by looking at the contents and checking for multibyte sequences.
    However, if the current buffer has enable-multibyte-characters = nil,
@@ -1451,7 +1455,7 @@ DEFUN ("chars-in-region", Fchars_in_region, Schars_in_region, 2, 2, 0,
 
 int
 chars_in_text (ptr, nbytes)
-     unsigned char *ptr;
+     const unsigned char *ptr;
      int nbytes;
 {
   /* current_buffer is null at early stages of Emacs initialization.  */
@@ -1468,10 +1472,10 @@ chars_in_text (ptr, nbytes)
 
 int
 multibyte_chars_in_text (ptr, nbytes)
-     unsigned char *ptr;
+     const unsigned char *ptr;
      int nbytes;
 {
-  unsigned char *endp;
+  const unsigned char *endp;
   int chars, bytes;
 
   endp = ptr + nbytes;
@@ -1493,10 +1497,10 @@ multibyte_chars_in_text (ptr, nbytes)
    0x80..0x9F are represented by 2 bytes in multibyte text.  */
 void
 parse_str_as_multibyte (str, len, nchars, nbytes)
-     unsigned char *str;
+     const unsigned char *str;
      int len, *nchars, *nbytes;
 {
-  unsigned char *endp = str + len;
+  const unsigned char *endp = str + len;
   int n, chars = 0, bytes = 0;
 
   while (str < endp)
@@ -1548,7 +1552,7 @@ str_as_multibyte (str, len, nbytes, nchars)
        {
          while (n--)
            *to++ = *p++;
-       }         
+       }
       else
        {
          *to++ = LEADING_CODE_8_BIT_CONTROL;
@@ -1600,7 +1604,7 @@ str_to_multibyte (str, len, bytes)
   endp = str + len;
   safe_bcopy (p, endp - bytes, bytes);
   p = endp - bytes;
-  while (p < endp)      
+  while (p < endp)
     {
       if (*p < 0x80 || *p >= 0xA0)
        *to++ = *p++;
@@ -1624,7 +1628,7 @@ str_as_unibyte (str, bytes)
 
   while (p < endp && *p != LEADING_CODE_8_BIT_CONTROL) p++;
   to = p;
-  while (p < endp)      
+  while (p < endp)
     {
       if (*p == LEADING_CODE_8_BIT_CONTROL)
        *to++ = *(p + 1) - 0x20, p += 2;
@@ -1642,11 +1646,16 @@ usage: (string &rest CHARACTERS)  */)
      int n;
      Lisp_Object *args;
 {
-  int i;
-  unsigned char *buf = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH * n);
-  unsigned char *p = buf;
+  int i, bufsize;
+  unsigned char *buf, *p;
   int c;
   int multibyte = 0;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
+
+  bufsize = MAX_MULTIBYTE_LENGTH * n;
+  SAFE_ALLOCA (buf, unsigned char *, bufsize);
+  p = buf;
 
   for (i = 0; i < n; i++)
     {
@@ -1664,7 +1673,10 @@ usage: (string &rest CHARACTERS)  */)
        *p++ = c;
     }
 
-  return make_string_from_bytes (buf, n, p - buf);
+  ret = make_string_from_bytes (buf, n, p - buf);
+  SAFE_FREE ();
+
+  return ret;
 }
 
 #endif /* emacs */
@@ -1693,6 +1705,12 @@ DEFUN ("setup-special-charsets", Fsetup_special_charsets,
   charset_latin_jisx0201 = charset_id_internal ("latin-jisx0201");
   charset_big5_1 = charset_id_internal ("chinese-big5-1");
   charset_big5_2 = charset_id_internal ("chinese-big5-2");
+  charset_mule_unicode_0100_24ff
+    = charset_id_internal ("mule-unicode-0100-24ff");
+  charset_mule_unicode_2500_33ff
+    = charset_id_internal ("mule-unicode-2500-33ff");
+  charset_mule_unicode_e000_ffff
+    = charset_id_internal ("mule-unicode-e000-ffff");
   return Qnil;
 }
 
@@ -1844,7 +1862,6 @@ syms_of_charset ()
   defsubr (&Schar_width);
   defsubr (&Sstring_width);
   defsubr (&Schar_direction);
-  defsubr (&Schars_in_region);
   defsubr (&Sstring);
   defsubr (&Ssetup_special_charsets);
 
@@ -1908,3 +1925,6 @@ Such characters have value t in this table.  */);
 }
 
 #endif /* emacs */
+
+/* arch-tag: 66a89b8d-4c28-47d3-9ca1-56f78440d69f
+   (do not change this comment) */