(syms_of_coding): Doc fix.
[bpt/emacs.git] / src / coding.c
index a6c0e7d..bd824bc 100644 (file)
@@ -1,7 +1,6 @@
 /* Coding system handler (conversion, detection, and etc).
-   Ver.1.0.
-   Copyright (C) 1995 Free Software Foundation, Inc.
-   Copyright (C) 1995 Electrotechnical Laboratory, JAPAN.
+   Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN.
+   Licensed to the Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -45,41 +44,40 @@ Boston, MA 02111-1307, USA.  */
   0. Emacs' internal format (emacs-mule)
 
   Emacs itself holds a multi-lingual character in a buffer and a string
-  in a special format.  Details are described in the section 2.
+  in a special format.  Details are described in section 2.
 
   1. ISO2022
 
   The most famous coding system for multiple character sets.  X's
-  Compound Text, various EUCs (Extended Unix Code), and such coding
-  systems used in Internet communication as ISO-2022-JP are all
-  variants of ISO2022.  Details are described in the section 3.
+  Compound Text, various EUCs (Extended Unix Code), and coding
+  systems used in Internet communication such as ISO-2022-JP are
+  all variants of ISO2022.  Details are described in section 3.
 
   2. SJIS (or Shift-JIS or MS-Kanji-Code)
    
   A coding system to encode character sets: ASCII, JISX0201, and
   JISX0208.  Widely used for PC's in Japan.  Details are described in
-  the section 4.
+  section 4.
 
   3. BIG5
 
   A coding system to encode character sets: ASCII and Big5.  Widely
   used by Chinese (mainly in Taiwan and Hong Kong).  Details are
-  described in the section 4.  In this file, when written as "BIG5"
-  (all uppercase), it means the coding system, and when written as
-  "Big5" (capitalized), it means the character set.
+  described in section 4.  In this file, when we write "BIG5"
+  (all uppercase), we mean the coding system, and when we write
+  "Big5" (capitalized), we mean the character set.
 
-  4. Else
+  4. Other
 
-  If a user want to read/write a text encoded in a coding system not
+  If a user wants to read/write a text encoded in a coding system not
   listed above, he can supply a decoder and an encoder for it in CCL
   (Code Conversion Language) programs.  Emacs executes the CCL program
   while reading/writing.
 
-  Emacs represent a coding-system by a Lisp symbol that has a property
+  Emacs represents a coding-system by a Lisp symbol that has a property
   `coding-system'.  But, before actually using the coding-system, the
   information about it is set in a structure of type `struct
-  coding_system' for rapid processing.  See the section 6 for more
-  detail.
+  coding_system' for rapid processing.  See section 6 for more details.
 
 */
 
@@ -87,14 +85,13 @@ Boston, MA 02111-1307, USA.  */
 
   How end-of-line of a text is encoded depends on a system.  For
   instance, Unix's format is just one byte of `line-feed' code,
-  whereas DOS's format is two bytes sequence of `carriage-return' and
+  whereas DOS's format is two-byte sequence of `carriage-return' and
   `line-feed' codes.  MacOS's format is one byte of `carriage-return'.
 
-  Since how characters in a text is encoded and how end-of-line is
-  encoded is independent, any coding system described above can take
+  Since text characters encoding and end-of-line encoding are
+  independent, any coding system described above can take
   any format of end-of-line.  So, Emacs has information of format of
-  end-of-line in each coding-system.  See the section 6 for more
-  detail.
+  end-of-line in each coding-system.  See section 6 for more details.
 
 */
 
@@ -118,10 +115,10 @@ detect_coding_emacs_mule (src, src_end)
 
   These functions decode SRC_BYTES length text at SOURCE encoded in
   CODING to Emacs' internal format (emacs-mule).  The resulting text
-  goes to a place pointed by DESTINATION, the length of which should
-  not exceed DST_BYTES.  The bytes actually processed is returned as
-  *CONSUMED.  The return value is the length of the decoded text.
-  Below is a template of these functions.  */
+  goes to a place pointed to by DESTINATION, the length of which should
+  not exceed DST_BYTES.  The number of bytes actually processed is
+  returned as *CONSUMED.  The return value is the length of the decoded
+  text.  Below is a template of these functions.  */
 #if 0
 decode_coding_XXX (coding, source, destination, src_bytes, dst_bytes, consumed)
      struct coding_system *coding;
@@ -137,10 +134,10 @@ decode_coding_XXX (coding, source, destination, src_bytes, dst_bytes, consumed)
 
   These functions encode SRC_BYTES length text at SOURCE of Emacs'
   internal format (emacs-mule) to CODING.  The resulting text goes to
-  a place pointed by DESTINATION, the length of which should not
-  exceed DST_BYTES.  The bytes actually processed is returned as
-  *CONSUMED.  The return value is the length of the encoded text.
-  Below is a template of these functions.  */
+  a place pointed to by DESTINATION, the length of which should not
+  exceed DST_BYTES.  The number of bytes actually processed is
+  returned as *CONSUMED.  The return value is the length of the
+  encoded text.  Below is a template of these functions.  */
 #if 0
 encode_coding_XXX (coding, source, destination, src_bytes, dst_bytes, consumed)
      struct coding_system *coding;
@@ -201,7 +198,7 @@ encode_coding_XXX (coding, source, destination, src_bytes, dst_bytes, consumed)
       *dst++ = (c);                                            \
   } while (0)
 
-/* Decode one DIMENSION1 character of which charset is CHARSET and
+/* Decode one DIMENSION1 character whose charset is CHARSET and whose
    position-code is C.  */
 
 #define DECODE_CHARACTER_DIMENSION1(charset, c)                                \
@@ -216,7 +213,7 @@ encode_coding_XXX (coding, source, destination, src_bytes, dst_bytes, consumed)
     *dst++ = (c) | 0x80;                                               \
   } while (0)
 
