* lisp.h (struct Lisp_Symbol): Replace field "name" with a lisp
[bpt/emacs.git] / src / charset.h
index 60cd120..42ab230 100644 (file)
@@ -1,6 +1,7 @@
 /* Header for multibyte character handler.
    Copyright (C) 1995, 1997, 1998 Electrotechnical Laboratory, JAPAN.
    Licensed to the Free Software Foundation.
+   Copyright (C) 2001 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -19,8 +20,8 @@ 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.  */
 
-#ifndef _CHARSET_H
-#define _CHARSET_H
+#ifndef EMACS_CHARSET_H
+#define EMACS_CHARSET_H
 
 /* #define BYTE_COMBINING_DEBUG */
 
@@ -29,19 +30,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 +52,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
@@ -66,14 +67,14 @@ Boston, MA 02111-1307, USA.  */
   0x00         official dim1    -- none --             -- none --
                (ASCII)
   0x01..0x7F   --never used--
-  0x80         --never used--
+  0x80         official dim1    -- none --             -- none --
+               (eight-bit-graphic)
   0x81..0x8F   official dim1    same as charset        -- none --
   0x90..0x99   official dim2    same as charset        -- none --
   0x9A..0x9D   --never used--
   0x9E         official dim1    same as charset        -- none --
                (eight-bit-control)
-  0x9F         official dim1    -- none --             -- none --
-               (eight-bit-graphic)
+  0x9F         --never used--
   0xA0..0xDF   private dim1        0x9A                same as charset
                of 1-column width
   0xE0..0xEF   private dim1        0x9B                same as charset
@@ -106,7 +107,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
@@ -119,7 +120,7 @@ Boston, MA 02111-1307, USA.  */
 /* Definition of special charsets.  */
 #define CHARSET_ASCII          0       /* 0x00..0x7F */
 #define CHARSET_8_BIT_CONTROL  0x9E    /* 0x80..0x9F */
-#define CHARSET_8_BIT_GRAPHIC  0x9F    /* 0xA0..0xFF */
+#define CHARSET_8_BIT_GRAPHIC  0x80    /* 0xA0..0xFF */
 
 extern int charset_latin_iso8859_1; /* ISO8859-1 (Latin-1) */
 extern int charset_jisx0208_1978; /* JISX0208.1978 (Japanese Kanji old set) */
@@ -136,8 +137,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 +150,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 +205,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 \
@@ -220,9 +221,9 @@ extern int charset_big5_2;  /* Big5 Level 2 (Chinese Traditional) */
 /* 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 +234,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 +252,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 +267,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 +275,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;
 
@@ -395,8 +396,10 @@ extern int width_by_char_head[256];
    : (((charset) == CHARSET_8_BIT_CONTROL                                  \
        || (charset) == CHARSET_8_BIT_GRAPHIC)                              \
       ? ((c1) & 0x7F) | 0x80                                               \
-      : (! CHARSET_DEFINED_P (charset) || CHARSET_DIMENSION (charset) == 1  \
-        ? (((charset) - 0x70) << 7) | ((c1) <= 0 ? 0 : (c1))               \
+      : ((CHARSET_DEFINED_P (charset)                                      \
+         ? CHARSET_DIMENSION (charset) == 1                                \
+         : (charset) < MIN_CHARSET_PRIVATE_DIMENSION2)                     \
+        ? (((charset) - 0x70) << 7) | ((c1) <= 0 ? 0 : ((c1) & 0x7F))      \
         : ((((charset)                                                     \
              - ((charset) < MIN_CHARSET_PRIVATE_DIMENSION2 ? 0x8F : 0xE0)) \
             << 14)                                                         \
@@ -443,14 +446,16 @@ extern int width_by_char_head[256];
    set to the byte length of the multibyte form.  */
 
 #define UNIBYTE_STR_AS_MULTIBYTE_P(str, length, bytes) \
