]> code.delx.au - gnu-emacs/blobdiff - src/charset.h
(Text): Replace inforef to emacs-xtra by conditional xref's, depending on
[gnu-emacs] / src / charset.h
index ad0f60ff48967c9e4b32094e1fb190b591a038f2..0d61aa054c0ba923461331f7a701070aaf21811b 100644 (file)
@@ -1,6 +1,9 @@
 /* Header for multibyte character handler.
-   Copyright (C) 1995, 1997, 1998 Electrotechnical Laboratory, JAPAN.
-   Licensed to the Free Software Foundation.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005,
+                 2006 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1997, 1998, 2003
+     National Institute of Advanced Industrial Science and Technology (AIST)
+     Registration Number H14PRO021
 
 This file is part of GNU Emacs.
 
@@ -16,8 +19,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.  */
 
 #ifndef EMACS_CHARSET_H
 #define EMACS_CHARSET_H
@@ -29,19 +32,19 @@ Boston, MA 02111-1307, USA.  */
   A character set ("charset" hereafter) is a meaningful collection
   (i.e. language, culture, functionality, etc) of characters.  Emacs
   handles multiple charsets at once.  Each charset corresponds to one
-  of ISO charsets.  Emacs identifies a charset by a unique
+  of the ISO charsets.  Emacs identifies a charset by a unique
   identification number, whereas ISO identifies a charset by a triplet
   of DIMENSION, CHARS and FINAL-CHAR.  So, hereafter, just saying
   "charset" means an identification number (integer value).
 
-  The value range of charset is 0x00, 0x81..0xFE.  There are four
+  The value range of charsets is 0x00, 0x81..0xFE.  There are four
   kinds of charset depending on DIMENSION (1 or 2) and CHARS (94 or
   96).  For instance, a charset of DIMENSION2_CHARS94 contains 94x94
   characters.
 
   Within Emacs Lisp, a charset is treated as a symbol which has a
   property `charset'.  The property value is a vector containing
-  various information about the charset.  For readability of C codes,
+  various information about the charset.  For readability of C code,
   we use the following convention for C variable names:
        charset_symbol: Emacs Lisp symbol of a charset
        charset_id: Emacs Lisp integer of an identification number of a charset
@@ -51,14 +54,14 @@ Boston, MA 02111-1307, USA.  */
   (range 0x80..0x9E).  In addition, a charset of greater than 0xA0
   (whose base leading-code is 0x9A..0x9D) is assigned an extended
   leading-code (range 0xA0..0xFE).  In this case, each base
-  leading-code specify the allowable range of extended leading-code as
-  shown in the table below.  A leading-code is used to represent a
+  leading-code specifies the allowable range of extended leading-code
+  as shown in the table below.  A leading-code is used to represent a
   character in Emacs' buffer and string.
 
-  We call a charset which has extended leading-code as "private
+  We call a charset which has extended leading-code a "private
   charset" because those are mainly for a charset which is not yet
   registered by ISO.  On the contrary, we call a charset which does
-  not have extended leading-code as "official charset".
+  not have extended leading-code an "official charset".
 
   ---------------------------------------------------------------------------
   charset      dimension        base leading-code      extended leading-code
@@ -106,7 +109,7 @@ Boston, MA 02111-1307, USA.  */
 #define LEADING_CODE_EXT_MAX 0xFE
 
 /* Definition of minimum/maximum charset of each DIMENSION.  */
-#define MIN_CHARSET_OFFICIAL_DIMENSION1        0x81
+#define MIN_CHARSET_OFFICIAL_DIMENSION1        0x80
 #define MAX_CHARSET_OFFICIAL_DIMENSION1        0x8F
 #define MIN_CHARSET_OFFICIAL_DIMENSION2        0x90
 #define MAX_CHARSET_OFFICIAL_DIMENSION2 0x99
@@ -128,6 +131,9 @@ extern int charset_katakana_jisx0201; /* JISX0201.Kana (Japanese Katakana) */
 extern int charset_latin_jisx0201; /* JISX0201.Roman (Japanese Roman) */
 extern int charset_big5_1;     /* Big5 Level 1 (Chinese Traditional) */
 extern int charset_big5_2;     /* Big5 Level 2 (Chinese Traditional) */
+extern int charset_mule_unicode_0100_24ff;
+extern int charset_mule_unicode_2500_33ff;
+extern int charset_mule_unicode_e000_ffff;
 
 /* Check if CH is an ASCII character or a base leading-code.
    Nowadays, any byte can be the first byte of a character in a
@@ -136,8 +142,8 @@ extern int charset_big5_2;  /* Big5 Level 2 (Chinese Traditional) */
 
 /*** GENERAL NOTE on CHARACTER REPRESENTATION ***
 
-  At first, the term "character" or "char" is used for a multilingual
-  character (of course, including ASCII character), not for a byte in
+  Firstly, the term "character" or "char" is used for a multilingual
+  character (of course, including ASCII characters), not for a byte in
   computer memory.  We use the term "code" or "byte" for the latter
   case.
 
@@ -149,14 +155,14 @@ extern int charset_big5_2;        /* Big5 Level 2 (Chinese Traditional) */
   POSITION-CODE is 0x20..0x7F.
 
   Emacs has two kinds of representation of a character: multi-byte
-  form (for buffer and string) and single-word form (for character
-  object in Emacs Lisp).  The latter is called "character code" here
-  after.  Both representations encode the information of charset and
-  POSITION-CODE but in a different way (for instance, MSB of
+  form (for buffers and strings) and single-word form (for character
+  objects in Emacs Lisp).  The latter is called "character code"
+  hereafter.  Both representations encode the information of charset
+  and POSITION-CODE but in a different way (for instance, the MSB of
   POSITION-CODE is set in multi-byte form).
 
-  For details of multi-byte form, see the section "2. Emacs internal
-  format handlers" of `coding.c'.
+  For details of the multi-byte form, see the section "2. Emacs
+  internal format handlers" of `coding.c'.
 
   Emacs uses 19 bits for a character code.  The bits are divided into
   3 fields: FIELD1(5bits):FIELD2(7bits):FIELD3(7bits).