-/* Decode one DIMENSION2 character of which charset is CHARSET and
+/* Decode one DIMENSION2 character whose charset is CHARSET and whose
    position-codes are C1 and C2.  */
 
 #define DECODE_CHARACTER_DIMENSION2(charset, c1, c2)   \
@@ -261,10 +258,17 @@ int eol_mnemonic_unix, eol_mnemonic_dos, eol_mnemonic_mac;
    decided.  */
 int eol_mnemonic_undecided;
 
+/* Format of end-of-line decided by system.  This is CODING_EOL_LF on
+   Unix, CODING_EOL_CRLF on DOS/Windows, and CODING_EOL_CR on Mac.  */
+int system_eol_type;
+
 #ifdef emacs
 
 Lisp_Object Qcoding_system_spec, Qcoding_system_p, Qcoding_system_error;
 
+/* Coding system emacs-mule is for converting only end-of-line format.  */
+Lisp_Object Qemacs_mule;
+
 /* Coding-systems are handed between Emacs Lisp programs and C internal
    routines by the following three variables.  */
 /* Coding-system for reading files and receiving data from process.  */
@@ -274,6 +278,9 @@ Lisp_Object Vcoding_system_for_write;
 /* Coding-system actually used in the latest I/O.  */
 Lisp_Object Vlast_coding_system_used;
 
+/* Flag to inhibit code conversion of end-of-line format.  */
+int inhibit_eol_conversion;
+
 /* Coding-system of what terminal accept for displaying.  */
 struct coding_system terminal_coding;
 
@@ -301,7 +308,8 @@ char *coding_category_name[CODING_CATEGORY_IDX_MAX] = {
   "coding-category-iso-7",
   "coding-category-iso-8-1",
   "coding-category-iso-8-2",
-  "coding-category-iso-else",
+  "coding-category-iso-7-else",
+  "coding-category-iso-8-else",
   "coding-category-big5",
   "coding-category-binary"
 };
@@ -309,12 +317,14 @@ char *coding_category_name[CODING_CATEGORY_IDX_MAX] = {
 /* Flag to tell if we look up unification table on character code
    conversion.  */
 Lisp_Object Venable_character_unification;
-/* Standard unification table to look up on reading (decoding).  */
-Lisp_Object Vstandard_character_unification_table_for_read;
-/* Standard unification table to look up on writing (encoding).  */
-Lisp_Object Vstandard_character_unification_table_for_write;
+/* Standard unification table to look up on decoding (reading).  */
+Lisp_Object Vstandard_character_unification_table_for_decode;
+/* Standard unification table to look up on encoding (writing).  */
+Lisp_Object Vstandard_character_unification_table_for_encode;
 
 Lisp_Object Qcharacter_unification_table;
+Lisp_Object Qcharacter_unification_table_for_decode;
+Lisp_Object Qcharacter_unification_table_for_encode;
 
 /* Alist of charsets vs revision number.  */
 Lisp_Object Vcharset_revision_alist;
@@ -326,25 +336,25 @@ Lisp_Object Vdefault_process_coding_system;
 /*** 2. Emacs internal format (emacs-mule) handlers ***/
 
 /* Emacs' internal format for encoding multiple character sets is a
-   kind of multi-byte encoding, i.e. encoding a character by a sequence
-   of one-byte codes of variable length.  ASCII characters and control
-   characters (e.g. `tab', `newline') are represented by one-byte as
-   is.  It takes the range 0x00 through 0x7F.  The other characters
-   are represented by a sequence of `base leading-code', optional
-   `extended leading-code', and one or two `position-code's.  Length
-   of the sequence is decided by the base leading-code.  Leading-code
-   takes the range 0x80 through 0x9F, whereas extended leading-code
-   and position-code take the range 0xA0 through 0xFF.  See the
-   document of `charset.h' for more detail about leading-code and
-   position-code.
-
-   There's one exception in this rule.  Special leading-code
+   kind of multi-byte encoding, i.e. characters are encoded by
+   variable-length sequences of one-byte codes.  ASCII characters
+   and control characters (e.g. `tab', `newline') are represented by
+   one-byte sequences which are their ASCII codes, in the range 0x00
+   through 0x7F.  The other characters are represented by a sequence
+   of `base leading-code', optional `extended leading-code', and one
+   or two `position-code's.  The length of the sequence is determined
+   by the base leading-code.  Leading-code takes the range 0x80
+   through 0x9F, whereas extended leading-code and position-code take
+   the range 0xA0 through 0xFF.  See `charset.h' for more details
+   about leading-code and position-code.
+
+   There's one exception to this rule.  Special leading-code
    `leading-code-composition' denotes that the following several
    characters should be composed into one character.  Leading-codes of
    components (except for ASCII) are added 0x20.  An ASCII character
    component is represented by a 2-byte sequence of `0xA0' and
-   `ASCII-code + 0x80'.  See also the document in `charset.h' for the
-   detail of composite character.  Hence, we can summarize the code
+   `ASCII-code + 0x80'.  See also the comments in `charset.h' for the
+   details of composite character.  Hence, we can summarize the code
    range as follows:
 
    --- CODE RANGE of Emacs' internal format ---
@@ -436,21 +446,21 @@ detect_coding_emacs_mule (src, src_end)
 /*** 3. ISO2022 handlers ***/
 
 /* The following note describes the coding system ISO2022 briefly.
-   Since the intension of this note is to help understanding of the
-   programs in this file, some parts are NOT ACCURATE or OVERLY
+   Since the intention of this note is to help in understanding of
+   the programs in this file, some parts are NOT ACCURATE or OVERLY
    SIMPLIFIED.  For the thorough understanding, please refer to the
    original document of ISO2022.
 
    ISO2022 provides many mechanisms to encode several character sets
-   in 7-bit and 8-bit environment.  If one choose 7-bite environment,
+   in 7-bit and 8-bit environment.  If one chooses 7-bite environment,
    all text is encoded by codes of less than 128.  This may make the
-   encoded text a little bit longer, but the text get more stability
-   to pass through several gateways (some of them split MSB off).
+   encoded text a little bit longer, but the text gets more stability
+   to pass through several gateways (some of them strip off the MSB).
 
-   There are two kind of character set: control character set and
+   There are two kinds of character set: control character set and
    graphic character set.  The former contains control characters such
    as `newline' and `escape' to provide control functions (control
-   functions are provided also by escape sequence).  The latter
+   functions are provided also by escape sequences).  The latter
    contains graphic characters such as ' A' and '-'.  Emacs recognizes
    two control character sets and many graphic character sets.
 
@@ -554,7 +564,7 @@ detect_coding_emacs_mule (src, src_end)
    '(' can be omitted.  We call this as "short-form" here after.
 
    Now you may notice that there are a lot of ways for encoding the
-   same multilingual text in ISO2022.  Actually, there exist many
+   same multilingual text in ISO2022.  Actually, there exists many
    coding systems such as Compound Text (used in X's inter client
    communication, ISO-2022-JP (used in Japanese Internet), ISO-2022-KR
    (used in Korean Internet), EUC (Extended UNIX Code, used in Asian
@@ -586,7 +596,8 @@ enum iso_code_class_type iso_code_class[256];
        CODING_CATEGORY_MASK_ISO_7
        CODING_CATEGORY_MASK_ISO_8_1
        CODING_CATEGORY_MASK_ISO_8_2
-       CODING_CATEGORY_MASK_ISO_ELSE
+       CODING_CATEGORY_MASK_ISO_7_ELSE
+       CODING_CATEGORY_MASK_ISO_8_ELSE
    are set.  If a code which should never appear in ISO2022 is found,
    returns 0.  */
 
@@ -594,7 +605,12 @@ int
 detect_coding_iso2022 (src, src_end)
      unsigned char *src, *src_end;
 {
-  int mask = CODING_CATEGORY_MASK_ANY;
+  int mask = (CODING_CATEGORY_MASK_ISO_7
+             | CODING_CATEGORY_MASK_ISO_8_1
+             | CODING_CATEGORY_MASK_ISO_8_2
+             | CODING_CATEGORY_MASK_ISO_7_ELSE
+             | CODING_CATEGORY_MASK_ISO_8_ELSE
+             );
   int g1 = 0;                  /* 1 iff designating to G1.  */
   int c, i;
 
@@ -613,31 +629,31 @@ detect_coding_iso2022 (src, src_end)
                                  || (*src >= '@' && *src <= 'B'))))
            {
              /* Valid designation sequence.  */
-             mask &= (CODING_CATEGORY_MASK_ISO_7
-                      | CODING_CATEGORY_MASK_ISO_8_1
-                      | CODING_CATEGORY_MASK_ISO_8_2
-                      | CODING_CATEGORY_MASK_ISO_ELSE);
              if (c == ')' || (c == '$' && *src == ')'))
                {
                  g1 = 1;
-                 mask &= ~CODING_CATEGORY_MASK_ISO_7;
+                 mask &= ~(CODING_CATEGORY_MASK_ISO_7
+                           | CODING_CATEGORY_MASK_ISO_7_ELSE);
                }
              src++;
              break;
            }
          else if (c == 'N' || c == 'O' || c == 'n' || c == 'o')