-  (((bytes) = BYTES_BY_CHAR_HEAD ((str)[0])) == 1      \
-   || ((str)[0] != LEADING_CODE_8_BIT_CONTROL          \
-       && (bytes) <= (length)                          \
+  (((str)[0] < 0x80 || (str)[0] >= 0xA0)               \
+   ? ((bytes) = 1)                                     \
+   : (((bytes) = BYTES_BY_CHAR_HEAD ((str)[0])),       \
+      ((bytes) > 1 && (bytes) <= (length)              \
+       && (str)[0] != LEADING_CODE_8_BIT_CONTROL       \
        && !CHAR_HEAD_P ((str)[1])                      \
        && ((bytes) == 2                                        \
           || (!CHAR_HEAD_P ((str)[2])                  \
               && ((bytes) == 3                         \
-                  || !CHAR_HEAD_P ((str)[3]))))))
+                  || !CHAR_HEAD_P ((str)[3])))))))
 
 /* 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
@@ -464,19 +469,20 @@ extern int width_by_char_head[256];
    position-codes of C are stored in C1 and C2.
    We store -1 in C2 if the dimension of the charset is 1.  */
 
-#define SPLIT_CHAR(c, charset, c1, c2)                                   \
-  (SINGLE_BYTE_CHAR_P (c)                                                \
-   ? ((charset = ASCII_BYTE_P (c)                                        \
-       ? CHARSET_ASCII                                                   \
-       : (c) < 0xA0 ? CHARSET_8_BIT_CONTROL : CHARSET_8_BIT_GRAPHIC),    \
-      c1 = (c), c2 = -1)                                                 \
-   : ((c) & CHAR_FIELD1_MASK                                             \
-      ? (charset = (CHAR_FIELD1 (c)                                      \
-                   + ((c) < MIN_CHAR_PRIVATE_DIMENSION2 ? 0x8F : 0xE0)), \
-        c1 = CHAR_FIELD2 (c),                                            \
-        c2 = CHAR_FIELD3 (c))                                            \
-      : (charset = CHAR_FIELD2 (c) + 0x70,                               \
-        c1 = CHAR_FIELD3 (c),                                            \
+#define SPLIT_CHAR(c, charset, c1, c2)                                     \
+  (SINGLE_BYTE_CHAR_P (c)                                                  \
+   ? ((charset                                                             \
+       = (ASCII_BYTE_P (c)                                                 \
+         ? CHARSET_ASCII                                                   \
+         : ((c) < 0xA0 ? CHARSET_8_BIT_CONTROL : CHARSET_8_BIT_GRAPHIC))), \
+      c1 = (c), c2 = -1)                                                   \
+   : ((c) & CHAR_FIELD1_MASK                                               \
+      ? (charset = (CHAR_FIELD1 (c)                                        \
+                   + ((c) < MIN_CHAR_PRIVATE_DIMENSION2 ? 0x8F : 0xE0)),   \
+        c1 = CHAR_FIELD2 (c),                                              \
+        c2 = CHAR_FIELD3 (c))                                              \
+      : (charset = CHAR_FIELD2 (c) + 0x70,                                 \
+        c1 = CHAR_FIELD3 (c),                                              \
         c2 = -1)))
 
 /* Return 1 iff character C has valid printable glyph.  */
@@ -510,7 +516,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).  */
 
@@ -519,11 +525,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.  */
@@ -657,13 +675,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);                            \
@@ -737,18 +757,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);                            \
@@ -768,17 +790,21 @@ 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 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 *,
                                    Lisp_Object));
 extern int strwidth P_ ((unsigned char *, int));
+extern int c_string_width P_ ((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));
 
@@ -803,4 +829,4 @@ extern Lisp_Object Vauto_fill_chars;
     while (i--) *to_p++ = *from_p++;           \
   } while (0)
 
-#endif /* _CHARSET_H */
+#endif /* EMACS_CHARSET_H */