/[emacs]/emacs/src/coding.c
ViewVC logotype

Diff of /emacs/src/coding.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.289 by monnier, Tue Jul 22 19:06:12 2003 UTC revision 1.289.2.1 by handa, Mon Sep 8 12:48:10 2003 UTC
# Line 1  Line 1 
1  /* Coding system handler (conversion, detection, and etc).  /* Coding system handler (conversion, detection, etc).
2     Copyright (C) 1995,97,1998,2002,2003  Electrotechnical Laboratory, JAPAN.     Copyright (C) 1995, 1997, 1998 Electrotechnical Laboratory, JAPAN.
3     Licensed to the Free Software Foundation.       Licensed to the Free Software Foundation.
4     Copyright (C) 2001,2002,2003  Free Software Foundation, Inc.     Copyright (C) 2001, 2002 Free Software Foundation, Inc.
5       Copyright (C) 2003
6         National Institute of Advanced Industrial Science and Technology (AIST)
7         Registration Number H13PRO009
8    
9  This file is part of GNU Emacs.  This file is part of GNU Emacs.
10    
# Line 24  Boston, MA 02111-1307, USA.  */ Line 27  Boston, MA 02111-1307, USA.  */
27    
28    0. General comments    0. General comments
29    1. Preamble    1. Preamble
30    2. Emacs' internal format (emacs-mule) handlers    2. Emacs' internal format (emacs-utf-8) handlers
31    3. ISO2022 handlers    3. UTF-8 handlers
32    4. Shift-JIS and BIG5 handlers    4. UTF-16 handlers
33    5. CCL handlers    5. Charset-base coding systems handlers
34    6. End-of-line handlers    6. emacs-mule (old Emacs' internal format) handlers
35    7. C library functions    7. ISO2022 handlers
36    8. Emacs Lisp library functions    8. Shift-JIS and BIG5 handlers
37    9. Post-amble    9. CCL handlers
38      10. C library functions
39      11. Emacs Lisp library functions
40      12. Postamble
41    
42  */  */
43    
44  /*** 0. General comments ***/  /*** 0. General comments ***
45    
46    
47  /*** GENERAL NOTE on CODING SYSTEMS ***  CODING SYSTEM
48    
49    A coding system is an encoding mechanism for one or more character    A coding system is an object for an encoding mechanism that contains
50    sets.  Here's a list of coding systems which Emacs can handle.  When    information about how to convert byte sequences to character
51    we say "decode", it means converting some other coding system to    sequences and vice versa.  When we say "decode", it means converting
52    Emacs' internal format (emacs-mule), and when we say "encode",    a byte sequence of a specific coding system into a character
53    it means converting the coding system emacs-mule to some other    sequence that is represented by Emacs' internal coding system
54      `emacs-utf-8', and when we say "encode", it means converting a
55      character sequence of emacs-utf-8 to a byte sequence of a specific
56    coding system.    coding system.
57    
58    0. Emacs' internal format (emacs-mule)    In Emacs Lisp, a coding system is represented by a Lisp symbol.  In
59      C level, a coding system is represented by a vector of attributes
60      stored in the hash table Vcharset_hash_table.  The conversion from
61      coding system symbol to attributes vector is done by looking up
62      Vcharset_hash_table by the symbol.
63    
64    Emacs itself holds a multi-lingual character in buffers and strings    Coding systems are classified into the following types depending on
65    in a special format.  Details are described in section 2.    the encoding mechanism.  Here's a brief description of the types.
66    
67    1. ISO2022    o UTF-8
68    
69      o UTF-16
70    
71      o Charset-base coding system
72    
73      A coding system defined by one or more (coded) character sets.
74      Decoding and encoding are done by a code converter defined for each
75      character set.
76    
77      o Old Emacs internal format (emacs-mule)
78    
79      The coding system adopted by old versions of Emacs (20 and 21).
80    
81      o ISO2022-base coding system
82    
83    The most famous coding system for multiple character sets.  X's    The most famous coding system for multiple character sets.  X's
84    Compound Text, various EUCs (Extended Unix Code), and coding    Compound Text, various EUCs (Extended Unix Code), and coding systems
85    systems used in Internet communication such as ISO-2022-JP are    used in the Internet communication such as ISO-2022-JP are all
86    all variants of ISO2022.  Details are described in section 3.    variants of ISO2022.
87    
88    2. SJIS (or Shift-JIS or MS-Kanji-Code)    o SJIS (or Shift-JIS or MS-Kanji-Code)
89    
90    A coding system to encode character sets: ASCII, JISX0201, and    A coding system to encode character sets: ASCII, JISX0201, and
91    JISX0208.  Widely used for PC's in Japan.  Details are described in    JISX0208.  Widely used for PC's in Japan.  Details are described in
92    section 4.    section 8.
93    
94    3. BIG5    o BIG5
95    
96    A coding system to encode the character sets ASCII and Big5.  Widely    A coding system to encode character sets: ASCII and Big5.  Widely
97    used for Chinese (mainly in Taiwan and Hong Kong).  Details are    used for Chinese (mainly in Taiwan and Hong Kong).  Details are
98    described in section 4.  In this file, when we write "BIG5"    described in section 8.  In this file, when we write "big5" (all
99    (all uppercase), we mean the coding system, and when we write    lowercase), we mean the coding system, and when we write "Big5"
100    "Big5" (capitalized), we mean the character set.    (capitalized), we mean the character set.
   
   4. Raw text  
   
   A coding system for text containing random 8-bit code.  Emacs does  
   no code conversion on such text except for end-of-line format.  
   
   5. Other  
   
   If a user wants to read/write text encoded in a coding system not  
   listed above, he can supply a decoder and an encoder for it as CCL  
   (Code Conversion Language) programs.  Emacs executes the CCL program  
   while reading/writing.  
   
   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 section 6 for more details.  
101    
102  */    o CCL
103    
104      If a user wants to decode/encode text encoded in a coding system
105      not listed above, he can supply a decoder and an encoder for it in
106      CCL (Code Conversion Language) programs.  Emacs executes the CCL
107      program while decoding/encoding.
108    
109      o Raw-text
110    
111      A coding system for text containing raw eight-bit data.  Emacs
112      treats each byte of source text as a character (except for
113      end-of-line conversion).
114    
115      o No-conversion
116    
117  /*** GENERAL NOTES on END-OF-LINE FORMAT ***    Like raw text, but don't do end-of-line conversion.
118    
119    How end-of-line of text is encoded depends on the operating system.  
120    For instance, Unix's format is just one byte of `line-feed' code,  END-OF-LINE FORMAT
121    
122      How text end-of-line is encoded depends on operating system.  For
123      instance, Unix's format is just one byte of LF (line-feed) code,
124    whereas DOS's format is two-byte sequence of `carriage-return' and    whereas DOS's format is two-byte sequence of `carriage-return' and
125    `line-feed' codes.  MacOS's format is usually one byte of    `line-feed' codes.  MacOS's format is usually one byte of
126    `carriage-return'.    `carriage-return'.
127    
128    Since text character encoding and end-of-line encoding are    Since text character encoding and end-of-line encoding are
129    independent, any coding system described above can have any    independent, any coding system described above can take any format
130    end-of-line format.  So Emacs has information about end-of-line    of end-of-line (except for no-conversion).
131    format in each coding-system.  See section 6 for more details.  
132    STRUCT CODING_SYSTEM
133    
134      Before using a coding system for code conversion (i.e. decoding and
135      encoding), we setup a structure of type `struct coding_system'.
136      This structure keeps various information about a specific code
137      conversion (e.g. the location of source and destination data).
138    
139  */  */
140    
141    /* COMMON MACROS */
142    
143    
144  /*** GENERAL NOTES on `detect_coding_XXX ()' functions ***  /*** GENERAL NOTES on `detect_coding_XXX ()' functions ***
145    
146    These functions check if a text between SRC and SRC_END is encoded    These functions check if a byte sequence specified as a source in
147    in the coding system category XXX.  Each returns an integer value in    CODING conforms to the format of XXX, and update the members of
148    which appropriate flag bits for the category XXX are set.  The flag    DETECT_INFO.
149    bits are defined in macros CODING_CATEGORY_MASK_XXX.  Below is the  
150    template for these functions.  If MULTIBYTEP is nonzero, 8-bit codes    Return 1 if the byte sequence conforms to XXX, otherwise return 0.
151    of the range 0x80..0x9F are in multibyte form.  */  
152      Below is the template of these functions.  */
153    
154  #if 0  #if 0
155  int  static int
156  detect_coding_emacs_mule (src, src_end, multibytep)  detect_coding_XXX (coding, detect_info)
157       unsigned char *src, *src_end;       struct coding_system *coding;
158       int multibytep;       struct coding_detection_info *detect_info;
159  {  {
160    ...    unsigned char *src = coding->source;
161      unsigned char *src_end = coding->source + coding->src_bytes;
162      int multibytep = coding->src_multibyte;
163      int consumed_chars = 0;
164      int found = 0;
165      ...;
166    
167      while (1)
168        {
169          /* Get one byte from the source.  If the souce is exausted, jump
170             to no_more_source:.  */
171          ONE_MORE_BYTE (c);
172    
173          if (! __C_conforms_to_XXX___ (c))
174            break;
175          if (! __C_strongly_suggests_XXX__ (c))
176            found = CATEGORY_MASK_XXX;
177        }
178      /* The byte sequence is invalid for XXX.  */
179      detect_info->rejected |= CATEGORY_MASK_XXX;
180      return 0;
181    
182     no_more_source:
183      /* The source exausted successfully.  */
184      detect_info->found |= found;
185      return 1;
186  }  }
187  #endif  #endif
188    
189  /*** GENERAL NOTES on `decode_coding_XXX ()' functions ***  /*** GENERAL NOTES on `decode_coding_XXX ()' functions ***
190    
191    These functions decode SRC_BYTES length of unibyte text at SOURCE    These functions decode a byte sequence specified as a source by
192    encoded in CODING to Emacs' internal format.  The resulting    CODING.  The resulting multibyte text goes to a place pointed to by
193    multibyte text goes to a place pointed to by DESTINATION, the length    CODING->charbuf, the length of which should not exceed
194    of which should not exceed DST_BYTES.    CODING->charbuf_size;
195    
196    These functions set the information about original and decoded texts    These functions set the information of original and decoded texts in
197    in the members `produced', `produced_char', `consumed', and    CODING->consumed, CODING->consumed_char, and CODING->charbuf_used.
198    `consumed_char' of the structure *CODING.  They also set the member    They also set CODING->result to one of CODING_RESULT_XXX indicating
199    `result' to one of CODING_FINISH_XXX indicating how the decoding    how the decoding is finished.
200    finished.  
201      Below is the template of these functions.  */
   DST_BYTES zero means that the source area and destination area are  
   overlapped, which means that we can produce a decoded text until it  
   reaches the head of the not-yet-decoded source text.  
202    
   Below is a template for these functions.  */  
203  #if 0  #if 0
204  static void  static void
205  decode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)  decode_coding_XXXX (coding)
206       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *source, *destination;  
      int src_bytes, dst_bytes;  
207  {  {
208    ...    unsigned char *src = coding->source + coding->consumed;
209      unsigned char *src_end = coding->source + coding->src_bytes;
210      /* SRC_BASE remembers the start position in source in each loop.
211         The loop will be exited when there's not enough source code, or
212         when there's no room in CHARBUF for a decoded character.  */
213      unsigned char *src_base;
214      /* A buffer to produce decoded characters.  */
215      int *charbuf = coding->charbuf;
216      int *charbuf_end = charbuf + coding->charbuf_size;
217      int multibytep = coding->src_multibyte;
218    
219      while (1)
220        {
221          src_base = src;
222          if (charbuf < charbuf_end)
223            /* No more room to produce a decoded character.  */
224            break;
225          ONE_MORE_BYTE (c);
226          /* Decode it. */
227        }
228    
229     no_more_source:
230      if (src_base < src_end
231          && coding->mode & CODING_MODE_LAST_BLOCK)
232        /* If the source ends by partial bytes to construct a character,
233           treat them as eight-bit raw data.  */
234        while (src_base < src_end && charbuf < charbuf_end)
235          *charbuf++ = *src_base++;
236      /* Remember how many bytes and characters we consumed.  If the
237         source is multibyte, the bytes and chars are not identical.  */
238      coding->consumed = coding->consumed_char = src_base - coding->source;
239      /* Remember how many characters we produced.  */
240      coding->charbuf_used = charbuf - coding->charbuf;
241  }  }
242  #endif  #endif
243    
244  /*** GENERAL NOTES on `encode_coding_XXX ()' functions ***  /*** GENERAL NOTES on `encode_coding_XXX ()' functions ***
245    
246    These functions encode SRC_BYTES length text at SOURCE from Emacs'    These functions encode SRC_BYTES length text at SOURCE of Emacs'
247    internal multibyte format to CODING.  The resulting unibyte text    internal multibyte format by CODING.  The resulting byte sequence
248    goes to a place pointed to by DESTINATION, the length of which    goes to a place pointed to by DESTINATION, the length of which
249    should not exceed DST_BYTES.    should not exceed DST_BYTES.
250    
251    These functions set the information about original and encoded texts    These functions set the information of original and encoded texts in
252    in the members `produced', `produced_char', `consumed', and    the members produced, produced_char, consumed, and consumed_char of
253    `consumed_char' of the structure *CODING.  They also set the member    the structure *CODING.  They also set the member result to one of
254    `result' to one of CODING_FINISH_XXX indicating how the encoding    CODING_RESULT_XXX indicating how the encoding finished.
255    finished.  
256      DST_BYTES zero means that source area and destination area are
257    DST_BYTES zero means that the source area and destination area are    overlapped, which means that we can produce a encoded text until it
258    overlapped, which means that we can produce encoded text until it    reaches at the head of not-yet-encoded source text.
   reaches at the head of the not-yet-encoded source text.  
259    
260    Below is a template for these functions.  */    Below is a template of these functions.  */
261  #if 0  #if 0
262  static void  static void
263  encode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)  encode_coding_XXX (coding)
264       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *source, *destination;  
      int src_bytes, dst_bytes;  
265  {  {
266    ...    int multibytep = coding->dst_multibyte;
267      int *charbuf = coding->charbuf;
268      int *charbuf_end = charbuf->charbuf + coding->charbuf_used;
269      unsigned char *dst = coding->destination + coding->produced;
270      unsigned char *dst_end = coding->destination + coding->dst_bytes;
271      unsigned char *adjusted_dst_end = dst_end - _MAX_BYTES_PRODUCED_IN_LOOP_;
272      int produced_chars = 0;
273    
274      for (; charbuf < charbuf_end && dst < adjusted_dst_end; charbuf++)
275        {
276          int c = *charbuf;
277          /* Encode C into DST, and increment DST.  */
278        }
279     label_no_more_destination:
280      /* How many chars and bytes we produced.  */
281      coding->produced_char += produced_chars;
282      coding->produced = dst - coding->destination;
283  }  }
284  #endif  #endif
285    
 /*** COMMONLY USED MACROS ***/  
   
 /* The following two macros ONE_MORE_BYTE and TWO_MORE_BYTES safely  
    get one, two, and three bytes from the source text respectively.  
    If there are not enough bytes in the source, they jump to  
    `label_end_of_loop'.  The caller should set variables `coding',  
    `src' and `src_end' to appropriate pointer in advance.  These  
    macros are called from decoding routines `decode_coding_XXX', thus  
    it is assumed that the source text is unibyte.  */  
   
 #define ONE_MORE_BYTE(c1)                                       \  
   do {                                                          \  
     if (src >= src_end)                                         \  
       {                                                         \  
         coding->result = CODING_FINISH_INSUFFICIENT_SRC;        \  
         goto label_end_of_loop;                                 \  
       }                                                         \  
     c1 = *src++;                                                \  
   } while (0)  
   
 #define TWO_MORE_BYTES(c1, c2)                                  \  
   do {                                                          \  
     if (src + 1 >= src_end)                                     \  
       {                                                         \  
         coding->result = CODING_FINISH_INSUFFICIENT_SRC;        \  
         goto label_end_of_loop;                                 \  
       }                                                         \  
     c1 = *src++;                                                \  
     c2 = *src++;                                                \  
   } while (0)  
   
   
 /* Like ONE_MORE_BYTE, but 8-bit bytes of data at SRC are in multibyte  
    form if MULTIBYTEP is nonzero.  */  
   
 #define ONE_MORE_BYTE_CHECK_MULTIBYTE(c1, multibytep)           \  
   do {                                                          \  
     if (src >= src_end)                                         \  
       {                                                         \  
         coding->result = CODING_FINISH_INSUFFICIENT_SRC;        \  
         goto label_end_of_loop;                                 \  
       }                                                         \  
     c1 = *src++;                                                \  
     if (multibytep && c1 == LEADING_CODE_8_BIT_CONTROL)         \  
       c1 = *src++ - 0x20;                                       \  
   } while (0)  
   
 /* Set C to the next character at the source text pointed by `src'.  
    If there are not enough characters in the source, jump to  
    `label_end_of_loop'.  The caller should set variables `coding'  
    `src', `src_end', and `translation_table' to appropriate pointers  
    in advance.  This macro is used in encoding routines  
    `encode_coding_XXX', thus it assumes that the source text is in  
    multibyte form except for 8-bit characters.  8-bit characters are  
    in multibyte form if coding->src_multibyte is nonzero, else they  
    are represented by a single byte.  */  
   
 #define ONE_MORE_CHAR(c)                                        \  
   do {                                                          \  
     int len = src_end - src;                                    \  
     int bytes;                                                  \  
     if (len <= 0)                                               \  
       {                                                         \  
         coding->result = CODING_FINISH_INSUFFICIENT_SRC;        \  
         goto label_end_of_loop;                                 \  
       }                                                         \  
     if (coding->src_multibyte                                   \  
         || UNIBYTE_STR_AS_MULTIBYTE_P (src, len, bytes))        \  
       c = STRING_CHAR_AND_LENGTH (src, len, bytes);             \  
     else                                                        \  
       c = *src, bytes = 1;                                      \  
     if (!NILP (translation_table))                              \  
       c = translate_char (translation_table, c, -1, 0, 0);      \  
     src += bytes;                                               \  
   } while (0)  
   
   
 /* Produce a multibyte form of character C to `dst'.  Jump to  
    `label_end_of_loop' if there's not enough space at `dst'.  
   
    If we are now in the middle of a composition sequence, the decoded  
    character may be ALTCHAR (for the current composition).  In that  
    case, the character goes to coding->cmp_data->data instead of  
    `dst'.  
   
    This macro is used in decoding routines.  */  
   
 #define EMIT_CHAR(c)                                                    \  
   do {                                                                  \  
     if (! COMPOSING_P (coding)                                          \  
         || coding->composing == COMPOSITION_RELATIVE                    \  
         || coding->composing == COMPOSITION_WITH_RULE)                  \  
       {                                                                 \  
         int bytes = CHAR_BYTES (c);                                     \  
         if ((dst + bytes) > (dst_bytes ? dst_end : src))                \  
           {                                                             \  
             coding->result = CODING_FINISH_INSUFFICIENT_DST;            \  
             goto label_end_of_loop;                                     \  
           }                                                             \  
         dst += CHAR_STRING (c, dst);                                    \  
         coding->produced_char++;                                        \  
       }                                                                 \  
                                                                         \  
     if (COMPOSING_P (coding)                                            \  
         && coding->composing != COMPOSITION_RELATIVE)                   \  
       {                                                                 \  
         CODING_ADD_COMPOSITION_COMPONENT (coding, c);                   \  
         coding->composition_rule_follows                                \  
           = coding->composing != COMPOSITION_WITH_ALTCHARS;             \  
       }                                                                 \  
   } while (0)  
   
   
 #define EMIT_ONE_BYTE(c)                                        \  
   do {                                                          \  
     if (dst >= (dst_bytes ? dst_end : src))                     \  
       {                                                         \  
         coding->result = CODING_FINISH_INSUFFICIENT_DST;        \  
         goto label_end_of_loop;                                 \  
       }                                                         \  
     *dst++ = c;                                                 \  
   } while (0)  
   
 #define EMIT_TWO_BYTES(c1, c2)                                  \  
   do {                                                          \  
     if (dst + 2 > (dst_bytes ? dst_end : src))                  \  
       {                                                         \  
         coding->result = CODING_FINISH_INSUFFICIENT_DST;        \  
         goto label_end_of_loop;                                 \  
       }                                                         \  
     *dst++ = c1, *dst++ = c2;                                   \  
   } while (0)  
   
 #define EMIT_BYTES(from, to)                                    \  
   do {                                                          \  
     if (dst + (to - from) > (dst_bytes ? dst_end : src))        \  
       {                                                         \  
         coding->result = CODING_FINISH_INSUFFICIENT_DST;        \  
         goto label_end_of_loop;                                 \  
       }                                                         \  
     while (from < to)                                           \  
       *dst++ = *from++;                                         \  
   } while (0)  
   
286    
287  /*** 1. Preamble ***/  /*** 1. Preamble ***/
288    
 #ifdef emacs  
289  #include <config.h>  #include <config.h>
 #endif  
   
290  #include <stdio.h>  #include <stdio.h>
291    
 #ifdef emacs  
   
292  #include "lisp.h"  #include "lisp.h"
293  #include "buffer.h"  #include "buffer.h"
294    #include "character.h"
295  #include "charset.h"  #include "charset.h"
 #include "composite.h"  
296  #include "ccl.h"  #include "ccl.h"
297    #include "composite.h"
298  #include "coding.h"  #include "coding.h"
299  #include "window.h"  #include "window.h"
 #include "intervals.h"  
   
 #else  /* not emacs */  
   
 #include "mulelib.h"  
300    
301  #endif /* not emacs */  Lisp_Object Vcoding_system_hash_table;
302    
303  Lisp_Object Qcoding_system, Qeol_type;  Lisp_Object Qcoding_system, Qcoding_aliases, Qeol_type;
304    Lisp_Object Qunix, Qdos;
305    extern Lisp_Object Qmac;        /* frame.c */
306  Lisp_Object Qbuffer_file_coding_system;  Lisp_Object Qbuffer_file_coding_system;
307  Lisp_Object Qpost_read_conversion, Qpre_write_conversion;  Lisp_Object Qpost_read_conversion, Qpre_write_conversion;
308    Lisp_Object Qdefault_char;
309  Lisp_Object Qno_conversion, Qundecided;  Lisp_Object Qno_conversion, Qundecided;
310    Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qshift_jis, Qbig5;
311    Lisp_Object Qbig, Qlittle;
312  Lisp_Object Qcoding_system_history;  Lisp_Object Qcoding_system_history;
 Lisp_Object Qsafe_chars;  
313  Lisp_Object Qvalid_codes;  Lisp_Object Qvalid_codes;
314    Lisp_Object QCcategory;
315    
316  extern Lisp_Object Qinsert_file_contents, Qwrite_region;  extern Lisp_Object Qinsert_file_contents, Qwrite_region;
317  Lisp_Object Qcall_process, Qcall_process_region, Qprocess_argument;  Lisp_Object Qcall_process, Qcall_process_region, Qprocess_argument;
318  Lisp_Object Qstart_process, Qopen_network_stream;  Lisp_Object Qstart_process, Qopen_network_stream;
319  Lisp_Object Qtarget_idx;  Lisp_Object Qtarget_idx;
320    
 Lisp_Object Vselect_safe_coding_system_function;  
   
321  int coding_system_require_warning;  int coding_system_require_warning;
322    
323    Lisp_Object Vselect_safe_coding_system_function;
324    
325  /* Mnemonic string for each format of end-of-line.  */  /* Mnemonic string for each format of end-of-line.  */
326  Lisp_Object eol_mnemonic_unix, eol_mnemonic_dos, eol_mnemonic_mac;  Lisp_Object eol_mnemonic_unix, eol_mnemonic_dos, eol_mnemonic_mac;
327  /* Mnemonic string to indicate format of end-of-line is not yet  /* Mnemonic string to indicate format of end-of-line is not yet
328     decided.  */     decided.  */
329  Lisp_Object eol_mnemonic_undecided;  Lisp_Object eol_mnemonic_undecided;
330    
 /* 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;  
   
331  #ifdef emacs  #ifdef emacs
332    
 /* Information about which coding system is safe for which chars.  
    The value has the form (GENERIC-LIST . NON-GENERIC-ALIST).  
   
    GENERIC-LIST is a list of generic coding systems which can encode  
    any characters.  
   
    NON-GENERIC-ALIST is an alist of non generic coding systems vs the  
    corresponding char table that contains safe chars.  */  
 Lisp_Object Vcoding_system_safe_chars;  
   
333  Lisp_Object Vcoding_system_list, Vcoding_system_alist;  Lisp_Object Vcoding_system_list, Vcoding_system_alist;
334    
335  Lisp_Object Qcoding_system_p, Qcoding_system_error;  Lisp_Object Qcoding_system_p, Qcoding_system_error;
# Line 399  Lisp_Object Qcoding_system_p, Qcoding_sy Line 337  Lisp_Object Qcoding_system_p, Qcoding_sy
337  /* Coding system emacs-mule and raw-text are for converting only  /* Coding system emacs-mule and raw-text are for converting only
338     end-of-line format.  */     end-of-line format.  */
339  Lisp_Object Qemacs_mule, Qraw_text;  Lisp_Object Qemacs_mule, Qraw_text;
340    Lisp_Object Qutf_8_emacs;
 Lisp_Object Qutf_8;  
341    
342  /* Coding-systems are handed between Emacs Lisp programs and C internal  /* Coding-systems are handed between Emacs Lisp programs and C internal
343     routines by the following three variables.  */     routines by the following three variables.  */
# Line 434  struct coding_system safe_terminal_codin Line 371  struct coding_system safe_terminal_codin
371  /* Coding system of what is sent from terminal keyboard.  */  /* Coding system of what is sent from terminal keyboard.  */
372  struct coding_system keyboard_coding;  struct coding_system keyboard_coding;
373    
 /* Default coding system to be used to write a file.  */  
 struct coding_system default_buffer_file_coding;  
   
374  Lisp_Object Vfile_coding_system_alist;  Lisp_Object Vfile_coding_system_alist;
375  Lisp_Object Vprocess_coding_system_alist;  Lisp_Object Vprocess_coding_system_alist;
376  Lisp_Object Vnetwork_coding_system_alist;  Lisp_Object Vnetwork_coding_system_alist;
# Line 445  Lisp_Object Vlocale_coding_system; Line 379  Lisp_Object Vlocale_coding_system;
379    
380  #endif /* emacs */  #endif /* emacs */
381    
 Lisp_Object Qcoding_category, Qcoding_category_index;  
   
 /* List of symbols `coding-category-xxx' ordered by priority.  */  
 Lisp_Object Vcoding_category_list;  
   
 /* Table of coding categories (Lisp symbols).  */  
 Lisp_Object Vcoding_category_table;  
   
 /* Table of names of symbol for each coding-category.  */  
 char *coding_category_name[CODING_CATEGORY_IDX_MAX] = {  
   "coding-category-emacs-mule",  
   "coding-category-sjis",  
   "coding-category-iso-7",  
   "coding-category-iso-7-tight",  
   "coding-category-iso-8-1",  
   "coding-category-iso-8-2",  
   "coding-category-iso-7-else",  
   "coding-category-iso-8-else",  
   "coding-category-ccl",  
   "coding-category-big5",  
   "coding-category-utf-8",  
   "coding-category-utf-16-be",  
   "coding-category-utf-16-le",  
   "coding-category-raw-text",  
   "coding-category-binary"  
 };  
   
 /* Table of pointers to coding systems corresponding to each coding  
    categories.  */  
 struct coding_system *coding_system_table[CODING_CATEGORY_IDX_MAX];  
   
 /* Table of coding category masks.  Nth element is a mask for a coding  
    category of which priority is Nth.  */  
 static  
 int coding_priorities[CODING_CATEGORY_IDX_MAX];  
   
382  /* Flag to tell if we look up translation table on character code  /* Flag to tell if we look up translation table on character code
383     conversion.  */     conversion.  */
384  Lisp_Object Venable_character_translation;  Lisp_Object Venable_character_translation;
# Line 495  Lisp_Object Qtranslation_table_for_decod Line 393  Lisp_Object Qtranslation_table_for_decod
393  Lisp_Object Qtranslation_table_for_encode;  Lisp_Object Qtranslation_table_for_encode;
394    
395  /* Alist of charsets vs revision number.  */  /* Alist of charsets vs revision number.  */
396  Lisp_Object Vcharset_revision_alist;  static Lisp_Object Vcharset_revision_table;
397    
398  /* Default coding systems used for process I/O.  */  /* Default coding systems used for process I/O.  */
399  Lisp_Object Vdefault_process_coding_system;  Lisp_Object Vdefault_process_coding_system;
# Line 509  Lisp_Object Vtranslation_table_for_input Line 407  Lisp_Object Vtranslation_table_for_input
407     to avoid infinite recursive call.  */     to avoid infinite recursive call.  */
408  static int inhibit_pre_post_conversion;  static int inhibit_pre_post_conversion;
409    
410  Lisp_Object Qchar_coding_system;  /* Two special coding systems.  */
411    Lisp_Object Vsjis_coding_system;
412    Lisp_Object Vbig5_coding_system;
413    
414    
415    static int detect_coding_utf_8 P_ ((struct coding_system *,
416                                        struct coding_detection_info *info));
417    static void decode_coding_utf_8 P_ ((struct coding_system *));
418    static int encode_coding_utf_8 P_ ((struct coding_system *));
419    
420    static int detect_coding_utf_16 P_ ((struct coding_system *,
421                                         struct coding_detection_info *info));
422    static void decode_coding_utf_16 P_ ((struct coding_system *));
423    static int encode_coding_utf_16 P_ ((struct coding_system *));
424    
425    static int detect_coding_iso_2022 P_ ((struct coding_system *,
426                                           struct coding_detection_info *info));
427    static void decode_coding_iso_2022 P_ ((struct coding_system *));
428    static int encode_coding_iso_2022 P_ ((struct coding_system *));
429    
430    static int detect_coding_emacs_mule P_ ((struct coding_system *,
431                                             struct coding_detection_info *info));
432    static void decode_coding_emacs_mule P_ ((struct coding_system *));
433    static int encode_coding_emacs_mule P_ ((struct coding_system *));
434    
435    static int detect_coding_sjis P_ ((struct coding_system *,
436                                       struct coding_detection_info *info));
437    static void decode_coding_sjis P_ ((struct coding_system *));
438    static int encode_coding_sjis P_ ((struct coding_system *));
439    
440    static int detect_coding_big5 P_ ((struct coding_system *,
441                                       struct coding_detection_info *info));
442    static void decode_coding_big5 P_ ((struct coding_system *));
443    static int encode_coding_big5 P_ ((struct coding_system *));
444    
445    static int detect_coding_ccl P_ ((struct coding_system *,
446                                      struct coding_detection_info *info));
447    static void decode_coding_ccl P_ ((struct coding_system *));
448    static int encode_coding_ccl P_ ((struct coding_system *));
449    
450    static void decode_coding_raw_text P_ ((struct coding_system *));
451    static int encode_coding_raw_text P_ ((struct coding_system *));
452    
453    
454    /* ISO2022 section */
455    
456    #define CODING_ISO_INITIAL(coding, reg)                 \
457      (XINT (AREF (AREF (CODING_ID_ATTRS ((coding)->id),    \
458                         coding_attr_iso_initial),          \
459                   reg)))
460    
461    
462    #define CODING_ISO_REQUEST(coding, charset_id)  \
463      ((charset_id <= (coding)->max_charset_id      \
464        ? (coding)->safe_charsets[charset_id]       \
465        : -1))
466    
467    
468    #define CODING_ISO_FLAGS(coding)        \
469      ((coding)->spec.iso_2022.flags)
470    #define CODING_ISO_DESIGNATION(coding, reg)     \
471      ((coding)->spec.iso_2022.current_designation[reg])
472    #define CODING_ISO_INVOCATION(coding, plane)    \
473      ((coding)->spec.iso_2022.current_invocation[plane])
474    #define CODING_ISO_SINGLE_SHIFTING(coding)      \
475      ((coding)->spec.iso_2022.single_shifting)
476    #define CODING_ISO_BOL(coding)  \
477      ((coding)->spec.iso_2022.bol)
478    #define CODING_ISO_INVOKED_CHARSET(coding, plane)       \
479      CODING_ISO_DESIGNATION ((coding), CODING_ISO_INVOCATION ((coding), (plane)))
480    
481    /* Control characters of ISO2022.  */
482                            /* code */      /* function */
483    #define ISO_CODE_LF     0x0A            /* line-feed */
484    #define ISO_CODE_CR     0x0D            /* carriage-return */
485    #define ISO_CODE_SO     0x0E            /* shift-out */
486    #define ISO_CODE_SI     0x0F            /* shift-in */
487    #define ISO_CODE_SS2_7  0x19            /* single-shift-2 for 7-bit code */
488    #define ISO_CODE_ESC    0x1B            /* escape */
489    #define ISO_CODE_SS2    0x8E            /* single-shift-2 */
490    #define ISO_CODE_SS3    0x8F            /* single-shift-3 */
491    #define ISO_CODE_CSI    0x9B            /* control-sequence-introducer */
492    
493    /* All code (1-byte) of ISO2022 is classified into one of the
494       followings.  */
495    enum iso_code_class_type
496      {
497        ISO_control_0,              /* Control codes in the range
498                                       0x00..0x1F and 0x7F, except for the
499                                       following 5 codes.  */
500        ISO_carriage_return,        /* ISO_CODE_CR (0x0D) */
501        ISO_shift_out,              /* ISO_CODE_SO (0x0E) */
502        ISO_shift_in,               /* ISO_CODE_SI (0x0F) */
503        ISO_single_shift_2_7,       /* ISO_CODE_SS2_7 (0x19) */
504        ISO_escape,                 /* ISO_CODE_SO (0x1B) */
505        ISO_control_1,              /* Control codes in the range
506                                       0x80..0x9F, except for the
507                                       following 3 codes.  */
508        ISO_single_shift_2,         /* ISO_CODE_SS2 (0x8E) */
509        ISO_single_shift_3,         /* ISO_CODE_SS3 (0x8F) */
510        ISO_control_sequence_introducer, /* ISO_CODE_CSI (0x9B) */
511        ISO_0x20_or_0x7F,           /* Codes of the values 0x20 or 0x7F.  */
512        ISO_graphic_plane_0,        /* Graphic codes in the range 0x21..0x7E.  */
513        ISO_0xA0_or_0xFF,           /* Codes of the values 0xA0 or 0xFF.  */
514        ISO_graphic_plane_1         /* Graphic codes in the range 0xA1..0xFE.  */
515      };
516    
517  /* Return `safe-chars' property of CODING_SYSTEM (symbol).  Don't check  /** The macros CODING_ISO_FLAG_XXX defines a flag bit of the
518     its validity.  */      `iso-flags' attribute of an iso2022 coding system.  */
519    
520  Lisp_Object  /* If set, produce long-form designation sequence (e.g. ESC $ ( A)
521  coding_safe_chars (coding_system)     instead of the correct short-form sequence (e.g. ESC $ A).  */
522       Lisp_Object coding_system;  #define CODING_ISO_FLAG_LONG_FORM       0x0001
523    
524    /* If set, reset graphic planes and registers at end-of-line to the
525       initial state.  */
526    #define CODING_ISO_FLAG_RESET_AT_EOL    0x0002
527    
528    /* If set, reset graphic planes and registers before any control
529       characters to the initial state.  */
530    #define CODING_ISO_FLAG_RESET_AT_CNTL   0x0004
531    
532    /* If set, encode by 7-bit environment.  */
533    #define CODING_ISO_FLAG_SEVEN_BITS      0x0008
534    
535    /* If set, use locking-shift function.  */
536    #define CODING_ISO_FLAG_LOCKING_SHIFT   0x0010
537    
538    /* If set, use single-shift function.  Overwrite
539       CODING_ISO_FLAG_LOCKING_SHIFT.  */
540    #define CODING_ISO_FLAG_SINGLE_SHIFT    0x0020
541    
542    /* If set, use designation escape sequence.  */
543    #define CODING_ISO_FLAG_DESIGNATION     0x0040
544    
545    /* If set, produce revision number sequence.  */
546    #define CODING_ISO_FLAG_REVISION        0x0080
547    
548    /* If set, produce ISO6429's direction specifying sequence.  */
549    #define CODING_ISO_FLAG_DIRECTION       0x0100
550    
551    /* If set, assume designation states are reset at beginning of line on
552       output.  */
553    #define CODING_ISO_FLAG_INIT_AT_BOL     0x0200
554    
555    /* If set, designation sequence should be placed at beginning of line
556       on output.  */
557    #define CODING_ISO_FLAG_DESIGNATE_AT_BOL 0x0400
558    
559    /* If set, do not encode unsafe charactes on output.  */
560    #define CODING_ISO_FLAG_SAFE            0x0800
561    
562    /* If set, extra latin codes (128..159) are accepted as a valid code
563       on input.  */
564    #define CODING_ISO_FLAG_LATIN_EXTRA     0x1000
565    
566    #define CODING_ISO_FLAG_COMPOSITION     0x2000
567    
568    #define CODING_ISO_FLAG_EUC_TW_SHIFT    0x4000
569    
570    #define CODING_ISO_FLAG_USE_ROMAN       0x8000
571    
572    #define CODING_ISO_FLAG_USE_OLDJIS      0x10000
573    
574    #define CODING_ISO_FLAG_FULL_SUPPORT    0x100000
575    
576    /* A character to be produced on output if encoding of the original
577       character is prohibited by CODING_ISO_FLAG_SAFE.  */
578    #define CODING_INHIBIT_CHARACTER_SUBSTITUTION  '?'
579    
580    
581    /* UTF-16 section */
582    #define CODING_UTF_16_BOM(coding)       \
583      ((coding)->spec.utf_16.bom)
584    
585    #define CODING_UTF_16_ENDIAN(coding)    \
586      ((coding)->spec.utf_16.endian)
587    
588    #define CODING_UTF_16_SURROGATE(coding) \
589      ((coding)->spec.utf_16.surrogate)
590    
591    
592    /* CCL section */
593    #define CODING_CCL_DECODER(coding)      \
594      AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_decoder)
595    #define CODING_CCL_ENCODER(coding)      \
596      AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_encoder)
597    #define CODING_CCL_VALIDS(coding)                                          \
598      (SDATA (AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_valids)))
599    
600    /* Index for each coding category in `coding_categories' */
601    
602    enum coding_category
603      {
604        coding_category_iso_7,
605        coding_category_iso_7_tight,
606        coding_category_iso_8_1,
607        coding_category_iso_8_2,
608        coding_category_iso_7_else,
609        coding_category_iso_8_else,
610        coding_category_utf_8,
611        coding_category_utf_16_auto,
612        coding_category_utf_16_be,
613        coding_category_utf_16_le,
614        coding_category_utf_16_be_nosig,
615        coding_category_utf_16_le_nosig,
616        coding_category_charset,
617        coding_category_sjis,
618        coding_category_big5,
619        coding_category_ccl,
620        coding_category_emacs_mule,
621        /* All above are targets of code detection.  */
622        coding_category_raw_text,
623        coding_category_undecided,
624        coding_category_max
625      };
626    
627    /* Definitions of flag bits used in detect_coding_XXXX.  */
628    #define CATEGORY_MASK_ISO_7             (1 << coding_category_iso_7)
629    #define CATEGORY_MASK_ISO_7_TIGHT       (1 << coding_category_iso_7_tight)
630    #define CATEGORY_MASK_ISO_8_1           (1 << coding_category_iso_8_1)
631    #define CATEGORY_MASK_ISO_8_2           (1 << coding_category_iso_8_2)
632    #define CATEGORY_MASK_ISO_7_ELSE        (1 << coding_category_iso_7_else)
633    #define CATEGORY_MASK_ISO_8_ELSE        (1 << coding_category_iso_8_else)
634    #define CATEGORY_MASK_UTF_8             (1 << coding_category_utf_8)
635    #define CATEGORY_MASK_UTF_16_AUTO       (1 << coding_category_utf_16_auto)
636    #define CATEGORY_MASK_UTF_16_BE         (1 << coding_category_utf_16_be)
637    #define CATEGORY_MASK_UTF_16_LE         (1 << coding_category_utf_16_le)
638    #define CATEGORY_MASK_UTF_16_BE_NOSIG   (1 << coding_category_utf_16_be_nosig)
639    #define CATEGORY_MASK_UTF_16_LE_NOSIG   (1 << coding_category_utf_16_le_nosig)
640    #define CATEGORY_MASK_CHARSET           (1 << coding_category_charset)
641    #define CATEGORY_MASK_SJIS              (1 << coding_category_sjis)
642    #define CATEGORY_MASK_BIG5              (1 << coding_category_big5)
643    #define CATEGORY_MASK_CCL               (1 << coding_category_ccl)
644    #define CATEGORY_MASK_EMACS_MULE        (1 << coding_category_emacs_mule)
645    #define CATEGORY_MASK_RAW_TEXT          (1 << coding_category_raw_text)
646    
647    /* This value is returned if detect_coding_mask () find nothing other
648       than ASCII characters.  */
649    #define CATEGORY_MASK_ANY               \
650      (CATEGORY_MASK_ISO_7                  \
651       | CATEGORY_MASK_ISO_7_TIGHT          \
652       | CATEGORY_MASK_ISO_8_1              \
653       | CATEGORY_MASK_ISO_8_2              \
654       | CATEGORY_MASK_ISO_7_ELSE           \
655       | CATEGORY_MASK_ISO_8_ELSE           \
656       | CATEGORY_MASK_UTF_8                \
657       | CATEGORY_MASK_UTF_16_BE            \
658       | CATEGORY_MASK_UTF_16_LE            \
659       | CATEGORY_MASK_UTF_16_BE_NOSIG      \
660       | CATEGORY_MASK_UTF_16_LE_NOSIG      \
661       | CATEGORY_MASK_CHARSET              \
662       | CATEGORY_MASK_SJIS                 \
663       | CATEGORY_MASK_BIG5                 \
664       | CATEGORY_MASK_CCL                  \
665       | CATEGORY_MASK_EMACS_MULE)
666    
667    
668    #define CATEGORY_MASK_ISO_7BIT \
669      (CATEGORY_MASK_ISO_7 | CATEGORY_MASK_ISO_7_TIGHT)
670    
671    #define CATEGORY_MASK_ISO_8BIT \
672      (CATEGORY_MASK_ISO_8_1 | CATEGORY_MASK_ISO_8_2)
673    
674    #define CATEGORY_MASK_ISO_ELSE \
675      (CATEGORY_MASK_ISO_7_ELSE | CATEGORY_MASK_ISO_8_ELSE)
676    
677    #define CATEGORY_MASK_ISO_ESCAPE        \
678      (CATEGORY_MASK_ISO_7                  \
679       | CATEGORY_MASK_ISO_7_TIGHT          \
680       | CATEGORY_MASK_ISO_7_ELSE           \
681       | CATEGORY_MASK_ISO_8_ELSE)
682    
683    #define CATEGORY_MASK_ISO       \
684      (  CATEGORY_MASK_ISO_7BIT     \
685         | CATEGORY_MASK_ISO_8BIT   \
686         | CATEGORY_MASK_ISO_ELSE)
687    
688    #define CATEGORY_MASK_UTF_16            \
689      (CATEGORY_MASK_UTF_16_BE              \
690       | CATEGORY_MASK_UTF_16_LE            \
691       | CATEGORY_MASK_UTF_16_BE_NOSIG      \
692       | CATEGORY_MASK_UTF_16_LE_NOSIG)
693    
694    
695    /* List of symbols `coding-category-xxx' ordered by priority.  This
696       variable is exposed to Emacs Lisp.  */
697    static Lisp_Object Vcoding_category_list;
698    
699    /* Table of coding categories (Lisp symbols).  This variable is for
700       internal use oly.  */
701    static Lisp_Object Vcoding_category_table;
702    
703    /* Table of coding-categories ordered by priority.  */
704    static enum coding_category coding_priorities[coding_category_max];
705    
706    /* Nth element is a coding context for the coding system bound to the
707       Nth coding category.  */
708    static struct coding_system coding_categories[coding_category_max];
709    
710    /*** Commonly used macros and functions ***/
711    
712    #ifndef min
713    #define min(a, b) ((a) < (b) ? (a) : (b))
714    #endif
715    #ifndef max
716    #define max(a, b) ((a) > (b) ? (a) : (b))
717    #endif
718    
719    #define CODING_GET_INFO(coding, attrs, eol_type, charset_list)  \
720      do {                                                          \
721        attrs = CODING_ID_ATTRS (coding->id);                       \
722        eol_type = CODING_ID_EOL_TYPE (coding->id);                 \
723        if (VECTORP (eol_type))                                     \
724          eol_type = Qunix;                                         \
725        charset_list = CODING_ATTR_CHARSET_LIST (attrs);            \
726      } while (0)
727    
728    
729    /* Safely get one byte from the source text pointed by SRC which ends
730       at SRC_END, and set C to that byte.  If there are not enough bytes
731       in the source, it jumps to `no_more_source'.  The caller
732       should declare and set these variables appropriately in advance:
733            src, src_end, multibytep
734    */
735    
736    #define ONE_MORE_BYTE(c)                                        \
737      do {                                                          \
738        if (src == src_end)                                         \
739          {                                                         \
740            if (src_base < src)                                     \
741              coding->result = CODING_RESULT_INSUFFICIENT_SRC;      \
742            goto no_more_source;                                    \
743          }                                                         \
744        c = *src++;                                                 \
745        if (multibytep && (c & 0x80))                               \
746          {                                                         \
747            if ((c & 0xFE) != 0xC0)                                 \
748              error ("Undecodable char found");                     \
749            c = ((c & 1) << 6) | *src++;                            \
750          }                                                         \
751        consumed_chars++;                                           \
752      } while (0)
753    
754    
755    #define ONE_MORE_BYTE_NO_CHECK(c)               \
756      do {                                          \
757        c = *src++;                                 \
758        if (multibytep && (c & 0x80))               \
759          {                                         \
760            if ((c & 0xFE) != 0xC0)                 \
761              error ("Undecodable char found");     \
762            c = ((c & 1) << 6) | *src++;            \
763          }                                         \
764        consumed_chars++;                           \
765      } while (0)
766    
767    
768    /* Store a byte C in the place pointed by DST and increment DST to the
769       next free point, and increment PRODUCED_CHARS.  The caller should
770       assure that C is 0..127, and declare and set the variable `dst'
771       appropriately in advance.
772    */
773    
774    
775    #define EMIT_ONE_ASCII_BYTE(c)  \
776      do {                          \
777        produced_chars++;           \
778        *dst++ = (c);               \
779      } while (0)
780    
781    
782    /* Like EMIT_ONE_ASCII_BYTE byt store two bytes; C1 and C2.  */
783    
784    #define EMIT_TWO_ASCII_BYTES(c1, c2)    \
785      do {                                  \
786        produced_chars += 2;                \
787        *dst++ = (c1), *dst++ = (c2);       \
788      } while (0)
789    
790    
791    /* Store a byte C in the place pointed by DST and increment DST to the
792       next free point, and increment PRODUCED_CHARS.  If MULTIBYTEP is
793       nonzero, store in an appropriate multibyte from.  The caller should
794       declare and set the variables `dst' and `multibytep' appropriately
795       in advance.  */
796    
797    #define EMIT_ONE_BYTE(c)                \
798      do {                                  \
799        produced_chars++;                   \
800        if (multibytep)                     \
801          {                                 \
802            int ch = (c);                   \
803            if (ch >= 0x80)                 \
804              ch = BYTE8_TO_CHAR (ch);      \
805            CHAR_STRING_ADVANCE (ch, dst);  \
806          }                                 \
807        else                                \
808          *dst++ = (c);                     \
809      } while (0)
810    
811    
812    /* Like EMIT_ONE_BYTE, but emit two bytes; C1 and C2.  */
813    
814    #define EMIT_TWO_BYTES(c1, c2)          \
815      do {                                  \
816        produced_chars += 2;                \
817        if (multibytep)                     \
818          {                                 \
819            int ch;                         \
820                                            \
821            ch = (c1);                      \
822            if (ch >= 0x80)                 \
823              ch = BYTE8_TO_CHAR (ch);      \
824            CHAR_STRING_ADVANCE (ch, dst);  \
825            ch = (c2);                      \
826            if (ch >= 0x80)                 \
827              ch = BYTE8_TO_CHAR (ch);      \
828            CHAR_STRING_ADVANCE (ch, dst);  \
829          }                                 \
830        else                                \
831          {                                 \
832            *dst++ = (c1);                  \
833            *dst++ = (c2);                  \
834          }                                 \
835      } while (0)
836    
837    
838    #define EMIT_THREE_BYTES(c1, c2, c3)    \
839      do {                                  \
840        EMIT_ONE_BYTE (c1);                 \
841        EMIT_TWO_BYTES (c2, c3);            \
842      } while (0)
843    
844    
845    #define EMIT_FOUR_BYTES(c1, c2, c3, c4)         \
846      do {                                          \
847        EMIT_TWO_BYTES (c1, c2);                    \
848        EMIT_TWO_BYTES (c3, c4);                    \
849      } while (0)
850    
851    
852    #define CODING_DECODE_CHAR(coding, src, src_base, src_end, charset, code, c) \
853      do {                                                                       \
854        charset_map_loaded = 0;                                                  \
855        c = DECODE_CHAR (charset, code);                                         \
856        if (charset_map_loaded)                                                  \
857          {                                                                      \
858            const unsigned char *orig = coding->source;                          \
859            EMACS_INT offset;                                                    \
860                                                                                 \
861            coding_set_source (coding);                                          \
862            offset = coding->source - orig;                                      \
863            src += offset;                                                       \
864            src_base += offset;                                                  \
865            src_end += offset;                                                   \
866          }                                                                      \
867      } while (0)
868    
869    
870    #define ASSURE_DESTINATION(bytes)                               \
871      do {                                                          \
872        if (dst + (bytes) >= dst_end)                               \
873          {                                                         \
874            int more_bytes = charbuf_end - charbuf + (bytes);       \
875                                                                    \
876            dst = alloc_destination (coding, more_bytes, dst);      \
877            dst_end = coding->destination + coding->dst_bytes;      \
878          }                                                         \
879      } while (0)
880    
881    
882    
883    static void
884    coding_set_source (coding)
885         struct coding_system *coding;
886    {
887      if (BUFFERP (coding->src_object))
888        {
889          struct buffer *buf = XBUFFER (coding->src_object);
890    
891          if (coding->src_pos < 0)
892            coding->source = BUF_GAP_END_ADDR (buf) + coding->src_pos_byte;
893          else
894            coding->source = BUF_BYTE_ADDRESS (buf, coding->src_pos_byte);
895        }
896      else if (STRINGP (coding->src_object))
897        {
898          coding->source = SDATA (coding->src_object) + coding->src_pos_byte;
899        }
900      else
901        /* Otherwise, the source is C string and is never relocated
902           automatically.  Thus we don't have to update anything.  */
903        ;
904    }
905    
906    static void
907    coding_set_destination (coding)
908         struct coding_system *coding;
909    {
910      if (BUFFERP (coding->dst_object))
911        {
912          if (coding->src_pos < 0)
913            {
914              coding->destination = BEG_ADDR + coding->dst_pos_byte - 1;
915              coding->dst_bytes = (GAP_END_ADDR
916                                   - (coding->src_bytes - coding->consumed)
917                                   - coding->destination);
918            }
919          else
920            {
921              /* We are sure that coding->dst_pos_byte is before the gap
922                 of the buffer. */
923              coding->destination = (BUF_BEG_ADDR (XBUFFER (coding->dst_object))
924                                     + coding->dst_pos_byte - 1);
925              coding->dst_bytes = (BUF_GAP_END_ADDR (XBUFFER (coding->dst_object))
926                                   - coding->destination);
927            }
928        }
929      else
930        /* Otherwise, the destination is C string and is never relocated
931           automatically.  Thus we don't have to update anything.  */
932        ;
933    }
934    
935    
936    static void
937    coding_alloc_by_realloc (coding, bytes)
938         struct coding_system *coding;
939         EMACS_INT bytes;
940    {
941      coding->destination = (unsigned char *) xrealloc (coding->destination,
942                                                        coding->dst_bytes + bytes);
943      coding->dst_bytes += bytes;
944    }
945    
946    static void
947    coding_alloc_by_making_gap (coding, bytes)
948         struct coding_system *coding;
949         EMACS_INT bytes;
950    {
951      if (BUFFERP (coding->dst_object)
952          && EQ (coding->src_object, coding->dst_object))
953        {
954          EMACS_INT add = coding->src_bytes - coding->consumed;
955    
956          GAP_SIZE -= add; ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
957          make_gap (bytes);
958          GAP_SIZE += add; ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;
959        }
960      else
961        {
962          Lisp_Object this_buffer;
963    
964          this_buffer = Fcurrent_buffer ();
965          set_buffer_internal (XBUFFER (coding->dst_object));
966          make_gap (bytes);
967          set_buffer_internal (XBUFFER (this_buffer));
968        }
969    }
970    
971    
972    static unsigned char *
973    alloc_destination (coding, nbytes, dst)
974         struct coding_system *coding;
975         int nbytes;
976         unsigned char *dst;
977    {
978      EMACS_INT offset = dst - coding->destination;
979    
980      if (BUFFERP (coding->dst_object))
981        coding_alloc_by_making_gap (coding, nbytes);
982      else
983        coding_alloc_by_realloc (coding, nbytes);
984      coding->result = CODING_RESULT_SUCCESS;
985      coding_set_destination (coding);
986      dst = coding->destination + offset;
987      return dst;
988    }
989    
990    /** Macros for annotations.  */
991    
992    /* Maximum length of annotation data (sum of annotations for
993       composition and charset).  */
994    #define MAX_ANNOTATION_LENGTH (5 + (MAX_COMPOSITION_COMPONENTS * 2) - 1 + 5)
995    
996    /* An annotation data is stored in the array coding->charbuf in this
997       format:
998         [ -LENGTH ANNOTATION_MASK FROM TO ... ]
999       LENGTH is the number of elements in the annotation.
1000       ANNOTATION_MASK is one of CODING_ANNOTATE_XXX_MASK.
1001       FROM and TO specify the range of text annotated.  They are relative
1002       to coding->src_pos (on encoding) or coding->dst_pos (on decoding).
1003    
1004       The format of the following elements depend on ANNOTATION_MASK.
1005    
1006       In the case of CODING_ANNOTATE_COMPOSITION_MASK, these elements
1007       follows:
1008         ... METHOD [ COMPOSITION-COMPONENTS ... ]
1009       METHOD is one of enum composition_method.
1010       Optionnal COMPOSITION-COMPONENTS are characters and composition
1011       rules.
1012    
1013       In the case of CODING_ANNOTATE_CHARSET_MASK, one element CHARSET-ID
1014       follows.  */
1015    
1016    #define ADD_ANNOTATION_DATA(buf, len, mask, from, to)   \
1017      do {                                                  \
1018        *(buf)++ = -(len);                                  \
1019        *(buf)++ = (mask);                                  \
1020        *(buf)++ = (from);                                  \
1021        *(buf)++ = (to);                                    \
1022        coding->annotated = 1;                              \
1023      } while (0);
1024    
1025    #define ADD_COMPOSITION_DATA(buf, from, to, method)                           \
1026      do {                                                                        \
1027        ADD_ANNOTATION_DATA (buf, 5, CODING_ANNOTATE_COMPOSITION_MASK, from, to); \
1028        *buf++ = method;                                                          \
1029      } while (0)
1030    
1031    
1032    #define ADD_CHARSET_DATA(buf, from, to, id)                               \
1033      do {                                                                    \
1034        ADD_ANNOTATION_DATA (buf, 5, CODING_ANNOTATE_CHARSET_MASK, from, to); \
1035        *buf++ = id;                                                          \
1036      } while (0)
1037    
1038    
1039    /*** 2. Emacs' internal format (emacs-utf-8) ***/
1040    
1041    
1042    
1043    
1044    /*** 3. UTF-8 ***/
1045    
1046    /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
1047       Check if a text is encoded in UTF-8.  If it is, return 1, else
1048       return 0.  */
1049    
1050    #define UTF_8_1_OCTET_P(c)         ((c) < 0x80)
1051    #define UTF_8_EXTRA_OCTET_P(c)     (((c) & 0xC0) == 0x80)
1052    #define UTF_8_2_OCTET_LEADING_P(c) (((c) & 0xE0) == 0xC0)
1053    #define UTF_8_3_OCTET_LEADING_P(c) (((c) & 0xF0) == 0xE0)
1054    #define UTF_8_4_OCTET_LEADING_P(c) (((c) & 0xF8) == 0xF0)
1055    #define UTF_8_5_OCTET_LEADING_P(c) (((c) & 0xFC) == 0xF8)
1056    
1057    static int
1058    detect_coding_utf_8 (coding, detect_info)
1059         struct coding_system *coding;
1060         struct coding_detection_info *detect_info;
1061    {
1062      const unsigned char *src = coding->source, *src_base = src;
1063      const unsigned char *src_end = coding->source + coding->src_bytes;
1064      int multibytep = coding->src_multibyte;
1065      int consumed_chars = 0;
1066      int found = 0;
1067      int incomplete;
1068    
1069      detect_info->checked |= CATEGORY_MASK_UTF_8;
1070      /* A coding system of this category is always ASCII compatible.  */
1071      src += coding->head_ascii;
1072    
1073      while (1)
1074        {
1075          int c, c1, c2, c3, c4;
1076    
1077          incomplete = 0;
1078          ONE_MORE_BYTE (c);
1079          if (UTF_8_1_OCTET_P (c))
1080            continue;
1081          incomplete = 1;
1082          ONE_MORE_BYTE (c1);
1083          if (! UTF_8_EXTRA_OCTET_P (c1))
1084            break;
1085          if (UTF_8_2_OCTET_LEADING_P (c))
1086            {
1087              found = CATEGORY_MASK_UTF_8;
1088              continue;
1089            }
1090          ONE_MORE_BYTE (c2);
1091          if (! UTF_8_EXTRA_OCTET_P (c2))
1092            break;
1093          if (UTF_8_3_OCTET_LEADING_P (c))
1094            {
1095              found = CATEGORY_MASK_UTF_8;
1096              continue;
1097            }
1098          ONE_MORE_BYTE (c3);
1099          if (! UTF_8_EXTRA_OCTET_P (c3))
1100            break;
1101          if (UTF_8_4_OCTET_LEADING_P (c))
1102            {
1103              found = CATEGORY_MASK_UTF_8;
1104              continue;
1105            }
1106          ONE_MORE_BYTE (c4);
1107          if (! UTF_8_EXTRA_OCTET_P (c4))
1108            break;
1109          if (UTF_8_5_OCTET_LEADING_P (c))
1110            {
1111              found = CATEGORY_MASK_UTF_8;
1112              continue;
1113            }
1114          break;
1115        }
1116      detect_info->rejected |= CATEGORY_MASK_UTF_8;
1117      return 0;
1118    
1119     no_more_source:
1120      if (incomplete && coding->mode & CODING_MODE_LAST_BLOCK)
1121        {
1122          detect_info->rejected |= CATEGORY_MASK_UTF_8;
1123          return 0;
1124        }
1125      detect_info->found |= found;
1126      return 1;
1127    }
1128    
1129    
1130    static void
1131    decode_coding_utf_8 (coding)
1132         struct coding_system *coding;
1133    {
1134      const unsigned char *src = coding->source + coding->consumed;
1135      const unsigned char *src_end = coding->source + coding->src_bytes;
1136      const unsigned char *src_base;
1137      int *charbuf = coding->charbuf;
1138      int *charbuf_end = charbuf + coding->charbuf_size;
1139      int consumed_chars = 0, consumed_chars_base;
1140      int multibytep = coding->src_multibyte;
1141      Lisp_Object attr, eol_type, charset_list;
1142    
1143      CODING_GET_INFO (coding, attr, eol_type, charset_list);
1144    
1145      while (1)
1146        {
1147          int c, c1, c2, c3, c4, c5;
1148    
1149          src_base = src;
1150          consumed_chars_base = consumed_chars;
1151    
1152          if (charbuf >= charbuf_end)
1153            break;
1154    
1155          ONE_MORE_BYTE (c1);
1156          if (UTF_8_1_OCTET_P(c1))
1157            {
1158              c = c1;
1159              if (c == '\r')
1160                {
1161                  if (EQ (eol_type, Qdos))
1162                    {
1163                      if (src == src_end)
1164                        {
1165                          coding->result = CODING_RESULT_INSUFFICIENT_SRC;
1166                          goto no_more_source;
1167                        }
1168                      if (*src == '\n')
1169                        ONE_MORE_BYTE (c);
1170                    }
1171                  else if (EQ (eol_type, Qmac))
1172                    c = '\n';
1173                }
1174            }
1175          else
1176            {
1177              ONE_MORE_BYTE (c2);
1178              if (! UTF_8_EXTRA_OCTET_P (c2))
1179                goto invalid_code;
1180              if (UTF_8_2_OCTET_LEADING_P (c1))
1181                {
1182                  c = ((c1 & 0x1F) << 6) | (c2 & 0x3F);
1183                  /* Reject overlong sequences here and below.  Encoders
1184                     producing them are incorrect, they can be misleading,
1185                     and they mess up read/write invariance.  */
1186                  if (c < 128)
1187                    goto invalid_code;
1188                }
1189              else
1190                {
1191                  ONE_MORE_BYTE (c3);
1192                  if (! UTF_8_EXTRA_OCTET_P (c3))
1193                    goto invalid_code;
1194                  if (UTF_8_3_OCTET_LEADING_P (c1))
1195                    {
1196                      c = (((c1 & 0xF) << 12)
1197                           | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
1198                      if (c < 0x800
1199                          || (c >= 0xd800 && c < 0xe000)) /* surrogates (invalid) */
1200                        goto invalid_code;
1201                    }
1202                  else
1203                    {
1204                      ONE_MORE_BYTE (c4);
1205                      if (! UTF_8_EXTRA_OCTET_P (c4))
1206                        goto invalid_code;
1207                      if (UTF_8_4_OCTET_LEADING_P (c1))
1208                        {
1209                        c = (((c1 & 0x7) << 18) | ((c2 & 0x3F) << 12)
1210                             | ((c3 & 0x3F) << 6) | (c4 & 0x3F));
1211                        if (c < 0x10000)
1212                          goto invalid_code;
1213                        }
1214                      else
1215                        {
1216                          ONE_MORE_BYTE (c5);
1217                          if (! UTF_8_EXTRA_OCTET_P (c5))
1218                            goto invalid_code;
1219                          if (UTF_8_5_OCTET_LEADING_P (c1))
1220                            {
1221                              c = (((c1 & 0x3) << 24) | ((c2 & 0x3F) << 18)
1222                                   | ((c3 & 0x3F) << 12) | ((c4 & 0x3F) << 6)
1223                                   | (c5 & 0x3F));
1224                              if ((c > MAX_CHAR) || (c < 0x200000))
1225                                goto invalid_code;
1226                            }
1227                          else
1228                            goto invalid_code;
1229                        }
1230                    }
1231                }
1232            }
1233    
1234          *charbuf++ = c;
1235          continue;
1236    
1237        invalid_code:
1238          src = src_base;
1239          consumed_chars = consumed_chars_base;
1240          ONE_MORE_BYTE (c);
1241          *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
1242          coding->errors++;
1243        }
1244    
1245     no_more_source:
1246      coding->consumed_char += consumed_chars_base;
1247      coding->consumed = src_base - coding->source;
1248      coding->charbuf_used = charbuf - coding->charbuf;
1249    }
1250    
1251    
1252    static int
1253    encode_coding_utf_8 (coding)
1254         struct coding_system *coding;
1255    {
1256      int multibytep = coding->dst_multibyte;
1257      int *charbuf = coding->charbuf;
1258      int *charbuf_end = charbuf + coding->charbuf_used;
1259      unsigned char *dst = coding->destination + coding->produced;
1260      unsigned char *dst_end = coding->destination + coding->dst_bytes;
1261      int produced_chars = 0;
1262      int c;
1263    
1264      if (multibytep)
1265        {
1266          int safe_room = MAX_MULTIBYTE_LENGTH * 2;
1267    
1268          while (charbuf < charbuf_end)
1269            {
1270              unsigned char str[MAX_MULTIBYTE_LENGTH], *p, *pend = str;
1271    
1272              ASSURE_DESTINATION (safe_room);
1273              c = *charbuf++;
1274              if (CHAR_BYTE8_P (c))
1275                {
1276                  c = CHAR_TO_BYTE8 (c);
1277                  EMIT_ONE_BYTE (c);
1278                }
1279              else
1280                {
1281                  CHAR_STRING_ADVANCE (c, pend);
1282                  for (p = str; p < pend; p++)
1283                    EMIT_ONE_BYTE (*p);
1284                }
1285            }
1286        }
1287      else
1288        {
1289          int safe_room = MAX_MULTIBYTE_LENGTH;
1290    
1291          while (charbuf < charbuf_end)
1292            {
1293              ASSURE_DESTINATION (safe_room);
1294              c = *charbuf++;
1295              dst += CHAR_STRING (c, dst);
1296              produced_chars++;
1297            }
1298        }
1299      coding->result = CODING_RESULT_SUCCESS;
1300      coding->produced_char += produced_chars;
1301      coding->produced = dst - coding->destination;
1302      return 0;
1303    }
1304    
1305    
1306    /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
1307       Check if a text is encoded in one of UTF-16 based coding systems.
1308       If it is, return 1, else return 0.  */
1309    
1310    #define UTF_16_HIGH_SURROGATE_P(val) \
1311      (((val) & 0xFC00) == 0xD800)
1312    
1313    #define UTF_16_LOW_SURROGATE_P(val) \
1314      (((val) & 0xFC00) == 0xDC00)
1315    
1316    #define UTF_16_INVALID_P(val)   \
1317      (((val) == 0xFFFE)            \
1318       || ((val) == 0xFFFF)         \
1319       || UTF_16_LOW_SURROGATE_P (val))
1320    
1321    
1322    static int
1323    detect_coding_utf_16 (coding, detect_info)
1324         struct coding_system *coding;
1325         struct coding_detection_info *detect_info;
1326    {
1327      const unsigned char *src = coding->source, *src_base = src;
1328      const unsigned char *src_end = coding->source + coding->src_bytes;
1329      int multibytep = coding->src_multibyte;
1330      int consumed_chars = 0;
1331      int c1, c2;
1332    
1333      detect_info->checked |= CATEGORY_MASK_UTF_16;
1334    
1335      if (coding->mode & CODING_MODE_LAST_BLOCK
1336          && (coding->src_bytes & 1))
1337        {
1338          detect_info->rejected |= CATEGORY_MASK_UTF_16;
1339          return 0;
1340        }
1341      ONE_MORE_BYTE (c1);
1342      ONE_MORE_BYTE (c2);
1343    
1344      if ((c1 == 0xFF) && (c2 == 0xFE))
1345        {
1346          detect_info->found |= (CATEGORY_MASK_UTF_16_LE
1347                                 | CATEGORY_MASK_UTF_16_AUTO);
1348          detect_info->rejected |= CATEGORY_MASK_UTF_16_BE;
1349        }
1350      else if ((c1 == 0xFE) && (c2 == 0xFF))
1351        {
1352          detect_info->found |= (CATEGORY_MASK_UTF_16_BE
1353                                 | CATEGORY_MASK_UTF_16_AUTO);
1354          detect_info->rejected |= CATEGORY_MASK_UTF_16_LE;
1355        }
1356     no_more_source:
1357      return 1;
1358    }
1359    
1360    static void
1361    decode_coding_utf_16 (coding)
1362         struct coding_system *coding;
1363  {  {
1364    Lisp_Object coding_spec, plist, safe_chars;    const unsigned char *src = coding->source + coding->consumed;
1365      const unsigned char *src_end = coding->source + coding->src_bytes;
1366      const unsigned char *src_base;
1367      int *charbuf = coding->charbuf;
1368      int *charbuf_end = charbuf + coding->charbuf_size;
1369      int consumed_chars = 0, consumed_chars_base;
1370      int multibytep = coding->src_multibyte;
1371      enum utf_16_bom_type bom = CODING_UTF_16_BOM (coding);
1372      enum utf_16_endian_type endian = CODING_UTF_16_ENDIAN (coding);
1373      int surrogate = CODING_UTF_16_SURROGATE (coding);
1374      Lisp_Object attr, eol_type, charset_list;
1375    
1376      CODING_GET_INFO (coding, attr, eol_type, charset_list);
1377    
1378    coding_spec = Fget (coding_system, Qcoding_system);    if (bom == utf_16_with_bom)
1379    plist = XVECTOR (coding_spec)->contents[3];      {
1380    safe_chars = Fplist_get (XVECTOR (coding_spec)->contents[3], Qsafe_chars);        int c, c1, c2;
1381    return (CHAR_TABLE_P (safe_chars) ? safe_chars : Qt);  
1382          src_base = src;
1383          ONE_MORE_BYTE (c1);
1384          ONE_MORE_BYTE (c2);
1385          c = (c1 << 8) | c2;
1386    
1387          if (endian == utf_16_big_endian
1388              ? c != 0xFEFF : c != 0xFFFE)
1389            {
1390              /* The first two bytes are not BOM.  Treat them as bytes
1391                 for a normal character.  */
1392              src = src_base;
1393              coding->errors++;
1394            }
1395          CODING_UTF_16_BOM (coding) = utf_16_without_bom;
1396        }
1397      else if (bom == utf_16_detect_bom)
1398        {
1399          /* We have already tried to detect BOM and failed in
1400             detect_coding.  */
1401          CODING_UTF_16_BOM (coding) = utf_16_without_bom;
1402        }
1403    
1404      while (1)
1405        {
1406          int c, c1, c2;
1407    
1408          src_base = src;
1409          consumed_chars_base = consumed_chars;
1410    
1411          if (charbuf + 2 >= charbuf_end)
1412            break;
1413    
1414          ONE_MORE_BYTE (c1);
1415          ONE_MORE_BYTE (c2);
1416          c = (endian == utf_16_big_endian
1417               ? ((c1 << 8) | c2) : ((c2 << 8) | c1));
1418          if (surrogate)
1419            {
1420              if (! UTF_16_LOW_SURROGATE_P (c))
1421                {
1422                  if (endian == utf_16_big_endian)
1423                    c1 = surrogate >> 8, c2 = surrogate & 0xFF;
1424                  else
1425                    c1 = surrogate & 0xFF, c2 = surrogate >> 8;
1426                  *charbuf++ = c1;
1427                  *charbuf++ = c2;
1428                  coding->errors++;
1429                  if (UTF_16_HIGH_SURROGATE_P (c))
1430                    CODING_UTF_16_SURROGATE (coding) = surrogate = c;
1431                  else
1432                    *charbuf++ = c;
1433                }
1434              else
1435                {
1436                  c = ((surrogate - 0xD800) << 10) | (c - 0xDC00);
1437                  CODING_UTF_16_SURROGATE (coding) = surrogate = 0;
1438                  *charbuf++ = c;
1439                }
1440            }
1441          else
1442            {
1443              if (UTF_16_HIGH_SURROGATE_P (c))
1444                CODING_UTF_16_SURROGATE (coding) = surrogate = c;
1445              else
1446                *charbuf++ = c;
1447            }
1448        }
1449    
1450     no_more_source:
1451      coding->consumed_char += consumed_chars_base;
1452      coding->consumed = src_base - coding->source;
1453      coding->charbuf_used = charbuf - coding->charbuf;
1454  }  }
1455    
1456  #define CODING_SAFE_CHAR_P(safe_chars, c) \  static int
1457    (EQ (safe_chars, Qt) || !NILP (CHAR_TABLE_REF (safe_chars, c)))  encode_coding_utf_16 (coding)
1458         struct coding_system *coding;
1459    {
1460      int multibytep = coding->dst_multibyte;
1461      int *charbuf = coding->charbuf;
1462      int *charbuf_end = charbuf + coding->charbuf_used;
1463      unsigned char *dst = coding->destination + coding->produced;
1464      unsigned char *dst_end = coding->destination + coding->dst_bytes;
1465      int safe_room = 8;
1466      enum utf_16_bom_type bom = CODING_UTF_16_BOM (coding);
1467      int big_endian = CODING_UTF_16_ENDIAN (coding) == utf_16_big_endian;
1468      int produced_chars = 0;
1469      Lisp_Object attrs, eol_type, charset_list;
1470      int c;
1471    
1472      CODING_GET_INFO (coding, attrs, eol_type, charset_list);
1473    
1474      if (bom != utf_16_without_bom)
1475        {
1476          ASSURE_DESTINATION (safe_room);
1477          if (big_endian)
1478            EMIT_TWO_BYTES (0xFE, 0xFF);
1479          else
1480            EMIT_TWO_BYTES (0xFF, 0xFE);
1481          CODING_UTF_16_BOM (coding) = utf_16_without_bom;
1482        }
1483    
1484      while (charbuf < charbuf_end)
1485        {
1486          ASSURE_DESTINATION (safe_room);
1487          c = *charbuf++;
1488          if (c >= MAX_UNICODE_CHAR)
1489            c = coding->default_char;
1490    
1491          if (c < 0x10000)
1492            {
1493              if (big_endian)
1494                EMIT_TWO_BYTES (c >> 8, c & 0xFF);
1495              else
1496                EMIT_TWO_BYTES (c & 0xFF, c >> 8);
1497            }
1498          else
1499            {
1500              int c1, c2;
1501    
1502              c -= 0x10000;
1503              c1 = (c >> 10) + 0xD800;
1504              c2 = (c & 0x3FF) + 0xDC00;
1505              if (big_endian)
1506                EMIT_FOUR_BYTES (c1 >> 8, c1 & 0xFF, c2 >> 8, c2 & 0xFF);
1507              else
1508                EMIT_FOUR_BYTES (c1 & 0xFF, c1 >> 8, c2 & 0xFF, c2 >> 8);
1509            }
1510        }
1511      coding->result = CODING_RESULT_SUCCESS;
1512      coding->produced = dst - coding->destination;
1513      coding->produced_char += produced_chars;
1514      return 0;
1515    }
1516    
1517    
1518  /*** 2. Emacs internal format (emacs-mule) handlers ***/  /*** 6. Old Emacs' internal format (emacs-mule) ***/
1519    
1520  /* Emacs' internal format for representation of multiple character  /* Emacs' internal format for representation of multiple character
1521     sets is a kind of multi-byte encoding, i.e. characters are     sets is a kind of multi-byte encoding, i.e. characters are
# Line 572  coding_safe_chars (coding_system) Line 1557  coding_safe_chars (coding_system)
1557     In that case, a sequence of one-byte codes has a slightly different     In that case, a sequence of one-byte codes has a slightly different
1558     form.     form.
1559    
1560     Firstly, all characters in eight-bit-control are represented by     At first, all characters in eight-bit-control are represented by
1561     one-byte sequences which are their 8-bit code.     one-byte sequences which are their 8-bit code.
1562    
1563     Next, character composition data are represented by the byte     Next, character composition data are represented by the byte
# Line 581  coding_safe_chars (coding_system) Line 1566  coding_safe_chars (coding_system)
1566          METHOD is 0xF0 plus one of composition method (enum          METHOD is 0xF0 plus one of composition method (enum
1567          composition_method),          composition_method),
1568    
1569          BYTES is 0xA0 plus the byte length of these composition data,          BYTES is 0xA0 plus a byte length of this composition data,
1570    
1571          CHARS is 0xA0 plus the number of characters composed by these          CHARS is 0x20 plus a number of characters composed by this
1572          data,          data,
1573    
1574          COMPONENTs are characters of multibyte form or composition          COMPONENTs are characters of multibye form or composition
1575          rules encoded by two-byte of ASCII codes.          rules encoded by two-byte of ASCII codes.
1576    
1577     In addition, for backward compatibility, the following formats are     In addition, for backward compatibility, the following formats are
# Line 603  coding_safe_chars (coding_system) Line 1588  coding_safe_chars (coding_system)
1588          represents a composition rule.          represents a composition rule.
1589    */    */
1590    
1591  enum emacs_code_class_type emacs_code_class[256];  char emacs_mule_bytes[256];
1592    
1593    int
1594    emacs_mule_char (coding, src, nbytes, nchars, id)
1595         struct coding_system *coding;
1596         unsigned char *src;
1597         int *nbytes, *nchars, *id;
1598    {
1599      const unsigned char *src_end = coding->source + coding->src_bytes;
1600      const unsigned char *src_base = src;
1601      int multibytep = coding->src_multibyte;
1602      struct charset *charset;
1603      unsigned code;
1604      int c;
1605      int consumed_chars = 0;
1606    
1607      ONE_MORE_BYTE (c);
1608      switch (emacs_mule_bytes[c])
1609        {
1610        case 2:
1611          if (! (charset = emacs_mule_charset[c]))
1612            goto invalid_code;
1613          ONE_MORE_BYTE (c);
1614          code = c & 0x7F;
1615          break;
1616    
1617        case 3:
1618          if (c == EMACS_MULE_LEADING_CODE_PRIVATE_11
1619              || c == EMACS_MULE_LEADING_CODE_PRIVATE_12)
1620            {
1621              ONE_MORE_BYTE (c);
1622              if (! (charset = emacs_mule_charset[c]))
1623                goto invalid_code;
1624              ONE_MORE_BYTE (c);
1625              code = c & 0x7F;
1626            }
1627          else
1628            {
1629              if (! (charset = emacs_mule_charset[c]))
1630                goto invalid_code;
1631              ONE_MORE_BYTE (c);
1632              code = (c & 0x7F) << 8;
1633              ONE_MORE_BYTE (c);
1634              code |= c & 0x7F;
1635            }
1636          break;
1637    
1638        case 4:
1639          ONE_MORE_BYTE (c);
1640          if (! (charset = emacs_mule_charset[c]))
1641            goto invalid_code;
1642          ONE_MORE_BYTE (c);
1643          code = (c & 0x7F) << 8;
1644          ONE_MORE_BYTE (c);
1645          code |= c & 0x7F;
1646          break;
1647    
1648        case 1:
1649          code = c;
1650          charset = CHARSET_FROM_ID (ASCII_BYTE_P (code)
1651                                     ? charset_ascii : charset_eight_bit);
1652          break;
1653    
1654        default:
1655          abort ();
1656        }
1657      c = DECODE_CHAR (charset, code);
1658      if (c < 0)
1659        goto invalid_code;
1660      *nbytes = src - src_base;
1661      *nchars = consumed_chars;
1662      if (id)
1663        *id = charset->id;
1664      return c;
1665    
1666     no_more_source:
1667      return -2;
1668    
1669     invalid_code:
1670      return -1;
1671    }
1672    
1673    
1674  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
1675     Check if a text is encoded in Emacs' internal format.  If it is,     Check if a text is encoded in `emacs-mule'.  If it is, return 1,
1676     return CODING_CATEGORY_MASK_EMACS_MULE, else return 0.  */     else return 0.  */
1677    
1678  static int  static int
1679  detect_coding_emacs_mule (src, src_end, multibytep)  detect_coding_emacs_mule (coding, detect_info)
1680        unsigned char *src, *src_end;       struct coding_system *coding;
1681        int multibytep;       struct coding_detection_info *detect_info;
1682  {  {
1683    unsigned char c;    const unsigned char *src = coding->source, *src_base = src;
1684    int composing = 0;    const unsigned char *src_end = coding->source + coding->src_bytes;
1685    /* Dummy for ONE_MORE_BYTE.  */    int multibytep = coding->src_multibyte;
1686    struct coding_system dummy_coding;    int consumed_chars = 0;
1687    struct coding_system *coding = &dummy_coding;    int c;
1688      int found = 0;
1689      int incomplete;
1690    
1691      detect_info->checked |= CATEGORY_MASK_EMACS_MULE;
1692      /* A coding system of this category is always ASCII compatible.  */
1693      src += coding->head_ascii;
1694    
1695    while (1)    while (1)
1696      {      {
1697        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);        incomplete = 0;
1698          ONE_MORE_BYTE (c);
1699          incomplete = 1;
1700    
1701        if (composing)        if (c == 0x80)
1702          {          {
1703            if (c < 0xA0)            /* Perhaps the start of composite character.  We simple skip
1704              composing = 0;               it because analyzing it is too heavy for detecting.  But,
1705            else if (c == 0xA0)               at least, we check that the composite character
1706                 constitues of more than 4 bytes.  */
1707              const unsigned char *src_base;
1708    
1709            repeat:
1710              src_base = src;
1711              do
1712              {              {
1713                ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);                ONE_MORE_BYTE (c);
               c &= 0x7F;  
1714              }              }
1715            else            while (c >= 0xA0);
1716              c -= 0x20;  
1717              if (src - src_base <= 4)
1718                break;
1719              found = CATEGORY_MASK_EMACS_MULE;
1720              if (c == 0x80)
1721                goto repeat;
1722          }          }
1723    
1724        if (c < 0x20)        if (c < 0x80)
1725          {          {
1726            if (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO)            if (c < 0x20
1727              return 0;                && (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO))
1728                break;
1729          }          }
1730        else if (c >= 0x80 && c < 0xA0)        else
1731          {          {
1732            if (c == 0x80)            const unsigned char *src_base = src - 1;
             /* Old leading code for a composite character.  */  
             composing = 1;  
           else  
             {  
               unsigned char *src_base = src - 1;  
               int bytes;  
1733    
1734                if (!UNIBYTE_STR_AS_MULTIBYTE_P (src_base, src_end - src_base,            do
1735                                                 bytes))              {
1736                  return 0;                ONE_MORE_BYTE (c);
               src = src_base + bytes;  
1737              }              }
1738              while (c >= 0xA0);
1739              if (src - src_base != emacs_mule_bytes[*src_base])
1740                break;
1741              found = CATEGORY_MASK_EMACS_MULE;
1742          }          }
1743      }      }
1744   label_end_of_loop:    detect_info->rejected |= CATEGORY_MASK_EMACS_MULE;
1745    return CODING_CATEGORY_MASK_EMACS_MULE;    return 0;
1746    
1747     no_more_source:
1748      if (incomplete && coding->mode & CODING_MODE_LAST_BLOCK)
1749        {
1750          detect_info->rejected |= CATEGORY_MASK_EMACS_MULE;
1751          return 0;
1752        }
1753      detect_info->found |= found;
1754      return 1;
1755  }  }
1756    
1757    
1758  /* Record the starting position START and METHOD of one composition.  */  /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */
1759    
1760  #define CODING_ADD_COMPOSITION_START(coding, start, method)     \  /* Decode a character represented as a component of composition
1761    do {                                                          \     sequence of Emacs 20/21 style at SRC.  Set C to that character and
1762      struct composition_data *cmp_data = coding->cmp_data;       \     update SRC to the head of next character (or an encoded composition
1763      int *data = cmp_data->data + cmp_data->used;                \     rule).  If SRC doesn't points a composition component, set C to -1.
1764      coding->cmp_data_start = cmp_data->used;                    \     If SRC points an invalid byte sequence, global exit by a return
1765      data[0] = -1;                                               \     value 0.  */
1766      data[1] = cmp_data->char_offset + start;                    \  
1767      data[3] = (int) method;                                     \  #define DECODE_EMACS_MULE_COMPOSITION_CHAR(buf)                 \
1768      cmp_data->used += 4;                                        \    if (1)                                                        \
1769        {                                                           \
1770          int c;                                                    \
1771          int nbytes, nchars;                                       \
1772                                                                    \
1773          if (src == src_end)                                       \
1774            break;                                                  \
1775          c = emacs_mule_char (coding, src, &nbytes, &nchars, NULL);\
1776          if (c < 0)                                                \
1777            {                                                       \
1778              if (c == -2)                                          \
1779                break;                                              \
1780              goto invalid_code;                                    \
1781            }                                                       \
1782          *buf++ = c;                                               \
1783          src += nbytes;                                            \
1784          consumed_chars += nchars;                                 \
1785        }                                                           \
1786      else
1787    
1788    
1789    /* Decode a composition rule represented as a component of composition
1790       sequence of Emacs 20 style at SRC.  Store the decoded rule in *BUF,
1791       and increment BUF.  If SRC points an invalid byte sequence, set C
1792       to -1.  */
1793    
1794    #define DECODE_EMACS_MULE_COMPOSITION_RULE_20(buf)      \
1795      do {                                                  \
1796        int c, gref, nref;                                  \
1797                                                            \
1798        if (src >= src_end)                                 \
1799          goto invalid_code;                                \
1800        ONE_MORE_BYTE_NO_CHECK (c);                         \
1801        c -= 0x20;                                          \
1802        if (c < 0 || c >= 81)                               \
1803          goto invalid_code;                                \
1804                                                            \
1805        gref = c / 9, nref = c % 9;                         \
1806        *buf++ = COMPOSITION_ENCODE_RULE (gref, nref);      \
1807    } while (0)    } while (0)
1808    
 /* Record the ending position END of the current composition.  */  
1809    
1810  #define CODING_ADD_COMPOSITION_END(coding, end)                 \  /* Decode a composition rule represented as a component of composition
1811    do {                                                          \     sequence of Emacs 21 style at SRC.  Store the decoded rule in *BUF,
1812      struct composition_data *cmp_data = coding->cmp_data;       \     and increment BUF.  If SRC points an invalid byte sequence, set C
1813      int *data = cmp_data->data + coding->cmp_data_start;        \     to -1.  */
1814      data[0] = cmp_data->used - coding->cmp_data_start;          \  
1815      data[2] = cmp_data->char_offset + end;                      \  #define DECODE_EMACS_MULE_COMPOSITION_RULE_21(buf)      \
1816      do {                                                  \
1817        int gref, nref;                                     \
1818                                                            \
1819        if (src + 1>= src_end)                              \
1820          goto invalid_code;                                \
1821        ONE_MORE_BYTE_NO_CHECK (gref);                      \
1822        gref -= 0x20;                                       \
1823        ONE_MORE_BYTE_NO_CHECK (nref);                      \
1824        nref -= 0x20;                                       \
1825        if (gref < 0 || gref >= 81                          \
1826            || nref < 0 || nref >= 81)                      \
1827          goto invalid_code;                                \
1828        *buf++ = COMPOSITION_ENCODE_RULE (gref, nref);      \
1829    } while (0)    } while (0)
1830    
 /* Record one COMPONENT (alternate character or composition rule).  */  
1831    
1832  #define CODING_ADD_COMPOSITION_COMPONENT(coding, component)             \  #define DECODE_EMACS_MULE_21_COMPOSITION(c)                             \
1833    do {                                                                  \    do {                                                                  \
1834      coding->cmp_data->data[coding->cmp_data->used++] = component;       \      /* Emacs 21 style format.  The first three bytes at SRC are         \
1835      if (coding->cmp_data->used - coding->cmp_data_start                 \         (METHOD - 0xF2), (BYTES - 0xA0), (CHARS - 0xA0), where BYTES is  \
1836          == COMPOSITION_DATA_MAX_BUNCH_LENGTH)                           \         the byte length of this composition information, CHARS is the    \
1837           number of characters composed by this composition.  */           \
1838        enum composition_method method = c - 0xF2;                          \
1839        int *charbuf_base = charbuf;                                        \
1840        int from, to;                                                       \
1841        int consumed_chars_limit;                                           \
1842        int nbytes, nchars;                                                 \
1843                                                                            \
1844        ONE_MORE_BYTE (c);                                                  \
1845        nbytes = c - 0xA0;                                                  \
1846        if (nbytes < 3)                                                     \
1847          goto invalid_code;                                                \
1848        ONE_MORE_BYTE (c);                                                  \
1849        nchars = c - 0xA0;                                                  \
1850        from = coding->produced + char_offset;                              \
1851        to = from + nchars;                                                 \
1852        ADD_COMPOSITION_DATA (charbuf, from, to, method);                   \
1853        consumed_chars_limit = consumed_chars_base + nbytes;                \
1854        if (method != COMPOSITION_RELATIVE)                                 \
1855        {                                                                 \        {                                                                 \
1856          CODING_ADD_COMPOSITION_END (coding, coding->produced_char);     \          int i = 0;                                                      \
1857          coding->composing = COMPOSITION_NO;                             \          while (consumed_chars < consumed_chars_limit)                   \
1858              {                                                             \
1859                if (i % 2 && method != COMPOSITION_WITH_ALTCHARS)           \
1860                  DECODE_EMACS_MULE_COMPOSITION_RULE_21 (charbuf);          \
1861                else                                                        \
1862                  DECODE_EMACS_MULE_COMPOSITION_CHAR (charbuf);             \
1863                i++;                                                        \
1864              }                                                             \
1865            if (consumed_chars < consumed_chars_limit)                      \
1866              goto invalid_code;                                            \
1867            charbuf_base[0] -= i;                                           \
1868        }                                                                 \        }                                                                 \
1869    } while (0)    } while (0)
1870    
1871    
1872  /* Get one byte from a data pointed by SRC and increment SRC.  If SRC  #define DECODE_EMACS_MULE_20_RELATIVE_COMPOSITION(c)            \
1873     is not less than SRC_END, return -1 without incrementing Src.  */    do {                                                          \
1874        /* Emacs 20 style format for relative composition.  */      \
1875  #define SAFE_ONE_MORE_BYTE() (src >= src_end ? -1 : *src++)      /* Store multibyte form of characters to be composed.  */   \
1876        enum composition_method method = COMPOSITION_RELATIVE;      \
1877        int components[MAX_COMPOSITION_COMPONENTS * 2 - 1];         \
1878        int *buf = components;                                      \
1879        int i, j;                                                   \
1880        int from, to;                                               \
1881                                                                    \
1882        src = src_base;                                             \
1883        ONE_MORE_BYTE (c);          /* skip 0x80 */                 \
1884        for (i = 0; i < MAX_COMPOSITION_COMPONENTS; i++)            \
1885          DECODE_EMACS_MULE_COMPOSITION_CHAR (buf);                 \
1886        if (i < 2)                                                  \
1887          goto invalid_code;                                        \
1888        from = coding->produced_char + char_offset;                 \
1889        to = from + i;                                              \
1890        ADD_COMPOSITION_DATA (charbuf, from, to, method);           \
1891        for (j = 0; j < i; j++)                                     \
1892          *charbuf++ = components[j];                               \
1893      } while (0)
1894    
1895    
1896  /* Decode a character represented as a component of composition  #define DECODE_EMACS_MULE_20_RULEBASE_COMPOSITION(c)            \
    sequence of Emacs 20 style at SRC.  Set C to that character, store  
    its multibyte form sequence at P, and set P to the end of that  
    sequence.  If no valid character is found, set C to -1.  */  
   
 #define DECODE_EMACS_MULE_COMPOSITION_CHAR(c, p)                \  
1897    do {                                                          \    do {                                                          \
1898      int bytes;                                                  \      /* Emacs 20 style format for rule-base composition.  */     \
1899        /* Store multibyte form of characters to be composed.  */   \
1900        enum composition_method method = COMPOSITION_WITH_RULE;     \
1901        int components[MAX_COMPOSITION_COMPONENTS * 2 - 1];         \
1902        int *buf = components;                                      \
1903        int i, j;                                                   \
1904        int from, to;                                               \
1905                                                                  \                                                                  \
1906      c = SAFE_ONE_MORE_BYTE ();                                  \      DECODE_EMACS_MULE_COMPOSITION_CHAR (buf);                   \
1907      if (c < 0)                                                  \      for (i = 0; i < MAX_COMPOSITION_COMPONENTS; i++)            \
       break;                                                    \  
     if (CHAR_HEAD_P (c))                                        \  
       c = -1;                                                   \  
     else if (c == 0xA0)                                         \  
1908        {                                                         \        {                                                         \
1909          c = SAFE_ONE_MORE_BYTE ();                              \          DECODE_EMACS_MULE_COMPOSITION_RULE_20 (buf);            \
1910          if (c < 0xA0)                                           \          DECODE_EMACS_MULE_COMPOSITION_CHAR (buf);               \
           c = -1;                                               \  
         else                                                    \  
           {                                                     \  
             c -= 0xA0;                                          \  
             *p++ = c;                                           \  
           }                                                     \  
       }                                                         \  
     else if (BASE_LEADING_CODE_P (c - 0x20))                    \  
       {                                                         \  
         unsigned char *p0 = p;                                  \  
                                                                 \  
         c -= 0x20;                                              \  
         *p++ = c;                                               \  
         bytes = BYTES_BY_CHAR_HEAD (c);                         \  
         while (--bytes)                                         \  
           {                                                     \  
             c = SAFE_ONE_MORE_BYTE ();                          \  
             if (c < 0)                                          \  
               break;                                            \  
             *p++ = c;                                           \  
           }                                                     \  
         if (UNIBYTE_STR_AS_MULTIBYTE_P (p0, p - p0, bytes)      \  
             || (coding->flags /* We are recovering a file.  */  \  
                 && p0[0] == LEADING_CODE_8_BIT_CONTROL          \  
                 && ! CHAR_HEAD_P (p0[1])))                      \  
           c = STRING_CHAR (p0, bytes);                          \  
         else                                                    \  
           c = -1;                                               \  
1911        }                                                         \        }                                                         \
1912      else                                                        \      if (i < 1 || (buf - components) % 2 == 0)                   \
1913        c = -1;                                                   \        goto invalid_code;                                        \
1914        if (charbuf + i + (i / 2) + 1 < charbuf_end)                \
1915          goto no_more_source;                                      \
1916        from = coding->produced_char + char_offset;                 \
1917        to = from + i;                                              \
1918        ADD_COMPOSITION_DATA (buf, from, to, method);               \
1919        for (j = 0; j < i; j++)                                     \
1920          *charbuf++ = components[j];                               \
1921        for (j = 0; j < i; j += 2)                                  \
1922          *charbuf++ = components[j];                               \
1923    } while (0)    } while (0)
1924    
1925    
1926  /* Decode a composition rule represented as a component of composition  static void
1927     sequence of Emacs 20 style at SRC.  Set C to the rule.  If not  decode_coding_emacs_mule (coding)
    valid rule is found, set C to -1.  */  
   
 #define DECODE_EMACS_MULE_COMPOSITION_RULE(c)           \  
   do {                                                  \  
     c = SAFE_ONE_MORE_BYTE ();                          \  
     c -= 0xA0;                                          \  
     if (c < 0 || c >= 81)                               \  
       c = -1;                                           \  
     else                                                \  
       {                                                 \  
         gref = c / 9, nref = c % 9;                     \  
         c = COMPOSITION_ENCODE_RULE (gref, nref);       \  
       }                                                 \  
   } while (0)  
   
   
 /* Decode composition sequence encoded by `emacs-mule' at the source  
    pointed by SRC.  SRC_END is the end of source.  Store information  
    of the composition in CODING->cmp_data.  
   
    For backward compatibility, decode also a composition sequence of  
    Emacs 20 style.  In that case, the composition sequence contains  
    characters that should be extracted into a buffer or string.  Store  
    those characters at *DESTINATION in multibyte form.  
   
    If we encounter an invalid byte sequence, return 0.  
    If we encounter an insufficient source or destination, or  
    insufficient space in CODING->cmp_data, return 1.  
    Otherwise, return consumed bytes in the source.  
   
 */  
 static INLINE int  
 decode_composition_emacs_mule (coding, src, src_end,  
                                destination, dst_end, dst_bytes)  
1928       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *src, *src_end, **destination, *dst_end;  
      int dst_bytes;  
1929  {  {
1930    unsigned char *dst = *destination;    const unsigned char *src = coding->source + coding->consumed;
1931    int method, data_len, nchars;    const unsigned char *src_end = coding->source + coding->src_bytes;
1932    unsigned char *src_base = src++;    const unsigned char *src_base;
1933    /* Store components of composition.  */    int *charbuf = coding->charbuf;
1934    int component[COMPOSITION_DATA_MAX_BUNCH_LENGTH];    int *charbuf_end = charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
1935    int ncomponent;    int consumed_chars = 0, consumed_chars_base;
1936    /* Store multibyte form of characters to be composed.  This is for    int multibytep = coding->src_multibyte;
1937       Emacs 20 style composition sequence.  */    Lisp_Object attrs, eol_type, charset_list;
1938    unsigned char buf[MAX_COMPOSITION_COMPONENTS * MAX_MULTIBYTE_LENGTH];    int char_offset = coding->produced_char;
1939    unsigned char *bufp = buf;    int last_offset = char_offset;
1940    int c, i, gref, nref;    int last_id = charset_ascii;
1941    
1942    if (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH    CODING_GET_INFO (coding, attrs, eol_type, charset_list);
       >= COMPOSITION_DATA_SIZE)  
     {  
       coding->result = CODING_FINISH_INSUFFICIENT_CMP;  
       return -1;  
     }  
1943    
1944    ONE_MORE_BYTE (c);    while (1)
   if (c - 0xF0 >= COMPOSITION_RELATIVE  
            && c - 0xF0 <= COMPOSITION_WITH_RULE_ALTCHARS)  
1945      {      {
1946        int with_rule;        int c;
1947    
1948          src_base = src;
1949          consumed_chars_base = consumed_chars;
1950    
1951          if (charbuf >= charbuf_end)
1952            break;
1953    
       method = c - 0xF0;  
       with_rule = (method == COMPOSITION_WITH_RULE  
                    || method == COMPOSITION_WITH_RULE_ALTCHARS);  
       ONE_MORE_BYTE (c);  
       data_len = c - 0xA0;  
       if (data_len < 4  
           || src_base + data_len > src_end)  
         return 0;  
1954        ONE_MORE_BYTE (c);        ONE_MORE_BYTE (c);
       nchars = c - 0xA0;  
       if (c < 1)  
         return 0;  
       for (ncomponent = 0; src < src_base + data_len; ncomponent++)  
         {  
           /* If it is longer than this, it can't be valid.  */  
           if (ncomponent >= COMPOSITION_DATA_MAX_BUNCH_LENGTH)  
             return 0;  
1955    
1956            if (ncomponent % 2 && with_rule)        if (c < 0x80)
1957              {          {
1958                ONE_MORE_BYTE (gref);            if (c == '\r')
               gref -= 32;  
               ONE_MORE_BYTE (nref);  
               nref -= 32;  
               c = COMPOSITION_ENCODE_RULE (gref, nref);  
             }  
           else  
1959              {              {
1960                int bytes;                if (EQ (eol_type, Qdos))
1961                if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes)                  {
1962                    || (coding->flags /* We are recovering a file.  */                    if (src == src_end)
1963                        && src[0] == LEADING_CODE_8_BIT_CONTROL                      {
1964                        && ! CHAR_HEAD_P (src[1])))                        coding->result = CODING_RESULT_INSUFFICIENT_SRC;
1965                  c = STRING_CHAR (src, bytes);                        goto no_more_source;
1966                else                      }
1967                  c = *src, bytes = 1;                    if (*src == '\n')
1968                src += bytes;                      ONE_MORE_BYTE (c);
1969                    }
1970                  else if (EQ (eol_type, Qmac))
1971                    c = '\n';
1972              }              }
1973            component[ncomponent] = c;            *charbuf++ = c;
1974              char_offset++;
1975          }          }
1976      }        else if (c == 0x80)
   else  
     {  
       /* This may be an old Emacs 20 style format.  See the comment at  
          the section 2 of this file.  */  
       while (src < src_end && !CHAR_HEAD_P (*src)) src++;  
       if (src == src_end  
           && !(coding->mode & CODING_MODE_LAST_BLOCK))  
         goto label_end_of_loop;  
   
       src_end = src;  
       src = src_base + 1;  
       if (c < 0xC0)  
1977          {          {
1978            method = COMPOSITION_RELATIVE;            ONE_MORE_BYTE (c);
1979            for (ncomponent = 0; ncomponent < MAX_COMPOSITION_COMPONENTS;)            if (c - 0xF2 >= COMPOSITION_RELATIVE
1980              {                && c - 0xF2 <= COMPOSITION_WITH_RULE_ALTCHARS)
1981                DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp);              DECODE_EMACS_MULE_21_COMPOSITION (c);
1982                if (c < 0)            else if (c < 0xC0)
1983                  break;              DECODE_EMACS_MULE_20_RELATIVE_COMPOSITION (c);
1984                component[ncomponent++] = c;            else if (c == 0xFF)
1985              }              DECODE_EMACS_MULE_20_RULEBASE_COMPOSITION (c);
1986            if (ncomponent < 2)            else
1987              return 0;              goto invalid_code;
           nchars = ncomponent;  
1988          }          }
1989        else if (c == 0xFF)        else if (c < 0xA0 && emacs_mule_bytes[c] > 1)
1990          {          {
1991            method = COMPOSITION_WITH_RULE;            int nbytes, nchars;
1992            src++;            int id;
1993            DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp);  
1994              src = src_base;
1995              consumed_chars = consumed_chars_base;
1996              c = emacs_mule_char (coding, src, &nbytes, &nchars, &id);
1997            if (c < 0)            if (c < 0)
             return 0;  
           component[0] = c;  
           for (ncomponent = 1;  
                ncomponent < MAX_COMPOSITION_COMPONENTS * 2 - 1;)  
1998              {              {
1999                DECODE_EMACS_MULE_COMPOSITION_RULE (c);                if (c == -2)
               if (c < 0)  
                 break;  
               component[ncomponent++] = c;  
               DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp);  
               if (c < 0)  
2000                  break;                  break;
2001                component[ncomponent++] = c;                goto invalid_code;
2002              }              }
2003            if (ncomponent < 3)            if (last_id != id)
2004              return 0;              {
2005            nchars = (ncomponent + 1) / 2;                if (last_id != charset_ascii)
2006                    ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
2007                  last_id = id;
2008                  last_offset = char_offset;
2009                }
2010              *charbuf++ = c;
2011              src += nbytes;
2012              consumed_chars += nchars;
2013              char_offset++;
2014          }          }
2015        else        continue;
         return 0;  
     }  
2016    
2017    if (buf == bufp || dst + (bufp - buf) <= (dst_bytes ? dst_end : src))      invalid_code:
2018      {        src = src_base;
2019        CODING_ADD_COMPOSITION_START (coding, coding->produced_char, method);        consumed_chars = consumed_chars_base;
2020        for (i = 0; i < ncomponent; i++)        ONE_MORE_BYTE (c);
2021          CODING_ADD_COMPOSITION_COMPONENT (coding, component[i]);        *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
2022        CODING_ADD_COMPOSITION_END (coding, coding->produced_char + nchars);        char_offset++;
2023        if (buf < bufp)        coding->errors++;
         {  
           unsigned char *p = buf;  
           EMIT_BYTES (p, bufp);  
           *destination += bufp - buf;  
           coding->produced_char += nchars;  
         }  
       return (src - src_base);  
2024      }      }
2025   label_end_of_loop:  
2026    return -1;   no_more_source:
2027      if (last_id != charset_ascii)
2028        ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
2029      coding->consumed_char += consumed_chars_base;
2030      coding->consumed = src_base - coding->source;
2031      coding->charbuf_used = charbuf - coding->charbuf;
2032  }  }
2033    
 /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */  
2034    
2035  static void  #define EMACS_MULE_LEADING_CODES(id, codes)     \
2036  decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)    do {                                          \
2037        if (id < 0xA0)                              \
2038          codes[0] = id, codes[1] = 0;              \
2039        else if (id < 0xE0)                         \
2040          codes[0] = 0x9A, codes[1] = id;           \
2041        else if (id < 0xF0)                         \
2042          codes[0] = 0x9B, codes[1] = id;           \
2043        else if (id < 0xF5)                         \
2044          codes[0] = 0x9C, codes[1] = id;           \
2045        else                                        \
2046          codes[0] = 0x9D, codes[1] = id;           \
2047      } while (0);
2048    
2049    
2050    static int
2051    encode_coding_emacs_mule (coding)
2052       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *source, *destination;  
      int src_bytes, dst_bytes;  
2053  {  {
2054    unsigned char *src = source;    int multibytep = coding->dst_multibyte;
2055    unsigned char *src_end = source + src_bytes;    int *charbuf = coding->charbuf;
2056    unsigned char *dst = destination;    int *charbuf_end = charbuf + coding->charbuf_used;
2057    unsigned char *dst_end = destination + dst_bytes;    unsigned char *dst = coding->destination + coding->produced;
2058    /* SRC_BASE remembers the start position in source in each loop.    unsigned char *dst_end = coding->destination + coding->dst_bytes;
2059       The loop will be exited when there's not enough source code, or    int safe_room = 8;
2060       when there's not enough destination area to produce a    int produced_chars = 0;
2061       character.  */    Lisp_Object attrs, eol_type, charset_list;
2062    unsigned char *src_base;    int c;
2063      int preferred_charset_id = -1;
2064    
2065    coding->produced_char = 0;    CODING_GET_INFO (coding, attrs, eol_type, charset_list);
   while ((src_base = src) < src_end)  
     {  
       unsigned char tmp[MAX_MULTIBYTE_LENGTH], *p;  
       int bytes;  
2066    
2067        if (*src == '\r')    while (charbuf < charbuf_end)
2068          {      {
2069            int c = *src++;        ASSURE_DESTINATION (safe_room);
2070          c = *charbuf++;
2071    
2072            if (coding->eol_type == CODING_EOL_CR)        if (c < 0)
             c = '\n';  
           else if (coding->eol_type == CODING_EOL_CRLF)  
             {  
               ONE_MORE_BYTE (c);  
               if (c != '\n')  
                 {  
                   src--;  
                   c = '\r';  
                 }  
             }  
           *dst++ = c;  
           coding->produced_char++;  
           continue;  
         }  
       else if (*src == '\n')  
2073          {          {
2074            if ((coding->eol_type == CODING_EOL_CR            /* Handle an annotation.  */
2075                 || coding->eol_type == CODING_EOL_CRLF)            switch (*charbuf)
               && coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)  
2076              {              {
2077                coding->result = CODING_FINISH_INCONSISTENT_EOL;              case CODING_ANNOTATE_COMPOSITION_MASK:
2078                goto label_end_of_loop;                /* Not yet implemented.  */
2079                  break;
2080                case CODING_ANNOTATE_CHARSET_MASK:
2081                  preferred_charset_id = charbuf[3];
2082                  if (preferred_charset_id >= 0
2083                      && NILP (Fmemq (make_number (preferred_charset_id),
2084                                      charset_list)))
2085                    preferred_charset_id = -1;
2086                  break;
2087                default:
2088                  abort ();
2089              }              }
2090            *dst++ = *src++;            charbuf += -c - 1;
           coding->produced_char++;  
2091            continue;            continue;
2092          }          }
2093        else if (*src == 0x80 && coding->cmp_data)  
2094          {        if (ASCII_CHAR_P (c))
2095            /* Start of composition data.  */          EMIT_ONE_ASCII_BYTE (c);
2096            int consumed  = decode_composition_emacs_mule (coding, src, src_end,        else if (CHAR_BYTE8_P (c))
                                                          &dst, dst_end,  
                                                          dst_bytes);  
           if (consumed < 0)  
             goto label_end_of_loop;  
           else if (consumed > 0)  
             {  
               src += consumed;  
               continue;  
             }  
           bytes = CHAR_STRING (*src, tmp);  
           p = tmp;  
           src++;  
         }  
       else if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes)  
                || (coding->flags /* We are recovering a file.  */  
                    && src[0] == LEADING_CODE_8_BIT_CONTROL  
                    && ! CHAR_HEAD_P (src[1])))  
2097          {          {
2098            p = src;            c = CHAR_TO_BYTE8 (c);
2099            src += bytes;            EMIT_ONE_BYTE (c);
2100          }          }
2101        else        else
2102          {          {
2103            bytes = CHAR_STRING (*src, tmp);            struct charset *charset;
2104            p = tmp;            unsigned code;
2105            src++;            int dimension;
2106          }            int emacs_mule_id;
2107        if (dst + bytes >= (dst_bytes ? dst_end : src))            unsigned char leading_codes[2];
2108          {  
2109            coding->result = CODING_FINISH_INSUFFICIENT_DST;            if (preferred_charset_id >= 0)
2110            break;              {
2111          }                charset = CHARSET_FROM_ID (preferred_charset_id);
2112        while (bytes--) *dst++ = *p++;                if (! CHAR_CHARSET_P (c, charset))
2113        coding->produced_char++;                  charset = char_charset (c, charset_list, NULL);
2114      }              }
  label_end_of_loop:  
   coding->consumed = coding->consumed_char = src_base - source;  
   coding->produced = dst - destination;  
 }  
   
   
 /* Encode composition data stored at DATA into a special byte sequence  
    starting by 0x80.  Update CODING->cmp_data_start and maybe  
    CODING->cmp_data for the next call.  */  
   
 #define ENCODE_COMPOSITION_EMACS_MULE(coding, data)                     \  
   do {                                                                  \  
     unsigned char buf[1024], *p0 = buf, *p;                             \  
     int len = data[0];                                                  \  
     int i;                                                              \  
                                                                         \  
     buf[0] = 0x80;                                                      \  
     buf[1] = 0xF0 + data[3];    /* METHOD */                            \  
     buf[3] = 0xA0 + (data[2] - data[1]); /* COMPOSED-CHARS */           \  
     p = buf + 4;                                                        \  
     if (data[3] == COMPOSITION_WITH_RULE                                \  
         || data[3] == COMPOSITION_WITH_RULE_ALTCHARS)                   \  
       {                                                                 \  
         p += CHAR_STRING (data[4], p);                                  \  
         for (i = 5; i < len; i += 2)                                    \  
           {                                                             \  
             int gref, nref;                                             \  
              COMPOSITION_DECODE_RULE (data[i], gref, nref);             \  
             *p++ = 0x20 + gref;                                         \  
             *p++ = 0x20 + nref;                                         \  
             p += CHAR_STRING (data[i + 1], p);                          \  
           }                                                             \  
       }                                                                 \  
     else                                                                \  
       {                                                                 \  
         for (i = 4; i < len; i++)                                       \  
           p += CHAR_STRING (data[i], p);                                \  
       }                                                                 \  
     buf[2] = 0xA0 + (p - buf);  /* COMPONENTS-BYTES */                  \  
                                                                         \  
     if (dst + (p - buf) + 4 > (dst_bytes ? dst_end : src))              \  
       {                                                                 \  
         coding->result = CODING_FINISH_INSUFFICIENT_DST;                \  
         goto label_end_of_loop;                                         \  
       }                                                                 \  
     while (p0 < p)                                                      \  
       *dst++ = *p0++;                                                   \  
     coding->cmp_data_start += data[0];                                  \  
     if (coding->cmp_data_start == coding->cmp_data->used                \  
         && coding->cmp_data->next)                                      \  
       {                                                                 \  
         coding->cmp_data = coding->cmp_data->next;                      \  
         coding->cmp_data_start = 0;                                     \  
       }                                                                 \  
   } while (0)  
   
   
 static void encode_eol P_ ((struct coding_system *, const unsigned char *,  
                             unsigned char *, int, int));  
   
 static void  
 encode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)  
      struct coding_system *coding;  
      unsigned char *source, *destination;  
      int src_bytes, dst_bytes;  
 {  
   unsigned char *src = source;  
   unsigned char *src_end = source + src_bytes;  
   unsigned char *dst = destination;  
   unsigned char *dst_end = destination + dst_bytes;  
   unsigned char *src_base;  
   int c;  
   int char_offset;  
   int *data;  
   
   Lisp_Object translation_table;  
   
   translation_table = Qnil;  
   
   /* Optimization for the case that there's no composition.  */  
   if (!coding->cmp_data || coding->cmp_data->used == 0)  
     {  
       encode_eol (coding, source, destination, src_bytes, dst_bytes);  
       return;  
     }  
   
   char_offset = coding->cmp_data->char_offset;  
   data = coding->cmp_data->data + coding->cmp_data_start;  
   while (1)  
     {  
       src_base = src;  
   
       /* If SRC starts a composition, encode the information about the  
          composition in advance.  */  
       if (coding->cmp_data_start < coding->cmp_data->used  
           && char_offset + coding->consumed_char == data[1])  
         {  
           ENCODE_COMPOSITION_EMACS_MULE (coding, data);  
           char_offset = coding->cmp_data->char_offset;  
           data = coding->cmp_data->data + coding->cmp_data_start;  
         }  
   
       ONE_MORE_CHAR (c);  
       if (c == '\n' && (coding->eol_type == CODING_EOL_CRLF  
                         || coding->eol_type == CODING_EOL_CR))  
         {  
           if (coding->eol_type == CODING_EOL_CRLF)  
             EMIT_TWO_BYTES ('\r', c);  
2115            else            else
2116              EMIT_ONE_BYTE ('\r');              charset = char_charset (c, charset_list, &code);
2117          }            if (! charset)
       else if (SINGLE_BYTE_CHAR_P (c))  
         {  
           if (coding->flags && ! ASCII_BYTE_P (c))  
2118              {              {
2119                /* As we are auto saving, retain the multibyte form for                c = coding->default_char;
2120                   8-bit chars.  */                if (ASCII_CHAR_P (c))
2121                unsigned char buf[MAX_MULTIBYTE_LENGTH];                  {
2122                int bytes = CHAR_STRING (c, buf);                    EMIT_ONE_ASCII_BYTE (c);
2123                      continue;
2124                if (bytes == 1)                  }
2125                  EMIT_ONE_BYTE (buf[0]);                charset = char_charset (c, charset_list, &code);
               else  
                 EMIT_TWO_BYTES (buf[0], buf[1]);  
2126              }              }
2127              dimension = CHARSET_DIMENSION (charset);
2128              emacs_mule_id = CHARSET_EMACS_MULE_ID (charset);
2129              EMACS_MULE_LEADING_CODES (emacs_mule_id, leading_codes);
2130              EMIT_ONE_BYTE (leading_codes[0]);
2131              if (leading_codes[1])
2132                EMIT_ONE_BYTE (leading_codes[1]);
2133              if (dimension == 1)
2134                EMIT_ONE_BYTE (code);
2135            else            else
2136              EMIT_ONE_BYTE (c);              {
2137                  EMIT_ONE_BYTE (code >> 8);
2138                  EMIT_ONE_BYTE (code & 0xFF);
2139                }
2140          }          }
       else  
         EMIT_BYTES (src_base, src);  
       coding->consumed_char++;  
2141      }      }
2142   label_end_of_loop:    coding->result = CODING_RESULT_SUCCESS;
2143    coding->consumed = src_base - source;    coding->produced_char += produced_chars;
2144    coding->produced = coding->produced_char = dst - destination;    coding->produced = dst - coding->destination;
2145    return;    return 0;
2146  }  }
2147    
2148    
2149  /*** 3. ISO2022 handlers ***/  /*** 7. ISO2022 handlers ***/
2150    
2151  /* The following note describes the coding system ISO2022 briefly.  /* The following note describes the coding system ISO2022 briefly.
2152     Since the intention of this note is to help understand the     Since the intention of this note is to help understand the
# Line 1301  encode_coding_emacs_mule (coding, source Line 2276  encode_coding_emacs_mule (coding, source
2276     7-bit environment, non-locking-shift, and non-single-shift.     7-bit environment, non-locking-shift, and non-single-shift.
2277    
2278     Note (**): If <F> is '@', 'A', or 'B', the intermediate character     Note (**): If <F> is '@', 'A', or 'B', the intermediate character
2279     '(' can be omitted.  We refer to this as "short-form" hereafter.     '(' must be omitted.  We refer to this as "short-form" hereafter.
2280    
2281     Now you may notice that there are a lot of ways of encoding the     Now you may notice that there are a lot of ways of encoding the
2282     same multilingual text in ISO2022.  Actually, there exist many     same multilingual text in ISO2022.  Actually, there exist many
# Line 1331  encode_coding_emacs_mule (coding, source Line 2306  encode_coding_emacs_mule (coding, source
2306    Since these are not standard escape sequences of any ISO standard,    Since these are not standard escape sequences of any ISO standard,
2307    the use of them with these meanings is restricted to Emacs only.    the use of them with these meanings is restricted to Emacs only.
2308    
2309    (*) This form is used only in Emacs 20.5 and older versions,    (*) This form is used only in Emacs 20.7 and older versions,
2310    but the newer versions can safely decode it.    but newer versions can safely decode it.
2311    (**) This form is used only in Emacs 21.1 and newer versions,    (**) This form is used only in Emacs 21.1 and newer versions,
2312    and the older versions can't decode it.    and older versions can't decode it.
2313    
2314    Here's a list of example usages of these composition escape    Here's a list of example usages of these composition escape
2315    sequences (categorized by `enum composition_method').    sequences (categorized by `enum composition_method').
# Line 1350  encode_coding_emacs_mule (coding, source Line 2325  encode_coding_emacs_mule (coding, source
2325    
2326  enum iso_code_class_type iso_code_class[256];  enum iso_code_class_type iso_code_class[256];
2327    
2328  #define CHARSET_OK(idx, charset, c)                                     \  #define SAFE_CHARSET_P(coding, id)      \
2329    (coding_system_table[idx]                                             \    ((id) <= (coding)->max_charset_id     \
2330     && (charset == CHARSET_ASCII                                         \     && (coding)->safe_charsets[id] >= 0)
2331         || (safe_chars = coding_safe_chars (coding_system_table[idx]->symbol), \  
2332             CODING_SAFE_CHAR_P (safe_chars, c)))                         \  
2333     && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding_system_table[idx], \  #define SHIFT_OUT_OK(category)  \
2334                                                charset)                  \    (CODING_ISO_INITIAL (&coding_categories[category], 1) >= 0)
2335         != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION))  
2336    static void
2337    setup_iso_safe_charsets (attrs)
2338         Lisp_Object attrs;
2339    {
2340      Lisp_Object charset_list, safe_charsets;
2341      Lisp_Object request;
2342      Lisp_Object reg_usage;
2343      Lisp_Object tail;
2344      int reg94, reg96;
2345      int flags = XINT (AREF (attrs, coding_attr_iso_flags));
2346      int max_charset_id;
2347    
2348      charset_list = CODING_ATTR_CHARSET_LIST (attrs);
2349      if ((flags & CODING_ISO_FLAG_FULL_SUPPORT)
2350          && ! EQ (charset_list, Viso_2022_charset_list))
2351        {
2352          CODING_ATTR_CHARSET_LIST (attrs)
2353            = charset_list = Viso_2022_charset_list;
2354          ASET (attrs, coding_attr_safe_charsets, Qnil);
2355        }
2356    
2357      if (STRINGP (AREF (attrs, coding_attr_safe_charsets)))
2358        return;
2359    
2360  #define SHIFT_OUT_OK(idx) \    max_charset_id = 0;
2361    (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding_system_table[idx], 1) >= 0)    for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
2362        {
2363          int id = XINT (XCAR (tail));
2364          if (max_charset_id < id)
2365            max_charset_id = id;
2366        }
2367    
2368      safe_charsets = Fmake_string (make_number (max_charset_id + 1),
2369                                    make_number (255));
2370      request = AREF (attrs, coding_attr_iso_request);
2371      reg_usage = AREF (attrs, coding_attr_iso_usage);
2372      reg94 = XINT (XCAR (reg_usage));
2373      reg96 = XINT (XCDR (reg_usage));
2374    
2375      for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
2376        {
2377          Lisp_Object id;
2378          Lisp_Object reg;
2379          struct charset *charset;
2380    
2381          id = XCAR (tail);
2382          charset = CHARSET_FROM_ID (XINT (id));
2383          reg = Fcdr (Fassq (id, request));
2384          if (! NILP (reg))
2385            SSET (safe_charsets, XINT (id), XINT (reg));
2386          else if (charset->iso_chars_96)
2387            {
2388              if (reg96 < 4)
2389                SSET (safe_charsets, XINT (id), reg96);
2390            }
2391          else
2392            {
2393              if (reg94 < 4)
2394                SSET (safe_charsets, XINT (id), reg94);
2395            }
2396        }
2397      ASET (attrs, coding_attr_safe_charsets, safe_charsets);
2398    }
2399    
 #define COMPOSITION_OK(idx)     \  
   (coding_system_table[idx]->composing != COMPOSITION_DISABLED)  
2400    
2401  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
2402     Check if a text is encoded in ISO2022.  If it is, return an     Check if a text is encoded in one of ISO-2022 based codig systems.
2403     integer in which appropriate flag bits any of:     If it is, return 1, else return 0.  */
         CODING_CATEGORY_MASK_ISO_7  
         CODING_CATEGORY_MASK_ISO_7_TIGHT  
         CODING_CATEGORY_MASK_ISO_8_1  
         CODING_CATEGORY_MASK_ISO_8_2  
         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.  */  
2404    
2405  static int  static int
2406  detect_coding_iso2022 (src, src_end, multibytep)  detect_coding_iso_2022 (coding, detect_info)
2407       unsigned char *src, *src_end;       struct coding_system *coding;
2408       int multibytep;       struct coding_detection_info *detect_info;
2409  {  {
2410    int mask = CODING_CATEGORY_MASK_ISO;    const unsigned char *src = coding->source, *src_base = src;
2411    int mask_found = 0;    const unsigned char *src_end = coding->source + coding->src_bytes;
2412    int reg[4], shift_out = 0, single_shifting = 0;    int multibytep = coding->src_multibyte;
2413    int c, c1, charset;    int single_shifting = 0;
2414    /* Dummy for ONE_MORE_BYTE.  */    int id;
2415    struct coding_system dummy_coding;    int c, c1;
2416    struct coding_system *coding = &dummy_coding;    int consumed_chars = 0;
2417    Lisp_Object safe_chars;    int i;
2418      int rejected = 0;
2419      int found = 0;
2420    
2421    reg[0] = CHARSET_ASCII, reg[1] = reg[2] = reg[3] = -1;    detect_info->checked |= CATEGORY_MASK_ISO;
2422    while (mask && src < src_end)  
2423      for (i = coding_category_iso_7; i <= coding_category_iso_8_else; i++)
2424      {      {
2425        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);        struct coding_system *this = &(coding_categories[i]);
2426      retry:        Lisp_Object attrs, val;
2427    
2428          attrs = CODING_ID_ATTRS (this->id);
2429          if (CODING_ISO_FLAGS (this) & CODING_ISO_FLAG_FULL_SUPPORT
2430              && ! EQ (CODING_ATTR_SAFE_CHARSETS (attrs), Viso_2022_charset_list))
2431            setup_iso_safe_charsets (attrs);
2432          val = CODING_ATTR_SAFE_CHARSETS (attrs);
2433          this->max_charset_id = SCHARS (val) - 1;
2434          this->safe_charsets = (char *) SDATA (val);
2435        }
2436    
2437      /* A coding system of this category is always ASCII compatible.  */
2438      src += coding->head_ascii;
2439    
2440      while (rejected != CATEGORY_MASK_ISO)
2441        {
2442          ONE_MORE_BYTE (c);
2443        switch (c)        switch (c)
2444          {          {
2445          case ISO_CODE_ESC:          case ISO_CODE_ESC:
2446            if (inhibit_iso_escape_detection)            if (inhibit_iso_escape_detection)
2447              break;              break;
2448            single_shifting = 0;            single_shifting = 0;
2449            ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);            ONE_MORE_BYTE (c);
2450            if (c >= '(' && c <= '/')            if (c >= '(' && c <= '/')
2451              {              {
2452                /* Designation sequence for a charset of dimension 1.  */                /* Designation sequence for a charset of dimension 1.  */
2453                ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep);                ONE_MORE_BYTE (c1);
2454                if (c1 < ' ' || c1 >= 0x80                if (c1 < ' ' || c1 >= 0x80
2455                    || (charset = iso_charset_table[0][c >= ','][c1]) < 0)                    || (id = iso_charset_table[0][c >= ','][c1]) < 0)
2456                  /* Invalid designation sequence.  Just ignore.  */                  /* Invalid designation sequence.  Just ignore.  */
2457                  break;                  break;
               reg[(c - '(') % 4] = charset;  
2458              }              }
2459            else if (c == '$')            else if (c == '$')
2460              {              {
2461                /* Designation sequence for a charset of dimension 2.  */                /* Designation sequence for a charset of dimension 2.  */
2462                ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);                ONE_MORE_BYTE (c);
2463                if (c >= '@' && c <= 'B')                if (c >= '@' && c <= 'B')
2464                  /* Designation for JISX0208.1978, GB2312, or JISX0208.  */                  /* Designation for JISX0208.1978, GB2312, or JISX0208.  */
2465                  reg[0] = charset = iso_charset_table[1][0][c];                  id = iso_charset_table[1][0][c];
2466                else if (c >= '(' && c <= '/')                else if (c >= '(' && c <= '/')
2467                  {                  {
2468                    ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep);                    ONE_MORE_BYTE (c1);
2469                    if (c1 < ' ' || c1 >= 0x80                    if (c1 < ' ' || c1 >= 0x80
2470                        || (charset = iso_charset_table[1][c >= ','][c1]) < 0)                        || (id = iso_charset_table[1][c >= ','][c1]) < 0)
2471                      /* Invalid designation sequence.  Just ignore.  */                      /* Invalid designation sequence.  Just ignore.  */
2472                      break;                      break;
                   reg[(c - '(') % 4] = charset;  
2473                  }                  }
2474                else                else
2475                  /* Invalid designation sequence.  Just ignore.  */                  /* Invalid designation sequence.  Just ignore it.  */
2476                  break;                  break;
2477              }              }
2478            else if (c == 'N' || c == 'O')            else if (c == 'N' || c == 'O')
2479              {              {
2480                /* ESC <Fe> for SS2 or SS3.  */                /* ESC <Fe> for SS2 or SS3.  */
2481                mask &= CODING_CATEGORY_MASK_ISO_7_ELSE;                single_shifting = 1;
2482                  rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_8BIT;
2483                break;                break;
2484              }              }
2485            else if (c >= '0' && c <= '4')            else if (c >= '0' && c <= '4')
2486              {              {
2487                /* ESC <Fp> for start/end composition.  */                /* ESC <Fp> for start/end composition.  */
2488                if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7))                found |= CATEGORY_MASK_ISO;
                 mask_found |= CODING_CATEGORY_MASK_ISO_7;  
               else  
                 mask &= ~CODING_CATEGORY_MASK_ISO_7;  
               if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7_TIGHT))  
                 mask_found |= CODING_CATEGORY_MASK_ISO_7_TIGHT;  
               else  
                 mask &= ~CODING_CATEGORY_MASK_ISO_7_TIGHT;  
               if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_1))  
                 mask_found |= CODING_CATEGORY_MASK_ISO_8_1;  
               else  
                 mask &= ~CODING_CATEGORY_MASK_ISO_8_1;  
               if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_2))  
                 mask_found |= CODING_CATEGORY_MASK_ISO_8_2;  
               else  
                 mask &= ~CODING_CATEGORY_MASK_ISO_8_2;  
               if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7_ELSE))  
                 mask_found |= CODING_CATEGORY_MASK_ISO_7_ELSE;  
               else  
                 mask &= ~CODING_CATEGORY_MASK_ISO_7_ELSE;  
               if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_ELSE))  
                 mask_found |= CODING_CATEGORY_MASK_ISO_8_ELSE;  
               else  
                 mask &= ~CODING_CATEGORY_MASK_ISO_8_ELSE;  
2489                break;                break;
2490              }              }
2491            else            else
2492              /* Invalid escape sequence.  Just ignore.  */              {
2493              break;                /* Invalid escape sequence.  Just ignore it.  */
2494                  break;
2495                }
2496    
2497            /* We found a valid designation sequence for CHARSET.  */            /* We found a valid designation sequence for CHARSET.  */
2498            mask &= ~CODING_CATEGORY_MASK_ISO_8BIT;            rejected |= CATEGORY_MASK_ISO_8BIT;
2499            c = MAKE_CHAR (charset, 0, 0);            if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7],
2500            if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7, charset, c))                                id))
2501              mask_found |= CODING_CATEGORY_MASK_ISO_7;              found |= CATEGORY_MASK_ISO_7;
2502            else            else
2503              mask &= ~CODING_CATEGORY_MASK_ISO_7;              rejected |= CATEGORY_MASK_ISO_7;
2504            if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7_TIGHT, charset, c))            if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_tight],
2505              mask_found |= CODING_CATEGORY_MASK_ISO_7_TIGHT;                                id))
2506                found |= CATEGORY_MASK_ISO_7_TIGHT;
2507            else            else
2508              mask &= ~CODING_CATEGORY_MASK_ISO_7_TIGHT;              rejected |= CATEGORY_MASK_ISO_7_TIGHT;
2509            if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7_ELSE, charset, c))            if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_else],
2510              mask_found |= CODING_CATEGORY_MASK_ISO_7_ELSE;                                id))
2511                found |= CATEGORY_MASK_ISO_7_ELSE;
2512            else            else
2513              mask &= ~CODING_CATEGORY_MASK_ISO_7_ELSE;              rejected |= CATEGORY_MASK_ISO_7_ELSE;
2514            if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_8_ELSE, charset, c))            if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_8_else],
2515              mask_found |= CODING_CATEGORY_MASK_ISO_8_ELSE;                                id))
2516                found |= CATEGORY_MASK_ISO_8_ELSE;
2517            else            else
2518              mask &= ~CODING_CATEGORY_MASK_ISO_8_ELSE;              rejected |= CATEGORY_MASK_ISO_8_ELSE;
2519            break;            break;
2520    
2521          case ISO_CODE_SO:          case ISO_CODE_SO:
           if (inhibit_iso_escape_detection)  
             break;  
           single_shifting = 0;  
           if (shift_out == 0  
               && (reg[1] >= 0  
                   || SHIFT_OUT_OK (CODING_CATEGORY_IDX_ISO_7_ELSE)  
                   || SHIFT_OUT_OK (CODING_CATEGORY_IDX_ISO_8_ELSE)))  
             {  
               /* Locking shift out.  */  
               mask &= ~CODING_CATEGORY_MASK_ISO_7BIT;  
               mask_found |= CODING_CATEGORY_MASK_ISO_SHIFT;  
             }  
           break;  
   
2522          case ISO_CODE_SI:          case ISO_CODE_SI:
2523              /* Locking shift out/in.  */
2524            if (inhibit_iso_escape_detection)            if (inhibit_iso_escape_detection)
2525              break;              break;
2526            single_shifting = 0;            single_shifting = 0;
2527            if (shift_out == 1)            rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_8BIT;
2528              {            found |= CATEGORY_MASK_ISO_ELSE;
               /* Locking shift in.  */  
               mask &= ~CODING_CATEGORY_MASK_ISO_7BIT;  
               mask_found |= CODING_CATEGORY_MASK_ISO_SHIFT;  
             }  
2529            break;            break;
2530    
2531          case ISO_CODE_CSI:          case ISO_CODE_CSI:
2532              /* Control sequence introducer.  */
2533            single_shifting = 0;            single_shifting = 0;
2534              rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_7_ELSE;
2535              found |= CATEGORY_MASK_ISO_8_ELSE;
2536              goto check_extra_latin;
2537    
2538    
2539          case ISO_CODE_SS2:          case ISO_CODE_SS2:
2540          case ISO_CODE_SS3:          case ISO_CODE_SS3:
2541            {            /* Single shift.   */
2542              int newmask = CODING_CATEGORY_MASK_ISO_8_ELSE;            if (inhibit_iso_escape_detection)
2543                break;
2544              if (inhibit_iso_escape_detection)            single_shifting = 1;
2545                break;            rejected |= CATEGORY_MASK_ISO_7BIT;
2546              if (c != ISO_CODE_CSI)            if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
2547                {                & CODING_ISO_FLAG_SINGLE_SHIFT)
2548                  if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags              found |= CATEGORY_MASK_ISO_8_1;
2549                      & CODING_FLAG_ISO_SINGLE_SHIFT)            if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_2])
2550                    newmask |= CODING_CATEGORY_MASK_ISO_8_1;                & CODING_ISO_FLAG_SINGLE_SHIFT)
2551                  if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags              found |= CATEGORY_MASK_ISO_8_2;
2552                      & CODING_FLAG_ISO_SINGLE_SHIFT)            goto check_extra_latin;
                   newmask |= CODING_CATEGORY_MASK_ISO_8_2;  
                 single_shifting = 1;  
               }  
             if (VECTORP (Vlatin_extra_code_table)  
                 && !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))  
               {  
                 if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags  
                     & CODING_FLAG_ISO_LATIN_EXTRA)  
                   newmask |= CODING_CATEGORY_MASK_ISO_8_1;  
                 if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags  
                     & CODING_FLAG_ISO_LATIN_EXTRA)  
                   newmask |= CODING_CATEGORY_MASK_ISO_8_2;  
               }  
             mask &= newmask;  
             mask_found |= newmask;  
           }  
           break;  
2553    
2554          default:          default:
2555            if (c < 0x80)            if (c < 0x80)
# Line 1560  detect_coding_iso2022 (src, src_end, mul Line 2557  detect_coding_iso2022 (src, src_end, mul
2557                single_shifting = 0;                single_shifting = 0;
2558                break;                break;
2559              }              }
2560            else if (c < 0xA0)            if (c >= 0xA0)
2561              {              {
2562                single_shifting = 0;                rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_7_ELSE;
2563                if (VECTORP (Vlatin_extra_code_table)                found |= CATEGORY_MASK_ISO_8_1;
                   && !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))  
                 {  
                   int newmask = 0;  
   
                   if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags  
                       & CODING_FLAG_ISO_LATIN_EXTRA)  
                     newmask |= CODING_CATEGORY_MASK_ISO_8_1;  
                   if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags  
                       & CODING_FLAG_ISO_LATIN_EXTRA)  
                     newmask |= CODING_CATEGORY_MASK_ISO_8_2;  
                   mask &= newmask;  
                   mask_found |= newmask;  
                 }  
               else  
                 return 0;  
             }  
           else  
             {  
               mask &= ~(CODING_CATEGORY_MASK_ISO_7BIT  
                         | CODING_CATEGORY_MASK_ISO_7_ELSE);  
               mask_found |= CODING_CATEGORY_MASK_ISO_8_1;  
2564                /* Check the length of succeeding codes of the range                /* Check the length of succeeding codes of the range
2565                   0xA0..0FF.  If the byte length is odd, we exclude                   0xA0..0FF.  If the byte length is even, we include
2566                   CODING_CATEGORY_MASK_ISO_8_2.  We can check this only                   CATEGORY_MASK_ISO_8_2 in `found'.  We can check this
2567                   when we are not single shifting.  */                   only when we are not single shifting.  */
2568                if (!single_shifting                if (! single_shifting
2569                    && mask & CODING_CATEGORY_MASK_ISO_8_2)                    && ! (rejected & CATEGORY_MASK_ISO_8_2))
2570                  {                  {
2571                    int i = 1;                    int i = 1;
   
                   c = -1;  
2572                    while (src < src_end)                    while (src < src_end)
2573                      {                      {
2574                        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);                        ONE_MORE_BYTE (c);
2575                        if (c < 0xA0)                        if (c < 0xA0)
2576                          break;                          break;
2577                        i++;                        i++;
2578                      }                      }
2579    
2580                    if (i & 1 && src < src_end)                    if (i & 1 && src < src_end)
2581                      mask &= ~CODING_CATEGORY_MASK_ISO_8_2;                      rejected |= CATEGORY_MASK_ISO_8_2;
2582                    else                    else
2583                      mask_found |= CODING_CATEGORY_MASK_ISO_8_2;                      found |= CATEGORY_MASK_ISO_8_2;
                   if (c >= 0)  
                     /* This means that we have read one extra byte.  */  
                     goto retry;  
2584                  }                  }
2585                  break;
2586              }              }
2587            break;          check_extra_latin:
2588              single_shifting = 0;
2589              if (! VECTORP (Vlatin_extra_code_table)
2590                  || NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
2591                {
2592                  rejected = CATEGORY_MASK_ISO;
2593                  break;
2594                }
2595              if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
2596                  & CODING_ISO_FLAG_LATIN_EXTRA)
2597                found |= CATEGORY_MASK_ISO_8_1;
2598              else
2599                rejected |= CATEGORY_MASK_ISO_8_1;
2600              if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_2])
2601                  & CODING_ISO_FLAG_LATIN_EXTRA)
2602                found |= CATEGORY_MASK_ISO_8_2;
2603              else
2604                rejected |= CATEGORY_MASK_ISO_8_2;
2605          }          }
2606      }      }
2607   label_end_of_loop:    detect_info->rejected |= CATEGORY_MASK_ISO;
2608    return (mask & mask_found);    return 0;
2609    
2610     no_more_source:
2611      detect_info->rejected |= rejected;
2612      detect_info->found |= (found & ~rejected);
2613      return 1;
2614  }  }
2615    
 /* Decode a character of which charset is CHARSET, the 1st position  
    code is C1, the 2nd position code is C2, and return the decoded  
    character code.  If the variable `translation_table' is non-nil,  
    returned the translated code.  */  
   
 #define DECODE_ISO_CHARACTER(charset, c1, c2)   \  
   (NILP (translation_table)                     \  
    ? MAKE_CHAR (charset, c1, c2)                \  
    : translate_char (translation_table, -1, charset, c1, c2))  
2616    
2617  /* Set designation state into CODING.  */  /* Set designation state into CODING.  */
2618  #define DECODE_DESIGNATION(reg, dimension, chars, final_char)              \  #define DECODE_DESIGNATION(reg, dim, chars_96, final)                   \
2619    do {                                                                     \    do {                                                                  \
2620      int charset, c;                                                        \      int id, prev;                                                       \
2621                                                                             \                                                                          \
2622      if (final_char < '0' || final_char >= 128)                             \      if (final < '0' || final >= 128                                     \
2623        goto label_invalid_code;                                             \          || ((id = ISO_CHARSET_TABLE (dim, chars_96, final)) < 0)        \
2624      charset = ISO_CHARSET_TABLE (make_number (dimension),                  \          || !SAFE_CHARSET_P (coding, id))                                \
2625                                   make_number (chars),                      \        {                                                                 \
2626                                   make_number (final_char));                \          CODING_ISO_DESIGNATION (coding, reg) = -2;                      \
2627      c = MAKE_CHAR (charset, 0, 0);                                         \          goto invalid_code;                                              \
2628      if (charset >= 0                                                       \        }                                                                 \
2629          && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) == reg \      prev = CODING_ISO_DESIGNATION (coding, reg);                        \
2630              || CODING_SAFE_CHAR_P (safe_chars, c)))                        \      if (id == charset_jisx0201_roman)                                   \
2631        {                                                                    \        {                                                                 \
2632          if (coding->spec.iso2022.last_invalid_designation_register == 0    \          if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_USE_ROMAN)      \
2633              && reg == 0                                                    \            id = charset_ascii;                                           \
2634              && charset == CHARSET_ASCII)                                   \        }                                                                 \
2635            {                                                                \      else if (id == charset_jisx0208_1978)                               \
2636              /* We should insert this designation sequence as is so         \        {                                                                 \
2637                 that it is surely written back to a file.  */               \          if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_USE_OLDJIS)     \
2638              coding->spec.iso2022.last_invalid_designation_register = -1;   \            id = charset_jisx0208;                                        \
2639              goto label_invalid_code;                                       \        }                                                                 \
2640            }                                                                \      CODING_ISO_DESIGNATION (coding, reg) = id;                          \
2641          coding->spec.iso2022.last_invalid_designation_register = -1;       \      /* If there was an invalid designation to REG previously, and this  \
2642          if ((coding->mode & CODING_MODE_DIRECTION)                         \         designation is ASCII to REG, we should keep this designation     \
2643              && CHARSET_REVERSE_CHARSET (charset) >= 0)                     \         sequence.  */                                                    \
2644            charset = CHARSET_REVERSE_CHARSET (charset);                     \      if (prev == -2 && id == charset_ascii)                              \
2645          CODING_SPEC_ISO_DESIGNATION (coding, reg) = charset;               \        goto invalid_code;                                                \
       }                                                                    \  
     else                                                                   \  
       {                                                                    \  
         coding->spec.iso2022.last_invalid_designation_register = reg;      \  
         goto label_invalid_code;                                           \  
       }                                                                    \  
2646    } while (0)    } while (0)
2647    
 /* Allocate a memory block for storing information about compositions.  
    The block is chained to the already allocated blocks.  */  
2648    
2649  void  #define MAYBE_FINISH_COMPOSITION()                              \
2650  coding_allocate_composition_data (coding, char_offset)    do {                                                          \
2651       struct coding_system *coding;      int i;                                                      \
2652       int char_offset;      if (composition_state == COMPOSING_NO)                      \
2653  {        break;                                                    \
2654    struct composition_data *cmp_data      /* It is assured that we have enough room for producing     \
2655      = (struct composition_data *) xmalloc (sizeof *cmp_data);         characters stored in the table `components'.  */         \
2656        if (charbuf + component_idx > charbuf_end)                  \
2657          goto no_more_source;                                      \
2658        composition_state = COMPOSING_NO;                           \
2659        if (method == COMPOSITION_RELATIVE                          \
2660            || method == COMPOSITION_WITH_ALTCHARS)                 \
2661          {                                                         \
2662            for (i = 0; i < component_idx; i++)                     \
2663              *charbuf++ = components[i];                           \
2664            char_offset += component_idx;                           \
2665          }                                                         \
2666        else                                                        \
2667          {                                                         \
2668            for (i = 0; i < component_idx; i += 2)                  \
2669              *charbuf++ = components[i];                           \
2670            char_offset += (component_idx / 2) + 1;                 \
2671          }                                                         \
2672      } while (0)
2673    
   cmp_data->char_offset = char_offset;  
   cmp_data->used = 0;  
   cmp_data->prev = coding->cmp_data;  
   cmp_data->next = NULL;  
   if (coding->cmp_data)  
     coding->cmp_data->next = cmp_data;  
   coding->cmp_data = cmp_data;  
   coding->cmp_data_start = 0;  
 }  
2674    
2675  /* Handle composition start sequence ESC 0, ESC 2, ESC 3, or ESC 4.  /* Handle composition start sequence ESC 0, ESC 2, ESC 3, or ESC 4.
2676     ESC 0 : relative composition : ESC 0 CHAR ... ESC 1     ESC 0 : relative composition : ESC 0 CHAR ... ESC 1
2677     ESC 2 : rulebase composition : ESC 2 CHAR RULE CHAR RULE ... CHAR ESC 1     ESC 2 : rulebase composition : ESC 2 CHAR RULE CHAR RULE ... CHAR ESC 1
2678     ESC 3 : altchar composition :  ESC 3 ALT ... ESC 0 CHAR ... ESC 1     ESC 3 : altchar composition :  ESC 3 CHAR ... ESC 0 CHAR ... ESC 1
2679     ESC 4 : alt&rule composition : ESC 4 ALT RULE .. ALT ESC 0 CHAR ... ESC 1     ESC 4 : alt&rule composition : ESC 4 CHAR RULE ... CHAR ESC 0 CHAR ... ESC 1
2680    */    */
2681    
2682  #define DECODE_COMPOSITION_START(c1)                                       \  #define DECODE_COMPOSITION_START(c1)                                    \
2683    do {                                                                     \    do {                                                                  \
2684      if (coding->composing == COMPOSITION_DISABLED)                         \      if (c1 == '0'                                                       \
2685        {                                                                    \          && composition_state == COMPOSING_COMPONENT_RULE)               \
2686          *dst++ = ISO_CODE_ESC;                                             \        {                                                                 \
2687          *dst++ = c1 & 0x7f;                                                \          component_len = component_idx;                                  \
2688          coding->produced_char += 2;                                        \          composition_state = COMPOSING_CHAR;                             \
2689        }                                                                    \        }                                                                 \
2690      else if (!COMPOSING_P (coding))                                        \      else                                                                \
2691        {                                                                    \        {                                                                 \
2692          /* This is surely the start of a composition.  We must be sure     \          const unsigned char *p;                                         \
2693             that coding->cmp_data has enough space to store the             \                                                                          \
2694             information about the composition.  If not, terminate the       \          MAYBE_FINISH_COMPOSITION ();                                    \
2695             current decoding loop, allocate one more memory block for       \          if (charbuf + MAX_COMPOSITION_COMPONENTS > charbuf_end)         \
2696             coding->cmp_data in the caller, then start the decoding         \            goto no_more_source;                                          \
2697             loop again.  We can't allocate memory here directly because     \          for (p = src; p < src_end - 1; p++)                             \
2698             it may cause buffer/string relocation.  */                      \            if (*p == ISO_CODE_ESC && p[1] == '1')                        \
2699          if (!coding->cmp_data                                              \              break;                                                      \
2700              || (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH \          if (p == src_end - 1)                                           \
2701                  >= COMPOSITION_DATA_SIZE))                                 \            {                                                             \
2702            {                                                                \              if (coding->mode & CODING_MODE_LAST_BLOCK)                  \
2703              coding->result = CODING_FINISH_INSUFFICIENT_CMP;               \                goto invalid_code;                                        \
2704              goto label_end_of_loop;                                        \              goto no_more_source;                                        \
2705            }                                                                \            }                                                             \
2706          coding->composing = (c1 == '0' ? COMPOSITION_RELATIVE              \                                                                          \
2707                               : c1 == '2' ? COMPOSITION_WITH_RULE           \          /* This is surely the start of a composition.  */               \
2708                               : c1 == '3' ? COMPOSITION_WITH_ALTCHARS       \          method = (c1 == '0' ? COMPOSITION_RELATIVE                      \
2709                               : COMPOSITION_WITH_RULE_ALTCHARS);            \                    : c1 == '2' ? COMPOSITION_WITH_RULE                   \
2710          CODING_ADD_COMPOSITION_START (coding, coding->produced_char,       \                    : c1 == '3' ? COMPOSITION_WITH_ALTCHARS               \
2711                                        coding->composing);                  \                    : COMPOSITION_WITH_RULE_ALTCHARS);                    \
2712          coding->composition_rule_follows = 0;                              \          composition_state = (c1 <= '2' ? COMPOSING_CHAR                 \
2713        }                                                                    \                               : COMPOSING_COMPONENT_CHAR);               \
2714      else                                                                   \          component_idx = component_len = 0;                              \
2715        {                                                                    \        }                                                                 \
         /* We are already handling a composition.  If the method is        \  
            the following two, the codes following the current escape       \  
            sequence are actual characters stored in a buffer.  */          \  
         if (coding->composing == COMPOSITION_WITH_ALTCHARS                 \  
             || coding->composing == COMPOSITION_WITH_RULE_ALTCHARS)        \  
           {                                                                \  
             coding->composing = COMPOSITION_RELATIVE;                      \  
             coding->composition_rule_follows = 0;                          \  
           }                                                                \  
       }                                                                    \  
2716    } while (0)    } while (0)
2717    
 /* Handle composition end sequence ESC 1.  */  
2718    
2719  #define DECODE_COMPOSITION_END(c1)                                      \  /* Handle compositoin end sequence ESC 1.  */
2720    
2721    #define DECODE_COMPOSITION_END()                                        \
2722    do {                                                                  \    do {                                                                  \
2723      if (! COMPOSING_P (coding))                                         \      int nchars = (component_len > 0 ? component_idx - component_len     \
2724                      : method == COMPOSITION_RELATIVE ? component_idx      \
2725                      : (component_idx + 1) / 2);                           \
2726        int i;                                                              \
2727        int *saved_charbuf = charbuf;                                       \
2728        int from = char_offset;                                             \
2729        int to = from + nchars;                                             \
2730                                                                            \
2731        ADD_COMPOSITION_DATA (charbuf, from, to, method);                   \
2732        if (method != COMPOSITION_RELATIVE)                                 \
2733        {                                                                 \        {                                                                 \
2734          *dst++ = ISO_CODE_ESC;                                          \          if (component_len == 0)                                         \
2735          *dst++ = c1;                                                    \            for (i = 0; i < component_idx; i++)                           \
2736          coding->produced_char += 2;                                     \              *charbuf++ = components[i];                                 \
2737            else                                                            \
2738              for (i = 0; i < component_len; i++)                           \
2739                *charbuf++ = components[i];                                 \
2740            *saved_charbuf = saved_charbuf - charbuf;                       \
2741        }                                                                 \        }                                                                 \
2742        if (method == COMPOSITION_WITH_RULE)                                \
2743          for (i = 0; i < component_idx; i += 2, char_offset++)             \
2744            *charbuf++ = components[i];                                     \
2745      else                                                                \      else                                                                \
2746        {                                                                 \        for (i = component_len; i < component_idx; i++, char_offset++)    \
2747          CODING_ADD_COMPOSITION_END (coding, coding->produced_char);     \          *charbuf++ = components[i];                                     \
2748          coding->composing = COMPOSITION_NO;                             \      coding->annotated = 1;                                              \
2749        }                                                                 \      composition_state = COMPOSING_NO;                                   \
2750    } while (0)    } while (0)
2751    
2752    
2753  /* Decode a composition rule from the byte C1 (and maybe one more byte  /* Decode a composition rule from the byte C1 (and maybe one more byte
2754     from SRC) and store one encoded composition rule in     from SRC) and store one encoded composition rule in
2755     coding->cmp_data.  */     coding->cmp_data.  */
2756    
2757  #define DECODE_COMPOSITION_RULE(c1)                                     \  #define DECODE_COMPOSITION_RULE(c1)                                     \
2758    do {                                                                  \    do {                                                                  \
     int rule = 0;                                                       \  
2759      (c1) -= 32;                                                         \      (c1) -= 32;                                                         \
2760      if (c1 < 81)                /* old format (before ver.21) */        \      if (c1 < 81)                /* old format (before ver.21) */        \
2761        {                                                                 \        {                                                                 \
# Line 1771  coding_allocate_composition_data (coding Line 2763  coding_allocate_composition_data (coding
2763          int nref = (c1) % 9;                                            \          int nref = (c1) % 9;                                            \
2764          if (gref == 4) gref = 10;                                       \          if (gref == 4) gref = 10;                                       \
2765          if (nref == 4) nref = 10;                                       \          if (nref == 4) nref = 10;                                       \
2766          rule = COMPOSITION_ENCODE_RULE (gref, nref);                    \          c1 = COMPOSITION_ENCODE_RULE (gref, nref);                      \
2767        }                                                                 \        }                                                                 \
2768      else if (c1 < 93)           /* new format (after ver.21) */         \      else if (c1 < 93)           /* new format (after ver.21) */         \
2769        {                                                                 \        {                                                                 \
2770          ONE_MORE_BYTE (c2);                                             \          ONE_MORE_BYTE (c2);                                             \
2771          rule = COMPOSITION_ENCODE_RULE (c1 - 81, c2 - 32);              \          c1 = COMPOSITION_ENCODE_RULE (c1 - 81, c2 - 32);                \
2772        }                                                                 \        }                                                                 \
2773      CODING_ADD_COMPOSITION_COMPONENT (coding, rule);                    \      else                                                                \
2774      coding->composition_rule_follows = 0;                               \        c1 = 0;                                                           \
2775    } while (0)    } while (0)
2776    
2777    
2778  /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */  /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */
2779    
2780  static void  static void
2781  decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)  decode_coding_iso_2022 (coding)
2782       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *source, *destination;  
      int src_bytes, dst_bytes;  
2783  {  {
2784    unsigned char *src = source;    const unsigned char *src = coding->source + coding->consumed;
2785    unsigned char *src_end = source + src_bytes;    const unsigned char *src_end = coding->source + coding->src_bytes;
2786    unsigned char *dst = destination;    const unsigned char *src_base;
2787    unsigned char *dst_end = destination + dst_bytes;    int *charbuf = coding->charbuf;
2788      int *charbuf_end
2789        = charbuf + coding->charbuf_size - 4 - MAX_ANNOTATION_LENGTH;
2790      int consumed_chars = 0, consumed_chars_base;
2791      int multibytep = coding->src_multibyte;
2792    /* Charsets invoked to graphic plane 0 and 1 respectively.  */    /* Charsets invoked to graphic plane 0 and 1 respectively.  */
2793    int charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);    int charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
2794    int charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1);    int charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
2795    /* SRC_BASE remembers the start position in source in each loop.    struct charset *charset;
2796       The loop will be exited when there's not enough source code    int c;
2797       (within macro ONE_MORE_BYTE), or when there's not enough    /* For handling composition sequence.  */
2798       destination area to produce a character (within macro  #define COMPOSING_NO                    0
2799       EMIT_CHAR).  */  #define COMPOSING_CHAR                  1
2800    unsigned char *src_base;  #define COMPOSING_RULE                  2
2801    int c, charset;  #define COMPOSING_COMPONENT_CHAR        3
2802    Lisp_Object translation_table;  #define COMPOSING_COMPONENT_RULE        4
2803    Lisp_Object safe_chars;  
2804      int composition_state = COMPOSING_NO;
2805    safe_chars = coding_safe_chars (coding->symbol);    enum composition_method method;
2806      int components[MAX_COMPOSITION_COMPONENTS * 2 + 1];
2807    if (NILP (Venable_character_translation))    int component_idx;
2808      translation_table = Qnil;    int component_len;
2809    else    Lisp_Object attrs, eol_type, charset_list;
2810      {    int char_offset = coding->produced_char;
2811        translation_table = coding->translation_table_for_decode;    int last_offset = char_offset;
2812        if (NILP (translation_table))    int last_id = charset_ascii;
         translation_table = Vstandard_translation_table_for_decode;  
     }  
2813    
2814    coding->result = CODING_FINISH_NORMAL;    CODING_GET_INFO (coding, attrs, eol_type, charset_list);
2815      setup_iso_safe_charsets (attrs);
2816    
2817    while (1)    while (1)
2818      {      {
2819        int c1, c2;        int c1, c2;
2820    
2821        src_base = src;        src_base = src;
2822          consumed_chars_base = consumed_chars;
2823    
2824          if (charbuf >= charbuf_end)
2825            break;
2826    
2827        ONE_MORE_BYTE (c1);        ONE_MORE_BYTE (c1);
2828    
2829        /* We produce no character or one character.  */        /* We produce at most one character.  */
2830        switch (iso_code_class [c1])        switch (iso_code_class [c1])
2831          {          {
2832          case ISO_0x20_or_0x7F:          case ISO_0x20_or_0x7F:
2833            if (COMPOSING_P (coding) && coding->composition_rule_follows)            if (composition_state != COMPOSING_NO)
2834              {              {
2835                DECODE_COMPOSITION_RULE (c1);                if (composition_state == COMPOSING_RULE
2836                continue;                    || composition_state == COMPOSING_COMPONENT_RULE)
2837              }                  {
2838            if (charset0 < 0 || CHARSET_CHARS (charset0) == 94)                    DECODE_COMPOSITION_RULE (c1);
2839              {                    components[component_idx++] = c1;
2840                /* This is SPACE or DEL.  */                    composition_state--;
2841                charset = CHARSET_ASCII;                    continue;
2842                break;                  }
2843              }              }
2844            /* This is a graphic character, we fall down ...  */            if (charset_id_0 < 0
2845                  || ! CHARSET_ISO_CHARS_96 (CHARSET_FROM_ID (charset_id_0)))
2846                /* This is SPACE or DEL.  */
2847                charset = CHARSET_FROM_ID (charset_ascii);
2848              else
2849                charset = CHARSET_FROM_ID (charset_id_0);
2850              break;
2851    
2852          case ISO_graphic_plane_0:          case ISO_graphic_plane_0:
2853            if (COMPOSING_P (coding) && coding->composition_rule_follows)            if (composition_state != COMPOSING_NO)
2854              {              {
2855                DECODE_COMPOSITION_RULE (c1);                if (composition_state == COMPOSING_RULE
2856                continue;                    || composition_state == COMPOSING_COMPONENT_RULE)
2857                    {
2858                      DECODE_COMPOSITION_RULE (c1);
2859                      components[component_idx++] = c1;
2860                      composition_state--;
2861                      continue;
2862                    }
2863              }              }
2864            charset = charset0;            charset = CHARSET_FROM_ID (charset_id_0);
2865            break;            break;
2866    
2867          case ISO_0xA0_or_0xFF:          case ISO_0xA0_or_0xFF:
2868            if (charset1 < 0 || CHARSET_CHARS (charset1) == 94            if (charset_id_1 < 0
2869                || coding->flags & CODING_FLAG_ISO_SEVEN_BITS)                || ! CHARSET_ISO_CHARS_96 (CHARSET_FROM_ID (charset_id_1))
2870              goto label_invalid_code;                || CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)
2871                goto invalid_code;
2872            /* This is a graphic character, we fall down ... */            /* This is a graphic character, we fall down ... */
2873    
2874          case ISO_graphic_plane_1:          case ISO_graphic_plane_1:
2875            if (charset1 < 0)            if (charset_id_1 < 0)
2876              goto label_invalid_code;              goto invalid_code;
2877            charset = charset1;            charset = CHARSET_FROM_ID (charset_id_1);
           break;  
   
         case ISO_control_0:  
           if (COMPOSING_P (coding))  
             DECODE_COMPOSITION_END ('1');  
   
           /* All ISO2022 control characters in this class have the  
              same representation in Emacs internal format.  */  
           if (c1 == '\n'  
               && (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)  
               && (coding->eol_type == CODING_EOL_CR  
                   || coding->eol_type == CODING_EOL_CRLF))  
             {  
               coding->result = CODING_FINISH_INCONSISTENT_EOL;  
               goto label_end_of_loop;  
             }  
           charset = CHARSET_ASCII;  
2878            break;            break;
2879    
         case ISO_control_1:  
           if (COMPOSING_P (coding))  
             DECODE_COMPOSITION_END ('1');  
           goto label_invalid_code;  
   
2880          case ISO_carriage_return:          case ISO_carriage_return:
2881            if (COMPOSING_P (coding))            if (c1 == '\r')
             DECODE_COMPOSITION_END ('1');  
   
           if (coding->eol_type == CODING_EOL_CR)  
             c1 = '\n';  
           else if (coding->eol_type == CODING_EOL_CRLF)  
2882              {              {
2883                ONE_MORE_BYTE (c1);                if (EQ (eol_type, Qdos))
               if (c1 != ISO_CODE_LF)  
2884                  {                  {
2885                    src--;                    if (src == src_end)
2886                    c1 = '\r';                      {
2887                          coding->result = CODING_RESULT_INSUFFICIENT_SRC;
2888                          goto no_more_source;
2889                        }
2890                      if (*src == '\n')
2891                        ONE_MORE_BYTE (c1);
2892                  }                  }
2893                  else if (EQ (eol_type, Qmac))
2894                    c1 = '\n';
2895              }              }
2896            charset = CHARSET_ASCII;            /* fall through */
2897    
2898            case ISO_control_0:
2899              MAYBE_FINISH_COMPOSITION ();
2900              charset = CHARSET_FROM_ID (charset_ascii);
2901            break;            break;
2902    
2903            case ISO_control_1:
2904              MAYBE_FINISH_COMPOSITION ();
2905              goto invalid_code;
2906    
2907          case ISO_shift_out:          case ISO_shift_out:
2908            if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT)            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT)
2909                || CODING_SPEC_ISO_DESIGNATION (coding, 1) < 0)                || CODING_ISO_DESIGNATION (coding, 1) < 0)
2910              goto label_invalid_code;              goto invalid_code;
2911            CODING_SPEC_ISO_INVOCATION (coding, 0) = 1;            CODING_ISO_INVOCATION (coding, 0) = 1;
2912            charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);            charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
2913            continue;            continue;
2914    
2915          case ISO_shift_in:          case ISO_shift_in:
2916            if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT))            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT))
2917              goto label_invalid_code;              goto invalid_code;
2918            CODING_SPEC_ISO_INVOCATION (coding, 0) = 0;            CODING_ISO_INVOCATION (coding, 0) = 0;
2919            charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);            charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
2920            continue;            continue;
2921    
2922          case ISO_single_shift_2_7:          case ISO_single_shift_2_7:
2923          case ISO_single_shift_2:          case ISO_single_shift_2:
2924            if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT))            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT))
2925              goto label_invalid_code;              goto invalid_code;
2926            /* SS2 is handled as an escape sequence of ESC 'N' */            /* SS2 is handled as an escape sequence of ESC 'N' */
2927            c1 = 'N';            c1 = 'N';
2928            goto label_escape_sequence;            goto label_escape_sequence;
2929    
2930          case ISO_single_shift_3:          case ISO_single_shift_3:
2931            if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT))            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT))
2932              goto label_invalid_code;              goto invalid_code;
2933            /* SS2 is handled as an escape sequence of ESC 'O' */            /* SS2 is handled as an escape sequence of ESC 'O' */
2934            c1 = 'O';            c1 = 'O';
2935            goto label_escape_sequence;            goto label_escape_sequence;
# Line 1944  decode_coding_iso2022 (coding, source, d Line 2942  decode_coding_iso2022 (coding, source, d
2942          case ISO_escape:          case ISO_escape:
2943            ONE_MORE_BYTE (c1);            ONE_MORE_BYTE (c1);
2944          label_escape_sequence:          label_escape_sequence:
2945            /* Escape sequences handled by Emacs are invocation,            /* Escape sequences handled here are invocation,
2946               designation, direction specification, and character               designation, direction specification, and character
2947               composition specification.  */               composition specification.  */
2948            switch (c1)            switch (c1)
# Line 1952  decode_coding_iso2022 (coding, source, d Line 2950  decode_coding_iso2022 (coding, source, d
2950              case '&':           /* revision of following character set */              case '&':           /* revision of following character set */
2951                ONE_MORE_BYTE (c1);                ONE_MORE_BYTE (c1);
2952                if (!(c1 >= '@' && c1 <= '~'))                if (!(c1 >= '@' && c1 <= '~'))
2953                  goto label_invalid_code;                  goto invalid_code;
2954                ONE_MORE_BYTE (c1);                ONE_MORE_BYTE (c1);
2955                if (c1 != ISO_CODE_ESC)                if (c1 != ISO_CODE_ESC)
2956                  goto label_invalid_code;                  goto invalid_code;
2957                ONE_MORE_BYTE (c1);                ONE_MORE_BYTE (c1);
2958                goto label_escape_sequence;                goto label_escape_sequence;
2959    
2960              case '$':           /* designation of 2-byte character set */              case '$':           /* designation of 2-byte character set */
2961                if (! (coding->flags & CODING_FLAG_ISO_DESIGNATION))                if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATION))
2962                  goto label_invalid_code;                  goto invalid_code;
2963                ONE_MORE_BYTE (c1);                ONE_MORE_BYTE (c1);
2964                if (c1 >= '@' && c1 <= 'B')                if (c1 >= '@' && c1 <= 'B')
2965                  {       /* designation of JISX0208.1978, GB2312.1980,                  {       /* designation of JISX0208.1978, GB2312.1980,
2966                             or JISX0208.1980 */                             or JISX0208.1980 */
2967                    DECODE_DESIGNATION (0, 2, 94, c1);                    DECODE_DESIGNATION (0, 2, 0, c1);
2968                  }                  }
2969                else if (c1 >= 0x28 && c1 <= 0x2B)                else if (c1 >= 0x28 && c1 <= 0x2B)
2970                  {       /* designation of DIMENSION2_CHARS94 character set */                  {       /* designation of DIMENSION2_CHARS94 character set */
2971                    ONE_MORE_BYTE (c2);                    ONE_MORE_BYTE (c2);
2972                    DECODE_DESIGNATION (c1 - 0x28, 2, 94, c2);                    DECODE_DESIGNATION (c1 - 0x28, 2, 0, c2);
2973                  }                  }
2974                else if (c1 >= 0x2C && c1 <= 0x2F)                else if (c1 >= 0x2C && c1 <= 0x2F)
2975                  {       /* designation of DIMENSION2_CHARS96 character set */                  {       /* designation of DIMENSION2_CHARS96 character set */
2976                    ONE_MORE_BYTE (c2);                    ONE_MORE_BYTE (c2);
2977                    DECODE_DESIGNATION (c1 - 0x2C, 2, 96, c2);                    DECODE_DESIGNATION (c1 - 0x2C, 2, 1, c2);
2978                  }                  }
2979                else                else
2980                  goto label_invalid_code;                  goto invalid_code;
2981                /* We must update these variables now.  */                /* We must update these variables now.  */
2982                charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);                charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
2983                charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1);                charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
2984                continue;                continue;
2985    
2986              case 'n':           /* invocation of locking-shift-2 */              case 'n':           /* invocation of locking-shift-2 */
2987                if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT)                if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT)
2988                    || CODING_SPEC_ISO_DESIGNATION (coding, 2) < 0)                    || CODING_ISO_DESIGNATION (coding, 2) < 0)
2989                  goto label_invalid_code;                  goto invalid_code;
2990                CODING_SPEC_ISO_INVOCATION (coding, 0) = 2;                CODING_ISO_INVOCATION (coding, 0) = 2;
2991                charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);                charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
2992                continue;                continue;
2993    
2994              case 'o':           /* invocation of locking-shift-3 */              case 'o':           /* invocation of locking-shift-3 */
2995                if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT)                if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT)
2996                    || CODING_SPEC_ISO_DESIGNATION (coding, 3) < 0)                    || CODING_ISO_DESIGNATION (coding, 3) < 0)
2997                  goto label_invalid_code;                  goto invalid_code;
2998                CODING_SPEC_ISO_INVOCATION (coding, 0) = 3;                CODING_ISO_INVOCATION (coding, 0) = 3;
2999                charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);                charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
3000                continue;                continue;
3001    
3002              case 'N':           /* invocation of single-shift-2 */              case 'N':           /* invocation of single-shift-2 */
3003                if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)                if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
3004                    || CODING_SPEC_ISO_DESIGNATION (coding, 2) < 0)                    || CODING_ISO_DESIGNATION (coding, 2) < 0)
3005                  goto label_invalid_code;                  goto invalid_code;
3006                charset = CODING_SPEC_ISO_DESIGNATION (coding, 2);                charset = CHARSET_FROM_ID (CODING_ISO_DESIGNATION (coding, 2));
3007                ONE_MORE_BYTE (c1);                ONE_MORE_BYTE (c1);
3008                if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0))                if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0))
3009                  goto label_invalid_code;                  goto invalid_code;
3010                break;                break;
3011    
3012              case 'O':           /* invocation of single-shift-3 */              case 'O':           /* invocation of single-shift-3 */
3013                if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)                if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
3014                    || CODING_SPEC_ISO_DESIGNATION (coding, 3) < 0)                    || CODING_ISO_DESIGNATION (coding, 3) < 0)
3015                  goto label_invalid_code;                  goto invalid_code;
3016                charset = CODING_SPEC_ISO_DESIGNATION (coding, 3);                charset = CHARSET_FROM_ID (CODING_ISO_DESIGNATION (coding, 3));
3017                ONE_MORE_BYTE (c1);                ONE_MORE_BYTE (c1);
3018                if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0))                if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0))
3019                  goto label_invalid_code;                  goto invalid_code;
3020                break;                break;
3021    
3022              case '0': case '2': case '3': case '4': /* start composition */              case '0': case '2': case '3': case '4': /* start composition */
3023                  if (! (coding->common_flags & CODING_ANNOTATE_COMPOSITION_MASK))
3024                    goto invalid_code;
3025                DECODE_COMPOSITION_START (c1);                DECODE_COMPOSITION_START (c1);
3026                continue;                continue;
3027    
3028              case '1':           /* end composition */              case '1':           /* end composition */
3029                DECODE_COMPOSITION_END (c1);                if (composition_state == COMPOSING_NO)
3030                    goto invalid_code;
3031                  DECODE_COMPOSITION_END ();
3032                continue;                continue;
3033    
3034              case '[':           /* specification of direction */              case '[':           /* specification of direction */
3035                if (coding->flags & CODING_FLAG_ISO_NO_DIRECTION)                if (! CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DIRECTION)
3036                  goto label_invalid_code;                  goto invalid_code;
3037                /* For the moment, nested direction is not supported.                /* For the moment, nested direction is not supported.
3038                   So, `coding->mode & CODING_MODE_DIRECTION' zero means                   So, `coding->mode & CODING_MODE_DIRECTION' zero means
3039                   left-to-right, and nonzero means right-to-left.  */                   left-to-right, and nozero means right-to-left.  */
3040                ONE_MORE_BYTE (c1);                ONE_MORE_BYTE (c1);
3041                switch (c1)                switch (c1)
3042                  {                  {
# Line 2047  decode_coding_iso2022 (coding, source, d Line 3049  decode_coding_iso2022 (coding, source, d
3049                    if (c1 == ']')                    if (c1 == ']')
3050                      coding->mode &= ~CODING_MODE_DIRECTION;                      coding->mode &= ~CODING_MODE_DIRECTION;
3051                    else                    else
3052                      goto label_invalid_code;                      goto invalid_code;
3053                    break;                    break;
3054    
3055                  case '2':       /* start of right-to-left direction */                  case '2':       /* start of right-to-left direction */
# Line 2055  decode_coding_iso2022 (coding, source, d Line 3057  decode_coding_iso2022 (coding, source, d
3057                    if (c1 == ']')                    if (c1 == ']')
3058                      coding->mode |= CODING_MODE_DIRECTION;                      coding->mode |= CODING_MODE_DIRECTION;
3059                    else                    else
3060                      goto label_invalid_code;                      goto invalid_code;
3061                    break;                    break;
3062    
3063                  default:                  default:
3064                    goto label_invalid_code;                    goto invalid_code;
3065                  }                  }
3066                continue;                continue;
3067    
3068              case '%':              case '%':
               if (COMPOSING_P (coding))  
                 DECODE_COMPOSITION_END ('1');  
3069                ONE_MORE_BYTE (c1);                ONE_MORE_BYTE (c1);
3070                if (c1 == '/')                if (c1 == '/')
3071                  {                  {
# Line 2074  decode_coding_iso2022 (coding, source, d Line 3074  decode_coding_iso2022 (coding, source, d
3074                       We keep these bytes as is for the moment.                       We keep these bytes as is for the moment.
3075                       They may be decoded by post-read-conversion.  */                       They may be decoded by post-read-conversion.  */
3076                    int dim, M, L;                    int dim, M, L;
3077                    int size, required;                    int size;
3078                    int produced_chars;  
                     
3079                    ONE_MORE_BYTE (dim);                    ONE_MORE_BYTE (dim);
3080                    ONE_MORE_BYTE (M);                    ONE_MORE_BYTE (M);
3081                    ONE_MORE_BYTE (L);                    ONE_MORE_BYTE (L);
3082                    size = ((M - 128) * 128) + (L - 128);                    size = ((M - 128) * 128) + (L - 128);
3083                    required = 8 + size * 2;                    if (charbuf + 8 + size > charbuf_end)
3084                    if (dst + required > (dst_bytes ? dst_end : src))                      goto break_loop;
3085                      goto label_end_of_loop;                    *charbuf++ = ISO_CODE_ESC;
3086                    *dst++ = ISO_CODE_ESC;                    *charbuf++ = '%';
3087                    *dst++ = '%';                    *charbuf++ = '/';
3088                    *dst++ = '/';                    *charbuf++ = dim;
3089                    *dst++ = dim;                    *charbuf++ = BYTE8_TO_CHAR (M);
3090                    produced_chars = 4;                    *charbuf++ = BYTE8_TO_CHAR (L);
                   dst += CHAR_STRING (M, dst), produced_chars++;  
                   dst += CHAR_STRING (L, dst), produced_chars++;  
3091                    while (size-- > 0)                    while (size-- > 0)
3092                      {                      {
3093                        ONE_MORE_BYTE (c1);                        ONE_MORE_BYTE (c1);
3094                        dst += CHAR_STRING (c1, dst), produced_chars++;                        *charbuf++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
3095                      }                      }
                   coding->produced_char += produced_chars;  
3096                  }                  }
3097                else if (c1 == 'G')                else if (c1 == 'G')
3098                  {                  {
                   unsigned char *d = dst;  
                   int produced_chars;  
   
3099                    /* XFree86 extension for embedding UTF-8 in CTEXT:                    /* XFree86 extension for embedding UTF-8 in CTEXT:
3100                       ESC % G --UTF-8-BYTES-- ESC % @                       ESC % G --UTF-8-BYTES-- ESC % @
3101                       We keep these bytes as is for the moment.                       We keep these bytes as is for the moment.
3102                       They may be decoded by post-read-conversion.  */                       They may be decoded by post-read-conversion.  */
3103                    if (d + 6 > (dst_bytes ? dst_end : src))                    int *p = charbuf;
3104                      goto label_end_of_loop;  
3105                    *d++ = ISO_CODE_ESC;                    if (p + 6 > charbuf_end)
3106                    *d++ = '%';                      goto break_loop;
3107                    *d++ = 'G';                    *p++ = ISO_CODE_ESC;
3108                    produced_chars = 3;                    *p++ = '%';
3109                    while (d + 1 < (dst_bytes ? dst_end : src))                    *p++ = 'G';
3110                      while (p < charbuf_end)
3111                      {                      {
3112                        ONE_MORE_BYTE (c1);                        ONE_MORE_BYTE (c1);
3113                        if (c1 == ISO_CODE_ESC                        if (c1 == ISO_CODE_ESC
# Line 2121  decode_coding_iso2022 (coding, source, d Line 3115  decode_coding_iso2022 (coding, source, d
3115                            && src[0] == '%'                            && src[0] == '%'
3116                            && src[1] == '@')                            && src[1] == '@')
3117                          break;                          break;
3118                        d += CHAR_STRING (c1, d), produced_chars++;                        *p++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
3119                      }                      }
3120                    if (d + 3 > (dst_bytes ? dst_end : src))                    if (p + 3 > charbuf_end)
3121                      goto label_end_of_loop;                      goto break_loop;
3122                    *d++ = ISO_CODE_ESC;                    *p++ = ISO_CODE_ESC;
3123                    *d++ = '%';                    *p++ = '%';
3124                    *d++ = '@';                    *p++ = '@';
3125                    dst = d;                    charbuf = p;
                   coding->produced_char += produced_chars + 3;  
3126                  }                  }
3127                else                else
3128                  goto label_invalid_code;                  goto invalid_code;
3129                continue;                continue;
3130                  break;
3131    
3132              default:              default:
3133                if (! (coding->flags & CODING_FLAG_ISO_DESIGNATION))                if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATION))
3134                  goto label_invalid_code;                  goto invalid_code;
3135                if (c1 >= 0x28 && c1 <= 0x2B)                if (c1 >= 0x28 && c1 <= 0x2B)
3136                  {       /* designation of DIMENSION1_CHARS94 character set */                  {       /* designation of DIMENSION1_CHARS94 character set */
3137                    ONE_MORE_BYTE (c2);                    ONE_MORE_BYTE (c2);
3138                    DECODE_DESIGNATION (c1 - 0x28, 1, 94, c2);                    DECODE_DESIGNATION (c1 - 0x28, 1, 0, c2);
3139                  }                  }
3140                else if (c1 >= 0x2C && c1 <= 0x2F)                else if (c1 >= 0x2C && c1 <= 0x2F)
3141                  {       /* designation of DIMENSION1_CHARS96 character set */                  {       /* designation of DIMENSION1_CHARS96 character set */
3142                    ONE_MORE_BYTE (c2);                    ONE_MORE_BYTE (c2);
3143                    DECODE_DESIGNATION (c1 - 0x2C, 1, 96, c2);                    DECODE_DESIGNATION (c1 - 0x2C, 1, 1, c2);
3144                  }                  }
3145                else                else
3146                  goto label_invalid_code;                  goto invalid_code;
3147                /* We must update these variables now.  */                /* We must update these variables now.  */
3148                charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);                charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
3149                charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1);                charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
3150                continue;                continue;
3151              }              }
3152          }          }
3153    
3154          if (charset->id != charset_ascii
3155              && last_id != charset->id)
3156            {
3157              if (last_id != charset_ascii)
3158                ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
3159              last_id = charset->id;
3160              last_offset = char_offset;
3161            }
3162    
3163        /* Now we know CHARSET and 1st position code C1 of a character.        /* Now we know CHARSET and 1st position code C1 of a character.
3164           Produce a multibyte sequence for that character while getting           Produce a decoded character while getting 2nd position code
3165           2nd position code C2 if necessary.  */           C2 if necessary.  */
3166        if (CHARSET_DIMENSION (charset) == 2)        c1 &= 0x7F;
3167          if (CHARSET_DIMENSION (charset) > 1)
3168          {          {
3169            ONE_MORE_BYTE (c2);            ONE_MORE_BYTE (c2);
3170            if (c1 < 0x80 ? c2 < 0x20 || c2 >= 0x80 : c2 < 0xA0)            if (c2 < 0x20 || (c2 >= 0x80 && c2 < 0xA0))
3171              /* C2 is not in a valid range.  */              /* C2 is not in a valid range.  */
3172              goto label_invalid_code;              goto invalid_code;
3173              c1 = (c1 << 8) | (c2 & 0x7F);
3174              if (CHARSET_DIMENSION (charset) > 2)
3175                {
3176                  ONE_MORE_BYTE (c2);
3177                  if (c2 < 0x20 || (c2 >= 0x80 && c2 < 0xA0))
3178                    /* C2 is not in a valid range.  */
3179                    goto invalid_code;
3180                  c1 = (c1 << 8) | (c2 & 0x7F);
3181                }
3182            }
3183    
3184          CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c1, c);
3185          if (c < 0)
3186            {
3187              MAYBE_FINISH_COMPOSITION ();
3188              for (; src_base < src; src_base++, char_offset++)
3189                {
3190                  if (ASCII_BYTE_P (*src_base))
3191                    *charbuf++ = *src_base;
3192                  else
3193                    *charbuf++ = BYTE8_TO_CHAR (*src_base);
3194                }
3195            }
3196          else if (composition_state == COMPOSING_NO)
3197            {
3198              *charbuf++ = c;
3199              char_offset++;
3200            }
3201          else
3202            {
3203              components[component_idx++] = c;
3204              if (method == COMPOSITION_WITH_RULE
3205                  || (method == COMPOSITION_WITH_RULE_ALTCHARS
3206                      && composition_state == COMPOSING_COMPONENT_CHAR))
3207                composition_state++;
3208          }          }
       c = DECODE_ISO_CHARACTER (charset, c1, c2);  
       EMIT_CHAR (c);  
3209        continue;        continue;
3210    
3211      label_invalid_code:      invalid_code:
3212        coding->errors++;        MAYBE_FINISH_COMPOSITION ();
       if (COMPOSING_P (coding))  
         DECODE_COMPOSITION_END ('1');  
3213        src = src_base;        src = src_base;
3214        c = *src++;        consumed_chars = consumed_chars_base;
3215        EMIT_CHAR (c);        ONE_MORE_BYTE (c);
3216          *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
3217          char_offset++;
3218          coding->errors++;
3219          continue;
3220    
3221        break_loop:
3222          break;
3223      }      }
3224    
3225   label_end_of_loop:   no_more_source:
3226    coding->consumed = coding->consumed_char = src_base - source;    if (last_id != charset_ascii)
3227    coding->produced = dst - destination;      ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
3228    return;    coding->consumed_char += consumed_chars_base;
3229      coding->consumed = src_base - coding->source;
3230      coding->charbuf_used = charbuf - coding->charbuf;
3231  }  }
3232    
3233    
# Line 2191  decode_coding_iso2022 (coding, source, d Line 3235  decode_coding_iso2022 (coding, source, d
3235    
3236  /*  /*
3237     It is not enough to say just "ISO2022" on encoding, we have to     It is not enough to say just "ISO2022" on encoding, we have to
3238     specify more details.  In Emacs, each ISO2022 coding system     specify more details.  In Emacs, each coding system of ISO2022
3239     variant has the following specifications:     variant has the following specifications:
3240          1. Initial designation to G0 through G3.          1. Initial designation to G0 thru G3.
3241          2. Allows short-form designation?          2. Allows short-form designation?
3242          3. ASCII should be designated to G0 before control characters?          3. ASCII should be designated to G0 before control characters?
3243          4. ASCII should be designated to G0 at end of line?          4. ASCII should be designated to G0 at end of line?
# Line 2203  decode_coding_iso2022 (coding, source, d Line 3247  decode_coding_iso2022 (coding, source, d
3247     And the following two are only for Japanese:     And the following two are only for Japanese:
3248          8. Use ASCII in place of JIS0201-1976-Roman?          8. Use ASCII in place of JIS0201-1976-Roman?
3249          9. Use JISX0208-1983 in place of JISX0208-1978?          9. Use JISX0208-1983 in place of JISX0208-1978?
3250     These specifications are encoded in `coding->flags' as flag bits     These specifications are encoded in CODING_ISO_FLAGS (coding) as flag bits
3251     defined by macros CODING_FLAG_ISO_XXX.  See `coding.h' for more     defined by macros CODING_ISO_FLAG_XXX.  See `coding.h' for more
3252     details.     details.
3253  */  */
3254    
# Line 2215  decode_coding_iso2022 (coding, source, d Line 3259  decode_coding_iso2022 (coding, source, d
3259    
3260  #define ENCODE_DESIGNATION(charset, reg, coding)                        \  #define ENCODE_DESIGNATION(charset, reg, coding)                        \
3261    do {                                                                  \    do {                                                                  \
3262      unsigned char final_char = CHARSET_ISO_FINAL_CHAR (charset);        \      unsigned char final_char = CHARSET_ISO_FINAL (charset);             \
3263      char *intermediate_char_94 = "()*+";                                \      char *intermediate_char_94 = "()*+";                                \
3264      char *intermediate_char_96 = ",-./";                                \      char *intermediate_char_96 = ",-./";                                \
3265      int revision = CODING_SPEC_ISO_REVISION_NUMBER(coding, charset);    \      int revision = -1;                                                  \
3266                                                                          \      int c;                                                              \
3267      if (revision < 255)                                                 \                                                                          \
3268        if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_REVISION)           \
3269          revision = CHARSET_ISO_REVISION (charset);                        \
3270                                                                            \
3271        if (revision >= 0)                                                  \
3272        {                                                                 \        {                                                                 \
3273          *dst++ = ISO_CODE_ESC;                                          \          EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, '&');                       \
3274          *dst++ = '&';                                                   \          EMIT_ONE_BYTE ('@' + revision);                                 \
         *dst++ = '@' + revision;                                        \  
3275        }                                                                 \        }                                                                 \
3276      *dst++ = ISO_CODE_ESC;                                              \      EMIT_ONE_ASCII_BYTE (ISO_CODE_ESC);                                 \
3277      if (CHARSET_DIMENSION (charset) == 1)                               \      if (CHARSET_DIMENSION (charset) == 1)                               \
3278        {                                                                 \        {                                                                 \
3279          if (CHARSET_CHARS (charset) == 94)                              \          if (! CHARSET_ISO_CHARS_96 (charset))                           \
3280            *dst++ = (unsigned char) (intermediate_char_94[reg]);         \            c = intermediate_char_94[reg];                                \
3281          else                                                            \          else                                                            \
3282            *dst++ = (unsigned char) (intermediate_char_96[reg]);         \            c = intermediate_char_96[reg];                                \
3283            EMIT_ONE_ASCII_BYTE (c);                                        \
3284        }                                                                 \        }                                                                 \
3285      else                                                                \      else                                                                \
3286        {                                                                 \        {                                                                 \
3287          *dst++ = '$';                                                   \          EMIT_ONE_ASCII_BYTE ('$');                                      \
3288          if (CHARSET_CHARS (charset) == 94)                              \          if (! CHARSET_ISO_CHARS_96 (charset))                           \
3289            {                                                             \            {                                                             \
3290              if (! (coding->flags & CODING_FLAG_ISO_SHORT_FORM)          \              if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LONG_FORM   \
3291                  || reg != 0                                             \                  || reg != 0                                             \
3292                  || final_char < '@' || final_char > 'B')                \                  || final_char < '@' || final_char > 'B')                \
3293                *dst++ = (unsigned char) (intermediate_char_94[reg]);     \                EMIT_ONE_ASCII_BYTE (intermediate_char_94[reg]);          \
3294            }                                                             \            }                                                             \
3295          else                                                            \          else                                                            \
3296            *dst++ = (unsigned char) (intermediate_char_96[reg]);         \            EMIT_ONE_ASCII_BYTE (intermediate_char_96[reg]);              \
3297        }                                                                 \        }                                                                 \
3298      *dst++ = final_char;                                                \      EMIT_ONE_ASCII_BYTE (final_char);                                   \
3299      CODING_SPEC_ISO_DESIGNATION (coding, reg) = charset;                \                                                                          \
3300        CODING_ISO_DESIGNATION (coding, reg) = CHARSET_ID (charset);        \
3301    } while (0)    } while (0)
3302    
3303    
3304  /* The following two macros produce codes (control character or escape  /* The following two macros produce codes (control character or escape
3305     sequence) for ISO2022 single-shift functions (single-shift-2 and     sequence) for ISO2022 single-shift functions (single-shift-2 and
3306     single-shift-3).  */     single-shift-3).  */
3307    
3308  #define ENCODE_SINGLE_SHIFT_2                           \  #define ENCODE_SINGLE_SHIFT_2                                           \
3309    do {                                                  \    do {                                                                  \
3310      if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)     \      if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)         \
3311        *dst++ = ISO_CODE_ESC, *dst++ = 'N';              \        EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'N');                         \
3312      else                                                \      else                                                                \
3313        *dst++ = ISO_CODE_SS2;                            \        EMIT_ONE_BYTE (ISO_CODE_SS2);                                     \
3314      CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 1;       \      CODING_ISO_SINGLE_SHIFTING (coding) = 1;                            \
3315    } while (0)    } while (0)
3316    
3317  #define ENCODE_SINGLE_SHIFT_3                           \  
3318    do {                                                  \  #define ENCODE_SINGLE_SHIFT_3                                           \
3319      if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)     \    do {                                                                  \
3320        *dst++ = ISO_CODE_ESC, *dst++ = 'O';              \      if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)         \
3321      else                                                \        EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'O');                         \
3322        *dst++ = ISO_CODE_SS3;                            \      else                                                                \
3323      CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 1;       \        EMIT_ONE_BYTE (ISO_CODE_SS3);                                     \
3324        CODING_ISO_SINGLE_SHIFTING (coding) = 1;                            \
3325    } while (0)    } while (0)
3326    
3327    
3328  /* The following four macros produce codes (control character or  /* The following four macros produce codes (control character or
3329     escape sequence) for ISO2022 locking-shift functions (shift-in,     escape sequence) for ISO2022 locking-shift functions (shift-in,
3330     shift-out, locking-shift-2, and locking-shift-3).  */     shift-out, locking-shift-2, and locking-shift-3).  */
3331    
3332  #define ENCODE_SHIFT_IN                         \  #define ENCODE_SHIFT_IN                                 \
3333    do {                                          \    do {                                                  \
3334      *dst++ = ISO_CODE_SI;                       \      EMIT_ONE_ASCII_BYTE (ISO_CODE_SI);                  \
3335      CODING_SPEC_ISO_INVOCATION (coding, 0) = 0; \      CODING_ISO_INVOCATION (coding, 0) = 0;              \
3336    } while (0)    } while (0)
3337    
3338  #define ENCODE_SHIFT_OUT                        \  
3339    do {                                          \  #define ENCODE_SHIFT_OUT                                \
3340      *dst++ = ISO_CODE_SO;                       \    do {                                                  \
3341      CODING_SPEC_ISO_INVOCATION (coding, 0) = 1; \      EMIT_ONE_ASCII_BYTE (ISO_CODE_SO);                  \
3342        CODING_ISO_INVOCATION (coding, 0) = 1;              \
3343    } while (0)    } while (0)
3344    
3345  #define ENCODE_LOCKING_SHIFT_2                  \  
3346    do {                                          \  #define ENCODE_LOCKING_SHIFT_2                          \
3347      *dst++ = ISO_CODE_ESC, *dst++ = 'n';        \    do {                                                  \
3348      CODING_SPEC_ISO_INVOCATION (coding, 0) = 2; \      EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'n');           \
3349        CODING_ISO_INVOCATION (coding, 0) = 2;              \
3350    } while (0)    } while (0)
3351    
3352  #define ENCODE_LOCKING_SHIFT_3                  \  
3353    do {                                          \  #define ENCODE_LOCKING_SHIFT_3                          \
3354      *dst++ = ISO_CODE_ESC, *dst++ = 'o';        \    do {                                                  \
3355      CODING_SPEC_ISO_INVOCATION (coding, 0) = 3; \      EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'n');           \
3356        CODING_ISO_INVOCATION (coding, 0) = 3;              \
3357    } while (0)    } while (0)
3358    
3359    
3360  /* Produce codes for a DIMENSION1 character whose character set is  /* Produce codes for a DIMENSION1 character whose character set is
3361     CHARSET and whose position-code is C1.  Designation and invocation     CHARSET and whose position-code is C1.  Designation and invocation
3362     sequences are also produced in advance if necessary.  */     sequences are also produced in advance if necessary.  */
3363    
3364  #define ENCODE_ISO_CHARACTER_DIMENSION1(charset, c1)                    \  #define ENCODE_ISO_CHARACTER_DIMENSION1(charset, c1)                    \
3365    do {                                                                  \    do {                                                                  \
3366      if (CODING_SPEC_ISO_SINGLE_SHIFTING (coding))                       \      int id = CHARSET_ID (charset);                                      \
3367                                                                            \
3368        if ((CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_USE_ROMAN)         \
3369            && id == charset_ascii)                                         \
3370        {                                                                 \        {                                                                 \
3371          if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)                 \          id = charset_jisx0201_roman;                                    \
3372            *dst++ = c1 & 0x7F;                                           \          charset = CHARSET_FROM_ID (id);                                 \
3373          }                                                                 \
3374                                                                            \
3375        if (CODING_ISO_SINGLE_SHIFTING (coding))                            \
3376          {                                                                 \
3377            if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)     \
3378              EMIT_ONE_ASCII_BYTE (c1 & 0x7F);                              \
3379          else                                                            \          else                                                            \
3380            *dst++ = c1 | 0x80;                                           \            EMIT_ONE_BYTE (c1 | 0x80);                                    \
3381          CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 0;                   \          CODING_ISO_SINGLE_SHIFTING (coding) = 0;                        \
3382          break;                                                          \          break;                                                          \
3383        }                                                                 \        }                                                                 \
3384      else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 0))      \      else if (id == CODING_ISO_INVOKED_CHARSET (coding, 0))              \
3385        {                                                                 \        {                                                                 \
3386          *dst++ = c1 & 0x7F;                                             \          EMIT_ONE_ASCII_BYTE (c1 & 0x7F);                                \
3387          break;                                                          \          break;                                                          \
3388        }                                                                 \        }                                                                 \
3389      else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 1))      \      else if (id == CODING_ISO_INVOKED_CHARSET (coding, 1))              \
3390        {                                                                 \        {                                                                 \
3391          *dst++ = c1 | 0x80;                                             \          EMIT_ONE_BYTE (c1 | 0x80);                                      \
3392          break;                                                          \          break;                                                          \
3393        }                                                                 \        }                                                                 \
3394      else                                                                \      else                                                                \
# Line 2331  decode_coding_iso2022 (coding, source, d Line 3396  decode_coding_iso2022 (coding, source, d
3396           must invoke it, or, at first, designate it to some graphic     \           must invoke it, or, at first, designate it to some graphic     \
3397           register.  Then repeat the loop to actually produce the        \           register.  Then repeat the loop to actually produce the        \
3398           character.  */                                                 \           character.  */                                                 \
3399        dst = encode_invocation_designation (charset, coding, dst);       \        dst = encode_invocation_designation (charset, coding, dst,        \
3400                                               &produced_chars);            \
3401    } while (1)    } while (1)
3402    
3403    
3404  /* Produce codes for a DIMENSION2 character whose character set is  /* Produce codes for a DIMENSION2 character whose character set is
3405     CHARSET and whose position-codes are C1 and C2.  Designation and     CHARSET and whose position-codes are C1 and C2.  Designation and
3406     invocation codes are also produced in advance if necessary.  */     invocation codes are also produced in advance if necessary.  */
3407    
3408  #define ENCODE_ISO_CHARACTER_DIMENSION2(charset, c1, c2)                \  #define ENCODE_ISO_CHARACTER_DIMENSION2(charset, c1, c2)                \
3409    do {                                                                  \    do {                                                                  \
3410      if (CODING_SPEC_ISO_SINGLE_SHIFTING (coding))                       \      int id = CHARSET_ID (charset);                                      \
3411                                                                            \
3412        if ((CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_USE_OLDJIS)        \
3413            && id == charset_jisx0208)                                      \
3414        {                                                                 \        {                                                                 \
3415          if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)                 \          id = charset_jisx0208_1978;                                     \
3416            *dst++ = c1 & 0x7F, *dst++ = c2 & 0x7F;                       \          charset = CHARSET_FROM_ID (id);                                 \
3417          }                                                                 \
3418                                                                            \
3419        if (CODING_ISO_SINGLE_SHIFTING (coding))                            \
3420          {                                                                 \
3421            if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)     \
3422              EMIT_TWO_ASCII_BYTES ((c1) & 0x7F, (c2) & 0x7F);              \
3423          else                                                            \          else                                                            \
3424            *dst++ = c1 | 0x80, *dst++ = c2 | 0x80;                       \            EMIT_TWO_BYTES ((c1) | 0x80, (c2) | 0x80);                    \
3425          CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 0;                   \          CODING_ISO_SINGLE_SHIFTING (coding) = 0;                        \
3426          break;                                                          \          break;                                                          \
3427        }                                                                 \        }                                                                 \
3428      else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 0))      \      else if (id == CODING_ISO_INVOKED_CHARSET (coding, 0))              \
3429        {                                                                 \        {                                                                 \
3430          *dst++ = c1 & 0x7F, *dst++= c2 & 0x7F;                          \          EMIT_TWO_ASCII_BYTES ((c1) & 0x7F, (c2) & 0x7F);                \
3431          break;                                                          \          break;                                                          \
3432        }                                                                 \        }                                                                 \
3433      else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 1))      \      else if (id == CODING_ISO_INVOKED_CHARSET (coding, 1))              \
3434        {                                                                 \        {                                                                 \
3435          *dst++ = c1 | 0x80, *dst++= c2 | 0x80;                          \          EMIT_TWO_BYTES ((c1) | 0x80, (c2) | 0x80);                      \
3436          break;                                                          \          break;                                                          \
3437        }                                                                 \        }                                                                 \
3438      else                                                                \      else                                                                \
# Line 2364  decode_coding_iso2022 (coding, source, d Line 3440  decode_coding_iso2022 (coding, source, d
3440           must invoke it, or, at first, designate it to some graphic     \           must invoke it, or, at first, designate it to some graphic     \
3441           register.  Then repeat the loop to actually produce the        \           register.  Then repeat the loop to actually produce the        \
3442           character.  */                                                 \           character.  */                                                 \
3443        dst = encode_invocation_designation (charset, coding, dst);       \        dst = encode_invocation_designation (charset, coding, dst,        \
3444                                               &produced_chars);            \
3445    } while (1)    } while (1)
3446    
 #define ENCODE_ISO_CHARACTER(c)                                 \  
   do {                                                          \  
     int charset, c1, c2;                                        \  
                                                                 \  
     SPLIT_CHAR (c, charset, c1, c2);                            \  
     if (CHARSET_DEFINED_P (charset))                            \  
       {                                                         \  
         if (CHARSET_DIMENSION (charset) == 1)                   \  
           {                                                     \  
             if (charset == CHARSET_ASCII                        \  
                 && coding->flags & CODING_FLAG_ISO_USE_ROMAN)   \  
               charset = charset_latin_jisx0201;                 \  
             ENCODE_ISO_CHARACTER_DIMENSION1 (charset, c1);      \  
           }                                                     \  
         else                                                    \  
           {                                                     \  
             if (charset == charset_jisx0208                     \  
                 && coding->flags & CODING_FLAG_ISO_USE_OLDJIS)  \  
               charset = charset_jisx0208_1978;                  \  
             ENCODE_ISO_CHARACTER_DIMENSION2 (charset, c1, c2);  \  
           }                                                     \  
       }                                                         \  
     else                                                        \  
       {                                                         \  
         *dst++ = c1;                                            \  
         if (c2 >= 0)                                            \  
           *dst++ = c2;                                          \  
       }                                                         \  
   } while (0)  
   
   
 /* Instead of encoding character C, produce one or two `?'s.  */  
3447    
3448  #define ENCODE_UNSAFE_CHARACTER(c)                              \  #define ENCODE_ISO_CHARACTER(charset, c)                                   \
3449    do {                                                          \    do {                                                                     \
3450      ENCODE_ISO_CHARACTER (CODING_REPLACEMENT_CHARACTER);        \      int code = ENCODE_CHAR ((charset),(c));                                \
3451      if (CHARSET_WIDTH (CHAR_CHARSET (c)) > 1)                   \                                                                             \
3452        ENCODE_ISO_CHARACTER (CODING_REPLACEMENT_CHARACTER);      \      if (CHARSET_DIMENSION (charset) == 1)                                  \
3453          ENCODE_ISO_CHARACTER_DIMENSION1 ((charset), code);                   \
3454        else                                                                   \
3455          ENCODE_ISO_CHARACTER_DIMENSION2 ((charset), code >> 8, code & 0xFF); \
3456    } while (0)    } while (0)
3457    
3458    
3459  /* Produce designation and invocation codes at a place pointed by DST  /* Produce designation and invocation codes at a place pointed by DST
3460     to use CHARSET.  The element `spec.iso2022' of *CODING is updated.     to use CHARSET.  The element `spec.iso_2022' of *CODING is updated.
3461     Return new DST.  */     Return new DST.  */
3462    
3463  unsigned char *  unsigned char *
3464  encode_invocation_designation (charset, coding, dst)  encode_invocation_designation (charset, coding, dst, p_nchars)
3465       int charset;       struct charset *charset;
3466       struct coding_system *coding;       struct coding_system *coding;
3467       unsigned char *dst;       unsigned char *dst;
3468         int *p_nchars;
3469  {  {
3470      int multibytep = coding->dst_multibyte;
3471      int produced_chars = *p_nchars;
3472    int reg;                      /* graphic register number */    int reg;                      /* graphic register number */
3473      int id = CHARSET_ID (charset);
3474    
3475    /* At first, check designations.  */    /* At first, check designations.  */
3476    for (reg = 0; reg < 4; reg++)    for (reg = 0; reg < 4; reg++)
3477      if (charset == CODING_SPEC_ISO_DESIGNATION (coding, reg))      if (id == CODING_ISO_DESIGNATION (coding, reg))
3478        break;        break;
3479    
3480    if (reg >= 4)    if (reg >= 4)
3481      {      {
3482        /* CHARSET is not yet designated to any graphic registers.  */        /* CHARSET is not yet designated to any graphic registers.  */
3483        /* At first check the requested designation.  */        /* At first check the requested designation.  */
3484        reg = CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset);        reg = CODING_ISO_REQUEST (coding, id);
3485        if (reg == CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION)        if (reg < 0)
3486          /* Since CHARSET requests no special designation, designate it          /* Since CHARSET requests no special designation, designate it
3487             to graphic register 0.  */             to graphic register 0.  */
3488          reg = 0;          reg = 0;
# Line 2438  encode_invocation_designation (charset, Line 3490  encode_invocation_designation (charset,
3490        ENCODE_DESIGNATION (charset, reg, coding);        ENCODE_DESIGNATION (charset, reg, coding);
3491      }      }
3492    
3493    if (CODING_SPEC_ISO_INVOCATION (coding, 0) != reg    if (CODING_ISO_INVOCATION (coding, 0) != reg
3494        && CODING_SPEC_ISO_INVOCATION (coding, 1) != reg)        && CODING_ISO_INVOCATION (coding, 1) != reg)
3495      {      {
3496        /* Since the graphic register REG is not invoked to any graphic        /* Since the graphic register REG is not invoked to any graphic
3497           planes, invoke it to graphic plane 0.  */           planes, invoke it to graphic plane 0.  */
# Line 2454  encode_invocation_designation (charset, Line 3506  encode_invocation_designation (charset,
3506            break;            break;
3507    
3508          case 2:                 /* graphic register 2 */          case 2:                 /* graphic register 2 */
3509            if (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)            if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
3510              ENCODE_SINGLE_SHIFT_2;              ENCODE_SINGLE_SHIFT_2;
3511            else            else
3512              ENCODE_LOCKING_SHIFT_2;              ENCODE_LOCKING_SHIFT_2;
3513            break;            break;
3514    
3515          case 3:                 /* graphic register 3 */          case 3:                 /* graphic register 3 */
3516            if (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)            if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
3517              ENCODE_SINGLE_SHIFT_3;              ENCODE_SINGLE_SHIFT_3;
3518            else            else
3519              ENCODE_LOCKING_SHIFT_3;              ENCODE_LOCKING_SHIFT_3;
# Line 2469  encode_invocation_designation (charset, Line 3521  encode_invocation_designation (charset,
3521          }          }
3522      }      }
3523    
3524      *p_nchars = produced_chars;
3525    return dst;    return dst;
3526  }  }
3527    
3528  /* Produce 2-byte codes for encoded composition rule RULE.  */  /* The following three macros produce codes for indicating direction
3529       of text.  */
3530  #define ENCODE_COMPOSITION_RULE(rule)           \  #define ENCODE_CONTROL_SEQUENCE_INTRODUCER                              \
   do {                                          \  
     int gref, nref;                             \  
     COMPOSITION_DECODE_RULE (rule, gref, nref); \  
     *dst++ = 32 + 81 + gref;                    \  
     *dst++ = 32 + nref;                         \  
   } while (0)  
   
 /* Produce codes for indicating the start of a composition sequence  
    (ESC 0, ESC 3, or ESC 4).  DATA points to an array of integers  
    which specify information about the composition.  See the comment  
    in coding.h for the format of DATA.  */  
   
 #define ENCODE_COMPOSITION_START(coding, data)                          \  
3531    do {                                                                  \    do {                                                                  \
3532      coding->composing = data[3];                                        \      if (CODING_ISO_FLAGS (coding) == CODING_ISO_FLAG_SEVEN_BITS)        \
3533      *dst++ = ISO_CODE_ESC;                                              \        EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, '[');                         \
     if (coding->composing == COMPOSITION_RELATIVE)                      \  
       *dst++ = '0';                                                     \  
3534      else                                                                \      else                                                                \
3535        {                                                                 \        EMIT_ONE_BYTE (ISO_CODE_CSI);                                     \
         *dst++ = (coding->composing == COMPOSITION_WITH_ALTCHARS        \  
                   ? '3' : '4');                                         \  
         coding->cmp_data_index = coding->cmp_data_start + 4;            \  
         coding->composition_rule_follows = 0;                           \  
       }                                                                 \  
3536    } while (0)    } while (0)
3537    
 /* Produce codes for indicating the end of the current composition.  */  
3538    
3539  #define ENCODE_COMPOSITION_END(coding, data)                    \  #define ENCODE_DIRECTION_R2L()                  \
3540    do {                                                          \    do {                                          \
3541      *dst++ = ISO_CODE_ESC;                                      \      ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst);   \
3542      *dst++ = '1';                                               \      EMIT_TWO_ASCII_BYTES ('2', ']');            \
     coding->cmp_data_start += data[0];                          \  
     coding->composing = COMPOSITION_NO;                         \  
     if (coding->cmp_data_start == coding->cmp_data->used        \  
         && coding->cmp_data->next)                              \  
       {                                                         \  
         coding->cmp_data = coding->cmp_data->next;              \  
         coding->cmp_data_start = 0;                             \  
       }                                                         \  
3543    } while (0)    } while (0)
3544    
 /* Produce composition start sequence ESC 0.  Here, this sequence  
    doesn't mean the start of a new composition but means that we have  
    just produced components (alternate chars and composition rules) of  
    the composition and the actual text follows in SRC.  */  
3545    
3546  #define ENCODE_COMPOSITION_FAKE_START(coding)   \  #define ENCODE_DIRECTION_L2R()                  \
3547    do {                                          \    do {                                          \
3548      *dst++ = ISO_CODE_ESC;                      \      ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst);   \
3549      *dst++ = '0';                               \      EMIT_TWO_ASCII_BYTES ('0', ']');            \
     coding->composing = COMPOSITION_RELATIVE;   \  
3550    } while (0)    } while (0)
3551    
 /* The following three macros produce codes for indicating direction  
    of text.  */  
 #define ENCODE_CONTROL_SEQUENCE_INTRODUCER              \  
   do {                                                  \  
     if (coding->flags == CODING_FLAG_ISO_SEVEN_BITS)    \  
       *dst++ = ISO_CODE_ESC, *dst++ = '[';              \  
     else                                                \  
       *dst++ = ISO_CODE_CSI;                            \  
   } while (0)  
   
 #define ENCODE_DIRECTION_R2L    \  
   ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst), *dst++ = '2', *dst++ = ']'  
   
 #define ENCODE_DIRECTION_L2R    \  
   ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst), *dst++ = '0', *dst++ = ']'  
3552    
3553  /* Produce codes for designation and invocation to reset the graphic  /* Produce codes for designation and invocation to reset the graphic
3554     planes and registers to initial state.  */     planes and registers to initial state.  */
3555  #define ENCODE_RESET_PLANE_AND_REGISTER                                     \  #define ENCODE_RESET_PLANE_AND_REGISTER()                               \
3556    do {                                                                      \    do {                                                                  \
3557      int reg;                                                                \      int reg;                                                            \
3558      if (CODING_SPEC_ISO_INVOCATION (coding, 0) != 0)                        \      struct charset *charset;                                            \
3559        ENCODE_SHIFT_IN;                                                      \                                                                          \
3560      for (reg = 0; reg < 4; reg++)                                           \      if (CODING_ISO_INVOCATION (coding, 0) != 0)                         \
3561        if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg) >= 0            \        ENCODE_SHIFT_IN;                                                  \
3562            && (CODING_SPEC_ISO_DESIGNATION (coding, reg)                     \      for (reg = 0; reg < 4; reg++)                                       \
3563                != CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg)))        \        if (CODING_ISO_INITIAL (coding, reg) >= 0                         \
3564          ENCODE_DESIGNATION                                                  \            && (CODING_ISO_DESIGNATION (coding, reg)                      \
3565            (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg), reg, coding); \                != CODING_ISO_INITIAL (coding, reg)))                     \
3566            {                                                               \
3567              charset = CHARSET_FROM_ID (CODING_ISO_INITIAL (coding, reg)); \
3568              ENCODE_DESIGNATION (charset, reg, coding);                    \
3569            }                                                               \
3570    } while (0)    } while (0)
3571    
3572    
3573  /* Produce designation sequences of charsets in the line started from  /* Produce designation sequences of charsets in the line started from
3574     SRC to a place pointed by DST, and return updated DST.     SRC to a place pointed by DST, and return updated DST.
3575    
# Line 2568  encode_invocation_designation (charset, Line 3577  encode_invocation_designation (charset,
3577     find all the necessary designations.  */     find all the necessary designations.  */
3578    
3579  static unsigned char *  static unsigned char *
3580  encode_designation_at_bol (coding, translation_table, src, src_end, dst)  encode_designation_at_bol (coding, charbuf, charbuf_end, dst)
3581       struct coding_system *coding;       struct coding_system *coding;
3582       Lisp_Object translation_table;       int *charbuf, *charbuf_end;
3583       unsigned char *src, *src_end, *dst;       unsigned char *dst;
3584  {  {
3585    int charset, c, found = 0, reg;    struct charset *charset;
3586    /* Table of charsets to be designated to each graphic register.  */    /* Table of charsets to be designated to each graphic register.  */
3587    int r[4];    int r[4];
3588      int c, found = 0, reg;
3589      int produced_chars = 0;
3590      int multibytep = coding->dst_multibyte;
3591      Lisp_Object attrs;
3592      Lisp_Object charset_list;
3593    
3594      attrs = CODING_ID_ATTRS (coding->id);
3595      charset_list = CODING_ATTR_CHARSET_LIST (attrs);
3596      if (EQ (charset_list, Qiso_2022))
3597        charset_list = Viso_2022_charset_list;
3598    
3599    for (reg = 0; reg < 4; reg++)    for (reg = 0; reg < 4; reg++)
3600      r[reg] = -1;      r[reg] = -1;
3601    
3602    while (found < 4)    while (found < 4)
3603      {      {
3604        ONE_MORE_CHAR (c);        int id;
3605    
3606          c = *charbuf++;
3607        if (c == '\n')        if (c == '\n')
3608          break;          break;
3609          charset = char_charset (c, charset_list, NULL);
3610        charset = CHAR_CHARSET (c);        id = CHARSET_ID (charset);
3611        reg = CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset);        reg = CODING_ISO_REQUEST (coding, id);
3612        if (reg != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION && r[reg] < 0)        if (reg >= 0 && r[reg] < 0)
3613          {          {
3614            found++;            found++;
3615            r[reg] = charset;            r[reg] = id;
3616          }          }
3617      }      }
3618    
  label_end_of_loop:  
3619    if (found)    if (found)
3620      {      {
3621        for (reg = 0; reg < 4; reg++)        for (reg = 0; reg < 4; reg++)
3622          if (r[reg] >= 0          if (r[reg] >= 0
3623              && CODING_SPEC_ISO_DESIGNATION (coding, reg) != r[reg])              && CODING_ISO_DESIGNATION (coding, reg) != r[reg])
3624            ENCODE_DESIGNATION (r[reg], reg, coding);            ENCODE_DESIGNATION (CHARSET_FROM_ID (r[reg]), reg, coding);
3625      }      }
3626    
3627    return dst;    return dst;
# Line 2609  encode_designation_at_bol (coding, trans Line 3629  encode_designation_at_bol (coding, trans
3629    
3630  /* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions".  */  /* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions".  */
3631    
3632  static void  static int
3633  encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)  encode_coding_iso_2022 (coding)
3634       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *source, *destination;  
      int src_bytes, dst_bytes;  
3635  {  {
3636    unsigned char *src = source;    int multibytep = coding->dst_multibyte;
3637    unsigned char *src_end = source + src_bytes;    int *charbuf = coding->charbuf;
3638    unsigned char *dst = destination;    int *charbuf_end = charbuf + coding->charbuf_used;
3639    unsigned char *dst_end = destination + dst_bytes;    unsigned char *dst = coding->destination + coding->produced;
3640    /* Since the maximum bytes produced by each loop is 20, we subtract 19    unsigned char *dst_end = coding->destination + coding->dst_bytes;
3641       from DST_END to assure overflow checking is necessary only at the    int safe_room = 16;
3642       head of loop.  */    int bol_designation
3643    unsigned char *adjusted_dst_end = dst_end - 19;      = (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATE_AT_BOL
3644    /* SRC_BASE remembers the start position in source in each loop.         && CODING_ISO_BOL (coding));
3645       The loop will be exited when there's not enough source text to    int produced_chars = 0;
3646       analyze multi-byte codes (within macro ONE_MORE_CHAR), or when    Lisp_Object attrs, eol_type, charset_list;
3647       there's not enough destination area to produce encoded codes    int ascii_compatible;
      (within macro EMIT_BYTES).  */  
   unsigned char *src_base;  
3648    int c;    int c;
3649    Lisp_Object translation_table;    int preferred_charset_id = -1;
   Lisp_Object safe_chars;  
3650    
3651    if (coding->flags & CODING_FLAG_ISO_SAFE)    CODING_GET_INFO (coding, attrs, eol_type, charset_list);
3652      coding->mode |= CODING_MODE_INHIBIT_UNENCODABLE_CHAR;    setup_iso_safe_charsets (attrs);
3653      /* Charset list may have been changed.  */
3654      charset_list = CODING_ATTR_CHARSET_LIST (attrs);              \
3655      coding->safe_charsets = (char *) SDATA (CODING_ATTR_SAFE_CHARSETS(attrs));
3656    
3657    safe_chars = coding_safe_chars (coding->symbol);    ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
   
   if (NILP (Venable_character_translation))  
     translation_table = Qnil;  
   else  
     {  
       translation_table = coding->translation_table_for_encode;  
       if (NILP (translation_table))  
         translation_table = Vstandard_translation_table_for_encode;  
     }  
3658    
3659    coding->consumed_char = 0;    while (charbuf < charbuf_end)
   coding->errors = 0;  
   while (1)  
3660      {      {
3661        src_base = src;        ASSURE_DESTINATION (safe_room);
3662    
3663        if (dst >= (dst_bytes ? adjusted_dst_end : (src - 19)))        if (bol_designation)
3664          {          {
3665            coding->result = CODING_FINISH_INSUFFICIENT_DST;            unsigned char *dst_prev = dst;
           break;  
         }  
3666    
       if (coding->flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL  
           && CODING_SPEC_ISO_BOL (coding))  
         {  
3667            /* We have to produce designation sequences if any now.  */            /* We have to produce designation sequences if any now.  */
3668            dst = encode_designation_at_bol (coding, translation_table,            dst = encode_designation_at_bol (coding, charbuf, charbuf_end, dst);
3669                                             src, src_end, dst);            bol_designation = 0;
3670            CODING_SPEC_ISO_BOL (coding) = 0;            /* We are sure that designation sequences are all ASCII bytes.  */
3671              produced_chars += dst - dst_prev;
3672          }          }
3673    
3674        /* Check composition start and end.  */        c = *charbuf++;
       if (coding->composing != COMPOSITION_DISABLED  
           && coding->cmp_data_start < coding->cmp_data->used)  
         {  
           struct composition_data *cmp_data = coding->cmp_data;  
           int *data = cmp_data->data + coding->cmp_data_start;  
           int this_pos = cmp_data->char_offset + coding->consumed_char;  
3675    
3676            if (coding->composing == COMPOSITION_RELATIVE)        if (c < 0)
3677              {          {
3678                if (this_pos == data[2])            /* Handle an annotation.  */
3679                  {            switch (*charbuf)
                   ENCODE_COMPOSITION_END (coding, data);  
                   cmp_data = coding->cmp_data;  
                   data = cmp_data->data + coding->cmp_data_start;  
                 }  
             }  
           else if (COMPOSING_P (coding))  
             {  
               /* COMPOSITION_WITH_ALTCHARS or COMPOSITION_WITH_RULE_ALTCHAR  */  
               if (coding->cmp_data_index == coding->cmp_data_start + data[0])  
                 /* We have consumed components of the composition.  
                    What follows in SRC is the composition's base  
                    text.  */  
                 ENCODE_COMPOSITION_FAKE_START (coding);  
               else  
                 {  
                   int c = cmp_data->data[coding->cmp_data_index++];  
                   if (coding->composition_rule_follows)  
                     {  
                       ENCODE_COMPOSITION_RULE (c);  
                       coding->composition_rule_follows = 0;  
                     }  
                   else  
                     {  
                       if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR  
                           && ! CODING_SAFE_CHAR_P (safe_chars, c))  
                         ENCODE_UNSAFE_CHARACTER (c);  
                       else  
                         ENCODE_ISO_CHARACTER (c);  
                       if (coding->composing == COMPOSITION_WITH_RULE_ALTCHARS)  
                         coding->composition_rule_follows = 1;  
                     }  
                   continue;  
                 }  
             }  
           if (!COMPOSING_P (coding))  
3680              {              {
3681                if (this_pos == data[1])              case CODING_ANNOTATE_COMPOSITION_MASK:
3682                  {                /* Not yet implemented.  */
3683                    ENCODE_COMPOSITION_START (coding, data);                break;
3684                    continue;              case CODING_ANNOTATE_CHARSET_MASK:
3685                  }                preferred_charset_id = charbuf[3];
3686                  if (preferred_charset_id >= 0
3687                      && NILP (Fmemq (make_number (preferred_charset_id),
3688                                      charset_list)))
3689                    preferred_charset_id = -1;
3690                  break;
3691                default:
3692                  abort ();
3693              }              }
3694              charbuf += -c - 1;
3695              continue;
3696          }          }
3697    
       ONE_MORE_CHAR (c);  
   
3698        /* Now encode the character C.  */        /* Now encode the character C.  */
3699        if (c < 0x20 || c == 0x7F)        if (c < 0x20 || c == 0x7F)
3700          {          {
3701            if (c == '\r')            if (c == '\n'
3702                  || (c == '\r' && EQ (eol_type, Qmac)))
3703              {              {
3704                if (! (coding->mode & CODING_MODE_SELECTIVE_DISPLAY))                if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_EOL)
3705                    ENCODE_RESET_PLANE_AND_REGISTER ();
3706                  if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_INIT_AT_BOL)
3707                  {                  {
3708                    if (coding->flags & CODING_FLAG_ISO_RESET_AT_CNTL)                    int i;
3709                      ENCODE_RESET_PLANE_AND_REGISTER;  
3710                    *dst++ = c;                    for (i = 0; i < 4; i++)
3711                    continue;                      CODING_ISO_DESIGNATION (coding, i)
3712                          = CODING_ISO_INITIAL (coding, i);
3713                  }                  }
3714                /* fall down to treat '\r' as '\n' ...  */                bol_designation
3715                c = '\n';                  = CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATE_AT_BOL;
             }  
           if (c == '\n')  
             {  
               if (coding->flags & CODING_FLAG_ISO_RESET_AT_EOL)  
                 ENCODE_RESET_PLANE_AND_REGISTER;  
               if (coding->flags & CODING_FLAG_ISO_INIT_AT_BOL)  
                 bcopy (coding->spec.iso2022.initial_designation,  
                        coding->spec.iso2022.current_designation,  
                        sizeof coding->spec.iso2022.initial_designation);  
               if (coding->eol_type == CODING_EOL_LF  
                   || coding->eol_type == CODING_EOL_UNDECIDED)  
                 *dst++ = ISO_CODE_LF;  
               else if (coding->eol_type == CODING_EOL_CRLF)  
                 *dst++ = ISO_CODE_CR, *dst++ = ISO_CODE_LF;  
               else  
                 *dst++ = ISO_CODE_CR;  
               CODING_SPEC_ISO_BOL (coding) = 1;  
3716              }              }
3717              else if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_CNTL)
3718                ENCODE_RESET_PLANE_AND_REGISTER ();
3719              EMIT_ONE_ASCII_BYTE (c);
3720            }
3721          else if (ASCII_CHAR_P (c))
3722            {
3723              if (ascii_compatible)
3724                EMIT_ONE_ASCII_BYTE (c);
3725            else            else
3726              {              {
3727                if (coding->flags & CODING_FLAG_ISO_RESET_AT_CNTL)                struct charset *charset = CHARSET_FROM_ID (charset_ascii);
3728                  ENCODE_RESET_PLANE_AND_REGISTER;                ENCODE_ISO_CHARACTER (charset, c);
               *dst++ = c;  
3729              }              }
3730          }          }
3731        else if (ASCII_BYTE_P (c))        else if (CHAR_BYTE8_P (c))
         ENCODE_ISO_CHARACTER (c);  
       else if (SINGLE_BYTE_CHAR_P (c))  
3732          {          {
3733            *dst++ = c;            c = CHAR_TO_BYTE8 (c);
3734            coding->errors++;            EMIT_ONE_BYTE (c);
3735          }          }
       else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR  
                && ! CODING_SAFE_CHAR_P (safe_chars, c))  
         ENCODE_UNSAFE_CHARACTER (c);  
3736        else        else
3737          ENCODE_ISO_CHARACTER (c);          {
3738              struct charset *charset;
3739    
3740        coding->consumed_char++;            if (preferred_charset_id >= 0)
3741                {
3742                  charset = CHARSET_FROM_ID (preferred_charset_id);
3743                  if (! CHAR_CHARSET_P (c, charset))
3744                    charset = char_charset (c, charset_list, NULL);
3745                }
3746              else
3747                charset = char_charset (c, charset_list, NULL);
3748              if (!charset)
3749                {
3750                  if (coding->mode & CODING_MODE_SAFE_ENCODING)
3751                    {
3752                      c = CODING_INHIBIT_CHARACTER_SUBSTITUTION;
3753                      charset = CHARSET_FROM_ID (charset_ascii);
3754                    }
3755                  else
3756                    {
3757                      c = coding->default_char;
3758                      charset = char_charset (c, charset_list, NULL);
3759                    }
3760                }
3761              ENCODE_ISO_CHARACTER (charset, c);
3762            }
3763      }      }
3764    
3765   label_end_of_loop:    if (coding->mode & CODING_MODE_LAST_BLOCK
3766    coding->consumed = src_base - source;        && CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_EOL)
3767    coding->produced = coding->produced_char = dst - destination;      {
3768          ASSURE_DESTINATION (safe_room);
3769          ENCODE_RESET_PLANE_AND_REGISTER ();
3770        }
3771      coding->result = CODING_RESULT_SUCCESS;
3772      CODING_ISO_BOL (coding) = bol_designation;
3773      coding->produced_char += produced_chars;
3774      coding->produced = dst - coding->destination;
3775      return 0;
3776  }  }
3777    
3778    
3779  /*** 4. SJIS and BIG5 handlers ***/  /*** 8,9. SJIS and BIG5 handlers ***/
3780    
3781  /* Although SJIS and BIG5 are not ISO coding systems, they are used  /* Although SJIS and BIG5 are not ISO's coding system, they are used
3782     quite widely.  So, for the moment, Emacs supports them in the bare     quite widely.  So, for the moment, Emacs supports them in the bare
3783     C code.  But, in the future, they may be supported only by CCL.  */     C code.  But, in the future, they may be supported only by CCL.  */
3784    
# Line 2798  encode_coding_iso2022 (coding, source, d Line 3787  encode_coding_iso2022 (coding, source, d
3787     as is.  A character of charset katakana-jisx0201 is encoded by     as is.  A character of charset katakana-jisx0201 is encoded by
3788     "position-code + 0x80".  A character of charset japanese-jisx0208     "position-code + 0x80".  A character of charset japanese-jisx0208
3789     is encoded in 2-byte but two position-codes are divided and shifted     is encoded in 2-byte but two position-codes are divided and shifted
3790     so that it fits in the range below.     so that it fit in the range below.
3791    
3792     --- CODE RANGE of SJIS ---     --- CODE RANGE of SJIS ---
3793     (character set)      (range)     (character set)      (range)
3794     ASCII                0x00 .. 0x7F     ASCII                0x00 .. 0x7F
3795     KATAKANA-JISX0201    0xA1 .. 0xDF     KATAKANA-JISX0201    0xA0 .. 0xDF
3796     JISX0208 (1st byte)  0x81 .. 0x9F and 0xE0 .. 0xEF     JISX0208 (1st byte)  0x81 .. 0x9F and 0xE0 .. 0xEF
3797              (2nd byte)  0x40 .. 0x7E and 0x80 .. 0xFC              (2nd byte)  0x40 .. 0x7E and 0x80 .. 0xFC
3798     -------------------------------     -------------------------------
# Line 2812  encode_coding_iso2022 (coding, source, d Line 3801  encode_coding_iso2022 (coding, source, d
3801    
3802  /* BIG5 is a coding system encoding two character sets: ASCII and  /* BIG5 is a coding system encoding two character sets: ASCII and
3803     Big5.  An ASCII character is encoded as is.  Big5 is a two-byte     Big5.  An ASCII character is encoded as is.  Big5 is a two-byte
3804     character set and is encoded in two bytes.     character set and is encoded in two-byte.
3805    
3806     --- CODE RANGE of BIG5 ---     --- CODE RANGE of BIG5 ---
3807     (character set)      (range)     (character set)      (range)
# Line 2821  encode_coding_iso2022 (coding, source, d Line 3810  encode_coding_iso2022 (coding, source, d
3810          (2nd byte)      0x40 .. 0x7E and 0xA1 .. 0xFE          (2nd byte)      0x40 .. 0x7E and 0xA1 .. 0xFE
3811     --------------------------     --------------------------
3812    
3813     Since the number of characters in Big5 is larger than maximum    */
    characters in Emacs' charset (96x96), it can't be handled as one  
    charset.  So, in Emacs, Big5 is divided into two: `charset-big5-1'  
    and `charset-big5-2'.  Both are DIMENSION2 and CHARS94.  The former  
    contains frequently used characters and the latter contains less  
    frequently used characters.  */  
   
 /* Macros to decode or encode a character of Big5 in BIG5.  B1 and B2  
    are the 1st and 2nd position-codes of Big5 in BIG5 coding system.  
    C1 and C2 are the 1st and 2nd position-codes of Emacs' internal  
    format.  CHARSET is `charset_big5_1' or `charset_big5_2'.  */  
   
 /* Number of Big5 characters which have the same code in 1st byte.  */  
 #define BIG5_SAME_ROW (0xFF - 0xA1 + 0x7F - 0x40)  
   
 #define DECODE_BIG5(b1, b2, charset, c1, c2)                            \  
   do {                                                                  \  
     unsigned int temp                                                   \  
       = (b1 - 0xA1) * BIG5_SAME_ROW + b2 - (b2 < 0x7F ? 0x40 : 0x62);   \  
     if (b1 < 0xC9)                                                      \  
       charset = charset_big5_1;                                         \  
     else                                                                \  
       {                                                                 \  
         charset = charset_big5_2;                                       \  
         temp -= (0xC9 - 0xA1) * BIG5_SAME_ROW;                          \  
       }                                                                 \  
     c1 = temp / (0xFF - 0xA1) + 0x21;                                   \  
     c2 = temp % (0xFF - 0xA1) + 0x21;                                   \  
   } while (0)  
   
 #define ENCODE_BIG5(charset, c1, c2, b1, b2)                            \  
   do {                                                                  \  
     unsigned int temp = (c1 - 0x21) * (0xFF - 0xA1) + (c2 - 0x21);      \  
     if (charset == charset_big5_2)                                      \  
       temp += BIG5_SAME_ROW * (0xC9 - 0xA1);                            \  
     b1 = temp / BIG5_SAME_ROW + 0xA1;                                   \  
     b2 = temp % BIG5_SAME_ROW;                                          \  
     b2 += b2 < 0x3F ? 0x40 : 0x62;                                      \  
   } while (0)  
3814    
3815  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
3816     Check if a text is encoded in SJIS.  If it is, return     Check if a text is encoded in SJIS.  If it is, return
3817     CODING_CATEGORY_MASK_SJIS, else return 0.  */     CATEGORY_MASK_SJIS, else return 0.  */
3818    
3819  static int  static int
3820  detect_coding_sjis (src, src_end, multibytep)  detect_coding_sjis (coding, detect_info)
3821       unsigned char *src, *src_end;       struct coding_system *coding;
3822       int multibytep;       struct coding_detection_info *detect_info;
3823  {  {
3824      const unsigned char *src = coding->source, *src_base = src;
3825      const unsigned char *src_end = coding->source + coding->src_bytes;
3826      int multibytep = coding->src_multibyte;
3827      int consumed_chars = 0;
3828      int found = 0;
3829    int c;    int c;
3830    /* Dummy for ONE_MORE_BYTE.  */    int incomplete;
3831    struct coding_system dummy_coding;  
3832    struct coding_system *coding = &dummy_coding;    detect_info->checked |= CATEGORY_MASK_SJIS;
3833      /* A coding system of this category is always ASCII compatible.  */
3834      src += coding->head_ascii;
3835    
3836    while (1)    while (1)
3837      {      {
3838        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);        incomplete = 0;
3839          ONE_MORE_BYTE (c);
3840          incomplete = 1;
3841        if (c < 0x80)        if (c < 0x80)
3842          continue;          continue;
3843        if (c == 0x80 || c == 0xA0 || c > 0xEF)        if ((c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xEF))
         return 0;  
       if (c <= 0x9F || c >= 0xE0)  
3844          {          {
3845            ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);            ONE_MORE_BYTE (c);
3846            if (c < 0x40 || c == 0x7F || c > 0xFC)            if (c < 0x40 || c == 0x7F || c > 0xFC)
3847              return 0;              break;
3848              found = CATEGORY_MASK_SJIS;
3849          }          }
3850          else if (c >= 0xA0 && c < 0xE0)
3851            found = CATEGORY_MASK_SJIS;
3852          else
3853            break;
3854        }
3855      detect_info->rejected |= CATEGORY_MASK_SJIS;
3856      return 0;
3857    
3858     no_more_source:
3859      if (incomplete && coding->mode & CODING_MODE_LAST_BLOCK)
3860        {
3861          detect_info->rejected |= CATEGORY_MASK_SJIS;
3862          return 0;
3863      }      }
3864   label_end_of_loop:    detect_info->found |= found;
3865    return CODING_CATEGORY_MASK_SJIS;    return 1;
3866  }  }
3867    
3868  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
3869     Check if a text is encoded in BIG5.  If it is, return     Check if a text is encoded in BIG5.  If it is, return
3870     CODING_CATEGORY_MASK_BIG5, else return 0.  */     CATEGORY_MASK_BIG5, else return 0.  */
3871    
3872  static int  static int
3873  detect_coding_big5 (src, src_end, multibytep)  detect_coding_big5 (coding, detect_info)
3874       unsigned char *src, *src_end;       struct coding_system *coding;
3875       int multibytep;       struct coding_detection_info *detect_info;
3876  {  {
3877      const unsigned char *src = coding->source, *src_base = src;
3878      const unsigned char *src_end = coding->source + coding->src_bytes;
3879      int multibytep = coding->src_multibyte;
3880      int consumed_chars = 0;
3881      int found = 0;
3882    int c;    int c;
3883    /* Dummy for ONE_MORE_BYTE.  */    int incomplete;
3884    struct coding_system dummy_coding;  
3885    struct coding_system *coding = &dummy_coding;    detect_info->checked |= CATEGORY_MASK_BIG5;
3886      /* A coding system of this category is always ASCII compatible.  */
3887      src += coding->head_ascii;
3888    
3889    while (1)    while (1)
3890      {      {
3891        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);        incomplete = 0;
3892          ONE_MORE_BYTE (c);
3893          incomplete = 1;
3894        if (c < 0x80)        if (c < 0x80)
3895          continue;          continue;
3896        if (c < 0xA1 || c > 0xFE)        if (c >= 0xA1)
3897          return 0;          {
3898        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);            ONE_MORE_BYTE (c);
3899        if (c < 0x40 || (c > 0x7F && c < 0xA1) || c > 0xFE)            if (c < 0x40 || (c >= 0x7F && c <= 0xA0))
3900          return 0;              return 0;
3901              found = CATEGORY_MASK_BIG5;
3902            }
3903          else
3904            break;
3905      }      }
3906   label_end_of_loop:    detect_info->rejected |= CATEGORY_MASK_BIG5;
3907    return CODING_CATEGORY_MASK_BIG5;    return 0;
 }  
3908    
3909  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".   no_more_source:
3910     Check if a text is encoded in UTF-8.  If it is, return    if (incomplete && coding->mode & CODING_MODE_LAST_BLOCK)
3911     CODING_CATEGORY_MASK_UTF_8, else return 0.  */      {
3912          detect_info->rejected |= CATEGORY_MASK_BIG5;
3913          return 0;
3914        }
3915      detect_info->found |= found;
3916      return 1;
3917    }
3918    
3919  #define UTF_8_1_OCTET_P(c)         ((c) < 0x80)  /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".
3920  #define UTF_8_EXTRA_OCTET_P(c)     (((c) & 0xC0) == 0x80)     If SJIS_P is 1, decode SJIS text, else decode BIG5 test.  */
 #define UTF_8_2_OCTET_LEADING_P(c) (((c) & 0xE0) == 0xC0)  
 #define UTF_8_3_OCTET_LEADING_P(c) (((c) & 0xF0) == 0xE0)  
 #define UTF_8_4_OCTET_LEADING_P(c) (((c) & 0xF8) == 0xF0)  
 #define UTF_8_5_OCTET_LEADING_P(c) (((c) & 0xFC) == 0xF8)  
 #define UTF_8_6_OCTET_LEADING_P(c) (((c) & 0xFE) == 0xFC)  
3921    
3922  static int  static void
3923  detect_coding_utf_8 (src, src_end, multibytep)  decode_coding_sjis (coding)
3924       unsigned char *src, *src_end;       struct coding_system *coding;
      int multibytep;  
3925  {  {
3926    unsigned char c;    const unsigned char *src = coding->source + coding->consumed;
3927    int seq_maybe_bytes;    const unsigned char *src_end = coding->source + coding->src_bytes;
3928    /* Dummy for ONE_MORE_BYTE.  */    const unsigned char *src_base;
3929    struct coding_system dummy_coding;    int *charbuf = coding->charbuf;
3930    struct coding_system *coding = &dummy_coding;    int *charbuf_end = charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
3931      int consumed_chars = 0, consumed_chars_base;
3932      int multibytep = coding->src_multibyte;
3933      struct charset *charset_roman, *charset_kanji, *charset_kana;
3934      Lisp_Object attrs, eol_type, charset_list, val;
3935      int char_offset = coding->produced_char;
3936      int last_offset = char_offset;
3937      int last_id = charset_ascii;
3938    
3939      CODING_GET_INFO (coding, attrs, eol_type, charset_list);
3940    
3941      val = charset_list;
3942      charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
3943      charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
3944      charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val)));
3945    
3946    while (1)    while (1)
3947      {      {
3948        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);        int c, c1;
       if (UTF_8_1_OCTET_P (c))  
         continue;  
       else if (UTF_8_2_OCTET_LEADING_P (c))  
         seq_maybe_bytes = 1;  
       else if (UTF_8_3_OCTET_LEADING_P (c))  
         seq_maybe_bytes = 2;  
       else if (UTF_8_4_OCTET_LEADING_P (c))  
         seq_maybe_bytes = 3;  
       else if (UTF_8_5_OCTET_LEADING_P (c))  
         seq_maybe_bytes = 4;  
       else if (UTF_8_6_OCTET_LEADING_P (c))  
         seq_maybe_bytes = 5;  
       else  
         return 0;  
   
       do  
         {  
           ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);  
           if (!UTF_8_EXTRA_OCTET_P (c))  
             return 0;  
           seq_maybe_bytes--;  
         }  
       while (seq_maybe_bytes > 0);  
     }  
   
  label_end_of_loop:  
   return CODING_CATEGORY_MASK_UTF_8;  
 }  
   
 /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".  
    Check if a text is encoded in UTF-16 Big Endian (endian == 1) or  
    Little Endian (otherwise).  If it is, return  
    CODING_CATEGORY_MASK_UTF_16_BE or CODING_CATEGORY_MASK_UTF_16_LE,  
    else return 0.  */  
3949    
3950  #define UTF_16_INVALID_P(val)   \        src_base = src;
3951    (((val) == 0xFFFE)            \        consumed_chars_base = consumed_chars;
    || ((val) == 0xFFFF))  
3952    
3953  #define UTF_16_HIGH_SURROGATE_P(val) \        if (charbuf >= charbuf_end)
3954    (((val) & 0xD800) == 0xD800)          break;
3955    
3956  #define UTF_16_LOW_SURROGATE_P(val) \        ONE_MORE_BYTE (c);
   (((val) & 0xDC00) == 0xDC00)  
3957    
3958  static int        if (c == '\r')
3959  detect_coding_utf_16 (src, src_end, multibytep)          {
3960       unsigned char *src, *src_end;            if (EQ (eol_type, Qdos))
3961       int multibytep;              {
3962  {                if (src == src_end)
3963    unsigned char c1, c2;                  {
3964    /* Dummy for ONE_MORE_BYTE_CHECK_MULTIBYTE.  */                    coding->result = CODING_RESULT_INSUFFICIENT_SRC;
3965    struct coding_system dummy_coding;                    goto no_more_source;
3966    struct coding_system *coding = &dummy_coding;                  }
3967                  if (*src == '\n')
3968                    ONE_MORE_BYTE (c);
3969                }
3970              else if (EQ (eol_type, Qmac))
3971                c = '\n';
3972            }
3973          else
3974            {
3975              struct charset *charset;
3976    
3977    ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep);            if (c < 0x80)
3978    ONE_MORE_BYTE_CHECK_MULTIBYTE (c2, multibytep);              charset = charset_roman;
3979              else
3980                {
3981                  if (c >= 0xF0)
3982                    goto invalid_code;
3983                  if (c < 0xA0 || c >= 0xE0)
3984                    {
3985                      /* SJIS -> JISX0208 */
3986                      ONE_MORE_BYTE (c1);
3987                      if (c1 < 0x40 || c1 == 0x7F || c1 > 0xFC)
3988                        goto invalid_code;
3989                      c = (c << 8) | c1;
3990                      SJIS_TO_JIS (c);
3991                      charset = charset_kanji;
3992                    }
3993                  else if (c > 0xA0)
3994                    {
3995                      /* SJIS -> JISX0201-Kana */
3996                      c &= 0x7F;
3997                      charset = charset_kana;
3998                    }
3999                  else
4000                    goto invalid_code;
4001                }
4002              if (charset->id != charset_ascii
4003                  && last_id != charset->id)
4004                {
4005                  if (last_id != charset_ascii)
4006                    ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
4007                  last_id = charset->id;
4008                  last_offset = char_offset;
4009                }
4010              CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c, c);
4011            }
4012          *charbuf++ = c;
4013          char_offset++;
4014          continue;
4015    
4016    if ((c1 == 0xFF) && (c2 == 0xFE))      invalid_code:
4017      return CODING_CATEGORY_MASK_UTF_16_LE;        src = src_base;
4018    else if ((c1 == 0xFE) && (c2 == 0xFF))        consumed_chars = consumed_chars_base;
4019      return CODING_CATEGORY_MASK_UTF_16_BE;        ONE_MORE_BYTE (c);
4020          *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
4021          char_offset++;
4022          coding->errors++;
4023        }
4024    
4025   label_end_of_loop:   no_more_source:
4026    return 0;    if (last_id != charset_ascii)
4027        ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
4028      coding->consumed_char += consumed_chars_base;
4029      coding->consumed = src_base - coding->source;
4030      coding->charbuf_used = charbuf - coding->charbuf;
4031  }  }
4032    
 /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  
    If SJIS_P is 1, decode SJIS text, else decode BIG5 test.  */  
   
4033  static void  static void
4034  decode_coding_sjis_big5 (coding, source, destination,  decode_coding_big5 (coding)
                          src_bytes, dst_bytes, sjis_p)  
4035       struct coding_system *coding;       struct coding_system *coding;
4036       unsigned char *source, *destination;  {
4037       int src_bytes, dst_bytes;    const unsigned char *src = coding->source + coding->consumed;
4038       int sjis_p;    const unsigned char *src_end = coding->source + coding->src_bytes;
4039  {    const unsigned char *src_base;
4040    unsigned char *src = source;    int *charbuf = coding->charbuf;
4041    unsigned char *src_end = source + src_bytes;    int *charbuf_end = charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
4042    unsigned char *dst = destination;    int consumed_chars = 0, consumed_chars_base;
4043    unsigned char *dst_end = destination + dst_bytes;    int multibytep = coding->src_multibyte;
4044    /* SRC_BASE remembers the start position in source in each loop.    struct charset *charset_roman, *charset_big5;
4045       The loop will be exited when there's not enough source code    Lisp_Object attrs, eol_type, charset_list, val;
4046       (within macro ONE_MORE_BYTE), or when there's not enough    int char_offset = coding->produced_char;
4047       destination area to produce a character (within macro    int last_offset = char_offset;
4048       EMIT_CHAR).  */    int last_id = charset_ascii;
4049    unsigned char *src_base;  
4050    Lisp_Object translation_table;    CODING_GET_INFO (coding, attrs, eol_type, charset_list);
4051      val = charset_list;
4052    if (NILP (Venable_character_translation))    charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
4053      translation_table = Qnil;    charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
   else  
     {  
       translation_table = coding->translation_table_for_decode;  
       if (NILP (translation_table))  
         translation_table = Vstandard_translation_table_for_decode;  
     }  
4054    
   coding->produced_char = 0;  
4055    while (1)    while (1)
4056      {      {
4057        int c, charset, c1, c2;        int c, c1;
4058    
4059        src_base = src;        src_base = src;
4060        ONE_MORE_BYTE (c1);        consumed_chars_base = consumed_chars;
4061    
4062          if (charbuf >= charbuf_end)
4063            break;
4064    
4065          ONE_MORE_BYTE (c);
4066    
4067        if (c1 < 0x80)        if (c == '\r')
4068          {          {
4069            charset = CHARSET_ASCII;            if (EQ (eol_type, Qdos))
           if (c1 < 0x20)  
4070              {              {
4071                if (c1 == '\r')                if (src == src_end)
                 {  
                   if (coding->eol_type == CODING_EOL_CRLF)  
                     {  
                       ONE_MORE_BYTE (c2);  
                       if (c2 == '\n')  
                         c1 = c2;  
                       else  
                         /* To process C2 again, SRC is subtracted by 1.  */  
                         src--;  
                     }  
                   else if (coding->eol_type == CODING_EOL_CR)  
                     c1 = '\n';  
                 }  
               else if (c1 == '\n'  
                        && (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)  
                        && (coding->eol_type == CODING_EOL_CR  
                            || coding->eol_type == CODING_EOL_CRLF))  
4072                  {                  {
4073                    coding->result = CODING_FINISH_INCONSISTENT_EOL;                    coding->result = CODING_RESULT_INSUFFICIENT_SRC;
4074                    goto label_end_of_loop;                    goto no_more_source;
4075                  }                  }
4076                  if (*src == '\n')
4077                    ONE_MORE_BYTE (c);
4078              }              }
4079              else if (EQ (eol_type, Qmac))
4080                c = '\n';
4081          }          }
4082        else        else
4083          {          {
4084            if (sjis_p)            struct charset *charset;
4085              {            if (c < 0x80)
4086                if (c1 == 0x80 || c1 == 0xA0 || c1 > 0xEF)              charset = charset_roman;
                 goto label_invalid_code;  
               if (c1 <= 0x9F || c1 >= 0xE0)  
                 {  
                   /* SJIS -> JISX0208 */  
                   ONE_MORE_BYTE (c2);  
                   if (c2 < 0x40 || c2 == 0x7F || c2 > 0xFC)  
                     goto label_invalid_code;  
                   DECODE_SJIS (c1, c2, c1, c2);  
                   charset = charset_jisx0208;  
                 }  
               else  
                 /* SJIS -> JISX0201-Kana */  
                 charset = charset_katakana_jisx0201;  
             }  
4087            else            else
4088              {              {
4089                /* BIG5 -> Big5 */                /* BIG5 -> Big5 */
4090                if (c1 < 0xA0 || c1 > 0xFE)                if (c < 0xA1 || c > 0xFE)
4091                  goto label_invalid_code;                  goto invalid_code;
4092                ONE_MORE_BYTE (c2);                ONE_MORE_BYTE (c1);
4093                if (c2 < 0x40 || (c2 > 0x7E && c2 < 0xA1) || c2 > 0xFE)                if (c1 < 0x40 || (c1 > 0x7E && c1 < 0xA1) || c1 > 0xFE)
4094                  goto label_invalid_code;                  goto invalid_code;
4095                DECODE_BIG5 (c1, c2, charset, c1, c2);                c = c << 8 | c1;
4096                  charset = charset_big5;
4097                }
4098              if (charset->id != charset_ascii
4099                  && last_id != charset->id)
4100                {
4101                  if (last_id != charset_ascii)
4102                    ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
4103                  last_id = charset->id;
4104                  last_offset = char_offset;
4105              }              }
4106              CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c, c);
4107          }          }
4108    
4109        c = DECODE_ISO_CHARACTER (charset, c1, c2);        *charbuf++ = c;
4110        EMIT_CHAR (c);        char_offset++;
4111        continue;        continue;
4112    
4113      label_invalid_code:      invalid_code:
       coding->errors++;  
4114        src = src_base;        src = src_base;
4115        c = *src++;        consumed_chars = consumed_chars_base;
4116        EMIT_CHAR (c);        ONE_MORE_BYTE (c);
4117          *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
4118          char_offset++;
4119          coding->errors++;
4120      }      }
4121    
4122   label_end_of_loop:   no_more_source:
4123    coding->consumed = coding->consumed_char = src_base - source;    if (last_id != charset_ascii)
4124    coding->produced = dst - destination;      ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
4125    return;    coding->consumed_char += consumed_chars_base;
4126      coding->consumed = src_base - coding->source;
4127      coding->charbuf_used = charbuf - coding->charbuf;
4128  }  }
4129    
4130  /* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions".  /* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions".
# Line 3140  decode_coding_sjis_big5 (coding, source, Line 4135  decode_coding_sjis_big5 (coding, source,
4135     charsets are produced without any encoding.  If SJIS_P is 1, encode     charsets are produced without any encoding.  If SJIS_P is 1, encode
4136     SJIS text, else encode BIG5 text.  */     SJIS text, else encode BIG5 text.  */
4137    
4138  static void  static int
4139  encode_coding_sjis_big5 (coding, source, destination,  encode_coding_sjis (coding)
                          src_bytes, dst_bytes, sjis_p)  
4140       struct coding_system *coding;       struct coding_system *coding;
4141       unsigned char *source, *destination;  {
4142       int src_bytes, dst_bytes;    int multibytep = coding->dst_multibyte;
4143       int sjis_p;    int *charbuf = coding->charbuf;
4144  {    int *charbuf_end = charbuf + coding->charbuf_used;
4145    unsigned char *src = source;    unsigned char *dst = coding->destination + coding->produced;
4146    unsigned char *src_end = source + src_bytes;    unsigned char *dst_end = coding->destination + coding->dst_bytes;
4147    unsigned char *dst = destination;    int safe_room = 4;
4148    unsigned char *dst_end = destination + dst_bytes;    int produced_chars = 0;
4149    /* SRC_BASE remembers the start position in source in each loop.    Lisp_Object attrs, eol_type, charset_list, val;
4150       The loop will be exited when there's not enough source text to    int ascii_compatible;
4151       analyze multi-byte codes (within macro ONE_MORE_CHAR), or when    struct charset *charset_roman, *charset_kanji, *charset_kana;
4152       there's not enough destination area to produce encoded codes    int c;
      (within macro EMIT_BYTES).  */  
   unsigned char *src_base;  
   Lisp_Object translation_table;  
4153    
4154    if (NILP (Venable_character_translation))    CODING_GET_INFO (coding, attrs, eol_type, charset_list);
4155      translation_table = Qnil;    val = charset_list;
4156    else    charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
4157      {    charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
4158        translation_table = coding->translation_table_for_encode;    charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val)));
       if (NILP (translation_table))  
         translation_table = Vstandard_translation_table_for_encode;  
     }  
4159    
4160    while (1)    ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
     {  
       int c, charset, c1, c2;  
   
       src_base = src;  
       ONE_MORE_CHAR (c);  
4161    
4162      while (charbuf < charbuf_end)
4163        {
4164          ASSURE_DESTINATION (safe_room);
4165          c = *charbuf++;
4166        /* Now encode the character C.  */        /* Now encode the character C.  */
4167        if (SINGLE_BYTE_CHAR_P (c))        if (ASCII_CHAR_P (c) && ascii_compatible)
4168            EMIT_ONE_ASCII_BYTE (c);
4169          else if (CHAR_BYTE8_P (c))
4170          {          {
4171            switch (c)            c = CHAR_TO_BYTE8 (c);
4172              EMIT_ONE_BYTE (c);
4173            }
4174          else
4175            {
4176              unsigned code;
4177              struct charset *charset = char_charset (c, charset_list, &code);
4178    
4179              if (!charset)
4180              {              {
4181              case '\r':                if (coding->mode & CODING_MODE_SAFE_ENCODING)
               if (!(coding->mode & CODING_MODE_SELECTIVE_DISPLAY))  
4182                  {                  {
4183                    EMIT_ONE_BYTE (c);                    code = CODING_INHIBIT_CHARACTER_SUBSTITUTION;
4184                    break;                    charset = CHARSET_FROM_ID (charset_ascii);
4185                  }                  }
4186                c = '\n';                else
             case '\n':  
               if (coding->eol_type == CODING_EOL_CRLF)  
4187                  {                  {
4188                    EMIT_TWO_BYTES ('\r', c);                    c = coding->default_char;
4189                    break;                    charset = char_charset (c, charset_list, &code);
4190                  }                  }
               else if (coding->eol_type == CODING_EOL_CR)  
                 c = '\r';  
             default:  
               EMIT_ONE_BYTE (c);  
4191              }              }
4192              if (code == CHARSET_INVALID_CODE (charset))
4193                abort ();
4194              if (charset == charset_kanji)
4195                {
4196                  int c1, c2;
4197                  JIS_TO_SJIS (code);
4198                  c1 = code >> 8, c2 = code & 0xFF;
4199                  EMIT_TWO_BYTES (c1, c2);
4200                }
4201              else if (charset == charset_kana)
4202                EMIT_ONE_BYTE (code | 0x80);
4203              else
4204                EMIT_ONE_ASCII_BYTE (code & 0x7F);
4205            }
4206        }
4207      coding->result = CODING_RESULT_SUCCESS;
4208      coding->produced_char += produced_chars;
4209      coding->produced = dst - coding->destination;
4210      return 0;
4211    }
4212    
4213    static int
4214    encode_coding_big5 (coding)
4215         struct coding_system *coding;
4216    {
4217      int multibytep = coding->dst_multibyte;
4218      int *charbuf = coding->charbuf;
4219      int *charbuf_end = charbuf + coding->charbuf_used;
4220      unsigned char *dst = coding->destination + coding->produced;
4221      unsigned char *dst_end = coding->destination + coding->dst_bytes;
4222      int safe_room = 4;
4223      int produced_chars = 0;
4224      Lisp_Object attrs, eol_type, charset_list, val;
4225      int ascii_compatible;
4226      struct charset *charset_roman, *charset_big5;
4227      int c;
4228    
4229      CODING_GET_INFO (coding, attrs, eol_type, charset_list);
4230      val = charset_list;
4231      charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
4232      charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
4233      ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
4234    
4235      while (charbuf < charbuf_end)
4236        {
4237          ASSURE_DESTINATION (safe_room);
4238          c = *charbuf++;
4239          /* Now encode the character C.  */
4240          if (ASCII_CHAR_P (c) && ascii_compatible)
4241            EMIT_ONE_ASCII_BYTE (c);
4242          else if (CHAR_BYTE8_P (c))
4243            {
4244              c = CHAR_TO_BYTE8 (c);
4245              EMIT_ONE_BYTE (c);
4246          }          }
4247        else        else
4248          {          {
4249            SPLIT_CHAR (c, charset, c1, c2);            unsigned code;
4250            if (sjis_p)            struct charset *charset = char_charset (c, charset_list, &code);
4251    
4252              if (! charset)
4253              {              {
4254                if (charset == charset_jisx0208                if (coding->mode & CODING_MODE_SAFE_ENCODING)
                   || charset == charset_jisx0208_1978)  
4255                  {                  {
4256                    ENCODE_SJIS (c1, c2, c1, c2);                    code = CODING_INHIBIT_CHARACTER_SUBSTITUTION;
4257                    EMIT_TWO_BYTES (c1, c2);                    charset = CHARSET_FROM_ID (charset_ascii);
                 }  
               else if (charset == charset_katakana_jisx0201)  
                 EMIT_ONE_BYTE (c1 | 0x80);  
               else if (charset == charset_latin_jisx0201)  
                 EMIT_ONE_BYTE (c1);  
               else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR)  
                 {  
                   EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);  
                   if (CHARSET_WIDTH (charset) > 1)  
                     EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);  
4258                  }                  }
4259                else                else
                 /* There's no way other than producing the internal  
                    codes as is.  */  
                 EMIT_BYTES (src_base, src);  
             }  
           else  
             {  
               if (charset == charset_big5_1 || charset == charset_big5_2)  
                 {  
                   ENCODE_BIG5 (charset, c1, c2, c1, c2);  
                   EMIT_TWO_BYTES (c1, c2);  
                 }  
               else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR)  
4260                  {                  {
4261                    EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);                    c = coding->default_char;
4262                    if (CHARSET_WIDTH (charset) > 1)                    charset = char_charset (c, charset_list, &code);
                     EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);  
4263                  }                  }
               else  
                 /* There's no way other than producing the internal  
                    codes as is.  */  
                 EMIT_BYTES (src_base, src);  
4264              }              }
4265              if (code == CHARSET_INVALID_CODE (charset))
4266                abort ();
4267              if (charset == charset_big5)
4268                {
4269                  int c1, c2;
4270    
4271                  c1 = code >> 8, c2 = code & 0xFF;
4272                  EMIT_TWO_BYTES (c1, c2);
4273                }
4274              else
4275                EMIT_ONE_ASCII_BYTE (code & 0x7F);
4276          }          }
       coding->consumed_char++;  
4277      }      }
4278      coding->result = CODING_RESULT_SUCCESS;
4279   label_end_of_loop:    coding->produced_char += produced_chars;
4280    coding->consumed = src_base - source;    coding->produced = dst - coding->destination;
4281    coding->produced = coding->produced_char = dst - destination;    return 0;
4282  }  }
4283    
4284    
4285  /*** 5. CCL handlers ***/  /*** 10. CCL handlers ***/
4286    
4287  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
4288     Check if a text is encoded in a coding system of which     Check if a text is encoded in a coding system of which
4289     encoder/decoder are written in CCL program.  If it is, return     encoder/decoder are written in CCL program.  If it is, return
4290     CODING_CATEGORY_MASK_CCL, else return 0.  */     CATEGORY_MASK_CCL, else return 0.  */
4291    
4292  static int  static int
4293  detect_coding_ccl (src, src_end, multibytep)  detect_coding_ccl (coding, detect_info)
4294       unsigned char *src, *src_end;       struct coding_system *coding;
4295       int multibytep;       struct coding_detection_info *detect_info;
4296  {  {
4297    unsigned char *valid;    const unsigned char *src = coding->source, *src_base = src;
4298    int c;    const unsigned char *src_end = coding->source + coding->src_bytes;
4299    /* Dummy for ONE_MORE_BYTE.  */    int multibytep = coding->src_multibyte;
4300    struct coding_system dummy_coding;    int consumed_chars = 0;
4301    struct coding_system *coding = &dummy_coding;    int found = 0;
4302      unsigned char *valids = CODING_CCL_VALIDS (coding);
4303    /* No coding system is assigned to coding-category-ccl.  */    int head_ascii = coding->head_ascii;
4304    if (!coding_system_table[CODING_CATEGORY_IDX_CCL])    Lisp_Object attrs;
4305      return 0;  
4306      detect_info->checked |= CATEGORY_MASK_CCL;
4307    
4308      coding = &coding_categories[coding_category_ccl];
4309      attrs = CODING_ID_ATTRS (coding->id);
4310      if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
4311        src += head_ascii;
4312    
   valid = coding_system_table[CODING_CATEGORY_IDX_CCL]->spec.ccl.valid_codes;  
4313    while (1)    while (1)
4314      {      {
4315        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep);        int c;
4316        if (! valid[c])        ONE_MORE_BYTE (c);
4317          return 0;        if (! valids[c])
4318            break;
4319          if ((valids[c] > 1))
4320            found = CATEGORY_MASK_CCL;
4321        }
4322      detect_info->rejected |= CATEGORY_MASK_CCL;
4323      return 0;
4324    
4325     no_more_source:
4326      detect_info->found |= found;
4327      return 1;
4328    }
4329    
4330    static void
4331    decode_coding_ccl (coding)
4332         struct coding_system *coding;
4333    {
4334      const unsigned char *src = coding->source + coding->consumed;
4335      const unsigned char *src_end = coding->source + coding->src_bytes;
4336      int *charbuf = coding->charbuf;
4337      int *charbuf_end = charbuf + coding->charbuf_size;
4338      int consumed_chars = 0;
4339      int multibytep = coding->src_multibyte;
4340      struct ccl_program ccl;
4341      int source_charbuf[1024];
4342      int source_byteidx[1024];
4343      Lisp_Object attrs, eol_type, charset_list;
4344    
4345      CODING_GET_INFO (coding, attrs, eol_type, charset_list);
4346      setup_ccl_program (&ccl, CODING_CCL_DECODER (coding));
4347    
4348      while (src < src_end)
4349        {
4350          const unsigned char *p = src;
4351          int *source, *source_end;
4352          int i = 0;
4353    
4354          if (multibytep)
4355            while (i < 1024 && p < src_end)
4356              {
4357                source_byteidx[i] = p - src;
4358                source_charbuf[i++] = STRING_CHAR_ADVANCE (p);
4359              }
4360          else
4361            while (i < 1024 && p < src_end)
4362              source_charbuf[i++] = *p++;
4363    
4364          if (p == src_end && coding->mode & CODING_MODE_LAST_BLOCK)
4365            ccl.last_block = 1;
4366    
4367          source = source_charbuf;
4368          source_end = source + i;
4369          while (source < source_end)
4370            {
4371              ccl_driver (&ccl, source, charbuf,
4372                          source_end - source, charbuf_end - charbuf,
4373                          charset_list);
4374              source += ccl.consumed;
4375              charbuf += ccl.produced;
4376              if (ccl.status != CCL_STAT_SUSPEND_BY_DST)
4377                break;
4378            }
4379          if (source < source_end)
4380            src += source_byteidx[source - source_charbuf];
4381          else
4382            src = p;
4383          consumed_chars += source - source_charbuf;
4384    
4385          if (ccl.status != CCL_STAT_SUSPEND_BY_SRC
4386              && ccl.status != CODING_RESULT_INSUFFICIENT_SRC)
4387            break;
4388        }
4389    
4390      switch (ccl.status)
4391        {
4392        case CCL_STAT_SUSPEND_BY_SRC:
4393          coding->result = CODING_RESULT_INSUFFICIENT_SRC;
4394          break;
4395        case CCL_STAT_SUSPEND_BY_DST:
4396          break;
4397        case CCL_STAT_QUIT:
4398        case CCL_STAT_INVALID_CMD:
4399          coding->result = CODING_RESULT_INTERRUPT;
4400          break;
4401        default:
4402          coding->result = CODING_RESULT_SUCCESS;
4403          break;
4404      }      }
4405   label_end_of_loop:    coding->consumed_char += consumed_chars;
4406    return CODING_CATEGORY_MASK_CCL;    coding->consumed = src - coding->source;
4407      coding->charbuf_used = charbuf - coding->charbuf;
4408  }  }
4409    
4410    static int
4411    encode_coding_ccl (coding)
4412         struct coding_system *coding;
4413    {
4414      struct ccl_program ccl;
4415      int multibytep = coding->dst_multibyte;
4416      int *charbuf = coding->charbuf;
4417      int *charbuf_end = charbuf + coding->charbuf_used;
4418      unsigned char *dst = coding->destination + coding->produced;
4419      unsigned char *dst_end = coding->destination + coding->dst_bytes;
4420      unsigned char *adjusted_dst_end = dst_end - 1;
4421      int destination_charbuf[1024];
4422      int i, produced_chars = 0;
4423      Lisp_Object attrs, eol_type, charset_list;
4424    
4425      CODING_GET_INFO (coding, attrs, eol_type, charset_list);
4426      setup_ccl_program (&ccl, CODING_CCL_ENCODER (coding));
4427    
4428      ccl.last_block = coding->mode & CODING_MODE_LAST_BLOCK;
4429      ccl.dst_multibyte = coding->dst_multibyte;
4430    
4431      while (charbuf < charbuf_end && dst < adjusted_dst_end)
4432        {
4433          int dst_bytes = dst_end - dst;
4434          if (dst_bytes > 1024)
4435            dst_bytes = 1024;
4436    
4437          ccl_driver (&ccl, charbuf, destination_charbuf,
4438                      charbuf_end - charbuf, dst_bytes, charset_list);
4439          charbuf += ccl.consumed;
4440          if (multibytep)
4441            for (i = 0; i < ccl.produced; i++)
4442              EMIT_ONE_BYTE (destination_charbuf[i] & 0xFF);
4443          else
4444            {
4445              for (i = 0; i < ccl.produced; i++)    
4446                *dst++ = destination_charbuf[i] & 0xFF;
4447              produced_chars += ccl.produced;
4448            }
4449        }
4450    
4451      switch (ccl.status)
4452        {
4453        case CCL_STAT_SUSPEND_BY_SRC:
4454          coding->result = CODING_RESULT_INSUFFICIENT_SRC;
4455          break;
4456        case CCL_STAT_SUSPEND_BY_DST:
4457          coding->result = CODING_RESULT_INSUFFICIENT_DST;
4458          break;
4459        case CCL_STAT_QUIT:
4460        case CCL_STAT_INVALID_CMD:
4461          coding->result = CODING_RESULT_INTERRUPT;
4462          break;
4463        default:
4464          coding->result = CODING_RESULT_SUCCESS;
4465          break;
4466        }
4467    
4468      coding->produced_char += produced_chars;
4469      coding->produced = dst - coding->destination;
4470      return 0;
4471    }
4472    
4473    
4474    
4475  /*** 6. End-of-line handlers ***/  /*** 10, 11. no-conversion handlers ***/
4476    
4477  /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */  /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */
4478    
4479  static void  static void
4480  decode_eol (coding, source, destination, src_bytes, dst_bytes)  decode_coding_raw_text (coding)
4481       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *source, *destination;  
      int src_bytes, dst_bytes;  
4482  {  {
4483    unsigned char *src = source;    coding->chars_at_source = 1;
4484    unsigned char *dst = destination;    coding->consumed_char = 0;
4485    unsigned char *src_end = src + src_bytes;    coding->consumed = 0;
4486    unsigned char *dst_end = dst + dst_bytes;    coding->result = CODING_RESULT_SUCCESS;
4487    Lisp_Object translation_table;  }
4488    /* SRC_BASE remembers the start position in source in each loop.  
4489       The loop will be exited when there's not enough source code  static int
4490       (within macro ONE_MORE_BYTE), or when there's not enough  encode_coding_raw_text (coding)
4491       destination area to produce a character (within macro       struct coding_system *coding;
4492       EMIT_CHAR).  */  {
4493    unsigned char *src_base;    int multibytep = coding->dst_multibyte;
4494      int *charbuf = coding->charbuf;
4495      int *charbuf_end = coding->charbuf + coding->charbuf_used;
4496      unsigned char *dst = coding->destination + coding->produced;
4497      unsigned char *dst_end = coding->destination + coding->dst_bytes;
4498      int produced_chars = 0;
4499    int c;    int c;
4500    
4501    translation_table = Qnil;    if (multibytep)
4502    switch (coding->eol_type)      {
4503          int safe_room = MAX_MULTIBYTE_LENGTH * 2;
4504    
4505          if (coding->src_multibyte)
4506            while (charbuf < charbuf_end)
4507              {
4508                ASSURE_DESTINATION (safe_room);
4509                c = *charbuf++;
4510                if (ASCII_CHAR_P (c))
4511                  EMIT_ONE_ASCII_BYTE (c);
4512                else if (CHAR_BYTE8_P (c))
4513                  {
4514                    c = CHAR_TO_BYTE8 (c);
4515                    EMIT_ONE_BYTE (c);
4516                  }
4517                else
4518                  {
4519                    unsigned char str[MAX_MULTIBYTE_LENGTH], *p0 = str, *p1 = str;
4520    
4521                    CHAR_STRING_ADVANCE (c, p1);
4522                    while (p0 < p1)
4523                      {
4524                        EMIT_ONE_BYTE (*p0);
4525                        p0++;
4526                      }
4527                  }
4528              }
4529          else
4530            while (charbuf < charbuf_end)
4531              {
4532                ASSURE_DESTINATION (safe_room);
4533                c = *charbuf++;
4534                EMIT_ONE_BYTE (c);
4535              }
4536        }
4537      else
4538      {      {
4539      case CODING_EOL_CRLF:        if (coding->src_multibyte)
       while (1)  
4540          {          {
4541            src_base = src;            int safe_room = MAX_MULTIBYTE_LENGTH;
4542            ONE_MORE_BYTE (c);  
4543            if (c == '\r')            while (charbuf < charbuf_end)
             {  
               ONE_MORE_BYTE (c);  
               if (c != '\n')  
                 {  
                   src--;  
                   c = '\r';  
                 }  
             }  
           else if (c == '\n'  
                    && (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL))  
4544              {              {
4545                coding->result = CODING_FINISH_INCONSISTENT_EOL;                ASSURE_DESTINATION (safe_room);
4546                goto label_end_of_loop;                c = *charbuf++;
4547                  if (ASCII_CHAR_P (c))
4548                    *dst++ = c;
4549                  else if (CHAR_BYTE8_P (c))
4550                    *dst++ = CHAR_TO_BYTE8 (c);
4551                  else
4552                    CHAR_STRING_ADVANCE (c, dst);
4553                  produced_chars++;
4554              }              }
           EMIT_CHAR (c);  
4555          }          }
4556        break;        else
4557            {
4558              ASSURE_DESTINATION (charbuf_end - charbuf);
4559              while (charbuf < charbuf_end && dst < dst_end)
4560                *dst++ = *charbuf++;
4561              produced_chars = dst - (coding->destination + coding->dst_bytes);
4562            }
4563        }
4564      coding->result = CODING_RESULT_SUCCESS;
4565      coding->produced_char += produced_chars;
4566      coding->produced = dst - coding->destination;
4567      return 0;
4568    }
4569    
4570    /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
4571       Check if a text is encoded in a charset-based coding system.  If it
4572       is, return 1, else return 0.  */
4573    
4574    static int
4575    detect_coding_charset (coding, detect_info)
4576         struct coding_system *coding;
4577         struct coding_detection_info *detect_info;
4578    {
4579      const unsigned char *src = coding->source, *src_base = src;
4580      const unsigned char *src_end = coding->source + coding->src_bytes;
4581      int multibytep = coding->src_multibyte;
4582      int consumed_chars = 0;
4583      Lisp_Object attrs, valids;
4584      int found = 0;
4585    
4586      detect_info->checked |= CATEGORY_MASK_CHARSET;
4587    
4588      coding = &coding_categories[coding_category_charset];
4589      attrs = CODING_ID_ATTRS (coding->id);
4590      valids = AREF (attrs, coding_attr_charset_valids);
4591    
4592      if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
4593        src += coding->head_ascii;
4594    
4595      while (1)
4596        {
4597          int c;
4598    
4599      case CODING_EOL_CR:        ONE_MORE_BYTE (c);
4600        while (1)        if (NILP (AREF (valids, c)))
4601            break;
4602          if (c >= 0x80)
4603            found = CATEGORY_MASK_CHARSET;
4604        }
4605      detect_info->rejected |= CATEGORY_MASK_CHARSET;
4606      return 0;
4607    
4608     no_more_source:
4609      detect_info->found |= found;
4610      return 1;
4611    }
4612    
4613    static void
4614    decode_coding_charset (coding)
4615         struct coding_system *coding;
4616    {
4617      const unsigned char *src = coding->source + coding->consumed;
4618      const unsigned char *src_end = coding->source + coding->src_bytes;
4619      const unsigned char *src_base;
4620      int *charbuf = coding->charbuf;
4621      int *charbuf_end = charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
4622      int consumed_chars = 0, consumed_chars_base;
4623      int multibytep = coding->src_multibyte;
4624      Lisp_Object attrs, eol_type, charset_list, valids;
4625      int char_offset = coding->produced_char;
4626      int last_offset = char_offset;
4627      int last_id = charset_ascii;
4628    
4629      CODING_GET_INFO (coding, attrs, eol_type, charset_list);
4630      valids = AREF (attrs, coding_attr_charset_valids);
4631    
4632      while (1)
4633        {
4634          int c;
4635    
4636          src_base = src;
4637          consumed_chars_base = consumed_chars;
4638    
4639          if (charbuf >= charbuf_end)
4640            break;
4641    
4642          ONE_MORE_BYTE (c);
4643          if (c == '\r')
4644          {          {
4645            src_base = src;            /* Here we assume that no charset maps '\r' to something
4646            ONE_MORE_BYTE (c);               else.  */
4647            if (c == '\n')            if (EQ (eol_type, Qdos))
4648              {              {
4649                if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)                if (src == src_end)
4650                  {                  {
4651                    coding->result = CODING_FINISH_INCONSISTENT_EOL;                    coding->result = CODING_RESULT_INSUFFICIENT_SRC;
4652                    goto label_end_of_loop;                    goto no_more_source;
4653                  }                  }
4654                  if (*src == '\n')
4655                    ONE_MORE_BYTE (c);
4656              }              }
4657            else if (c == '\r')            else if (EQ (eol_type, Qmac))
4658              c = '\n';              c = '\n';
           EMIT_CHAR (c);  
4659          }          }
4660        break;        else
   
     default:                    /* no need for EOL handling */  
       while (1)  
4661          {          {
4662            src_base = src;            Lisp_Object val;
4663            ONE_MORE_BYTE (c);            struct charset *charset;
4664            EMIT_CHAR (c);            int dim;
4665              int len = 1;
4666              unsigned code = c;
4667    
4668              val = AREF (valids, c);
4669              if (NILP (val))
4670                goto invalid_code;
4671              if (INTEGERP (val))
4672                {
4673                  charset = CHARSET_FROM_ID (XFASTINT (val));
4674                  dim = CHARSET_DIMENSION (charset);
4675                  while (len < dim)
4676                    {
4677                      ONE_MORE_BYTE (c);
4678                      code = (code << 8) | c;
4679                      len++;
4680                    }
4681                  CODING_DECODE_CHAR (coding, src, src_base, src_end,
4682                                      charset, code, c);
4683                }
4684              else
4685                {
4686                  /* VAL is a list of charset IDs.  It is assured that the
4687                     list is sorted by charset dimensions (smaller one
4688                     comes first).  */
4689                  while (CONSP (val))
4690                    {
4691                      charset = CHARSET_FROM_ID (XFASTINT (XCAR (val)));
4692                      dim = CHARSET_DIMENSION (charset);
4693                      while (len < dim)
4694                        {
4695                          ONE_MORE_BYTE (c);
4696                          code = (code << 8) | c;
4697                          len++;
4698                        }
4699                      CODING_DECODE_CHAR (coding, src, src_base,
4700                                          src_end, charset, code, c);
4701                      if (c >= 0)
4702                        break;
4703                      val = XCDR (val);
4704                    }
4705                }
4706              if (c < 0)
4707                goto invalid_code;
4708              if (charset->id != charset_ascii
4709                  && last_id != charset->id)
4710                {
4711                  if (last_id != charset_ascii)
4712                    ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
4713                  last_id = charset->id;
4714                  last_offset = char_offset;
4715                }
4716          }          }
4717          *charbuf++ = c;
4718          char_offset++;
4719          continue;
4720    
4721        invalid_code:
4722          src = src_base;
4723          consumed_chars = consumed_chars_base;
4724          ONE_MORE_BYTE (c);
4725          *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
4726          char_offset++;
4727          coding->errors++;
4728      }      }
4729    
4730   label_end_of_loop:   no_more_source:
4731    coding->consumed = coding->consumed_char = src_base - source;    if (last_id != charset_ascii)
4732    coding->produced = dst - destination;      ADD_CHARSET_DATA (charbuf, last_offset, char_offset, last_id);
4733    return;    coding->consumed_char += consumed_chars_base;
4734      coding->consumed = src_base - coding->source;
4735      coding->charbuf_used = charbuf - coding->charbuf;
4736  }  }
4737    
4738  /* See "GENERAL NOTES about `encode_coding_XXX ()' functions".  Encode  static int
4739     format of end-of-line according to `coding->eol_type'.  It also  encode_coding_charset (coding)
    convert multibyte form 8-bit characters to unibyte if  
    CODING->src_multibyte is nonzero.  If `coding->mode &  
    CODING_MODE_SELECTIVE_DISPLAY' is nonzero, code '\r' in source text  
    also means end-of-line.  */  
   
 static void  
 encode_eol (coding, source, destination, src_bytes, dst_bytes)  
4740       struct coding_system *coding;       struct coding_system *coding;
      const unsigned char *source;  
      unsigned char *destination;  
      int src_bytes, dst_bytes;  
4741  {  {
4742    const unsigned char *src = source;    int multibytep = coding->dst_multibyte;
4743    unsigned char *dst = destination;    int *charbuf = coding->charbuf;
4744    const unsigned char *src_end = src + src_bytes;    int *charbuf_end = charbuf + coding->charbuf_used;
4745    unsigned char *dst_end = dst + dst_bytes;    unsigned char *dst = coding->destination + coding->produced;
4746    Lisp_Object translation_table;    unsigned char *dst_end = coding->destination + coding->dst_bytes;
4747    /* SRC_BASE remembers the start position in source in each loop.    int safe_room = MAX_MULTIBYTE_LENGTH;
4748       The loop will be exited when there's not enough source text to    int produced_chars = 0;
4749       analyze multi-byte codes (within macro ONE_MORE_CHAR), or when    Lisp_Object attrs, eol_type, charset_list;
4750       there's not enough destination area to produce encoded codes    int ascii_compatible;
      (within macro EMIT_BYTES).  */  
   const unsigned char *src_base;  
   unsigned char *tmp;  
4751    int c;    int c;
   int selective_display = coding->mode & CODING_MODE_SELECTIVE_DISPLAY;  
4752    
4753    translation_table = Qnil;    CODING_GET_INFO (coding, attrs, eol_type, charset_list);
4754    if (coding->src_multibyte    ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
       && *(src_end - 1) == LEADING_CODE_8_BIT_CONTROL)  
     {  
       src_end--;  
       src_bytes--;  
       coding->result = CODING_FINISH_INSUFFICIENT_SRC;  
     }  
4755    
4756    if (coding->eol_type == CODING_EOL_CRLF)    while (charbuf < charbuf_end)
     {  
       while (src < src_end)  
         {  
           src_base = src;  
           c = *src++;  
           if (c >= 0x20)  
             EMIT_ONE_BYTE (c);  
           else if (c == '\n' || (c == '\r' && selective_display))  
             EMIT_TWO_BYTES ('\r', '\n');  
           else  
             EMIT_ONE_BYTE (c);  
         }  
       src_base = src;  
     label_end_of_loop:  
       ;  
     }  
   else  
4757      {      {
4758        if (!dst_bytes || src_bytes <= dst_bytes)        struct charset *charset;
4759          unsigned code;
4760    
4761          ASSURE_DESTINATION (safe_room);
4762          c = *charbuf++;
4763          if (ascii_compatible && ASCII_CHAR_P (c))
4764            EMIT_ONE_ASCII_BYTE (c);
4765          else if (CHAR_BYTE8_P (c))
4766          {          {
4767            safe_bcopy (src, dst, src_bytes);            c = CHAR_TO_BYTE8 (c);
4768            src_base = src_end;            EMIT_ONE_BYTE (c);
           dst += src_bytes;  
4769          }          }
4770        else        else
4771          {          {
4772            if (coding->src_multibyte            charset = char_charset (c, charset_list, &code);
4773                && *(src + dst_bytes - 1) == LEADING_CODE_8_BIT_CONTROL)            if (charset)
4774              dst_bytes--;              {
4775            safe_bcopy (src, dst, dst_bytes);                if (CHARSET_DIMENSION (charset) == 1)
4776            src_base = src + dst_bytes;                  EMIT_ONE_BYTE (code);
4777            dst = destination + dst_bytes;                else if (CHARSET_DIMENSION (charset) == 2)
4778            coding->result = CODING_FINISH_INSUFFICIENT_DST;                  EMIT_TWO_BYTES (code >> 8, code & 0xFF);
4779          }                else if (CHARSET_DIMENSION (charset) == 3)
4780        if (coding->eol_type == CODING_EOL_CR)                  EMIT_THREE_BYTES (code >> 16, (code >> 8) & 0xFF, code & 0xFF);
4781          {                else
4782            for (tmp = destination; tmp < dst; tmp++)                  EMIT_FOUR_BYTES (code >> 24, (code >> 16) & 0xFF,
4783              if (*tmp == '\n') *tmp = '\r';                                   (code >> 8) & 0xFF, code & 0xFF);
4784          }              }
4785        else if (selective_display)            else
4786          {              {
4787            for (tmp = destination; tmp < dst; tmp++)                if (coding->mode & CODING_MODE_SAFE_ENCODING)
4788              if (*tmp == '\r') *tmp = '\n';                  c = CODING_INHIBIT_CHARACTER_SUBSTITUTION;
4789                  else
4790                    c = coding->default_char;
4791                  EMIT_ONE_BYTE (c);
4792                }
4793          }          }
4794      }      }
   if (coding->src_multibyte)  
     dst = destination + str_as_unibyte (destination, dst - destination);  
4795    
4796    coding->consumed = src_base - source;    coding->result = CODING_RESULT_SUCCESS;
4797    coding->produced = dst - destination;    coding->produced_char += produced_chars;
4798    coding->produced_char = coding->produced;    coding->produced = dst - coding->destination;
4799      return 0;
4800  }  }
4801    
4802    
4803  /*** 7. C library functions ***/  /*** 7. C library functions ***/
4804    
4805  /* In Emacs Lisp, a coding system is represented by a Lisp symbol which  /* Setup coding context CODING from information about CODING_SYSTEM.
4806     has a property `coding-system'.  The value of this property is a     If CODING_SYSTEM is nil, `no-conversion' is assumed.  If
4807     vector of length 5 (called the coding-vector).  Among elements of     CODING_SYSTEM is invalid, signal an error.  */
    this vector, the first (element[0]) and the fifth (element[4])  
    carry important information for decoding/encoding.  Before  
    decoding/encoding, this information should be set in fields of a  
    structure of type `coding_system'.  
   
    The value of the property `coding-system' can be a symbol of another  
    subsidiary coding-system.  In that case, Emacs gets coding-vector  
    from that symbol.  
   
    `element[0]' contains information to be set in `coding->type'.  The  
    value and its meaning is as follows:  
   
    0 -- coding_type_emacs_mule  
    1 -- coding_type_sjis  
    2 -- coding_type_iso2022  
    3 -- coding_type_big5  
    4 -- coding_type_ccl encoder/decoder written in CCL  
    nil -- coding_type_no_conversion  
    t -- coding_type_undecided (automatic conversion on decoding,  
                                no-conversion on encoding)  
   
    `element[4]' contains information to be set in `coding->flags' and  
    `coding->spec'.  The meaning varies by `coding->type'.  
   
    If `coding->type' is `coding_type_iso2022', element[4] is a vector  
    of length 32 (of which the first 13 sub-elements are used now).  
    Meanings of these sub-elements are:  
   
    sub-element[N] where N is 0 through 3: to be set in `coding->spec.iso2022'  
         If the value is an integer of valid charset, the charset is  
         assumed to be designated to graphic register N initially.  
   
         If the value is minus, it is a minus value of charset which  
         reserves graphic register N, which means that the charset is  
         not designated initially but should be designated to graphic  
         register N just before encoding a character in that charset.  
   
         If the value is nil, graphic register N is never used on  
         encoding.  
   
    sub-element[N] where N is 4 through 11: to be set in `coding->flags'  
         Each value takes t or nil.  See the section ISO2022 of  
         `coding.h' for more information.  
   
    If `coding->type' is `coding_type_big5', element[4] is t to denote  
    BIG5-ETen or nil to denote BIG5-HKU.  
   
    If `coding->type' takes the other value, element[4] is ignored.  
   
    Emacs Lisp's coding systems also carry information about format of  
    end-of-line in a value of property `eol-type'.  If the value is  
    integer, 0 means CODING_EOL_LF, 1 means CODING_EOL_CRLF, and 2  
    means CODING_EOL_CR.  If it is not integer, it should be a vector  
    of subsidiary coding systems of which property `eol-type' has one  
    of the above values.  
4808    
4809  */  void
   
 /* Extract information for decoding/encoding from CODING_SYSTEM_SYMBOL  
    and set it in CODING.  If CODING_SYSTEM_SYMBOL is invalid, CODING  
    is setup so that no conversion is necessary and return -1, else  
    return 0.  */  
   
 int  
4810  setup_coding_system (coding_system, coding)  setup_coding_system (coding_system, coding)
4811       Lisp_Object coding_system;       Lisp_Object coding_system;
4812       struct coding_system *coding;       struct coding_system *coding;
4813  {  {
4814    Lisp_Object coding_spec, coding_type, eol_type, plist;    Lisp_Object attrs;
4815      Lisp_Object eol_type;
4816      Lisp_Object coding_type;
4817    Lisp_Object val;    Lisp_Object val;
4818    
   /* At first, zero clear all members.  */  
   bzero (coding, sizeof (struct coding_system));  
   
   /* Initialize some fields required for all kinds of coding systems.  */  
   coding->symbol = coding_system;  
   coding->heading_ascii = -1;  
   coding->post_read_conversion = coding->pre_write_conversion = Qnil;  
   coding->composing = COMPOSITION_DISABLED;  
   coding->cmp_data = NULL;  
   
4819    if (NILP (coding_system))    if (NILP (coding_system))
4820      goto label_invalid_coding_system;      coding_system = Qno_conversion;
4821    
4822    coding_spec = Fget (coding_system, Qcoding_system);    CHECK_CODING_SYSTEM_GET_ID (coding_system, coding->id);
4823    
4824    if (!VECTORP (coding_spec)    attrs = CODING_ID_ATTRS (coding->id);
4825        || XVECTOR (coding_spec)->size != 5    eol_type = CODING_ID_EOL_TYPE (coding->id);
       || !CONSP (XVECTOR (coding_spec)->contents[3]))  
     goto label_invalid_coding_system;  
4826    
4827    eol_type = inhibit_eol_conversion ? Qnil : Fget (coding_system, Qeol_type);    coding->mode = 0;
4828    if (VECTORP (eol_type))    coding->head_ascii = -1;
4829      {    coding->common_flags
4830        coding->eol_type = CODING_EOL_UNDECIDED;      = (VECTORP (eol_type) ? CODING_REQUIRE_DETECTION_MASK : 0);
4831        coding->common_flags = CODING_REQUIRE_DETECTION_MASK;    if (! NILP (CODING_ATTR_POST_READ (attrs)))
4832        coding->common_flags |= CODING_REQUIRE_DECODING_MASK;
4833      if (! NILP (CODING_ATTR_PRE_WRITE (attrs)))
4834        coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;
4835      if (! NILP (CODING_ATTR_FOR_UNIBYTE (attrs)))
4836        coding->common_flags |= CODING_FOR_UNIBYTE_MASK;
4837    
4838      val = CODING_ATTR_SAFE_CHARSETS (attrs);
4839      coding->max_charset_id = SCHARS (val) - 1;
4840      coding->safe_charsets = (char *) SDATA (val);
4841      coding->default_char = XINT (CODING_ATTR_DEFAULT_CHAR (attrs));
4842    
4843      coding_type = CODING_ATTR_TYPE (attrs);
4844      if (EQ (coding_type, Qundecided))
4845        {
4846          coding->detector = NULL;
4847          coding->decoder = decode_coding_raw_text;
4848          coding->encoder = encode_coding_raw_text;
4849          coding->common_flags |= CODING_REQUIRE_DETECTION_MASK;
4850      }      }
4851    else if (XFASTINT (eol_type) == 1)    else if (EQ (coding_type, Qiso_2022))
4852      {      {
4853        coding->eol_type = CODING_EOL_CRLF;        int i;
4854          int flags = XINT (AREF (attrs, coding_attr_iso_flags));
4855    
4856          /* Invoke graphic register 0 to plane 0.  */
4857          CODING_ISO_INVOCATION (coding, 0) = 0;
4858          /* Invoke graphic register 1 to plane 1 if we can use 8-bit.  */
4859          CODING_ISO_INVOCATION (coding, 1)
4860            = (flags & CODING_ISO_FLAG_SEVEN_BITS ? -1 : 1);
4861          /* Setup the initial status of designation.  */
4862          for (i = 0; i < 4; i++)
4863            CODING_ISO_DESIGNATION (coding, i) = CODING_ISO_INITIAL (coding, i);
4864          /* Not single shifting initially.  */
4865          CODING_ISO_SINGLE_SHIFTING (coding) = 0;
4866          /* Beginning of buffer should also be regarded as bol. */
4867          CODING_ISO_BOL (coding) = 1;
4868          coding->detector = detect_coding_iso_2022;
4869          coding->decoder = decode_coding_iso_2022;
4870          coding->encoder = encode_coding_iso_2022;
4871          if (flags & CODING_ISO_FLAG_SAFE)
4872            coding->mode |= CODING_MODE_SAFE_ENCODING;
4873        coding->common_flags        coding->common_flags
4874          = CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;          |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK
4875      }              | CODING_REQUIRE_FLUSHING_MASK);
4876    else if (XFASTINT (eol_type) == 2)        if (flags & CODING_ISO_FLAG_COMPOSITION)
4877      {          coding->common_flags |= CODING_ANNOTATE_COMPOSITION_MASK;
4878        coding->eol_type = CODING_EOL_CR;        if (flags & CODING_ISO_FLAG_DESIGNATION)
4879            coding->common_flags |= CODING_ANNOTATE_CHARSET_MASK;
4880          if (flags & CODING_ISO_FLAG_FULL_SUPPORT)
4881            {
4882              setup_iso_safe_charsets (attrs);
4883              val = CODING_ATTR_SAFE_CHARSETS (attrs);
4884              coding->max_charset_id = SCHARS (val) - 1;
4885              coding->safe_charsets = (char *) SDATA (val);
4886            }
4887          CODING_ISO_FLAGS (coding) = flags;
4888        }
4889      else if (EQ (coding_type, Qcharset))
4890        {
4891          coding->detector = detect_coding_charset;
4892          coding->decoder = decode_coding_charset;
4893          coding->encoder = encode_coding_charset;
4894        coding->common_flags        coding->common_flags
4895          = CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;          |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
4896      }      }
4897    else    else if (EQ (coding_type, Qutf_8))
     coding->eol_type = CODING_EOL_LF;  
   
   coding_type = XVECTOR (coding_spec)->contents[0];  
   /* Try short cut.  */  
   if (SYMBOLP (coding_type))  
4898      {      {
4899        if (EQ (coding_type, Qt))        coding->detector = detect_coding_utf_8;
4900          {        coding->decoder = decode_coding_utf_8;
4901            coding->type = coding_type_undecided;        coding->encoder = encode_coding_utf_8;
4902            coding->common_flags |= CODING_REQUIRE_DETECTION_MASK;        coding->common_flags
4903          }          |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
       else  
         coding->type = coding_type_no_conversion;  
       /* Initialize this member.  Any thing other than  
          CODING_CATEGORY_IDX_UTF_16_BE and  
          CODING_CATEGORY_IDX_UTF_16_LE are ok because they have  
          special treatment in detect_eol.  */  
       coding->category_idx = CODING_CATEGORY_IDX_EMACS_MULE;  
   
       return 0;  
     }  
   
   /* Get values of coding system properties:  
      `post-read-conversion', `pre-write-conversion',  
      `translation-table-for-decode', `translation-table-for-encode'.  */  
   plist = XVECTOR (coding_spec)->contents[3];  
   /* Pre & post conversion functions should be disabled if  
      inhibit_eol_conversion is nonzero.  This is the case that a code  
      conversion function is called while those functions are running.  */  
   if (! inhibit_pre_post_conversion)  
     {  
       coding->post_read_conversion = Fplist_get (plist, Qpost_read_conversion);  
       coding->pre_write_conversion = Fplist_get (plist, Qpre_write_conversion);  
     }  
   val = Fplist_get (plist, Qtranslation_table_for_decode);  
   if (SYMBOLP (val))  
     val = Fget (val, Qtranslation_table_for_decode);  
   coding->translation_table_for_decode = CHAR_TABLE_P (val) ? val : Qnil;  
   val = Fplist_get (plist, Qtranslation_table_for_encode);  
   if (SYMBOLP (val))  
     val = Fget (val, Qtranslation_table_for_encode);  
   coding->translation_table_for_encode = CHAR_TABLE_P (val) ? val : Qnil;  
   val = Fplist_get (plist, Qcoding_category);  
   if (!NILP (val))  
     {  
       val = Fget (val, Qcoding_category_index);  
       if (INTEGERP (val))  
         coding->category_idx = XINT (val);  
       else  
         goto label_invalid_coding_system;  
4904      }      }
4905    else    else if (EQ (coding_type, Qutf_16))
     goto label_invalid_coding_system;  
   
   /* If the coding system has non-nil `composition' property, enable  
      composition handling.  */  
   val = Fplist_get (plist, Qcomposition);  
   if (!NILP (val))  
     coding->composing = COMPOSITION_NO;  
   
   switch (XFASTINT (coding_type))  
4906      {      {
4907      case 0:        val = AREF (attrs, coding_attr_utf_16_bom);
4908        coding->type = coding_type_emacs_mule;        CODING_UTF_16_BOM (coding) = (CONSP (val) ? utf_16_detect_bom
4909                                        : EQ (val, Qt) ? utf_16_with_bom
4910                                        : utf_16_without_bom);
4911          val = AREF (attrs, coding_attr_utf_16_endian);
4912          CODING_UTF_16_ENDIAN (coding) = (EQ (val, Qbig) ? utf_16_big_endian
4913                                           : utf_16_little_endian);
4914          CODING_UTF_16_SURROGATE (coding) = 0;
4915          coding->detector = detect_coding_utf_16;
4916          coding->decoder = decode_coding_utf_16;
4917          coding->encoder = encode_coding_utf_16;
4918        coding->common_flags        coding->common_flags
4919          |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;          |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
4920        if (!NILP (coding->post_read_conversion))        if (CODING_UTF_16_BOM (coding) == utf_16_detect_bom)
4921          coding->common_flags |= CODING_REQUIRE_DECODING_MASK;          coding->common_flags |= CODING_REQUIRE_DETECTION_MASK;
4922        if (!NILP (coding->pre_write_conversion))      }
4923          coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;    else if (EQ (coding_type, Qccl))
4924        break;      {
4925          coding->detector = detect_coding_ccl;
4926      case 1:        coding->decoder = decode_coding_ccl;
4927        coding->type = coding_type_sjis;        coding->encoder = encode_coding_ccl;
4928        coding->common_flags        coding->common_flags
4929          |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;          |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK
4930        break;              | CODING_REQUIRE_FLUSHING_MASK);
4931        }
4932      case 2:    else if (EQ (coding_type, Qemacs_mule))
4933        coding->type = coding_type_iso2022;      {
4934          coding->detector = detect_coding_emacs_mule;
4935          coding->decoder = decode_coding_emacs_mule;
4936          coding->encoder = encode_coding_emacs_mule;
4937        coding->common_flags        coding->common_flags
4938          |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;          |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
4939        {        if (! NILP (AREF (attrs, coding_attr_emacs_mule_full))
4940          Lisp_Object val, temp;            && ! EQ (CODING_ATTR_CHARSET_LIST (attrs), Vemacs_mule_charset_list))
4941          Lisp_Object *flags;          {
4942          int i, charset, reg_bits = 0;            Lisp_Object tail, safe_charsets;
4943              int max_charset_id = 0;
4944          val = XVECTOR (coding_spec)->contents[4];  
4945              for (tail = Vemacs_mule_charset_list; CONSP (tail);
4946          if (!VECTORP (val) || XVECTOR (val)->size != 32)                 tail = XCDR (tail))
4947            goto label_invalid_coding_system;              if (max_charset_id < XFASTINT (XCAR (tail)))
4948                  max_charset_id = XFASTINT (XCAR (tail));
4949          flags = XVECTOR (val)->contents;            safe_charsets = Fmake_string (make_number (max_charset_id + 1),
4950          coding->flags                                          make_number (255));
4951            = ((NILP (flags[4]) ? 0 : CODING_FLAG_ISO_SHORT_FORM)            for (tail = Vemacs_mule_charset_list; CONSP (tail);
4952               | (NILP (flags[5]) ? 0 : CODING_FLAG_ISO_RESET_AT_EOL)                 tail = XCDR (tail))
4953               | (NILP (flags[6]) ? 0 : CODING_FLAG_ISO_RESET_AT_CNTL)              SSET (safe_charsets, XFASTINT (XCAR (tail)), 0);
4954               | (NILP (flags[7]) ? 0 : CODING_FLAG_ISO_SEVEN_BITS)            coding->max_charset_id = max_charset_id;
4955               | (NILP (flags[8]) ? 0 : CODING_FLAG_ISO_LOCKING_SHIFT)            coding->safe_charsets = (char *) SDATA (safe_charsets);
4956               | (NILP (flags[9]) ? 0 : CODING_FLAG_ISO_SINGLE_SHIFT)          }
4957               | (NILP (flags[10]) ? 0 : CODING_FLAG_ISO_USE_ROMAN)      }
4958               | (NILP (flags[11]) ? 0 : CODING_FLAG_ISO_USE_OLDJIS)    else if (EQ (coding_type, Qshift_jis))
4959               | (NILP (flags[12]) ? 0 : CODING_FLAG_ISO_NO_DIRECTION)      {
4960               | (NILP (flags[13]) ? 0 : CODING_FLAG_ISO_INIT_AT_BOL)        coding->detector = detect_coding_sjis;
4961               | (NILP (flags[14]) ? 0 : CODING_FLAG_ISO_DESIGNATE_AT_BOL)        coding->decoder = decode_coding_sjis;
4962               | (NILP (flags[15]) ? 0 : CODING_FLAG_ISO_SAFE)        coding->encoder = encode_coding_sjis;
              | (NILP (flags[16]) ? 0 : CODING_FLAG_ISO_LATIN_EXTRA)  
              );  
   
         /* Invoke graphic register 0 to plane 0.  */  
         CODING_SPEC_ISO_INVOCATION (coding, 0) = 0;  
         /* Invoke graphic register 1 to plane 1 if we can use full 8-bit.  */  
         CODING_SPEC_ISO_INVOCATION (coding, 1)  
           = (coding->flags & CODING_FLAG_ISO_SEVEN_BITS ? -1 : 1);  
         /* Not single shifting at first.  */  
         CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 0;  
         /* Beginning of buffer should also be regarded as bol. */  
         CODING_SPEC_ISO_BOL (coding) = 1;  
   
         for (charset = 0; charset <= MAX_CHARSET; charset++)  
           CODING_SPEC_ISO_REVISION_NUMBER (coding, charset) = 255;  
         val = Vcharset_revision_alist;  
         while (CONSP (val))  
           {  
             charset = get_charset_id (Fcar_safe (XCAR (val)));  
             if (charset >= 0  
                 && (temp = Fcdr_safe (XCAR (val)), INTEGERP (temp))  
                 && (i = XINT (temp), (i >= 0 && (i + '@') < 128)))  
               CODING_SPEC_ISO_REVISION_NUMBER (coding, charset) = i;  
             val = XCDR (val);  
           }  
   
         /* Checks FLAGS[REG] (REG = 0, 1, 2 3) and decide designations.  
            FLAGS[REG] can be one of below:  
                 integer CHARSET: CHARSET occupies register I,  
                 t: designate nothing to REG initially, but can be used  
                   by any charsets,  
                 list of integer, nil, or t: designate the first  
                   element (if integer) to REG initially, the remaining  
                   elements (if integer) is designated to REG on request,  
                   if an element is t, REG can be used by any charsets,  
                 nil: REG is never used.  */  
         for (charset = 0; charset <= MAX_CHARSET; charset++)  
           CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)  
             = CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION;  
         for (i = 0; i < 4; i++)  
           {  
             if ((INTEGERP (flags[i])  
                  && (charset = XINT (flags[i]), CHARSET_VALID_P (charset)))  
                 || (charset = get_charset_id (flags[i])) >= 0)  
               {  
                 CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;  
                 CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) = i;  
               }  
             else if (EQ (flags[i], Qt))  
               {  
                 CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;  
                 reg_bits |= 1 << i;  
                 coding->flags |= CODING_FLAG_ISO_DESIGNATION;  
               }  
             else if (CONSP (flags[i]))  
               {  
                 Lisp_Object tail;  
                 tail = flags[i];  
   
                 coding->flags |= CODING_FLAG_ISO_DESIGNATION;  
                 if ((INTEGERP (XCAR (tail))  
                      && (charset = XINT (XCAR (tail)),  
                          CHARSET_VALID_P (charset)))  
                     || (charset = get_charset_id (XCAR (tail))) >= 0)  
                   {  
                     CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;  
                     CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) =i;  
                   }  
                 else  
                   CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;  
                 tail = XCDR (tail);  
                 while (CONSP (tail))  
                   {  
                     if ((INTEGERP (XCAR (tail))  
                          && (charset = XINT (XCAR (tail)),  
                              CHARSET_VALID_P (charset)))  
                         || (charset = get_charset_id (XCAR (tail))) >= 0)  
                       CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)  
                         = i;  
                     else if (EQ (XCAR (tail), Qt))  
                       reg_bits |= 1 << i;  
                     tail = XCDR (tail);  
                   }  
               }  
             else  
               CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;  
   
             CODING_SPEC_ISO_DESIGNATION (coding, i)  
               = CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i);  
           }  
   
         if (reg_bits && ! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT))  
           {  
             /* REG 1 can be used only by locking shift in 7-bit env.  */  
             if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)  
               reg_bits &= ~2;  
             if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT))  
               /* Without any shifting, only REG 0 and 1 can be used.  */  
               reg_bits &= 3;  
           }  
   
         if (reg_bits)  
           for (charset = 0; charset <= MAX_CHARSET; charset++)  
             {  
               if (CHARSET_DEFINED_P (charset)  
                   && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)  
                       == CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION))  
                 {  
                   /* There exist some default graphic registers to be  
                      used by CHARSET.  */  
   
                   /* We had better avoid designating a charset of  
                      CHARS96 to REG 0 as far as possible.  */  
                   if (CHARSET_CHARS (charset) == 96)  
                     CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)  
                       = (reg_bits & 2  
                          ? 1 : (reg_bits & 4 ? 2 : (reg_bits & 8 ? 3 : 0)));  
                   else  
                     CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)  
                       = (reg_bits & 1  
                          ? 0 : (reg_bits & 2 ? 1 : (reg_bits & 4 ? 2 : 3)));  
                 }  
             }  
       }  
       coding->common_flags |= CODING_REQUIRE_FLUSHING_MASK;  
       coding->spec.iso2022.last_invalid_designation_register = -1;  
       break;  
   
     case 3:  
       coding->type = coding_type_big5;  
4963        coding->common_flags        coding->common_flags
4964          |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;          |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
4965        coding->flags      }
4966          = (NILP (XVECTOR (coding_spec)->contents[4])    else if (EQ (coding_type, Qbig5))
4967             ? CODING_FLAG_BIG5_HKU      {
4968             : CODING_FLAG_BIG5_ETEN);        coding->detector = detect_coding_big5;
4969        break;        coding->decoder = decode_coding_big5;
4970          coding->encoder = encode_coding_big5;
     case 4:  
       coding->type = coding_type_ccl;  
4971        coding->common_flags        coding->common_flags
4972          |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;          |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
4973        {      }
4974          val = XVECTOR (coding_spec)->contents[4];    else                          /* EQ (coding_type, Qraw_text) */
4975          if (! CONSP (val)      {
4976              || setup_ccl_program (&(coding->spec.ccl.decoder),        coding->detector = NULL;
4977                                    XCAR (val)) < 0        coding->decoder = decode_coding_raw_text;
4978              || setup_ccl_program (&(coding->spec.ccl.encoder),        coding->encoder = encode_coding_raw_text;
                                   XCDR (val)) < 0)  
           goto label_invalid_coding_system;  
   
         bzero (coding->spec.ccl.valid_codes, 256);  
         val = Fplist_get (plist, Qvalid_codes);  
         if (CONSP (val))  
           {  
             Lisp_Object this;  
   
             for (; CONSP (val); val = XCDR (val))  
               {  
                 this = XCAR (val);  
                 if (INTEGERP (this)  
                     && XINT (this) >= 0 && XINT (this) < 256)  
                   coding->spec.ccl.valid_codes[XINT (this)] = 1;  
                 else if (CONSP (this)  
                          && INTEGERP (XCAR (this))  
                          && INTEGERP (XCDR (this)))  
                   {  
                     int start = XINT (XCAR (this));  
                     int end = XINT (XCDR (this));  
   
                     if (start >= 0 && start <= end && end < 256)  
                       while (start <= end)  
                         coding->spec.ccl.valid_codes[start++] = 1;  
                   }  
               }  
           }  
       }  
       coding->common_flags |= CODING_REQUIRE_FLUSHING_MASK;  
       coding->spec.ccl.cr_carryover = 0;  
       coding->spec.ccl.eight_bit_carryover[0] = 0;  
       break;  
   
     case 5:  
       coding->type = coding_type_raw_text;  
       break;  
   
     default:  
       goto label_invalid_coding_system;  
4979      }      }
   return 0;  
4980    
4981   label_invalid_coding_system:    return;
   coding->type = coding_type_no_conversion;  
   coding->category_idx = CODING_CATEGORY_IDX_BINARY;  
   coding->common_flags = 0;  
   coding->eol_type = CODING_EOL_LF;  
   coding->pre_write_conversion = coding->post_read_conversion = Qnil;  
   return -1;  
4982  }  }
4983    
4984  /* Free memory blocks allocated for storing composition information.  */  /* Return raw-text or one of its subsidiaries that has the same
4985       eol_type as CODING-SYSTEM.  */
4986    
4987  void  Lisp_Object
4988  coding_free_composition_data (coding)  raw_text_coding_system (coding_system)
4989       struct coding_system *coding;       Lisp_Object coding_system;
4990  {  {
4991    struct composition_data *cmp_data = coding->cmp_data, *next;    Lisp_Object spec, attrs;
4992      Lisp_Object eol_type, raw_text_eol_type;
4993    
4994    if (!cmp_data)    if (NILP (coding_system))
4995      return;      return Qraw_text;
4996    /* Memory blocks are chained.  At first, rewind to the first, then,    spec = CODING_SYSTEM_SPEC (coding_system);
4997       free blocks one by one.  */    attrs = AREF (spec, 0);
   while (cmp_data->prev)  
     cmp_data = cmp_data->prev;  
   while (cmp_data)  
     {  
       next = cmp_data->next;  
       xfree (cmp_data);  
       cmp_data = next;  
     }  
   coding->cmp_data = NULL;  
 }  
   
 /* Set `char_offset' member of all memory blocks pointed by  
    coding->cmp_data to POS.  */  
4998    
4999  void    if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
5000  coding_adjust_composition_offset (coding, pos)      return coding_system;
      struct coding_system *coding;  
      int pos;  
 {  
   struct composition_data *cmp_data;  
5001    
5002    for (cmp_data = coding->cmp_data; cmp_data; cmp_data = cmp_data->next)    eol_type = AREF (spec, 2);
5003      cmp_data->char_offset = pos;    if (VECTORP (eol_type))
5004        return Qraw_text;
5005      spec = CODING_SYSTEM_SPEC (Qraw_text);
5006      raw_text_eol_type = AREF (spec, 2);
5007      return (EQ (eol_type, Qunix) ? AREF (raw_text_eol_type, 0)
5008              : EQ (eol_type, Qdos) ? AREF (raw_text_eol_type, 1)
5009              : AREF (raw_text_eol_type, 2));
5010  }  }
5011    
 /* Setup raw-text or one of its subsidiaries in the structure  
    coding_system CODING according to the already setup value eol_type  
    in CODING.  CODING should be setup for some coding system in  
    advance.  */  
5012    
5013  void  /* If CODING_SYSTEM doesn't specify end-of-line format but PARENT
5014  setup_raw_text_coding_system (coding)     does, return one of the subsidiary that has the same eol-spec as
5015       struct coding_system *coding;     PARENT.  Otherwise, return CODING_SYSTEM.  */
5016    
5017    Lisp_Object
5018    coding_inherit_eol_type (coding_system, parent)
5019         Lisp_Object coding_system, parent;
5020  {  {
5021    if (coding->type != coding_type_raw_text)    Lisp_Object spec, attrs, eol_type;
     {  
       coding->symbol = Qraw_text;  
       coding->type = coding_type_raw_text;  
       if (coding->eol_type != CODING_EOL_UNDECIDED)  
         {  
           Lisp_Object subsidiaries;  
           subsidiaries = Fget (Qraw_text, Qeol_type);  
5022    
5023            if (VECTORP (subsidiaries)    if (NILP (coding_system))
5024                && XVECTOR (subsidiaries)->size == 3)      coding_system = Qraw_text;
5025              coding->symbol    spec = CODING_SYSTEM_SPEC (coding_system);
5026                = XVECTOR (subsidiaries)->contents[coding->eol_type];    attrs = AREF (spec, 0);
5027          }    eol_type = AREF (spec, 2);
5028        setup_coding_system (coding->symbol, coding);    if (VECTORP (eol_type)
5029          && ! NILP (parent))
5030        {
5031          Lisp_Object parent_spec;
5032          Lisp_Object parent_eol_type;
5033    
5034          parent_spec
5035            = CODING_SYSTEM_SPEC (buffer_defaults.buffer_file_coding_system);
5036          parent_eol_type = AREF (parent_spec, 2);
5037          if (EQ (parent_eol_type, Qunix))
5038            coding_system = AREF (eol_type, 0);
5039          else if (EQ (parent_eol_type, Qdos))
5040            coding_system = AREF (eol_type, 1);
5041          else if (EQ (parent_eol_type, Qmac))
5042            coding_system = AREF (eol_type, 2);
5043      }      }
5044    return;    return coding_system;
5045  }  }
5046    
5047  /* Emacs has a mechanism to automatically detect a coding system if it  /* Emacs has a mechanism to automatically detect a coding system if it
# Line 4001  setup_raw_text_coding_system (coding) Line 5094  setup_raw_text_coding_system (coding)
5094     o coding-category-iso-7-else     o coding-category-iso-7-else
5095    
5096          The category for a coding system which has the same code range          The category for a coding system which has the same code range
5097          as ISO2022 of 7-bit environment but uses locking shift or          as ISO2022 of 7-bit environemnt but uses locking shift or
5098          single shift functions.  Assigned the coding-system (Lisp          single shift functions.  Assigned the coding-system (Lisp
5099          symbol) `iso-2022-7bit-lock' by default.          symbol) `iso-2022-7bit-lock' by default.
5100    
5101     o coding-category-iso-8-else     o coding-category-iso-8-else
5102    
5103          The category for a coding system which has the same code range          The category for a coding system which has the same code range
5104          as ISO2022 of 8-bit environment but uses locking shift or          as ISO2022 of 8-bit environemnt but uses locking shift or
5105          single shift functions.  Assigned the coding-system (Lisp          single shift functions.  Assigned the coding-system (Lisp
5106          symbol) `iso-2022-8bit-ss2' by default.          symbol) `iso-2022-8bit-ss2' by default.
5107    
# Line 4051  setup_raw_text_coding_system (coding) Line 5144  setup_raw_text_coding_system (coding)
5144          `no-conversion' by default.          `no-conversion' by default.
5145    
5146     Each of them is a Lisp symbol and the value is an actual     Each of them is a Lisp symbol and the value is an actual
5147     `coding-system' (this is also a Lisp symbol) assigned by a user.     `coding-system's (this is also a Lisp symbol) assigned by a user.
5148     What Emacs does actually is to detect a category of coding system.     What Emacs does actually is to detect a category of coding system.
5149     Then, it uses a `coding-system' assigned to it.  If Emacs can't     Then, it uses a `coding-system' assigned to it.  If Emacs can't
5150     decide a single possible category, it selects a category of the     decide only one possible category, it selects a category of the
5151     highest priority.  Priorities of categories are also specified by a     highest priority.  Priorities of categories are also specified by a
5152     user in a Lisp variable `coding-category-list'.     user in a Lisp variable `coding-category-list'.
5153    
5154  */  */
5155    
5156  static  #define EOL_SEEN_NONE   0
5157  int ascii_skip_code[256];  #define EOL_SEEN_LF     1
5158    #define EOL_SEEN_CR     2
5159    #define EOL_SEEN_CRLF   4
5160    
5161    /* Detect how end-of-line of a text of length SRC_BYTES pointed by
5162       SOURCE is encoded.  If CATEGORY is one of
5163       coding_category_utf_16_XXXX, assume that CR and LF are encoded by
5164       two-byte, else they are encoded by one-byte.
5165    
5166  /* Detect how a text of length SRC_BYTES pointed by SOURCE is encoded.     Return one of EOL_SEEN_XXX.  */
    If it detects possible coding systems, return an integer in which  
    appropriate flag bits are set.  Flag bits are defined by macros  
    CODING_CATEGORY_MASK_XXX in `coding.h'.  If PRIORITIES is non-NULL,  
    it should point the table `coding_priorities'.  In that case, only  
    the flag bit for a coding system of the highest priority is set in  
    the returned value.  If MULTIBYTEP is nonzero, 8-bit codes of the  
    range 0x80..0x9F are in multibyte form.  
5167    
5168     How many ASCII characters are at the head is returned as *SKIP.  */  #define MAX_EOL_CHECK_COUNT 3
5169    
5170  static int  static int
5171  detect_coding_mask (source, src_bytes, priorities, skip, multibytep)  detect_eol (source, src_bytes, category)
5172       unsigned char *source;       unsigned char *source;
5173       int src_bytes, *priorities, *skip;       EMACS_INT src_bytes;
5174       int multibytep;       enum coding_category category;
5175  {  {
5176    register unsigned char c;    unsigned char *src = source, *src_end = src + src_bytes;
5177    unsigned char *src = source, *src_end = source + src_bytes;    unsigned char c;
5178    unsigned int mask, utf16_examined_p, iso2022_examined_p;    int total  = 0;
5179    int i;    int eol_seen = EOL_SEEN_NONE;
5180    
5181    /* At first, skip all ASCII characters and control characters except    if ((1 << category) & CATEGORY_MASK_UTF_16)
5182       for three ISO2022 specific control characters.  */      {
5183    ascii_skip_code[ISO_CODE_SO] = 0;        int msb, lsb;
5184    ascii_skip_code[ISO_CODE_SI] = 0;  
5185    ascii_skip_code[ISO_CODE_ESC] = 0;        msb = category == (coding_category_utf_16_le
5186                             | coding_category_utf_16_le_nosig);
5187   label_loop_detect_coding:        lsb = 1 - msb;
5188    while (src < src_end && ascii_skip_code[*src]) src++;  
5189    *skip = src - source;        while (src + 1 < src_end)
   
   if (src >= src_end)  
     /* We found nothing other than ASCII.  There's nothing to do.  */  
     return 0;  
   
   c = *src;  
   /* The text seems to be encoded in some multilingual coding system.  
      Now, try to find in which coding system the text is encoded.  */  
   if (c < 0x80)  
     {  
       /* i.e. (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO) */  
       /* C is an ISO2022 specific control code of C0.  */  
       mask = detect_coding_iso2022 (src, src_end, multibytep);  
       if (mask == 0)  
         {  
           /* No valid ISO2022 code follows C.  Try again.  */  
           src++;  
           if (c == ISO_CODE_ESC)  
             ascii_skip_code[ISO_CODE_ESC] = 1;  
           else  
             ascii_skip_code[ISO_CODE_SO] = ascii_skip_code[ISO_CODE_SI] = 1;  
           goto label_loop_detect_coding;  
         }  
       if (priorities)  
5190          {          {
5191            for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++)            c = src[lsb];
5192              if (src[msb] == 0 && (c == '\n' || c == '\r'))
5193              {              {
5194                if (mask & priorities[i])                int this_eol;
5195                  return priorities[i];  
5196                  if (c == '\n')
5197                    this_eol = EOL_SEEN_LF;
5198                  else if (src + 3 >= src_end
5199                           || src[msb + 2] != 0
5200                           || src[lsb + 2] != '\n')
5201                    this_eol = EOL_SEEN_CR;
5202                  else
5203                    this_eol = EOL_SEEN_CRLF;
5204    
5205                  if (eol_seen == EOL_SEEN_NONE)
5206                    /* This is the first end-of-line.  */
5207                    eol_seen = this_eol;
5208                  else if (eol_seen != this_eol)
5209                    {
5210                      /* The found type is different from what found before.  */
5211                      eol_seen = EOL_SEEN_LF;
5212                      break;
5213                    }
5214                  if (++total == MAX_EOL_CHECK_COUNT)
5215                    break;
5216              }              }
5217            return CODING_CATEGORY_MASK_RAW_TEXT;            src += 2;
5218          }          }
5219      }      }
5220    else    else
5221      {      {
5222        int try;        while (src < src_end)
5223            {
5224              c = *src++;
5225              if (c == '\n' || c == '\r')
5226                {
5227                  int this_eol;
5228    
5229        if (multibytep && c == LEADING_CODE_8_BIT_CONTROL)                if (c == '\n')
5230          c = src[1] - 0x20;                  this_eol = EOL_SEEN_LF;
5231                  else if (src >= src_end || *src != '\n')
5232                    this_eol = EOL_SEEN_CR;
5233                  else
5234                    this_eol = EOL_SEEN_CRLF, src++;
5235    
5236        if (c < 0xA0)                if (eol_seen == EOL_SEEN_NONE)
5237          {                  /* This is the first end-of-line.  */
5238            /* C is the first byte of SJIS character code,                  eol_seen = this_eol;
5239               or a leading-code of Emacs' internal format (emacs-mule),                else if (eol_seen != this_eol)
5240               or the first byte of UTF-16.  */                  {
5241            try = (CODING_CATEGORY_MASK_SJIS                    /* The found type is different from what found before.  */
5242                    | CODING_CATEGORY_MASK_EMACS_MULE                    eol_seen = EOL_SEEN_LF;
5243                    | CODING_CATEGORY_MASK_UTF_16_BE                    break;
5244                    | CODING_CATEGORY_MASK_UTF_16_LE);                  }
5245                  if (++total == MAX_EOL_CHECK_COUNT)
5246            /* Or, if C is a special latin extra code,                  break;
5247               or is an ISO2022 specific control code of C1 (SS2 or SS3),              }
5248               or is an ISO2022 control-sequence-introducer (CSI),          }
              we should also consider the possibility of ISO2022 codings.  */  
           if ((VECTORP (Vlatin_extra_code_table)  
                && !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))  
               || (c == ISO_CODE_SS2 || c == ISO_CODE_SS3)  
               || (c == ISO_CODE_CSI  
                   && (src < src_end  
                       && (*src == ']'  
                           || ((*src == '0' || *src == '1' || *src == '2')  
                               && src + 1 < src_end  
                               && src[1] == ']')))))  
             try |= (CODING_CATEGORY_MASK_ISO_8_ELSE  
                      | CODING_CATEGORY_MASK_ISO_8BIT);  
         }  
       else  
         /* C is a character of ISO2022 in graphic plane right,  
            or a SJIS's 1-byte character code (i.e. JISX0201),  
            or the first byte of BIG5's 2-byte code,  
            or the first byte of UTF-8/16.  */  
         try = (CODING_CATEGORY_MASK_ISO_8_ELSE  
                 | CODING_CATEGORY_MASK_ISO_8BIT  
                 | CODING_CATEGORY_MASK_SJIS  
                 | CODING_CATEGORY_MASK_BIG5  
                 | CODING_CATEGORY_MASK_UTF_8  
                 | CODING_CATEGORY_MASK_UTF_16_BE  
                 | CODING_CATEGORY_MASK_UTF_16_LE);  
   
       /* Or, we may have to consider the possibility of CCL.  */  
       if (coding_system_table[CODING_CATEGORY_IDX_CCL]  
           && (coding_system_table[CODING_CATEGORY_IDX_CCL]  
               ->spec.ccl.valid_codes)[c])  
         try |= CODING_CATEGORY_MASK_CCL;  
   
       mask = 0;  
       utf16_examined_p = iso2022_examined_p = 0;  
       if (priorities)  
         {  
           for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++)  
             {  
               if (!iso2022_examined_p  
                   && (priorities[i] & try & CODING_CATEGORY_MASK_ISO))  
                 {  
                   mask |= detect_coding_iso2022 (src, src_end, multibytep);  
                   iso2022_examined_p = 1;  
                 }  
               else if (priorities[i] & try & CODING_CATEGORY_MASK_SJIS)  
                 mask |= detect_coding_sjis (src, src_end, multibytep);  
               else if (priorities[i] & try & CODING_CATEGORY_MASK_UTF_8)  
                 mask |= detect_coding_utf_8 (src, src_end, multibytep);  
               else if (!utf16_examined_p  
                        && (priorities[i] & try &  
                            CODING_CATEGORY_MASK_UTF_16_BE_LE))  
                 {  
                   mask |= detect_coding_utf_16 (src, src_end, multibytep);  
                   utf16_examined_p = 1;  
                 }  
               else if (priorities[i] & try & CODING_CATEGORY_MASK_BIG5)  
                 mask |= detect_coding_big5 (src, src_end, multibytep);  
               else if (priorities[i] & try & CODING_CATEGORY_MASK_EMACS_MULE)  
                 mask |= detect_coding_emacs_mule (src, src_end, multibytep);  
               else if (priorities[i] & try & CODING_CATEGORY_MASK_CCL)  
                 mask |= detect_coding_ccl (src, src_end, multibytep);  
               else if (priorities[i] & CODING_CATEGORY_MASK_RAW_TEXT)  
                 mask |= CODING_CATEGORY_MASK_RAW_TEXT;  
               else if (priorities[i] & CODING_CATEGORY_MASK_BINARY)  
                 mask |= CODING_CATEGORY_MASK_BINARY;  
               if (mask & priorities[i])  
                 return priorities[i];  
             }  
           return CODING_CATEGORY_MASK_RAW_TEXT;  
         }  
       if (try & CODING_CATEGORY_MASK_ISO)  
         mask |= detect_coding_iso2022 (src, src_end, multibytep);  
       if (try & CODING_CATEGORY_MASK_SJIS)  
         mask |= detect_coding_sjis (src, src_end, multibytep);  
       if (try & CODING_CATEGORY_MASK_BIG5)  
         mask |= detect_coding_big5 (src, src_end, multibytep);  
       if (try & CODING_CATEGORY_MASK_UTF_8)  
         mask |= detect_coding_utf_8 (src, src_end, multibytep);  
       if (try & CODING_CATEGORY_MASK_UTF_16_BE_LE)  
         mask |= detect_coding_utf_16 (src, src_end, multibytep);  
       if (try & CODING_CATEGORY_MASK_EMACS_MULE)  
         mask |= detect_coding_emacs_mule (src, src_end, multibytep);  
       if (try & CODING_CATEGORY_MASK_CCL)  
         mask |= detect_coding_ccl (src, src_end, multibytep);  
5249      }      }
5250    return (mask | CODING_CATEGORY_MASK_RAW_TEXT | CODING_CATEGORY_MASK_BINARY);    return eol_seen;
5251  }  }
5252    
 /* Detect how a text of length SRC_BYTES pointed by SRC is encoded.  
    The information of the detected coding system is set in CODING.  */  
5253    
5254  void  static void
5255  detect_coding (coding, src, src_bytes)  adjust_coding_eol_type (coding, eol_seen)
5256       struct coding_system *coding;       struct coding_system *coding;
5257       const unsigned char *src;       int eol_seen;
      int src_bytes;  
5258  {  {
5259    unsigned int idx;    Lisp_Object eol_type;
   int skip, mask;  
   Lisp_Object val;  
5260    
5261    val = Vcoding_category_list;    eol_type = CODING_ID_EOL_TYPE (coding->id);
5262    mask = detect_coding_mask (src, src_bytes, coding_priorities, &skip,    if (eol_seen & EOL_SEEN_LF)
5263                               coding->src_multibyte);      coding->id = CODING_SYSTEM_ID (AREF (eol_type, 0));
5264    coding->heading_ascii = skip;    else if (eol_seen & EOL_SEEN_CRLF)
5265        coding->id = CODING_SYSTEM_ID (AREF (eol_type, 1));
5266      else if (eol_seen & EOL_SEEN_CR)
5267        coding->id = CODING_SYSTEM_ID (AREF (eol_type, 2));
5268    }
5269    
5270    /* Detect how a text specified in CODING is encoded.  If a coding
5271       system is detected, update fields of CODING by the detected coding
5272       system.  */
5273    
5274    if (!mask) return;  void
5275    detect_coding (coding)
5276         struct coding_system *coding;
5277    {
5278      const unsigned char *src, *src_end;
5279      Lisp_Object attrs, coding_type;
5280    
5281    /* We found a single coding system of the highest priority in MASK.  */    coding->consumed = coding->consumed_char = 0;
5282    idx = 0;    coding->produced = coding->produced_char = 0;
5283    while (mask && ! (mask & 1)) mask >>= 1, idx++;    coding_set_source (coding);
   if (! mask)  
     idx = CODING_CATEGORY_IDX_RAW_TEXT;  
5284    
5285    val = SYMBOL_VALUE (XVECTOR (Vcoding_category_table)->contents[idx]);    src_end = coding->source + coding->src_bytes;
5286    
5287    if (coding->eol_type != CODING_EOL_UNDECIDED)    /* If we have not yet decided the text encoding type, detect it
5288         now.  */
5289      if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qundecided))
5290      {      {
5291        Lisp_Object tmp;        int c, i;
   
       tmp = Fget (val, Qeol_type);  
       if (VECTORP (tmp))  
         val = XVECTOR (tmp)->contents[coding->eol_type];  
     }  
   
   /* Setup this new coding system while preserving some slots.  */  
   {  
     int src_multibyte = coding->src_multibyte;  
     int dst_multibyte = coding->dst_multibyte;  
   
     setup_coding_system (val, coding);  
     coding->src_multibyte = src_multibyte;  
     coding->dst_multibyte = dst_multibyte;  
     coding->heading_ascii = skip;  
   }  
 }  
   
 /* Detect how end-of-line of a text of length SRC_BYTES pointed by  
    SOURCE is encoded.  Return one of CODING_EOL_LF, CODING_EOL_CRLF,  
    CODING_EOL_CR, and CODING_EOL_UNDECIDED.  
   
    How many non-eol characters are at the head is returned as *SKIP.  */  
   
 #define MAX_EOL_CHECK_COUNT 3  
   
 static int  
 detect_eol_type (source, src_bytes, skip)  
      unsigned char *source;  
      int src_bytes, *skip;  
 {  
   unsigned char *src = source, *src_end = src + src_bytes;  
   unsigned char c;  
   int total = 0;                /* How many end-of-lines are found so far.  */  
   int eol_type = CODING_EOL_UNDECIDED;  
   int this_eol_type;  
   
   *skip = 0;  
5292    
5293    while (src < src_end && total < MAX_EOL_CHECK_COUNT)        for (src = coding->source; src < src_end; src++)
     {  
       c = *src++;  
       if (c == '\n' || c == '\r')  
5294          {          {
5295            if (*skip == 0)            c = *src;
5296              *skip = src - 1 - source;            if (c & 0x80 || (c < 0x20 && (c == ISO_CODE_ESC
5297            total++;                                          || c == ISO_CODE_SI
5298            if (c == '\n')                                          || c == ISO_CODE_SO)))
5299              this_eol_type = CODING_EOL_LF;              break;
           else if (src >= src_end || *src != '\n')  
             this_eol_type = CODING_EOL_CR;  
           else  
             this_eol_type = CODING_EOL_CRLF, src++;  
   
           if (eol_type == CODING_EOL_UNDECIDED)  
             /* This is the first end-of-line.  */  
             eol_type = this_eol_type;  
           else if (eol_type != this_eol_type)  
             {  
               /* The found type is different from what found before.  */  
               eol_type = CODING_EOL_INCONSISTENT;  
               break;  
             }  
5300          }          }
5301      }        coding->head_ascii = src - (coding->source + coding->consumed);
   
   if (*skip == 0)  
     *skip = src_end - source;  
   return eol_type;  
 }  
   
 /* Like detect_eol_type, but detect EOL type in 2-octet  
    big-endian/little-endian format for coding systems utf-16-be and  
    utf-16-le.  */  
   
 static int  
 detect_eol_type_in_2_octet_form (source, src_bytes, skip, big_endian_p)  
      unsigned char *source;  
      int src_bytes, *skip, big_endian_p;  
 {  
   unsigned char *src = source, *src_end = src + src_bytes;  
   unsigned int c1, c2;  
   int total = 0;                /* How many end-of-lines are found so far.  */  
   int eol_type = CODING_EOL_UNDECIDED;  
   int this_eol_type;  
   int msb, lsb;  
   
   if (big_endian_p)  
     msb = 0, lsb = 1;  
   else  
     msb = 1, lsb = 0;  
   
   *skip = 0;  
   
   while ((src + 1) < src_end && total < MAX_EOL_CHECK_COUNT)  
     {  
       c1 = (src[msb] << 8) | (src[lsb]);  
       src += 2;  
5302    
5303        if (c1 == '\n' || c1 == '\r')        if (coding->head_ascii < coding->src_bytes)
5304          {          {
5305            if (*skip == 0)            struct coding_detection_info detect_info;
5306              *skip = src - 2 - source;            enum coding_category category;
5307            total++;            struct coding_system *this;
5308            if (c1 == '\n')  
5309              {            detect_info.checked = detect_info.found = detect_info.rejected = 0;
5310                this_eol_type = CODING_EOL_LF;            for (i = 0; i < coding_category_raw_text; i++)
             }  
           else  
5311              {              {
5312                if ((src + 1) >= src_end)                category = coding_priorities[i];
5313                  this = coding_categories + category;
5314                  if (this->id < 0)
5315                  {                  {
5316                    this_eol_type = CODING_EOL_CR;                    /* No coding system of this category is defined.  */
5317                      detect_info.rejected |= (1 << category);
5318                  }                  }
5319                else                else if (category >= coding_category_raw_text)
5320                    continue;
5321                  else if (detect_info.checked & (1 << category))
5322                  {                  {
5323                    c2 = (src[msb] << 8) | (src[lsb]);                    if (detect_info.found & (1 << category))
5324                    if (c2 == '\n')                      break;
                     this_eol_type = CODING_EOL_CRLF, src += 2;  
                   else  
                     this_eol_type = CODING_EOL_CR;  
5325                  }                  }
5326                  else if ((*(this->detector)) (coding, &detect_info)
5327                           && detect_info.found & (1 << category))
5328                    break;
5329              }              }
5330              if (i < coding_category_raw_text)
5331            if (eol_type == CODING_EOL_UNDECIDED)              setup_coding_system (CODING_ID_NAME (this->id), coding);
5332              /* This is the first end-of-line.  */            else if (detect_info.rejected == CATEGORY_MASK_ANY)
5333              eol_type = this_eol_type;              setup_coding_system (Qraw_text, coding);
5334            else if (eol_type != this_eol_type)            else if (detect_info.rejected)
5335              {              for (i = 0; i < coding_category_raw_text; i++)
5336                /* The found type is different from what found before.  */                if (! (detect_info.rejected & (1 << coding_priorities[i])))
5337                eol_type = CODING_EOL_INCONSISTENT;                  {
5338                break;                    this = coding_categories + coding_priorities[i];
5339              }                    setup_coding_system (CODING_ID_NAME (this->id), coding);
5340                      break;
5341                    }
5342          }          }
5343      }      }
5344      else if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qutf_16))
   if (*skip == 0)  
     *skip = src_end - source;  
   return eol_type;  
 }  
   
 /* Detect how end-of-line of a text of length SRC_BYTES pointed by SRC  
    is encoded.  If it detects an appropriate format of end-of-line, it  
    sets the information in *CODING.  */  
   
 void  
 detect_eol (coding, src, src_bytes)  
      struct coding_system *coding;  
      const unsigned char *src;  
      int src_bytes;  
 {  
   Lisp_Object val;  
   int skip;  
   int eol_type;  
   
   switch (coding->category_idx)  
     {  
     case CODING_CATEGORY_IDX_UTF_16_BE:  
       eol_type = detect_eol_type_in_2_octet_form (src, src_bytes, &skip, 1);  
       break;  
     case CODING_CATEGORY_IDX_UTF_16_LE:  
       eol_type = detect_eol_type_in_2_octet_form (src, src_bytes, &skip, 0);  
       break;  
     default:  
       eol_type = detect_eol_type (src, src_bytes, &skip);  
       break;  
     }  
   
   if (coding->heading_ascii > skip)  
     coding->heading_ascii = skip;  
   else  
     skip = coding->heading_ascii;  
   
   if (eol_type == CODING_EOL_UNDECIDED)  
     return;  
   if (eol_type == CODING_EOL_INCONSISTENT)  
5345      {      {
5346  #if 0        Lisp_Object coding_systems;
5347        /* This code is suppressed until we find a better way to        struct coding_detection_info detect_info;
          distinguish raw text file and binary file.  */  
5348    
5349        /* If we have already detected that the coding is raw-text, the        coding_systems
5350           coding should actually be no-conversion.  */          = AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_16_bom);
5351        if (coding->type == coding_type_raw_text)        detect_info.found = detect_info.rejected = 0;
5352          if (CONSP (coding_systems)
5353              && detect_coding_utf_16 (coding, &detect_info)
5354              && (detect_info.found & (CATEGORY_MASK_UTF_16_LE
5355                                       | CATEGORY_MASK_UTF_16_BE)))
5356          {          {
5357            setup_coding_system (Qno_conversion, coding);            if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
5358            return;              setup_coding_system (XCAR (coding_systems), coding);
5359              else
5360                setup_coding_system (XCDR (coding_systems), coding);
5361          }          }
       /* Else, let's decode only text code anyway.  */  
 #endif /* 0 */  
       eol_type = CODING_EOL_LF;  
5362      }      }
5363    
5364    val = Fget (coding->symbol, Qeol_type);    attrs = CODING_ID_ATTRS (coding->id);
5365    if (VECTORP (val) && XVECTOR (val)->size == 3)    coding_type = CODING_ATTR_TYPE (attrs);
5366    
5367      /* If we have not yet decided the EOL type, detect it now.  But, the
5368         detection is impossible for a CCL based coding system, in which
5369         case, we detct the EOL type after decoding.  */
5370      if (VECTORP (CODING_ID_EOL_TYPE (coding->id))
5371          && ! EQ (coding_type, Qccl))
5372      {      {
5373        int src_multibyte = coding->src_multibyte;        int eol_seen = detect_eol (coding->source, coding->src_bytes,
5374        int dst_multibyte = coding->dst_multibyte;                                   XINT (CODING_ATTR_CATEGORY (attrs)));
       struct composition_data *cmp_data = coding->cmp_data;  
5375    
5376        setup_coding_system (XVECTOR (val)->contents[eol_type], coding);        if (eol_seen != EOL_SEEN_NONE)
5377        coding->src_multibyte = src_multibyte;          adjust_coding_eol_type (coding, eol_seen);
       coding->dst_multibyte = dst_multibyte;  
       coding->heading_ascii = skip;  
       coding->cmp_data = cmp_data;  
5378      }      }
5379  }  }
5380    
 #define CONVERSION_BUFFER_EXTRA_ROOM 256  
5381    
5382  #define DECODING_BUFFER_MAG(coding)                     \  static void
5383    (coding->type == coding_type_iso2022                  \  decode_eol (coding)
    ? 3                                                  \  
    : (coding->type == coding_type_ccl                   \  
       ? coding->spec.ccl.decoder.buf_magnification      \  
       : 2))  
   
 /* Return maximum size (bytes) of a buffer enough for decoding  
    SRC_BYTES of text encoded in CODING.  */  
   
 int  
 decoding_buffer_size (coding, src_bytes)  
5384       struct coding_system *coding;       struct coding_system *coding;
      int src_bytes;  
5385  {  {
5386    return (src_bytes * DECODING_BUFFER_MAG (coding)    if (VECTORP (CODING_ID_EOL_TYPE (coding->id)))
5387            + CONVERSION_BUFFER_EXTRA_ROOM);      {
5388  }        unsigned char *p = CHAR_POS_ADDR (coding->dst_pos);
5389          unsigned char *pend = p + coding->produced;
5390  /* Return maximum size (bytes) of a buffer enough for encoding        int eol_seen = EOL_SEEN_NONE;
    SRC_BYTES of text to CODING.  */  
5391    
5392  int        for (; p < pend; p++)
5393  encoding_buffer_size (coding, src_bytes)          {
5394       struct coding_system *coding;            if (*p == '\n')
5395       int src_bytes;              eol_seen |= EOL_SEEN_LF;
5396  {            else if (*p == '\r')
5397    int magnification;              {
5398                  if (p + 1 < pend && *(p + 1) == '\n')
5399                    {
5400                      eol_seen |= EOL_SEEN_CRLF;
5401                      p++;
5402                    }
5403                  else
5404                    eol_seen |= EOL_SEEN_CR;
5405                }
5406            }
5407          if (eol_seen != EOL_SEEN_NONE)
5408            adjust_coding_eol_type (coding, eol_seen);
5409        }
5410    
5411    if (coding->type == coding_type_ccl)    if (EQ (CODING_ID_EOL_TYPE (coding->id), Qmac))
5412      {      {
5413        magnification = coding->spec.ccl.encoder.buf_magnification;        unsigned char *p = CHAR_POS_ADDR (coding->dst_pos);
5414        if (coding->eol_type == CODING_EOL_CRLF)        unsigned char *pend = p + coding->produced;
5415          magnification *= 2;  
5416          for (; p < pend; p++)
5417            if (*p == '\r')
5418              *p = '\n';
5419      }      }
5420    else if (CODING_REQUIRE_ENCODING (coding))    else if (EQ (CODING_ID_EOL_TYPE (coding->id), Qdos))
5421      magnification = 3;      {
5422    else        unsigned char *p, *pbeg, *pend;
5423      magnification = 1;        Lisp_Object undo_list;
5424    
5425          move_gap_both (coding->dst_pos + coding->produced_char,
5426                         coding->dst_pos_byte + coding->produced);
5427          undo_list = current_buffer->undo_list;
5428          current_buffer->undo_list = Qt;
5429          del_range_2 (coding->dst_pos, coding->dst_pos_byte, GPT, GPT_BYTE, 0);
5430          current_buffer->undo_list = undo_list;
5431          pbeg = GPT_ADDR;
5432          pend = pbeg + coding->produced;
5433    
5434    return (src_bytes * magnification + CONVERSION_BUFFER_EXTRA_ROOM);        for (p = pend - 1; p >= pbeg; p--)
5435            if (*p == '\r')
5436              {
5437                safe_bcopy ((char *) (p + 1), (char *) p, pend - p - 1);
5438                pend--;
5439              }
5440          coding->produced_char -= coding->produced - (pend - pbeg);
5441          coding->produced = pend - pbeg;
5442          insert_from_gap (coding->produced_char, coding->produced);
5443        }
5444  }  }
5445    
5446  /* Working buffer for code conversion.  */  static void
5447  struct conversion_buffer  translate_chars (coding, table)
5448         struct coding_system *coding;
5449         Lisp_Object table;
5450  {  {
5451    int size;                     /* size of data.  */    int *charbuf = coding->charbuf;
5452    int on_stack;                 /* 1 if allocated by alloca.  */    int *charbuf_end = charbuf + coding->charbuf_used;
5453    unsigned char *data;    int c;
 };  
   
 /* Don't use alloca for allocating memory space larger than this, lest  
    we overflow their stack.  */  
 #define MAX_ALLOCA 16*1024  
5454    
5455  /* Allocate LEN bytes of memory for BUF (struct conversion_buffer).  */    if (coding->chars_at_source)
5456  #define allocate_conversion_buffer(buf, len)            \      return;
   do {                                                  \  
     if (len < MAX_ALLOCA)                               \  
       {                                                 \  
         buf.data = (unsigned char *) alloca (len);      \  
         buf.on_stack = 1;                               \  
       }                                                 \  
     else                                                \  
       {                                                 \  
         buf.data = (unsigned char *) xmalloc (len);     \  
         buf.on_stack = 0;                               \  
       }                                                 \  
     buf.size = len;                                     \  
   } while (0)  
5457    
5458  /* Double the allocated memory for *BUF.  */    while (charbuf < charbuf_end)
 static void  
 extend_conversion_buffer (buf)  
      struct conversion_buffer *buf;  
 {  
   if (buf->on_stack)  
     {  
       unsigned char *save = buf->data;  
       buf->data = (unsigned char *) xmalloc (buf->size * 2);  
       bcopy (save, buf->data, buf->size);  
       buf->on_stack = 0;  
     }  
   else  
5459      {      {
5460        buf->data = (unsigned char *) xrealloc (buf->data, buf->size * 2);        c = *charbuf;
5461          if (c < 0)
5462            charbuf += c;
5463          else
5464            *charbuf++ = translate_char (table, c);
5465      }      }
   buf->size *= 2;  
5466  }  }
5467    
5468  /* Free the allocated memory for BUF if it is not on stack.  */  static int
5469  static void  produce_chars (coding)
 free_conversion_buffer (buf)  
      struct conversion_buffer *buf;  
 {  
   if (!buf->on_stack)  
     xfree (buf->data);  
 }  
   
 int  
 ccl_coding_driver (coding, source, destination, src_bytes, dst_bytes, encodep)  
5470       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *source, *destination;  
      int src_bytes, dst_bytes, encodep;  
5471  {  {
5472    struct ccl_program *ccl    unsigned char *dst = coding->destination + coding->produced;
5473      = encodep ? &coding->spec.ccl.encoder : &coding->spec.ccl.decoder;    unsigned char *dst_end = coding->destination + coding->dst_bytes;
5474    unsigned char *dst = destination;    int produced;
5475      int produced_chars = 0;
5476    
5477    ccl->suppress_error = coding->suppress_error;    if (! coding->chars_at_source)
   ccl->last_block = coding->mode & CODING_MODE_LAST_BLOCK;  
   if (encodep)  
5478      {      {
5479        /* On encoding, EOL format is converted within ccl_driver.  For        /* Characters are in coding->charbuf.  */
5480           that, setup proper information in the structure CCL.  */        int *buf = coding->charbuf;
5481        ccl->eol_type = coding->eol_type;        int *buf_end = buf + coding->charbuf_used;
5482        if (ccl->eol_type ==CODING_EOL_UNDECIDED)        unsigned char *adjusted_dst_end;
         ccl->eol_type = CODING_EOL_LF;  
       ccl->cr_consumed = coding->spec.ccl.cr_carryover;  
       ccl->eight_bit_control = coding->dst_multibyte;  
     }  
   else  
     ccl->eight_bit_control = 1;  
   ccl->multibyte = coding->src_multibyte;  
   if (coding->spec.ccl.eight_bit_carryover[0] != 0)  
     {  
       /* Move carryover bytes to DESTINATION.  */  
       unsigned char *p = coding->spec.ccl.eight_bit_carryover;  
       while (*p)  
         *dst++ = *p++;  
       coding->spec.ccl.eight_bit_carryover[0] = 0;  
       if (dst_bytes)  
         dst_bytes -= dst - destination;  
     }  
   
   coding->produced = (ccl_driver (ccl, source, dst, src_bytes, dst_bytes,  
                                   &(coding->consumed))  
                       + dst - destination);  
5483    
5484    if (encodep)        if (BUFFERP (coding->src_object)
5485      {            && EQ (coding->src_object, coding->dst_object))
5486        coding->produced_char = coding->produced;          dst_end = ((unsigned char *) coding->source) + coding->consumed;
5487        coding->spec.ccl.cr_carryover = ccl->cr_consumed;        adjusted_dst_end = dst_end - MAX_MULTIBYTE_LENGTH;
     }  
   else if (!ccl->eight_bit_control)  
     {  
       /* The produced bytes forms a valid multibyte sequence. */  
       coding->produced_char  
         = multibyte_chars_in_text (destination, coding->produced);  
       coding->spec.ccl.eight_bit_carryover[0] = 0;  
     }  
   else  
     {  
       /* On decoding, the destination should always multibyte.  But,  
          CCL program might have been generated an invalid multibyte  
          sequence.  Here we make such a sequence valid as  
          multibyte.  */  
       int bytes  
         = dst_bytes ? dst_bytes : source + coding->consumed - destination;  
5488    
5489        if ((coding->consumed < src_bytes        while (buf < buf_end)
            || !ccl->last_block)  
           && coding->produced >= 1  
           && destination[coding->produced - 1] >= 0x80)  
5490          {          {
5491            /* We should not convert the tailing 8-bit codes to            int c = *buf++;
              multibyte form even if they doesn't form a valid  
              multibyte sequence.  They may form a valid sequence in  
              the next call.  */  
           int carryover = 0;  
5492    
5493            if (destination[coding->produced - 1] < 0xA0)            if (dst >= adjusted_dst_end)
             carryover = 1;  
           else if (coding->produced >= 2)  
5494              {              {
5495                if (destination[coding->produced - 2] >= 0x80)                dst = alloc_destination (coding,
5496                  {                                         buf_end - buf + MAX_MULTIBYTE_LENGTH,
5497                    if (destination[coding->produced - 2] < 0xA0)                                         dst);
5498                      carryover = 2;                dst_end = coding->destination + coding->dst_bytes;
5499                    else if (coding->produced >= 3                adjusted_dst_end = dst_end - MAX_MULTIBYTE_LENGTH;
                            && destination[coding->produced - 3] >= 0x80  
                            && destination[coding->produced - 3] < 0xA0)  
                     carryover = 3;  
                 }  
5500              }              }
5501            if (carryover > 0)            if (c >= 0)
5502              {              {
5503                BCOPY_SHORT (destination + coding->produced - carryover,                if (coding->dst_multibyte
5504                             coding->spec.ccl.eight_bit_carryover,                    || ! CHAR_BYTE8_P (c))
5505                             carryover);                  CHAR_STRING_ADVANCE (c, dst);
5506                coding->spec.ccl.eight_bit_carryover[carryover] = 0;                else
5507                coding->produced -= carryover;                  *dst++ = CHAR_TO_BYTE8 (c);
5508                  produced_chars++;
5509              }              }
5510              else
5511                /* This is an annotation datum.  (-C) is the length of
5512                   it.  */
5513                buf += -c - 1;
5514          }          }
       coding->produced = str_as_multibyte (destination, bytes,  
                                            coding->produced,  
                                            &(coding->produced_char));  
5515      }      }
5516      else
   switch (ccl->status)  
5517      {      {
5518      case CCL_STAT_SUSPEND_BY_SRC:        const unsigned char *src = coding->source;
5519        coding->result = CODING_FINISH_INSUFFICIENT_SRC;        const unsigned char *src_end = src + coding->src_bytes;
5520        break;        Lisp_Object eol_type;
     case CCL_STAT_SUSPEND_BY_DST:  
       coding->result = CODING_FINISH_INSUFFICIENT_DST;  
       break;  
     case CCL_STAT_QUIT:  
     case CCL_STAT_INVALID_CMD:  
       coding->result = CODING_FINISH_INTERRUPT;  
       break;  
     default:  
       coding->result = CODING_FINISH_NORMAL;  
       break;  
     }  
   return coding->result;  
 }  
5521    
5522  /* Decode EOL format of the text at PTR of BYTES length destructively        eol_type = CODING_ID_EOL_TYPE (coding->id);
    according to CODING->eol_type.  This is called after the CCL  
    program produced a decoded text at PTR.  If we do CRLF->LF  
    conversion, update CODING->produced and CODING->produced_char.  */  
5523    
5524  static void        if (coding->src_multibyte != coding->dst_multibyte)
5525  decode_eol_post_ccl (coding, ptr, bytes)          {
5526       struct coding_system *coding;            if (coding->src_multibyte)
5527       unsigned char *ptr;              {
5528       int bytes;                int multibytep = 1;
5529  {                int consumed_chars;
   Lisp_Object val, saved_coding_symbol;  
   unsigned char *pend = ptr + bytes;  
   int dummy;  
5530    
5531    /* Remember the current coding system symbol.  We set it back when                while (1)
5532       an inconsistent EOL is found so that `last-coding-system-used' is                  {
5533       set to the coding system that doesn't specify EOL conversion.  */                    const unsigned char *src_base = src;
5534    saved_coding_symbol = coding->symbol;                    int c;
5535    
5536    coding->spec.ccl.cr_carryover = 0;                    ONE_MORE_BYTE (c);
5537    if (coding->eol_type == CODING_EOL_UNDECIDED)                    if (c == '\r')
5538      {                      {
5539        /* Here, to avoid the call of setup_coding_system, we directly                        if (EQ (eol_type, Qdos))
5540           call detect_eol_type.  */                          {
5541        coding->eol_type = detect_eol_type (ptr, bytes, &dummy);                            if (src == src_end)
5542        if (coding->eol_type == CODING_EOL_INCONSISTENT)                              {
5543          coding->eol_type = CODING_EOL_LF;                                coding->result = CODING_RESULT_INSUFFICIENT_SRC;
5544        if (coding->eol_type != CODING_EOL_UNDECIDED)                                goto no_more_source;
5545          {                              }
5546            val = Fget (coding->symbol, Qeol_type);                            if (*src == '\n')
5547            if (VECTORP (val) && XVECTOR (val)->size == 3)                              c = *src++;
5548              coding->symbol = XVECTOR (val)->contents[coding->eol_type];                          }
5549          }                        else if (EQ (eol_type, Qmac))
5550        coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL;                          c = '\n';
5551      }                      }
5552                      if (dst == dst_end)
5553                        {
5554                          coding->consumed = src - coding->source;
5555    
5556    if (coding->eol_type == CODING_EOL_LF                      if (EQ (coding->src_object, coding->dst_object))
5557        || coding->eol_type == CODING_EOL_UNDECIDED)                        dst_end = (unsigned char *) src;
5558      {                      if (dst == dst_end)
5559        /* We have nothing to do.  */                        {
5560        ptr = pend;                          dst = alloc_destination (coding, src_end - src + 1,
5561      }                                                   dst);
5562    else if (coding->eol_type == CODING_EOL_CRLF)                          dst_end = coding->destination + coding->dst_bytes;
5563      {                          coding_set_source (coding);
5564        unsigned char *pstart = ptr, *p = ptr;                          src = coding->source + coding->consumed;
5565                            src_end = coding->source + coding->src_bytes;
5566                          }
5567                        }
5568                      *dst++ = c;
5569                      produced_chars++;
5570                    }
5571                no_more_source:
5572                  ;
5573                }
5574              else
5575                while (src < src_end)
5576                  {
5577                    int multibytep = 1;
5578                    int c = *src++;
5579    
5580        if (! (coding->mode & CODING_MODE_LAST_BLOCK)                  if (c == '\r')
5581            && *(pend - 1) == '\r')                    {
5582          {                      if (EQ (eol_type, Qdos))
5583            /* If the last character is CR, we can't handle it here                        {
5584               because LF will be in the not-yet-decoded source text.                          if (src < src_end
5585               Record that the CR is not yet processed.  */                              && *src == '\n')
5586            coding->spec.ccl.cr_carryover = 1;                            c = *src++;
5587            coding->produced--;                        }
5588            coding->produced_char--;                      else if (EQ (eol_type, Qmac))
5589            pend--;                        c = '\n';
5590                      }
5591                    if (dst >= dst_end - 1)
5592                      {
5593                        coding->consumed = src - coding->source;
5594    
5595                        if (EQ (coding->src_object, coding->dst_object))
5596                          dst_end = (unsigned char *) src;
5597                        if (dst >= dst_end - 1)
5598                          {
5599                            dst = alloc_destination (coding, src_end - src + 2,
5600                                                     dst);
5601                            dst_end = coding->destination + coding->dst_bytes;
5602                            coding_set_source (coding);
5603                            src = coding->source + coding->consumed;
5604                            src_end = coding->source + coding->src_bytes;
5605                          }
5606                      }
5607                    EMIT_ONE_BYTE (c);
5608                  }
5609          }          }
5610        while (ptr < pend)        else
5611          {          {
5612            if (*ptr == '\r')            if (!EQ (coding->src_object, coding->dst_object))
5613              {              {
5614                if (ptr + 1 < pend && *(ptr + 1) == '\n')                int require = coding->src_bytes - coding->dst_bytes;
5615                  {  
5616                    *p++ = '\n';                if (require > 0)
                   ptr += 2;  
                 }  
               else  
5617                  {                  {
5618                    if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)                    EMACS_INT offset = src - coding->source;
                     goto undo_eol_conversion;  
                   *p++ = *ptr++;  
                 }  
             }  
           else if (*ptr == '\n'  
                    && coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)  
             goto undo_eol_conversion;  
           else  
             *p++ = *ptr++;  
           continue;  
5619    
5620          undo_eol_conversion:                    dst = alloc_destination (coding, require, dst);
5621            /* We have faced with inconsistent EOL format at PTR.                    coding_set_source (coding);
5622               Convert all LFs before PTR back to CRLFs.  */                    src = coding->source + offset;
5623            for (p--, ptr--; p >= pstart; p--)                    src_end = coding->source + coding->src_bytes;
5624              {                  }
               if (*p == '\n')  
                 *ptr-- = '\n', *ptr-- = '\r';  
               else  
                 *ptr-- = *p;  
5625              }              }
5626            /*  If carryover is recorded, cancel it because we don't            produced_chars = coding->src_chars;
5627                convert CRLF anymore.  */            while (src < src_end)
           if (coding->spec.ccl.cr_carryover)  
5628              {              {
5629                coding->spec.ccl.cr_carryover = 0;                int c = *src++;
               coding->produced++;  
               coding->produced_char++;  
               pend++;  
             }  
           p = ptr = pend;  
           coding->eol_type = CODING_EOL_LF;  
           coding->symbol = saved_coding_symbol;  
         }  
       if (p < pend)  
         {  
           /* As each two-byte sequence CRLF was converted to LF, (PEND  
              - P) is the number of deleted characters.  */  
           coding->produced -= pend - p;  
           coding->produced_char -= pend - p;  
         }  
     }  
   else                  /* i.e. coding->eol_type == CODING_EOL_CR */  
     {  
       unsigned char *p = ptr;  
5630    
5631        for (; ptr < pend; ptr++)                if (c == '\r')
         {  
           if (*ptr == '\r')  
             *ptr = '\n';  
           else if (*ptr == '\n'  
                    && coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)  
             {  
               for (; p < ptr; p++)  
5632                  {                  {
5633                    if (*p == '\n')                    if (EQ (eol_type, Qdos))
5634                      *p = '\r';                      {
5635                          if (src < src_end
5636                              && *src == '\n')
5637                            c = *src++;
5638                          produced_chars--;
5639                        }
5640                      else if (EQ (eol_type, Qmac))
5641                        c = '\n';
5642                  }                  }
5643                ptr = pend;                *dst++ = c;
               coding->eol_type = CODING_EOL_LF;  
               coding->symbol = saved_coding_symbol;  
5644              }              }
5645          }          }
5646          coding->consumed = coding->src_bytes;
5647          coding->consumed_char = coding->src_chars;
5648      }      }
5649    
5650      produced = dst - (coding->destination + coding->produced);
5651      if (BUFFERP (coding->dst_object))
5652        insert_from_gap (produced_chars, produced);
5653      coding->produced += produced;
5654      coding->produced_char += produced_chars;
5655      return produced_chars;
5656  }  }
5657    
5658  /* See "GENERAL NOTES about `decode_coding_XXX ()' functions".  Before  /* Compose text in CODING->object according to the annotation data at
5659     decoding, it may detect coding system and format of end-of-line if     CHARBUF.  CHARBUF is an array:
5660     those are not yet decided.  The source should be unibyte, the       [ -LENGTH ANNOTATION_MASK FROM TO METHOD COMP_LEN [ COMPONENTS... ] ]
5661     result is multibyte if CODING->dst_multibyte is nonzero, else   */
    unibyte.  */  
5662    
5663  int  static INLINE void
5664  decode_coding (coding, source, destination, src_bytes, dst_bytes)  produce_composition (coding, charbuf)
5665       struct coding_system *coding;       struct coding_system *coding;
5666       const unsigned char *source;       int *charbuf;
      unsigned char *destination;  
      int src_bytes, dst_bytes;  
5667  {  {
5668    int extra = 0;    int len;
5669      EMACS_INT from, to;
5670    if (coding->type == coding_type_undecided)    enum composition_method method;
5671      detect_coding (coding, source, src_bytes);    Lisp_Object components;
5672    
5673      len = -charbuf[0];
5674      from = coding->dst_pos + charbuf[2];
5675      to = coding->dst_pos + charbuf[3];
5676      method = (enum composition_method) (charbuf[4]);
5677    
5678    if (coding->eol_type == CODING_EOL_UNDECIDED    if (method == COMPOSITION_RELATIVE)
5679        && coding->type != coding_type_ccl)      components = Qnil;
5680      else
5681      {      {
5682        detect_eol (coding, source, src_bytes);        Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1];
5683        /* We had better recover the original eol format if we        int i;
5684           encounter an inconsistent eol format while decoding.  */  
5685        coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL;        len -= 5;
5686          charbuf += 5;
5687          for (i = 0; i < len; i++)
5688            args[i] = make_number (charbuf[i]);
5689          components = (method == COMPOSITION_WITH_ALTCHARS
5690                        ? Fstring (len, args) : Fvector (len, args));
5691      }      }
5692      compose_text (from, to, components, Qnil, coding->dst_object);
5693    }
5694    
   coding->produced = coding->produced_char = 0;  
   coding->consumed = coding->consumed_char = 0;  
   coding->errors = 0;  
   coding->result = CODING_FINISH_NORMAL;  
5695    
5696    switch (coding->type)  /* Put `charset' property on text in CODING->object according to
5697      {     the annotation data at CHARBUF.  CHARBUF is an array:
5698      case coding_type_sjis:       [ -LENGTH ANNOTATION_MASK FROM TO CHARSET-ID ]
5699        decode_coding_sjis_big5 (coding, source, destination,   */
                                src_bytes, dst_bytes, 1);  
       break;  
5700    
5701      case coding_type_iso2022:  static INLINE void
5702        decode_coding_iso2022 (coding, source, destination,  produce_charset (coding, charbuf)
5703                               src_bytes, dst_bytes);       struct coding_system *coding;
5704        break;       int *charbuf;
5705    {
5706      EMACS_INT from = coding->dst_pos + charbuf[2];
5707      EMACS_INT to = coding->dst_pos + charbuf[3];
5708      struct charset *charset = CHARSET_FROM_ID (charbuf[4]);
5709    
5710      case coding_type_big5:    Fput_text_property (make_number (from), make_number (to),
5711        decode_coding_sjis_big5 (coding, source, destination,                        Qcharset, CHARSET_NAME (charset),
5712                                 src_bytes, dst_bytes, 0);                        coding->dst_object);
5713        break;  }
5714    
     case coding_type_emacs_mule:  
       decode_coding_emacs_mule (coding, source, destination,  
                                 src_bytes, dst_bytes);  
       break;  
5715    
5716      case coding_type_ccl:  #define CHARBUF_SIZE 0x4000
       if (coding->spec.ccl.cr_carryover)  
         {  
           /* Put the CR which was not processed by the previous call  
              of decode_eol_post_ccl in DESTINATION.  It will be  
              decoded together with the following LF by the call to  
              decode_eol_post_ccl below.  */  
           *destination = '\r';  
           coding->produced++;  
           coding->produced_char++;  
           dst_bytes--;  
           extra = coding->spec.ccl.cr_carryover;  
         }  
       ccl_coding_driver (coding, source, destination + extra,  
                          src_bytes, dst_bytes, 0);  
       if (coding->eol_type != CODING_EOL_LF)  
         {  
           coding->produced += extra;  
           coding->produced_char += extra;  
           decode_eol_post_ccl (coding, destination, coding->produced);  
         }  
       break;  
5717    
5718      default:  #define ALLOC_CONVERSION_WORK_AREA(coding)                              \
5719        decode_eol (coding, source, destination, src_bytes, dst_bytes);    do {                                                                  \
5720      }      int size = CHARBUF_SIZE;;                                           \
5721                                                                            \
5722        coding->charbuf = NULL;                                             \
5723        while (size > 1024)                                                 \
5724          {                                                                 \
5725            coding->charbuf = (int *) alloca (sizeof (int) * size);         \
5726            if (coding->charbuf)                                            \
5727              break;                                                        \
5728            size >>= 1;                                                     \
5729          }                                                                 \
5730        if (! coding->charbuf)                                              \
5731          {                                                                 \
5732            coding->result = CODING_RESULT_INSUFFICIENT_MEM;                \
5733            return coding->result;                                          \
5734          }                                                                 \
5735        coding->charbuf_size = size;                                        \
5736      } while (0)
5737    
   if (coding->result == CODING_FINISH_INSUFFICIENT_SRC  
       && coding->mode & CODING_MODE_LAST_BLOCK  
       && coding->consumed == src_bytes)  
     coding->result = CODING_FINISH_NORMAL;  
5738    
5739    if (coding->mode & CODING_MODE_LAST_BLOCK  static void
5740        && coding->result == CODING_FINISH_INSUFFICIENT_SRC)  produce_annotation (coding)
5741      {       struct coding_system *coding;
5742        const unsigned char *src = source + coding->consumed;  {
5743        unsigned char *dst = destination + coding->produced;    int *charbuf = coding->charbuf;
5744      int *charbuf_end = charbuf + coding->charbuf_used;
5745    
5746        src_bytes -= coding->consumed;    if (NILP (coding->dst_object))
5747        coding->errors++;      return;
5748        if (COMPOSING_P (coding))  
5749          DECODE_COMPOSITION_END ('1');    while (charbuf < charbuf_end)
5750        while (src_bytes--)      {
5751          if (*charbuf >= 0)
5752            charbuf++;
5753          else
5754          {          {
5755            int c = *src++;            int len = -*charbuf;
5756            dst += CHAR_STRING (c, dst);            switch (charbuf[1])
5757            coding->produced_char++;              {
5758                case CODING_ANNOTATE_COMPOSITION_MASK:
5759                  produce_composition (coding, charbuf);
5760                  break;
5761                case CODING_ANNOTATE_CHARSET_MASK:
5762                  produce_charset (coding, charbuf);
5763                  break;
5764                default:
5765                  abort ();
5766                }
5767              charbuf += len;
5768          }          }
       coding->consumed = coding->consumed_char = src - source;  
       coding->produced = dst - destination;  
       coding->result = CODING_FINISH_NORMAL;  
5769      }      }
5770    }
5771    
5772    if (!coding->dst_multibyte)  /* Decode the data at CODING->src_object into CODING->dst_object.
5773      {     CODING->src_object is a buffer, a string, or nil.
5774        coding->produced = str_as_unibyte (destination, coding->produced);     CODING->dst_object is a buffer.
       coding->produced_char = coding->produced;  
     }  
5775    
5776    return coding->result;     If CODING->src_object is a buffer, it must be the current buffer.
5777  }     In this case, if CODING->src_pos is positive, it is a position of
5778       the source text in the buffer, otherwise, the source text is in the
5779       gap area of the buffer, and CODING->src_pos specifies the offset of
5780       the text from GPT (which must be the same as PT).  If this is the
5781       same buffer as CODING->dst_object, CODING->src_pos must be
5782       negative.
5783    
5784  /* See "GENERAL NOTES about `encode_coding_XXX ()' functions".  The     If CODING->src_object is a string, CODING->src_pos in an index to
5785     multibyteness of the source is CODING->src_multibyte, the     that string.
    multibyteness of the result is always unibyte.  */  
5786    
5787  int     If CODING->src_object is nil, CODING->source must already point to
5788  encode_coding (coding, source, destination, src_bytes, dst_bytes)     the non-relocatable memory area.  In this case, CODING->src_pos is
5789       struct coding_system *coding;     an offset from CODING->source.
      const unsigned char *source;  
      unsigned char *destination;  
      int src_bytes, dst_bytes;  
 {  
   coding->produced = coding->produced_char = 0;  
   coding->consumed = coding->consumed_char = 0;  
   coding->errors = 0;  
   coding->result = CODING_FINISH_NORMAL;  
5790    
5791    switch (coding->type)     The decoded data is inserted at the current point of the buffer
5792      {     CODING->dst_object.
5793      case coding_type_sjis:  */
       encode_coding_sjis_big5 (coding, source, destination,  
                                src_bytes, dst_bytes, 1);  
       break;  
5794    
5795      case coding_type_iso2022:  static int
5796        encode_coding_iso2022 (coding, source, destination,  decode_coding (coding)
5797                               src_bytes, dst_bytes);       struct coding_system *coding;
5798        break;  {
5799      Lisp_Object attrs;
5800    
5801      case coding_type_big5:    if (BUFFERP (coding->src_object)
5802        encode_coding_sjis_big5 (coding, source, destination,        && coding->src_pos > 0
5803                                 src_bytes, dst_bytes, 0);        && coding->src_pos < GPT
5804        break;        && coding->src_pos + coding->src_chars > GPT)
5805        move_gap_both (coding->src_pos, coding->src_pos_byte);
5806    
5807      if (BUFFERP (coding->dst_object))
5808        {
5809          if (current_buffer != XBUFFER (coding->dst_object))
5810            set_buffer_internal (XBUFFER (coding->dst_object));
5811          if (GPT != PT)
5812            move_gap_both (PT, PT_BYTE);
5813        }
5814    
5815      case coding_type_emacs_mule:    coding->consumed = coding->consumed_char = 0;
5816        encode_coding_emacs_mule (coding, source, destination,    coding->produced = coding->produced_char = 0;
5817                                  src_bytes, dst_bytes);    coding->chars_at_source = 0;
5818        break;    coding->result = CODING_RESULT_SUCCESS;
5819      coding->errors = 0;
5820    
5821      case coding_type_ccl:    ALLOC_CONVERSION_WORK_AREA (coding);
       ccl_coding_driver (coding, source, destination,  
                          src_bytes, dst_bytes, 1);  
       break;  
5822    
5823      default:    attrs = CODING_ID_ATTRS (coding->id);
       encode_eol (coding, source, destination, src_bytes, dst_bytes);  
     }  
5824    
5825    if (coding->mode & CODING_MODE_LAST_BLOCK    do
       && coding->result == CODING_FINISH_INSUFFICIENT_SRC)  
5826      {      {
5827        const unsigned char *src = source + coding->consumed;        coding_set_source (coding);
5828        unsigned char *dst = destination + coding->produced;        coding->annotated = 0;
5829          (*(coding->decoder)) (coding);
5830          if (!NILP (CODING_ATTR_DECODE_TBL (attrs)))
5831            translate_chars (coding, CODING_ATTR_DECODE_TBL (attrs));
5832          else if (!NILP (Vstandard_translation_table_for_decode))
5833            translate_chars (coding, Vstandard_translation_table_for_decode);
5834          coding_set_destination (coding);
5835          produce_chars (coding);
5836          if (coding->annotated)
5837            produce_annotation (coding);
5838        }
5839      while (coding->consumed < coding->src_bytes
5840             && ! coding->result);
5841    
5842      if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qccl)
5843          && SYMBOLP (CODING_ID_EOL_TYPE (coding->id))
5844          && ! EQ (CODING_ID_EOL_TYPE (coding->id), Qunix))
5845        decode_eol (coding);
5846    
5847      coding->carryover_bytes = 0;
5848      if (coding->consumed < coding->src_bytes)
5849        {
5850          int nbytes = coding->src_bytes - coding->consumed;
5851          const unsigned char *src;
5852    
5853          coding_set_source (coding);
5854          coding_set_destination (coding);
5855          src = coding->source + coding->consumed;
5856    
5857          if (coding->mode & CODING_MODE_LAST_BLOCK)
5858            {
5859              /* Flush out unprocessed data as binary chars.  We are sure
5860                 that the number of data is less than the size of
5861                 coding->charbuf.  */
5862              while (nbytes-- > 0)
5863                {
5864                  int c = *src++;
5865    
5866        if (coding->type == coding_type_iso2022)                coding->charbuf[coding->charbuf_used++] = (c & 0x80 ? - c : c);
5867          ENCODE_RESET_PLANE_AND_REGISTER;              }
5868        if (COMPOSING_P (coding))            produce_chars (coding);
5869          *dst++ = ISO_CODE_ESC, *dst++ = '1';          }
5870        if (coding->consumed < src_bytes)        else
5871          {          {
5872            int len = src_bytes - coding->consumed;            /* Record unprocessed bytes in coding->carryover.  We are
5873                 sure that the number of data is less than the size of
5874            BCOPY_SHORT (src, dst, len);               coding->carryover.  */
5875            if (coding->src_multibyte)            unsigned char *p = coding->carryover;
5876              len = str_as_unibyte (dst, len);  
5877            dst += len;            coding->carryover_bytes = nbytes;
5878            coding->consumed = src_bytes;            while (nbytes-- > 0)
5879                *p++ = *src++;
5880          }          }
5881        coding->produced = coding->produced_char = dst - destination;        coding->consumed = coding->src_bytes;
       coding->result = CODING_FINISH_NORMAL;  
5882      }      }
5883    
   if (coding->result == CODING_FINISH_INSUFFICIENT_SRC  
       && coding->consumed == src_bytes)  
     coding->result = CODING_FINISH_NORMAL;  
   
5884    return coding->result;    return coding->result;
5885  }  }
5886    
 /* Scan text in the region between *BEG and *END (byte positions),  
    skip characters which we don't have to decode by coding system  
    CODING at the head and tail, then set *BEG and *END to the region  
    of the text we actually have to convert.  The caller should move  
    the gap out of the region in advance if the region is from a  
    buffer.  
5887    
5888     If STR is not NULL, *BEG and *END are indices into STR.  */  /* Extract an annotation datum from a composition starting at POS and
5889       ending before LIMIT of CODING->src_object (buffer or string), store
5890  static void     the data in BUF, set *STOP to a starting position of the next
5891  shrink_decoding_region (beg, end, coding, str)     composition (if any) or to LIMIT, and return the address of the
5892       int *beg, *end;     next element of BUF.
5893    
5894       If such an annotation is not found, set *STOP to a starting
5895       position of a composition after POS (if any) or to LIMIT, and
5896       return BUF.  */
5897    
5898    static INLINE int *
5899    handle_composition_annotation (pos, limit, coding, buf, stop)
5900         EMACS_INT pos, limit;
5901       struct coding_system *coding;       struct coding_system *coding;
5902       unsigned char *str;       int *buf;
5903         EMACS_INT *stop;
5904  {  {
5905    unsigned char *begp_orig, *begp, *endp_orig, *endp, c;    EMACS_INT start, end;
5906    int eol_conversion;    Lisp_Object prop;
   Lisp_Object translation_table;  
   
   if (coding->type == coding_type_ccl  
       || coding->type == coding_type_undecided  
       || coding->eol_type != CODING_EOL_LF  
       || !NILP (coding->post_read_conversion)  
       || coding->composing != COMPOSITION_DISABLED)  
     {  
       /* We can't skip any data.  */  
       return;  
     }  
   if (coding->type == coding_type_no_conversion  
       || coding->type == coding_type_raw_text  
       || coding->type == coding_type_emacs_mule)  
     {  
       /* We need no conversion, but don't have to skip any data here.  
          Decoding routine handles them effectively anyway.  */  
       return;  
     }  
   
   translation_table = coding->translation_table_for_decode;  
   if (NILP (translation_table) && !NILP (Venable_character_translation))  
     translation_table = Vstandard_translation_table_for_decode;  
   if (CHAR_TABLE_P (translation_table))  
     {  
       int i;  
       for (i = 0; i < 128; i++)  
         if (!NILP (CHAR_TABLE_REF (translation_table, i)))  
           break;  
       if (i < 128)  
         /* Some ASCII character should be translated.  We give up  
            shrinking.  */  
         return;  
     }  
   
   if (coding->heading_ascii >= 0)  
     /* Detection routine has already found how much we can skip at the  
        head.  */  
     *beg += coding->heading_ascii;  
5907    
5908    if (str)    if (! find_composition (pos, limit, &start, &end, &prop, coding->src_object)
5909      {        || end > limit)
5910        begp_orig = begp = str + *beg;      *stop = limit;
5911        endp_orig = endp = str + *end;    else if (start > pos)
5912      }      *stop = start;
5913    else    else
5914      {      {
5915        begp_orig = begp = BYTE_POS_ADDR (*beg);        if (start == pos)
       endp_orig = endp = begp + *end - *beg;  
     }  
   
   eol_conversion = (coding->eol_type == CODING_EOL_CR  
                     || coding->eol_type == CODING_EOL_CRLF);  
   
   switch (coding->type)  
     {  
     case coding_type_sjis:  
     case coding_type_big5:  
       /* We can skip all ASCII characters at the head.  */  
       if (coding->heading_ascii < 0)  
5916          {          {
5917            if (eol_conversion)            /* We found a composition.  Store the corresponding
5918              while (begp < endp && *begp < 0x80 && *begp != '\r') begp++;               annotation data in BUF.  */
5919            else            int *head = buf;
5920              while (begp < endp && *begp < 0x80) begp++;            enum composition_method method = COMPOSITION_METHOD (prop);
5921          }            int nchars = COMPOSITION_LENGTH (prop);
       /* We can skip all ASCII characters at the tail except for the  
          second byte of SJIS or BIG5 code.  */  
       if (eol_conversion)  
         while (begp < endp && endp[-1] < 0x80 && endp[-1] != '\r') endp--;  
       else  
         while (begp < endp && endp[-1] < 0x80) endp--;  
       /* Do not consider LF as ascii if preceded by CR, since that  
          confuses eol decoding. */  
       if (begp < endp && endp < endp_orig && endp[-1] == '\r' && endp[0] == '\n')  
         endp++;  
       if (begp < endp && endp < endp_orig && endp[-1] >= 0x80)  
         endp++;  
       break;  
5922    
5923      case coding_type_iso2022:            ADD_COMPOSITION_DATA (buf, 0, nchars, method);
5924        if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, 0) != CHARSET_ASCII)            if (method != COMPOSITION_RELATIVE)
5925          /* We can't skip any data.  */              {
5926          break;                Lisp_Object components;
5927        if (coding->heading_ascii < 0)                int len, i, i_byte;
         {  
           /* We can skip all ASCII characters at the head except for a  
              few control codes.  */  
           while (begp < endp && (c = *begp) < 0x80  
                  && c != ISO_CODE_CR && c != ISO_CODE_SO  
                  && c != ISO_CODE_SI && c != ISO_CODE_ESC  
                  && (!eol_conversion || c != ISO_CODE_LF))  
             begp++;  
         }  
       switch (coding->category_idx)  
         {  
         case CODING_CATEGORY_IDX_ISO_8_1:  
         case CODING_CATEGORY_IDX_ISO_8_2:  
           /* We can skip all ASCII characters at the tail.  */  
           if (eol_conversion)  
             while (begp < endp && (c = endp[-1]) < 0x80 && c != '\r') endp--;  
           else  
             while (begp < endp && endp[-1] < 0x80) endp--;  
           /* Do not consider LF as ascii if preceded by CR, since that  
              confuses eol decoding. */  
           if (begp < endp && endp < endp_orig && endp[-1] == '\r' && endp[0] == '\n')  
             endp++;  
           break;  
5928    
5929          case CODING_CATEGORY_IDX_ISO_7:                components = COMPOSITION_COMPONENTS (prop);
5930          case CODING_CATEGORY_IDX_ISO_7_TIGHT:                if (VECTORP (components))
           {  
             /* We can skip all characters at the tail except for 8-bit  
                codes and ESC and the following 2-byte at the tail.  */  
             unsigned char *eight_bit = NULL;  
   
             if (eol_conversion)  
               while (begp < endp  
                      && (c = endp[-1]) != ISO_CODE_ESC && c != '\r')  
5931                  {                  {
5932                    if (!eight_bit && c & 0x80) eight_bit = endp;                    len = XVECTOR (components)->size;
5933                    endp--;                    for (i = 0; i < len; i++)
5934                        *buf++ = XINT (AREF (components, i));
5935                  }                  }
5936              else                else if (STRINGP (components))
               while (begp < endp  
                      && (c = endp[-1]) != ISO_CODE_ESC)  
5937                  {                  {
5938                    if (!eight_bit && c & 0x80) eight_bit = endp;                    len = SCHARS (components);
5939                    endp--;                    i = i_byte = 0;
5940                      while (i < len)
5941                        {
5942                          FETCH_STRING_CHAR_ADVANCE (*buf, components, i, i_byte);
5943                          buf++;
5944                        }
5945                  }                  }
5946              /* Do not consider LF as ascii if preceded by CR, since that                else if (INTEGERP (components))
5947                 confuses eol decoding. */                  {
5948              if (begp < endp && endp < endp_orig                    len = 1;
5949                  && endp[-1] == '\r' && endp[0] == '\n')                    *buf++ = XINT (components);
5950                endp++;                  }
5951              if (begp < endp && endp[-1] == ISO_CODE_ESC)                else if (CONSP (components))
5952                {                  {
5953                  if (endp + 1 < endp_orig && end[0] == '(' && end[1] == 'B')                    for (len = 0; CONSP (components);
5954                    /* This is an ASCII designation sequence.  We can                         len++, components = XCDR (components))
5955                       surely skip the tail.  But, if we have                      *buf++ = XINT (XCAR (components));
5956                       encountered an 8-bit code, skip only the codes                  }
5957                       after that.  */                else
5958                    endp = eight_bit ? eight_bit : endp + 2;                  abort ();
5959                  else                *head -= len;
5960                    /* Hmmm, we can't skip the tail.  */              }
                   endp = endp_orig;  
               }  
             else if (eight_bit)  
               endp = eight_bit;  
           }  
5961          }          }
       break;  
5962    
5963      default:        if (find_composition (end, limit, &start, &end, &prop,
5964        abort ();                              coding->src_object)
5965              && end <= limit)
5966            *stop = start;
5967          else
5968            *stop = limit;
5969      }      }
5970    *beg += begp - begp_orig;    return buf;
5971    *end += endp - endp_orig;  }
5972    return;  
5973    
5974    /* Extract an annotation datum from a text property `charset' at POS of
5975       CODING->src_object (buffer of string), store the data in BUF, set
5976       *STOP to the position where the value of `charset' property changes
5977       (limiting by LIMIT), and return the address of the next element of
5978       BUF.
5979    
5980       If the property value is nil, set *STOP to the position where the
5981       property value is non-nil (limiting by LIMIT), and return BUF.  */
5982    
5983    static INLINE int *
5984    handle_charset_annotation (pos, limit, coding, buf, stop)
5985         EMACS_INT pos, limit;
5986         struct coding_system *coding;
5987         int *buf;
5988         EMACS_INT *stop;
5989    {
5990      Lisp_Object val, next;
5991      int id;
5992    
5993      val = Fget_text_property (make_number (pos), Qcharset, coding->src_object);
5994      if (! NILP (val) && CHARSETP (val))
5995        id = XINT (CHARSET_SYMBOL_ID (val));
5996      else
5997        id = -1;
5998      ADD_CHARSET_DATA (buf, 0, 0, id);
5999      next = Fnext_single_property_change (make_number (pos), Qcharset,
6000                                           coding->src_object,
6001                                           make_number (limit));
6002      *stop = XINT (next);
6003      return buf;
6004  }  }
6005    
 /* Like shrink_decoding_region but for encoding.  */  
6006    
6007  static void  static void
6008  shrink_encoding_region (beg, end, coding, str)  consume_chars (coding)
      int *beg, *end;  
6009       struct coding_system *coding;       struct coding_system *coding;
      unsigned char *str;  
6010  {  {
6011    unsigned char *begp_orig, *begp, *endp_orig, *endp;    int *buf = coding->charbuf;
6012    int eol_conversion;    int *buf_end = coding->charbuf + coding->charbuf_size;
6013    Lisp_Object translation_table;    const unsigned char *src = coding->source + coding->consumed;
6014      const unsigned char *src_end = coding->source + coding->src_bytes;
6015      EMACS_INT pos = coding->src_pos + coding->consumed_char;
6016      EMACS_INT end_pos = coding->src_pos + coding->src_chars;
6017      int multibytep = coding->src_multibyte;
6018      Lisp_Object eol_type;
6019      int c;
6020      EMACS_INT stop, stop_composition, stop_charset;
6021    
6022    if (coding->type == coding_type_ccl    eol_type = CODING_ID_EOL_TYPE (coding->id);
6023        || coding->eol_type == CODING_EOL_CRLF    if (VECTORP (eol_type))
6024        || coding->eol_type == CODING_EOL_CR      eol_type = Qunix;
       || (coding->cmp_data && coding->cmp_data->used > 0))  
     {  
       /* We can't skip any data.  */  
       return;  
     }  
   if (coding->type == coding_type_no_conversion  
       || coding->type == coding_type_raw_text  
       || coding->type == coding_type_emacs_mule  
       || coding->type == coding_type_undecided)  
     {  
       /* We need no conversion, but don't have to skip any data here.  
          Encoding routine handles them effectively anyway.  */  
       return;  
     }  
6025    
6026    translation_table = coding->translation_table_for_encode;    /* Note: composition handling is not yet implemented.  */
6027    if (NILP (translation_table) && !NILP (Venable_character_translation))    coding->common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
     translation_table = Vstandard_translation_table_for_encode;  
   if (CHAR_TABLE_P (translation_table))  
     {  
       int i;  
       for (i = 0; i < 128; i++)  
         if (!NILP (CHAR_TABLE_REF (translation_table, i)))  
           break;  
       if (i < 128)  
         /* Some ASCII character should be translated.  We give up  
            shrinking.  */  
         return;  
     }  
6028    
6029    if (str)    if (coding->common_flags & CODING_ANNOTATE_COMPOSITION_MASK)
6030      {      stop = stop_composition = pos;
       begp_orig = begp = str + *beg;  
       endp_orig = endp = str + *end;  
     }  
6031    else    else
6032      {      stop = stop_composition = end_pos;
6033        begp_orig = begp = BYTE_POS_ADDR (*beg);    if (coding->common_flags & CODING_ANNOTATE_CHARSET_MASK)
6034        endp_orig = endp = begp + *end - *beg;      stop = stop_charset = pos;
6035      }    else
6036        stop_charset = end_pos;
   eol_conversion = (coding->eol_type == CODING_EOL_CR  
                     || coding->eol_type == CODING_EOL_CRLF);  
6037    
6038    /* Here, we don't have to check coding->pre_write_conversion because    /* Compensate for CRLF and annotation.  */
6039       the caller is expected to have handled it already.  */    buf_end -= 1 + MAX_ANNOTATION_LENGTH;
6040    switch (coding->type)    while (buf < buf_end)
6041      {      {
6042      case coding_type_iso2022:        if (pos == stop)
6043        if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, 0) != CHARSET_ASCII)          {
6044          /* We can't skip any data.  */            if (pos == end_pos)
6045          break;              break;
6046        if (coding->flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL)            if (pos == stop_composition)
6047                buf = handle_composition_annotation (pos, end_pos, coding,
6048                                                     buf, &stop_composition);
6049              if (pos == stop_charset)
6050                buf = handle_charset_annotation (pos, end_pos, coding,
6051                                                 buf, &stop_charset);
6052              stop = (stop_composition < stop_charset
6053                      ? stop_composition : stop_charset);
6054            }
6055    
6056          if (! multibytep)
6057            {
6058              EMACS_INT bytes;
6059    
6060              if (! CODING_FOR_UNIBYTE (coding)
6061                  && (bytes = MULTIBYTE_LENGTH (src, src_end)) > 0)
6062                c = STRING_CHAR_ADVANCE (src), pos += bytes;
6063              else
6064                c = *src++, pos++;
6065            }
6066          else
6067            c = STRING_CHAR_ADVANCE (src), pos++;
6068          if ((c == '\r') && (coding->mode & CODING_MODE_SELECTIVE_DISPLAY))
6069            c = '\n';
6070          if (! EQ (eol_type, Qunix))
6071          {          {
6072            unsigned char *bol = begp;            if (c == '\n')
           while (begp < endp && *begp < 0x80)  
6073              {              {
6074                begp++;                if (EQ (eol_type, Qdos))
6075                if (begp[-1] == '\n')                  *buf++ = '\r';
6076                  bol = begp;                else
6077                    c = '\r';
6078              }              }
           begp = bol;  
           goto label_skip_tail;  
6079          }          }
6080        /* fall down ... */        *buf++ = c;
   
     case coding_type_sjis:  
     case coding_type_big5:  
       /* We can skip all ASCII characters at the head and tail.  */  
       if (eol_conversion)  
         while (begp < endp && *begp < 0x80 && *begp != '\n') begp++;  
       else  
         while (begp < endp && *begp < 0x80) begp++;  
     label_skip_tail:  
       if (eol_conversion)  
         while (begp < endp && endp[-1] < 0x80 && endp[-1] != '\n') endp--;  
       else  
         while (begp < endp && *(endp - 1) < 0x80) endp--;  
       break;  
   
     default:  
       abort ();  
6081      }      }
6082    
6083    *beg += begp - begp_orig;    coding->consumed = src - coding->source;
6084    *end += endp - endp_orig;    coding->consumed_char = pos - coding->src_pos;
6085    return;    coding->charbuf_used = buf - coding->charbuf;
6086      coding->chars_at_source = 0;
6087  }  }
6088    
 /* As shrinking conversion region requires some overhead, we don't try  
    shrinking if the length of conversion region is less than this  
    value.  */  
 static int shrink_conversion_region_threshhold = 1024;  
6089    
6090  #define SHRINK_CONVERSION_REGION(beg, end, coding, str, encodep)        \  /* Encode the text at CODING->src_object into CODING->dst_object.
6091    do {                                                                  \     CODING->src_object is a buffer or a string.
6092      if (*(end) - *(beg) > shrink_conversion_region_threshhold)          \     CODING->dst_object is a buffer or nil.
       {                                                                 \  
         if (encodep) shrink_encoding_region (beg, end, coding, str);    \  
         else shrink_decoding_region (beg, end, coding, str);            \  
       }                                                                 \  
   } while (0)  
6093    
6094  static Lisp_Object     If CODING->src_object is a buffer, it must be the current buffer.
6095  code_convert_region_unwind (arg)     In this case, if CODING->src_pos is positive, it is a position of
6096       Lisp_Object arg;     the source text in the buffer, otherwise. the source text is in the
6097  {     gap area of the buffer, and coding->src_pos specifies the offset of
6098    inhibit_pre_post_conversion = 0;     the text from GPT (which must be the same as PT).  If this is the
6099    Vlast_coding_system_used = arg;     same buffer as CODING->dst_object, CODING->src_pos must be
6100    return Qnil;     negative and CODING should not have `pre-write-conversion'.
 }  
6101    
6102  /* Store information about all compositions in the range FROM and TO     If CODING->src_object is a string, CODING should not have
6103     of OBJ in memory blocks pointed by CODING->cmp_data.  OBJ is a     `pre-write-conversion'.
    buffer or a string, defaults to the current buffer.  */  
6104    
6105  void     If CODING->dst_object is a buffer, the encoded data is inserted at
6106  coding_save_composition (coding, from, to, obj)     the current point of that buffer.
6107    
6108       If CODING->dst_object is nil, the encoded data is placed at the
6109       memory area specified by CODING->destination.  */
6110    
6111    static int
6112    encode_coding (coding)
6113       struct coding_system *coding;       struct coding_system *coding;
      int from, to;  
      Lisp_Object obj;  
6114  {  {
6115    Lisp_Object prop;    Lisp_Object attrs;
   int start, end;  
6116    
6117    if (coding->composing == COMPOSITION_DISABLED)    attrs = CODING_ID_ATTRS (coding->id);
     return;  
   if (!coding->cmp_data)  
     coding_allocate_composition_data (coding, from);  
   if (!find_composition (from, to, &start, &end, &prop, obj)  
       || end > to)  
     return;  
   if (start < from  
       && (!find_composition (end, to, &start, &end, &prop, obj)  
           || end > to))  
     return;  
   coding->composing = COMPOSITION_NO;  
   do  
     {  
       if (COMPOSITION_VALID_P (start, end, prop))  
         {  
           enum composition_method method = COMPOSITION_METHOD (prop);  
           if (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH  
               >= COMPOSITION_DATA_SIZE)  
             coding_allocate_composition_data (coding, from);  
           /* For relative composition, we remember start and end  
              positions, for the other compositions, we also remember  
              components.  */  
           CODING_ADD_COMPOSITION_START (coding, start - from, method);  
           if (method != COMPOSITION_RELATIVE)  
             {  
               /* We must store a*/  
               Lisp_Object val, ch;  
6118    
6119                val = COMPOSITION_COMPONENTS (prop);    if (BUFFERP (coding->dst_object))
6120                if (CONSP (val))      {
6121                  while (CONSP (val))        set_buffer_internal (XBUFFER (coding->dst_object));
6122                    {        coding->dst_multibyte
6123                      ch = XCAR (val), val = XCDR (val);          = ! NILP (current_buffer->enable_multibyte_characters);
                     CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (ch));  
                   }  
               else if (VECTORP (val) || STRINGP (val))  
                 {  
                   int len = (VECTORP (val)  
                              ? XVECTOR (val)->size : SCHARS (val));  
                   int i;  
                   for (i = 0; i < len; i++)  
                     {  
                       ch = (STRINGP (val)  
                             ? Faref (val, make_number (i))  
                             : XVECTOR (val)->contents[i]);  
                       CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (ch));  
                     }  
                 }  
               else              /* INTEGERP (val) */  
                 CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (val));  
             }  
           CODING_ADD_COMPOSITION_END (coding, end - from);  
         }  
       start = end;  
6124      }      }
   while (start < to  
          && find_composition (start, to, &start, &end, &prop, obj)  
          && end <= to);  
6125    
6126    /* Make coding->cmp_data point to the first memory block.  */    coding->consumed = coding->consumed_char = 0;
6127    while (coding->cmp_data->prev)    coding->produced = coding->produced_char = 0;
6128      coding->cmp_data = coding->cmp_data->prev;    coding->result = CODING_RESULT_SUCCESS;
6129    coding->cmp_data_start = 0;    coding->errors = 0;
 }  
   
 /* Reflect the saved information about compositions to OBJ.  
    CODING->cmp_data points to a memory block for the information.  OBJ  
    is a buffer or a string, defaults to the current buffer.  */  
   
 void  
 coding_restore_composition (coding, obj)  
      struct coding_system *coding;  
      Lisp_Object obj;  
 {  
   struct composition_data *cmp_data = coding->cmp_data;  
6130    
6131    if (!cmp_data)    ALLOC_CONVERSION_WORK_AREA (coding);
     return;  
6132    
6133    while (cmp_data->prev)    do {
6134      cmp_data = cmp_data->prev;      coding_set_source (coding);
6135        consume_chars (coding);
6136    
6137    while (cmp_data)      if (!NILP (CODING_ATTR_ENCODE_TBL (attrs)))
6138      {        translate_chars (coding, CODING_ATTR_ENCODE_TBL (attrs));
6139        int i;      else if (!NILP (Vstandard_translation_table_for_encode))
6140          translate_chars (coding, Vstandard_translation_table_for_encode);
6141    
6142        for (i = 0; i < cmp_data->used && cmp_data->data[i] > 0;      coding_set_destination (coding);
6143             i += cmp_data->data[i])      (*(coding->encoder)) (coding);
6144          {    } while (coding->consumed_char < coding->src_chars);
           int *data = cmp_data->data + i;  
           enum composition_method method = (enum composition_method) data[3];  
           Lisp_Object components;  
6145    
6146            if (method == COMPOSITION_RELATIVE)    if (BUFFERP (coding->dst_object))
6147              components = Qnil;      insert_from_gap (coding->produced_char, coding->produced);
           else  
             {  
               int len = data[0] - 4, j;  
               Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1];  
6148    
6149                if (method == COMPOSITION_WITH_RULE_ALTCHARS    return (coding->result);
                   && len % 2 == 0)  
                 len --;  
               for (j = 0; j < len; j++)  
                 args[j] = make_number (data[4 + j]);  
               components = (method == COMPOSITION_WITH_ALTCHARS  
                             ? Fstring (len, args) : Fvector (len, args));  
             }  
           compose_text (data[1], data[2], components, Qnil, obj);  
         }  
       cmp_data = cmp_data->next;  
     }  
6150  }  }
6151    
 /* Decode (if ENCODEP is zero) or encode (if ENCODEP is nonzero) the  
    text from FROM to TO (byte positions are FROM_BYTE and TO_BYTE) by  
    coding system CODING, and return the status code of code conversion  
    (currently, this value has no meaning).  
6152    
6153     How many characters (and bytes) are converted to how many  /* Stack of working buffers used in code conversion.  An nil element
6154     characters (and bytes) are recorded in members of the structure     means that the code conversion of that level is not using a working
6155     CODING.     buffer.  */
6156    Lisp_Object Vcode_conversion_work_buf_list;
6157    
6158     If REPLACE is nonzero, we do various things as if the original text  /* A working buffer used by the top level conversion.  */
6159     is deleted and a new text is inserted.  See the comments in  Lisp_Object Vcode_conversion_reused_work_buf;
    replace_range (insdel.c) to know what we are doing.  
6160    
    If REPLACE is zero, it is assumed that the source text is unibyte.  
    Otherwise, it is assumed that the source text is multibyte.  */  
6161    
6162  int  /* Return a working buffer that can be freely used by the following
6163  code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)     code conversion.  MULTIBYTEP specifies the multibyteness of the
6164       int from, from_byte, to, to_byte, encodep, replace;     buffer.  */
      struct coding_system *coding;  
 {  
   int len = to - from, len_byte = to_byte - from_byte;  
   int nchars_del = 0, nbytes_del = 0;  
   int require, inserted, inserted_byte;  
   int head_skip, tail_skip, total_skip = 0;  
   Lisp_Object saved_coding_symbol;  
   int first = 1;  
   unsigned char *src, *dst;  
   Lisp_Object deletion;  
   int orig_point = PT, orig_len = len;  
   int prev_Z;  
   int multibyte_p = !NILP (current_buffer->enable_multibyte_characters);  
6165    
6166    deletion = Qnil;  Lisp_Object
6167    saved_coding_symbol = coding->symbol;  make_conversion_work_buffer (multibytep, depth)
6168         int multibytep, depth;
6169    {
6170      struct buffer *current = current_buffer;
6171      Lisp_Object buf, name;
6172    
6173    if (from < PT && PT < to)    if (depth == 0)
6174      {      {
6175        TEMP_SET_PT_BOTH (from, from_byte);        if (NILP (Vcode_conversion_reused_work_buf))
6176        orig_point = from;          Vcode_conversion_reused_work_buf
6177              = Fget_buffer_create (build_string (" *code-converting-work<0>*"));
6178          buf = Vcode_conversion_reused_work_buf;
6179      }      }
6180      else
   if (replace)  
6181      {      {
6182        int saved_from = from;        if (depth < 0)
       int saved_inhibit_modification_hooks;  
   
       prepare_to_modify_buffer (from, to, &from);  
       if (saved_from != from)  
6183          {          {
6184            to = from + len;            name = build_string (" *code-converting-work*");
6185            from_byte = CHAR_TO_BYTE (from), to_byte = CHAR_TO_BYTE (to);            name = Fgenerate_new_buffer_name (name, Qnil);
           len_byte = to_byte - from_byte;  
6186          }          }
6187          else
       /* The code conversion routine can not preserve text properties  
          for now.  So, we must remove all text properties in the  
          region.  Here, we must suppress all modification hooks.  */  
       saved_inhibit_modification_hooks = inhibit_modification_hooks;  
       inhibit_modification_hooks = 1;  
       Fset_text_properties (make_number (from), make_number (to), Qnil, Qnil);  
       inhibit_modification_hooks = saved_inhibit_modification_hooks;  
     }  
   
   if (! encodep && CODING_REQUIRE_DETECTION (coding))  
     {  
       /* We must detect encoding of text and eol format.  */  
   
       if (from < GPT && to > GPT)  
         move_gap_both (from, from_byte);  
       if (coding->type == coding_type_undecided)  
6188          {          {
6189            detect_coding (coding, BYTE_POS_ADDR (from_byte), len_byte);            char str[128];
           if (coding->type == coding_type_undecided)  
             {  
               /* It seems that the text contains only ASCII, but we  
                  should not leave it undecided because the deeper  
                  decoding routine (decode_coding) tries to detect the  
                  encodings again in vain.  */  
               coding->type = coding_type_emacs_mule;  
               coding->category_idx = CODING_CATEGORY_IDX_EMACS_MULE;  
               /* As emacs-mule decoder will handle composition, we  
                  need this setting to allocate coding->cmp_data  
                  later.  */  
               coding->composing = COMPOSITION_NO;  
             }  
         }  
       if (coding->eol_type == CODING_EOL_UNDECIDED  
           && coding->type != coding_type_ccl)  
         {  
           detect_eol (coding, BYTE_POS_ADDR (from_byte), len_byte);  
           if (coding->eol_type == CODING_EOL_UNDECIDED)  
             coding->eol_type = CODING_EOL_LF;  
           /* We had better recover the original eol format if we  
              encounter an inconsistent eol format while decoding.  */  
           coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL;  
         }  
     }  
6190    
6191    /* Now we convert the text.  */            sprintf (str, " *code-converting-work*<%d>", depth);
6192              name = build_string (str);
   /* For encoding, we must process pre-write-conversion in advance.  */  
   if (! inhibit_pre_post_conversion  
       && encodep  
       && SYMBOLP (coding->pre_write_conversion)  
       && ! NILP (Ffboundp (coding->pre_write_conversion)))  
     {  
       /* The function in pre-write-conversion may put a new text in a  
          new buffer.  */  
       struct buffer *prev = current_buffer;  
       Lisp_Object new;  
   
       record_unwind_protect (code_convert_region_unwind,  
                              Vlast_coding_system_used);  
       /* We should not call any more pre-write/post-read-conversion  
          functions while this pre-write-conversion is running.  */  
       inhibit_pre_post_conversion = 1;  
       call2 (coding->pre_write_conversion,  
              make_number (from), make_number (to));  
       inhibit_pre_post_conversion = 0;  
       /* Discard the unwind protect.  */  
       specpdl_ptr--;  
   
       if (current_buffer != prev)  
         {  
           len = ZV - BEGV;  
           new = Fcurrent_buffer ();  
           set_buffer_internal_1 (prev);  
           del_range_2 (from, from_byte, to, to_byte, 0);  
           TEMP_SET_PT_BOTH (from, from_byte);  
           insert_from_buffer (XBUFFER (new), 1, len, 0);  
           Fkill_buffer (new);  
           if (orig_point >= to)  
             orig_point += len - orig_len;  
           else if (orig_point > from)  
             orig_point = from;  
           orig_len = len;  
           to = from + len;  
           from_byte = CHAR_TO_BYTE (from);  
           to_byte = CHAR_TO_BYTE (to);  
           len_byte = to_byte - from_byte;  
           TEMP_SET_PT_BOTH (from, from_byte);  
6193          }          }
6194          buf = Fget_buffer_create (name);
6195      }      }
6196      set_buffer_internal (XBUFFER (buf));
6197      current_buffer->undo_list = Qt;
6198      Ferase_buffer ();
6199      Fset_buffer_multibyte (multibytep ? Qt : Qnil);
6200      set_buffer_internal (current);
6201      return buf;
6202    }
6203    
6204    if (replace)  static Lisp_Object
6205      {  code_conversion_restore (buffer)
6206        if (! EQ (current_buffer->undo_list, Qt))       Lisp_Object buffer;
6207          deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);  {
6208        else    Lisp_Object workbuf;
         {  
           nchars_del = to - from;  
           nbytes_del = to_byte - from_byte;  
         }  
     }  
6209    
6210    if (coding->composing != COMPOSITION_DISABLED)    workbuf = XCAR (Vcode_conversion_work_buf_list);
6211      {    if (! NILP (workbuf)
6212        if (encodep)        && ! EQ (workbuf, Vcode_conversion_reused_work_buf)
6213          coding_save_composition (coding, from, to, Fcurrent_buffer ());        && ! NILP (Fbuffer_live_p (workbuf)))
6214        else      Fkill_buffer (workbuf);
6215          coding_allocate_composition_data (coding, from);    Vcode_conversion_work_buf_list = XCDR (Vcode_conversion_work_buf_list);
6216      }    set_buffer_internal (XBUFFER (buffer));
6217      return Qnil;
6218    }
6219    
6220    /* Try to skip the heading and tailing ASCIIs.  */  static Lisp_Object
6221    if (coding->type != coding_type_ccl)  code_conversion_save (buffer, with_work_buf, multibyte)
6222      {       Lisp_Object buffer;
6223        int from_byte_orig = from_byte, to_byte_orig = to_byte;       int with_work_buf, multibyte;
6224    {
6225      Lisp_Object workbuf;
6226    
6227        if (from < GPT && GPT < to)    if (with_work_buf)
6228          move_gap_both (from, from_byte);      {
6229        SHRINK_CONVERSION_REGION (&from_byte, &to_byte, coding, NULL, encodep);        int depth = XINT (Flength (Vcode_conversion_work_buf_list));
       if (from_byte == to_byte  
           && (encodep || NILP (coding->post_read_conversion))  
           && ! CODING_REQUIRE_FLUSHING (coding))  
         {  
           coding->produced = len_byte;  
           coding->produced_char = len;  
           if (!replace)  
             /* We must record and adjust for this new text now.  */  
             adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len);  
           return 0;  
         }  
6230    
6231        head_skip = from_byte - from_byte_orig;        workbuf = make_conversion_work_buffer (multibyte, depth);
       tail_skip = to_byte_orig - to_byte;  
       total_skip = head_skip + tail_skip;  
       from += head_skip;  
       to -= tail_skip;  
       len -= total_skip; len_byte -= total_skip;  
6232      }      }
6233      else
6234        workbuf = Qnil;
6235      Vcode_conversion_work_buf_list
6236        = Fcons (workbuf, Vcode_conversion_work_buf_list);
6237      record_unwind_protect (code_conversion_restore, buffer);
6238      return workbuf;
6239    }
6240    
6241    /* For conversion, we must put the gap before the text in addition to  int
6242       making the gap larger for efficient decoding.  The required gap  decode_coding_gap (coding, chars, bytes)
6243       size starts from 2000 which is the magic number used in make_gap.       struct coding_system *coding;
6244       But, after one batch of conversion, it will be incremented if we       EMACS_INT chars, bytes;
6245       find that it is not enough .  */  {
6246    require = 2000;    int count = specpdl_ptr - specpdl;
6247      Lisp_Object attrs;
6248      Lisp_Object buffer;
6249    
6250    if (GAP_SIZE  < require)    buffer = Fcurrent_buffer ();
6251      make_gap (require - GAP_SIZE);    code_conversion_save (buffer, 0, 0);
   move_gap_both (from, from_byte);  
6252    
6253    inserted = inserted_byte = 0;    coding->src_object = buffer;
6254      coding->src_chars = chars;
6255      coding->src_bytes = bytes;
6256      coding->src_pos = -chars;
6257      coding->src_pos_byte = -bytes;
6258      coding->src_multibyte = chars < bytes;
6259      coding->dst_object = buffer;
6260      coding->dst_pos = PT;
6261      coding->dst_pos_byte = PT_BYTE;
6262      coding->dst_multibyte = ! NILP (current_buffer->enable_multibyte_characters);
6263      coding->mode |= CODING_MODE_LAST_BLOCK;
6264    
6265    GAP_SIZE += len_byte;    if (CODING_REQUIRE_DETECTION (coding))
6266    ZV -= len;      detect_coding (coding);
   Z -= len;  
   ZV_BYTE -= len_byte;  
   Z_BYTE -= len_byte;  
6267    
6268    if (GPT - BEG < BEG_UNCHANGED)    decode_coding (coding);
     BEG_UNCHANGED = GPT - BEG;  
   if (Z - GPT < END_UNCHANGED)  
     END_UNCHANGED = Z - GPT;  
6269    
6270    if (!encodep && coding->src_multibyte)    attrs = CODING_ID_ATTRS (coding->id);
6271      if (! NILP (CODING_ATTR_POST_READ (attrs)))
6272      {      {
6273        /* Decoding routines expects that the source text is unibyte.        EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
6274           We must convert 8-bit characters of multibyte form to        Lisp_Object val;
6275           unibyte.  */  
6276        int len_byte_orig = len_byte;        TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
6277        len_byte = str_as_unibyte (GAP_END_ADDR - len_byte, len_byte);        val = call1 (CODING_ATTR_POST_READ (attrs),
6278        if (len_byte < len_byte_orig)                     make_number (coding->produced_char));
6279          safe_bcopy (GAP_END_ADDR - len_byte_orig, GAP_END_ADDR - len_byte,        CHECK_NATNUM (val);
6280                      len_byte);        coding->produced_char += Z - prev_Z;
6281        coding->src_multibyte = 0;        coding->produced += Z_BYTE - prev_Z_BYTE;
6282      }      }
6283    
6284    for (;;)    unbind_to (count, Qnil);
6285      {    return coding->result;
6286        int result;  }
6287    
6288        /* The buffer memory is now:  int
6289           +--------+converted-text+---------+-------original-text-------+---+  encode_coding_gap (coding, chars, bytes)
6290           |<-from->|<--inserted-->|---------|<--------len_byte--------->|---|       struct coding_system *coding;
6291                    |<---------------------- GAP ----------------------->|  */       EMACS_INT chars, bytes;
6292        src = GAP_END_ADDR - len_byte;  {
6293        dst = GPT_ADDR + inserted_byte;    int count = specpdl_ptr - specpdl;
6294      Lisp_Object buffer;
6295    
6296        if (encodep)    buffer = Fcurrent_buffer ();
6297          result = encode_coding (coding, src, dst, len_byte, 0);    code_conversion_save (buffer, 0, 0);
       else  
         {  
           if (coding->composing != COMPOSITION_DISABLED)  
             coding->cmp_data->char_offset = from + inserted;  
           result = decode_coding (coding, src, dst, len_byte, 0);  
         }  
6298    
6299        /* The buffer memory is now:    coding->src_object = buffer;
6300           +--------+-------converted-text----+--+------original-text----+---+    coding->src_chars = chars;
6301           |<-from->|<-inserted->|<-produced->|--|<-(len_byte-consumed)->|---|    coding->src_bytes = bytes;
6302                    |<---------------------- GAP ----------------------->|  */    coding->src_pos = -chars;
6303      coding->src_pos_byte = -bytes;
6304      coding->src_multibyte = chars < bytes;
6305      coding->dst_object = coding->src_object;
6306      coding->dst_pos = PT;
6307      coding->dst_pos_byte = PT_BYTE;
6308    
6309        inserted += coding->produced_char;    encode_coding (coding);
       inserted_byte += coding->produced;  
       len_byte -= coding->consumed;  
6310    
6311        if (result == CODING_FINISH_INSUFFICIENT_CMP)    unbind_to (count, Qnil);
6312          {    return coding->result;
6313            coding_allocate_composition_data (coding, from + inserted);  }
           continue;  
         }  
6314    
       src += coding->consumed;  
       dst += coding->produced;  
6315    
6316        if (result == CODING_FINISH_NORMAL)  /* Decode the text in the range FROM/FROM_BYTE and TO/TO_BYTE in
6317          {     SRC_OBJECT into DST_OBJECT by coding context CODING.
           src += len_byte;  
           break;  
         }  
       if (! encodep && result == CODING_FINISH_INCONSISTENT_EOL)  
         {  
           unsigned char *pend = dst, *p = pend - inserted_byte;  
           Lisp_Object eol_type;  
6318    
6319            /* Encode LFs back to the original eol format (CR or CRLF).  */     SRC_OBJECT is a buffer, a string, or Qnil.
           if (coding->eol_type == CODING_EOL_CR)  
             {  
               while (p < pend) if (*p++ == '\n') p[-1] = '\r';  
             }  
           else  
             {  
               int count = 0;  
6320    
6321                while (p < pend) if (*p++ == '\n') count++;     If it is a buffer, the text is at point of the buffer.  FROM and TO
6322                if (src - dst < count)     are positions in the buffer.
                 {  
                   /* We don't have sufficient room for encoding LFs  
                      back to CRLF.  We must record converted and  
                      not-yet-converted text back to the buffer  
                      content, enlarge the gap, then record them out of  
                      the buffer contents again.  */  
                   int add = len_byte + inserted_byte;  
   
                   GAP_SIZE -= add;  
                   ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;  
                   GPT += inserted_byte; GPT_BYTE += inserted_byte;  
                   make_gap (count - GAP_SIZE);  
                   GAP_SIZE += add;  
                   ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;  
                   GPT -= inserted_byte; GPT_BYTE -= inserted_byte;  
                   /* Don't forget to update SRC, DST, and PEND.  */  
                   src = GAP_END_ADDR - len_byte;  
                   dst = GPT_ADDR + inserted_byte;  
                   pend = dst;  
                 }  
               inserted += count;  
               inserted_byte += count;  
               coding->produced += count;  
               p = dst = pend + count;  
               while (count)  
                 {  
                   *--p = *--pend;  
                   if (*p == '\n') count--, *--p = '\r';  
                 }  
             }  
6323    
6324            /* Suppress eol-format conversion in the further conversion.  */     If it is a string, the text is at the beginning of the string.
6325            coding->eol_type = CODING_EOL_LF;     FROM and TO are indices to the string.
   
           /* Set the coding system symbol to that for Unix-like EOL.  */  
           eol_type = Fget (saved_coding_symbol, Qeol_type);  
           if (VECTORP (eol_type)  
               && XVECTOR (eol_type)->size == 3  
               && SYMBOLP (XVECTOR (eol_type)->contents[CODING_EOL_LF]))  
             coding->symbol = XVECTOR (eol_type)->contents[CODING_EOL_LF];  
           else  
             coding->symbol = saved_coding_symbol;  
6326    
6327            continue;     If it is nil, the text is at coding->source.  FROM and TO are
6328          }     indices to coding->source.
       if (len_byte <= 0)  
         {  
           if (coding->type != coding_type_ccl  
               || coding->mode & CODING_MODE_LAST_BLOCK)  
             break;  
           coding->mode |= CODING_MODE_LAST_BLOCK;  
           continue;  
         }  
       if (result == CODING_FINISH_INSUFFICIENT_SRC)  
         {  
           /* The source text ends in invalid codes.  Let's just  
              make them valid buffer contents, and finish conversion.  */  
           if (multibyte_p)  
             {  
               unsigned char *start = dst;  
6329    
6330                inserted += len_byte;     DST_OBJECT is a buffer, Qt, or Qnil.
               while (len_byte--)  
                 {  
                   int c = *src++;  
                   dst += CHAR_STRING (c, dst);  
                 }  
6331    
6332                inserted_byte += dst - start;     If it is a buffer, the decoded text is inserted at point of the
6333              }     buffer.  If the buffer is the same as SRC_OBJECT, the source text
6334            else     is deleted.
             {  
               inserted += len_byte;  
               inserted_byte += len_byte;  
               while (len_byte--)  
                 *dst++ = *src++;  
             }  
           break;  
         }  
       if (result == CODING_FINISH_INTERRUPT)  
         {  
           /* The conversion procedure was interrupted by a user.  */  
           break;  
         }  
       /* Now RESULT == CODING_FINISH_INSUFFICIENT_DST  */  
       if (coding->consumed < 1)  
         {  
           /* It's quite strange to require more memory without  
              consuming any bytes.  Perhaps CCL program bug.  */  
           break;  
         }  
       if (first)  
         {  
           /* We have just done the first batch of conversion which was  
              stopped because of insufficient gap.  Let's reconsider the  
              required gap size (i.e. SRT - DST) now.  
   
              We have converted ORIG bytes (== coding->consumed) into  
              NEW bytes (coding->produced).  To convert the remaining  
              LEN bytes, we may need REQUIRE bytes of gap, where:  
                 REQUIRE + LEN_BYTE = LEN_BYTE * (NEW / ORIG)  
                 REQUIRE = LEN_BYTE * (NEW - ORIG) / ORIG  
              Here, we are sure that NEW >= ORIG.  */  
           float ratio;  
   
           if (coding->produced <= coding->consumed)  
             {  
               /* This happens because of CCL-based coding system with  
                  eol-type CRLF.  */  
               require = 0;  
             }  
           else  
             {  
               ratio = (coding->produced - coding->consumed) / coding->consumed;  
               require = len_byte * ratio;  
             }  
           first = 0;  
         }  
       if ((src - dst) < (require + 2000))  
         {  
           /* See the comment above the previous call of make_gap.  */  
           int add = len_byte + inserted_byte;  
6335    
6336            GAP_SIZE -= add;     If it is Qt, a string is made from the decoded text, and
6337            ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;     set in CODING->dst_object.
6338            GPT += inserted_byte; GPT_BYTE += inserted_byte;  
6339            make_gap (require + 2000);     If it is Qnil, the decoded text is stored at CODING->destination.
6340            GAP_SIZE += add;     The caller must allocate CODING->dst_bytes bytes at
6341            ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;     CODING->destination by xmalloc.  If the decoded text is longer than
6342            GPT -= inserted_byte; GPT_BYTE -= inserted_byte;     CODING->dst_bytes, CODING->destination is relocated by xrealloc.
6343          }   */
6344    
6345    void
6346    decode_coding_object (coding, src_object, from, from_byte, to, to_byte,
6347                          dst_object)
6348         struct coding_system *coding;
6349         Lisp_Object src_object;
6350         EMACS_INT from, from_byte, to, to_byte;
6351         Lisp_Object dst_object;
6352    {
6353      int count = specpdl_ptr - specpdl;
6354      unsigned char *destination;
6355      EMACS_INT dst_bytes;
6356      EMACS_INT chars = to - from;
6357      EMACS_INT bytes = to_byte - from_byte;
6358      Lisp_Object attrs;
6359      Lisp_Object buffer;
6360      int saved_pt = -1, saved_pt_byte;
6361    
6362      buffer = Fcurrent_buffer ();
6363    
6364      if (NILP (dst_object))
6365        {
6366          destination = coding->destination;
6367          dst_bytes = coding->dst_bytes;
6368      }      }
   if (src - dst > 0) *dst = 0; /* Put an anchor.  */  
6369    
6370    if (encodep && coding->dst_multibyte)    coding->src_object = src_object;
6371      coding->src_chars = chars;
6372      coding->src_bytes = bytes;
6373      coding->src_multibyte = chars < bytes;
6374    
6375      if (STRINGP (src_object))
6376        {
6377          coding->src_pos = from;
6378          coding->src_pos_byte = from_byte;
6379        }
6380      else if (BUFFERP (src_object))
6381      {      {
6382        /* The output is unibyte.  We must convert 8-bit characters to        set_buffer_internal (XBUFFER (src_object));
6383           multibyte form.  */        if (from != GPT)
6384        if (inserted_byte * 2 > GAP_SIZE)          move_gap_both (from, from_byte);
6385          if (EQ (src_object, dst_object))
6386            {
6387              saved_pt = PT, saved_pt_byte = PT_BYTE;
6388              TEMP_SET_PT_BOTH (from, from_byte);
6389              del_range_both (from, from_byte, to, to_byte, 1);
6390              coding->src_pos = -chars;
6391              coding->src_pos_byte = -bytes;
6392            }
6393          else
6394          {          {
6395            GAP_SIZE -= inserted_byte;            coding->src_pos = from;
6396            ZV += inserted_byte; Z += inserted_byte;            coding->src_pos_byte = from_byte;
           ZV_BYTE += inserted_byte; Z_BYTE += inserted_byte;  
           GPT += inserted_byte; GPT_BYTE += inserted_byte;  
           make_gap (inserted_byte - GAP_SIZE);  
           GAP_SIZE += inserted_byte;  
           ZV -= inserted_byte; Z -= inserted_byte;  
           ZV_BYTE -= inserted_byte; Z_BYTE -= inserted_byte;  
           GPT -= inserted_byte; GPT_BYTE -= inserted_byte;  
6397          }          }
       inserted_byte = str_to_multibyte (GPT_ADDR, GAP_SIZE, inserted_byte);  
6398      }      }
6399    
6400    /* If we shrank the conversion area, adjust it now.  */    if (CODING_REQUIRE_DETECTION (coding))
6401    if (total_skip > 0)      detect_coding (coding);
6402      attrs = CODING_ID_ATTRS (coding->id);
6403    
6404      if (EQ (dst_object, Qt)
6405          || (! NILP (CODING_ATTR_POST_READ (attrs))
6406              && NILP (dst_object)))
6407        {
6408          coding->dst_object = code_conversion_save (buffer, 1, 1);
6409          coding->dst_pos = BEG;
6410          coding->dst_pos_byte = BEG_BYTE;
6411          coding->dst_multibyte = 1;
6412        }
6413      else if (BUFFERP (dst_object))
6414        {
6415          code_conversion_save (buffer, 0, 0);
6416          coding->dst_object = dst_object;
6417          coding->dst_pos = BUF_PT (XBUFFER (dst_object));
6418          coding->dst_pos_byte = BUF_PT_BYTE (XBUFFER (dst_object));
6419          coding->dst_multibyte
6420            = ! NILP (XBUFFER (dst_object)->enable_multibyte_characters);
6421        }
6422      else
6423      {      {
6424        if (tail_skip > 0)        code_conversion_save (buffer, 0, 0);
6425          safe_bcopy (GAP_END_ADDR, GPT_ADDR + inserted_byte, tail_skip);        coding->dst_object = Qnil;
6426        inserted += total_skip; inserted_byte += total_skip;        coding->dst_multibyte = 1;
       GAP_SIZE += total_skip;  
       GPT -= head_skip; GPT_BYTE -= head_skip;  
       ZV -= total_skip; ZV_BYTE -= total_skip;  
       Z -= total_skip; Z_BYTE -= total_skip;  
       from -= head_skip; from_byte -= head_skip;  
       to += tail_skip; to_byte += tail_skip;  
6427      }      }
6428    
6429    prev_Z = Z;    decode_coding (coding);
   if (! EQ (current_buffer->undo_list, Qt))  
     adjust_after_replace (from, from_byte, deletion, inserted, inserted_byte);  
   else  
     adjust_after_replace_noundo (from, from_byte, nchars_del, nbytes_del,  
                                  inserted, inserted_byte);  
   inserted = Z - prev_Z;  
   
   if (!encodep && coding->cmp_data && coding->cmp_data->used)  
     coding_restore_composition (coding, Fcurrent_buffer ());  
   coding_free_composition_data (coding);  
6430    
6431    if (! inhibit_pre_post_conversion    if (BUFFERP (coding->dst_object))
6432        && ! encodep && ! NILP (coding->post_read_conversion))      set_buffer_internal (XBUFFER (coding->dst_object));
6433    
6434      if (! NILP (CODING_ATTR_POST_READ (attrs)))
6435      {      {
6436          struct gcpro gcpro1, gcpro2;
6437          EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
6438        Lisp_Object val;        Lisp_Object val;
       Lisp_Object saved_coding_system;  
6439    
6440        if (from != PT)        TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
6441          TEMP_SET_PT_BOTH (from, from_byte);        GCPRO2 (coding->src_object, coding->dst_object);
6442        prev_Z = Z;        val = call1 (CODING_ATTR_POST_READ (attrs),
6443        record_unwind_protect (code_convert_region_unwind,                     make_number (coding->produced_char));
6444                               Vlast_coding_system_used);        UNGCPRO;
6445        saved_coding_system = Vlast_coding_system_used;        CHECK_NATNUM (val);
6446        Vlast_coding_system_used = coding->symbol;        coding->produced_char += Z - prev_Z;
6447        /* We should not call any more pre-write/post-read-conversion        coding->produced += Z_BYTE - prev_Z_BYTE;
          functions while this post-read-conversion is running.  */  
       inhibit_pre_post_conversion = 1;  
       val = call1 (coding->post_read_conversion, make_number (inserted));  
       inhibit_pre_post_conversion = 0;  
       coding->symbol = Vlast_coding_system_used;  
       Vlast_coding_system_used = saved_coding_system;  
       /* Discard the unwind protect.  */  
       specpdl_ptr--;  
       CHECK_NUMBER (val);  
       inserted += Z - prev_Z;  
     }  
   
   if (orig_point >= from)  
     {  
       if (orig_point >= from + orig_len)  
         orig_point += inserted - orig_len;  
       else  
         orig_point = from;  
       TEMP_SET_PT (orig_point);  
6448      }      }
6449    
6450    if (replace)    if (EQ (dst_object, Qt))
6451      {      {
6452        signal_after_change (from, to - from, inserted);        coding->dst_object = Fbuffer_string ();
6453        update_compositions (from, from + inserted, CHECK_BORDER);      }
6454      else if (NILP (dst_object) && BUFFERP (coding->dst_object))
6455        {
6456          set_buffer_internal (XBUFFER (coding->dst_object));
6457          if (dst_bytes < coding->produced)
6458            {
6459              destination
6460                = (unsigned char *) xrealloc (destination, coding->produced);
6461              if (! destination)
6462                {
6463                  coding->result = CODING_RESULT_INSUFFICIENT_DST;
6464                  unbind_to (count, Qnil);
6465                  return;
6466                }
6467              if (BEGV < GPT && GPT < BEGV + coding->produced_char)
6468                move_gap_both (BEGV, BEGV_BYTE);
6469              bcopy (BEGV_ADDR, destination, coding->produced);
6470              coding->destination = destination;
6471            }
6472      }      }
6473    
6474    {    if (saved_pt >= 0)
6475      coding->consumed = to_byte - from_byte;      {
6476      coding->consumed_char = to - from;        /* This is the case of:
6477      coding->produced = inserted_byte;           (BUFFERP (src_object) && EQ (src_object, dst_object))
6478      coding->produced_char = inserted;           As we have moved PT while replacing the original buffer
6479    }           contents, we must recover it now.  */
6480          set_buffer_internal (XBUFFER (src_object));
6481          if (saved_pt < from)
6482            TEMP_SET_PT_BOTH (saved_pt, saved_pt_byte);
6483          else if (saved_pt < from + chars)
6484            TEMP_SET_PT_BOTH (from, from_byte);
6485          else if (! NILP (current_buffer->enable_multibyte_characters))
6486            TEMP_SET_PT_BOTH (saved_pt + (coding->produced_char - chars),
6487                              saved_pt_byte + (coding->produced - bytes));
6488          else
6489            TEMP_SET_PT_BOTH (saved_pt + (coding->produced - bytes),
6490                              saved_pt_byte + (coding->produced - bytes));
6491        }
6492    
6493    return 0;    unbind_to (count, Qnil);
6494  }  }
6495    
6496  Lisp_Object  
6497  run_pre_post_conversion_on_str (str, coding, encodep)  void
6498       Lisp_Object str;  encode_coding_object (coding, src_object, from, from_byte, to, to_byte,
6499                          dst_object)
6500       struct coding_system *coding;       struct coding_system *coding;
6501       int encodep;       Lisp_Object src_object;
6502  {       EMACS_INT from, from_byte, to, to_byte;
6503    int count = SPECPDL_INDEX ();       Lisp_Object dst_object;
6504    struct gcpro gcpro1, gcpro2;  {
6505    int multibyte = STRING_MULTIBYTE (str);    int count = specpdl_ptr - specpdl;
6506      EMACS_INT chars = to - from;
6507      EMACS_INT bytes = to_byte - from_byte;
6508      Lisp_Object attrs;
6509    Lisp_Object buffer;    Lisp_Object buffer;
6510    struct buffer *buf;    int saved_pt = -1, saved_pt_byte;
   Lisp_Object old_deactivate_mark;  
6511    
6512    record_unwind_protect (Fset_buffer, Fcurrent_buffer ());    buffer = Fcurrent_buffer ();
   record_unwind_protect (code_convert_region_unwind,  
                          Vlast_coding_system_used);  
   /* It is not crucial to specbind this.  */  
   old_deactivate_mark = Vdeactivate_mark;  
   GCPRO2 (str, old_deactivate_mark);  
   
   buffer = Fget_buffer_create (build_string (" *code-converting-work*"));  
   buf = XBUFFER (buffer);  
   
   delete_all_overlays (buf);  
   buf->directory = current_buffer->directory;  
   buf->read_only = Qnil;  
   buf->filename = Qnil;  
   buf->undo_list = Qt;  
   eassert (buf->overlays_before == NULL);  
   eassert (buf->overlays_after == NULL);  
   
   set_buffer_internal (buf);  
   /* We must insert the contents of STR as is without  
      unibyte<->multibyte conversion.  For that, we adjust the  
      multibyteness of the working buffer to that of STR.  */  
   Ferase_buffer ();  
   buf->enable_multibyte_characters = multibyte ? Qt : Qnil;  
6513    
6514    insert_from_string (str, 0, 0,    coding->src_object = src_object;
6515                        SCHARS (str), SBYTES (str), 0);    coding->src_chars = chars;
6516    UNGCPRO;    coding->src_bytes = bytes;
6517    inhibit_pre_post_conversion = 1;    coding->src_multibyte = chars < bytes;
6518    if (encodep)  
6519      call2 (coding->pre_write_conversion, make_number (BEG), make_number (Z));    attrs = CODING_ID_ATTRS (coding->id);
6520    else  
6521      {    if (! NILP (CODING_ATTR_PRE_WRITE (attrs)))
6522        Vlast_coding_system_used = coding->symbol;      {
6523        TEMP_SET_PT_BOTH (BEG, BEG_BYTE);        coding->src_object = code_conversion_save (buffer, 1,
6524        call1 (coding->post_read_conversion, make_number (Z - BEG));                                                   coding->src_multibyte);
6525        coding->symbol = Vlast_coding_system_used;        set_buffer_internal (XBUFFER (coding->src_object));
6526      }        if (STRINGP (src_object))
6527    inhibit_pre_post_conversion = 0;          insert_from_string (src_object, from, from_byte, chars, bytes, 0);
6528    Vdeactivate_mark = old_deactivate_mark;        else if (BUFFERP (src_object))
6529    str = make_buffer_string (BEG, Z, 1);          insert_from_buffer (XBUFFER (src_object), from, chars, 0);
6530    return unbind_to (count, str);        else
6531  }          insert_1_both (coding->source + from, chars, bytes, 0, 0, 0);
6532    
6533  Lisp_Object        if (EQ (src_object, dst_object))
 decode_coding_string (str, coding, nocopy)  
      Lisp_Object str;  
      struct coding_system *coding;  
      int nocopy;  
 {  
   int len;  
   struct conversion_buffer buf;  
   int from, to_byte;  
   Lisp_Object saved_coding_symbol;  
   int result;  
   int require_decoding;  
   int shrinked_bytes = 0;  
   Lisp_Object newstr;  
   int consumed, consumed_char, produced, produced_char;  
   
   from = 0;  
   to_byte = SBYTES (str);  
   
   saved_coding_symbol = coding->symbol;  
   coding->src_multibyte = STRING_MULTIBYTE (str);  
   coding->dst_multibyte = 1;  
   if (CODING_REQUIRE_DETECTION (coding))  
     {  
       /* See the comments in code_convert_region.  */  
       if (coding->type == coding_type_undecided)  
6534          {          {
6535            detect_coding (coding, SDATA (str), to_byte);            set_buffer_internal (XBUFFER (src_object));
6536            if (coding->type == coding_type_undecided)            saved_pt = PT, saved_pt_byte = PT_BYTE;
6537              {            del_range_both (from, from_byte, to, to_byte, 1);
6538                coding->type = coding_type_emacs_mule;            set_buffer_internal (XBUFFER (coding->src_object));
6539                coding->category_idx = CODING_CATEGORY_IDX_EMACS_MULE;          }
6540                /* As emacs-mule decoder will handle composition, we  
6541                   need this setting to allocate coding->cmp_data        call2 (CODING_ATTR_PRE_WRITE (attrs),
6542                   later.  */               make_number (BEG), make_number (Z));
6543                coding->composing = COMPOSITION_NO;        coding->src_object = Fcurrent_buffer ();
6544              }        if (BEG != GPT)
6545            move_gap_both (BEG, BEG_BYTE);
6546          coding->src_chars = Z - BEG;
6547          coding->src_bytes = Z_BYTE - BEG_BYTE;
6548          coding->src_pos = BEG;
6549          coding->src_pos_byte = BEG_BYTE;
6550          coding->src_multibyte = Z < Z_BYTE;
6551        }
6552      else if (STRINGP (src_object))
6553        {
6554          code_conversion_save (buffer, 0, 0);
6555          coding->src_pos = from;
6556          coding->src_pos_byte = from_byte;
6557        }
6558      else if (BUFFERP (src_object))
6559        {
6560          code_conversion_save (buffer, 0, 0);
6561          set_buffer_internal (XBUFFER (src_object));
6562          if (EQ (src_object, dst_object))
6563            {
6564              saved_pt = PT, saved_pt_byte = PT_BYTE;
6565              coding->src_object = del_range_1 (from, to, 1, 1);
6566              coding->src_pos = 0;
6567              coding->src_pos_byte = 0;
6568          }          }
6569        if (coding->eol_type == CODING_EOL_UNDECIDED        else
           && coding->type != coding_type_ccl)  
6570          {          {
6571            saved_coding_symbol = coding->symbol;            if (from < GPT && to >= GPT)
6572            detect_eol (coding, SDATA (str), to_byte);              move_gap_both (from, from_byte);
6573            if (coding->eol_type == CODING_EOL_UNDECIDED)            coding->src_pos = from;
6574              coding->eol_type = CODING_EOL_LF;            coding->src_pos_byte = from_byte;
           /* We had better recover the original eol format if we  
              encounter an inconsistent eol format while decoding.  */  
           coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL;  
6575          }          }
6576      }      }
6577      else
6578        code_conversion_save (buffer, 0, 0);
6579    
6580    if (coding->type == coding_type_no_conversion    if (BUFFERP (dst_object))
       || coding->type == coding_type_raw_text)  
     coding->dst_multibyte = 0;  
   
   require_decoding = CODING_REQUIRE_DECODING (coding);  
   
   if (STRING_MULTIBYTE (str))  
     {  
       /* Decoding routines expect the source text to be unibyte.  */  
       str = Fstring_as_unibyte (str);  
       to_byte = SBYTES (str);  
       nocopy = 1;  
       coding->src_multibyte = 0;  
     }  
   
   /* Try to skip the heading and tailing ASCIIs.  */  
   if (require_decoding && coding->type != coding_type_ccl)  
     {  
       SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),  
                                 0);  
       if (from == to_byte)  
         require_decoding = 0;  
       shrinked_bytes = from + (SBYTES (str) - to_byte);  
     }  
   
   if (!require_decoding  
       && !(SYMBOLP (coding->post_read_conversion)  
            && !NILP (Ffboundp (coding->post_read_conversion))))  
6581      {      {
6582        coding->consumed = SBYTES (str);        coding->dst_object = dst_object;
6583        coding->consumed_char = SCHARS (str);        if (EQ (src_object, dst_object))
6584        if (coding->dst_multibyte)          {
6585              coding->dst_pos = from;
6586              coding->dst_pos_byte = from_byte;
6587            }
6588          else
6589          {          {
6590            str = Fstring_as_multibyte (str);            coding->dst_pos = BUF_PT (XBUFFER (dst_object));
6591            nocopy = 1;            coding->dst_pos_byte = BUF_PT_BYTE (XBUFFER (dst_object));
6592          }          }
6593        coding->produced = SBYTES (str);        coding->dst_multibyte
6594        coding->produced_char = SCHARS (str);          = ! NILP (XBUFFER (dst_object)->enable_multibyte_characters);
       return (nocopy ? str : Fcopy_sequence (str));  
6595      }      }
6596      else if (EQ (dst_object, Qt))
   if (coding->composing != COMPOSITION_DISABLED)  
     coding_allocate_composition_data (coding, from);  
   len = decoding_buffer_size (coding, to_byte - from);  
   allocate_conversion_buffer (buf, len);  
   
   consumed = consumed_char = produced = produced_char = 0;  
   while (1)  
6597      {      {
6598        result = decode_coding (coding, SDATA (str) + from + consumed,        coding->dst_object = Qnil;
6599                                buf.data + produced, to_byte - from - consumed,        coding->dst_bytes = coding->src_chars;
6600                                buf.size - produced);        if (coding->dst_bytes == 0)
6601        consumed += coding->consumed;          coding->dst_bytes = 1;
6602        consumed_char += coding->consumed_char;        coding->destination = (unsigned char *) xmalloc (coding->dst_bytes);
6603        produced += coding->produced;        coding->dst_multibyte = 0;
       produced_char += coding->produced_char;  
       if (result == CODING_FINISH_NORMAL  
           || (result == CODING_FINISH_INSUFFICIENT_SRC  
               && coding->consumed == 0))  
         break;  
       if (result == CODING_FINISH_INSUFFICIENT_CMP)  
         coding_allocate_composition_data (coding, from + produced_char);  
       else if (result == CODING_FINISH_INSUFFICIENT_DST)  
         extend_conversion_buffer (&buf);  
       else if (result == CODING_FINISH_INCONSISTENT_EOL)  
         {  
           Lisp_Object eol_type;  
   
           /* Recover the original EOL format.  */  
           if (coding->eol_type == CODING_EOL_CR)  
             {  
               unsigned char *p;  
               for (p = buf.data; p < buf.data + produced; p++)  
                 if (*p == '\n') *p = '\r';  
             }  
           else if (coding->eol_type == CODING_EOL_CRLF)  
             {  
               int num_eol = 0;  
               unsigned char *p0, *p1;  
               for (p0 = buf.data, p1 = p0 + produced; p0 < p1; p0++)  
                 if (*p0 == '\n') num_eol++;  
               if (produced + num_eol >= buf.size)  
                 extend_conversion_buffer (&buf);  
               for (p0 = buf.data + produced, p1 = p0 + num_eol; p0 > buf.data;)  
                 {  
                   *--p1 = *--p0;  
                   if (*p0 == '\n') *--p1 = '\r';  
                 }  
               produced += num_eol;  
               produced_char += num_eol;  
             }  
           /* Suppress eol-format conversion in the further conversion.  */  
           coding->eol_type = CODING_EOL_LF;  
   
           /* Set the coding system symbol to that for Unix-like EOL.  */  
           eol_type = Fget (saved_coding_symbol, Qeol_type);  
           if (VECTORP (eol_type)  
               && XVECTOR (eol_type)->size == 3  
               && SYMBOLP (XVECTOR (eol_type)->contents[CODING_EOL_LF]))  
             coding->symbol = XVECTOR (eol_type)->contents[CODING_EOL_LF];  
           else  
             coding->symbol = saved_coding_symbol;  
   
   
         }  
6604      }      }
   
   coding->consumed = consumed;  
   coding->consumed_char = consumed_char;  
   coding->produced = produced;  
   coding->produced_char = produced_char;  
   
   if (coding->dst_multibyte)  
     newstr = make_uninit_multibyte_string (produced_char + shrinked_bytes,  
                                            produced + shrinked_bytes);  
6605    else    else
6606      newstr = make_uninit_string (produced + shrinked_bytes);      {
6607    if (from > 0)        coding->dst_object = Qnil;
6608      STRING_COPYIN (newstr, 0, SDATA (str), from);        coding->dst_multibyte = 0;
6609    STRING_COPYIN (newstr, from, buf.data, produced);      }
   if (shrinked_bytes > from)  
     STRING_COPYIN (newstr, from + produced,  
                    SDATA (str) + to_byte,  
                    shrinked_bytes - from);  
   free_conversion_buffer (&buf);  
   
   if (coding->cmp_data && coding->cmp_data->used)  
     coding_restore_composition (coding, newstr);  
   coding_free_composition_data (coding);  
   
   if (SYMBOLP (coding->post_read_conversion)  
       && !NILP (Ffboundp (coding->post_read_conversion)))  
     newstr = run_pre_post_conversion_on_str (newstr, coding, 0);  
   
   return newstr;  
 }  
   
 Lisp_Object  
 encode_coding_string (str, coding, nocopy)  
      Lisp_Object str;  
      struct coding_system *coding;  
      int nocopy;  
 {  
   int len;  
   struct conversion_buffer buf;  
   int from, to, to_byte;  
   int result;  
   int shrinked_bytes = 0;  
   Lisp_Object newstr;  
   int consumed, consumed_char, produced, produced_char;  
   
   if (SYMBOLP (coding->pre_write_conversion)  
       && !NILP (Ffboundp (coding->pre_write_conversion)))  
     str = run_pre_post_conversion_on_str (str, coding, 1);  
6610    
6611    from = 0;    encode_coding (coding);
   to = SCHARS (str);  
   to_byte = SBYTES (str);  
6612    
6613    /* Encoding routines determine the multibyteness of the source text    if (EQ (dst_object, Qt))
      by coding->src_multibyte.  */  
   coding->src_multibyte = STRING_MULTIBYTE (str);  
   coding->dst_multibyte = 0;  
   if (! CODING_REQUIRE_ENCODING (coding))  
6614      {      {
6615        coding->consumed = SBYTES (str);        if (BUFFERP (coding->dst_object))
6616        coding->consumed_char = SCHARS (str);          coding->dst_object = Fbuffer_string ();
6617        if (STRING_MULTIBYTE (str))        else
6618          {          {
6619            str = Fstring_as_unibyte (str);            coding->dst_object
6620            nocopy = 1;              = make_unibyte_string ((char *) coding->destination,
6621                                       coding->produced);
6622              xfree (coding->destination);
6623          }          }
       coding->produced = SBYTES (str);  
       coding->produced_char = SCHARS (str);  
       return (nocopy ? str : Fcopy_sequence (str));  
6624      }      }
6625    
6626    if (coding->composing != COMPOSITION_DISABLED)    if (saved_pt >= 0)
6627      coding_save_composition (coding, from, to, str);      {
6628          /* This is the case of:
6629    /* Try to skip the heading and tailing ASCIIs.  */           (BUFFERP (src_object) && EQ (src_object, dst_object))
6630    if (coding->type != coding_type_ccl)           As we have moved PT while replacing the original buffer
6631      {           contents, we must recover it now.  */
6632        SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),        set_buffer_internal (XBUFFER (src_object));
6633                                  1);        if (saved_pt < from)
6634        if (from == to_byte)          TEMP_SET_PT_BOTH (saved_pt, saved_pt_byte);
6635          return (nocopy ? str : Fcopy_sequence (str));        else if (saved_pt < from + chars)
6636        shrinked_bytes = from + (SBYTES (str) - to_byte);          TEMP_SET_PT_BOTH (from, from_byte);
6637          else if (! NILP (current_buffer->enable_multibyte_characters))
6638            TEMP_SET_PT_BOTH (saved_pt + (coding->produced_char - chars),
6639                              saved_pt_byte + (coding->produced - bytes));
6640          else
6641            TEMP_SET_PT_BOTH (saved_pt + (coding->produced - bytes),
6642                              saved_pt_byte + (coding->produced - bytes));
6643      }      }
6644    
6645    len = encoding_buffer_size (coding, to_byte - from);    unbind_to (count, Qnil);
6646    allocate_conversion_buffer (buf, len);  }
   
   consumed = consumed_char = produced = produced_char = 0;  
   while (1)  
     {  
       result = encode_coding (coding, SDATA (str) + from + consumed,  
                               buf.data + produced, to_byte - from - consumed,  
                               buf.size - produced);  
       consumed += coding->consumed;  
       consumed_char += coding->consumed_char;  
       produced += coding->produced;  
       produced_char += coding->produced_char;  
       if (result == CODING_FINISH_NORMAL  
           || (result == CODING_FINISH_INSUFFICIENT_SRC  
               && coding->consumed == 0))  
         break;  
       /* Now result should be CODING_FINISH_INSUFFICIENT_DST.  */  
       extend_conversion_buffer (&buf);  
     }  
6647    
   coding->consumed = consumed;  
   coding->consumed_char = consumed_char;  
   coding->produced = produced;  
   coding->produced_char = produced_char;  
   
   newstr = make_uninit_string (produced + shrinked_bytes);  
   if (from > 0)  
     STRING_COPYIN (newstr, 0, SDATA (str), from);  
   STRING_COPYIN (newstr, from, buf.data, produced);  
   if (shrinked_bytes > from)  
     STRING_COPYIN (newstr, from + produced,  
                    SDATA (str) + to_byte,  
                    shrinked_bytes - from);  
6648    
6649    free_conversion_buffer (&buf);  Lisp_Object
6650    coding_free_composition_data (coding);  preferred_coding_system ()
6651    {
6652      int id = coding_categories[coding_priorities[0]].id;
6653    
6654    return newstr;    return CODING_ID_NAME (id);
6655  }  }
6656    
6657    
# Line 6320  encode_coding_string (str, coding, nocop Line 6660  encode_coding_string (str, coding, nocop
6660    
6661  DEFUN ("coding-system-p", Fcoding_system_p, Scoding_system_p, 1, 1, 0,  DEFUN ("coding-system-p", Fcoding_system_p, Scoding_system_p, 1, 1, 0,
6662         doc: /* Return t if OBJECT is nil or a coding-system.         doc: /* Return t if OBJECT is nil or a coding-system.
6663  See the documentation of `make-coding-system' for information  See the documentation of `define-coding-system' for information
6664  about coding-system objects.  */)  about coding-system objects.  */)
6665       (obj)       (obj)
6666       Lisp_Object obj;       Lisp_Object obj;
6667  {  {
6668    if (NILP (obj))    return ((NILP (obj) || CODING_SYSTEM_P (obj)) ? Qt : Qnil);
     return Qt;  
   if (!SYMBOLP (obj))  
     return Qnil;  
   /* Get coding-spec vector for OBJ.  */  
   obj = Fget (obj, Qcoding_system);  
   return ((VECTORP (obj) && XVECTOR (obj)->size == 5)  
           ? Qt : Qnil);  
6669  }  }
6670    
6671  DEFUN ("read-non-nil-coding-system", Fread_non_nil_coding_system,  DEFUN ("read-non-nil-coding-system", Fread_non_nil_coding_system,
# Line 6359  If the user enters null input, return se Line 6692  If the user enters null input, return se
6692  {  {
6693    Lisp_Object val;    Lisp_Object val;
6694    if (SYMBOLP (default_coding_system))    if (SYMBOLP (default_coding_system))
6695      default_coding_system = SYMBOL_NAME (default_coding_system);      XSETSTRING (default_coding_system, SYMBOL_NAME (default_coding_system));
6696    val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,    val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,
6697                            Qt, Qnil, Qcoding_system_history,                            Qt, Qnil, Qcoding_system_history,
6698                            default_coding_system, Qnil);                            default_coding_system, Qnil);
# Line 6369  If the user enters null input, return se Line 6702  If the user enters null input, return se
6702  DEFUN ("check-coding-system", Fcheck_coding_system, Scheck_coding_system,  DEFUN ("check-coding-system", Fcheck_coding_system, Scheck_coding_system,
6703         1, 1, 0,         1, 1, 0,
6704         doc: /* Check validity of CODING-SYSTEM.         doc: /* Check validity of CODING-SYSTEM.
6705  If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.  If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.  */)
6706  It is valid if it is a symbol with a non-nil `coding-system' property.    (coding_system)
 The value of property should be a vector of length 5.  */)  
      (coding_system)  
6707       Lisp_Object coding_system;       Lisp_Object coding_system;
6708  {  {
6709    CHECK_SYMBOL (coding_system);    CHECK_SYMBOL (coding_system);
# Line 6381  The value of property should be a vector Line 6712  The value of property should be a vector
6712    while (1)    while (1)
6713      Fsignal (Qcoding_system_error, Fcons (coding_system, Qnil));      Fsignal (Qcoding_system_error, Fcons (coding_system, Qnil));
6714  }  }
6715    
6716    
6717    /* Detect how the bytes at SRC of length SRC_BYTES are encoded.  If
6718       HIGHEST is nonzero, return the coding system of the highest
6719       priority among the detected coding systems.  Otherwize return a
6720       list of detected coding systems sorted by their priorities.  If
6721       MULTIBYTEP is nonzero, it is assumed that the bytes are in correct
6722       multibyte form but contains only ASCII and eight-bit chars.
6723       Otherwise, the bytes are raw bytes.
6724    
6725       CODING-SYSTEM controls the detection as below:
6726    
6727       If it is nil, detect both text-format and eol-format.  If the
6728       text-format part of CODING-SYSTEM is already specified
6729       (e.g. `iso-latin-1'), detect only eol-format.  If the eol-format
6730       part of CODING-SYSTEM is already specified (e.g. `undecided-unix'),
6731       detect only text-format.  */
6732    
6733  Lisp_Object  Lisp_Object
6734  detect_coding_system (src, src_bytes, highest, multibytep)  detect_coding_system (src, src_bytes, highest, multibytep, coding_system)
6735       const unsigned char *src;       const unsigned char *src;
6736       int src_bytes, highest;       int src_bytes, highest;
6737       int multibytep;       int multibytep;
6738         Lisp_Object coding_system;
6739  {  {
6740    int coding_mask, eol_type;    const unsigned char *src_end = src + src_bytes;
6741    Lisp_Object val, tmp;    Lisp_Object attrs, eol_type;
6742    int dummy;    Lisp_Object val;
6743      struct coding_system coding;
6744      int id;
6745      struct coding_detection_info detect_info;
6746    
6747      if (NILP (coding_system))
6748        coding_system = Qundecided;
6749      setup_coding_system (coding_system, &coding);
6750      attrs = CODING_ID_ATTRS (coding.id);
6751      eol_type = CODING_ID_EOL_TYPE (coding.id);
6752      coding_system = CODING_ATTR_BASE_NAME (attrs);
6753    
6754      coding.source = src;
6755      coding.src_bytes = src_bytes;
6756      coding.src_multibyte = multibytep;
6757      coding.consumed = 0;
6758      coding.mode |= CODING_MODE_LAST_BLOCK;
6759    
6760    coding_mask = detect_coding_mask (src, src_bytes, NULL, &dummy, multibytep);    detect_info.checked = detect_info.found = detect_info.rejected = 0;
   eol_type  = detect_eol_type (src, src_bytes, &dummy);  
   if (eol_type == CODING_EOL_INCONSISTENT)  
     eol_type = CODING_EOL_UNDECIDED;  
6761    
6762    if (!coding_mask)    /* At first, detect text-format if necessary.  */
6763      if (XINT (CODING_ATTR_CATEGORY (attrs)) == coding_category_undecided)
6764      {      {
6765        val = Qundecided;        enum coding_category category;
6766        if (eol_type != CODING_EOL_UNDECIDED)        struct coding_system *this;
6767          {        int c, i;
6768            Lisp_Object val2;  
6769            val2 = Fget (Qundecided, Qeol_type);        for (; src < src_end; src++)
6770            if (VECTORP (val2))          {
6771              val = XVECTOR (val2)->contents[eol_type];            c = *src;
6772              if (c & 0x80
6773                  || (c < 0x20 && (c == ISO_CODE_ESC
6774                                   || c == ISO_CODE_SI
6775                                   || c == ISO_CODE_SO)))
6776                break;
6777          }          }
6778        return (highest ? val : Fcons (val, Qnil));        coding.head_ascii = src - coding.source;
     }  
6779    
6780    /* At first, gather possible coding systems in VAL.  */        if (src < src_end)
6781    val = Qnil;          for (i = 0; i < coding_category_raw_text; i++)
6782    for (tmp = Vcoding_category_list; CONSP (tmp); tmp = XCDR (tmp))            {
6783      {              category = coding_priorities[i];
6784        Lisp_Object category_val, category_index;              this = coding_categories + category;
6785    
6786        category_index = Fget (XCAR (tmp), Qcoding_category_index);              if (this->id < 0)
6787        category_val = Fsymbol_value (XCAR (tmp));                {
6788        if (!NILP (category_val)                  /* No coding system of this category is defined.  */
6789            && NATNUMP (category_index)                  detect_info.rejected |= (1 << category);
6790            && (coding_mask & (1 << XFASTINT (category_index))))                }
6791                else if (category >= coding_category_raw_text)
6792                  continue;
6793                else if (detect_info.checked & (1 << category))
6794                  {
6795                    if (highest
6796                        && (detect_info.found & (1 << category)))
6797                      break;
6798                  }
6799                else
6800                  {
6801                    if ((*(this->detector)) (&coding, &detect_info)
6802                        && highest
6803                        && (detect_info.found & (1 << category)))
6804                      break;
6805                  }
6806              }
6807    
6808    
6809          if (detect_info.rejected == CATEGORY_MASK_ANY)
6810          {          {
6811            val = Fcons (category_val, val);            detect_info.found = CATEGORY_MASK_RAW_TEXT;
6812            if (highest)            id = coding_categories[coding_category_raw_text].id;
6813              break;            val = Fcons (make_number (id), Qnil);
6814          }          }
6815      }        else if (! detect_info.rejected && ! detect_info.found)
6816    if (!highest)          {
6817      val = Fnreverse (val);            detect_info.found = CATEGORY_MASK_ANY;
6818              id = coding_categories[coding_category_undecided].id;
6819    /* Then, replace the elements with subsidiary coding systems.  */            val = Fcons (make_number (id), Qnil);
6820    for (tmp = val; CONSP (tmp); tmp = XCDR (tmp))          }
6821      {        else if (highest)
6822        if (eol_type != CODING_EOL_UNDECIDED          {
6823            && eol_type != CODING_EOL_INCONSISTENT)            if (detect_info.found)
6824                {
6825                  detect_info.found = 1 << category;
6826                  val = Fcons (make_number (this->id), Qnil);
6827                }
6828              else
6829                for (i = 0; i < coding_category_raw_text; i++)
6830                  if (! (detect_info.rejected & (1 << coding_priorities[i])))
6831                    {
6832                      detect_info.found = 1 << coding_priorities[i];
6833                      id = coding_categories[coding_priorities[i]].id;
6834                      val = Fcons (make_number (id), Qnil);
6835                      break;
6836                    }
6837            }
6838          else
6839          {          {
6840            Lisp_Object eol;            int mask = detect_info.rejected | detect_info.found;
6841            eol = Fget (XCAR (tmp), Qeol_type);            int found = 0;
6842            if (VECTORP (eol))            val = Qnil;
6843              XSETCAR (tmp, XVECTOR (eol)->contents[eol_type]);  
6844              for (i = coding_category_raw_text - 1; i >= 0; i--)
6845                {
6846                  category = coding_priorities[i];
6847                  if (! (mask & (1 << category)))
6848                    {
6849                      found |= 1 << category;
6850                      id = coding_categories[category].id;
6851                      val = Fcons (make_number (id), val);
6852                    }
6853                }
6854              for (i = coding_category_raw_text - 1; i >= 0; i--)
6855                {
6856                  category = coding_priorities[i];
6857                  if (detect_info.found & (1 << category))
6858                    {
6859                      id = coding_categories[category].id;
6860                      val = Fcons (make_number (id), val);
6861                    }
6862                }
6863              detect_info.found |= found;
6864          }          }
6865      }      }
6866      else
6867        {
6868          detect_info.found = 1 << XINT (CODING_ATTR_CATEGORY (attrs));
6869          val = Fcons (make_number (coding.id), Qnil);
6870        }
6871    
6872      /* Then, detect eol-format if necessary.  */
6873      {
6874        int normal_eol = -1, utf_16_be_eol = -1, utf_16_le_eol;
6875        Lisp_Object tail;
6876    
6877        if (VECTORP (eol_type))
6878          {
6879            if (detect_info.found & ~CATEGORY_MASK_UTF_16)
6880              normal_eol = detect_eol (coding.source, src_bytes,
6881                                       coding_category_raw_text);
6882            if (detect_info.found & (CATEGORY_MASK_UTF_16_BE
6883                                     | CATEGORY_MASK_UTF_16_BE_NOSIG))
6884              utf_16_be_eol = detect_eol (coding.source, src_bytes,
6885                                          coding_category_utf_16_be);
6886            if (detect_info.found & (CATEGORY_MASK_UTF_16_LE
6887                                     | CATEGORY_MASK_UTF_16_LE_NOSIG))
6888              utf_16_le_eol = detect_eol (coding.source, src_bytes,
6889                                          coding_category_utf_16_le);
6890          }
6891        else
6892          {
6893            if (EQ (eol_type, Qunix))
6894              normal_eol = utf_16_be_eol = utf_16_le_eol = EOL_SEEN_LF;
6895            else if (EQ (eol_type, Qdos))
6896              normal_eol = utf_16_be_eol = utf_16_le_eol = EOL_SEEN_CRLF;
6897            else
6898              normal_eol = utf_16_be_eol = utf_16_le_eol = EOL_SEEN_CR;
6899          }
6900    
6901        for (tail = val; CONSP (tail); tail = XCDR (tail))
6902          {
6903            enum coding_category category;
6904            int this_eol;
6905    
6906            id = XINT (XCAR (tail));
6907            attrs = CODING_ID_ATTRS (id);
6908            category = XINT (CODING_ATTR_CATEGORY (attrs));
6909            eol_type = CODING_ID_EOL_TYPE (id);
6910            if (VECTORP (eol_type))
6911              {
6912                if (category == coding_category_utf_16_be
6913                    || category == coding_category_utf_16_be_nosig)
6914                  this_eol = utf_16_be_eol;
6915                else if (category == coding_category_utf_16_le
6916                         || category == coding_category_utf_16_le_nosig)
6917                  this_eol = utf_16_le_eol;
6918                else
6919                  this_eol = normal_eol;
6920    
6921                if (this_eol == EOL_SEEN_LF)
6922                  XSETCAR (tail, AREF (eol_type, 0));
6923                else if (this_eol == EOL_SEEN_CRLF)
6924                  XSETCAR (tail, AREF (eol_type, 1));
6925                else if (this_eol == EOL_SEEN_CR)
6926                  XSETCAR (tail, AREF (eol_type, 2));
6927                else
6928                  XSETCAR (tail, CODING_ID_NAME (id));
6929              }
6930            else
6931              XSETCAR (tail, CODING_ID_NAME (id));
6932          }
6933      }
6934    
6935    return (highest ? XCAR (val) : val);    return (highest ? XCAR (val) : val);
6936  }  }
6937    
6938    
6939  DEFUN ("detect-coding-region", Fdetect_coding_region, Sdetect_coding_region,  DEFUN ("detect-coding-region", Fdetect_coding_region, Sdetect_coding_region,
6940         2, 3, 0,         2, 3, 0,
6941         doc: /* Detect how the byte sequence in the region is encoded.         doc: /* Detect coding system of the text in the region between START and END.
6942  Return a list of possible coding systems used on decoding a byte  Return a list of possible coding systems ordered by priority.
 sequence containing the bytes in the region between START and END when  
 the coding system `undecided' is specified.  The list is ordered by  
 priority decided in the current language environment.  
6943    
6944  If only ASCII characters are found, it returns a list of single element  If only ASCII characters are found, it returns a list of single element
6945  `undecided' or its subsidiary coding system according to a detected  `undecided' or its subsidiary coding system according to a detected
# Line 6464  highest priority.  */) Line 6952  highest priority.  */)
6952  {  {
6953    int from, to;    int from, to;
6954    int from_byte, to_byte;    int from_byte, to_byte;
   int include_anchor_byte = 0;  
6955    
6956    CHECK_NUMBER_COERCE_MARKER (start);    CHECK_NUMBER_COERCE_MARKER (start);
6957    CHECK_NUMBER_COERCE_MARKER (end);    CHECK_NUMBER_COERCE_MARKER (end);
# Line 6476  highest priority.  */) Line 6963  highest priority.  */)
6963    
6964    if (from < GPT && to >= GPT)    if (from < GPT && to >= GPT)
6965      move_gap_both (to, to_byte);      move_gap_both (to, to_byte);
   /* If we an anchor byte `\0' follows the region, we include it in  
      the detecting source.  Then code detectors can handle the tailing  
      byte sequence more accurately.  
6966    
      Fix me: This is not a perfect solution.  It is better that we  
      add one more argument, say LAST_BLOCK, to all detect_coding_XXX.  
   */  
   if (to == Z || (to == GPT && GAP_SIZE > 0))  
     include_anchor_byte = 1;  
6967    return detect_coding_system (BYTE_POS_ADDR (from_byte),    return detect_coding_system (BYTE_POS_ADDR (from_byte),
6968                                 to_byte - from_byte + include_anchor_byte,                                 to_byte - from_byte,
6969                                 !NILP (highest),                                 !NILP (highest),
6970                                 !NILP (current_buffer                                 !NILP (current_buffer
6971                                        ->enable_multibyte_characters));                                        ->enable_multibyte_characters),
6972                                   Qnil);
6973  }  }
6974    
6975  DEFUN ("detect-coding-string", Fdetect_coding_string, Sdetect_coding_string,  DEFUN ("detect-coding-string", Fdetect_coding_string, Sdetect_coding_string,
6976         1, 2, 0,         1, 2, 0,
6977         doc: /* Detect how the byte sequence in STRING is encoded.         doc: /* Detect coding system of the text in STRING.
6978  Return a list of possible coding systems used on decoding a byte  Return a list of possible coding systems ordered by priority.
 sequence containing the bytes in STRING when the coding system  
 `undecided' is specified.  The list is ordered by priority decided in  
 the current language environment.  
6979    
6980  If only ASCII characters are found, it returns a list of single element  If only ASCII characters are found, it returns a list of single element
6981  `undecided' or its subsidiary coding system according to a detected  `undecided' or its subsidiary coding system according to a detected
# Line 6511  highest priority.  */) Line 6988  highest priority.  */)
6988  {  {
6989    CHECK_STRING (string);    CHECK_STRING (string);
6990    
6991    return detect_coding_system (SDATA (string),    return detect_coding_system (SDATA (string), SBYTES (string),
6992                                 /* "+ 1" is to include the anchor byte                                 !NILP (highest), STRING_MULTIBYTE (string),
6993                                    `\0'.  With this, code detectors can                                 Qnil);
                                   handle the tailing bytes more  
                                   accurately.  */  
                                SBYTES (string) + 1,  
                                !NILP (highest),  
                                STRING_MULTIBYTE (string));  
6994  }  }
6995    
 /*  Subroutine for Fsafe_coding_systems_region_internal.  
6996    
6997      Return a list of coding systems that safely encode the multibyte  static INLINE int
6998      text between P and PEND.  SAFE_CODINGS, if non-nil, is an alist of  char_encodable_p (c, attrs)
6999      possible coding systems.  If it is nil, it means that we have not       int c;
7000      yet found any coding systems.       Lisp_Object attrs;
7001    {
7002      WORK_TABLE is a copy of the char-table Vchar_coding_system_table.  An    Lisp_Object tail;
7003      element of WORK_TABLE is set to t once the element is looked up.    struct charset *charset;
   
     If a non-ASCII single byte char is found, set  
     *single_byte_char_found to 1.  */  
   
 static Lisp_Object  
 find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found)  
      unsigned char *p, *pend;  
      Lisp_Object safe_codings, work_table;  
      int *single_byte_char_found;  
 {  
   int c, len;  
   Lisp_Object val, ch;  
   Lisp_Object prev, tail;  
7004    
7005    while (p < pend)    for (tail = CODING_ATTR_CHARSET_LIST (attrs);
7006           CONSP (tail); tail = XCDR (tail))
7007      {      {
7008        c = STRING_CHAR_AND_LENGTH (p, pend - p, len);        charset = CHARSET_FROM_ID (XINT (XCAR (tail)));
7009        p += len;        if (CHAR_CHARSET_P (c, charset))
7010        if (ASCII_BYTE_P (c))          break;
         /* We can ignore ASCII characters here.  */  
         continue;  
       if (SINGLE_BYTE_CHAR_P (c))  
         *single_byte_char_found = 1;  
       if (NILP (safe_codings))  
         /* Already all coding systems are excluded.  But, we can't  
            terminate the loop here because non-ASCII single-byte char  
            must be found.  */  
         continue;  
       /* Check the safe coding systems for C.  */  
       ch = make_number (c);  
       val = Faref (work_table, ch);  
       if (EQ (val, Qt))  
         /* This element was already checked.  Ignore it.  */  
         continue;  
       /* Remember that we checked this element.  */  
       Faset (work_table, ch, Qt);  
   
       for (prev = tail = safe_codings; CONSP (tail); tail = XCDR (tail))  
         {  
           Lisp_Object elt, translation_table, hash_table, accept_latin_extra;  
           int encodable;  
   
           elt = XCAR (tail);  
           if (CONSP (XCDR (elt)))  
             {  
               /* This entry has this format now:  
                  ( CODING SAFE-CHARS TRANSLATION-TABLE HASH-TABLE  
                           ACCEPT-LATIN-EXTRA ) */  
               val = XCDR (elt);  
               encodable = ! NILP (Faref (XCAR (val), ch));  
               if (! encodable)  
                 {  
                   val = XCDR (val);  
                   translation_table = XCAR (val);  
                   hash_table = XCAR (XCDR (val));  
                   accept_latin_extra = XCAR (XCDR (XCDR (val)));  
                 }  
             }  
           else  
             {  
               /* This entry has this format now: ( CODING . SAFE-CHARS) */  
               encodable = ! NILP (Faref (XCDR (elt), ch));  
               if (! encodable)  
                 {  
                   /* Transform the format to:  
                      ( CODING SAFE-CHARS TRANSLATION-TABLE HASH-TABLE  
                        ACCEPT-LATIN-EXTRA )  */  
                   val = Fget (XCAR (elt), Qcoding_system);  
                   translation_table  
                     = Fplist_get (AREF (val, 3),  
                                   Qtranslation_table_for_encode);  
                   if (SYMBOLP (translation_table))  
                     translation_table = Fget (translation_table,  
                                               Qtranslation_table);  
                   hash_table  
                     = (CHAR_TABLE_P (translation_table)  
                        ? XCHAR_TABLE (translation_table)->extras[1]  
                        : Qnil);  
                   accept_latin_extra  
                     = ((EQ (AREF (val, 0), make_number (2))  
                         && VECTORP (AREF (val, 4)))  
                        ? AREF (AREF (val, 4), 16)  
                        : Qnil);  
                   XSETCAR (tail, list5 (XCAR (elt), XCDR (elt),  
                                         translation_table, hash_table,  
                                         accept_latin_extra));  
                 }  
             }  
                 
           if (! encodable  
               && ((CHAR_TABLE_P (translation_table)  
                    && ! NILP (Faref (translation_table, ch)))  
                   || (HASH_TABLE_P (hash_table)  
                       && ! NILP (Fgethash (ch, hash_table, Qnil)))  
                   || (SINGLE_BYTE_CHAR_P (c)  
                       && ! NILP (accept_latin_extra)  
                       && VECTORP (Vlatin_extra_code_table)  
                       && ! NILP (AREF (Vlatin_extra_code_table, c)))))  
             encodable = 1;  
           if (encodable)  
             prev = tail;  
           else  
             {  
               /* Exclude this coding system from SAFE_CODINGS.  */  
               if (EQ (tail, safe_codings))  
                 safe_codings = XCDR (safe_codings);  
               else  
                 XSETCDR (prev, XCDR (tail));  
             }  
         }  
7011      }      }
7012    return safe_codings;    return (! NILP (tail));
7013  }  }
7014    
7015    
7016    /* Return a list of coding systems that safely encode the text between
7017       START and END.  If EXCLUDE is non-nil, it is a list of coding
7018       systems not to check.  The returned list doesn't contain any such
7019       coding systems.  In any case, if the text contains only ASCII or is
7020       unibyte, return t.  */
7021    
7022  DEFUN ("find-coding-systems-region-internal",  DEFUN ("find-coding-systems-region-internal",
7023         Ffind_coding_systems_region_internal,         Ffind_coding_systems_region_internal,
7024         Sfind_coding_systems_region_internal, 2, 2, 0,         Sfind_coding_systems_region_internal, 2, 3, 0,
7025         doc: /* Internal use only.  */)         doc: /* Internal use only.  */)
7026       (start, end)       (start, end, exclude)
7027       Lisp_Object start, end;       Lisp_Object start, end, exclude;
7028  {  {
7029    Lisp_Object work_table, safe_codings;    Lisp_Object coding_attrs_list, safe_codings;
7030    int non_ascii_p = 0;    EMACS_INT start_byte, end_byte;
7031    int single_byte_char_found = 0;    const unsigned char *p, *pbeg, *pend;
7032    const unsigned char *p1, *p1end, *p2, *p2end, *p;    int c;
7033      Lisp_Object tail, elt;
7034    
7035    if (STRINGP (start))    if (STRINGP (start))
7036      {      {
7037        if (!STRING_MULTIBYTE (start))        if (!STRING_MULTIBYTE (start)
7038              || SCHARS (start) == SBYTES (start))
7039          return Qt;          return Qt;
7040        p1 = SDATA (start), p1end = p1 + SBYTES (start);        start_byte = 0;
7041        p2 = p2end = p1end;        end_byte = SBYTES (start);
       if (SCHARS (start) != SBYTES (start))  
         non_ascii_p = 1;  
7042      }      }
7043    else    else
7044      {      {
       int from, to, stop;  
   
7045        CHECK_NUMBER_COERCE_MARKER (start);        CHECK_NUMBER_COERCE_MARKER (start);
7046        CHECK_NUMBER_COERCE_MARKER (end);        CHECK_NUMBER_COERCE_MARKER (end);
7047        if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end))        if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end))
7048          args_out_of_range (start, end);          args_out_of_range (start, end);
7049        if (NILP (current_buffer->enable_multibyte_characters))        if (NILP (current_buffer->enable_multibyte_characters))
7050          return Qt;          return Qt;
7051        from = CHAR_TO_BYTE (XINT (start));        start_byte = CHAR_TO_BYTE (XINT (start));
7052        to = CHAR_TO_BYTE (XINT (end));        end_byte = CHAR_TO_BYTE (XINT (end));
7053        stop = from < GPT_BYTE && GPT_BYTE < to ? GPT_BYTE : to;        if (XINT (end) - XINT (start) == end_byte - start_byte)
7054        p1 = BYTE_POS_ADDR (from), p1end = p1 + (stop - from);          return Qt;
       if (stop == to)  
         p2 = p2end = p1end;  
       else  
         p2 = BYTE_POS_ADDR (stop), p2end = p2 + (to - stop);  
       if (XINT (end) - XINT (start) != to - from)  
         non_ascii_p = 1;  
     }  
7055    
7056    if (!non_ascii_p)        if (XINT (start) < GPT && XINT (end) > GPT)
     {  
       /* We are sure that the text contains no multibyte character.  
          Check if it contains eight-bit-graphic.  */  
       p = p1;  
       for (p = p1; p < p1end && ASCII_BYTE_P (*p); p++);  
       if (p == p1end)  
7057          {          {
7058            for (p = p2; p < p2end && ASCII_BYTE_P (*p); p++);            if ((GPT - XINT (start)) < (XINT (end) - GPT))
7059            if (p == p2end)              move_gap_both (XINT (start), start_byte);
7060              return Qt;            else
7061                move_gap_both (XINT (end), end_byte);
7062          }          }
7063      }      }
7064    
7065    /* The text contains non-ASCII characters.  */    coding_attrs_list = Qnil;
7066      for (tail = Vcoding_system_list; CONSP (tail); tail = XCDR (tail))
7067        if (NILP (exclude)
7068            || NILP (Fmemq (XCAR (tail), exclude)))
7069          {
7070            Lisp_Object attrs;
7071    
7072    work_table = Fmake_char_table (Qchar_coding_system, Qnil);          attrs = AREF (CODING_SYSTEM_SPEC (XCAR (tail)), 0);
7073    safe_codings = Fcopy_sequence (XCDR (Vcoding_system_safe_chars));          if (EQ (XCAR (tail), CODING_ATTR_BASE_NAME (attrs))
7074                && ! EQ (CODING_ATTR_TYPE (attrs), Qundecided))
7075              coding_attrs_list = Fcons (attrs, coding_attrs_list);
7076          }
7077    
7078    safe_codings = find_safe_codings (p1, p1end, safe_codings, work_table,    if (STRINGP (start))
7079                                      &single_byte_char_found);      p = pbeg = SDATA (start);
   if (p2 < p2end)  
     safe_codings = find_safe_codings (p2, p2end, safe_codings, work_table,  
                                       &single_byte_char_found);  
   if (EQ (safe_codings, XCDR (Vcoding_system_safe_chars)))  
     safe_codings = Qt;  
7080    else    else
7081      {      p = pbeg = BYTE_POS_ADDR (start_byte);
7082        /* Turn safe_codings to a list of coding systems... */    pend = p + (end_byte - start_byte);
       Lisp_Object val;  
   
       if (single_byte_char_found)  
         /* ... and append these for eight-bit chars.  */  
         val = Fcons (Qraw_text,  
                      Fcons (Qemacs_mule, Fcons (Qno_conversion, Qnil)));  
       else  
         /* ... and append generic coding systems.  */  
         val = Fcopy_sequence (XCAR (Vcoding_system_safe_chars));  
   
       for (; CONSP (safe_codings); safe_codings = XCDR (safe_codings))  
         val = Fcons (XCAR (XCAR (safe_codings)), val);  
       safe_codings = val;  
     }  
   
   return safe_codings;  
 }  
   
   
 /* Search from position POS for such characters that are unencodable  
    accoding to SAFE_CHARS, and return a list of their positions.  P  
    points where in the memory the character at POS exists.  Limit the  
    search at PEND or when Nth unencodable characters are found.  
   
    If SAFE_CHARS is a char table, an element for an unencodable  
    character is nil.  
   
    If SAFE_CHARS is nil, all non-ASCII characters are unencodable.  
7083    
7084     Otherwise, SAFE_CHARS is t, and only eight-bit-contrl and    while (p < pend && ASCII_BYTE_P (*p)) p++;
7085     eight-bit-graphic characters are unencodable.  */    while (p < pend && ASCII_BYTE_P (*(pend - 1))) pend--;
7086    
 static Lisp_Object  
 unencodable_char_position (safe_chars, pos, p, pend, n)  
      Lisp_Object safe_chars;  
      int pos;  
      unsigned char *p, *pend;  
      int n;  
 {  
   Lisp_Object pos_list;  
   
   pos_list = Qnil;  
7087    while (p < pend)    while (p < pend)
7088      {      {
7089        int len;        if (ASCII_BYTE_P (*p))
7090        int c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, len);          p++;
7091          else
       if (c >= 128  
           && (CHAR_TABLE_P (safe_chars)  
               ? NILP (CHAR_TABLE_REF (safe_chars, c))  
               : (NILP (safe_chars) || c < 256)))  
7092          {          {
7093            pos_list = Fcons (make_number (pos), pos_list);            c = STRING_CHAR_ADVANCE (p);
7094            if (--n <= 0)  
7095              break;            charset_map_loaded = 0;
7096              for (tail = coding_attrs_list; CONSP (tail);)
7097                {
7098                  elt = XCAR (tail);
7099                  if (NILP (elt))
7100                    tail = XCDR (tail);
7101                  else if (char_encodable_p (c, elt))
7102                    tail = XCDR (tail);
7103                  else if (CONSP (XCDR (tail)))
7104                    {
7105                      XSETCAR (tail, XCAR (XCDR (tail)));
7106                      XSETCDR (tail, XCDR (XCDR (tail)));
7107                    }
7108                  else
7109                    {
7110                      XSETCAR (tail, Qnil);
7111                      tail = XCDR (tail);
7112                    }
7113                }
7114              if (charset_map_loaded)
7115                {
7116                  EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
7117    
7118                  if (STRINGP (start))
7119                    pbeg = SDATA (start);
7120                  else
7121                    pbeg = BYTE_POS_ADDR (start_byte);
7122                  p = pbeg + p_offset;
7123                  pend = pbeg + pend_offset;
7124                }
7125          }          }
       pos++;  
       p += len;  
7126      }      }
7127    return Fnreverse (pos_list);  
7128      safe_codings = Qnil;
7129      for (tail = coding_attrs_list; CONSP (tail); tail = XCDR (tail))
7130        if (! NILP (XCAR (tail)))
7131          safe_codings = Fcons (CODING_ATTR_BASE_NAME (XCAR (tail)), safe_codings);
7132    
7133      return safe_codings;
7134  }  }
7135    
7136    
# Line 6797  to the string.  */) Line 7152  to the string.  */)
7152       Lisp_Object start, end, coding_system, count, string;       Lisp_Object start, end, coding_system, count, string;
7153  {  {
7154    int n;    int n;
   Lisp_Object safe_chars;  
7155    struct coding_system coding;    struct coding_system coding;
7156      Lisp_Object attrs, charset_list;
7157    Lisp_Object positions;    Lisp_Object positions;
7158    int from, to;    int from, to;
7159    unsigned char *p, *pend;    const unsigned char *p, *stop, *pend;
7160      int ascii_compatible;
7161    
7162      setup_coding_system (Fcheck_coding_system (coding_system), &coding);
7163      attrs = CODING_ID_ATTRS (coding.id);
7164      if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
7165        return Qnil;
7166      ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
7167      charset_list = CODING_ATTR_CHARSET_LIST (attrs);
7168    
7169    if (NILP (string))    if (NILP (string))
7170      {      {
7171        validate_region (&start, &end);        validate_region (&start, &end);
7172        from = XINT (start);        from = XINT (start);
7173        to = XINT (end);        to = XINT (end);
7174        if (NILP (current_buffer->enable_multibyte_characters))        if (NILP (current_buffer->enable_multibyte_characters)
7175              || (ascii_compatible
7176                  && (to - from) == (CHAR_TO_BYTE (to) - (CHAR_TO_BYTE (from)))))
7177          return Qnil;          return Qnil;
7178        p = CHAR_POS_ADDR (from);        p = CHAR_POS_ADDR (from);
7179        if (to == GPT)        pend = CHAR_POS_ADDR (to);
7180          pend = GPT_ADDR;        if (from < GPT && to >= GPT)
7181            stop = GPT_ADDR;
7182        else        else
7183          pend = CHAR_POS_ADDR (to);          stop = pend;
7184      }      }
7185    else    else
7186      {      {
# Line 6829  to the string.  */) Line 7195  to the string.  */)
7195        if (! STRING_MULTIBYTE (string))        if (! STRING_MULTIBYTE (string))
7196          return Qnil;          return Qnil;
7197        p = SDATA (string) + string_char_to_byte (string, from);        p = SDATA (string) + string_char_to_byte (string, from);
7198        pend = SDATA (string) + string_char_to_byte (string, to);        stop = pend = SDATA (string) + string_char_to_byte (string, to);
7199          if (ascii_compatible && (to - from) == (pend - p))
7200            return Qnil;
7201      }      }
7202    
   setup_coding_system (Fcheck_coding_system (coding_system), &coding);  
   
7203    if (NILP (count))    if (NILP (count))
7204      n = 1;      n = 1;
7205    else    else
# Line 6842  to the string.  */) Line 7208  to the string.  */)
7208        n = XINT (count);        n = XINT (count);
7209      }      }
7210    
7211    if (coding.type == coding_type_no_conversion    positions = Qnil;
7212        || coding.type == coding_type_raw_text)    while (1)
7213      return Qnil;      {
7214          int c;
7215    
7216    if (coding.type == coding_type_undecided)        if (ascii_compatible)
7217      safe_chars = Qnil;          while (p < stop && ASCII_BYTE_P (*p))
7218    else            p++, from++;
7219      safe_chars = coding_safe_chars (coding_system);        if (p >= stop)
7220            {
7221              if (p >= pend)
7222                break;
7223              stop = pend;
7224              p = GAP_END_ADDR;
7225            }
7226    
7227          c = STRING_CHAR_ADVANCE (p);
7228          if (! (ASCII_CHAR_P (c) && ascii_compatible)
7229              && ! char_charset (c, charset_list, NULL))
7230            {
7231              positions = Fcons (make_number (from), positions);
7232              n--;
7233              if (n == 0)
7234                break;
7235            }
7236    
7237          from++;
7238        }
7239    
7240    if (STRINGP (string)    return (NILP (count) ? Fcar (positions) : Fnreverse (positions));
7241        || from >= GPT || to <= GPT)  }
7242      positions = unencodable_char_position (safe_chars, from, p, pend, n);  
7243    
7244    DEFUN ("check-coding-systems-region", Fcheck_coding_systems_region,
7245           Scheck_coding_systems_region, 3, 3, 0,
7246           doc: /* Check if the region is encodable by coding systems.
7247    
7248    START and END are buffer positions specifying the region.
7249    CODING-SYSTEM-LIST is a list of coding systems to check.
7250    
7251    The value is an alist ((CODING-SYSTEM POS0 POS1 ...) ...), where
7252    CODING-SYSTEM is a member of CODING-SYSTEM-LIst and can't encode the
7253    whole region, POS0, POS1, ... are buffer positions where non-encodable
7254    characters are found.
7255    
7256    If all coding systems in CODING-SYSTEM-LIST can encode the region, the
7257    value is nil.
7258    
7259    START may be a string.  In that case, check if the string is
7260    encodable, and the value contains indices to the string instead of
7261    buffer positions.  END is ignored.  */)
7262         (start, end, coding_system_list)
7263         Lisp_Object start, end, coding_system_list;
7264    {
7265      Lisp_Object list;
7266      EMACS_INT start_byte, end_byte;
7267      int pos;
7268      const unsigned char *p, *pbeg, *pend;
7269      int c;
7270      Lisp_Object tail, elt;
7271    
7272      if (STRINGP (start))
7273        {
7274          if (!STRING_MULTIBYTE (start)
7275              && SCHARS (start) != SBYTES (start))
7276            return Qnil;
7277          start_byte = 0;
7278          end_byte = SBYTES (start);
7279          pos = 0;
7280        }
7281    else    else
7282      {      {
7283        Lisp_Object args[2];        CHECK_NUMBER_COERCE_MARKER (start);
7284          CHECK_NUMBER_COERCE_MARKER (end);
7285          if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end))
7286            args_out_of_range (start, end);
7287          if (NILP (current_buffer->enable_multibyte_characters))
7288            return Qnil;
7289          start_byte = CHAR_TO_BYTE (XINT (start));
7290          end_byte = CHAR_TO_BYTE (XINT (end));
7291          if (XINT (end) - XINT (start) == end_byte - start_byte)
7292            return Qt;
7293    
7294          if (XINT (start) < GPT && XINT (end) > GPT)
7295            {
7296              if ((GPT - XINT (start)) < (XINT (end) - GPT))
7297                move_gap_both (XINT (start), start_byte);
7298              else
7299                move_gap_both (XINT (end), end_byte);
7300            }
7301          pos = XINT (start);
7302        }
7303    
7304      list = Qnil;
7305      for (tail = coding_system_list; CONSP (tail); tail = XCDR (tail))
7306        {
7307          elt = XCAR (tail);
7308          list = Fcons (Fcons (elt, Fcons (AREF (CODING_SYSTEM_SPEC (elt), 0),
7309                                           Qnil)),
7310                        list);
7311        }
7312    
7313      if (STRINGP (start))
7314        p = pbeg = SDATA (start);
7315      else
7316        p = pbeg = BYTE_POS_ADDR (start_byte);
7317      pend = p + (end_byte - start_byte);
7318    
7319        args[0] = unencodable_char_position (safe_chars, from, p, GPT_ADDR, n);    while (p < pend && ASCII_BYTE_P (*p)) p++, pos++;
7320        n -= XINT (Flength (args[0]));    while (p < pend && ASCII_BYTE_P (*(pend - 1))) pend--;
7321        if (n <= 0)  
7322          positions = args[0];    while (p < pend)
7323        {
7324          if (ASCII_BYTE_P (*p))
7325            p++;
7326        else        else
7327          {          {
7328            args[1] = unencodable_char_position (safe_chars, GPT, GAP_END_ADDR,            c = STRING_CHAR_ADVANCE (p);
7329                                                 pend, n);  
7330            positions = Fappend (2, args);            charset_map_loaded = 0;
7331              for (tail = list; CONSP (tail); tail = XCDR (tail))
7332                {
7333                  elt = XCDR (XCAR (tail));
7334                  if (! char_encodable_p (c, XCAR (elt)))
7335                    XSETCDR (elt, Fcons (make_number (pos), XCDR (elt)));
7336                }
7337              if (charset_map_loaded)
7338                {
7339                  EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
7340    
7341                  if (STRINGP (start))
7342                    pbeg = SDATA (start);
7343                  else
7344                    pbeg = BYTE_POS_ADDR (start_byte);
7345                  p = pbeg + p_offset;
7346                  pend = pbeg + pend_offset;
7347                }
7348          }          }
7349          pos++;
7350      }      }
7351    
7352    return  (NILP (count) ? Fcar (positions) : positions);    tail = list;
7353      list = Qnil;
7354      for (; CONSP (tail); tail = XCDR (tail))
7355        {
7356          elt = XCAR (tail);
7357          if (CONSP (XCDR (XCDR (elt))))
7358            list = Fcons (Fcons (XCAR (elt), Fnreverse (XCDR (XCDR (elt)))),
7359                          list);
7360        }
7361    
7362      return list;
7363  }  }
7364    
7365    
7366    
7367  Lisp_Object  Lisp_Object
7368  code_convert_region1 (start, end, coding_system, encodep)  code_convert_region (start, end, coding_system, dst_object, encodep, norecord)
7369       Lisp_Object start, end, coding_system;       Lisp_Object start, end, coding_system, dst_object;
7370       int encodep;       int encodep, norecord;
7371  {  {
7372    struct coding_system coding;    struct coding_system coding;
7373    int from, to;    EMACS_INT from, from_byte, to, to_byte;
7374      Lisp_Object src_object;
7375    
7376    CHECK_NUMBER_COERCE_MARKER (start);    CHECK_NUMBER_COERCE_MARKER (start);
7377    CHECK_NUMBER_COERCE_MARKER (end);    CHECK_NUMBER_COERCE_MARKER (end);
7378    CHECK_SYMBOL (coding_system);    if (NILP (coding_system))
7379        coding_system = Qno_conversion;
7380      else
7381        CHECK_CODING_SYSTEM (coding_system);
7382      src_object = Fcurrent_buffer ();
7383      if (NILP (dst_object))
7384        dst_object = src_object;
7385      else if (! EQ (dst_object, Qt))
7386        CHECK_BUFFER (dst_object);
7387    
7388    validate_region (&start, &end);    validate_region (&start, &end);
7389    from = XFASTINT (start);    from = XFASTINT (start);
7390      from_byte = CHAR_TO_BYTE (from);
7391    to = XFASTINT (end);    to = XFASTINT (end);
7392      to_byte = CHAR_TO_BYTE (to);
7393    
7394    if (NILP (coding_system))    setup_coding_system (coding_system, &coding);
     return make_number (to - from);  
   
   if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)  
     error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));  
   
7395    coding.mode |= CODING_MODE_LAST_BLOCK;    coding.mode |= CODING_MODE_LAST_BLOCK;
7396    coding.src_multibyte = coding.dst_multibyte  
7397      = !NILP (current_buffer->enable_multibyte_characters);    if (encodep)
7398    code_convert_region (from, CHAR_TO_BYTE (from), to, CHAR_TO_BYTE (to),      encode_coding_object (&coding, src_object, from, from_byte, to, to_byte,
7399                         &coding, encodep, 1);                            dst_object);
7400    Vlast_coding_system_used = coding.symbol;    else
7401    return make_number (coding.produced_char);      decode_coding_object (&coding, src_object, from, from_byte, to, to_byte,
7402                              dst_object);
7403      if (! norecord)
7404        Vlast_coding_system_used = CODING_ID_NAME (coding.id);
7405    
7406      if (coding.result != CODING_RESULT_SUCCESS)
7407        error ("Code conversion error: %d", coding.result);
7408    
7409      return (BUFFERP (dst_object)
7410              ? make_number (coding.produced_char)
7411              : coding.dst_object);
7412  }  }
7413    
7414    
7415  DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region,  DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region,
7416         3, 3, "r\nzCoding system: ",         3, 4, "r\nzCoding system: ",
7417         doc: /* Decode the current region from the specified coding system.         doc: /* Decode the current region from the specified coding system.
7418  When called from a program, takes three arguments:  When called from a program, takes four arguments:
7419  START, END, and CODING-SYSTEM.  START and END are buffer positions.          START, END, CODING-SYSTEM, and DESTINATION.
7420    START and END are buffer positions.
7421    
7422    Optional 4th arguments DESTINATION specifies where the decoded text goes.
7423    If nil, the region between START and END is replace by the decoded text.
7424    If buffer, the decoded text is inserted in the buffer.
7425    If t, the decoded text is returned.
7426    
7427  This function sets `last-coding-system-used' to the precise coding system  This function sets `last-coding-system-used' to the precise coding system
7428  used (which may be different from CODING-SYSTEM if CODING-SYSTEM is  used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
7429  not fully specified.)  not fully specified.)
7430  It returns the length of the decoded text.  */)  It returns the length of the decoded text.  */)
7431       (start, end, coding_system)       (start, end, coding_system, destination)
7432       Lisp_Object start, end, coding_system;       Lisp_Object start, end, coding_system, destination;
7433  {  {
7434    return code_convert_region1 (start, end, coding_system, 0);    return code_convert_region (start, end, coding_system, destination, 0, 0);
7435  }  }
7436    
7437  DEFUN ("encode-coding-region", Fencode_coding_region, Sencode_coding_region,  DEFUN ("encode-coding-region", Fencode_coding_region, Sencode_coding_region,
7438         3, 3, "r\nzCoding system: ",         3, 4, "r\nzCoding system: ",
7439         doc: /* Encode the current region into the specified coding system.         doc: /* Encode the current region by specified coding system.
7440  When called from a program, takes three arguments:  When called from a program, takes three arguments:
7441  START, END, and CODING-SYSTEM.  START and END are buffer positions.  START, END, and CODING-SYSTEM.  START and END are buffer positions.
7442    
7443    Optional 4th arguments DESTINATION specifies where the encoded text goes.
7444    If nil, the region between START and END is replace by the encoded text.
7445    If buffer, the encoded text is inserted in the buffer.
7446    If t, the encoded text is returned.
7447    
7448  This function sets `last-coding-system-used' to the precise coding system  This function sets `last-coding-system-used' to the precise coding system
7449  used (which may be different from CODING-SYSTEM if CODING-SYSTEM is  used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
7450  not fully specified.)  not fully specified.)
7451  It returns the length of the encoded text.  */)  It returns the length of the encoded text.  */)
7452       (start, end, coding_system)    (start, end, coding_system, destination)
7453       Lisp_Object start, end, coding_system;       Lisp_Object start, end, coding_system, destination;
7454  {  {
7455    return code_convert_region1 (start, end, coding_system, 1);    return code_convert_region (start, end, coding_system, destination, 1, 0);
7456  }  }
7457    
7458  Lisp_Object  Lisp_Object
7459  code_convert_string1 (string, coding_system, nocopy, encodep)  code_convert_string (string, coding_system, dst_object,
7460       Lisp_Object string, coding_system, nocopy;                       encodep, nocopy, norecord)
7461       int encodep;       Lisp_Object string, coding_system, dst_object;
7462         int encodep, nocopy, norecord;
7463  {  {
7464    struct coding_system coding;    struct coding_system coding;
7465      EMACS_INT chars, bytes;
7466    
7467    CHECK_STRING (string);    CHECK_STRING (string);
   CHECK_SYMBOL (coding_system);  
   
7468    if (NILP (coding_system))    if (NILP (coding_system))
7469      return (NILP (nocopy) ? Fcopy_sequence (string) : string);      {
7470          if (! norecord)
7471            Vlast_coding_system_used = Qno_conversion;
7472          if (NILP (dst_object))
7473            return (nocopy ? Fcopy_sequence (string) : string);
7474        }
7475    
7476    if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)    if (NILP (coding_system))
7477      error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));      coding_system = Qno_conversion;
7478      else
7479        CHECK_CODING_SYSTEM (coding_system);
7480      if (NILP (dst_object))
7481        dst_object = Qt;
7482      else if (! EQ (dst_object, Qt))
7483        CHECK_BUFFER (dst_object);
7484    
7485      setup_coding_system (coding_system, &coding);
7486    coding.mode |= CODING_MODE_LAST_BLOCK;    coding.mode |= CODING_MODE_LAST_BLOCK;
7487    string = (encodep    chars = SCHARS (string);
7488              ? encode_coding_string (string, &coding, !NILP (nocopy))    bytes = SBYTES (string);
7489              : decode_coding_string (string, &coding, !NILP (nocopy)));    if (encodep)
7490    Vlast_coding_system_used = coding.symbol;      encode_coding_object (&coding, string, 0, 0, chars, bytes, dst_object);
7491      else
7492    return string;      decode_coding_object (&coding, string, 0, 0, chars, bytes, dst_object);
7493  }    if (! norecord)
7494        Vlast_coding_system_used = CODING_ID_NAME (coding.id);
7495  DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string,  
7496         2, 3, 0,    if (coding.result != CODING_RESULT_SUCCESS)
7497         doc: /* Decode STRING which is encoded in CODING-SYSTEM, and return the result.      error ("Code conversion error: %d", coding.result);
7498  Optional arg NOCOPY non-nil means it is OK to return STRING itself  
7499  if the decoding operation is trivial.    return (BUFFERP (dst_object)
7500  This function sets `last-coding-system-used' to the precise coding system            ? make_number (coding.produced_char)
7501  used (which may be different from CODING-SYSTEM if CODING-SYSTEM is            : coding.dst_object);
 not fully specified.)  */)  
      (string, coding_system, nocopy)  
      Lisp_Object string, coding_system, nocopy;  
 {  
   return code_convert_string1 (string, coding_system, nocopy, 0);  
7502  }  }
7503    
 DEFUN ("encode-coding-string", Fencode_coding_string, Sencode_coding_string,  
        2, 3, 0,  
        doc: /* Encode STRING to CODING-SYSTEM, and return the result.  
 Optional arg NOCOPY non-nil means it is OK to return STRING itself  
 if the encoding operation is trivial.  
 This function sets `last-coding-system-used' to the precise coding system  
 used (which may be different from CODING-SYSTEM if CODING-SYSTEM is  
 not fully specified.)  */)  
      (string, coding_system, nocopy)  
      Lisp_Object string, coding_system, nocopy;  
 {  
   return code_convert_string1 (string, coding_system, nocopy, 1);  
 }  
7504    
7505  /* Encode or decode STRING according to CODING_SYSTEM.  /* Encode or decode STRING according to CODING_SYSTEM.
7506     Do not set Vlast_coding_system_used.     Do not set Vlast_coding_system_used.
# Line 6999  code_convert_string_norecord (string, co Line 7513  code_convert_string_norecord (string, co
7513       Lisp_Object string, coding_system;       Lisp_Object string, coding_system;
7514       int encodep;       int encodep;
7515  {  {
7516    struct coding_system coding;    return code_convert_string (string, coding_system, Qt, encodep, 0, 1);
7517    }
7518    
   CHECK_STRING (string);  
   CHECK_SYMBOL (coding_system);  
7519    
7520    if (NILP (coding_system))  DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string,
7521      return string;         2, 4, 0,
7522           doc: /* Decode STRING which is encoded in CODING-SYSTEM, and return the result.
7523    
7524    if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)  Optional third arg NOCOPY non-nil means it is OK to return STRING itself
7525      error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));  if the decoding operation is trivial.
7526    
7527    coding.composing = COMPOSITION_DISABLED;  Optional fourth arg BUFFER non-nil meant that the decoded text is
7528    coding.mode |= CODING_MODE_LAST_BLOCK;  inserted in BUFFER instead of returned as a string.  In this case,
7529    return (encodep  the return value is BUFFER.
7530            ? encode_coding_string (string, &coding, 1)  
7531            : decode_coding_string (string, &coding, 1));  This function sets `last-coding-system-used' to the precise coding system
7532    used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
7533    not fully specified.  */)
7534      (string, coding_system, nocopy, buffer)
7535         Lisp_Object string, coding_system, nocopy, buffer;
7536    {
7537      return code_convert_string (string, coding_system, buffer,
7538                                  0, ! NILP (nocopy), 0);
7539    }
7540    
7541    DEFUN ("encode-coding-string", Fencode_coding_string, Sencode_coding_string,
7542           2, 4, 0,
7543           doc: /* Encode STRING to CODING-SYSTEM, and return the result.
7544    
7545    Optional third arg NOCOPY non-nil means it is OK to return STRING
7546    itself if the encoding operation is trivial.
7547    
7548    Optional fourth arg BUFFER non-nil meant that the encoded text is
7549    inserted in BUFFER instead of returned as a string.  In this case,
7550    the return value is BUFFER.
7551    
7552    This function sets `last-coding-system-used' to the precise coding system
7553    used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
7554    not fully specified.)  */)
7555         (string, coding_system, nocopy, buffer)
7556         Lisp_Object string, coding_system, nocopy, buffer;
7557    {
7558      return code_convert_string (string, coding_system, buffer,
7559                                  1, ! NILP (nocopy), 1);
7560  }  }
7561    
7562    
7563  DEFUN ("decode-sjis-char", Fdecode_sjis_char, Sdecode_sjis_char, 1, 1, 0,  DEFUN ("decode-sjis-char", Fdecode_sjis_char, Sdecode_sjis_char, 1, 1, 0,
7564         doc: /* Decode a Japanese character which has CODE in shift_jis encoding.         doc: /* Decode a Japanese character which has CODE in shift_jis encoding.
# Line 7023  Return the corresponding character.  */) Line 7566  Return the corresponding character.  */)
7566       (code)       (code)
7567       Lisp_Object code;       Lisp_Object code;
7568  {  {
7569    unsigned char c1, c2, s1, s2;    Lisp_Object spec, attrs, val;
7570    Lisp_Object val;    struct charset *charset_roman, *charset_kanji, *charset_kana, *charset;
7571      int c;
7572    
7573    CHECK_NUMBER (code);    CHECK_NATNUM (code);
7574    s1 = (XFASTINT (code)) >> 8, s2 = (XFASTINT (code)) & 0xFF;    c = XFASTINT (code);
7575    if (s1 == 0)    CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec);
7576      {    attrs = AREF (spec, 0);
7577        if (s2 < 0x80)  
7578          XSETFASTINT (val, s2);    if (ASCII_BYTE_P (c)
7579        else if (s2 >= 0xA0 || s2 <= 0xDF)        && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
7580          XSETFASTINT (val, MAKE_CHAR (charset_katakana_jisx0201, s2, 0));      return code;
7581        else  
7582          error ("Invalid Shift JIS code: %x", XFASTINT (code));    val = CODING_ATTR_CHARSET_LIST (attrs);
7583      charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
7584      charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
7585      charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val)));
7586    
7587      if (c <= 0x7F)
7588        charset = charset_roman;
7589      else if (c >= 0xA0 && c < 0xDF)
7590        {
7591          charset = charset_kana;
7592          c -= 0x80;
7593      }      }
7594    else    else
7595      {      {
7596        if ((s1 < 0x80 || (s1 > 0x9F && s1 < 0xE0) || s1 > 0xEF)        int s1 = c >> 8, s2 = c & 0xFF;
7597            || (s2 < 0x40 || s2 == 0x7F || s2 > 0xFC))  
7598          error ("Invalid Shift JIS code: %x", XFASTINT (code));        if (s1 < 0x81 || (s1 > 0x9F && s1 < 0xE0) || s1 > 0xEF
7599        DECODE_SJIS (s1, s2, c1, c2);            || s2 < 0x40 || s2 == 0x7F || s2 > 0xFC)
7600        XSETFASTINT (val, MAKE_CHAR (charset_jisx0208, c1, c2));          error ("Invalid code: %d", code);
7601      }        SJIS_TO_JIS (c);
7602    return val;        charset = charset_kanji;
7603        }
7604      c = DECODE_CHAR (charset, c);
7605      if (c < 0)
7606        error ("Invalid code: %d", code);
7607      return make_number (c);
7608  }  }
7609    
7610    
7611  DEFUN ("encode-sjis-char", Fencode_sjis_char, Sencode_sjis_char, 1, 1, 0,  DEFUN ("encode-sjis-char", Fencode_sjis_char, Sencode_sjis_char, 1, 1, 0,
7612         doc: /* Encode a Japanese character CHAR to shift_jis encoding.         doc: /* Encode a Japanese character CHAR to shift_jis encoding.
7613  Return the corresponding code in SJIS.  */)  Return the corresponding code in SJIS.  */)
7614       (ch)       (ch)
7615       Lisp_Object ch;      Lisp_Object ch;
7616  {  {
7617    int charset, c1, c2, s1, s2;    Lisp_Object spec, attrs, charset_list;
7618    Lisp_Object val;    int c;
7619      struct charset *charset;
7620      unsigned code;
7621    
7622    CHECK_NUMBER (ch);    CHECK_CHARACTER (ch);
7623    SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);    c = XFASTINT (ch);
7624    if (charset == CHARSET_ASCII)    CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec);
7625      {    attrs = AREF (spec, 0);
7626        val = ch;  
7627      }    if (ASCII_CHAR_P (c)
7628    else if (charset == charset_jisx0208        && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
7629             && c1 > 0x20 && c1 < 0x7F && c2 > 0x20 && c2 < 0x7F)      return ch;
7630      {  
7631        ENCODE_SJIS (c1, c2, s1, s2);    charset_list = CODING_ATTR_CHARSET_LIST (attrs);
7632        XSETFASTINT (val, (s1 << 8) | s2);    charset = char_charset (c, charset_list, &code);
7633      }    if (code == CHARSET_INVALID_CODE (charset))
7634    else if (charset == charset_katakana_jisx0201      error ("Can't encode by shift_jis encoding: %d", c);
7635             && c1 > 0x20 && c2 < 0xE0)    JIS_TO_SJIS (code);
7636      {  
7637        XSETFASTINT (val, c1 | 0x80);    return make_number (code);
     }  
   else  
     error ("Can't encode to shift_jis: %d", XFASTINT (ch));  
   return val;  
7638  }  }
7639    
7640  DEFUN ("decode-big5-char", Fdecode_big5_char, Sdecode_big5_char, 1, 1, 0,  DEFUN ("decode-big5-char", Fdecode_big5_char, Sdecode_big5_char, 1, 1, 0,
# Line 7085  Return the corresponding character.  */) Line 7643  Return the corresponding character.  */)
7643       (code)       (code)
7644       Lisp_Object code;       Lisp_Object code;
7645  {  {
7646    int charset;    Lisp_Object spec, attrs, val;
7647    unsigned char b1, b2, c1, c2;    struct charset *charset_roman, *charset_big5, *charset;
7648    Lisp_Object val;    int c;
7649    
7650    CHECK_NUMBER (code);    CHECK_NATNUM (code);
7651    b1 = (XFASTINT (code)) >> 8, b2 = (XFASTINT (code)) & 0xFF;    c = XFASTINT (code);
7652    if (b1 == 0)    CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec);
7653      {    attrs = AREF (spec, 0);
7654        if (b2 >= 0x80)  
7655          error ("Invalid BIG5 code: %x", XFASTINT (code));    if (ASCII_BYTE_P (c)
7656        val = code;        && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
7657      }      return code;
7658    
7659      val = CODING_ATTR_CHARSET_LIST (attrs);
7660      charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
7661      charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
7662    
7663      if (c <= 0x7F)
7664        charset = charset_roman;
7665    else    else
7666      {      {
7667        if ((b1 < 0xA1 || b1 > 0xFE)        int b1 = c >> 8, b2 = c & 0x7F;
7668            || (b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE))        if (b1 < 0xA1 || b1 > 0xFE
7669          error ("Invalid BIG5 code: %x", XFASTINT (code));            || b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE)
7670        DECODE_BIG5 (b1, b2, charset, c1, c2);          error ("Invalid code: %d", code);
7671        XSETFASTINT (val, MAKE_CHAR (charset, c1, c2));        charset = charset_big5;
7672      }      }
7673    return val;    c = DECODE_CHAR (charset, (unsigned )c);
7674      if (c < 0)
7675        error ("Invalid code: %d", code);
7676      return make_number (c);
7677  }  }
7678    
7679  DEFUN ("encode-big5-char", Fencode_big5_char, Sencode_big5_char, 1, 1, 0,  DEFUN ("encode-big5-char", Fencode_big5_char, Sencode_big5_char, 1, 1, 0,
# Line 7114  Return the corresponding character code Line 7682  Return the corresponding character code
7682       (ch)       (ch)
7683       Lisp_Object ch;       Lisp_Object ch;
7684  {  {
7685    int charset, c1, c2, b1, b2;    Lisp_Object spec, attrs, charset_list;
7686    Lisp_Object val;    struct charset *charset;
7687      int c;
7688      unsigned code;
7689    
7690    CHECK_NUMBER (ch);    CHECK_CHARACTER (ch);
7691    SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);    c = XFASTINT (ch);
7692    if (charset == CHARSET_ASCII)    CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec);
7693      {    attrs = AREF (spec, 0);
7694        val = ch;    if (ASCII_CHAR_P (c)
7695      }        && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
7696    else if ((charset == charset_big5_1      return ch;
7697              && (XFASTINT (ch) >= 0x250a1 && XFASTINT (ch) <= 0x271ec))  
7698             || (charset == charset_big5_2    charset_list = CODING_ATTR_CHARSET_LIST (attrs);
7699                 && XFASTINT (ch) >= 0x290a1 && XFASTINT (ch) <= 0x2bdb2))    charset = char_charset (c, charset_list, &code);
7700      {    if (code == CHARSET_INVALID_CODE (charset))
7701        ENCODE_BIG5 (charset, c1, c2, b1, b2);      error ("Can't encode by Big5 encoding: %d", c);
7702        XSETFASTINT (val, (b1 << 8) | b2);  
7703      }    return make_number (code);
   else  
     error ("Can't encode to Big5: %d", XFASTINT (ch));  
   return val;  
7704  }  }
7705    
7706    
7707  DEFUN ("set-terminal-coding-system-internal", Fset_terminal_coding_system_internal,  DEFUN ("set-terminal-coding-system-internal",
7708           Fset_terminal_coding_system_internal,
7709         Sset_terminal_coding_system_internal, 1, 1, 0,         Sset_terminal_coding_system_internal, 1, 1, 0,
7710         doc: /* Internal use only.  */)         doc: /* Internal use only.  */)
7711       (coding_system)       (coding_system)
7712       Lisp_Object coding_system;       Lisp_Object coding_system;
7713  {  {
7714    CHECK_SYMBOL (coding_system);    CHECK_SYMBOL (coding_system);
7715    setup_coding_system (Fcheck_coding_system (coding_system), &terminal_coding);    setup_coding_system (Fcheck_coding_system (coding_system),
7716                            &terminal_coding);
7717    
7718    /* We had better not send unsafe characters to terminal.  */    /* We had better not send unsafe characters to terminal.  */
7719    terminal_coding.mode |= CODING_MODE_INHIBIT_UNENCODABLE_CHAR;    terminal_coding.mode |= CODING_MODE_SAFE_ENCODING;
7720    /* Character composition should be disabled.  */    /* Characer composition should be disabled.  */
7721    terminal_coding.composing = COMPOSITION_DISABLED;    terminal_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
   /* Error notification should be suppressed.  */  
   terminal_coding.suppress_error = 1;  
7722    terminal_coding.src_multibyte = 1;    terminal_coding.src_multibyte = 1;
7723    terminal_coding.dst_multibyte = 0;    terminal_coding.dst_multibyte = 0;
7724    return Qnil;    return Qnil;
7725  }  }
7726    
7727  DEFUN ("set-safe-terminal-coding-system-internal", Fset_safe_terminal_coding_system_internal,  DEFUN ("set-safe-terminal-coding-system-internal",
7728           Fset_safe_terminal_coding_system_internal,
7729         Sset_safe_terminal_coding_system_internal, 1, 1, 0,         Sset_safe_terminal_coding_system_internal, 1, 1, 0,
7730         doc: /* Internal use only.  */)         doc: /* Internal use only.  */)
7731       (coding_system)       (coding_system)
# Line 7164  DEFUN ("set-safe-terminal-coding-system- Line 7734  DEFUN ("set-safe-terminal-coding-system-
7734    CHECK_SYMBOL (coding_system);    CHECK_SYMBOL (coding_system);
7735    setup_coding_system (Fcheck_coding_system (coding_system),    setup_coding_system (Fcheck_coding_system (coding_system),
7736                         &safe_terminal_coding);                         &safe_terminal_coding);
7737    /* Character composition should be disabled.  */    /* Characer composition should be disabled.  */
7738    safe_terminal_coding.composing = COMPOSITION_DISABLED;    safe_terminal_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
   /* Error notification should be suppressed.  */  
   terminal_coding.suppress_error = 1;  
7739    safe_terminal_coding.src_multibyte = 1;    safe_terminal_coding.src_multibyte = 1;
7740    safe_terminal_coding.dst_multibyte = 0;    safe_terminal_coding.dst_multibyte = 0;
7741    return Qnil;    return Qnil;
7742  }  }
7743    
7744  DEFUN ("terminal-coding-system", Fterminal_coding_system,  DEFUN ("terminal-coding-system",
7745         Sterminal_coding_system, 0, 0, 0,         Fterminal_coding_system, Sterminal_coding_system, 0, 0, 0,
7746         doc: /* Return coding system specified for terminal output.  */)         doc: /* Return coding system specified for terminal output.  */)
7747       ()       ()
7748  {  {
7749    return terminal_coding.symbol;    return CODING_ID_NAME (terminal_coding.id);
7750  }  }
7751    
7752  DEFUN ("set-keyboard-coding-system-internal", Fset_keyboard_coding_system_internal,  DEFUN ("set-keyboard-coding-system-internal",
7753           Fset_keyboard_coding_system_internal,
7754         Sset_keyboard_coding_system_internal, 1, 1, 0,         Sset_keyboard_coding_system_internal, 1, 1, 0,
7755         doc: /* Internal use only.  */)         doc: /* Internal use only.  */)
7756       (coding_system)       (coding_system)
7757       Lisp_Object coding_system;       Lisp_Object coding_system;
7758  {  {
7759    CHECK_SYMBOL (coding_system);    CHECK_SYMBOL (coding_system);
7760    setup_coding_system (Fcheck_coding_system (coding_system), &keyboard_coding);    setup_coding_system (Fcheck_coding_system (coding_system),
7761    /* Character composition should be disabled.  */                         &keyboard_coding);
7762    keyboard_coding.composing = COMPOSITION_DISABLED;    /* Characer composition should be disabled.  */
7763      keyboard_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
7764    return Qnil;    return Qnil;
7765  }  }
7766    
7767  DEFUN ("keyboard-coding-system", Fkeyboard_coding_system,  DEFUN ("keyboard-coding-system",
7768         Skeyboard_coding_system, 0, 0, 0,         Fkeyboard_coding_system, Skeyboard_coding_system, 0, 0, 0,
7769         doc: /* Return coding system specified for decoding keyboard input.  */)         doc: /* Return coding system specified for decoding keyboard input.  */)
7770       ()       ()
7771  {  {
7772    return keyboard_coding.symbol;    return CODING_ID_NAME (keyboard_coding.id);
7773  }  }
7774    
7775    
# Line 7247  usage: (find-operation-coding-system OPE Line 7817  usage: (find-operation-coding-system OPE
7817    operation = args[0];    operation = args[0];
7818    if (!SYMBOLP (operation)    if (!SYMBOLP (operation)
7819        || !INTEGERP (target_idx = Fget (operation, Qtarget_idx)))        || !INTEGERP (target_idx = Fget (operation, Qtarget_idx)))
7820      error ("Invalid first argument");      error ("Invalid first arguement");
7821    if (nargs < 1 + XINT (target_idx))    if (nargs < 1 + XINT (target_idx))
7822      error ("Too few arguments for operation: %s",      error ("Too few arguments for operation: %s",
7823             SDATA (SYMBOL_NAME (operation)));             SDATA (SYMBOL_NAME (operation)));
   /* For write-region, if the 6th argument (i.e. VISIT, the 5th  
      argument to write-region) is string, it must be treated as a  
      target file name.  */  
   if (EQ (operation, Qwrite_region)  
       && nargs > 5  
       && STRINGP (args[5]))  
     target_idx = make_number (4);  
7824    target = args[XINT (target_idx) + 1];    target = args[XINT (target_idx) + 1];
7825    if (!(STRINGP (target)    if (!(STRINGP (target)
7826          || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))          || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
7827      error ("Invalid argument %d", XINT (target_idx) + 1);      error ("Invalid %dth argument", XINT (target_idx) + 1);
7828    
7829    chain = ((EQ (operation, Qinsert_file_contents)    chain = ((EQ (operation, Qinsert_file_contents)
7830              || EQ (operation, Qwrite_region))              || EQ (operation, Qwrite_region))
# Line 7275  usage: (find-operation-coding-system OPE Line 7838  usage: (find-operation-coding-system OPE
7838    for (; CONSP (chain); chain = XCDR (chain))    for (; CONSP (chain); chain = XCDR (chain))
7839      {      {
7840        Lisp_Object elt;        Lisp_Object elt;
       elt = XCAR (chain);  
7841    
7842          elt = XCAR (chain);
7843        if (CONSP (elt)        if (CONSP (elt)
7844            && ((STRINGP (target)            && ((STRINGP (target)
7845                 && STRINGP (XCAR (elt))                 && STRINGP (XCAR (elt))
# Line 7306  usage: (find-operation-coding-system OPE Line 7869  usage: (find-operation-coding-system OPE
7869    return Qnil;    return Qnil;
7870  }  }
7871    
7872  DEFUN ("update-coding-systems-internal",  Fupdate_coding_systems_internal,  DEFUN ("set-coding-system-priority", Fset_coding_system_priority,
7873         Supdate_coding_systems_internal, 0, 0, 0,         Sset_coding_system_priority, 0, MANY, 0,
7874         doc: /* Update internal database for ISO2022 and CCL based coding systems.         doc: /* Assign higher priority to the coding systems given as arguments.
7875  When values of any coding categories are changed, you must  If multiple coding systems belongs to the same category,
7876  call this function.  */)  all but the first one are ignored.  */)
7877       ()       (nargs, args)
7878         int nargs;
7879         Lisp_Object *args;
7880    {
7881      int i, j;
7882      int changed[coding_category_max];
7883      enum coding_category priorities[coding_category_max];
7884    
7885      bzero (changed, sizeof changed);
7886    
7887      for (i = j = 0; i < nargs; i++)
7888        {
7889          enum coding_category category;
7890          Lisp_Object spec, attrs;
7891    
7892          CHECK_CODING_SYSTEM_GET_SPEC (args[i], spec);
7893          attrs = AREF (spec, 0);
7894          category = XINT (CODING_ATTR_CATEGORY (attrs));
7895          if (changed[category])
7896            /* Ignore this coding system because a coding system of the
7897               same category already had a higher priority.  */
7898            continue;
7899          changed[category] = 1;
7900          priorities[j++] = category;
7901          if (coding_categories[category].id >= 0
7902              && ! EQ (args[i], CODING_ID_NAME (coding_categories[category].id)))
7903            setup_coding_system (args[i], &coding_categories[category]);
7904          Fset (AREF (Vcoding_category_table, category), args[i]);
7905        }
7906    
7907      /* Now we have decided top J priorities.  Reflect the order of the
7908         original priorities to the remaining priorities.  */
7909    
7910      for (i = j, j = 0; i < coding_category_max; i++, j++)
7911        {
7912          while (j < coding_category_max
7913                 && changed[coding_priorities[j]])
7914            j++;
7915          if (j == coding_category_max)
7916            abort ();
7917          priorities[i] = coding_priorities[j];
7918        }
7919    
7920      bcopy (priorities, coding_priorities, sizeof priorities);
7921    
7922      /* Update `coding-category-list'.  */
7923      Vcoding_category_list = Qnil;
7924      for (i = coding_category_max - 1; i >= 0; i--)
7925        Vcoding_category_list
7926          = Fcons (AREF (Vcoding_category_table, priorities[i]),
7927                   Vcoding_category_list);
7928    
7929      return Qnil;
7930    }
7931    
7932    DEFUN ("coding-system-priority-list", Fcoding_system_priority_list,
7933           Scoding_system_priority_list, 0, 1, 0,
7934           doc: /* Return a list of coding systems ordered by their priorities.
7935    HIGHESTP non-nil means just return the highest priority one.  */)
7936         (highestp)
7937         Lisp_Object highestp;
7938  {  {
7939    int i;    int i;
7940      Lisp_Object val;
7941    
7942    for (i = CODING_CATEGORY_IDX_EMACS_MULE; i < CODING_CATEGORY_IDX_MAX; i++)    for (i = 0, val = Qnil; i < coding_category_max; i++)
7943      {      {
7944        Lisp_Object val;        enum coding_category category = coding_priorities[i];
7945          int id = coding_categories[category].id;
7946          Lisp_Object attrs;
7947    
7948          if (id < 0)
7949            continue;
7950          attrs = CODING_ID_ATTRS (id);
7951          if (! NILP (highestp))
7952            return CODING_ATTR_BASE_NAME (attrs);
7953          val = Fcons (CODING_ATTR_BASE_NAME (attrs), val);
7954        }
7955      return Fnreverse (val);
7956    }
7957    
7958    static char *suffixes[] = { "-unix", "-dos", "-mac" };
7959    
7960    static Lisp_Object
7961    make_subsidiaries (base)
7962         Lisp_Object base;
7963    {
7964      Lisp_Object subsidiaries;
7965      int base_name_len = SBYTES (SYMBOL_NAME (base));
7966      char *buf = (char *) alloca (base_name_len + 6);
7967      int i;
7968    
7969        val = SYMBOL_VALUE (XVECTOR (Vcoding_category_table)->contents[i]);    bcopy (SDATA (SYMBOL_NAME (base)), buf, base_name_len);
7970        if (!NILP (val))    subsidiaries = Fmake_vector (make_number (3), Qnil);
7971      for (i = 0; i < 3; i++)
7972        {
7973          bcopy (suffixes[i], buf + base_name_len, strlen (suffixes[i]) + 1);
7974          ASET (subsidiaries, i, intern (buf));
7975        }
7976      return subsidiaries;
7977    }
7978    
7979    
7980    DEFUN ("define-coding-system-internal", Fdefine_coding_system_internal,
7981           Sdefine_coding_system_internal, coding_arg_max, MANY, 0,
7982           doc: /* For internal use only.
7983    usage: (define-coding-system-internal ...)  */)
7984         (nargs, args)
7985         int nargs;
7986         Lisp_Object *args;
7987    {
7988      Lisp_Object name;
7989      Lisp_Object spec_vec;         /* [ ATTRS ALIASE EOL_TYPE ] */
7990      Lisp_Object attrs;            /* Vector of attributes.  */
7991      Lisp_Object eol_type;
7992      Lisp_Object aliases;
7993      Lisp_Object coding_type, charset_list, safe_charsets;
7994      enum coding_category category;
7995      Lisp_Object tail, val;
7996      int max_charset_id = 0;
7997      int i;
7998    
7999      if (nargs < coding_arg_max)
8000        goto short_args;
8001    
8002      attrs = Fmake_vector (make_number (coding_attr_last_index), Qnil);
8003    
8004      name = args[coding_arg_name];
8005      CHECK_SYMBOL (name);
8006      CODING_ATTR_BASE_NAME (attrs) = name;
8007    
8008      val = args[coding_arg_mnemonic];
8009      if (! STRINGP (val))
8010        CHECK_CHARACTER (val);
8011      CODING_ATTR_MNEMONIC (attrs) = val;
8012    
8013      coding_type = args[coding_arg_coding_type];
8014      CHECK_SYMBOL (coding_type);
8015      CODING_ATTR_TYPE (attrs) = coding_type;
8016    
8017      charset_list = args[coding_arg_charset_list];
8018      if (SYMBOLP (charset_list))
8019        {
8020          if (EQ (charset_list, Qiso_2022))
8021          {          {
8022            if (! coding_system_table[i])            if (! EQ (coding_type, Qiso_2022))
8023              coding_system_table[i] = ((struct coding_system *)              error ("Invalid charset-list");
8024                                        xmalloc (sizeof (struct coding_system)));            charset_list = Viso_2022_charset_list;
           setup_coding_system (val, coding_system_table[i]);  
8025          }          }
8026        else if (coding_system_table[i])        else if (EQ (charset_list, Qemacs_mule))
8027          {          {
8028            xfree (coding_system_table[i]);            if (! EQ (coding_type, Qemacs_mule))
8029            coding_system_table[i] = NULL;              error ("Invalid charset-list");
8030              charset_list = Vemacs_mule_charset_list;
8031          }          }
8032          for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
8033            if (max_charset_id < XFASTINT (XCAR (tail)))
8034              max_charset_id = XFASTINT (XCAR (tail));
8035      }      }
8036      else
8037        {
8038          charset_list = Fcopy_sequence (charset_list);
8039          for (tail = charset_list; !NILP (tail); tail = Fcdr (tail))
8040            {
8041              struct charset *charset;
8042    
8043    return Qnil;            val = Fcar (tail);
8044  }            CHECK_CHARSET_GET_CHARSET (val, charset);
8045              if (EQ (coding_type, Qiso_2022)
8046                  ? CHARSET_ISO_FINAL (charset) < 0
8047                  : EQ (coding_type, Qemacs_mule)
8048                  ? CHARSET_EMACS_MULE_ID (charset) < 0
8049                  : 0)
8050                error ("Can't handle charset `%s'",
8051                       SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
8052    
8053              XSETCAR (tail, make_number (charset->id));
8054              if (max_charset_id < charset->id)
8055                max_charset_id = charset->id;
8056            }
8057        }
8058      CODING_ATTR_CHARSET_LIST (attrs) = charset_list;
8059    
8060      safe_charsets = Fmake_string (make_number (max_charset_id + 1),
8061                                    make_number (255));
8062      for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
8063        SSET (safe_charsets, XFASTINT (XCAR (tail)), 0);
8064      CODING_ATTR_SAFE_CHARSETS (attrs) = safe_charsets;
8065    
8066      CODING_ATTR_ASCII_COMPAT (attrs) = args[coding_arg_ascii_compatible_p];
8067    
8068      val = args[coding_arg_decode_translation_table];
8069      if (! NILP (val))
8070        CHECK_CHAR_TABLE (val);
8071      CODING_ATTR_DECODE_TBL (attrs) = val;
8072    
8073      val = args[coding_arg_encode_translation_table];
8074      if (! NILP (val))
8075        CHECK_CHAR_TABLE (val);
8076      CODING_ATTR_ENCODE_TBL (attrs) = val;
8077    
8078      val = args[coding_arg_post_read_conversion];
8079      CHECK_SYMBOL (val);
8080      CODING_ATTR_POST_READ (attrs) = val;
8081    
8082      val = args[coding_arg_pre_write_conversion];
8083      CHECK_SYMBOL (val);
8084      CODING_ATTR_PRE_WRITE (attrs) = val;
8085    
8086      val = args[coding_arg_default_char];
8087      if (NILP (val))
8088        CODING_ATTR_DEFAULT_CHAR (attrs) = make_number (' ');
8089      else
8090        {
8091          CHECK_CHARACTER (val);
8092          CODING_ATTR_DEFAULT_CHAR (attrs) = val;
8093        }
8094    
8095  DEFUN ("set-coding-priority-internal", Fset_coding_priority_internal,    val = args[coding_arg_for_unibyte];
8096         Sset_coding_priority_internal, 0, 0, 0,    CODING_ATTR_FOR_UNIBYTE (attrs) = NILP (val) ? Qnil : Qt;
        doc: /* Update internal database for the current value of `coding-category-list'.  
 This function is internal use only.  */)  
      ()  
 {  
   int i = 0, idx;  
   Lisp_Object val;  
8097    
8098    val = Vcoding_category_list;    val = args[coding_arg_plist];
8099      CHECK_LIST (val);
8100      CODING_ATTR_PLIST (attrs) = val;
8101    
8102    while (CONSP (val) && i < CODING_CATEGORY_IDX_MAX)    if (EQ (coding_type, Qcharset))
8103      {      {
8104        if (! SYMBOLP (XCAR (val)))        Lisp_Object list;
8105          break;        /* Generate a lisp vector of 256 elements.  Each element is nil,
8106        idx = XFASTINT (Fget (XCAR (val), Qcoding_category_index));           integer, or a list of charset IDs.
8107        if (idx >= CODING_CATEGORY_IDX_MAX)  
8108          break;           If Nth element is nil, the byte code N is invalid in this
8109        coding_priorities[i++] = (1 << idx);           coding system.
8110        val = XCDR (val);  
8111             If Nth element is a number NUM, N is the first byte of a
8112             charset whose ID is NUM.
8113    
8114             If Nth element is a list of charset IDs, N is the first byte
8115             of one of them.  The list is sorted by dimensions of the
8116             charsets.  A charset of smaller dimension comes firtst.
8117          */
8118          for (list = Qnil, tail = charset_list; CONSP (tail); tail = XCDR (tail))
8119            {
8120              struct charset *charset = CHARSET_FROM_ID (XFASTINT (XCAR (tail)));
8121    
8122              if (charset->method == CHARSET_METHOD_SUPERSET)
8123                {
8124                  val = CHARSET_SUPERSET (charset);
8125                  for (; CONSP (val); val = XCDR (val))
8126                    list = Fcons (XCAR (XCAR (val)), list);
8127                }
8128              else
8129                list = Fcons (XCAR (tail), list);
8130            }
8131    
8132          val = Fmake_vector (make_number (256), Qnil);
8133    
8134          for (tail = Fnreverse (list); CONSP (tail); tail = XCDR (tail))
8135            {
8136              struct charset *charset = CHARSET_FROM_ID (XFASTINT (XCAR (tail)));
8137              int dim = CHARSET_DIMENSION (charset);
8138              int idx = (dim - 1) * 4;
8139    
8140              if (CHARSET_ASCII_COMPATIBLE_P (charset))
8141                CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
8142    
8143              for (i = charset->code_space[idx];
8144                   i <= charset->code_space[idx + 1]; i++)
8145                {
8146                  Lisp_Object tmp, tmp2;
8147                  int dim2;
8148    
8149                  tmp = AREF (val, i);
8150                  if (NILP (tmp))
8151                    tmp = XCAR (tail);
8152                  else if (NUMBERP (tmp))
8153                    {
8154                      dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (tmp)));
8155                      if (dim < dim2)
8156                        tmp = Fcons (XCAR (tail), Fcons (tmp, Qnil));
8157                      else
8158                        tmp = Fcons (tmp, Fcons (XCAR (tail), Qnil));
8159                    }
8160                  else
8161                    {
8162                      for (tmp2 = tmp; CONSP (tmp2); tmp2 = XCDR (tmp2))
8163                        {
8164                          dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (XCAR (tmp2))));
8165                          if (dim < dim2)
8166                            break;
8167                        }
8168                      if (NILP (tmp2))
8169                        tmp = nconc2 (tmp, Fcons (XCAR (tail), Qnil));
8170                      else
8171                        {
8172                          XSETCDR (tmp2, Fcons (XCAR (tmp2), XCDR (tmp2)));
8173                          XSETCAR (tmp2, XCAR (tail));
8174                        }
8175                    }
8176                  ASET (val, i, tmp);
8177                }
8178            }
8179          ASET (attrs, coding_attr_charset_valids, val);
8180          category = coding_category_charset;
8181      }      }
8182    /* If coding-category-list is valid and contains all coding    else if (EQ (coding_type, Qccl))
8183       categories, `i' should be CODING_CATEGORY_IDX_MAX now.  If not,      {
8184       the following code saves Emacs from crashing.  */        Lisp_Object valids;
   while (i < CODING_CATEGORY_IDX_MAX)  
     coding_priorities[i++] = CODING_CATEGORY_MASK_RAW_TEXT;  
8185    
8186    return Qnil;        if (nargs < coding_arg_ccl_max)
8187  }          goto short_args;
8188    
8189  DEFUN ("define-coding-system-internal", Fdefine_coding_system_internal,        val = args[coding_arg_ccl_decoder];
8190         Sdefine_coding_system_internal, 1, 1, 0,        CHECK_CCL_PROGRAM (val);
8191         doc: /* Register CODING-SYSTEM as a base coding system.        if (VECTORP (val))
8192  This function is internal use only.  */)          val = Fcopy_sequence (val);
8193       (coding_system)        ASET (attrs, coding_attr_ccl_decoder, val);
      Lisp_Object coding_system;  
 {  
   Lisp_Object safe_chars, slot;  
8194    
8195    if (NILP (Fcheck_coding_system (coding_system)))        val = args[coding_arg_ccl_encoder];
8196      Fsignal (Qcoding_system_error, Fcons (coding_system, Qnil));        CHECK_CCL_PROGRAM (val);
8197    safe_chars = coding_safe_chars (coding_system);        if (VECTORP (val))
8198    if (! EQ (safe_chars, Qt) && ! CHAR_TABLE_P (safe_chars))          val = Fcopy_sequence (val);
8199      error ("No valid safe-chars property for %s",        ASET (attrs, coding_attr_ccl_encoder, val);
8200             SDATA (SYMBOL_NAME (coding_system)));  
8201    if (EQ (safe_chars, Qt))        val = args[coding_arg_ccl_valids];
8202      {        valids = Fmake_string (make_number (256), make_number (0));
8203        if (NILP (Fmemq (coding_system, XCAR (Vcoding_system_safe_chars))))        for (tail = val; !NILP (tail); tail = Fcdr (tail))
8204          XSETCAR (Vcoding_system_safe_chars,          {
8205                   Fcons (coding_system, XCAR (Vcoding_system_safe_chars)));            int from, to;
8206    
8207              val = Fcar (tail);
8208              if (INTEGERP (val))
8209                {
8210                  from = to = XINT (val);
8211                  if (from < 0 || from > 255)
8212                    args_out_of_range_3 (val, make_number (0), make_number (255));
8213                }
8214              else
8215                {
8216                  CHECK_CONS (val);
8217                  CHECK_NATNUM_CAR (val);
8218                  CHECK_NATNUM_CDR (val);
8219                  from = XINT (XCAR (val));
8220                  if (from > 255)
8221                    args_out_of_range_3 (XCAR (val),
8222                                         make_number (0), make_number (255));
8223                  to = XINT (XCDR (val));
8224                  if (to < from || to > 255)
8225                    args_out_of_range_3 (XCDR (val),
8226                                         XCAR (val), make_number (255));
8227                }
8228              for (i = from; i <= to; i++)
8229                SSET (valids, i, 1);
8230            }
8231          ASET (attrs, coding_attr_ccl_valids, valids);
8232    
8233          category = coding_category_ccl;
8234        }
8235      else if (EQ (coding_type, Qutf_16))
8236        {
8237          Lisp_Object bom, endian;
8238    
8239          CODING_ATTR_ASCII_COMPAT (attrs) = Qnil;
8240    
8241          if (nargs < coding_arg_utf16_max)
8242            goto short_args;
8243    
8244          bom = args[coding_arg_utf16_bom];
8245          if (! NILP (bom) && ! EQ (bom, Qt))
8246            {
8247              CHECK_CONS (bom);
8248              val = XCAR (bom);
8249              CHECK_CODING_SYSTEM (val);
8250              val = XCDR (bom);
8251              CHECK_CODING_SYSTEM (val);
8252            }
8253          ASET (attrs, coding_attr_utf_16_bom, bom);
8254    
8255          endian = args[coding_arg_utf16_endian];
8256          CHECK_SYMBOL (endian);
8257          if (NILP (endian))
8258            endian = Qbig;
8259          else if (! EQ (endian, Qbig) && ! EQ (endian, Qlittle))
8260            error ("Invalid endian: %s", SDATA (SYMBOL_NAME (endian)));
8261          ASET (attrs, coding_attr_utf_16_endian, endian);
8262    
8263          category = (CONSP (bom)
8264                      ? coding_category_utf_16_auto
8265                      : NILP (bom)
8266                      ? (EQ (endian, Qbig)
8267                         ? coding_category_utf_16_be_nosig
8268                         : coding_category_utf_16_le_nosig)
8269                      : (EQ (endian, Qbig)
8270                         ? coding_category_utf_16_be
8271                         : coding_category_utf_16_le));
8272      }      }
8273    else    else if (EQ (coding_type, Qiso_2022))
8274      {      {
8275        slot = Fassq (coding_system, XCDR (Vcoding_system_safe_chars));        Lisp_Object initial, reg_usage, request, flags;
8276        if (NILP (slot))        int i;
8277          XSETCDR (Vcoding_system_safe_chars,  
8278                   nconc2 (XCDR (Vcoding_system_safe_chars),        if (nargs < coding_arg_iso2022_max)
8279                           Fcons (Fcons (coding_system, safe_chars), Qnil)));          goto short_args;
8280    
8281          initial = Fcopy_sequence (args[coding_arg_iso2022_initial]);
8282          CHECK_VECTOR (initial);
8283          for (i = 0; i < 4; i++)
8284            {
8285              val = Faref (initial, make_number (i));
8286              if (! NILP (val))
8287                {
8288                  struct charset *charset;
8289    
8290                  CHECK_CHARSET_GET_CHARSET (val, charset);
8291                  ASET (initial, i, make_number (CHARSET_ID (charset)));
8292                  if (i == 0 && CHARSET_ASCII_COMPATIBLE_P (charset))
8293                    CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
8294                }
8295              else
8296                ASET (initial, i, make_number (-1));
8297            }
8298    
8299          reg_usage = args[coding_arg_iso2022_reg_usage];
8300          CHECK_CONS (reg_usage);
8301          CHECK_NUMBER_CAR (reg_usage);
8302          CHECK_NUMBER_CDR (reg_usage);
8303    
8304          request = Fcopy_sequence (args[coding_arg_iso2022_request]);
8305          for (tail = request; ! NILP (tail); tail = Fcdr (tail))
8306            {
8307              int id;
8308              Lisp_Object tmp;
8309    
8310              val = Fcar (tail);
8311              CHECK_CONS (val);
8312              tmp = XCAR (val);
8313              CHECK_CHARSET_GET_ID (tmp, id);
8314              CHECK_NATNUM_CDR (val);
8315              if (XINT (XCDR (val)) >= 4)
8316                error ("Invalid graphic register number: %d", XINT (XCDR (val)));
8317              XSETCAR (val, make_number (id));
8318            }
8319    
8320          flags = args[coding_arg_iso2022_flags];
8321          CHECK_NATNUM (flags);
8322          i = XINT (flags);
8323          if (EQ (args[coding_arg_charset_list], Qiso_2022))
8324            flags = make_number (i | CODING_ISO_FLAG_FULL_SUPPORT);
8325    
8326          ASET (attrs, coding_attr_iso_initial, initial);
8327          ASET (attrs, coding_attr_iso_usage, reg_usage);
8328          ASET (attrs, coding_attr_iso_request, request);
8329          ASET (attrs, coding_attr_iso_flags, flags);
8330          setup_iso_safe_charsets (attrs);
8331    
8332          if (i & CODING_ISO_FLAG_SEVEN_BITS)
8333            category = ((i & (CODING_ISO_FLAG_LOCKING_SHIFT
8334                              | CODING_ISO_FLAG_SINGLE_SHIFT))
8335                        ? coding_category_iso_7_else
8336                        : EQ (args[coding_arg_charset_list], Qiso_2022)
8337                        ? coding_category_iso_7
8338                        : coding_category_iso_7_tight);
8339        else        else
8340          XSETCDR (slot, safe_chars);          {
8341              int id = XINT (AREF (initial, 1));
8342    
8343              category = (((i & CODING_ISO_FLAG_LOCKING_SHIFT)
8344                           || EQ (args[coding_arg_charset_list], Qiso_2022)
8345                           || id < 0)
8346                          ? coding_category_iso_8_else
8347                          : (CHARSET_DIMENSION (CHARSET_FROM_ID (id)) == 1)
8348                          ? coding_category_iso_8_1
8349                          : coding_category_iso_8_2);
8350            }
8351          if (category != coding_category_iso_8_1
8352              && category != coding_category_iso_8_2)
8353            CODING_ATTR_ASCII_COMPAT (attrs) = Qnil;
8354        }
8355      else if (EQ (coding_type, Qemacs_mule))
8356        {
8357          if (EQ (args[coding_arg_charset_list], Qemacs_mule))
8358            ASET (attrs, coding_attr_emacs_mule_full, Qt);
8359          CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
8360          category = coding_category_emacs_mule;
8361        }
8362      else if (EQ (coding_type, Qshift_jis))
8363        {
8364    
8365          struct charset *charset;
8366    
8367          if (XINT (Flength (charset_list)) != 3)
8368            error ("There should be just three charsets");
8369    
8370          charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
8371          if (CHARSET_DIMENSION (charset) != 1)
8372            error ("Dimension of charset %s is not one",
8373                   SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
8374          if (CHARSET_ASCII_COMPATIBLE_P (charset))
8375            CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
8376    
8377          charset_list = XCDR (charset_list);
8378          charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
8379          if (CHARSET_DIMENSION (charset) != 1)
8380            error ("Dimension of charset %s is not one",
8381                   SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
8382    
8383          charset_list = XCDR (charset_list);
8384          charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
8385          if (CHARSET_DIMENSION (charset) != 2)
8386            error ("Dimension of charset %s is not two",
8387                   SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
8388    
8389          category = coding_category_sjis;
8390          Vsjis_coding_system = name;
8391        }
8392      else if (EQ (coding_type, Qbig5))
8393        {
8394          struct charset *charset;
8395    
8396          if (XINT (Flength (charset_list)) != 2)
8397            error ("There should be just two charsets");
8398    
8399          charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
8400          if (CHARSET_DIMENSION (charset) != 1)
8401            error ("Dimension of charset %s is not one",
8402                   SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
8403          if (CHARSET_ASCII_COMPATIBLE_P (charset))
8404            CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
8405    
8406          charset_list = XCDR (charset_list);
8407          charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
8408          if (CHARSET_DIMENSION (charset) != 2)
8409            error ("Dimension of charset %s is not two",
8410                   SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
8411    
8412          category = coding_category_big5;
8413          Vbig5_coding_system = name;
8414        }
8415      else if (EQ (coding_type, Qraw_text))
8416        {
8417          category = coding_category_raw_text;
8418          CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
8419        }
8420      else if (EQ (coding_type, Qutf_8))
8421        {
8422          category = coding_category_utf_8;
8423          CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
8424        }
8425      else if (EQ (coding_type, Qundecided))
8426        category = coding_category_undecided;
8427      else
8428        error ("Invalid coding system type: %s",
8429               SDATA (SYMBOL_NAME (coding_type)));
8430    
8431      CODING_ATTR_CATEGORY (attrs) = make_number (category);
8432      CODING_ATTR_PLIST (attrs)
8433        = Fcons (QCcategory, Fcons (AREF (Vcoding_category_table, category),
8434                                    CODING_ATTR_PLIST (attrs)));
8435    
8436      eol_type = args[coding_arg_eol_type];
8437      if (! NILP (eol_type)
8438          && ! EQ (eol_type, Qunix)
8439          && ! EQ (eol_type, Qdos)
8440          && ! EQ (eol_type, Qmac))
8441        error ("Invalid eol-type");
8442    
8443      aliases = Fcons (name, Qnil);
8444    
8445      if (NILP (eol_type))
8446        {
8447          eol_type = make_subsidiaries (name);
8448          for (i = 0; i < 3; i++)
8449            {
8450              Lisp_Object this_spec, this_name, this_aliases, this_eol_type;
8451    
8452              this_name = AREF (eol_type, i);
8453              this_aliases = Fcons (this_name, Qnil);
8454              this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac);
8455              this_spec = Fmake_vector (make_number (3), attrs);
8456              ASET (this_spec, 1, this_aliases);
8457              ASET (this_spec, 2, this_eol_type);
8458              Fputhash (this_name, this_spec, Vcoding_system_hash_table);
8459              Vcoding_system_list = Fcons (this_name, Vcoding_system_list);
8460              Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (this_name), Qnil),
8461                                            Vcoding_system_alist);
8462            }
8463      }      }
8464    
8465      spec_vec = Fmake_vector (make_number (3), attrs);
8466      ASET (spec_vec, 1, aliases);
8467      ASET (spec_vec, 2, eol_type);
8468    
8469      Fputhash (name, spec_vec, Vcoding_system_hash_table);
8470      Vcoding_system_list = Fcons (name, Vcoding_system_list);
8471      Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (name), Qnil),
8472                                    Vcoding_system_alist);
8473    
8474      {
8475        int id = coding_categories[category].id;
8476    
8477        if (id < 0 || EQ (name, CODING_ID_NAME (id)))
8478          setup_coding_system (name, &coding_categories[category]);
8479      }
8480    
8481    return Qnil;    return Qnil;
8482    
8483     short_args:
8484      return Fsignal (Qwrong_number_of_arguments,
8485                      Fcons (intern ("define-coding-system-internal"),
8486                             make_number (nargs)));
8487    }
8488    
8489    /* Fixme: should this record the alias relationships for
8490       diagnostics?  Should it update coding-system-list?  */
8491    DEFUN ("define-coding-system-alias", Fdefine_coding_system_alias,
8492           Sdefine_coding_system_alias, 2, 2, 0,
8493           doc: /* Define ALIAS as an alias for CODING-SYSTEM.  */)
8494         (alias, coding_system)
8495         Lisp_Object alias, coding_system;
8496    {
8497      Lisp_Object spec, aliases, eol_type;
8498    
8499      CHECK_SYMBOL (alias);
8500      CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
8501      aliases = AREF (spec, 1);
8502      while (!NILP (XCDR (aliases)))
8503        aliases = XCDR (aliases);
8504      XSETCDR (aliases, Fcons (alias, Qnil));
8505    
8506      eol_type = AREF (spec, 2);
8507      if (VECTORP (eol_type))
8508        {
8509          Lisp_Object subsidiaries;
8510          int i;
8511    
8512          subsidiaries = make_subsidiaries (alias);
8513          for (i = 0; i < 3; i++)
8514            Fdefine_coding_system_alias (AREF (subsidiaries, i),
8515                                         AREF (eol_type, i));
8516    
8517          ASET (spec, 2, subsidiaries);
8518        }
8519    
8520      Fputhash (alias, spec, Vcoding_system_hash_table);
8521      Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (alias), Qnil),
8522                                    Vcoding_system_alist);
8523    
8524      return Qnil;
8525    }
8526    
8527    DEFUN ("coding-system-base", Fcoding_system_base, Scoding_system_base,
8528           1, 1, 0,
8529           doc: /* Return the base of CODING-SYSTEM.
8530    Any alias or subsidiary coding system is not a base coding system.  */)
8531      (coding_system)
8532         Lisp_Object coding_system;
8533    {
8534      Lisp_Object spec, attrs;
8535    
8536      if (NILP (coding_system))
8537        return (Qno_conversion);
8538      CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
8539      attrs = AREF (spec, 0);
8540      return CODING_ATTR_BASE_NAME (attrs);
8541    }
8542    
8543    DEFUN ("coding-system-plist", Fcoding_system_plist, Scoding_system_plist,
8544           1, 1, 0,
8545           doc: "Return the property list of CODING-SYSTEM.")
8546         (coding_system)
8547         Lisp_Object coding_system;
8548    {
8549      Lisp_Object spec, attrs;
8550    
8551      if (NILP (coding_system))
8552        coding_system = Qno_conversion;
8553      CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
8554      attrs = AREF (spec, 0);
8555      return CODING_ATTR_PLIST (attrs);
8556    }
8557    
8558    
8559    DEFUN ("coding-system-aliases", Fcoding_system_aliases, Scoding_system_aliases,
8560           1, 1, 0,
8561           doc: /* Return the list of aliases of CODING-SYSTEM.  */)
8562         (coding_system)
8563         Lisp_Object coding_system;
8564    {
8565      Lisp_Object spec;
8566    
8567      if (NILP (coding_system))
8568        coding_system = Qno_conversion;
8569      CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
8570      return AREF (spec, 1);
8571    }
8572    
8573    DEFUN ("coding-system-eol-type", Fcoding_system_eol_type,
8574           Scoding_system_eol_type, 1, 1, 0,
8575           doc: /* Return eol-type of CODING-SYSTEM.
8576    An eol-type is integer 0, 1, 2, or a vector of coding systems.
8577    
8578    Integer values 0, 1, and 2 indicate a format of end-of-line; LF, CRLF,
8579    and CR respectively.
8580    
8581    A vector value indicates that a format of end-of-line should be
8582    detected automatically.  Nth element of the vector is the subsidiary
8583    coding system whose eol-type is N.  */)
8584         (coding_system)
8585         Lisp_Object coding_system;
8586    {
8587      Lisp_Object spec, eol_type;
8588      int n;
8589    
8590      if (NILP (coding_system))
8591        coding_system = Qno_conversion;
8592      if (! CODING_SYSTEM_P (coding_system))
8593        return Qnil;
8594      spec = CODING_SYSTEM_SPEC (coding_system);
8595      eol_type = AREF (spec, 2);
8596      if (VECTORP (eol_type))
8597        return Fcopy_sequence (eol_type);
8598      n = EQ (eol_type, Qunix) ? 0 : EQ (eol_type, Qdos) ? 1 : 2;
8599      return make_number (n);
8600  }  }
8601    
8602  #endif /* emacs */  #endif /* emacs */
# Line 7411  init_coding_once () Line 8609  init_coding_once ()
8609  {  {
8610    int i;    int i;
8611    
8612    /* Emacs' internal format specific initialize routine.  */    for (i = 0; i < coding_category_max; i++)
8613    for (i = 0; i <= 0x20; i++)      {
8614      emacs_code_class[i] = EMACS_control_code;        coding_categories[i].id = -1;
8615    emacs_code_class[0x0A] = EMACS_linefeed_code;        coding_priorities[i] = i;
8616    emacs_code_class[0x0D] = EMACS_carriage_return_code;      }
   for (i = 0x21 ; i < 0x7F; i++)  
     emacs_code_class[i] = EMACS_ascii_code;  
   emacs_code_class[0x7F] = EMACS_control_code;  
   for (i = 0x80; i < 0xFF; i++)  
     emacs_code_class[i] = EMACS_invalid_code;  
   emacs_code_class[LEADING_CODE_PRIVATE_11] = EMACS_leading_code_3;  
   emacs_code_class[LEADING_CODE_PRIVATE_12] = EMACS_leading_code_3;  
   emacs_code_class[LEADING_CODE_PRIVATE_21] = EMACS_leading_code_4;  
   emacs_code_class[LEADING_CODE_PRIVATE_22] = EMACS_leading_code_4;  
8617    
8618    /* ISO2022 specific initialize routine.  */    /* ISO2022 specific initialize routine.  */
8619    for (i = 0; i < 0x20; i++)    for (i = 0; i < 0x20; i++)
# Line 7446  init_coding_once () Line 8635  init_coding_once ()
8635    iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3;    iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3;
8636    iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer;    iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer;
8637    
   setup_coding_system (Qnil, &keyboard_coding);  
   setup_coding_system (Qnil, &terminal_coding);  
   setup_coding_system (Qnil, &safe_terminal_coding);  
   setup_coding_system (Qnil, &default_buffer_file_coding);  
   
   bzero (coding_system_table, sizeof coding_system_table);  
   
   bzero (ascii_skip_code, sizeof ascii_skip_code);  
   for (i = 0; i < 128; i++)  
     ascii_skip_code[i] = 1;  
   
 #if defined (MSDOS) || defined (WINDOWSNT)  
   system_eol_type = CODING_EOL_CRLF;  
 #else  
   system_eol_type = CODING_EOL_LF;  
 #endif  
   
8638    inhibit_pre_post_conversion = 0;    inhibit_pre_post_conversion = 0;
8639    
8640      for (i = 0; i < 256; i++)
8641        {
8642          emacs_mule_bytes[i] = 1;
8643        }
8644      emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_11] = 3;
8645      emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_12] = 3;
8646      emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_21] = 4;
8647      emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_22] = 4;
8648  }  }
8649    
8650  #ifdef emacs  #ifdef emacs
# Line 7471  init_coding_once () Line 8652  init_coding_once ()
8652  void  void
8653  syms_of_coding ()  syms_of_coding ()
8654  {  {
8655    Qtarget_idx = intern ("target-idx");    staticpro (&Vcoding_system_hash_table);
8656    staticpro (&Qtarget_idx);    {
8657        Lisp_Object args[2];
8658        args[0] = QCtest;
8659        args[1] = Qeq;
8660        Vcoding_system_hash_table = Fmake_hash_table (2, args);
8661      }
8662    
8663      staticpro (&Vsjis_coding_system);
8664      Vsjis_coding_system = Qnil;
8665    
8666    Qcoding_system_history = intern ("coding-system-history");    staticpro (&Vbig5_coding_system);
8667    staticpro (&Qcoding_system_history);    Vbig5_coding_system = Qnil;
8668    
8669      staticpro (&Vcode_conversion_work_buf_list);
8670      Vcode_conversion_work_buf_list = Qnil;
8671    
8672      staticpro (&Vcode_conversion_reused_work_buf);
8673      Vcode_conversion_reused_work_buf = Qnil;
8674    
8675      DEFSYM (Qcharset, "charset");
8676      DEFSYM (Qtarget_idx, "target-idx");
8677      DEFSYM (Qcoding_system_history, "coding-system-history");
8678    Fset (Qcoding_system_history, Qnil);    Fset (Qcoding_system_history, Qnil);
8679    
8680    /* Target FILENAME is the first argument.  */    /* Target FILENAME is the first argument.  */
# Line 7483  syms_of_coding () Line 8682  syms_of_coding ()
8682    /* Target FILENAME is the third argument.  */    /* Target FILENAME is the third argument.  */
8683    Fput (Qwrite_region, Qtarget_idx, make_number (2));    Fput (Qwrite_region, Qtarget_idx, make_number (2));
8684    
8685    Qcall_process = intern ("call-process");    DEFSYM (Qcall_process, "call-process");
   staticpro (&Qcall_process);  
8686    /* Target PROGRAM is the first argument.  */    /* Target PROGRAM is the first argument.  */
8687    Fput (Qcall_process, Qtarget_idx, make_number (0));    Fput (Qcall_process, Qtarget_idx, make_number (0));
8688    
8689    Qcall_process_region = intern ("call-process-region");    DEFSYM (Qcall_process_region, "call-process-region");
   staticpro (&Qcall_process_region);  
8690    /* Target PROGRAM is the third argument.  */    /* Target PROGRAM is the third argument.  */
8691    Fput (Qcall_process_region, Qtarget_idx, make_number (2));    Fput (Qcall_process_region, Qtarget_idx, make_number (2));
8692    
8693    Qstart_process = intern ("start-process");    DEFSYM (Qstart_process, "start-process");
   staticpro (&Qstart_process);  
8694    /* Target PROGRAM is the third argument.  */    /* Target PROGRAM is the third argument.  */
8695    Fput (Qstart_process, Qtarget_idx, make_number (2));    Fput (Qstart_process, Qtarget_idx, make_number (2));
8696    
8697    Qopen_network_stream = intern ("open-network-stream");    DEFSYM (Qopen_network_stream, "open-network-stream");
   staticpro (&Qopen_network_stream);  
8698    /* Target SERVICE is the fourth argument.  */    /* Target SERVICE is the fourth argument.  */
8699    Fput (Qopen_network_stream, Qtarget_idx, make_number (3));    Fput (Qopen_network_stream, Qtarget_idx, make_number (3));
8700    
8701    Qcoding_system = intern ("coding-system");    DEFSYM (Qcoding_system, "coding-system");
8702    staticpro (&Qcoding_system);    DEFSYM (Qcoding_aliases, "coding-aliases");
8703    
8704    Qeol_type = intern ("eol-type");    DEFSYM (Qeol_type, "eol-type");
8705    staticpro (&Qeol_type);    DEFSYM (Qunix, "unix");
8706      DEFSYM (Qdos, "dos");
8707    
8708    Qbuffer_file_coding_system = intern ("buffer-file-coding-system");    DEFSYM (Qbuffer_file_coding_system, "buffer-file-coding-system");
8709    staticpro (&Qbuffer_file_coding_system);    DEFSYM (Qpost_read_conversion, "post-read-conversion");
8710      DEFSYM (Qpre_write_conversion, "pre-write-conversion");
8711      DEFSYM (Qdefault_char, "default-char");
8712      DEFSYM (Qundecided, "undecided");
8713      DEFSYM (Qno_conversion, "no-conversion");
8714      DEFSYM (Qraw_text, "raw-text");
8715    
8716    Qpost_read_conversion = intern ("post-read-conversion");    DEFSYM (Qiso_2022, "iso-2022");
   staticpro (&Qpost_read_conversion);  
8717    
8718    Qpre_write_conversion = intern ("pre-write-conversion");    DEFSYM (Qutf_8, "utf-8");
8719    staticpro (&Qpre_write_conversion);    DEFSYM (Qutf_8_emacs, "utf-8-emacs");
8720    
8721    Qno_conversion = intern ("no-conversion");    DEFSYM (Qutf_16, "utf-16");
8722    staticpro (&Qno_conversion);    DEFSYM (Qbig, "big");
8723      DEFSYM (Qlittle, "little");
8724    
8725    Qundecided = intern ("undecided");    DEFSYM (Qshift_jis, "shift-jis");
8726    staticpro (&Qundecided);    DEFSYM (Qbig5, "big5");
8727    
8728    Qcoding_system_p = intern ("coding-system-p");    DEFSYM (Qcoding_system_p, "coding-system-p");
   staticpro (&Qcoding_system_p);  
   
   Qcoding_system_error = intern ("coding-system-error");  
   staticpro (&Qcoding_system_error);  
8729    
8730      DEFSYM (Qcoding_system_error, "coding-system-error");
8731    Fput (Qcoding_system_error, Qerror_conditions,    Fput (Qcoding_system_error, Qerror_conditions,
8732          Fcons (Qcoding_system_error, Fcons (Qerror, Qnil)));          Fcons (Qcoding_system_error, Fcons (Qerror, Qnil)));
8733    Fput (Qcoding_system_error, Qerror_message,    Fput (Qcoding_system_error, Qerror_message,
8734          build_string ("Invalid coding system"));          build_string ("Invalid coding system"));
8735    
   Qcoding_category = intern ("coding-category");  
   staticpro (&Qcoding_category);  
   Qcoding_category_index = intern ("coding-category-index");  
   staticpro (&Qcoding_category_index);  
   
   Vcoding_category_table  
     = Fmake_vector (make_number (CODING_CATEGORY_IDX_MAX), Qnil);  
   staticpro (&Vcoding_category_table);  
   {  
     int i;  
     for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++)  
       {  
         XVECTOR (Vcoding_category_table)->contents[i]  
           = intern (coding_category_name[i]);  
         Fput (XVECTOR (Vcoding_category_table)->contents[i],  
               Qcoding_category_index, make_number (i));  
       }  
   }  
   
   Vcoding_system_safe_chars = Fcons (Qnil, Qnil);  
   staticpro (&Vcoding_system_safe_chars);  
   
   Qtranslation_table = intern ("translation-table");  
   staticpro (&Qtranslation_table);  
   Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (2));  
   
   Qtranslation_table_id = intern ("translation-table-id");  
   staticpro (&Qtranslation_table_id);  
   
   Qtranslation_table_for_decode = intern ("translation-table-for-decode");  
   staticpro (&Qtranslation_table_for_decode);  
   
   Qtranslation_table_for_encode = intern ("translation-table-for-encode");  
   staticpro (&Qtranslation_table_for_encode);  
   
   Qsafe_chars = intern ("safe-chars");  
   staticpro (&Qsafe_chars);  
   
   Qchar_coding_system = intern ("char-coding-system");  
   staticpro (&Qchar_coding_system);  
   
8736    /* Intern this now in case it isn't already done.    /* Intern this now in case it isn't already done.
8737       Setting this variable twice is harmless.       Setting this variable twice is harmless.
8738       But don't staticpro it here--that is done in alloc.c.  */       But don't staticpro it here--that is done in alloc.c.  */
8739    Qchar_table_extra_slots = intern ("char-table-extra-slots");    Qchar_table_extra_slots = intern ("char-table-extra-slots");
   Fput (Qsafe_chars, Qchar_table_extra_slots, make_number (0));  
   Fput (Qchar_coding_system, Qchar_table_extra_slots, make_number (0));  
8740    
8741    Qvalid_codes = intern ("valid-codes");    DEFSYM (Qtranslation_table, "translation-table");
8742    staticpro (&Qvalid_codes);    Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (1));
8743      DEFSYM (Qtranslation_table_id, "translation-table-id");
8744      DEFSYM (Qtranslation_table_for_decode, "translation-table-for-decode");
8745      DEFSYM (Qtranslation_table_for_encode, "translation-table-for-encode");
8746    
8747    Qemacs_mule = intern ("emacs-mule");    DEFSYM (Qvalid_codes, "valid-codes");
   staticpro (&Qemacs_mule);  
8748    
8749    Qraw_text = intern ("raw-text");    DEFSYM (Qemacs_mule, "emacs-mule");
   staticpro (&Qraw_text);  
8750    
8751    Qutf_8 = intern ("utf-8");    DEFSYM (QCcategory, ":category");
8752    staticpro (&Qutf_8);  
8753      Vcoding_category_table
8754        = Fmake_vector (make_number (coding_category_max), Qnil);
8755      staticpro (&Vcoding_category_table);
8756      /* Followings are target of code detection.  */
8757      ASET (Vcoding_category_table, coding_category_iso_7,
8758            intern ("coding-category-iso-7"));
8759      ASET (Vcoding_category_table, coding_category_iso_7_tight,
8760            intern ("coding-category-iso-7-tight"));
8761      ASET (Vcoding_category_table, coding_category_iso_8_1,
8762            intern ("coding-category-iso-8-1"));
8763      ASET (Vcoding_category_table, coding_category_iso_8_2,
8764            intern ("coding-category-iso-8-2"));
8765      ASET (Vcoding_category_table, coding_category_iso_7_else,
8766            intern ("coding-category-iso-7-else"));
8767      ASET (Vcoding_category_table, coding_category_iso_8_else,
8768            intern ("coding-category-iso-8-else"));
8769      ASET (Vcoding_category_table, coding_category_utf_8,
8770            intern ("coding-category-utf-8"));
8771      ASET (Vcoding_category_table, coding_category_utf_16_be,
8772            intern ("coding-category-utf-16-be"));
8773      ASET (Vcoding_category_table, coding_category_utf_16_auto,
8774            intern ("coding-category-utf-16-auto"));
8775      ASET (Vcoding_category_table, coding_category_utf_16_le,
8776            intern ("coding-category-utf-16-le"));
8777      ASET (Vcoding_category_table, coding_category_utf_16_be_nosig,
8778            intern ("coding-category-utf-16-be-nosig"));
8779      ASET (Vcoding_category_table, coding_category_utf_16_le_nosig,
8780            intern ("coding-category-utf-16-le-nosig"));
8781      ASET (Vcoding_category_table, coding_category_charset,
8782            intern ("coding-category-charset"));
8783      ASET (Vcoding_category_table, coding_category_sjis,
8784            intern ("coding-category-sjis"));
8785      ASET (Vcoding_category_table, coding_category_big5,
8786            intern ("coding-category-big5"));
8787      ASET (Vcoding_category_table, coding_category_ccl,
8788            intern ("coding-category-ccl"));
8789      ASET (Vcoding_category_table, coding_category_emacs_mule,
8790            intern ("coding-category-emacs-mule"));
8791      /* Followings are NOT target of code detection.  */
8792      ASET (Vcoding_category_table, coding_category_raw_text,
8793            intern ("coding-category-raw-text"));
8794      ASET (Vcoding_category_table, coding_category_undecided,
8795            intern ("coding-category-undecided"));
8796    
8797    defsubr (&Scoding_system_p);    defsubr (&Scoding_system_p);
8798    defsubr (&Sread_coding_system);    defsubr (&Sread_coding_system);
# Line 7603  syms_of_coding () Line 8802  syms_of_coding ()
8802    defsubr (&Sdetect_coding_string);    defsubr (&Sdetect_coding_string);
8803    defsubr (&Sfind_coding_systems_region_internal);    defsubr (&Sfind_coding_systems_region_internal);
8804    defsubr (&Sunencodable_char_position);    defsubr (&Sunencodable_char_position);
8805      defsubr (&Scheck_coding_systems_region);
8806    defsubr (&Sdecode_coding_region);    defsubr (&Sdecode_coding_region);
8807    defsubr (&Sencode_coding_region);    defsubr (&Sencode_coding_region);
8808    defsubr (&Sdecode_coding_string);    defsubr (&Sdecode_coding_string);
# Line 7617  syms_of_coding () Line 8817  syms_of_coding ()
8817    defsubr (&Sset_keyboard_coding_system_internal);    defsubr (&Sset_keyboard_coding_system_internal);
8818    defsubr (&Skeyboard_coding_system);    defsubr (&Skeyboard_coding_system);
8819    defsubr (&Sfind_operation_coding_system);    defsubr (&Sfind_operation_coding_system);
8820    defsubr (&Supdate_coding_systems_internal);    defsubr (&Sset_coding_system_priority);
   defsubr (&Sset_coding_priority_internal);  
8821    defsubr (&Sdefine_coding_system_internal);    defsubr (&Sdefine_coding_system_internal);
8822      defsubr (&Sdefine_coding_system_alias);
8823      defsubr (&Scoding_system_base);
8824      defsubr (&Scoding_system_plist);
8825      defsubr (&Scoding_system_aliases);
8826      defsubr (&Scoding_system_eol_type);
8827      defsubr (&Scoding_system_priority_list);
8828    
8829    DEFVAR_LISP ("coding-system-list", &Vcoding_system_list,    DEFVAR_LISP ("coding-system-list", &Vcoding_system_list,
8830                 doc: /* List of coding systems.                 doc: /* List of coding systems.
8831    
8832  Do not alter the value of this variable manually.  This variable should be  Do not alter the value of this variable manually.  This variable should be
8833  updated by the functions `make-coding-system' and  updated by the functions `define-coding-system' and
8834  `define-coding-system-alias'.  */);  `define-coding-system-alias'.  */);
8835    Vcoding_system_list = Qnil;    Vcoding_system_list = Qnil;
8836    
# Line 7650  system bound to the corresponding coding Line 8855  system bound to the corresponding coding
8855      int i;      int i;
8856    
8857      Vcoding_category_list = Qnil;      Vcoding_category_list = Qnil;
8858      for (i = CODING_CATEGORY_IDX_MAX - 1; i >= 0; i--)      for (i = coding_category_max - 1; i >= 0; i--)
8859        Vcoding_category_list        Vcoding_category_list
8860          = Fcons (XVECTOR (Vcoding_category_table)->contents[i],          = Fcons (XVECTOR (Vcoding_category_table)->contents[i],
8861                   Vcoding_category_list);                   Vcoding_category_list);
# Line 7680  the value of `buffer-file-coding-system' Line 8885  the value of `buffer-file-coding-system'
8885    Vcoding_system_for_write = Qnil;    Vcoding_system_for_write = Qnil;
8886    
8887    DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used,    DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used,
8888                 doc: /* Coding system used in the latest file or process I/O.                 doc: /*
8889  Also set by `encode-coding-region', `decode-coding-region',  Coding system used in the latest file or process I/O.  */);
 `encode-coding-string' and `decode-coding-string'.  */);  
8890    Vlast_coding_system_used = Qnil;    Vlast_coding_system_used = Qnil;
8891    
8892    DEFVAR_BOOL ("inhibit-eol-conversion", &inhibit_eol_conversion,    DEFVAR_BOOL ("inhibit-eol-conversion", &inhibit_eol_conversion,
8893                 doc: /* *Non-nil means always inhibit code conversion of end-of-line format.                 doc: /*
8894    *Non-nil means always inhibit code conversion of end-of-line format.
8895  See info node `Coding Systems' and info node `Text and Binary' concerning  See info node `Coding Systems' and info node `Text and Binary' concerning
8896  such conversion.  */);  such conversion.  */);
8897    inhibit_eol_conversion = 0;    inhibit_eol_conversion = 0;
8898    
8899    DEFVAR_BOOL ("inherit-process-coding-system", &inherit_process_coding_system,    DEFVAR_BOOL ("inherit-process-coding-system", &inherit_process_coding_system,
8900                 doc: /* Non-nil means process buffer inherits coding system of process output.                 doc: /*
8901    Non-nil means process buffer inherits coding system of process output.
8902  Bind it to t if the process output is to be treated as if it were a file  Bind it to t if the process output is to be treated as if it were a file
8903  read from some filesystem.  */);  read from some filesystem.  */);
8904    inherit_process_coding_system = 0;    inherit_process_coding_system = 0;
8905    
8906    DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist,    DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist,
8907                 doc: /* Alist to decide a coding system to use for a file I/O operation.                 doc: /*
8908    Alist to decide a coding system to use for a file I/O operation.
8909  The format is ((PATTERN . VAL) ...),  The format is ((PATTERN . VAL) ...),
8910  where PATTERN is a regular expression matching a file name,  where PATTERN is a regular expression matching a file name,
8911  VAL is a coding system, a cons of coding systems, or a function symbol.  VAL is a coding system, a cons of coding systems, or a function symbol.
# Line 7708  If VAL is a cons of coding systems, the Line 8915  If VAL is a cons of coding systems, the
8915  and the cdr part is used for encoding.  and the cdr part is used for encoding.
8916  If VAL is a function symbol, the function must return a coding system  If VAL is a function symbol, the function must return a coding system
8917  or a cons of coding systems which are used as above.  The function gets  or a cons of coding systems which are used as above.  The function gets
8918  the arguments with which `find-operation-coding-system' was called.  the arguments with which `find-operation-coding-systems' was called.
8919    
8920  See also the function `find-operation-coding-system'  See also the function `find-operation-coding-system'
8921  and the variable `auto-coding-alist'.  */);  and the variable `auto-coding-alist'.  */);
8922    Vfile_coding_system_alist = Qnil;    Vfile_coding_system_alist = Qnil;
8923    
8924    DEFVAR_LISP ("process-coding-system-alist", &Vprocess_coding_system_alist,    DEFVAR_LISP ("process-coding-system-alist", &Vprocess_coding_system_alist,
8925      doc: /* Alist to decide a coding system to use for a process I/O operation.                 doc: /*
8926    Alist to decide a coding system to use for a process I/O operation.
8927  The format is ((PATTERN . VAL) ...),  The format is ((PATTERN . VAL) ...),
8928  where PATTERN is a regular expression matching a program name,  where PATTERN is a regular expression matching a program name,
8929  VAL is a coding system, a cons of coding systems, or a function symbol.  VAL is a coding system, a cons of coding systems, or a function symbol.
# Line 7730  See also the function `find-operation-co Line 8938  See also the function `find-operation-co
8938    Vprocess_coding_system_alist = Qnil;    Vprocess_coding_system_alist = Qnil;
8939    
8940    DEFVAR_LISP ("network-coding-system-alist", &Vnetwork_coding_system_alist,    DEFVAR_LISP ("network-coding-system-alist", &Vnetwork_coding_system_alist,
8941      doc: /* Alist to decide a coding system to use for a network I/O operation.                 doc: /*
8942    Alist to decide a coding system to use for a network I/O operation.
8943  The format is ((PATTERN . VAL) ...),  The format is ((PATTERN . VAL) ...),
8944  where PATTERN is a regular expression matching a network service name  where PATTERN is a regular expression matching a network service name
8945  or is a port number to connect to,  or is a port number to connect to,
# Line 7752  Also used for decoding keyboard input on Line 8961  Also used for decoding keyboard input on
8961    
8962    /* The eol mnemonics are reset in startup.el system-dependently.  */    /* The eol mnemonics are reset in startup.el system-dependently.  */
8963    DEFVAR_LISP ("eol-mnemonic-unix", &eol_mnemonic_unix,    DEFVAR_LISP ("eol-mnemonic-unix", &eol_mnemonic_unix,
8964                 doc: /* *String displayed in mode line for UNIX-like (LF) end-of-line format.  */);                 doc: /*
8965    *String displayed in mode line for UNIX-like (LF) end-of-line format.  */);
8966    eol_mnemonic_unix = build_string (":");    eol_mnemonic_unix = build_string (":");
8967    
8968    DEFVAR_LISP ("eol-mnemonic-dos", &eol_mnemonic_dos,    DEFVAR_LISP ("eol-mnemonic-dos", &eol_mnemonic_dos,
8969                 doc: /* *String displayed in mode line for DOS-like (CRLF) end-of-line format.  */);                 doc: /*
8970    *String displayed in mode line for DOS-like (CRLF) end-of-line format.  */);
8971    eol_mnemonic_dos = build_string ("\\");    eol_mnemonic_dos = build_string ("\\");
8972    
8973    DEFVAR_LISP ("eol-mnemonic-mac", &eol_mnemonic_mac,    DEFVAR_LISP ("eol-mnemonic-mac", &eol_mnemonic_mac,
8974                 doc: /* *String displayed in mode line for MAC-like (CR) end-of-line format.  */);                 doc: /*
8975    *String displayed in mode line for MAC-like (CR) end-of-line format.  */);
8976    eol_mnemonic_mac = build_string ("/");    eol_mnemonic_mac = build_string ("/");
8977    
8978    DEFVAR_LISP ("eol-mnemonic-undecided", &eol_mnemonic_undecided,    DEFVAR_LISP ("eol-mnemonic-undecided", &eol_mnemonic_undecided,
8979                 doc: /* *String displayed in mode line when end-of-line format is not yet determined.  */);                 doc: /*
8980    *String displayed in mode line when end-of-line format is not yet determined.  */);
8981    eol_mnemonic_undecided = build_string (":");    eol_mnemonic_undecided = build_string (":");
8982    
8983    DEFVAR_LISP ("enable-character-translation", &Venable_character_translation,    DEFVAR_LISP ("enable-character-translation", &Venable_character_translation,
8984                 doc: /* *Non-nil enables character translation while encoding and decoding.  */);                 doc: /*
8985    *Non-nil enables character translation while encoding and decoding.  */);
8986    Venable_character_translation = Qt;    Venable_character_translation = Qt;
8987    
8988    DEFVAR_LISP ("standard-translation-table-for-decode",    DEFVAR_LISP ("standard-translation-table-for-decode",
# Line 7781  Also used for decoding keyboard input on Line 8995  Also used for decoding keyboard input on
8995                 doc: /* Table for translating characters while encoding.  */);                 doc: /* Table for translating characters while encoding.  */);
8996    Vstandard_translation_table_for_encode = Qnil;    Vstandard_translation_table_for_encode = Qnil;
8997    
8998    DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_alist,    DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_table,
8999                 doc: /* Alist of charsets vs revision numbers.                 doc: /* Alist of charsets vs revision numbers.
9000  While encoding, if a charset (car part of an element) is found,  While encoding, if a charset (car part of an element) is found,
9001  designate it with the escape sequence identifying revision (cdr part of the element).  */);  designate it with the escape sequence identifying revision (cdr part
9002    Vcharset_revision_alist = Qnil;  of the element).  */);
9003      Vcharset_revision_table = Qnil;
9004    
9005    DEFVAR_LISP ("default-process-coding-system",    DEFVAR_LISP ("default-process-coding-system",
9006                 &Vdefault_process_coding_system,                 &Vdefault_process_coding_system,
# Line 7795  the cdr part is used for encoding a text Line 9010  the cdr part is used for encoding a text
9010    Vdefault_process_coding_system = Qnil;    Vdefault_process_coding_system = Qnil;
9011    
9012    DEFVAR_LISP ("latin-extra-code-table", &Vlatin_extra_code_table,    DEFVAR_LISP ("latin-extra-code-table", &Vlatin_extra_code_table,
9013                 doc: /* Table of extra Latin codes in the range 128..159 (inclusive).                 doc: /*
9014    Table of extra Latin codes in the range 128..159 (inclusive).
9015  This is a vector of length 256.  This is a vector of length 256.
9016  If Nth element is non-nil, the existence of code N in a file  If Nth element is non-nil, the existence of code N in a file
9017  \(or output of subprocess) doesn't prevent it to be detected as  \(or output of subprocess) doesn't prevent it to be detected as
# Line 7807  Only 128th through 159th elements has a Line 9023  Only 128th through 159th elements has a
9023    
9024    DEFVAR_LISP ("select-safe-coding-system-function",    DEFVAR_LISP ("select-safe-coding-system-function",
9025                 &Vselect_safe_coding_system_function,                 &Vselect_safe_coding_system_function,
9026                 doc: /* Function to call to select safe coding system for encoding a text.                 doc: /*
9027    Function to call to select safe coding system for encoding a text.
9028    
9029  If set, this function is called to force a user to select a proper  If set, this function is called to force a user to select a proper
9030  coding system which can encode the text in the case that a default  coding system which can encode the text in the case that a default
# Line 7827  called even if `coding-system-for-write' Line 9044  called even if `coding-system-for-write'
9044    
9045    DEFVAR_BOOL ("inhibit-iso-escape-detection",    DEFVAR_BOOL ("inhibit-iso-escape-detection",
9046                 &inhibit_iso_escape_detection,                 &inhibit_iso_escape_detection,
9047                 doc: /* If non-nil, Emacs ignores ISO2022's escape sequence on code detection.                 doc: /*
9048    If non-nil, Emacs ignores ISO2022's escape sequence on code detection.
9049    
9050  By default, on reading a file, Emacs tries to detect how the text is  By default, on reading a file, Emacs tries to detect how the text is
9051  encoded.  This code detection is sensitive to escape sequences.  If  encoded.  This code detection is sensitive to escape sequences.  If
# Line 7857  escape sequence (e.g `latin-1') on readi Line 9075  escape sequence (e.g `latin-1') on readi
9075  This is applied to the result of input methods, not their input.  See also  This is applied to the result of input methods, not their input.  See also
9076  `keyboard-translate-table'.  */);  `keyboard-translate-table'.  */);
9077      Vtranslation_table_for_input = Qnil;      Vtranslation_table_for_input = Qnil;
9078    
9079      {
9080        Lisp_Object args[coding_arg_max];
9081        Lisp_Object plist[16];
9082        int i;
9083    
9084        for (i = 0; i < coding_arg_max; i++)
9085          args[i] = Qnil;
9086    
9087        plist[0] = intern (":name");
9088        plist[1] = args[coding_arg_name] = Qno_conversion;
9089        plist[2] = intern (":mnemonic");
9090        plist[3] = args[coding_arg_mnemonic] = make_number ('=');
9091        plist[4] = intern (":coding-type");
9092        plist[5] = args[coding_arg_coding_type] = Qraw_text;
9093        plist[6] = intern (":ascii-compatible-p");
9094        plist[7] = args[coding_arg_ascii_compatible_p] = Qt;
9095        plist[8] = intern (":default-char");
9096        plist[9] = args[coding_arg_default_char] = make_number (0);
9097        plist[10] = intern (":for-unibyte");
9098        plist[11] = args[coding_arg_for_unibyte] = Qt;
9099        plist[12] = intern (":docstring");
9100        plist[13] = build_string ("Do no conversion.\n\
9101    \n\
9102    When you visit a file with this coding, the file is read into a\n\
9103    unibyte buffer as is, thus each byte of a file is treated as a\n\
9104    character.");
9105        plist[14] = intern (":eol-type");
9106        plist[15] = args[coding_arg_eol_type] = Qunix;
9107        args[coding_arg_plist] = Flist (16, plist);
9108        Fdefine_coding_system_internal (coding_arg_max, args);
9109      }
9110    
9111      setup_coding_system (Qno_conversion, &keyboard_coding);
9112      setup_coding_system (Qno_conversion, &terminal_coding);
9113      setup_coding_system (Qno_conversion, &safe_terminal_coding);
9114    
9115      {
9116        int i;
9117    
9118        for (i = 0; i < coding_category_max; i++)
9119          Fset (AREF (Vcoding_category_table, i), Qno_conversion);
9120      }
9121  }  }
9122    
9123  char *  char *
# Line 7880  emacs_strerror (error_number) Line 9141  emacs_strerror (error_number)
9141  }  }
9142    
9143  #endif /* emacs */  #endif /* emacs */
   

Legend:
Removed from v.1.289  
changed lines
  Added in v.1.289.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26