-           return CODING_CATEGORY_MASK_ISO_ELSE;
+           mask &= (CODING_CATEGORY_MASK_ISO_7_ELSE
+                    | CODING_CATEGORY_MASK_ISO_8_ELSE);
          break;
 
        case ISO_CODE_SO:
          if (g1)
-           return CODING_CATEGORY_MASK_ISO_ELSE;
+           mask &= (CODING_CATEGORY_MASK_ISO_7_ELSE
+                    | CODING_CATEGORY_MASK_ISO_8_ELSE);
          break;
          
        case ISO_CODE_CSI:
        case ISO_CODE_SS2:
        case ISO_CODE_SS3:
-         mask &= ~CODING_CATEGORY_MASK_ISO_7;
+         mask &= ~(CODING_CATEGORY_MASK_ISO_7
+                   | CODING_CATEGORY_MASK_ISO_7_ELSE);
          break;
 
        default:
@@ -647,12 +663,13 @@ detect_coding_iso2022 (src, src_end)
            return 0;
          else
            {
-             int count = 1;
+             unsigned char *src_begin = src;
 
-             mask &= ~CODING_CATEGORY_MASK_ISO_7;
+             mask &= ~(CODING_CATEGORY_MASK_ISO_7
+                       | CODING_CATEGORY_MASK_ISO_7_ELSE);
              while (src < src_end && *src >= 0xA0)
-               count++, src++;
-             if (count & 1 && src < src_end)
+               src++;
+             if ((src - src_begin - 1) & 1 && src < src_end)
                mask &= ~CODING_CATEGORY_MASK_ISO_8_2;
            }
          break;