@@ -204,7 +210,7 @@ extern int charset_big5_2;  /* Big5 Level 2 (Chinese Traditional) */
 
 /* Minimum character code of character of each DIMENSION.  */
 #define MIN_CHAR_OFFICIAL_DIMENSION1 \
-  ((MIN_CHARSET_OFFICIAL_DIMENSION1 - 0x70) << 7)
+  ((0x81 - 0x70) << 7)
 #define MIN_CHAR_PRIVATE_DIMENSION1 \
   ((MIN_CHARSET_PRIVATE_DIMENSION1 - 0x70) << 7)
 #define MIN_CHAR_OFFICIAL_DIMENSION2 \
@@ -215,14 +221,14 @@ extern int charset_big5_2;        /* Big5 Level 2 (Chinese Traditional) */
 #define MAX_CHAR (0x1F << 14)
 
 /* 1 if C is a single byte character, else 0.  */
-#define SINGLE_BYTE_CHAR_P(c) ((unsigned) (c) < 0x100)
+#define SINGLE_BYTE_CHAR_P(c) (((unsigned)(c) & 0xFF) == (c))
 
 /* 1 if BYTE is an ASCII character in itself, in multibyte mode.  */
 #define ASCII_BYTE_P(byte) ((byte) < 0x80)
 
-/* A char-table containing information of each character set.
+/* A char-table containing information on each character set.
 
-   Unlike ordinary char-tables, this doesn't contain any nested table.
+   Unlike ordinary char-tables, this doesn't contain any nested tables.
    Only the top level elements are used.  Each element is a vector of
    the following information:
        CHARSET-ID, BYTES, DIMENSION, CHARS, WIDTH, DIRECTION,
@@ -233,8 +239,8 @@ extern int charset_big5_2;  /* Big5 Level 2 (Chinese Traditional) */
 
    CHARSET-ID (integer) is the identification number of the charset.
 
-   BYTES (integer) is the length of multi-byte form of a character in
-   the charset: one of 1, 2, 3, and 4.
+   BYTES (integer) is the length of the multi-byte form of a character
+   in the charset: one of 1, 2, 3, and 4.
 
    DIMENSION (integer) is the number of bytes to represent a character: 1 or 2.
 
@@ -251,7 +257,7 @@ extern int charset_big5_2;  /* Big5 Level 2 (Chinese Traditional) */
    charset.
 
    LEADING-CODE-EXT (integer) is the extended leading-code for the
-   charset.  All charsets of less than 0xA0 has the value 0.
+   charset.  All charsets of less than 0xA0 have the value 0.
 
    ISO-FINAL-CHAR (character) is the final character of the
    corresponding ISO 2022 charset.  It is -1 for such a character
@@ -266,7 +272,7 @@ extern int charset_big5_2;  /* Big5 Level 2 (Chinese Traditional) */
    REVERSE-CHARSET (integer) is the charset which differs only in
    LEFT-TO-RIGHT value from the charset.  If there's no such a
    charset, the value is -1.
-   
+
    SHORT-NAME (string) is the short name to refer to the charset.
 
    LONG-NAME (string) is the long name to refer to the charset.
@@ -274,7 +280,7 @@ extern int charset_big5_2;  /* Big5 Level 2 (Chinese Traditional) */
    DESCRIPTION (string) is the description string of the charset.
 
    PLIST (property list) may contain any type of information a user
-   want to put and get by functions `put-charset-property' and
+   wants to put and get by functions `put-charset-property' and
    `get-charset-property' respectively.  */
 extern Lisp_Object Vcharset_table;
 
@@ -398,7 +404,7 @@ extern int width_by_char_head[256];
       : ((CHARSET_DEFINED_P (charset)                                      \
          ? CHARSET_DIMENSION (charset) == 1                                \
          : (charset) < MIN_CHARSET_PRIVATE_DIMENSION2)                     \
-        ? (((charset) - 0x70) << 7) | ((c1) <= 0 ? 0 : (c1))               \
+        ? (((charset) - 0x70) << 7) | ((c1) <= 0 ? 0 : ((c1) & 0x7F))      \
         : ((((charset)                                                     \
              - ((charset) < MIN_CHARSET_PRIVATE_DIMENSION2 ? 0x8F : 0xE0)) \
             << 14)                                                         \
@@ -436,25 +442,33 @@ extern int width_by_char_head[256];
 #else  /* not BYTE_COMBINING_DEBUG */
 
 #define PARSE_MULTIBYTE_SEQ(str, length, bytes)        \
-  (bytes) = BYTES_BY_CHAR_HEAD ((str)[0])
+  ((void)(length), (bytes) = BYTES_BY_CHAR_HEAD ((str)[0]))
 
 #endif /* not BYTE_COMBINING_DEBUG */
 
+#define VALID_LEADING_CODE_P(code)     \
+  (! NILP (CHARSET_TABLE_ENTRY (code)))
+
 /* Return 1 iff the byte sequence at unibyte string STR (LENGTH bytes)
    is valid as a multibyte form.  If valid, by a side effect, BYTES is
    set to the byte length of the multibyte form.  */
 
-#define UNIBYTE_STR_AS_MULTIBYTE_P(str, length, bytes) \
-  (((str)[0] < 0x80 || (str)[0] >= 0xA0)               \
-   ? (bytes) = 1                                       \
-   : (((bytes) = BYTES_BY_CHAR_HEAD ((str)[0])),       \
-      ((str)[0] != LEADING_CODE_8_BIT_CONTROL          \
-       && (bytes) <= (length)                          \
-       && !CHAR_HEAD_P ((str)[1])                      \
-       && ((bytes) == 2                                        \
-          || (!CHAR_HEAD_P ((str)[2])                  \
-              && ((bytes) == 3                         \
-                  || !CHAR_HEAD_P ((str)[3])))))))
+#define UNIBYTE_STR_AS_MULTIBYTE_P(str, length, bytes)         \
+  (((str)[0] < 0x80 || (str)[0] >= 0xA0)                       \
+   ? ((bytes) = 1)                                             \
+   : (((bytes) = BYTES_BY_CHAR_HEAD ((str)[0])),               \
+      ((bytes) <= (length)                                     \
+       && !CHAR_HEAD_P ((str)[1])                              \
+       && ((bytes) == 2                                                \
+          ? (str)[0] != LEADING_CODE_8_BIT_CONTROL             \
+          : (!CHAR_HEAD_P ((str)[2])                           \
+             && ((bytes) == 3                                  \
+                 ? (((str)[0] != LEADING_CODE_PRIVATE_11       \
+                     && (str)[0] != LEADING_CODE_PRIVATE_12)   \
+                    || VALID_LEADING_CODE_P (str[1]))          \
+                 : (!CHAR_HEAD_P ((str)[3])                    \
+                    && VALID_LEADING_CODE_P (str[1]))))))))
+
 
 /* Return 1 iff the byte sequence at multibyte string STR is valid as
    a unibyte form.  By a side effect, BYTES is set to the byte length
@@ -515,7 +529,7 @@ extern int iso_charset_table[2][2][128];
    : char_bytes (c))
 
 /* The following two macros CHAR_STRING and STRING_CHAR are the main
-   entry points to convert between Emacs two types of character
+   entry points to convert between Emacs's two types of character
    representations: multi-byte form and single-word form (character
    code).  */
 
@@ -524,11 +538,23 @@ extern int iso_charset_table[2][2][128];
    advance.  Returns the length of the multi-byte form.  If C is an
    invalid character code, signal an error.  */
 
-#define CHAR_STRING(c, str)            \
-  (ASCII_BYTE_P (c)                    \
-   ? (*(str) = (unsigned char)(c), 1)  \
+#define CHAR_STRING(c, str)                                              \
+  (SINGLE_BYTE_CHAR_P (c)                                                \
+   ? ((ASCII_BYTE_P (c) || c >= 0xA0)                    \
+      ? (*(str) = (unsigned char)(c), 1)                                 \
+      : (*(str) = LEADING_CODE_8_BIT_CONTROL, *((str)+ 1) = c + 0x20, 2)) \
    : char_to_string (c, (unsigned char *) str))
 
+/* Like CHAR_STRING but don't signal an error if C is invalid.
+   Value is -1 in this case.  */
+
+#define CHAR_STRING_NO_SIGNAL(c, str)                                    \
+  (SINGLE_BYTE_CHAR_P (c)                                                \
+   ? ((ASCII_BYTE_P (c) || c >= 0xA0)                                    \
+      ? (*(str) = (unsigned char)(c), 1)                                 \
+      : (*(str) = LEADING_CODE_8_BIT_CONTROL, *((str)+ 1) = c + 0x20, 2)) \
+   : char_to_string_1 (c, (unsigned char *) str))
+
 /* Return a character code of the character of which multi-byte form
    is at STR and the length is LEN.  If STR doesn't contain valid
    multi-byte form, only the first byte in STR is returned.  */
@@ -560,15 +586,15 @@ if (1)                                                                       \
     CHARIDX++;                                                            \
     if (STRING_MULTIBYTE (STRING))                                        \
       {                                                                           \
-       unsigned char *ptr = &XSTRING (STRING)->data[BYTEIDX];             \
-       int space_left = XSTRING (STRING)->size_byte - BYTEIDX;            \
+       const unsigned char *ptr = SDATA (STRING) + BYTEIDX;               \
+       int space_left = SBYTES (STRING) - BYTEIDX;                        \
        int actual_len;                                                    \
                                                                           \
        OUTPUT = STRING_CHAR_AND_LENGTH (ptr, space_left, actual_len);     \
        BYTEIDX += actual_len;                                             \
       }                                                                           \
     else                                                                  \
-      OUTPUT = XSTRING (STRING)->data[BYTEIDX++];                         \
+      OUTPUT = SREF (STRING, BYTEIDX++);                                  \
   }                                                                       \
 else
 
@@ -577,8 +603,8 @@ else
 #define FETCH_STRING_CHAR_ADVANCE_NO_CHECK(OUTPUT, STRING, CHARIDX, BYTEIDX)  \
 if (1)                                                                       \
   {                                                                          \
-    unsigned char *fetch_string_char_ptr = &XSTRING (STRING)->data[BYTEIDX];  \
-    int fetch_string_char_space_left = XSTRING (STRING)->size_byte - BYTEIDX; \
+    const unsigned char *fetch_string_char_ptr = SDATA (STRING) + BYTEIDX;    \
+    int fetch_string_char_space_left = SBYTES (STRING) - BYTEIDX;            \
     int actual_len;                                                          \
                                                                              \
     OUTPUT                                                                   \
@@ -621,6 +647,34 @@ else
    ? 1                                                 \
    : multibyte_form_length (str, len))
 
+/* If P is before LIMIT, advance P to the next character boundary.  It
+   assumes that P is already at a character boundary of the sane
+   mulitbyte form whose end address is LIMIT.  */
+
+#define NEXT_CHAR_BOUNDARY(p, limit)   \
+  do {                                 \
+    if ((p) < (limit))                 \
+      (p) += BYTES_BY_CHAR_HEAD (*(p));        \
+  } while (0)
+
+
+/* If P is after LIMIT, advance P to the previous character boundary.
+   It assumes that P is already at a character boundary of the sane
+   mulitbyte form whose beginning address is LIMIT.  */
+
+#define PREV_CHAR_BOUNDARY(p, limit)                                   \
+  do {                                                                 \
+    if ((p) > (limit))                                                 \
+      {                                                                        \
+       const unsigned char *p0 = (p);                                  \
+       do {                                                            \
+         p0--;                                                         \
+       } while (p0 >= limit && ! CHAR_HEAD_P (*p0));                   \
+       (p) = (BYTES_BY_CHAR_HEAD (*p0) == (p) - p0) ? p0 : (p) - 1;    \
+      }                                                                        \
+  } while (0)
+
+
 #ifdef emacs
 
 /* Increase the buffer byte position POS_BYTE of the current buffer to
@@ -662,13 +716,15 @@ else
                                                                        \
     pos_byte--;                                                                \
     if (pos_byte < GPT_BYTE)                                           \
-      p = BEG_ADDR + pos_byte - 1, p_min = BEG_ADDR;                   \
+      p = BEG_ADDR + pos_byte - BEG_BYTE, p_min = BEG_ADDR;            \
     else                                                               \
-      p = BEG_ADDR + GAP_SIZE + pos_byte - 1, p_min = GAP_END_ADDR;    \
+      p = BEG_ADDR + GAP_SIZE + pos_byte - BEG_BYTE, p_min = GAP_END_ADDR;\
     if (p > p_min && !CHAR_HEAD_P (*p))                                        \
       {                                                                        \
        unsigned char *pend = p--;                                      \
        int len, bytes;                                                 \
+        if (p_min < p - MAX_MULTIBYTE_LENGTH)                          \
+          p_min = p - MAX_MULTIBYTE_LENGTH;                            \
        while (p > p_min && !CHAR_HEAD_P (*p)) p--;                     \
        len = pend + 1 - p;                                             \
        PARSE_MULTIBYTE_SEQ (p, len, bytes);                            \
@@ -742,18 +798,20 @@ while (0)
     pos_byte--;                                                                \
     if (pos_byte < BUF_GPT_BYTE (buf))                                 \
       {                                                                        \
-       p = BUF_BEG_ADDR (buf) + pos_byte - 1;                          \
+       p = BUF_BEG_ADDR (buf) + pos_byte - BEG_BYTE;                   \
        p_min = BUF_BEG_ADDR (buf);                                     \
       }                                                                        \
     else                                                               \
       {                                                                        \
-       p = BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + pos_byte - 1;     \
+       p = BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + pos_byte - BEG_BYTE;\
        p_min = BUF_GAP_END_ADDR (buf);                                 \
       }                                                                        \
     if (p > p_min && !CHAR_HEAD_P (*p))                                        \
       {                                                                        \
        unsigned char *pend = p--;                                      \
        int len, bytes;                                                 \
+        if (p_min < p - MAX_MULTIBYTE_LENGTH)                          \
+          p_min = p - MAX_MULTIBYTE_LENGTH;                            \
        while (p > p_min && !CHAR_HEAD_P (*p)) p--;                     \
        len = pend + 1 - p;                                             \
        PARSE_MULTIBYTE_SEQ (p, len, bytes);                            \
@@ -773,20 +831,27 @@ extern int translate_char P_ ((Lisp_Object, int, int, int, int));
 extern int split_string P_ ((const unsigned char *, int, int *,
                                       unsigned char *, unsigned char *));
 extern int char_to_string P_ ((int, unsigned char *));
+extern int char_to_string_1 P_ ((int, unsigned char *));
 extern int string_to_char P_ ((const unsigned char *, int, int *));
 extern int char_printable_p P_ ((int c));
 extern int multibyte_form_length P_ ((const unsigned char *, int));
-extern void parse_str_as_multibyte P_ ((unsigned char *, int, int *, int *));
+extern void parse_str_as_multibyte P_ ((const unsigned char *, int, int *,
+                                       int *));
 extern int str_as_multibyte P_ ((unsigned char *, int, int, int *));
+extern int parse_str_to_multibyte P_ ((unsigned char *, int));
 extern int str_to_multibyte P_ ((unsigned char *, int, int));
 extern int str_as_unibyte P_ ((unsigned char *, int));
 extern int get_charset_id P_ ((Lisp_Object));
-extern int find_charset_in_text P_ ((unsigned char *, int, int, int *,
+extern int find_charset_in_text P_ ((const unsigned char *, int, int, int *,
                                    Lisp_Object));
 extern int strwidth P_ ((unsigned char *, int));
+extern int c_string_width P_ ((const unsigned char *, int, int, int *, int *));
+extern int lisp_string_width P_ ((Lisp_Object, int, int *, int *));
 extern int char_bytes P_ ((int));
 extern int char_valid_p P_ ((int, int));
 
+EXFUN (Funibyte_char_to_multibyte, 1);
+
 extern Lisp_Object Vtranslation_table_vector;
 
 /* Return a translation table of id number ID.  */
@@ -804,8 +869,12 @@ extern Lisp_Object Vauto_fill_chars;
 #define BCOPY_SHORT(from, to, len)             \
   do {                                         \
     int i = len;                               \
-    unsigned char *from_p = from, *to_p = to;  \
+    const unsigned char *from_p = from;                \
+    unsigned char *to_p = to;                  \
     while (i--) *to_p++ = *from_p++;           \
   } while (0)
 
 #endif /* EMACS_CHARSET_H */
+
+/* arch-tag: 3b96db55-4961-481d-ac3e-219f46a2b3aa
+   (do not change this comment) */