@@ -702,7 +719,9 @@ detect_coding_iso2022 (src, src_end)
 /* Set designation state into CODING.  */
 #define DECODE_DESIGNATION(reg, dimension, chars, final_char)          \
   do {                                                                 \
-    int charset = ISO_CHARSET_TABLE (dimension, chars, final_char);    \
+    int charset = ISO_CHARSET_TABLE (make_number (dimension),          \
+                                    make_number (chars),               \
+                                    make_number (final_char));         \
     if (charset >= 0)                                                  \
       {                                                                        \
         if (coding->direction == 1                                     \
@@ -734,10 +753,11 @@ decode_coding_iso2022 (coding, source, destination,
   /* Charsets invoked to graphic plane 0 and 1 respectively.  */
   int charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
   int charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1);
-  Lisp_Object unification_table = coding->character_unification_table;
+  Lisp_Object unification_table
+      = coding->character_unification_table_for_decode;
 
   if (!NILP (Venable_character_unification) && NILP (unification_table))
-    unification_table = Vstandard_character_unification_table_for_read;
+    unification_table = Vstandard_character_unification_table_for_decode;
 
   while (src < src_end && dst < adjusted_dst_end)
     {
@@ -1005,10 +1025,10 @@ decode_coding_iso2022 (coding, source, destination,
   return dst - destination;
 }
 
-/* ISO2022 encoding staffs.  */
+/* ISO2022 encoding stuff.  */
 
 /*
-   It is not enough to say just "ISO2022" on encoding, but we have to
+   It is not enough to say just "ISO2022" on encoding, we have to
    specify more details.  In Emacs, each coding-system of ISO2022
    variant has the following specifications:
        1. Initial designation to G0 thru G3.
@@ -1023,7 +1043,7 @@ decode_coding_iso2022 (coding, source, destination,
        9. Use JISX0208-1983 in place of JISX0208-1978?
    These specifications are encoded in `coding->flags' as flag bits
    defined by macros CODING_FLAG_ISO_XXX.  See `coding.h' for more
-   detail.
+   details.
 */
 
 /* Produce codes (escape sequence) for designating CHARSET to graphic
@@ -1119,8 +1139,8 @@ decode_coding_iso2022 (coding, source, destination,
     CODING_SPEC_ISO_INVOCATION (coding, 0) = 3;        \
   } while (0)
 
-/* Produce codes for a DIMENSION1 character of which character set is
-   CHARSET and position-code is C1.  Designation and invocation
+/* Produce codes for a DIMENSION1 character whose character set is
+   CHARSET and whose position-code is C1.  Designation and invocation
    sequences are also produced in advance if necessary.  */
 
 
@@ -1153,8 +1173,8 @@ decode_coding_iso2022 (coding, source, destination,
       dst = encode_invocation_designation (charset, coding, dst);      \
   } while (1)
 
-/* Produce codes for a DIMENSION2 character of which character set is
-   CHARSET and position-codes are C1 and C2.  Designation and
+/* Produce codes for a DIMENSION2 character whose character set is
+   CHARSET and whose position-codes are C1 and C2.  Designation and
    invocation codes are also produced in advance if necessary.  */
 
 #define ENCODE_ISO_CHARACTER_DIMENSION2(charset, c1, c2)               \
@@ -1191,7 +1211,7 @@ decode_coding_iso2022 (coding, source, destination,
     int c_alt, charset_alt;                                              \
     if (!NILP (unification_table)                                        \
        && ((c_alt = unify_char (unification_table, -1, charset, c1, c2)) \
-           < 0))                                                         \
+           >= 0))                                                        \
       SPLIT_CHAR (c_alt, charset_alt, c1, c2);                           \
     else                                                                 \
       charset_alt = charset;                                             \
@@ -1371,10 +1391,11 @@ encode_coding_iso2022 (coding, source, destination,
      from DST_END to assure overflow checking is necessary only at the
      head of loop.  */
   unsigned char *adjusted_dst_end = dst_end - 19;
-  Lisp_Object unification_table = coding->character_unification_table;
+  Lisp_Object unification_table
+      = coding->character_unification_table_for_encode;
 
   if (!NILP (Venable_character_unification) && NILP (unification_table))
-    unification_table = Vstandard_character_unification_table_for_write;
+    unification_table = Vstandard_character_unification_table_for_encode;
 
   while (src < src_end && dst < adjusted_dst_end)
     {
@@ -1538,7 +1559,7 @@ encode_coding_iso2022 (coding, source, destination,
 \f
 /*** 4. SJIS and BIG5 handlers ***/
 
-/* Although SJIS and BIG5 are not ISO's coding system, They are used
+/* Although SJIS and BIG5 are not ISO's coding system, they are used
    quite widely.  So, for the moment, Emacs supports them in the bare
    C code.  But, in the future, they may be supported only by CCL.  */
 
@@ -1610,6 +1631,63 @@ encode_coding_iso2022 (coding, source, destination,
     b2 += b2 < 0x3F ? 0x40 : 0x62;                                     \
   } while (0)
 
+#define DECODE_SJIS_BIG5_CHARACTER(charset, c1, c2)                    \
+  do {                                                                 \
+    int c_alt, charset_alt = (charset);                                        \
+    if (!NILP (unification_table)                                      \
+       && ((c_alt = unify_char (unification_table,                     \
+                                -1, (charset), c1, c2)) >= 0))         \
+         SPLIT_CHAR (c_alt, charset_alt, c1, c2);                      \
+    if (charset_alt == CHARSET_ASCII || charset_alt < 0)               \
+      DECODE_CHARACTER_ASCII (c1);                                     \
+    else if (CHARSET_DIMENSION (charset_alt) == 1)                     \
+      DECODE_CHARACTER_DIMENSION1 (charset_alt, c1);                   \
+    else                                                               \
+      DECODE_CHARACTER_DIMENSION2 (charset_alt, c1, c2);               \
+  } while (0)
+
+#define ENCODE_SJIS_BIG5_CHARACTER(charset, c1, c2)                      \
+  do {                                                                   \
+    int c_alt, charset_alt;                                              \
+    if (!NILP (unification_table)                                        \
+        && ((c_alt = unify_char (unification_table, -1, charset, c1, c2)) \
+           >= 0))                                                        \
+      SPLIT_CHAR (c_alt, charset_alt, c1, c2);                           \
+    else                                                                 \
+      charset_alt = charset;                                             \
+    if (charset_alt == charset_ascii)                                    \
+      *dst++ = c1;                                                       \
+    else if (CHARSET_DIMENSION (charset_alt) == 1)                       \
+      {                                                                          \
+       if (sjis_p && charset_alt == charset_katakana_jisx0201)           \
+         *dst++ = c1;                                                    \
+       else                                                              \
+         *dst++ = charset_alt, *dst++ = c1;                              \
+      }                                                                          \
+    else                                                                 \
+      {                                                                          \
+       c1 &= 0x7F, c2 &= 0x7F;                                           \
+       if (sjis_p && charset_alt == charset_jisx0208)                    \
+         {                                                               \
+           unsigned char s1, s2;                                         \
+                                                                         \
+           ENCODE_SJIS (c1, c2, s1, s2);                                 \
+           *dst++ = s1, *dst++ = s2;                                     \
+         }                                                               \
+       else if (!sjis_p                                                  \
+                && (charset_alt == charset_big5_1                        \
+                    || charset_alt == charset_big5_2))                   \
+         {                                                               \
+           unsigned char b1, b2;                                         \
+                                                                         \
+           ENCODE_BIG5 (charset_alt, c1, c2, b1, b2);                    \
+           *dst++ = b1, *dst++ = b2;                                     \
+         }                                                               \
+       else                                                              \
+         *dst++ = charset_alt, *dst++ = c1, *dst++ = c2;                 \
+      }                                                                          \
+  } while (0);
+
 /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
    Check if a text is encoded in SJIS.  If it is, return
    CODING_CATEGORY_MASK_SJIS, else return 0.  */
@@ -1681,6 +1759,11 @@ decode_coding_sjis_big5 (coding, source, destination,
      from DST_END to assure overflow checking is necessary only at the
      head of loop.  */
   unsigned char *adjusted_dst_end = dst_end - 3;
+  Lisp_Object unification_table
+      = coding->character_unification_table_for_decode;
+
+  if (!NILP (Venable_character_unification) && NILP (unification_table))
+    unification_table = Vstandard_character_unification_table_for_decode;
 
   while (src < src_end && dst < adjusted_dst_end)
     {
@@ -1705,8 +1788,10 @@ decode_coding_sjis_big5 (coding, source, destination,
          else
            *dst++ = c1;
        }
-      else if (c1 < 0x80)
+      else if (c1 < 0x20)
        *dst++ = c1;
+      else if (c1 < 0x80)
+       DECODE_SJIS_BIG5_CHARACTER (charset_ascii, c1, /* dummy */ c2);
       else if (c1 < 0xA0 || c1 >= 0xE0)
        {
          /* SJIS -> JISX0208, BIG5 -> Big5 (only if 0xE0 <= c1 < 0xFF) */
@@ -1714,7 +1799,7 @@ decode_coding_sjis_big5 (coding, source, destination,
            {
              ONE_MORE_BYTE (c2);
              DECODE_SJIS (c1, c2, c3, c4);
-             DECODE_CHARACTER_DIMENSION2 (charset_jisx0208, c3, c4);
+             DECODE_SJIS_BIG5_CHARACTER (charset_jisx0208, c3, c4);
            }
          else if (c1 >= 0xE0 && c1 < 0xFF)
            {
@@ -1722,7 +1807,7 @@ decode_coding_sjis_big5 (coding, source, destination,
 
              ONE_MORE_BYTE (c2);
              DECODE_BIG5 (c1, c2, charset, c3, c4);
-             DECODE_CHARACTER_DIMENSION2 (charset, c3, c4);
+             DECODE_SJIS_BIG5_CHARACTER (charset, c3, c4);
            }
          else                  /* Invalid code */
            *dst++ = c1;
@@ -1731,14 +1816,14 @@ decode_coding_sjis_big5 (coding, source, destination,
        {
          /* SJIS -> JISX0201-Kana, BIG5 -> Big5 */
          if (sjis_p)
-           DECODE_CHARACTER_DIMENSION1 (charset_katakana_jisx0201, c1);
+           DECODE_SJIS_BIG5_CHARACTER (charset_katakana_jisx0201, c1, /* dummy */ c2);
          else
            {
              int charset;
 
              ONE_MORE_BYTE (c2);
              DECODE_BIG5 (c1, c2, charset, c3, c4);
-             DECODE_CHARACTER_DIMENSION2 (charset, c3, c4);
+             DECODE_SJIS_BIG5_CHARACTER (charset, c3, c4);
            }
        }
       continue;
@@ -1779,6 +1864,11 @@ encode_coding_sjis_big5 (coding, source, destination,
      from DST_END to assure overflow checking is necessary only at the
      head of loop.  */
   unsigned char *adjusted_dst_end = dst_end - 1;
+  Lisp_Object unification_table
+      = coding->character_unification_table_for_encode;
+
+  if (!NILP (Venable_character_unification) && NILP (unification_table))
+    unification_table = Vstandard_character_unification_table_for_encode;
 
   while (src < src_end && dst < adjusted_dst_end)
     {
@@ -1806,6 +1896,9 @@ encode_coding_sjis_big5 (coding, source, destination,
       switch (emacs_code_class[c1])
        {
        case EMACS_ascii_code:
+         ENCODE_SJIS_BIG5_CHARACTER (charset_ascii, c1, /* dummy */ c2);
+         break;
+
        case EMACS_control_code:
          *dst++ = c1;
          break;
@@ -1830,36 +1923,17 @@ encode_coding_sjis_big5 (coding, source, destination,
 
        case EMACS_leading_code_2:
          ONE_MORE_BYTE (c2);
-         if (sjis_p && c1 == charset_katakana_jisx0201)
-           *dst++ = c2;
-         else
-           *dst++ = c1, *dst++ = c2;
+         ENCODE_SJIS_BIG5_CHARACTER (c1, c2, /* dummy */ c3);
          break;
 
        case EMACS_leading_code_3:
          TWO_MORE_BYTES (c2, c3);
-         c2 &= 0x7F, c3 &= 0x7F;
-         if (sjis_p && c1 == charset_jisx0208)
-           {
-             unsigned char s1, s2;
-
-             ENCODE_SJIS (c2, c3, s1, s2);
-             *dst++ = s1, *dst++ = s2;
-           }
-         else if (!sjis_p && (c1 == charset_big5_1 || c1 == charset_big5_2))
-           {
-             unsigned char b1, b2;
-
-             ENCODE_BIG5 (c1, c2, c3, b1, b2);
-             *dst++ = b1, *dst++ = b2;
-           }
-         else
-           *dst++ = c1, *dst++ = c2, *dst++ = c3;
+         ENCODE_SJIS_BIG5_CHARACTER (c1, c2, c3);
          break;
 
        case EMACS_leading_code_4:
          THREE_MORE_BYTES (c2, c3, c4);
-         *dst++ = c1, *dst++ = c2, *dst++ = c3, *dst++ = c4;
+         ENCODE_SJIS_BIG5_CHARACTER (c2, c3, c4);
          break;
 
        case EMACS_leading_code_composition:
@@ -2100,7 +2174,7 @@ setup_coding_system (coding_system, coding)
 {
   Lisp_Object type, eol_type;
 
-  /* At first, set several fields default values.  */
+  /* At first, set several fields to default values.  */
   coding->require_flushing = 0;
   coding->last_block = 0;
   coding->selective = 0;
@@ -2108,15 +2182,16 @@ setup_coding_system (coding_system, coding)
   coding->direction = 0;
   coding->carryover_size = 0;
   coding->post_read_conversion = coding->pre_write_conversion = Qnil;
-  /* We have not yet implemented a way to specify unification table in
-     a coding system.  */
-  coding->character_unification_table = Qnil;
+  coding->character_unification_table_for_decode = Qnil;
+  coding->character_unification_table_for_encode = Qnil;
 
   Vlast_coding_system_used = coding->symbol = coding_system;
   eol_type = Qnil;
   /* Get value of property `coding-system' until we get a vector.
      While doing that, also get values of properties
-     `post-read-conversion', `pre-write-conversion', and `eol-type'.  */
+     `post-read-conversion', `pre-write-conversion',
+     `character-unification-table-for-decode',
+     `character-unification-table-for-encode' and `eol-type'.  */
   while (!NILP (coding_system) && SYMBOLP (coding_system))
     {
       if (NILP (coding->post_read_conversion))
@@ -2125,10 +2200,38 @@ setup_coding_system (coding_system, coding)
       if (NILP (coding->pre_write_conversion)) 
        coding->pre_write_conversion = Fget (coding_system,
                                             Qpre_write_conversion);
-      if (NILP (eol_type))
+      if (!inhibit_eol_conversion && NILP (eol_type))
        eol_type = Fget (coding_system, Qeol_type);
+
+      if (NILP (coding->character_unification_table_for_decode))
+       coding->character_unification_table_for_decode
+         = Fget (coding_system, Qcharacter_unification_table_for_decode);
+
+      if (NILP (coding->character_unification_table_for_encode))
+       coding->character_unification_table_for_encode
+         = Fget (coding_system, Qcharacter_unification_table_for_encode);
+
       coding_system = Fget (coding_system, Qcoding_system);
     }
+
+  while (!NILP (coding->character_unification_table_for_decode)
+        && SYMBOLP (coding->character_unification_table_for_decode))
+       coding->character_unification_table_for_decode
+         = Fget (coding->character_unification_table_for_decode,
+                 Qcharacter_unification_table_for_decode);
+  if (!NILP (coding->character_unification_table_for_decode)
+      && !CHAR_TABLE_P (coding->character_unification_table_for_decode))
+      coding->character_unification_table_for_decode = Qnil;
+
+  while (!NILP (coding->character_unification_table_for_encode)
+        && SYMBOLP (coding->character_unification_table_for_encode))
+       coding->character_unification_table_for_encode
+         = Fget (coding->character_unification_table_for_encode,
+                 Qcharacter_unification_table_for_encode);
+  if (!NILP (coding->character_unification_table_for_encode)
+      && !CHAR_TABLE_P (coding->character_unification_table_for_encode))
+      coding->character_unification_table_for_encode = Qnil;
+
   if (!VECTORP (coding_system)
       || XVECTOR (coding_system)->size != 5)
     goto label_invalid_coding_system;
@@ -2349,34 +2452,44 @@ setup_coding_system (coding_system, coding)
 
        The category for a coding system which has the same code range
        as SJIS.  Assigned the coding-system (Lisp
-       symbol) `shift-jis' by default.
+       symbol) `japanese-shift-jis' by default.
 
    o coding-category-iso-7
 
        The category for a coding system which has the same code range
-       as ISO2022 of 7-bit environment.  Assigned the coding-system
-       (Lisp symbol) `iso-2022-7' by default.
+       as ISO2022 of 7-bit environment.  This doesn't use any locking
+       shift and single shift functions.  Assigned the coding-system
+       (Lisp symbol) `iso-2022-7bit' by default.
 
    o coding-category-iso-8-1
 
        The category for a coding system which has the same code range
        as ISO2022 of 8-bit environment and graphic plane 1 used only
-       for DIMENSION1 charset.  Assigned the coding-system (Lisp
-       symbol) `iso-8859-1' by default.
+       for DIMENSION1 charset.  This doesn't use any locking shift
+       and single shift functions.  Assigned the coding-system (Lisp
+       symbol) `iso-latin-1' by default.
 
    o coding-category-iso-8-2
 
        The category for a coding system which has the same code range
        as ISO2022 of 8-bit environment and graphic plane 1 used only
-       for DIMENSION2 charset.  Assigned the coding-system (Lisp
-       symbol) `euc-japan' by default.
+       for DIMENSION2 charset.  This doesn't use any locking shift
+       and single shift functions.  Assigned the coding-system (Lisp
+       symbol) `japanese-iso-8bit' by default.
+
+   o coding-category-iso-7-else
+
+       The category for a coding system which has the same code range
+       as ISO2022 of 7-bit environemnt but uses locking shift or
+       single shift functions.  Assigned the coding-system (Lisp
+       symbol) `iso-2022-7bit-lock' by default.
 
-   o coding-category-iso-else
+   o coding-category-iso-8-else
 
        The category for a coding system which has the same code range
-       as ISO2022 but not belongs to any of the above three
-       categories.  Assigned the coding-system (Lisp symbol)
-       `iso-2022-ss2-7' by default.
+       as ISO2022 of 8-bit environemnt but uses locking shift or
+       single shift functions.  Assigned the coding-system (Lisp
+       symbol) `iso-2022-8bit-ss2' by default.
 
    o coding-category-big5
 
@@ -3380,13 +3493,13 @@ DEFUN ("keyboard-coding-system",
 }
 
 \f
-DEFUN ("find-coding-system", Ffind_coding_system, Sfind_coding_system,
-       1, MANY, 0,
-  "Choose a coding system for a file operation based on file name.\n\
-The value names a pair of coding systems: (ENCODING-SYSTEM DECODING-SYSTEM).\n\
-ENCODING-SYSTEM is the coding system to use for encoding\n\
-\(in case OPERATION does encoding), and DECODING-SYSTEM is the coding system\n\
-for decoding (in case OPERATION does decoding).\n\
+DEFUN ("find-operation-coding-system", Ffind_operation_coding_system,
+       Sfind_operation_coding_system,  1, MANY, 0,
+  "Choose a coding system for an operation based on the target name.\n\
+The value names a pair of coding systems: (DECODING-SYSTEM ENCODING-SYSTEM).\n\
+DECODING-SYSTEM is the coding system to use for decoding\n\
+\(in case OPERATION does decoding), and ENCODING-SYSTEM is the coding system\n\
+for encoding (in case OPERATION does encoding).\n\
 \n\
 The first argument OPERATION specifies an I/O primitive:\n\
   For file I/O, `insert-file-contents' or `write-region'.\n\
@@ -3409,7 +3522,7 @@ or `network-coding-system-alist' depending on OPERATION.\n\
 They may specify a coding system, a cons of coding systems,\n\
 or a function symbol to call.\n\
 In the last case, we call the function with one argument,\n\
-which is a list of all the arguments given to `find-coding-system'.")
+which is a list of all the arguments given to this function.")
   (nargs, args)
      int nargs;
      Lisp_Object *args;
@@ -3431,9 +3544,10 @@ which is a list of all the arguments given to `find-coding-system'.")
        || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
     error ("Invalid %dth argument", XINT (target_idx) + 1);
 
-  chain = (operation == Qinsert_file_contents || operation == Qwrite_region
+  chain = ((EQ (operation, Qinsert_file_contents)
+           || EQ (operation, Qwrite_region))
           ? Vfile_coding_system_alist
-          : (operation == Qopen_network_stream
+          : (EQ (operation, Qopen_network_stream)
              ? Vnetwork_coding_system_alist
              : Vprocess_coding_system_alist));
   if (NILP (chain))
@@ -3456,8 +3570,8 @@ which is a list of all the arguments given to `find-coding-system'.")
            return Qnil;
          if (! NILP (Fcoding_system_p (val)))
            return Fcons (val, val);
-         if (!NILP (Fboundp (val)))
-           return call2 (val, Flist (nargs, args));
+         if (!NILP (Ffboundp (val)))
+           return call1 (val, Flist (nargs, args));
          return Qnil;
        }
     }
@@ -3514,6 +3628,12 @@ init_coding_once ()
 
   setup_coding_system (Qnil, &keyboard_coding);
   setup_coding_system (Qnil, &terminal_coding);
+
+#if defined (MSDOS) || defined (WINDOWSNT)
+  system_eol_type = CODING_EOL_CRLF;
+#else
+  system_eol_type = CODING_EOL_LF;
+#endif
 }
 
 #ifdef emacs
@@ -3523,23 +3643,29 @@ syms_of_coding ()
   Qtarget_idx = intern ("target-idx");
   staticpro (&Qtarget_idx);
 
+  /* Target FILENAME is the first argument.  */
   Fput (Qinsert_file_contents, Qtarget_idx, make_number (0));
+  /* Target FILENAME is the third argument.  */
   Fput (Qwrite_region, Qtarget_idx, make_number (2));
 
   Qcall_process = intern ("call-process");
   staticpro (&Qcall_process);
+  /* Target PROGRAM is the first argument.  */
   Fput (Qcall_process, Qtarget_idx, make_number (0));
 
   Qcall_process_region = intern ("call-process-region");
   staticpro (&Qcall_process_region);
+  /* Target PROGRAM is the third argument.  */
   Fput (Qcall_process_region, Qtarget_idx, make_number (2));
 
   Qstart_process = intern ("start-process");
   staticpro (&Qstart_process);
+  /* Target PROGRAM is the third argument.  */
   Fput (Qstart_process, Qtarget_idx, make_number (2));
 
   Qopen_network_stream = intern ("open-network-stream");
   staticpro (&Qopen_network_stream);
+  /* Target SERVICE is the fourth argument.  */
   Fput (Qopen_network_stream, Qtarget_idx, make_number (3));
 
   Qcoding_system = intern ("coding-system");
@@ -3569,7 +3695,7 @@ syms_of_coding ()
   Fput (Qcoding_system_error, Qerror_conditions,
        Fcons (Qcoding_system_error, Fcons (Qerror, Qnil)));
   Fput (Qcoding_system_error, Qerror_message,
-       build_string ("Coding-system error"));
+       build_string ("Invalid coding system"));
 
   Qcoding_category_index = intern ("coding-category-index");
   staticpro (&Qcoding_category_index);
@@ -3590,6 +3716,17 @@ syms_of_coding ()
   Fput (Qcharacter_unification_table, Qchar_table_extra_slots,
        make_number (0));
 
+  Qcharacter_unification_table_for_decode
+    = intern ("character-unification-table-for-decode");
+  staticpro (&Qcharacter_unification_table_for_decode);
+
+  Qcharacter_unification_table_for_encode
+    = intern ("character-unification-table-for-encode");
+  staticpro (&Qcharacter_unification_table_for_encode);
+
+  Qemacs_mule = intern ("emacs-mule");
+  staticpro (&Qemacs_mule);
+
   defsubr (&Scoding_system_spec);
   defsubr (&Scoding_system_p);
   defsubr (&Sread_coding_system);
@@ -3608,7 +3745,7 @@ syms_of_coding ()
   defsubr (&Sterminal_coding_system);
   defsubr (&Sset_keyboard_coding_system_internal);
   defsubr (&Skeyboard_coding_system);
-  defsubr (&Sfind_coding_system);
+  defsubr (&Sfind_operation_coding_system);
 
   DEFVAR_LISP ("coding-category-list", &Vcoding_category_list,
     "List of coding-categories (symbols) ordered by priority.");
@@ -3624,19 +3761,27 @@ syms_of_coding ()
   DEFVAR_LISP ("coding-system-for-read", &Vcoding_system_for_read,
     "A variable of internal use only.\n\
 If the value is a coding system, it is used for decoding on read operation.\n\
-If not, an appropriate element in `coding-system-alist' (which see) is used.");
+If not, an appropriate element is used from one of the coding system alists:\n\
+There are three of such tables, `file-coding-system-alist',\n\
+`process-coding-system-alist', and `network-coding-system-alist'.");
   Vcoding_system_for_read = Qnil;
 
   DEFVAR_LISP ("coding-system-for-write", &Vcoding_system_for_write,
     "A variable of internal use only.\n\
 If the value is a coding system, it is used for encoding on write operation.\n\
-If not, an appropriate element in `coding-system-alist' (which see) is used.");
+If not, an appropriate element is used from one of the coding system alists:\n\
+There are three of such tables, `file-coding-system-alist',\n\
+`process-coding-system-alist', and `network-coding-system-alist'.");
   Vcoding_system_for_write = Qnil;
 
   DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used,
-    "Coding-system used in the latest file or process I/O.");
+    "Coding system used in the latest file or process I/O.");
   Vlast_coding_system_used = Qnil;
 
+  DEFVAR_BOOL ("inhibit-eol-conversion", &inhibit_eol_conversion,
+    "*Non-nil inhibit code conversion of end-of-line format in any cases.");
+  inhibit_eol_conversion = 0;
+
   DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist,
     "Alist to decide a coding system to use for a file I/O operation.\n\
 The format is ((PATTERN . VAL) ...),\n\
@@ -3649,7 +3794,7 @@ and the cdr part is used for encoding.\n\
 If VAL is a function symbol, the function must return a coding system\n\
 or a cons of coding systems which are used as above.\n\
 \n\
-See also the function `find-coding-system'.");
+See also the function `find-operation-coding-system'.");
   Vfile_coding_system_alist = Qnil;
 
   DEFVAR_LISP ("process-coding-system-alist", &Vprocess_coding_system_alist,
@@ -3664,7 +3809,7 @@ and the cdr part is used for encoding.\n\
 If VAL is a function symbol, the function must return a coding system\n\
 or a cons of coding systems which are used as above.\n\
 \n\
-See also the function `find-coding-system'.");
+See also the function `find-operation-coding-system'.");
   Vprocess_coding_system_alist = Qnil;
 
   DEFVAR_LISP ("network-coding-system-alist", &Vnetwork_coding_system_alist,
@@ -3680,38 +3825,38 @@ and the cdr part is used for encoding.\n\
 If VAL is a function symbol, the function must return a coding system\n\
 or a cons of coding systems which are used as above.\n\
 \n\
-See also the function `find-coding-system'.");
+See also the function `find-operation-coding-system'.");
   Vnetwork_coding_system_alist = Qnil;
 
   DEFVAR_INT ("eol-mnemonic-unix", &eol_mnemonic_unix,
     "Mnemonic character indicating UNIX-like end-of-line format (i.e. LF) .");
-  eol_mnemonic_unix = '.';
+  eol_mnemonic_unix = ':';
 
   DEFVAR_INT ("eol-mnemonic-dos", &eol_mnemonic_dos,
     "Mnemonic character indicating DOS-like end-of-line format (i.e. CRLF).");
-  eol_mnemonic_dos = ':';
+  eol_mnemonic_dos = '\\';
 
   DEFVAR_INT ("eol-mnemonic-mac", &eol_mnemonic_mac,
     "Mnemonic character indicating MAC-like end-of-line format (i.e. CR).");
-  eol_mnemonic_mac = '\'';
+  eol_mnemonic_mac = '/';
 
   DEFVAR_INT ("eol-mnemonic-undecided", &eol_mnemonic_undecided,
     "Mnemonic character indicating end-of-line format is not yet decided.");
-  eol_mnemonic_undecided = '-';
+  eol_mnemonic_undecided = ':';
 
   DEFVAR_LISP ("enable-character-unification", &Venable_character_unification,
     "Non-nil means ISO 2022 encoder/decoder do character unification.");
   Venable_character_unification = Qt;
 
-  DEFVAR_LISP ("standard-character-unification-table-for-read",
-    &Vstandard_character_unification_table_for_read,
+  DEFVAR_LISP ("standard-character-unification-table-for-decode",
+    &Vstandard_character_unification_table_for_decode,
     "Table for unifying characters when reading.");
-  Vstandard_character_unification_table_for_read = Qnil;
+  Vstandard_character_unification_table_for_decode = Qnil;
 
-  DEFVAR_LISP ("standard-character-unification-table-for-write",
-    &Vstandard_character_unification_table_for_write,
+  DEFVAR_LISP ("standard-character-unification-table-for-encode",
+    &Vstandard_character_unification_table_for_encode,
     "Table for unifying characters when writing.");
-  Vstandard_character_unification_table_for_write = Qnil;
+  Vstandard_character_unification_table_for_encode = Qnil;
 
   DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_alist,
     "Alist of charsets vs revision numbers.\n\