2 |
Copyright (C) 1995, 1997, 1998 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 Free Software Foundation, Inc. |
Copyright (C) 2001 Free Software Foundation, Inc. |
5 |
|
Copyright (C) 2001, 2002 |
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 |
|
|
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 |
Coding system is an encoding mechanism of one or more character |
50 |
sets. Here's a list of coding systems which Emacs can handle. When |
sets. Here's a list of coding system types supported by Emacs. |
51 |
we say "decode", it means converting some other coding system to |
When we say "decode", it means converting a text encoded by some |
52 |
Emacs' internal format (emacs-mule), and when we say "encode", |
coding system into Emacs' internal format (emacs-utf-8), and when we |
53 |
it means converting the coding system emacs-mule to some other |
say "encode", it means converting a text of emacs-utf-8 to some |
54 |
coding system. |
other coding system. |
55 |
|
|
56 |
0. Emacs' internal format (emacs-mule) |
Emacs represents a coding system by a Lisp symbol. Each symbol is a |
57 |
|
key to the hash table Vcharset_hash_table. This hash table |
58 |
|
associates the symbol to the corresponding detailed specifications. |
59 |
|
|
60 |
Emacs itself holds a multi-lingual character in buffers and strings |
Before using a coding system for decoding and encoding, we setup a |
61 |
in a special format. Details are described in section 2. |
structure of type `struct coding_system'. This structure keeps |
62 |
|
various information about a specific code conversion (e.g. the |
63 |
|
location of source and destination data). |
64 |
|
|
65 |
1. ISO2022 |
Coding systems are classified into the following types by how to |
66 |
|
represent a character in a byte sequence. Here's a brief descrition |
67 |
|
about type. |
68 |
|
|
69 |
The most famous coding system for multiple character sets. X's |
o Emacs' internal format (emacs-utf-8) |
70 |
Compound Text, various EUCs (Extended Unix Code), and coding |
|
71 |
systems used in Internet communication such as ISO-2022-JP are |
The extended UTF-8 which allows eight-bit raw bytes mixed with |
72 |
all variants of ISO2022. Details are described in section 3. |
character codes. Emacs holds characters in buffers and strings by |
73 |
|
this format. |
74 |
|
|
75 |
|
o UTF-8 |
76 |
|
|
77 |
|
o UTF-16 |
78 |
|
|
79 |
|
o Charset-base coding system |
80 |
|
|
81 |
2. SJIS (or Shift-JIS or MS-Kanji-Code) |
A coding system defined by one or more (coded) character sets. |
82 |
|
Decoding and encoding are done by code converter defined for each |
83 |
|
character set. |
84 |
|
|
85 |
|
o Old Emacs' internal format (emacs-mule) |
86 |
|
|
87 |
|
The coding system adopted by an old versions of Emacs (20 and 21). |
88 |
|
|
89 |
|
o ISO2022-base coding system |
90 |
|
|
91 |
|
The most famous coding system for multiple character sets. X's |
92 |
|
Compound Text, various EUCs (Extended Unix Code), and coding systems |
93 |
|
used in the Internet communication such as ISO-2022-JP are all |
94 |
|
variants of ISO2022. |
95 |
|
|
96 |
|
o SJIS (or Shift-JIS or MS-Kanji-Code) |
97 |
|
|
98 |
A coding system to encode character sets: ASCII, JISX0201, and |
A coding system to encode character sets: ASCII, JISX0201, and |
99 |
JISX0208. Widely used for PC's in Japan. Details are described in |
JISX0208. Widely used for PC's in Japan. Details are described in |
100 |
section 4. |
section 8. |
101 |
|
|
102 |
3. BIG5 |
o BIG5 |
103 |
|
|
104 |
A coding system to encode the character sets ASCII and Big5. Widely |
A coding system to encode character sets: ASCII and Big5. Widely |
105 |
used for Chinese (mainly in Taiwan and Hong Kong). Details are |
used by Chinese (mainly in Taiwan and Hong Kong). Details are |
106 |
described in section 4. In this file, when we write "BIG5" |
described in section 8. In this file, when we write "big5" (all |
107 |
(all uppercase), we mean the coding system, and when we write |
lowercase), we mean the coding system, and when we write "Big5" |
108 |
"Big5" (capitalized), we mean the character set. |
(capitalized), we mean the character set. |
109 |
|
|
110 |
4. Raw text |
o CCL |
111 |
|
|
112 |
A coding system for text containing random 8-bit code. Emacs does |
If a user wants to decode/encode a text encoded in a coding system |
113 |
no code conversion on such text except for end-of-line format. |
not listed above, he can supply a decoder and an encoder for it in |
114 |
|
CCL (Code Conversion Language) programs. Emacs executes the CCL |
115 |
|
program while decoding/encoding. |
116 |
|
|
117 |
5. Other |
o Raw-text |
118 |
|
|
119 |
If a user wants to read/write text encoded in a coding system not |
A coding system for a text containing raw eight-bit data. Emacs |
120 |
listed above, he can supply a decoder and an encoder for it as CCL |
treat each byte of source text as a character (except for |
121 |
(Code Conversion Language) programs. Emacs executes the CCL program |
end-of-line conversion). |
|
while reading/writing. |
|
122 |
|
|
123 |
Emacs represents a coding system by a Lisp symbol that has a property |
o No-conversion |
124 |
`coding-system'. But, before actually using the coding system, the |
|
125 |
information about it is set in a structure of type `struct |
Like raw text, but don't do end-of-line conversion. |
|
coding_system' for rapid processing. See section 6 for more details. |
|
126 |
|
|
|
*/ |
|
127 |
|
|
128 |
/*** GENERAL NOTES on END-OF-LINE FORMAT *** |
END-OF-LINE FORMAT |
129 |
|
|
130 |
How end-of-line of text is encoded depends on the operating system. |
How end-of-line of a text is encoded depends on a system. For |
131 |
For instance, Unix's format is just one byte of `line-feed' code, |
instance, Unix's format is just one byte of LF (line-feed) code, |
132 |
whereas DOS's format is two-byte sequence of `carriage-return' and |
whereas DOS's format is two-byte sequence of `carriage-return' and |
133 |
`line-feed' codes. MacOS's format is usually one byte of |
`line-feed' codes. MacOS's format is usually one byte of |
134 |
`carriage-return'. |
`carriage-return'. |
135 |
|
|
136 |
Since text character encoding and end-of-line encoding are |
Since text characters encoding and end-of-line encoding are |
137 |
independent, any coding system described above can have any |
independent, any coding system described above can take any format |
138 |
end-of-line format. So Emacs has information about end-of-line |
of end-of-line (except for no-conversion). |
|
format in each coding-system. See section 6 for more details. |
|
139 |
|
|
140 |
*/ |
*/ |
141 |
|
|
142 |
|
/* COMMON MACROS */ |
143 |
|
|
144 |
|
|
145 |
/*** GENERAL NOTES on `detect_coding_XXX ()' functions *** |
/*** GENERAL NOTES on `detect_coding_XXX ()' functions *** |
146 |
|
|
147 |
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 |
148 |
in the coding system category XXX. Each returns an integer value in |
CODING conforms to the format of XXX. Return 1 if the data contains |
149 |
which appropriate flag bits for the category XXX are set. The flag |
a byte sequence which can be decoded into non-ASCII characters by |
150 |
bits are defined in macros CODING_CATEGORY_MASK_XXX. Below is the |
the coding system. Otherwize (i.e. the data contains only ASCII |
151 |
template for these functions. If MULTIBYTEP is nonzero, 8-bit codes |
characters or invalid sequence) return 0. |
152 |
of the range 0x80..0x9F are in multibyte form. */ |
|
153 |
|
It also resets some bits of an integer pointed by MASK. The macros |
154 |
|
CATEGORY_MASK_XXX specifies each bit of this integer. |
155 |
|
|
156 |
|
Below is the template of these functions. */ |
157 |
|
|
158 |
#if 0 |
#if 0 |
159 |
int |
static int |
160 |
detect_coding_emacs_mule (src, src_end, multibytep) |
detect_coding_XXX (coding, mask) |
161 |
unsigned char *src, *src_end; |
struct coding_system *coding; |
162 |
int multibytep; |
int *mask; |
163 |
{ |
{ |
164 |
... |
unsigned char *src = coding->source; |
165 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
166 |
|
int multibytep = coding->src_multibyte; |
167 |
|
int c; |
168 |
|
int found = 0; |
169 |
|
...; |
170 |
|
|
171 |
|
while (1) |
172 |
|
{ |
173 |
|
/* Get one byte from the source. If the souce is exausted, jump |
174 |
|
to no_more_source:. */ |
175 |
|
ONE_MORE_BYTE (c); |
176 |
|
/* Check if it conforms to XXX. If not, break the loop. */ |
177 |
|
} |
178 |
|
/* As the data is invalid for XXX, reset a proper bits. */ |
179 |
|
*mask &= ~CODING_CATEGORY_XXX; |
180 |
|
return 0; |
181 |
|
no_more_source: |
182 |
|
/* The source exausted. */ |
183 |
|
if (!found) |
184 |
|
/* ASCII characters only. */ |
185 |
|
return 0; |
186 |
|
/* Some data should be decoded into non-ASCII characters. */ |
187 |
|
*mask &= CODING_CATEGORY_XXX; |
188 |
|
return 1; |
189 |
} |
} |
190 |
#endif |
#endif |
191 |
|
|
192 |
/*** GENERAL NOTES on `decode_coding_XXX ()' functions *** |
/*** GENERAL NOTES on `decode_coding_XXX ()' functions *** |
193 |
|
|
194 |
These functions decode SRC_BYTES length of unibyte text at SOURCE |
These functions decode a byte sequence specified as a source by |
195 |
encoded in CODING to Emacs' internal format. The resulting |
CODING. The resulting multibyte text goes to a place pointed to by |
196 |
multibyte text goes to a place pointed to by DESTINATION, the length |
CODING->charbuf, the length of which should not exceed |
197 |
of which should not exceed DST_BYTES. |
CODING->charbuf_size; |
198 |
|
|
199 |
These functions set the information about original and decoded texts |
These functions set the information of original and decoded texts in |
200 |
in the members `produced', `produced_char', `consumed', and |
CODING->consumed, CODING->consumed_char, and CODING->charbuf_used. |
201 |
`consumed_char' of the structure *CODING. They also set the member |
They also set CODING->result to one of CODING_RESULT_XXX indicating |
202 |
`result' to one of CODING_FINISH_XXX indicating how the decoding |
how the decoding is finished. |
203 |
finished. |
|
204 |
|
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. |
|
205 |
|
|
|
Below is a template for these functions. */ |
|
206 |
#if 0 |
#if 0 |
207 |
static void |
static void |
208 |
decode_coding_XXX (coding, source, destination, src_bytes, dst_bytes) |
decode_coding_XXXX (coding) |
209 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
210 |
{ |
{ |
211 |
... |
unsigned char *src = coding->source + coding->consumed; |
212 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
213 |
|
/* SRC_BASE remembers the start position in source in each loop. |
214 |
|
The loop will be exited when there's not enough source code, or |
215 |
|
when there's no room in CHARBUF for a decoded character. */ |
216 |
|
unsigned char *src_base; |
217 |
|
/* A buffer to produce decoded characters. */ |
218 |
|
int *charbuf = coding->charbuf; |
219 |
|
int *charbuf_end = charbuf + coding->charbuf_size; |
220 |
|
int multibytep = coding->src_multibyte; |
221 |
|
|
222 |
|
while (1) |
223 |
|
{ |
224 |
|
src_base = src; |
225 |
|
if (charbuf < charbuf_end) |
226 |
|
/* No more room to produce a decoded character. */ |
227 |
|
break; |
228 |
|
ONE_MORE_BYTE (c); |
229 |
|
/* Decode it. */ |
230 |
|
} |
231 |
|
|
232 |
|
no_more_source: |
233 |
|
if (src_base < src_end |
234 |
|
&& coding->mode & CODING_MODE_LAST_BLOCK) |
235 |
|
/* If the source ends by partial bytes to construct a character, |
236 |
|
treat them as eight-bit raw data. */ |
237 |
|
while (src_base < src_end && charbuf < charbuf_end) |
238 |
|
*charbuf++ = *src_base++; |
239 |
|
/* Remember how many bytes and characters we consumed. If the |
240 |
|
source is multibyte, the bytes and chars are not identical. */ |
241 |
|
coding->consumed = coding->consumed_char = src_base - coding->source; |
242 |
|
/* Remember how many characters we produced. */ |
243 |
|
coding->charbuf_used = charbuf - coding->charbuf; |
244 |
} |
} |
245 |
#endif |
#endif |
246 |
|
|
247 |
/*** GENERAL NOTES on `encode_coding_XXX ()' functions *** |
/*** GENERAL NOTES on `encode_coding_XXX ()' functions *** |
248 |
|
|
249 |
These functions encode SRC_BYTES length text at SOURCE from Emacs' |
These functions encode SRC_BYTES length text at SOURCE of Emacs' |
250 |
internal multibyte format to CODING. The resulting unibyte text |
internal multibyte format by CODING. The resulting byte sequence |
251 |
goes to a place pointed to by DESTINATION, the length of which |
goes to a place pointed to by DESTINATION, the length of which |
252 |
should not exceed DST_BYTES. |
should not exceed DST_BYTES. |
253 |
|
|
254 |
These functions set the information about original and encoded texts |
These functions set the information of original and encoded texts in |
255 |
in the members `produced', `produced_char', `consumed', and |
the members produced, produced_char, consumed, and consumed_char of |
256 |
`consumed_char' of the structure *CODING. They also set the member |
the structure *CODING. They also set the member result to one of |
257 |
`result' to one of CODING_FINISH_XXX indicating how the encoding |
CODING_RESULT_XXX indicating how the encoding finished. |
258 |
finished. |
|
259 |
|
DST_BYTES zero means that source area and destination area are |
260 |
DST_BYTES zero means that the source area and destination area are |
overlapped, which means that we can produce a encoded text until it |
261 |
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. |
|
262 |
|
|
263 |
Below is a template for these functions. */ |
Below is a template of these functions. */ |
264 |
#if 0 |
#if 0 |
265 |
static void |
static void |
266 |
encode_coding_XXX (coding, source, destination, src_bytes, dst_bytes) |
encode_coding_XXX (coding) |
267 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
268 |
{ |
{ |
269 |
... |
int multibytep = coding->dst_multibyte; |
270 |
|
int *charbuf = coding->charbuf; |
271 |
|
int *charbuf_end = charbuf->charbuf + coding->charbuf_used; |
272 |
|
unsigned char *dst = coding->destination + coding->produced; |
273 |
|
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
274 |
|
unsigned char *adjusted_dst_end = dst_end - _MAX_BYTES_PRODUCED_IN_LOOP_; |
275 |
|
int produced_chars = 0; |
276 |
|
|
277 |
|
for (; charbuf < charbuf_end && dst < adjusted_dst_end; charbuf++) |
278 |
|
{ |
279 |
|
int c = *charbuf; |
280 |
|
/* Encode C into DST, and increment DST. */ |
281 |
|
} |
282 |
|
label_no_more_destination: |
283 |
|
/* How many chars and bytes we produced. */ |
284 |
|
coding->produced_char += produced_chars; |
285 |
|
coding->produced = dst - coding->destination; |
286 |
} |
} |
287 |
#endif |
#endif |
288 |
|
|
|
/*** 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) |
|
|
|
|
289 |
|
|
290 |
/*** 1. Preamble ***/ |
/*** 1. Preamble ***/ |
291 |
|
|
|
#ifdef emacs |
|
292 |
#include <config.h> |
#include <config.h> |
|
#endif |
|
|
|
|
293 |
#include <stdio.h> |
#include <stdio.h> |
294 |
|
|
|
#ifdef emacs |
|
|
|
|
295 |
#include "lisp.h" |
#include "lisp.h" |
296 |
#include "buffer.h" |
#include "buffer.h" |
297 |
|
#include "character.h" |
298 |
#include "charset.h" |
#include "charset.h" |
|
#include "composite.h" |
|
299 |
#include "ccl.h" |
#include "ccl.h" |
300 |
|
#include "composite.h" |
301 |
#include "coding.h" |
#include "coding.h" |
302 |
#include "window.h" |
#include "window.h" |
303 |
|
|
304 |
#else /* not emacs */ |
Lisp_Object Vcoding_system_hash_table; |
305 |
|
|
306 |
#include "mulelib.h" |
Lisp_Object Qcoding_system, Qcoding_aliases, Qeol_type; |
307 |
|
Lisp_Object Qunix, Qdos, Qmac; |
|
#endif /* not emacs */ |
|
|
|
|
|
Lisp_Object Qcoding_system, Qeol_type; |
|
308 |
Lisp_Object Qbuffer_file_coding_system; |
Lisp_Object Qbuffer_file_coding_system; |
309 |
Lisp_Object Qpost_read_conversion, Qpre_write_conversion; |
Lisp_Object Qpost_read_conversion, Qpre_write_conversion; |
310 |
|
Lisp_Object Qdefault_char; |
311 |
Lisp_Object Qno_conversion, Qundecided; |
Lisp_Object Qno_conversion, Qundecided; |
312 |
|
Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qshift_jis, Qbig5; |
313 |
|
Lisp_Object Qutf_16_be_nosig, Qutf_16_be, Qutf_16_le_nosig, Qutf_16_le; |
314 |
|
Lisp_Object Qsignature, Qendian, Qbig, Qlittle; |
315 |
Lisp_Object Qcoding_system_history; |
Lisp_Object Qcoding_system_history; |
|
Lisp_Object Qsafe_chars; |
|
316 |
Lisp_Object Qvalid_codes; |
Lisp_Object Qvalid_codes; |
317 |
|
|
318 |
extern Lisp_Object Qinsert_file_contents, Qwrite_region; |
extern Lisp_Object Qinsert_file_contents, Qwrite_region; |
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 |
|
|
333 |
Lisp_Object Vcoding_system_list, Vcoding_system_alist; |
Lisp_Object Vcoding_system_list, Vcoding_system_alist; |
370 |
/* Coding system of what is sent from terminal keyboard. */ |
/* Coding system of what is sent from terminal keyboard. */ |
371 |
struct coding_system keyboard_coding; |
struct coding_system keyboard_coding; |
372 |
|
|
|
/* Default coding system to be used to write a file. */ |
|
|
struct coding_system default_buffer_file_coding; |
|
|
|
|
373 |
Lisp_Object Vfile_coding_system_alist; |
Lisp_Object Vfile_coding_system_alist; |
374 |
Lisp_Object Vprocess_coding_system_alist; |
Lisp_Object Vprocess_coding_system_alist; |
375 |
Lisp_Object Vnetwork_coding_system_alist; |
Lisp_Object Vnetwork_coding_system_alist; |
378 |
|
|
379 |
#endif /* emacs */ |
#endif /* emacs */ |
380 |
|
|
|
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]; |
|
|
|
|
381 |
/* Flag to tell if we look up translation table on character code |
/* Flag to tell if we look up translation table on character code |
382 |
conversion. */ |
conversion. */ |
383 |
Lisp_Object Venable_character_translation; |
Lisp_Object Venable_character_translation; |
392 |
Lisp_Object Qtranslation_table_for_encode; |
Lisp_Object Qtranslation_table_for_encode; |
393 |
|
|
394 |
/* Alist of charsets vs revision number. */ |
/* Alist of charsets vs revision number. */ |
395 |
Lisp_Object Vcharset_revision_alist; |
static Lisp_Object Vcharset_revision_table; |
396 |
|
|
397 |
/* Default coding systems used for process I/O. */ |
/* Default coding systems used for process I/O. */ |
398 |
Lisp_Object Vdefault_process_coding_system; |
Lisp_Object Vdefault_process_coding_system; |
407 |
Lisp_Object Vchar_coding_system_table; |
Lisp_Object Vchar_coding_system_table; |
408 |
Lisp_Object Qchar_coding_system; |
Lisp_Object Qchar_coding_system; |
409 |
|
|
410 |
/* Return `safe-chars' property of coding system CODING. Don't check |
/* Two special coding systems. */ |
411 |
validity of CODING. */ |
Lisp_Object Vsjis_coding_system; |
412 |
|
Lisp_Object Vbig5_coding_system; |
413 |
|
|
414 |
|
|
415 |
|
static int detect_coding_utf_8 P_ ((struct coding_system *, int *)); |
416 |
|
static void decode_coding_utf_8 P_ ((struct coding_system *)); |
417 |
|
static int encode_coding_utf_8 P_ ((struct coding_system *)); |
418 |
|
|
419 |
|
static int detect_coding_utf_16 P_ ((struct coding_system *, int *)); |
420 |
|
static void decode_coding_utf_16 P_ ((struct coding_system *)); |
421 |
|
static int encode_coding_utf_16 P_ ((struct coding_system *)); |
422 |
|
|
423 |
|
static int detect_coding_iso_2022 P_ ((struct coding_system *, int *)); |
424 |
|
static void decode_coding_iso_2022 P_ ((struct coding_system *)); |
425 |
|
static int encode_coding_iso_2022 P_ ((struct coding_system *)); |
426 |
|
|
427 |
|
static int detect_coding_emacs_mule P_ ((struct coding_system *, int *)); |
428 |
|
static void decode_coding_emacs_mule P_ ((struct coding_system *)); |
429 |
|
static int encode_coding_emacs_mule P_ ((struct coding_system *)); |
430 |
|
|
431 |
|
static int detect_coding_sjis P_ ((struct coding_system *, int *)); |
432 |
|
static void decode_coding_sjis P_ ((struct coding_system *)); |
433 |
|
static int encode_coding_sjis P_ ((struct coding_system *)); |
434 |
|
|
435 |
|
static int detect_coding_big5 P_ ((struct coding_system *, int *)); |
436 |
|
static void decode_coding_big5 P_ ((struct coding_system *)); |
437 |
|
static int encode_coding_big5 P_ ((struct coding_system *)); |
438 |
|
|
439 |
|
static int detect_coding_ccl P_ ((struct coding_system *, int *)); |
440 |
|
static void decode_coding_ccl P_ ((struct coding_system *)); |
441 |
|
static int encode_coding_ccl P_ ((struct coding_system *)); |
442 |
|
|
443 |
|
static void decode_coding_raw_text P_ ((struct coding_system *)); |
444 |
|
static int encode_coding_raw_text P_ ((struct coding_system *)); |
445 |
|
|
446 |
|
|
447 |
|
/* ISO2022 section */ |
448 |
|
|
449 |
|
#define CODING_ISO_INITIAL(coding, reg) \ |
450 |
|
(XINT (AREF (AREF (CODING_ID_ATTRS ((coding)->id), \ |
451 |
|
coding_attr_iso_initial), \ |
452 |
|
reg))) |
453 |
|
|
454 |
|
|
455 |
|
#define CODING_ISO_REQUEST(coding, charset_id) \ |
456 |
|
((charset_id <= (coding)->max_charset_id \ |
457 |
|
? (coding)->safe_charsets[charset_id] \ |
458 |
|
: -1)) |
459 |
|
|
460 |
|
|
461 |
|
#define CODING_ISO_FLAGS(coding) \ |
462 |
|
((coding)->spec.iso_2022.flags) |
463 |
|
#define CODING_ISO_DESIGNATION(coding, reg) \ |
464 |
|
((coding)->spec.iso_2022.current_designation[reg]) |
465 |
|
#define CODING_ISO_INVOCATION(coding, plane) \ |
466 |
|
((coding)->spec.iso_2022.current_invocation[plane]) |
467 |
|
#define CODING_ISO_SINGLE_SHIFTING(coding) \ |
468 |
|
((coding)->spec.iso_2022.single_shifting) |
469 |
|
#define CODING_ISO_BOL(coding) \ |
470 |
|
((coding)->spec.iso_2022.bol) |
471 |
|
#define CODING_ISO_INVOKED_CHARSET(coding, plane) \ |
472 |
|
CODING_ISO_DESIGNATION ((coding), CODING_ISO_INVOCATION ((coding), (plane))) |
473 |
|
|
474 |
|
/* Control characters of ISO2022. */ |
475 |
|
/* code */ /* function */ |
476 |
|
#define ISO_CODE_LF 0x0A /* line-feed */ |
477 |
|
#define ISO_CODE_CR 0x0D /* carriage-return */ |
478 |
|
#define ISO_CODE_SO 0x0E /* shift-out */ |
479 |
|
#define ISO_CODE_SI 0x0F /* shift-in */ |
480 |
|
#define ISO_CODE_SS2_7 0x19 /* single-shift-2 for 7-bit code */ |
481 |
|
#define ISO_CODE_ESC 0x1B /* escape */ |
482 |
|
#define ISO_CODE_SS2 0x8E /* single-shift-2 */ |
483 |
|
#define ISO_CODE_SS3 0x8F /* single-shift-3 */ |
484 |
|
#define ISO_CODE_CSI 0x9B /* control-sequence-introducer */ |
485 |
|
|
486 |
|
/* All code (1-byte) of ISO2022 is classified into one of the |
487 |
|
followings. */ |
488 |
|
enum iso_code_class_type |
489 |
|
{ |
490 |
|
ISO_control_0, /* Control codes in the range |
491 |
|
0x00..0x1F and 0x7F, except for the |
492 |
|
following 5 codes. */ |
493 |
|
ISO_carriage_return, /* ISO_CODE_CR (0x0D) */ |
494 |
|
ISO_shift_out, /* ISO_CODE_SO (0x0E) */ |
495 |
|
ISO_shift_in, /* ISO_CODE_SI (0x0F) */ |
496 |
|
ISO_single_shift_2_7, /* ISO_CODE_SS2_7 (0x19) */ |
497 |
|
ISO_escape, /* ISO_CODE_SO (0x1B) */ |
498 |
|
ISO_control_1, /* Control codes in the range |
499 |
|
0x80..0x9F, except for the |
500 |
|
following 3 codes. */ |
501 |
|
ISO_single_shift_2, /* ISO_CODE_SS2 (0x8E) */ |
502 |
|
ISO_single_shift_3, /* ISO_CODE_SS3 (0x8F) */ |
503 |
|
ISO_control_sequence_introducer, /* ISO_CODE_CSI (0x9B) */ |
504 |
|
ISO_0x20_or_0x7F, /* Codes of the values 0x20 or 0x7F. */ |
505 |
|
ISO_graphic_plane_0, /* Graphic codes in the range 0x21..0x7E. */ |
506 |
|
ISO_0xA0_or_0xFF, /* Codes of the values 0xA0 or 0xFF. */ |
507 |
|
ISO_graphic_plane_1 /* Graphic codes in the range 0xA1..0xFE. */ |
508 |
|
}; |
509 |
|
|
510 |
Lisp_Object |
/** The macros CODING_ISO_FLAG_XXX defines a flag bit of the |
511 |
coding_safe_chars (coding) |
`iso-flags' attribute of an iso2022 coding system. */ |
512 |
|
|
513 |
|
/* If set, produce long-form designation sequence (e.g. ESC $ ( A) |
514 |
|
instead of the correct short-form sequence (e.g. ESC $ A). */ |
515 |
|
#define CODING_ISO_FLAG_LONG_FORM 0x0001 |
516 |
|
|
517 |
|
/* If set, reset graphic planes and registers at end-of-line to the |
518 |
|
initial state. */ |
519 |
|
#define CODING_ISO_FLAG_RESET_AT_EOL 0x0002 |
520 |
|
|
521 |
|
/* If set, reset graphic planes and registers before any control |
522 |
|
characters to the initial state. */ |
523 |
|
#define CODING_ISO_FLAG_RESET_AT_CNTL 0x0004 |
524 |
|
|
525 |
|
/* If set, encode by 7-bit environment. */ |
526 |
|
#define CODING_ISO_FLAG_SEVEN_BITS 0x0008 |
527 |
|
|
528 |
|
/* If set, use locking-shift function. */ |
529 |
|
#define CODING_ISO_FLAG_LOCKING_SHIFT 0x0010 |
530 |
|
|
531 |
|
/* If set, use single-shift function. Overwrite |
532 |
|
CODING_ISO_FLAG_LOCKING_SHIFT. */ |
533 |
|
#define CODING_ISO_FLAG_SINGLE_SHIFT 0x0020 |
534 |
|
|
535 |
|
/* If set, use designation escape sequence. */ |
536 |
|
#define CODING_ISO_FLAG_DESIGNATION 0x0040 |
537 |
|
|
538 |
|
/* If set, produce revision number sequence. */ |
539 |
|
#define CODING_ISO_FLAG_REVISION 0x0080 |
540 |
|
|
541 |
|
/* If set, produce ISO6429's direction specifying sequence. */ |
542 |
|
#define CODING_ISO_FLAG_DIRECTION 0x0100 |
543 |
|
|
544 |
|
/* If set, assume designation states are reset at beginning of line on |
545 |
|
output. */ |
546 |
|
#define CODING_ISO_FLAG_INIT_AT_BOL 0x0200 |
547 |
|
|
548 |
|
/* If set, designation sequence should be placed at beginning of line |
549 |
|
on output. */ |
550 |
|
#define CODING_ISO_FLAG_DESIGNATE_AT_BOL 0x0400 |
551 |
|
|
552 |
|
/* If set, do not encode unsafe charactes on output. */ |
553 |
|
#define CODING_ISO_FLAG_SAFE 0x0800 |
554 |
|
|
555 |
|
/* If set, extra latin codes (128..159) are accepted as a valid code |
556 |
|
on input. */ |
557 |
|
#define CODING_ISO_FLAG_LATIN_EXTRA 0x1000 |
558 |
|
|
559 |
|
#define CODING_ISO_FLAG_COMPOSITION 0x2000 |
560 |
|
|
561 |
|
#define CODING_ISO_FLAG_EUC_TW_SHIFT 0x4000 |
562 |
|
|
563 |
|
#define CODING_ISO_FLAG_FULL_SUPPORT 0x8000 |
564 |
|
|
565 |
|
/* A character to be produced on output if encoding of the original |
566 |
|
character is prohibited by CODING_ISO_FLAG_SAFE. */ |
567 |
|
#define CODING_INHIBIT_CHARACTER_SUBSTITUTION '?' |
568 |
|
|
569 |
|
|
570 |
|
/* UTF-16 section */ |
571 |
|
#define CODING_UTF_16_BOM(coding) \ |
572 |
|
((coding)->spec.utf_16.bom) |
573 |
|
|
574 |
|
#define CODING_UTF_16_ENDIAN(coding) \ |
575 |
|
((coding)->spec.utf_16.endian) |
576 |
|
|
577 |
|
#define CODING_UTF_16_SURROGATE(coding) \ |
578 |
|
((coding)->spec.utf_16.surrogate) |
579 |
|
|
580 |
|
|
581 |
|
/* CCL section */ |
582 |
|
#define CODING_CCL_DECODER(coding) \ |
583 |
|
AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_decoder) |
584 |
|
#define CODING_CCL_ENCODER(coding) \ |
585 |
|
AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_encoder) |
586 |
|
#define CODING_CCL_VALIDS(coding) \ |
587 |
|
(XSTRING (AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_valids)) \ |
588 |
|
->data) |
589 |
|
|
590 |
|
/* Index for each coding category in `coding_category_table' */ |
591 |
|
|
592 |
|
enum coding_category |
593 |
|
{ |
594 |
|
coding_category_iso_7, |
595 |
|
coding_category_iso_7_tight, |
596 |
|
coding_category_iso_8_1, |
597 |
|
coding_category_iso_8_2, |
598 |
|
coding_category_iso_7_else, |
599 |
|
coding_category_iso_8_else, |
600 |
|
coding_category_utf_8, |
601 |
|
coding_category_utf_16_auto, |
602 |
|
coding_category_utf_16_be, |
603 |
|
coding_category_utf_16_le, |
604 |
|
coding_category_utf_16_be_nosig, |
605 |
|
coding_category_utf_16_le_nosig, |
606 |
|
coding_category_charset, |
607 |
|
coding_category_sjis, |
608 |
|
coding_category_big5, |
609 |
|
coding_category_ccl, |
610 |
|
coding_category_emacs_mule, |
611 |
|
/* All above are targets of code detection. */ |
612 |
|
coding_category_raw_text, |
613 |
|
coding_category_undecided, |
614 |
|
coding_category_max |
615 |
|
}; |
616 |
|
|
617 |
|
/* Definitions of flag bits used in detect_coding_XXXX. */ |
618 |
|
#define CATEGORY_MASK_ISO_7 (1 << coding_category_iso_7) |
619 |
|
#define CATEGORY_MASK_ISO_7_TIGHT (1 << coding_category_iso_7_tight) |
620 |
|
#define CATEGORY_MASK_ISO_8_1 (1 << coding_category_iso_8_1) |
621 |
|
#define CATEGORY_MASK_ISO_8_2 (1 << coding_category_iso_8_2) |
622 |
|
#define CATEGORY_MASK_ISO_7_ELSE (1 << coding_category_iso_7_else) |
623 |
|
#define CATEGORY_MASK_ISO_8_ELSE (1 << coding_category_iso_8_else) |
624 |
|
#define CATEGORY_MASK_UTF_8 (1 << coding_category_utf_8) |
625 |
|
#define CATEGORY_MASK_UTF_16_BE (1 << coding_category_utf_16_be) |
626 |
|
#define CATEGORY_MASK_UTF_16_LE (1 << coding_category_utf_16_le) |
627 |
|
#define CATEGORY_MASK_UTF_16_BE_NOSIG (1 << coding_category_utf_16_be_nosig) |
628 |
|
#define CATEGORY_MASK_UTF_16_LE_NOSIG (1 << coding_category_utf_16_le_nosig) |
629 |
|
#define CATEGORY_MASK_CHARSET (1 << coding_category_charset) |
630 |
|
#define CATEGORY_MASK_SJIS (1 << coding_category_sjis) |
631 |
|
#define CATEGORY_MASK_BIG5 (1 << coding_category_big5) |
632 |
|
#define CATEGORY_MASK_CCL (1 << coding_category_ccl) |
633 |
|
#define CATEGORY_MASK_EMACS_MULE (1 << coding_category_emacs_mule) |
634 |
|
|
635 |
|
/* This value is returned if detect_coding_mask () find nothing other |
636 |
|
than ASCII characters. */ |
637 |
|
#define CATEGORY_MASK_ANY \ |
638 |
|
(CATEGORY_MASK_ISO_7 \ |
639 |
|
| CATEGORY_MASK_ISO_7_TIGHT \ |
640 |
|
| CATEGORY_MASK_ISO_8_1 \ |
641 |
|
| CATEGORY_MASK_ISO_8_2 \ |
642 |
|
| CATEGORY_MASK_ISO_7_ELSE \ |
643 |
|
| CATEGORY_MASK_ISO_8_ELSE \ |
644 |
|
| CATEGORY_MASK_UTF_8 \ |
645 |
|
| CATEGORY_MASK_UTF_16_BE \ |
646 |
|
| CATEGORY_MASK_UTF_16_LE \ |
647 |
|
| CATEGORY_MASK_UTF_16_BE_NOSIG \ |
648 |
|
| CATEGORY_MASK_UTF_16_LE_NOSIG \ |
649 |
|
| CATEGORY_MASK_CHARSET \ |
650 |
|
| CATEGORY_MASK_SJIS \ |
651 |
|
| CATEGORY_MASK_BIG5 \ |
652 |
|
| CATEGORY_MASK_CCL \ |
653 |
|
| CATEGORY_MASK_EMACS_MULE) |
654 |
|
|
655 |
|
|
656 |
|
#define CATEGORY_MASK_ISO_7BIT \ |
657 |
|
(CATEGORY_MASK_ISO_7 | CATEGORY_MASK_ISO_7_TIGHT) |
658 |
|
|
659 |
|
#define CATEGORY_MASK_ISO_8BIT \ |
660 |
|
(CATEGORY_MASK_ISO_8_1 | CATEGORY_MASK_ISO_8_2) |
661 |
|
|
662 |
|
#define CATEGORY_MASK_ISO_ELSE \ |
663 |
|
(CATEGORY_MASK_ISO_7_ELSE | CATEGORY_MASK_ISO_8_ELSE) |
664 |
|
|
665 |
|
#define CATEGORY_MASK_ISO_ESCAPE \ |
666 |
|
(CATEGORY_MASK_ISO_7 \ |
667 |
|
| CATEGORY_MASK_ISO_7_TIGHT \ |
668 |
|
| CATEGORY_MASK_ISO_7_ELSE \ |
669 |
|
| CATEGORY_MASK_ISO_8_ELSE) |
670 |
|
|
671 |
|
#define CATEGORY_MASK_ISO \ |
672 |
|
( CATEGORY_MASK_ISO_7BIT \ |
673 |
|
| CATEGORY_MASK_ISO_8BIT \ |
674 |
|
| CATEGORY_MASK_ISO_ELSE) |
675 |
|
|
676 |
|
#define CATEGORY_MASK_UTF_16 \ |
677 |
|
(CATEGORY_MASK_UTF_16_BE \ |
678 |
|
| CATEGORY_MASK_UTF_16_LE \ |
679 |
|
| CATEGORY_MASK_UTF_16_BE_NOSIG \ |
680 |
|
| CATEGORY_MASK_UTF_16_LE_NOSIG) |
681 |
|
|
682 |
|
|
683 |
|
/* List of symbols `coding-category-xxx' ordered by priority. This |
684 |
|
variable is exposed to Emacs Lisp. */ |
685 |
|
static Lisp_Object Vcoding_category_list; |
686 |
|
|
687 |
|
/* Table of coding categories (Lisp symbols). This variable is for |
688 |
|
internal use oly. */ |
689 |
|
static Lisp_Object Vcoding_category_table; |
690 |
|
|
691 |
|
/* Table of coding-categories ordered by priority. */ |
692 |
|
static enum coding_category coding_priorities[coding_category_max]; |
693 |
|
|
694 |
|
/* Nth element is a coding context for the coding system bound to the |
695 |
|
Nth coding category. */ |
696 |
|
static struct coding_system coding_categories[coding_category_max]; |
697 |
|
|
698 |
|
static int detected_mask[coding_category_raw_text] = |
699 |
|
{ CATEGORY_MASK_ISO, |
700 |
|
CATEGORY_MASK_ISO, |
701 |
|
CATEGORY_MASK_ISO, |
702 |
|
CATEGORY_MASK_ISO, |
703 |
|
CATEGORY_MASK_ISO, |
704 |
|
CATEGORY_MASK_ISO, |
705 |
|
CATEGORY_MASK_UTF_8, |
706 |
|
CATEGORY_MASK_UTF_16, |
707 |
|
CATEGORY_MASK_UTF_16, |
708 |
|
CATEGORY_MASK_UTF_16, |
709 |
|
CATEGORY_MASK_UTF_16, |
710 |
|
CATEGORY_MASK_UTF_16, |
711 |
|
CATEGORY_MASK_CHARSET, |
712 |
|
CATEGORY_MASK_SJIS, |
713 |
|
CATEGORY_MASK_BIG5, |
714 |
|
CATEGORY_MASK_CCL, |
715 |
|
CATEGORY_MASK_EMACS_MULE |
716 |
|
}; |
717 |
|
|
718 |
|
/*** Commonly used macros and functions ***/ |
719 |
|
|
720 |
|
#ifndef min |
721 |
|
#define min(a, b) ((a) < (b) ? (a) : (b)) |
722 |
|
#endif |
723 |
|
#ifndef max |
724 |
|
#define max(a, b) ((a) > (b) ? (a) : (b)) |
725 |
|
#endif |
726 |
|
|
727 |
|
#define CODING_GET_INFO(coding, attrs, eol_type, charset_list) \ |
728 |
|
do { \ |
729 |
|
attrs = CODING_ID_ATTRS (coding->id); \ |
730 |
|
eol_type = CODING_ID_EOL_TYPE (coding->id); \ |
731 |
|
if (VECTORP (eol_type)) \ |
732 |
|
eol_type = Qunix; \ |
733 |
|
charset_list = CODING_ATTR_CHARSET_LIST (attrs); \ |
734 |
|
} while (0) |
735 |
|
|
736 |
|
|
737 |
|
/* Safely get one byte from the source text pointed by SRC which ends |
738 |
|
at SRC_END, and set C to that byte. If there are not enough bytes |
739 |
|
in the source, it jumps to `no_more_source'. The caller |
740 |
|
should declare and set these variables appropriately in advance: |
741 |
|
src, src_end, multibytep |
742 |
|
*/ |
743 |
|
|
744 |
|
#define ONE_MORE_BYTE(c) \ |
745 |
|
do { \ |
746 |
|
if (src == src_end) \ |
747 |
|
{ \ |
748 |
|
if (src_base < src) \ |
749 |
|
coding->result = CODING_RESULT_INSUFFICIENT_SRC; \ |
750 |
|
goto no_more_source; \ |
751 |
|
} \ |
752 |
|
c = *src++; \ |
753 |
|
if (multibytep && (c & 0x80)) \ |
754 |
|
{ \ |
755 |
|
if ((c & 0xFE) != 0xC0) \ |
756 |
|
error ("Undecodable char found"); \ |
757 |
|
c = ((c & 1) << 6) | *src++; \ |
758 |
|
} \ |
759 |
|
consumed_chars++; \ |
760 |
|
} while (0) |
761 |
|
|
762 |
|
|
763 |
|
#define ONE_MORE_BYTE_NO_CHECK(c) \ |
764 |
|
do { \ |
765 |
|
c = *src++; \ |
766 |
|
if (multibytep && (c & 0x80)) \ |
767 |
|
{ \ |
768 |
|
if ((c & 0xFE) != 0xC0) \ |
769 |
|
error ("Undecodable char found"); \ |
770 |
|
c = ((c & 1) << 6) | *src++; \ |
771 |
|
} \ |
772 |
|
} while (0) |
773 |
|
|
774 |
|
|
775 |
|
/* Store a byte C in the place pointed by DST and increment DST to the |
776 |
|
next free point, and increment PRODUCED_CHARS. The caller should |
777 |
|
assure that C is 0..127, and declare and set the variable `dst' |
778 |
|
appropriately in advance. |
779 |
|
*/ |
780 |
|
|
781 |
|
|
782 |
|
#define EMIT_ONE_ASCII_BYTE(c) \ |
783 |
|
do { \ |
784 |
|
produced_chars++; \ |
785 |
|
*dst++ = (c); \ |
786 |
|
} while (0) |
787 |
|
|
788 |
|
|
789 |
|
/* Like EMIT_ONE_ASCII_BYTE byt store two bytes; C1 and C2. */ |
790 |
|
|
791 |
|
#define EMIT_TWO_ASCII_BYTES(c1, c2) \ |
792 |
|
do { \ |
793 |
|
produced_chars += 2; \ |
794 |
|
*dst++ = (c1), *dst++ = (c2); \ |
795 |
|
} while (0) |
796 |
|
|
797 |
|
|
798 |
|
/* Store a byte C in the place pointed by DST and increment DST to the |
799 |
|
next free point, and increment PRODUCED_CHARS. If MULTIBYTEP is |
800 |
|
nonzero, store in an appropriate multibyte from. The caller should |
801 |
|
declare and set the variables `dst' and `multibytep' appropriately |
802 |
|
in advance. */ |
803 |
|
|
804 |
|
#define EMIT_ONE_BYTE(c) \ |
805 |
|
do { \ |
806 |
|
produced_chars++; \ |
807 |
|
if (multibytep) \ |
808 |
|
{ \ |
809 |
|
int ch = (c); \ |
810 |
|
if (ch >= 0x80) \ |
811 |
|
ch = BYTE8_TO_CHAR (ch); \ |
812 |
|
CHAR_STRING_ADVANCE (ch, dst); \ |
813 |
|
} \ |
814 |
|
else \ |
815 |
|
*dst++ = (c); \ |
816 |
|
} while (0) |
817 |
|
|
818 |
|
|
819 |
|
/* Like EMIT_ONE_BYTE, but emit two bytes; C1 and C2. */ |
820 |
|
|
821 |
|
#define EMIT_TWO_BYTES(c1, c2) \ |
822 |
|
do { \ |
823 |
|
produced_chars += 2; \ |
824 |
|
if (multibytep) \ |
825 |
|
{ \ |
826 |
|
CHAR_STRING_ADVANCE ((int) (c1), dst); \ |
827 |
|
CHAR_STRING_ADVANCE ((int) (c2), dst); \ |
828 |
|
} \ |
829 |
|
else \ |
830 |
|
{ \ |
831 |
|
*dst++ = (c1); \ |
832 |
|
*dst++ = (c2); \ |
833 |
|
} \ |
834 |
|
} while (0) |
835 |
|
|
836 |
|
|
837 |
|
#define EMIT_THREE_BYTES(c1, c2, c3) \ |
838 |
|
do { \ |
839 |
|
EMIT_ONE_BYTE (c1); \ |
840 |
|
EMIT_TWO_BYTES (c2, c3); \ |
841 |
|
} while (0) |
842 |
|
|
843 |
|
|
844 |
|
#define EMIT_FOUR_BYTES(c1, c2, c3, c4) \ |
845 |
|
do { \ |
846 |
|
EMIT_TWO_BYTES (c1, c2); \ |
847 |
|
EMIT_TWO_BYTES (c3, c4); \ |
848 |
|
} while (0) |
849 |
|
|
850 |
|
|
851 |
|
#define CODING_DECODE_CHAR(coding, src, src_base, src_end, charset, code, c) \ |
852 |
|
do { \ |
853 |
|
charset_map_loaded = 0; \ |
854 |
|
c = DECODE_CHAR (charset, code); \ |
855 |
|
if (charset_map_loaded) \ |
856 |
|
{ \ |
857 |
|
unsigned char *orig = coding->source; \ |
858 |
|
EMACS_INT offset; \ |
859 |
|
\ |
860 |
|
coding_set_source (coding); \ |
861 |
|
offset = coding->source - orig; \ |
862 |
|
src += offset; \ |
863 |
|
src_base += offset; \ |
864 |
|
src_end += offset; \ |
865 |
|
} \ |
866 |
|
} while (0) |
867 |
|
|
868 |
|
|
869 |
|
#define ASSURE_DESTINATION(bytes) \ |
870 |
|
do { \ |
871 |
|
if (dst + (bytes) >= dst_end) \ |
872 |
|
{ \ |
873 |
|
int more_bytes = charbuf_end - charbuf + (bytes); \ |
874 |
|
\ |
875 |
|
dst = alloc_destination (coding, more_bytes, dst); \ |
876 |
|
dst_end = coding->destination + coding->dst_bytes; \ |
877 |
|
} \ |
878 |
|
} while (0) |
879 |
|
|
880 |
|
|
881 |
|
|
882 |
|
static void |
883 |
|
coding_set_source (coding) |
884 |
|
struct coding_system *coding; |
885 |
|
{ |
886 |
|
if (BUFFERP (coding->src_object)) |
887 |
|
{ |
888 |
|
if (coding->src_pos < 0) |
889 |
|
coding->source = GAP_END_ADDR + coding->src_pos_byte; |
890 |
|
else |
891 |
|
{ |
892 |
|
if (coding->src_pos < GPT |
893 |
|
&& coding->src_pos + coding->src_chars >= GPT) |
894 |
|
move_gap_both (coding->src_pos, coding->src_pos_byte); |
895 |
|
coding->source = BYTE_POS_ADDR (coding->src_pos_byte); |
896 |
|
} |
897 |
|
} |
898 |
|
else if (STRINGP (coding->src_object)) |
899 |
|
{ |
900 |
|
coding->source = (XSTRING (coding->src_object)->data |
901 |
|
+ coding->src_pos_byte); |
902 |
|
} |
903 |
|
else |
904 |
|
/* Otherwise, the source is C string and is never relocated |
905 |
|
automatically. Thus we don't have to update anything. */ |
906 |
|
; |
907 |
|
} |
908 |
|
|
909 |
|
static void |
910 |
|
coding_set_destination (coding) |
911 |
|
struct coding_system *coding; |
912 |
|
{ |
913 |
|
if (BUFFERP (coding->dst_object)) |
914 |
|
{ |
915 |
|
/* We are sure that coding->dst_pos_byte is before the gap of the |
916 |
|
buffer. */ |
917 |
|
coding->destination = (BUF_BEG_ADDR (XBUFFER (coding->dst_object)) |
918 |
|
+ coding->dst_pos_byte - 1); |
919 |
|
if (coding->src_pos < 0) |
920 |
|
/* The source and destination is in the same buffer. */ |
921 |
|
coding->dst_bytes = (GAP_END_ADDR |
922 |
|
- (coding->src_bytes - coding->consumed) |
923 |
|
- coding->destination); |
924 |
|
else |
925 |
|
coding->dst_bytes = (BUF_GAP_END_ADDR (XBUFFER (coding->dst_object)) |
926 |
|
- coding->destination); |
927 |
|
} |
928 |
|
else |
929 |
|
/* Otherwise, the destination is C string and is never relocated |
930 |
|
automatically. Thus we don't have to update anything. */ |
931 |
|
; |
932 |
|
} |
933 |
|
|
934 |
|
|
935 |
|
static void |
936 |
|
coding_alloc_by_realloc (coding, bytes) |
937 |
|
struct coding_system *coding; |
938 |
|
EMACS_INT bytes; |
939 |
|
{ |
940 |
|
coding->destination = (unsigned char *) xrealloc (coding->destination, |
941 |
|
coding->dst_bytes + bytes); |
942 |
|
coding->dst_bytes += bytes; |
943 |
|
} |
944 |
|
|
945 |
|
static void |
946 |
|
coding_alloc_by_making_gap (coding, bytes) |
947 |
|
struct coding_system *coding; |
948 |
|
EMACS_INT bytes; |
949 |
|
{ |
950 |
|
Lisp_Object this_buffer; |
951 |
|
|
952 |
|
this_buffer = Fcurrent_buffer (); |
953 |
|
if (EQ (this_buffer, coding->dst_object)) |
954 |
|
{ |
955 |
|
EMACS_INT add = coding->src_bytes - coding->consumed; |
956 |
|
|
957 |
|
GAP_SIZE -= add; ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add; |
958 |
|
make_gap (bytes); |
959 |
|
GAP_SIZE += add; ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add; |
960 |
|
} |
961 |
|
else |
962 |
|
{ |
963 |
|
set_buffer_internal (XBUFFER (coding->dst_object)); |
964 |
|
make_gap (bytes); |
965 |
|
set_buffer_internal (XBUFFER (this_buffer)); |
966 |
|
} |
967 |
|
} |
968 |
|
|
969 |
|
|
970 |
|
static unsigned char * |
971 |
|
alloc_destination (coding, nbytes, dst) |
972 |
|
struct coding_system *coding; |
973 |
|
int nbytes; |
974 |
|
unsigned char *dst; |
975 |
|
{ |
976 |
|
EMACS_INT offset = dst - coding->destination; |
977 |
|
|
978 |
|
if (BUFFERP (coding->dst_object)) |
979 |
|
coding_alloc_by_making_gap (coding, nbytes); |
980 |
|
else |
981 |
|
coding_alloc_by_realloc (coding, nbytes); |
982 |
|
coding->result = CODING_RESULT_SUCCESS; |
983 |
|
coding_set_destination (coding); |
984 |
|
dst = coding->destination + offset; |
985 |
|
return dst; |
986 |
|
} |
987 |
|
|
988 |
|
|
989 |
|
/*** 2. Emacs' internal format (emacs-utf-8) ***/ |
990 |
|
|
991 |
|
|
992 |
|
|
993 |
|
|
994 |
|
/*** 3. UTF-8 ***/ |
995 |
|
|
996 |
|
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
997 |
|
Check if a text is encoded in UTF-8. If it is, return |
998 |
|
CATEGORY_MASK_UTF_8, else return 0. */ |
999 |
|
|
1000 |
|
#define UTF_8_1_OCTET_P(c) ((c) < 0x80) |
1001 |
|
#define UTF_8_EXTRA_OCTET_P(c) (((c) & 0xC0) == 0x80) |
1002 |
|
#define UTF_8_2_OCTET_LEADING_P(c) (((c) & 0xE0) == 0xC0) |
1003 |
|
#define UTF_8_3_OCTET_LEADING_P(c) (((c) & 0xF0) == 0xE0) |
1004 |
|
#define UTF_8_4_OCTET_LEADING_P(c) (((c) & 0xF8) == 0xF0) |
1005 |
|
#define UTF_8_5_OCTET_LEADING_P(c) (((c) & 0xFC) == 0xF8) |
1006 |
|
|
1007 |
|
static int |
1008 |
|
detect_coding_utf_8 (coding, mask) |
1009 |
|
struct coding_system *coding; |
1010 |
|
int *mask; |
1011 |
|
{ |
1012 |
|
unsigned char *src = coding->source, *src_base = src; |
1013 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
1014 |
|
int multibytep = coding->src_multibyte; |
1015 |
|
int consumed_chars = 0; |
1016 |
|
int found = 0; |
1017 |
|
|
1018 |
|
/* A coding system of this category is always ASCII compatible. */ |
1019 |
|
src += coding->head_ascii; |
1020 |
|
|
1021 |
|
while (1) |
1022 |
|
{ |
1023 |
|
int c, c1, c2, c3, c4; |
1024 |
|
|
1025 |
|
ONE_MORE_BYTE (c); |
1026 |
|
if (UTF_8_1_OCTET_P (c)) |
1027 |
|
continue; |
1028 |
|
ONE_MORE_BYTE (c1); |
1029 |
|
if (! UTF_8_EXTRA_OCTET_P (c1)) |
1030 |
|
break; |
1031 |
|
if (UTF_8_2_OCTET_LEADING_P (c)) |
1032 |
|
{ |
1033 |
|
found++; |
1034 |
|
continue; |
1035 |
|
} |
1036 |
|
ONE_MORE_BYTE (c2); |
1037 |
|
if (! UTF_8_EXTRA_OCTET_P (c2)) |
1038 |
|
break; |
1039 |
|
if (UTF_8_3_OCTET_LEADING_P (c)) |
1040 |
|
{ |
1041 |
|
found++; |
1042 |
|
continue; |
1043 |
|
} |
1044 |
|
ONE_MORE_BYTE (c3); |
1045 |
|
if (! UTF_8_EXTRA_OCTET_P (c3)) |
1046 |
|
break; |
1047 |
|
if (UTF_8_4_OCTET_LEADING_P (c)) |
1048 |
|
{ |
1049 |
|
found++; |
1050 |
|
continue; |
1051 |
|
} |
1052 |
|
ONE_MORE_BYTE (c4); |
1053 |
|
if (! UTF_8_EXTRA_OCTET_P (c4)) |
1054 |
|
break; |
1055 |
|
if (UTF_8_5_OCTET_LEADING_P (c)) |
1056 |
|
{ |
1057 |
|
found++; |
1058 |
|
continue; |
1059 |
|
} |
1060 |
|
break; |
1061 |
|
} |
1062 |
|
*mask &= ~CATEGORY_MASK_UTF_8; |
1063 |
|
return 0; |
1064 |
|
|
1065 |
|
no_more_source: |
1066 |
|
if (! found) |
1067 |
|
return 0; |
1068 |
|
*mask &= CATEGORY_MASK_UTF_8; |
1069 |
|
return 1; |
1070 |
|
} |
1071 |
|
|
1072 |
|
|
1073 |
|
static void |
1074 |
|
decode_coding_utf_8 (coding) |
1075 |
|
struct coding_system *coding; |
1076 |
|
{ |
1077 |
|
unsigned char *src = coding->source + coding->consumed; |
1078 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
1079 |
|
unsigned char *src_base; |
1080 |
|
int *charbuf = coding->charbuf; |
1081 |
|
int *charbuf_end = charbuf + coding->charbuf_size; |
1082 |
|
int consumed_chars = 0, consumed_chars_base; |
1083 |
|
int multibytep = coding->src_multibyte; |
1084 |
|
Lisp_Object attr, eol_type, charset_list; |
1085 |
|
|
1086 |
|
CODING_GET_INFO (coding, attr, eol_type, charset_list); |
1087 |
|
|
1088 |
|
while (1) |
1089 |
|
{ |
1090 |
|
int c, c1, c2, c3, c4, c5; |
1091 |
|
|
1092 |
|
src_base = src; |
1093 |
|
consumed_chars_base = consumed_chars; |
1094 |
|
|
1095 |
|
if (charbuf >= charbuf_end) |
1096 |
|
break; |
1097 |
|
|
1098 |
|
ONE_MORE_BYTE (c1); |
1099 |
|
if (UTF_8_1_OCTET_P(c1)) |
1100 |
|
{ |
1101 |
|
c = c1; |
1102 |
|
if (c == '\r') |
1103 |
|
{ |
1104 |
|
if (EQ (eol_type, Qdos)) |
1105 |
|
{ |
1106 |
|
if (src == src_end) |
1107 |
|
goto no_more_source; |
1108 |
|
if (*src == '\n') |
1109 |
|
ONE_MORE_BYTE (c); |
1110 |
|
} |
1111 |
|
else if (EQ (eol_type, Qmac)) |
1112 |
|
c = '\n'; |
1113 |
|
} |
1114 |
|
} |
1115 |
|
else |
1116 |
|
{ |
1117 |
|
ONE_MORE_BYTE (c2); |
1118 |
|
if (! UTF_8_EXTRA_OCTET_P (c2)) |
1119 |
|
goto invalid_code; |
1120 |
|
if (UTF_8_2_OCTET_LEADING_P (c1)) |
1121 |
|
c = ((c1 & 0x1F) << 6) | (c2 & 0x3F); |
1122 |
|
else |
1123 |
|
{ |
1124 |
|
ONE_MORE_BYTE (c3); |
1125 |
|
if (! UTF_8_EXTRA_OCTET_P (c3)) |
1126 |
|
goto invalid_code; |
1127 |
|
if (UTF_8_3_OCTET_LEADING_P (c1)) |
1128 |
|
c = (((c1 & 0xF) << 12) |
1129 |
|
| ((c2 & 0x3F) << 6) | (c3 & 0x3F)); |
1130 |
|
else |
1131 |
|
{ |
1132 |
|
ONE_MORE_BYTE (c4); |
1133 |
|
if (! UTF_8_EXTRA_OCTET_P (c4)) |
1134 |
|
goto invalid_code; |
1135 |
|
if (UTF_8_4_OCTET_LEADING_P (c1)) |
1136 |
|
c = (((c1 & 0x7) << 18) | ((c2 & 0x3F) << 12) |
1137 |
|
| ((c3 & 0x3F) << 6) | (c4 & 0x3F)); |
1138 |
|
else |
1139 |
|
{ |
1140 |
|
ONE_MORE_BYTE (c5); |
1141 |
|
if (! UTF_8_EXTRA_OCTET_P (c5)) |
1142 |
|
goto invalid_code; |
1143 |
|
if (UTF_8_5_OCTET_LEADING_P (c1)) |
1144 |
|
{ |
1145 |
|
c = (((c1 & 0x3) << 24) | ((c2 & 0x3F) << 18) |
1146 |
|
| ((c3 & 0x3F) << 12) | ((c4 & 0x3F) << 6) |
1147 |
|
| (c5 & 0x3F)); |
1148 |
|
if (c > MAX_CHAR) |
1149 |
|
goto invalid_code; |
1150 |
|
} |
1151 |
|
else |
1152 |
|
goto invalid_code; |
1153 |
|
} |
1154 |
|
} |
1155 |
|
} |
1156 |
|
} |
1157 |
|
|
1158 |
|
*charbuf++ = c; |
1159 |
|
continue; |
1160 |
|
|
1161 |
|
invalid_code: |
1162 |
|
src = src_base; |
1163 |
|
consumed_chars = consumed_chars_base; |
1164 |
|
ONE_MORE_BYTE (c); |
1165 |
|
*charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c); |
1166 |
|
coding->errors++; |
1167 |
|
} |
1168 |
|
|
1169 |
|
no_more_source: |
1170 |
|
coding->consumed_char += consumed_chars_base; |
1171 |
|
coding->consumed = src_base - coding->source; |
1172 |
|
coding->charbuf_used = charbuf - coding->charbuf; |
1173 |
|
} |
1174 |
|
|
1175 |
|
|
1176 |
|
static int |
1177 |
|
encode_coding_utf_8 (coding) |
1178 |
|
struct coding_system *coding; |
1179 |
|
{ |
1180 |
|
int multibytep = coding->dst_multibyte; |
1181 |
|
int *charbuf = coding->charbuf; |
1182 |
|
int *charbuf_end = charbuf + coding->charbuf_used; |
1183 |
|
unsigned char *dst = coding->destination + coding->produced; |
1184 |
|
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
1185 |
|
int produced_chars; |
1186 |
|
int c; |
1187 |
|
|
1188 |
|
if (multibytep) |
1189 |
|
{ |
1190 |
|
int safe_room = MAX_MULTIBYTE_LENGTH * 2; |
1191 |
|
|
1192 |
|
while (charbuf < charbuf_end) |
1193 |
|
{ |
1194 |
|
unsigned char str[MAX_MULTIBYTE_LENGTH], *p, *pend = str; |
1195 |
|
|
1196 |
|
ASSURE_DESTINATION (safe_room); |
1197 |
|
c = *charbuf++; |
1198 |
|
CHAR_STRING_ADVANCE (c, pend); |
1199 |
|
for (p = str; p < pend; p++) |
1200 |
|
EMIT_ONE_BYTE (*p); |
1201 |
|
} |
1202 |
|
} |
1203 |
|
else |
1204 |
|
{ |
1205 |
|
int safe_room = MAX_MULTIBYTE_LENGTH; |
1206 |
|
|
1207 |
|
while (charbuf < charbuf_end) |
1208 |
|
{ |
1209 |
|
ASSURE_DESTINATION (safe_room); |
1210 |
|
c = *charbuf++; |
1211 |
|
dst += CHAR_STRING (c, dst); |
1212 |
|
produced_chars++; |
1213 |
|
} |
1214 |
|
} |
1215 |
|
coding->result = CODING_RESULT_SUCCESS; |
1216 |
|
coding->produced_char += produced_chars; |
1217 |
|
coding->produced = dst - coding->destination; |
1218 |
|
return 0; |
1219 |
|
} |
1220 |
|
|
1221 |
|
|
1222 |
|
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
1223 |
|
Check if a text is encoded in UTF-16 Big Endian (endian == 1) or |
1224 |
|
Little Endian (otherwise). If it is, return |
1225 |
|
CATEGORY_MASK_UTF_16_BE or CATEGORY_MASK_UTF_16_LE, |
1226 |
|
else return 0. */ |
1227 |
|
|
1228 |
|
#define UTF_16_HIGH_SURROGATE_P(val) \ |
1229 |
|
(((val) & 0xFC00) == 0xD800) |
1230 |
|
|
1231 |
|
#define UTF_16_LOW_SURROGATE_P(val) \ |
1232 |
|
(((val) & 0xFC00) == 0xDC00) |
1233 |
|
|
1234 |
|
#define UTF_16_INVALID_P(val) \ |
1235 |
|
(((val) == 0xFFFE) \ |
1236 |
|
|| ((val) == 0xFFFF) \ |
1237 |
|
|| UTF_16_LOW_SURROGATE_P (val)) |
1238 |
|
|
1239 |
|
|
1240 |
|
static int |
1241 |
|
detect_coding_utf_16 (coding, mask) |
1242 |
|
struct coding_system *coding; |
1243 |
|
int *mask; |
1244 |
|
{ |
1245 |
|
unsigned char *src = coding->source, *src_base = src; |
1246 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
1247 |
|
int multibytep = coding->src_multibyte; |
1248 |
|
int consumed_chars = 0; |
1249 |
|
int c1, c2; |
1250 |
|
|
1251 |
|
ONE_MORE_BYTE (c1); |
1252 |
|
ONE_MORE_BYTE (c2); |
1253 |
|
|
1254 |
|
if ((c1 == 0xFF) && (c2 == 0xFE)) |
1255 |
|
{ |
1256 |
|
*mask &= CATEGORY_MASK_UTF_16_LE; |
1257 |
|
return 1; |
1258 |
|
} |
1259 |
|
else if ((c1 == 0xFE) && (c2 == 0xFF)) |
1260 |
|
{ |
1261 |
|
*mask &= CATEGORY_MASK_UTF_16_BE; |
1262 |
|
return 1; |
1263 |
|
} |
1264 |
|
no_more_source: |
1265 |
|
return 0; |
1266 |
|
} |
1267 |
|
|
1268 |
|
static void |
1269 |
|
decode_coding_utf_16 (coding) |
1270 |
struct coding_system *coding; |
struct coding_system *coding; |
1271 |
{ |
{ |
1272 |
Lisp_Object coding_spec, plist, safe_chars; |
unsigned char *src = coding->source + coding->consumed; |
1273 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
1274 |
|
unsigned char *src_base, *surrogate_high_base; |
1275 |
|
int *charbuf = coding->charbuf; |
1276 |
|
int *charbuf_end = charbuf + coding->charbuf_size; |
1277 |
|
int consumed_chars = 0, consumed_chars_base; |
1278 |
|
int multibytep = coding->src_multibyte; |
1279 |
|
enum utf_16_bom_type bom = CODING_UTF_16_BOM (coding); |
1280 |
|
enum utf_16_endian_type endian = CODING_UTF_16_ENDIAN (coding); |
1281 |
|
int surrogate = CODING_UTF_16_SURROGATE (coding); |
1282 |
|
Lisp_Object attr, eol_type, charset_list; |
1283 |
|
|
1284 |
|
CODING_GET_INFO (coding, attr, eol_type, charset_list); |
1285 |
|
|
1286 |
|
if (bom != utf_16_without_bom) |
1287 |
|
{ |
1288 |
|
int c, c1, c2; |
1289 |
|
|
1290 |
|
src_base = src; |
1291 |
|
ONE_MORE_BYTE (c1); |
1292 |
|
ONE_MORE_BYTE (c2); |
1293 |
|
c = (c1 << 16) | c2; |
1294 |
|
if (bom == utf_16_with_bom) |
1295 |
|
{ |
1296 |
|
if (endian == utf_16_big_endian |
1297 |
|
? c != 0xFFFE : c != 0xFEFF) |
1298 |
|
{ |
1299 |
|
/* We are sure that there's enouph room at CHARBUF. */ |
1300 |
|
*charbuf++ = c1; |
1301 |
|
*charbuf++ = c2; |
1302 |
|
coding->errors++; |
1303 |
|
} |
1304 |
|
} |
1305 |
|
else |
1306 |
|
{ |
1307 |
|
if (c == 0xFFFE) |
1308 |
|
CODING_UTF_16_ENDIAN (coding) |
1309 |
|
= endian = utf_16_big_endian; |
1310 |
|
else if (c == 0xFEFF) |
1311 |
|
CODING_UTF_16_ENDIAN (coding) |
1312 |
|
= endian = utf_16_little_endian; |
1313 |
|
else |
1314 |
|
{ |
1315 |
|
CODING_UTF_16_ENDIAN (coding) |
1316 |
|
= endian = utf_16_big_endian; |
1317 |
|
src = src_base; |
1318 |
|
} |
1319 |
|
} |
1320 |
|
CODING_UTF_16_BOM (coding) = utf_16_with_bom; |
1321 |
|
} |
1322 |
|
|
1323 |
|
while (1) |
1324 |
|
{ |
1325 |
|
int c, c1, c2; |
1326 |
|
|
1327 |
coding_spec = Fget (coding->symbol, Qcoding_system); |
src_base = src; |
1328 |
plist = XVECTOR (coding_spec)->contents[3]; |
consumed_chars_base = consumed_chars; |
1329 |
safe_chars = Fplist_get (XVECTOR (coding_spec)->contents[3], Qsafe_chars); |
|
1330 |
return (CHAR_TABLE_P (safe_chars) ? safe_chars : Qt); |
if (charbuf + 2 >= charbuf_end) |
1331 |
|
break; |
1332 |
|
|
1333 |
|
ONE_MORE_BYTE (c1); |
1334 |
|
ONE_MORE_BYTE (c2); |
1335 |
|
c = (endian == utf_16_big_endian |
1336 |
|
? ((c1 << 16) | c2) : ((c2 << 16) | c1)); |
1337 |
|
if (surrogate) |
1338 |
|
{ |
1339 |
|
if (! UTF_16_LOW_SURROGATE_P (c)) |
1340 |
|
{ |
1341 |
|
if (endian == utf_16_big_endian) |
1342 |
|
c1 = surrogate >> 8, c2 = surrogate & 0xFF; |
1343 |
|
else |
1344 |
|
c1 = surrogate & 0xFF, c2 = surrogate >> 8; |
1345 |
|
*charbuf++ = c1; |
1346 |
|
*charbuf++ = c2; |
1347 |
|
coding->errors++; |
1348 |
|
if (UTF_16_HIGH_SURROGATE_P (c)) |
1349 |
|
CODING_UTF_16_SURROGATE (coding) = surrogate = c; |
1350 |
|
else |
1351 |
|
*charbuf++ = c; |
1352 |
|
} |
1353 |
|
else |
1354 |
|
{ |
1355 |
|
c = ((surrogate - 0xD800) << 10) | (c - 0xDC00); |
1356 |
|
CODING_UTF_16_SURROGATE (coding) = surrogate = 0; |
1357 |
|
*charbuf++ = c; |
1358 |
|
} |
1359 |
|
} |
1360 |
|
else |
1361 |
|
{ |
1362 |
|
if (UTF_16_HIGH_SURROGATE_P (c)) |
1363 |
|
CODING_UTF_16_SURROGATE (coding) = surrogate = c; |
1364 |
|
else |
1365 |
|
*charbuf++ = c; |
1366 |
|
} |
1367 |
|
} |
1368 |
|
|
1369 |
|
no_more_source: |
1370 |
|
coding->consumed_char += consumed_chars_base; |
1371 |
|
coding->consumed = src_base - coding->source; |
1372 |
|
coding->charbuf_used = charbuf - coding->charbuf; |
1373 |
} |
} |
1374 |
|
|
1375 |
#define CODING_SAFE_CHAR_P(safe_chars, c) \ |
static int |
1376 |
(EQ (safe_chars, Qt) || !NILP (CHAR_TABLE_REF (safe_chars, c))) |
encode_coding_utf_16 (coding) |
1377 |
|
struct coding_system *coding; |
1378 |
|
{ |
1379 |
|
int multibytep = coding->dst_multibyte; |
1380 |
|
int *charbuf = coding->charbuf; |
1381 |
|
int *charbuf_end = charbuf + coding->charbuf_used; |
1382 |
|
unsigned char *dst = coding->destination + coding->produced; |
1383 |
|
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
1384 |
|
int safe_room = 8; |
1385 |
|
enum utf_16_bom_type bom = CODING_UTF_16_BOM (coding); |
1386 |
|
int big_endian = CODING_UTF_16_ENDIAN (coding) == utf_16_big_endian; |
1387 |
|
int produced_chars = 0; |
1388 |
|
Lisp_Object attrs, eol_type, charset_list; |
1389 |
|
int c; |
1390 |
|
|
1391 |
|
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
1392 |
|
|
1393 |
|
if (bom == utf_16_with_bom) |
1394 |
|
{ |
1395 |
|
ASSURE_DESTINATION (safe_room); |
1396 |
|
if (big_endian) |
1397 |
|
EMIT_TWO_BYTES (0xFF, 0xFE); |
1398 |
|
else |
1399 |
|
EMIT_TWO_BYTES (0xFE, 0xFF); |
1400 |
|
CODING_UTF_16_BOM (coding) = utf_16_without_bom; |
1401 |
|
} |
1402 |
|
|
1403 |
|
while (charbuf < charbuf_end) |
1404 |
|
{ |
1405 |
|
ASSURE_DESTINATION (safe_room); |
1406 |
|
c = *charbuf++; |
1407 |
|
if (c >= 0x110000) |
1408 |
|
c = 0xFFFF; |
1409 |
|
|
1410 |
|
if (c < 0x10000) |
1411 |
|
{ |
1412 |
|
if (big_endian) |
1413 |
|
EMIT_TWO_BYTES (c >> 8, c & 0xFF); |
1414 |
|
else |
1415 |
|
EMIT_TWO_BYTES (c & 0xFF, c >> 8); |
1416 |
|
} |
1417 |
|
else |
1418 |
|
{ |
1419 |
|
int c1, c2; |
1420 |
|
|
1421 |
|
c -= 0x10000; |
1422 |
|
c1 = (c >> 10) + 0xD800; |
1423 |
|
c2 = (c & 0x3FF) + 0xDC00; |
1424 |
|
if (big_endian) |
1425 |
|
EMIT_FOUR_BYTES (c1 >> 8, c1 & 0xFF, c2 >> 8, c2 & 0xFF); |
1426 |
|
else |
1427 |
|
EMIT_FOUR_BYTES (c1 & 0xFF, c1 >> 8, c2 & 0xFF, c2 >> 8); |
1428 |
|
} |
1429 |
|
} |
1430 |
|
coding->result = CODING_RESULT_SUCCESS; |
1431 |
|
coding->produced = dst - coding->destination; |
1432 |
|
coding->produced_char += produced_chars; |
1433 |
|
return 0; |
1434 |
|
} |
1435 |
|
|
1436 |
|
|
1437 |
/*** 2. Emacs internal format (emacs-mule) handlers ***/ |
/*** 6. Old Emacs' internal format (emacs-mule) ***/ |
1438 |
|
|
1439 |
/* Emacs' internal format for representation of multiple character |
/* Emacs' internal format for representation of multiple character |
1440 |
sets is a kind of multi-byte encoding, i.e. characters are |
sets is a kind of multi-byte encoding, i.e. characters are |
1476 |
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 |
1477 |
form. |
form. |
1478 |
|
|
1479 |
Firstly, all characters in eight-bit-control are represented by |
At first, all characters in eight-bit-control are represented by |
1480 |
one-byte sequences which are their 8-bit code. |
one-byte sequences which are their 8-bit code. |
1481 |
|
|
1482 |
Next, character composition data are represented by the byte |
Next, character composition data are represented by the byte |
1485 |
METHOD is 0xF0 plus one of composition method (enum |
METHOD is 0xF0 plus one of composition method (enum |
1486 |
composition_method), |
composition_method), |
1487 |
|
|
1488 |
BYTES is 0xA0 plus the byte length of these composition data, |
BYTES is 0xA0 plus a byte length of this composition data, |
1489 |
|
|
1490 |
CHARS is 0xA0 plus the number of characters composed by these |
CHARS is 0x20 plus a number of characters composed by this |
1491 |
data, |
data, |
1492 |
|
|
1493 |
COMPONENTs are characters of multibyte form or composition |
COMPONENTs are characters of multibye form or composition |
1494 |
rules encoded by two-byte of ASCII codes. |
rules encoded by two-byte of ASCII codes. |
1495 |
|
|
1496 |
In addition, for backward compatibility, the following formats are |
In addition, for backward compatibility, the following formats are |
1507 |
represents a composition rule. |
represents a composition rule. |
1508 |
*/ |
*/ |
1509 |
|
|
1510 |
enum emacs_code_class_type emacs_code_class[256]; |
char emacs_mule_bytes[256]; |
1511 |
|
|
1512 |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
/* Leading-code followed by extended leading-code. */ |
1513 |
Check if a text is encoded in Emacs' internal format. If it is, |
#define LEADING_CODE_PRIVATE_11 0x9A /* for private DIMENSION1 of 1-column */ |
1514 |
return CODING_CATEGORY_MASK_EMACS_MULE, else return 0. */ |
#define LEADING_CODE_PRIVATE_12 0x9B /* for private DIMENSION1 of 2-column */ |
1515 |
|
#define LEADING_CODE_PRIVATE_21 0x9C /* for private DIMENSION2 of 1-column */ |
1516 |
|
#define LEADING_CODE_PRIVATE_22 0x9D /* for private DIMENSION2 of 2-column */ |
1517 |
|
|
1518 |
static int |
|
1519 |
detect_coding_emacs_mule (src, src_end, multibytep) |
int |
1520 |
unsigned char *src, *src_end; |
emacs_mule_char (coding, composition, nbytes, nchars) |
1521 |
int multibytep; |
struct coding_system *coding; |
1522 |
|
int composition; |
1523 |
|
int *nbytes, *nchars; |
1524 |
{ |
{ |
1525 |
unsigned char c; |
unsigned char *src = coding->source + coding->consumed; |
1526 |
int composing = 0; |
unsigned char *src_end = coding->source + coding->src_bytes; |
1527 |
/* Dummy for ONE_MORE_BYTE. */ |
int multibytep = coding->src_multibyte; |
1528 |
struct coding_system dummy_coding; |
unsigned char *src_base = src; |
1529 |
struct coding_system *coding = &dummy_coding; |
struct charset *charset; |
1530 |
|
unsigned code; |
1531 |
|
int c; |
1532 |
|
int consumed_chars = 0; |
1533 |
|
|
1534 |
while (1) |
ONE_MORE_BYTE (c); |
1535 |
|
if (composition) |
1536 |
{ |
{ |
1537 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
c -= 0x20; |
1538 |
|
if (c == 0x80) |
|
if (composing) |
|
1539 |
{ |
{ |
1540 |
|
ONE_MORE_BYTE (c); |
1541 |
if (c < 0xA0) |
if (c < 0xA0) |
1542 |
composing = 0; |
goto invalid_code; |
1543 |
else if (c == 0xA0) |
*nbytes = src - src_base; |
1544 |
{ |
*nchars = consumed_chars; |
1545 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
return (c - 0x80); |
|
c &= 0x7F; |
|
|
} |
|
|
else |
|
|
c -= 0x20; |
|
1546 |
} |
} |
1547 |
|
} |
1548 |
|
|
1549 |
|
switch (emacs_mule_bytes[c]) |
1550 |
|
{ |
1551 |
|
case 2: |
1552 |
|
if (! (charset = emacs_mule_charset[c])) |
1553 |
|
goto invalid_code; |
1554 |
|
ONE_MORE_BYTE (c); |
1555 |
|
code = c & 0x7F; |
1556 |
|
break; |
1557 |
|
|
1558 |
if (c < 0x20) |
case 3: |
1559 |
|
if (c == LEADING_CODE_PRIVATE_11 |
1560 |
|
|| c == LEADING_CODE_PRIVATE_12) |
1561 |
{ |
{ |
1562 |
if (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO) |
ONE_MORE_BYTE (c); |
1563 |
return 0; |
if (! (charset = emacs_mule_charset[c])) |
1564 |
|
goto invalid_code; |
1565 |
|
ONE_MORE_BYTE (c); |
1566 |
|
code = c & 0x7F; |
1567 |
} |
} |
1568 |
else if (c >= 0x80 && c < 0xA0) |
else |
1569 |
{ |
{ |
1570 |
if (c == 0x80) |
if (! (charset = emacs_mule_charset[c])) |
1571 |
/* Old leading code for a composite character. */ |
goto invalid_code; |
1572 |
composing = 1; |
ONE_MORE_BYTE (c); |
1573 |
else |
code = (c & 0x7F) << 7; |
1574 |
{ |
ONE_MORE_BYTE (c); |
1575 |
unsigned char *src_base = src - 1; |
code |= c & 0x7F; |
|
int bytes; |
|
|
|
|
|
if (!UNIBYTE_STR_AS_MULTIBYTE_P (src_base, src_end - src_base, |
|
|
bytes)) |
|
|
return 0; |
|
|
src = src_base + bytes; |
|
|
} |
|
1576 |
} |
} |
1577 |
|
break; |
1578 |
|
|
1579 |
|
case 4: |
1580 |
|
if (! (charset = emacs_mule_charset[c])) |
1581 |
|
goto invalid_code; |
1582 |
|
ONE_MORE_BYTE (c); |
1583 |
|
code = (c & 0x7F) << 7; |
1584 |
|
ONE_MORE_BYTE (c); |
1585 |
|
code |= c & 0x7F; |
1586 |
|
break; |
1587 |
|
|
1588 |
|
case 1: |
1589 |
|
code = c; |
1590 |
|
charset = CHARSET_FROM_ID (ASCII_BYTE_P (code) ? charset_ascii |
1591 |
|
: code < 0xA0 ? charset_8_bit_control |
1592 |
|
: charset_8_bit_graphic); |
1593 |
|
break; |
1594 |
|
|
1595 |
|
default: |
1596 |
|
abort (); |
1597 |
} |
} |
1598 |
label_end_of_loop: |
c = DECODE_CHAR (charset, code); |
1599 |
return CODING_CATEGORY_MASK_EMACS_MULE; |
if (c < 0) |
1600 |
|
goto invalid_code; |
1601 |
|
*nbytes = src - src_base; |
1602 |
|
*nchars = consumed_chars; |
1603 |
|
return c; |
1604 |
|
|
1605 |
|
no_more_source: |
1606 |
|
return -2; |
1607 |
|
|
1608 |
|
invalid_code: |
1609 |
|
return -1; |
1610 |
} |
} |
1611 |
|
|
1612 |
|
|
1613 |
/* Record the starting position START and METHOD of one composition. */ |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
1614 |
|
Check if a text is encoded in `emacs-mule'. */ |
1615 |
|
|
1616 |
#define CODING_ADD_COMPOSITION_START(coding, start, method) \ |
static int |
1617 |
do { \ |
detect_coding_emacs_mule (coding, mask) |
1618 |
struct composition_data *cmp_data = coding->cmp_data; \ |
struct coding_system *coding; |
1619 |
int *data = cmp_data->data + cmp_data->used; \ |
int *mask; |
1620 |
coding->cmp_data_start = cmp_data->used; \ |
{ |
1621 |
data[0] = -1; \ |
unsigned char *src = coding->source, *src_base = src; |
1622 |
data[1] = cmp_data->char_offset + start; \ |
unsigned char *src_end = coding->source + coding->src_bytes; |
1623 |
data[3] = (int) method; \ |
int multibytep = coding->src_multibyte; |
1624 |
cmp_data->used += 4; \ |
int consumed_chars = 0; |
1625 |
} while (0) |
int c; |
1626 |
|
int found = 0; |
1627 |
|
|
1628 |
/* Record the ending position END of the current composition. */ |
/* A coding system of this category is always ASCII compatible. */ |
1629 |
|
src += coding->head_ascii; |
1630 |
|
|
1631 |
#define CODING_ADD_COMPOSITION_END(coding, end) \ |
while (1) |
1632 |
do { \ |
{ |
1633 |
struct composition_data *cmp_data = coding->cmp_data; \ |
ONE_MORE_BYTE (c); |
|
int *data = cmp_data->data + coding->cmp_data_start; \ |
|
|
data[0] = cmp_data->used - coding->cmp_data_start; \ |
|
|
data[2] = cmp_data->char_offset + end; \ |
|
|
} while (0) |
|
1634 |
|
|
1635 |
/* Record one COMPONENT (alternate character or composition rule). */ |
if (c == 0x80) |
1636 |
|
{ |
1637 |
|
/* Perhaps the start of composite character. We simple skip |
1638 |
|
it because analyzing it is too heavy for detecting. But, |
1639 |
|
at least, we check that the composite character |
1640 |
|
constitues of more than 4 bytes. */ |
1641 |
|
unsigned char *src_base; |
1642 |
|
|
1643 |
#define CODING_ADD_COMPOSITION_COMPONENT(coding, component) \ |
repeat: |
1644 |
(coding->cmp_data->data[coding->cmp_data->used++] = component) |
src_base = src; |
1645 |
|
do |
1646 |
|
{ |
1647 |
|
ONE_MORE_BYTE (c); |
1648 |
|
} |
1649 |
|
while (c >= 0xA0); |
1650 |
|
|
1651 |
|
if (src - src_base <= 4) |
1652 |
|
break; |
1653 |
|
found = 1; |
1654 |
|
if (c == 0x80) |
1655 |
|
goto repeat; |
1656 |
|
} |
1657 |
|
|
1658 |
/* Get one byte from a data pointed by SRC and increment SRC. If SRC |
if (c < 0x80) |
1659 |
is not less than SRC_END, return -1 without incrementing Src. */ |
{ |
1660 |
|
if (c < 0x20 |
1661 |
|
&& (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO)) |
1662 |
|
break; |
1663 |
|
} |
1664 |
|
else |
1665 |
|
{ |
1666 |
|
unsigned char *src_base = src - 1; |
1667 |
|
|
1668 |
#define SAFE_ONE_MORE_BYTE() (src >= src_end ? -1 : *src++) |
do |
1669 |
|
{ |
1670 |
|
ONE_MORE_BYTE (c); |
1671 |
|
} |
1672 |
|
while (c >= 0xA0); |
1673 |
|
if (src - src_base != emacs_mule_bytes[*src_base]) |
1674 |
|
break; |
1675 |
|
found = 1; |
1676 |
|
} |
1677 |
|
} |
1678 |
|
*mask &= ~CATEGORY_MASK_EMACS_MULE; |
1679 |
|
return 0; |
1680 |
|
|
1681 |
|
no_more_source: |
1682 |
|
if (!found) |
1683 |
|
return 0; |
1684 |
|
*mask &= CATEGORY_MASK_EMACS_MULE; |
1685 |
|
return 1; |
1686 |
|
} |
1687 |
|
|
|
/* Decode a character represented as a component of composition |
|
|
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. */ |
|
1688 |
|
|
1689 |
#define DECODE_EMACS_MULE_COMPOSITION_CHAR(c, p) \ |
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". */ |
1690 |
do { \ |
|
1691 |
int bytes; \ |
/* Decode a character represented as a component of composition |
1692 |
\ |
sequence of Emacs 20/21 style at SRC. Set C to that character and |
1693 |
c = SAFE_ONE_MORE_BYTE (); \ |
update SRC to the head of next character (or an encoded composition |
1694 |
if (c < 0) \ |
rule). If SRC doesn't points a composition component, set C to -1. |
1695 |
break; \ |
If SRC points an invalid byte sequence, global exit by a return |
1696 |
if (CHAR_HEAD_P (c)) \ |
value 0. */ |
1697 |
c = -1; \ |
|
1698 |
else if (c == 0xA0) \ |
#define DECODE_EMACS_MULE_COMPOSITION_CHAR(buf) \ |
1699 |
{ \ |
if (1) \ |
1700 |
c = SAFE_ONE_MORE_BYTE (); \ |
{ \ |
1701 |
if (c < 0xA0) \ |
int c; \ |
1702 |
c = -1; \ |
int nbytes, nchars; \ |
|
else \ |
|
|
{ \ |
|
|
c -= 0xA0; \ |
|
|
*p++ = c; \ |
|
|
} \ |
|
|
} \ |
|
|
else if (BASE_LEADING_CODE_P (c - 0x20)) \ |
|
|
{ \ |
|
|
unsigned char *p0 = p; \ |
|
1703 |
\ |
\ |
1704 |
c -= 0x20; \ |
if (src == src_end) \ |
1705 |
*p++ = c; \ |
break; \ |
1706 |
bytes = BYTES_BY_CHAR_HEAD (c); \ |
c = emacs_mule_char (coding, 1, &nbytes, &nchars); \ |
1707 |
while (--bytes) \ |
if (c < 0) \ |
1708 |
{ \ |
{ \ |
1709 |
c = SAFE_ONE_MORE_BYTE (); \ |
if (c == -2) \ |
1710 |
if (c < 0) \ |
break; \ |
1711 |
break; \ |
goto invalid_code; \ |
1712 |
*p++ = c; \ |
} \ |
1713 |
} \ |
*buf++ = c; \ |
1714 |
if (UNIBYTE_STR_AS_MULTIBYTE_P (p0, p - p0, bytes)) \ |
src += nbytes; \ |
1715 |
c = STRING_CHAR (p0, bytes); \ |
consumed_chars += nchars; \ |
1716 |
else \ |
} \ |
1717 |
c = -1; \ |
else |
|
} \ |
|
|
else \ |
|
|
c = -1; \ |
|
|
} while (0) |
|
1718 |
|
|
1719 |
|
|
1720 |
/* Decode a composition rule represented as a component of composition |
/* Decode a composition rule represented as a component of composition |
1721 |
sequence of Emacs 20 style at SRC. Set C to the rule. If not |
sequence of Emacs 20 style at SRC. Set C to the rule. If SRC |
1722 |
valid rule is found, set C to -1. */ |
points an invalid byte sequence, set C to -1. */ |
1723 |
|
|
1724 |
#define DECODE_EMACS_MULE_COMPOSITION_RULE(c) \ |
#define DECODE_EMACS_MULE_COMPOSITION_RULE(buf) \ |
1725 |
do { \ |
do { \ |
1726 |
c = SAFE_ONE_MORE_BYTE (); \ |
int c, gref, nref; \ |
1727 |
|
\ |
1728 |
|
if (src < src_end) \ |
1729 |
|
goto invalid_code; \ |
1730 |
|
ONE_MORE_BYTE_NO_CHECK (c); \ |
1731 |
c -= 0xA0; \ |
c -= 0xA0; \ |
1732 |
if (c < 0 || c >= 81) \ |
if (c < 0 || c >= 81) \ |
1733 |
c = -1; \ |
goto invalid_code; \ |
1734 |
else \ |
\ |
1735 |
{ \ |
gref = c / 9, nref = c % 9; \ |
1736 |
gref = c / 9, nref = c % 9; \ |
*buf++ = COMPOSITION_ENCODE_RULE (gref, nref); \ |
|
c = COMPOSITION_ENCODE_RULE (gref, nref); \ |
|
|
} \ |
|
1737 |
} while (0) |
} while (0) |
1738 |
|
|
1739 |
|
|
1740 |
/* Decode composition sequence encoded by `emacs-mule' at the source |
#define ADD_COMPOSITION_DATA(buf, method, nchars) \ |
1741 |
pointed by SRC. SRC_END is the end of source. Store information |
do { \ |
1742 |
of the composition in CODING->cmp_data. |
*buf++ = -5; \ |
1743 |
|
*buf++ = coding->produced_char + char_offset; \ |
1744 |
For backward compatibility, decode also a composition sequence of |
*buf++ = CODING_ANNOTATE_COMPOSITION_MASK; \ |
1745 |
Emacs 20 style. In that case, the composition sequence contains |
*buf++ = method; \ |
1746 |
characters that should be extracted into a buffer or string. Store |
*buf++ = nchars; \ |
1747 |
those characters at *DESTINATION in multibyte form. |
} while (0) |
|
|
|
|
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. |
|
1748 |
|
|
|
*/ |
|
|
static INLINE int |
|
|
decode_composition_emacs_mule (coding, src, src_end, |
|
|
destination, dst_end, dst_bytes) |
|
|
struct coding_system *coding; |
|
|
unsigned char *src, *src_end, **destination, *dst_end; |
|
|
int dst_bytes; |
|
|
{ |
|
|
unsigned char *dst = *destination; |
|
|
int method, data_len, nchars; |
|
|
unsigned char *src_base = src++; |
|
|
/* Store components of composition. */ |
|
|
int component[COMPOSITION_DATA_MAX_BUNCH_LENGTH]; |
|
|
int ncomponent; |
|
|
/* Store multibyte form of characters to be composed. This is for |
|
|
Emacs 20 style composition sequence. */ |
|
|
unsigned char buf[MAX_COMPOSITION_COMPONENTS * MAX_MULTIBYTE_LENGTH]; |
|
|
unsigned char *bufp = buf; |
|
|
int c, i, gref, nref; |
|
1749 |
|
|
1750 |
if (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH |
#define DECODE_EMACS_MULE_21_COMPOSITION(c) \ |
1751 |
>= COMPOSITION_DATA_SIZE) |
do { \ |
1752 |
{ |
/* Emacs 21 style format. The first three bytes at SRC are \ |
1753 |
coding->result = CODING_FINISH_INSUFFICIENT_CMP; |
(METHOD - 0xF0), (BYTES - 0xA0), (CHARS - 0xA0), where BYTES is \ |
1754 |
return -1; |
the byte length of this composition information, CHARS is the \ |
1755 |
} |
number of characters composed by this composition. */ \ |
1756 |
|
enum composition_method method = c - 0xF0; \ |
1757 |
|
int consumed_chars_limit; \ |
1758 |
|
int nbytes, nchars; \ |
1759 |
|
\ |
1760 |
|
ONE_MORE_BYTE (c); \ |
1761 |
|
nbytes = c - 0xA0; \ |
1762 |
|
if (nbytes < 3) \ |
1763 |
|
goto invalid_code; \ |
1764 |
|
ONE_MORE_BYTE (c); \ |
1765 |
|
nchars = c - 0xA0; \ |
1766 |
|
ADD_COMPOSITION_DATA (charbuf, method, nchars); \ |
1767 |
|
consumed_chars_limit = consumed_chars_base + nbytes; \ |
1768 |
|
if (method != COMPOSITION_RELATIVE) \ |
1769 |
|
{ \ |
1770 |
|
int i = 0; \ |
1771 |
|
while (consumed_chars < consumed_chars_limit) \ |
1772 |
|
{ \ |
1773 |
|
if (i % 2 && method != COMPOSITION_WITH_ALTCHARS) \ |
1774 |
|
DECODE_EMACS_MULE_COMPOSITION_RULE (charbuf); \ |
1775 |
|
else \ |
1776 |
|
DECODE_EMACS_MULE_COMPOSITION_CHAR (charbuf); \ |
1777 |
|
} \ |
1778 |
|
if (consumed_chars < consumed_chars_limit) \ |
1779 |
|
goto invalid_code; \ |
1780 |
|
} \ |
1781 |
|
} while (0) |
1782 |
|
|
|
ONE_MORE_BYTE (c); |
|
|
if (c - 0xF0 >= COMPOSITION_RELATIVE |
|
|
&& c - 0xF0 <= COMPOSITION_WITH_RULE_ALTCHARS) |
|
|
{ |
|
|
int with_rule; |
|
1783 |
|
|
1784 |
method = c - 0xF0; |
#define DECODE_EMACS_MULE_20_RELATIVE_COMPOSITION(c) \ |
1785 |
with_rule = (method == COMPOSITION_WITH_RULE |
do { \ |
1786 |
|| method == COMPOSITION_WITH_RULE_ALTCHARS); |
/* Emacs 20 style format for relative composition. */ \ |
1787 |
ONE_MORE_BYTE (c); |
/* Store multibyte form of characters to be composed. */ \ |
1788 |
data_len = c - 0xA0; |
int components[MAX_COMPOSITION_COMPONENTS * 2 - 1]; \ |
1789 |
if (data_len < 4 |
int *buf = components; \ |
1790 |
|| src_base + data_len > src_end) |
int i, j; \ |
1791 |
return 0; |
\ |
1792 |
ONE_MORE_BYTE (c); |
src = src_base; \ |
1793 |
nchars = c - 0xA0; |
ONE_MORE_BYTE (c); /* skip 0x80 */ \ |
1794 |
if (c < 1) |
for (i = 0; i < MAX_COMPOSITION_COMPONENTS; i++) \ |
1795 |
return 0; |
DECODE_EMACS_MULE_COMPOSITION_CHAR (buf); \ |
1796 |
for (ncomponent = 0; src < src_base + data_len; ncomponent++) |
if (i < 2) \ |
1797 |
{ |
goto invalid_code; \ |
1798 |
/* If it is longer than this, it can't be valid. */ |
ADD_COMPOSITION_DATA (charbuf, COMPOSITION_RELATIVE, i); \ |
1799 |
if (ncomponent >= COMPOSITION_DATA_MAX_BUNCH_LENGTH) |
for (j = 0; j < i; j++) \ |
1800 |
return 0; |
*charbuf++ = components[j]; \ |
1801 |
|
} while (0) |
1802 |
|
|
|
if (ncomponent % 2 && with_rule) |
|
|
{ |
|
|
ONE_MORE_BYTE (gref); |
|
|
gref -= 32; |
|
|
ONE_MORE_BYTE (nref); |
|
|
nref -= 32; |
|
|
c = COMPOSITION_ENCODE_RULE (gref, nref); |
|
|
} |
|
|
else |
|
|
{ |
|
|
int bytes; |
|
|
if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes)) |
|
|
c = STRING_CHAR (src, bytes); |
|
|
else |
|
|
c = *src, bytes = 1; |
|
|
src += bytes; |
|
|
} |
|
|
component[ncomponent] = c; |
|
|
} |
|
|
} |
|
|
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) |
|
|
{ |
|
|
method = COMPOSITION_RELATIVE; |
|
|
for (ncomponent = 0; ncomponent < MAX_COMPOSITION_COMPONENTS;) |
|
|
{ |
|
|
DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp); |
|
|
if (c < 0) |
|
|
break; |
|
|
component[ncomponent++] = c; |
|
|
} |
|
|
if (ncomponent < 2) |
|
|
return 0; |
|
|
nchars = ncomponent; |
|
|
} |
|
|
else if (c == 0xFF) |
|
|
{ |
|
|
method = COMPOSITION_WITH_RULE; |
|
|
src++; |
|
|
DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp); |
|
|
if (c < 0) |
|
|
return 0; |
|
|
component[0] = c; |
|
|
for (ncomponent = 1; |
|
|
ncomponent < MAX_COMPOSITION_COMPONENTS * 2 - 1;) |
|
|
{ |
|
|
DECODE_EMACS_MULE_COMPOSITION_RULE (c); |
|
|
if (c < 0) |
|
|
break; |
|
|
component[ncomponent++] = c; |
|
|
DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp); |
|
|
if (c < 0) |
|
|
break; |
|
|
component[ncomponent++] = c; |
|
|
} |
|
|
if (ncomponent < 3) |
|
|
return 0; |
|
|
nchars = (ncomponent + 1) / 2; |
|
|
} |
|
|
else |
|
|
return 0; |
|
|
} |
|
1803 |
|
|
1804 |
if (buf == bufp || dst + (bufp - buf) <= (dst_bytes ? dst_end : src)) |
#define DECODE_EMACS_MULE_20_RULEBASE_COMPOSITION(c) \ |
1805 |
{ |
do { \ |
1806 |
CODING_ADD_COMPOSITION_START (coding, coding->produced_char, method); |
/* Emacs 20 style format for rule-base composition. */ \ |
1807 |
for (i = 0; i < ncomponent; i++) |
/* Store multibyte form of characters to be composed. */ \ |
1808 |
CODING_ADD_COMPOSITION_COMPONENT (coding, component[i]); |
int components[MAX_COMPOSITION_COMPONENTS * 2 - 1]; \ |
1809 |
CODING_ADD_COMPOSITION_END (coding, coding->produced_char + nchars); |
int *buf = components; \ |
1810 |
if (buf < bufp) |
int i, j; \ |
1811 |
{ |
\ |
1812 |
unsigned char *p = buf; |
DECODE_EMACS_MULE_COMPOSITION_CHAR (buf); \ |
1813 |
EMIT_BYTES (p, bufp); |
for (i = 0; i < MAX_COMPOSITION_COMPONENTS; i++) \ |
1814 |
*destination += bufp - buf; |
{ \ |
1815 |
coding->produced_char += nchars; |
DECODE_EMACS_MULE_COMPOSITION_RULE (buf); \ |
1816 |
} |
DECODE_EMACS_MULE_COMPOSITION_CHAR (buf); \ |
1817 |
return (src - src_base); |
} \ |
1818 |
} |
if (i < 1 || (buf - components) % 2 == 0) \ |
1819 |
label_end_of_loop: |
goto invalid_code; \ |
1820 |
return -1; |
if (charbuf + i + (i / 2) + 1 < charbuf_end) \ |
1821 |
} |
goto no_more_source; \ |
1822 |
|
ADD_COMPOSITION_DATA (buf, COMPOSITION_WITH_RULE, i); \ |
1823 |
|
for (j = 0; j < i; j++) \ |
1824 |
|
*charbuf++ = components[j]; \ |
1825 |
|
for (j = 0; j < i; j += 2) \ |
1826 |
|
*charbuf++ = components[j]; \ |
1827 |
|
} while (0) |
1828 |
|
|
|
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". */ |
|
1829 |
|
|
1830 |
static void |
static void |
1831 |
decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes) |
decode_coding_emacs_mule (coding) |
1832 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
1833 |
{ |
{ |
1834 |
unsigned char *src = source; |
unsigned char *src = coding->source + coding->consumed; |
1835 |
unsigned char *src_end = source + src_bytes; |
unsigned char *src_end = coding->source + coding->src_bytes; |
|
unsigned char *dst = destination; |
|
|
unsigned char *dst_end = destination + dst_bytes; |
|
|
/* SRC_BASE remembers the start position in source in each loop. |
|
|
The loop will be exited when there's not enough source code, or |
|
|
when there's not enough destination area to produce a |
|
|
character. */ |
|
1836 |
unsigned char *src_base; |
unsigned char *src_base; |
1837 |
|
int *charbuf = coding->charbuf; |
1838 |
|
int *charbuf_end = charbuf + coding->charbuf_size; |
1839 |
|
int consumed_chars = 0, consumed_chars_base; |
1840 |
|
int char_offset = 0; |
1841 |
|
int multibytep = coding->src_multibyte; |
1842 |
|
Lisp_Object attrs, eol_type, charset_list; |
1843 |
|
|
1844 |
coding->produced_char = 0; |
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
1845 |
while ((src_base = src) < src_end) |
|
1846 |
|
while (1) |
1847 |
{ |
{ |
1848 |
unsigned char tmp[MAX_MULTIBYTE_LENGTH], *p; |
int c; |
|
int bytes; |
|
1849 |
|
|
1850 |
if (*src == '\r') |
src_base = src; |
1851 |
{ |
consumed_chars_base = consumed_chars; |
|
int c = *src++; |
|
1852 |
|
|
1853 |
if (coding->eol_type == CODING_EOL_CR) |
if (charbuf >= charbuf_end) |
1854 |
c = '\n'; |
break; |
1855 |
else if (coding->eol_type == CODING_EOL_CRLF) |
|
1856 |
|
ONE_MORE_BYTE (c); |
1857 |
|
|
1858 |
|
if (c < 0x80) |
1859 |
|
{ |
1860 |
|
if (c == '\r') |
1861 |
{ |
{ |
1862 |
ONE_MORE_BYTE (c); |
if (EQ (eol_type, Qdos)) |
|
if (c != '\n') |
|
1863 |
{ |
{ |
1864 |
if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL) |
if (src == src_end) |
1865 |
{ |
goto no_more_source; |
1866 |
coding->result = CODING_FINISH_INCONSISTENT_EOL; |
if (*src == '\n') |
1867 |
goto label_end_of_loop; |
ONE_MORE_BYTE (c); |
|
} |
|
|
src--; |
|
|
c = '\r'; |
|
1868 |
} |
} |
1869 |
|
else if (EQ (eol_type, Qmac)) |
1870 |
|
c = '\n'; |
1871 |
} |
} |
1872 |
*dst++ = c; |
*charbuf++ = c; |
1873 |
coding->produced_char++; |
char_offset++; |
|
continue; |
|
1874 |
} |
} |
1875 |
else if (*src == '\n') |
else if (c == 0x80) |
1876 |
{ |
{ |
1877 |
if ((coding->eol_type == CODING_EOL_CR |
if (charbuf + 5 + (MAX_COMPOSITION_COMPONENTS * 2) - 1 > charbuf_end) |
1878 |
|| coding->eol_type == CODING_EOL_CRLF) |
break; |
1879 |
&& coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL) |
ONE_MORE_BYTE (c); |
1880 |
{ |
if (c - 0xF0 >= COMPOSITION_RELATIVE |
1881 |
coding->result = CODING_FINISH_INCONSISTENT_EOL; |
&& c - 0xF0 <= COMPOSITION_WITH_RULE_ALTCHARS) |
1882 |
goto label_end_of_loop; |
DECODE_EMACS_MULE_21_COMPOSITION (c); |
1883 |
} |
else if (c < 0xC0) |
1884 |
*dst++ = *src++; |
DECODE_EMACS_MULE_20_RELATIVE_COMPOSITION (c); |
1885 |
coding->produced_char++; |
else if (c == 0xFF) |
1886 |
continue; |
DECODE_EMACS_MULE_20_RULEBASE_COMPOSITION (c); |
1887 |
|
else |
1888 |
|
goto invalid_code; |
1889 |
} |
} |
1890 |
else if (*src == 0x80) |
else if (c < 0xA0 && emacs_mule_bytes[c] > 1) |
1891 |
{ |
{ |
1892 |
/* Start of composition data. */ |
int nbytes, nchars; |
1893 |
int consumed = decode_composition_emacs_mule (coding, src, src_end, |
src--; |
1894 |
&dst, dst_end, |
c = emacs_mule_char (coding, 0, &nbytes, &nchars); |
1895 |
dst_bytes); |
if (c < 0) |
|
if (consumed < 0) |
|
|
goto label_end_of_loop; |
|
|
else if (consumed > 0) |
|
1896 |
{ |
{ |
1897 |
src += consumed; |
if (c == -2) |
1898 |
continue; |
break; |
1899 |
|
goto invalid_code; |
1900 |
} |
} |
1901 |
bytes = CHAR_STRING (*src, tmp); |
*charbuf++ = c; |
1902 |
p = tmp; |
char_offset++; |
|
src++; |
|
|
} |
|
|
else if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes)) |
|
|
{ |
|
|
p = src; |
|
|
src += bytes; |
|
|
} |
|
|
else |
|
|
{ |
|
|
bytes = CHAR_STRING (*src, tmp); |
|
|
p = tmp; |
|
|
src++; |
|
1903 |
} |
} |
1904 |
if (dst + bytes >= (dst_bytes ? dst_end : src)) |
continue; |
1905 |
{ |
|
1906 |
coding->result = CODING_FINISH_INSUFFICIENT_DST; |
invalid_code: |
1907 |
break; |
src = src_base; |
1908 |
} |
consumed_chars = consumed_chars_base; |
1909 |
while (bytes--) *dst++ = *p++; |
ONE_MORE_BYTE (c); |
1910 |
coding->produced_char++; |
*charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c); |
1911 |
|
coding->errors++; |
1912 |
} |
} |
|
label_end_of_loop: |
|
|
coding->consumed = coding->consumed_char = src_base - source; |
|
|
coding->produced = dst - destination; |
|
|
} |
|
1913 |
|
|
1914 |
|
no_more_source: |
1915 |
|
coding->consumed_char += consumed_chars_base; |
1916 |
|
coding->consumed = src_base - coding->source; |
1917 |
|
coding->charbuf_used = charbuf - coding->charbuf; |
1918 |
|
} |
1919 |
|
|
|
/* 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) |
|
1920 |
|
|
1921 |
|
#define EMACS_MULE_LEADING_CODES(id, codes) \ |
1922 |
|
do { \ |
1923 |
|
if (id < 0xA0) \ |
1924 |
|
codes[0] = id, codes[1] = 0; \ |
1925 |
|
else if (id < 0xE0) \ |
1926 |
|
codes[0] = 0x9A, codes[1] = id; \ |
1927 |
|
else if (id < 0xF0) \ |
1928 |
|
codes[0] = 0x9B, codes[1] = id; \ |
1929 |
|
else if (id < 0xF5) \ |
1930 |
|
codes[0] = 0x9C, codes[1] = id; \ |
1931 |
|
else \ |
1932 |
|
codes[0] = 0x9D, codes[1] = id; \ |
1933 |
|
} while (0); |
1934 |
|
|
|
static void encode_eol P_ ((struct coding_system *, unsigned char *, |
|
|
unsigned char *, int, int)); |
|
1935 |
|
|
1936 |
static void |
static int |
1937 |
encode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes) |
encode_coding_emacs_mule (coding) |
1938 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
1939 |
{ |
{ |
1940 |
unsigned char *src = source; |
int multibytep = coding->dst_multibyte; |
1941 |
unsigned char *src_end = source + src_bytes; |
int *charbuf = coding->charbuf; |
1942 |
unsigned char *dst = destination; |
int *charbuf_end = charbuf + coding->charbuf_used; |
1943 |
unsigned char *dst_end = destination + dst_bytes; |
unsigned char *dst = coding->destination + coding->produced; |
1944 |
unsigned char *src_base; |
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
1945 |
|
int safe_room = 8; |
1946 |
|
unsigned char *adjusted_dst_end =dst_end - 8; |
1947 |
|
int produced_chars = 0; |
1948 |
|
Lisp_Object attrs, eol_type, charset_list; |
1949 |
int c; |
int c; |
|
int char_offset; |
|
|
int *data; |
|
|
|
|
|
Lisp_Object translation_table; |
|
1950 |
|
|
1951 |
translation_table = Qnil; |
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
|
|
|
|
/* 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; |
|
|
} |
|
1952 |
|
|
1953 |
char_offset = coding->cmp_data->char_offset; |
while (charbuf < charbuf_end) |
|
data = coding->cmp_data->data + coding->cmp_data_start; |
|
|
while (1) |
|
1954 |
{ |
{ |
1955 |
src_base = src; |
ASSURE_DESTINATION (safe_room); |
1956 |
|
c = *charbuf++; |
1957 |
/* If SRC starts a composition, encode the information about the |
if (ASCII_CHAR_P (c)) |
1958 |
composition in advance. */ |
EMIT_ONE_ASCII_BYTE (c); |
1959 |
if (coding->cmp_data_start < coding->cmp_data->used |
else |
|
&& 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)) |
|
1960 |
{ |
{ |
1961 |
if (coding->eol_type == CODING_EOL_CRLF) |
struct charset *charset; |
1962 |
EMIT_TWO_BYTES ('\r', c); |
unsigned code; |
1963 |
|
int dimension; |
1964 |
|
int emacs_mule_id; |
1965 |
|
unsigned char leading_codes[2]; |
1966 |
|
|
1967 |
|
charset = char_charset (c, charset_list, &code); |
1968 |
|
if (! charset) |
1969 |
|
{ |
1970 |
|
c = coding->default_char; |
1971 |
|
if (ASCII_CHAR_P (c)) |
1972 |
|
{ |
1973 |
|
EMIT_ONE_ASCII_BYTE (c); |
1974 |
|
continue; |
1975 |
|
} |
1976 |
|
charset = char_charset (c, charset_list, &code); |
1977 |
|
} |
1978 |
|
dimension = CHARSET_DIMENSION (charset); |
1979 |
|
emacs_mule_id = CHARSET_EMACS_MULE_ID (charset); |
1980 |
|
EMACS_MULE_LEADING_CODES (emacs_mule_id, leading_codes); |
1981 |
|
EMIT_ONE_BYTE (leading_codes[0]); |
1982 |
|
if (leading_codes[1]) |
1983 |
|
EMIT_ONE_BYTE (leading_codes[1]); |
1984 |
|
if (dimension == 1) |
1985 |
|
EMIT_ONE_BYTE (code); |
1986 |
else |
else |
1987 |
EMIT_ONE_BYTE ('\r'); |
{ |
1988 |
|
EMIT_ONE_BYTE (code >> 8); |
1989 |
|
EMIT_ONE_BYTE (code & 0xFF); |
1990 |
|
} |
1991 |
} |
} |
|
else if (SINGLE_BYTE_CHAR_P (c)) |
|
|
EMIT_ONE_BYTE (c); |
|
|
else |
|
|
EMIT_BYTES (src_base, src); |
|
|
coding->consumed_char++; |
|
1992 |
} |
} |
1993 |
label_end_of_loop: |
coding->result = CODING_RESULT_SUCCESS; |
1994 |
coding->consumed = src_base - source; |
coding->produced_char += produced_chars; |
1995 |
coding->produced = coding->produced_char = dst - destination; |
coding->produced = dst - coding->destination; |
1996 |
return; |
return 0; |
1997 |
} |
} |
1998 |
|
|
1999 |
|
|
2000 |
/*** 3. ISO2022 handlers ***/ |
/*** 7. ISO2022 handlers ***/ |
2001 |
|
|
2002 |
/* The following note describes the coding system ISO2022 briefly. |
/* The following note describes the coding system ISO2022 briefly. |
2003 |
Since the intention of this note is to help understand the |
Since the intention of this note is to help understand the |
2004 |
functions in this file, some parts are NOT ACCURATE or are OVERLY |
functions in this file, some parts are NOT ACCURATE or OVERLY |
2005 |
SIMPLIFIED. For thorough understanding, please refer to the |
SIMPLIFIED. For thorough understanding, please refer to the |
2006 |
original document of ISO2022. This is equivalent to the standard |
original document of ISO2022. |
|
ECMA-35, obtainable from <URL:http://www.ecma.ch/> (*). |
|
2007 |
|
|
2008 |
ISO2022 provides many mechanisms to encode several character sets |
ISO2022 provides many mechanisms to encode several character sets |
2009 |
in 7-bit and 8-bit environments. For 7-bit environments, all text |
in 7-bit and 8-bit environments. For 7-bite environments, all text |
2010 |
is encoded using bytes less than 128. This may make the encoded |
is encoded using bytes less than 128. This may make the encoded |
2011 |
text a little bit longer, but the text passes more easily through |
text a little bit longer, but the text passes more easily through |
2012 |
several types of gateway, some of which strip off the MSB (Most |
several gateways, some of which strip off MSB (Most Signigant Bit). |
|
Significant Bit). |
|
2013 |
|
|
2014 |
There are two kinds of character sets: control character sets and |
There are two kinds of character sets: control character set and |
2015 |
graphic character sets. The former contain control characters such |
graphic character set. The former contains control characters such |
2016 |
as `newline' and `escape' to provide control functions (control |
as `newline' and `escape' to provide control functions (control |
2017 |
functions are also provided by escape sequences). The latter |
functions are also provided by escape sequences). The latter |
2018 |
contain graphic characters such as 'A' and '-'. Emacs recognizes |
contains graphic characters such as 'A' and '-'. Emacs recognizes |
2019 |
two control character sets and many graphic character sets. |
two control character sets and many graphic character sets. |
2020 |
|
|
2021 |
Graphic character sets are classified into one of the following |
Graphic character sets are classified into one of the following |
2027 |
- DIMENSION2_CHARS96 |
- DIMENSION2_CHARS96 |
2028 |
|
|
2029 |
In addition, each character set is assigned an identification tag, |
In addition, each character set is assigned an identification tag, |
2030 |
unique for each set, called the "final character" (denoted as <F> |
unique for each set, called "final character" (denoted as <F> |
2031 |
hereafter). The <F> of each character set is decided by ECMA(*) |
hereafter). The <F> of each character set is decided by ECMA(*) |
2032 |
when it is registered in ISO. The code range of <F> is 0x30..0x7F |
when it is registered in ISO. The code range of <F> is 0x30..0x7F |
2033 |
(0x30..0x3F are for private use only). |
(0x30..0x3F are for private use only). |
2034 |
|
|
2035 |
Note (*): ECMA = European Computer Manufacturers Association |
Note (*): ECMA = European Computer Manufacturers Association |
2036 |
|
|
2037 |
Here are examples of graphic character sets [NAME(<F>)]: |
Here are examples of graphic character set [NAME(<F>)]: |
2038 |
o DIMENSION1_CHARS94 -- ASCII('B'), right-half-of-JISX0201('I'), ... |
o DIMENSION1_CHARS94 -- ASCII('B'), right-half-of-JISX0201('I'), ... |
2039 |
o DIMENSION1_CHARS96 -- right-half-of-ISO8859-1('A'), ... |
o DIMENSION1_CHARS96 -- right-half-of-ISO8859-1('A'), ... |
2040 |
o DIMENSION2_CHARS94 -- GB2312('A'), JISX0208('B'), ... |
o DIMENSION2_CHARS94 -- GB2312('A'), JISX0208('B'), ... |
2125 |
7-bit environment, non-locking-shift, and non-single-shift. |
7-bit environment, non-locking-shift, and non-single-shift. |
2126 |
|
|
2127 |
Note (**): If <F> is '@', 'A', or 'B', the intermediate character |
Note (**): If <F> is '@', 'A', or 'B', the intermediate character |
2128 |
'(' can be omitted. We refer to this as "short-form" hereafter. |
'(' must be omitted. We refer to this as "short-form" hereafter. |
2129 |
|
|
2130 |
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 for encoding the |
2131 |
same multilingual text in ISO2022. Actually, there exist many |
same multilingual text in ISO2022. Actually, there exist many |
2132 |
coding systems such as Compound Text (used in X11's inter client |
coding systems such as Compound Text (used in X11's inter client |
2133 |
communication, ISO-2022-JP (used in Japanese Internet), ISO-2022-KR |
communication, ISO-2022-JP (used in Japanese internet), ISO-2022-KR |
2134 |
(used in Korean Internet), EUC (Extended UNIX Code, used in Asian |
(used in Korean internet), EUC (Extended UNIX Code, used in Asian |
2135 |
localized platforms), and all of these are variants of ISO2022. |
localized platforms), and all of these are variants of ISO2022. |
2136 |
|
|
2137 |
In addition to the above, Emacs handles two more kinds of escape |
In addition to the above, Emacs handles two more kinds of escape |
2153 |
o ESC '3' -- start relative composition with alternate chars (**) |
o ESC '3' -- start relative composition with alternate chars (**) |
2154 |
o ESC '4' -- start rule-base composition with alternate chars (**) |
o ESC '4' -- start rule-base composition with alternate chars (**) |
2155 |
Since these are not standard escape sequences of any ISO standard, |
Since these are not standard escape sequences of any ISO standard, |
2156 |
the use of them with these meanings is restricted to Emacs only. |
the use of them for these meaning is restricted to Emacs only. |
2157 |
|
|
2158 |
(*) This form is used only in Emacs 20.5 and older versions, |
(*) This form is used only in Emacs 20.5 and the older versions, |
2159 |
but the newer versions can safely decode it. |
but the newer versions can safely decode it. |
2160 |
(**) This form is used only in Emacs 21.1 and newer versions, |
(**) This form is used only in Emacs 21.1 and the newer versions, |
2161 |
and the older versions can't decode it. |
and the older versions can't decode it. |
2162 |
|
|
2163 |
Here's a list of example usages of these composition escape |
Here's a list of examples usages of these composition escape |
2164 |
sequences (categorized by `enum composition_method'). |
sequences (categorized by `enum composition_method'). |
2165 |
|
|
2166 |
COMPOSITION_RELATIVE: |
COMPOSITION_RELATIVE: |
2167 |
ESC 0 CHAR [ CHAR ] ESC 1 |
ESC 0 CHAR [ CHAR ] ESC 1 |
2168 |
COMPOSITION_WITH_RULE: |
COMPOSITOIN_WITH_RULE: |
2169 |
ESC 2 CHAR [ RULE CHAR ] ESC 1 |
ESC 2 CHAR [ RULE CHAR ] ESC 1 |
2170 |
COMPOSITION_WITH_ALTCHARS: |
COMPOSITION_WITH_ALTCHARS: |
2171 |
ESC 3 ALTCHAR [ ALTCHAR ] ESC 0 CHAR [ CHAR ] ESC 1 |
ESC 3 ALTCHAR [ ALTCHAR ] ESC 0 CHAR [ CHAR ] ESC 1 |
2174 |
|
|
2175 |
enum iso_code_class_type iso_code_class[256]; |
enum iso_code_class_type iso_code_class[256]; |
2176 |
|
|
2177 |
#define CHARSET_OK(idx, charset, c) \ |
#define SAFE_CHARSET_P(coding, id) \ |
2178 |
(coding_system_table[idx] \ |
((id) <= (coding)->max_charset_id \ |
2179 |
&& (charset == CHARSET_ASCII \ |
&& (coding)->safe_charsets[id] >= 0) |
2180 |
|| (safe_chars = coding_safe_chars (coding_system_table[idx]), \ |
|
2181 |
CODING_SAFE_CHAR_P (safe_chars, c))) \ |
|
2182 |
&& (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding_system_table[idx], \ |
#define SHIFT_OUT_OK(category) \ |
2183 |
charset) \ |
(CODING_ISO_INITIAL (&coding_categories[category], 1) >= 0) |
2184 |
!= CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION)) |
|
2185 |
|
static void |
2186 |
|
setup_iso_safe_charsets (Lisp_Object attrs) |
2187 |
|
{ |
2188 |
|
Lisp_Object charset_list, safe_charsets; |
2189 |
|
Lisp_Object request; |
2190 |
|
Lisp_Object reg_usage; |
2191 |
|
Lisp_Object tail; |
2192 |
|
int reg94, reg96; |
2193 |
|
int flags = XINT (AREF (attrs, coding_attr_iso_flags)); |
2194 |
|
int max_charset_id; |
2195 |
|
|
2196 |
|
charset_list = CODING_ATTR_CHARSET_LIST (attrs); |
2197 |
|
if ((flags & CODING_ISO_FLAG_FULL_SUPPORT) |
2198 |
|
&& ! EQ (charset_list, Viso_2022_charset_list)) |
2199 |
|
{ |
2200 |
|
CODING_ATTR_CHARSET_LIST (attrs) |
2201 |
|
= charset_list = Viso_2022_charset_list; |
2202 |
|
ASET (attrs, coding_attr_safe_charsets, Qnil); |
2203 |
|
} |
2204 |
|
|
2205 |
|
if (STRINGP (AREF (attrs, coding_attr_safe_charsets))) |
2206 |
|
return; |
2207 |
|
|
2208 |
|
max_charset_id = 0; |
2209 |
|
for (tail = charset_list; CONSP (tail); tail = XCDR (tail)) |
2210 |
|
{ |
2211 |
|
int id = XINT (XCAR (tail)); |
2212 |
|
if (max_charset_id < id) |
2213 |
|
max_charset_id = id; |
2214 |
|
} |
2215 |
|
|
2216 |
|
safe_charsets = Fmake_string (make_number (max_charset_id + 1), |
2217 |
|
make_number (255)); |
2218 |
|
request = AREF (attrs, coding_attr_iso_request); |
2219 |
|
reg_usage = AREF (attrs, coding_attr_iso_usage); |
2220 |
|
reg94 = XINT (XCAR (reg_usage)); |
2221 |
|
reg96 = XINT (XCDR (reg_usage)); |
2222 |
|
|
2223 |
|
for (tail = charset_list; CONSP (tail); tail = XCDR (tail)) |
2224 |
|
{ |
2225 |
|
Lisp_Object id; |
2226 |
|
Lisp_Object reg; |
2227 |
|
struct charset *charset; |
2228 |
|
|
2229 |
|
id = XCAR (tail); |
2230 |
|
charset = CHARSET_FROM_ID (XINT (id)); |
2231 |
|
reg = Fcdr (Fassq (request, id)); |
2232 |
|
if (! NILP (reg)) |
2233 |
|
XSTRING (safe_charsets)->data[XINT (id)] = XINT (reg); |
2234 |
|
else if (charset->iso_chars_96) |
2235 |
|
{ |
2236 |
|
if (reg96 < 4) |
2237 |
|
XSTRING (safe_charsets)->data[XINT (id)] = reg96; |
2238 |
|
} |
2239 |
|
else |
2240 |
|
{ |
2241 |
|
if (reg94 < 4) |
2242 |
|
XSTRING (safe_charsets)->data[XINT (id)] = reg94; |
2243 |
|
} |
2244 |
|
} |
2245 |
|
ASET (attrs, coding_attr_safe_charsets, safe_charsets); |
2246 |
|
} |
2247 |
|
|
|
#define SHIFT_OUT_OK(idx) \ |
|
|
(CODING_SPEC_ISO_INITIAL_DESIGNATION (coding_system_table[idx], 1) >= 0) |
|
2248 |
|
|
2249 |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
2250 |
Check if a text is encoded in ISO2022. If it is, return an |
Check if a text is encoded in ISO2022. If it is, returns an |
2251 |
integer in which appropriate flag bits any of: |
integer in which appropriate flag bits any of: |
2252 |
CODING_CATEGORY_MASK_ISO_7 |
CATEGORY_MASK_ISO_7 |
2253 |
CODING_CATEGORY_MASK_ISO_7_TIGHT |
CATEGORY_MASK_ISO_7_TIGHT |
2254 |
CODING_CATEGORY_MASK_ISO_8_1 |
CATEGORY_MASK_ISO_8_1 |
2255 |
CODING_CATEGORY_MASK_ISO_8_2 |
CATEGORY_MASK_ISO_8_2 |
2256 |
CODING_CATEGORY_MASK_ISO_7_ELSE |
CATEGORY_MASK_ISO_7_ELSE |
2257 |
CODING_CATEGORY_MASK_ISO_8_ELSE |
CATEGORY_MASK_ISO_8_ELSE |
2258 |
are set. If a code which should never appear in ISO2022 is found, |
are set. If a code which should never appear in ISO2022 is found, |
2259 |
returns 0. */ |
returns 0. */ |
2260 |
|
|
2261 |
static int |
static int |
2262 |
detect_coding_iso2022 (src, src_end, multibytep) |
detect_coding_iso_2022 (coding, mask) |
2263 |
unsigned char *src, *src_end; |
struct coding_system *coding; |
2264 |
int multibytep; |
int *mask; |
2265 |
{ |
{ |
2266 |
int mask = CODING_CATEGORY_MASK_ISO; |
unsigned char *src = coding->source, *src_base = src; |
2267 |
int mask_found = 0; |
unsigned char *src_end = coding->source + coding->src_bytes; |
2268 |
|
int multibytep = coding->src_multibyte; |
2269 |
|
int mask_iso = CATEGORY_MASK_ISO; |
2270 |
|
int mask_found = 0, mask_8bit_found = 0; |
2271 |
int reg[4], shift_out = 0, single_shifting = 0; |
int reg[4], shift_out = 0, single_shifting = 0; |
2272 |
int c, c1, charset; |
int id; |
2273 |
/* Dummy for ONE_MORE_BYTE. */ |
int c, c1; |
2274 |
struct coding_system dummy_coding; |
int consumed_chars = 0; |
2275 |
struct coding_system *coding = &dummy_coding; |
int i; |
2276 |
Lisp_Object safe_chars; |
|
2277 |
|
for (i = coding_category_iso_7; i <= coding_category_iso_8_else; i++) |
2278 |
|
{ |
2279 |
|
struct coding_system *this = &(coding_categories[i]); |
2280 |
|
Lisp_Object attrs, val; |
2281 |
|
|
2282 |
|
attrs = CODING_ID_ATTRS (this->id); |
2283 |
|
if (CODING_ISO_FLAGS (this) & CODING_ISO_FLAG_FULL_SUPPORT |
2284 |
|
&& ! EQ (CODING_ATTR_SAFE_CHARSETS (attrs), Viso_2022_charset_list)) |
2285 |
|
setup_iso_safe_charsets (attrs); |
2286 |
|
val = CODING_ATTR_SAFE_CHARSETS (attrs); |
2287 |
|
this->max_charset_id = XSTRING (val)->size - 1; |
2288 |
|
this->safe_charsets = (char *) XSTRING (val)->data; |
2289 |
|
} |
2290 |
|
|
2291 |
|
/* A coding system of this category is always ASCII compatible. */ |
2292 |
|
src += coding->head_ascii; |
2293 |
|
|
2294 |
reg[0] = CHARSET_ASCII, reg[1] = reg[2] = reg[3] = -1; |
reg[0] = charset_ascii, reg[1] = reg[2] = reg[3] = -1; |
2295 |
while (mask && src < src_end) |
while (mask_iso && src < src_end) |
2296 |
{ |
{ |
2297 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
ONE_MORE_BYTE (c); |
2298 |
switch (c) |
switch (c) |
2299 |
{ |
{ |
2300 |
case ISO_CODE_ESC: |
case ISO_CODE_ESC: |
2301 |
if (inhibit_iso_escape_detection) |
if (inhibit_iso_escape_detection) |
2302 |
break; |
break; |
2303 |
single_shifting = 0; |
single_shifting = 0; |
2304 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
ONE_MORE_BYTE (c); |
2305 |
if (c >= '(' && c <= '/') |
if (c >= '(' && c <= '/') |
2306 |
{ |
{ |
2307 |
/* Designation sequence for a charset of dimension 1. */ |
/* Designation sequence for a charset of dimension 1. */ |
2308 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep); |
ONE_MORE_BYTE (c1); |
2309 |
if (c1 < ' ' || c1 >= 0x80 |
if (c1 < ' ' || c1 >= 0x80 |
2310 |
|| (charset = iso_charset_table[0][c >= ','][c1]) < 0) |
|| (id = iso_charset_table[0][c >= ','][c1]) < 0) |
2311 |
/* Invalid designation sequence. Just ignore. */ |
/* Invalid designation sequence. Just ignore. */ |
2312 |
break; |
break; |
2313 |
reg[(c - '(') % 4] = charset; |
reg[(c - '(') % 4] = id; |
2314 |
} |
} |
2315 |
else if (c == '$') |
else if (c == '$') |
2316 |
{ |
{ |
2317 |
/* Designation sequence for a charset of dimension 2. */ |
/* Designation sequence for a charset of dimension 2. */ |
2318 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
ONE_MORE_BYTE (c); |
2319 |
if (c >= '@' && c <= 'B') |
if (c >= '@' && c <= 'B') |
2320 |
/* Designation for JISX0208.1978, GB2312, or JISX0208. */ |
/* Designation for JISX0208.1978, GB2312, or JISX0208. */ |
2321 |
reg[0] = charset = iso_charset_table[1][0][c]; |
reg[0] = id = iso_charset_table[1][0][c]; |
2322 |
else if (c >= '(' && c <= '/') |
else if (c >= '(' && c <= '/') |
2323 |
{ |
{ |
2324 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep); |
ONE_MORE_BYTE (c1); |
2325 |
if (c1 < ' ' || c1 >= 0x80 |
if (c1 < ' ' || c1 >= 0x80 |
2326 |
|| (charset = iso_charset_table[1][c >= ','][c1]) < 0) |
|| (id = iso_charset_table[1][c >= ','][c1]) < 0) |
2327 |
/* Invalid designation sequence. Just ignore. */ |
/* Invalid designation sequence. Just ignore. */ |
2328 |
break; |
break; |
2329 |
reg[(c - '(') % 4] = charset; |
reg[(c - '(') % 4] = id; |
2330 |
} |
} |
2331 |
else |
else |
2332 |
/* Invalid designation sequence. Just ignore. */ |
/* Invalid designation sequence. Just ignore. */ |
2335 |
else if (c == 'N' || c == 'O') |
else if (c == 'N' || c == 'O') |
2336 |
{ |
{ |
2337 |
/* ESC <Fe> for SS2 or SS3. */ |
/* ESC <Fe> for SS2 or SS3. */ |
2338 |
mask &= CODING_CATEGORY_MASK_ISO_7_ELSE; |
mask_iso &= CATEGORY_MASK_ISO_7_ELSE; |
2339 |
break; |
break; |
2340 |
} |
} |
2341 |
else if (c >= '0' && c <= '4') |
else if (c >= '0' && c <= '4') |
2342 |
{ |
{ |
2343 |
/* ESC <Fp> for start/end composition. */ |
/* ESC <Fp> for start/end composition. */ |
2344 |
mask_found |= CODING_CATEGORY_MASK_ISO; |
mask_found |= CATEGORY_MASK_ISO; |
2345 |
break; |
break; |
2346 |
} |
} |
2347 |
else |
else |
2348 |
/* Invalid escape sequence. Just ignore. */ |
{ |
2349 |
break; |
/* Invalid escape sequence. */ |
2350 |
|
mask_iso &= ~CATEGORY_MASK_ISO_ESCAPE; |
2351 |
|
break; |
2352 |
|
} |
2353 |
|
|
2354 |
/* We found a valid designation sequence for CHARSET. */ |
/* We found a valid designation sequence for CHARSET. */ |
2355 |
mask &= ~CODING_CATEGORY_MASK_ISO_8BIT; |
mask_iso &= ~CATEGORY_MASK_ISO_8BIT; |
2356 |
c = MAKE_CHAR (charset, 0, 0); |
if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7], |
2357 |
if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7, charset, c)) |
id)) |
2358 |
mask_found |= CODING_CATEGORY_MASK_ISO_7; |
mask_found |= CATEGORY_MASK_ISO_7; |
2359 |
else |
else |
2360 |
mask &= ~CODING_CATEGORY_MASK_ISO_7; |
mask_iso &= ~CATEGORY_MASK_ISO_7; |
2361 |
if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7_TIGHT, charset, c)) |
if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_tight], |
2362 |
mask_found |= CODING_CATEGORY_MASK_ISO_7_TIGHT; |
id)) |
2363 |
|
mask_found |= CATEGORY_MASK_ISO_7_TIGHT; |
2364 |
else |
else |
2365 |
mask &= ~CODING_CATEGORY_MASK_ISO_7_TIGHT; |
mask_iso &= ~CATEGORY_MASK_ISO_7_TIGHT; |
2366 |
if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7_ELSE, charset, c)) |
if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_else], |
2367 |
mask_found |= CODING_CATEGORY_MASK_ISO_7_ELSE; |
id)) |
2368 |
|
mask_found |= CATEGORY_MASK_ISO_7_ELSE; |
2369 |
else |
else |
2370 |
mask &= ~CODING_CATEGORY_MASK_ISO_7_ELSE; |
mask_iso &= ~CATEGORY_MASK_ISO_7_ELSE; |
2371 |
if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_8_ELSE, charset, c)) |
if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_8_else], |
2372 |
mask_found |= CODING_CATEGORY_MASK_ISO_8_ELSE; |
id)) |
2373 |
|
mask_found |= CATEGORY_MASK_ISO_8_ELSE; |
2374 |
else |
else |
2375 |
mask &= ~CODING_CATEGORY_MASK_ISO_8_ELSE; |
mask_iso &= ~CATEGORY_MASK_ISO_8_ELSE; |
2376 |
break; |
break; |
2377 |
|
|
2378 |
case ISO_CODE_SO: |
case ISO_CODE_SO: |
2381 |
single_shifting = 0; |
single_shifting = 0; |
2382 |
if (shift_out == 0 |
if (shift_out == 0 |
2383 |
&& (reg[1] >= 0 |
&& (reg[1] >= 0 |
2384 |
|| SHIFT_OUT_OK (CODING_CATEGORY_IDX_ISO_7_ELSE) |
|| SHIFT_OUT_OK (coding_category_iso_7_else) |
2385 |
|| SHIFT_OUT_OK (CODING_CATEGORY_IDX_ISO_8_ELSE))) |
|| SHIFT_OUT_OK (coding_category_iso_8_else))) |
2386 |
{ |
{ |
2387 |
/* Locking shift out. */ |
/* Locking shift out. */ |
2388 |
mask &= ~CODING_CATEGORY_MASK_ISO_7BIT; |
mask_iso &= ~CATEGORY_MASK_ISO_7BIT; |
2389 |
mask_found |= CODING_CATEGORY_MASK_ISO_SHIFT; |
mask_found |= CATEGORY_MASK_ISO_ELSE; |
2390 |
} |
} |
2391 |
break; |
break; |
2392 |
|
|
2393 |
case ISO_CODE_SI: |
case ISO_CODE_SI: |
2394 |
if (inhibit_iso_escape_detection) |
if (inhibit_iso_escape_detection) |
2395 |
break; |
break; |
2397 |
if (shift_out == 1) |
if (shift_out == 1) |
2398 |
{ |
{ |
2399 |
/* Locking shift in. */ |
/* Locking shift in. */ |
2400 |
mask &= ~CODING_CATEGORY_MASK_ISO_7BIT; |
mask_iso &= ~CATEGORY_MASK_ISO_7BIT; |
2401 |
mask_found |= CODING_CATEGORY_MASK_ISO_SHIFT; |
mask_found |= CATEGORY_MASK_ISO_ELSE; |
2402 |
} |
} |
2403 |
break; |
break; |
2404 |
|
|
2407 |
case ISO_CODE_SS2: |
case ISO_CODE_SS2: |
2408 |
case ISO_CODE_SS3: |
case ISO_CODE_SS3: |
2409 |
{ |
{ |
2410 |
int newmask = CODING_CATEGORY_MASK_ISO_8_ELSE; |
int newmask = CATEGORY_MASK_ISO_8_ELSE; |
2411 |
|
|
2412 |
if (inhibit_iso_escape_detection) |
if (inhibit_iso_escape_detection) |
2413 |
break; |
break; |
2414 |
if (c != ISO_CODE_CSI) |
if (c != ISO_CODE_CSI) |
2415 |
{ |
{ |
2416 |
if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags |
if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1]) |
2417 |
& CODING_FLAG_ISO_SINGLE_SHIFT) |
& CODING_ISO_FLAG_SINGLE_SHIFT) |
2418 |
newmask |= CODING_CATEGORY_MASK_ISO_8_1; |
newmask |= CATEGORY_MASK_ISO_8_1; |
2419 |
if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags |
if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_2]) |
2420 |
& CODING_FLAG_ISO_SINGLE_SHIFT) |
& CODING_ISO_FLAG_SINGLE_SHIFT) |
2421 |
newmask |= CODING_CATEGORY_MASK_ISO_8_2; |
newmask |= CATEGORY_MASK_ISO_8_2; |
2422 |
single_shifting = 1; |
single_shifting = 1; |
2423 |
} |
} |
2424 |
if (VECTORP (Vlatin_extra_code_table) |
if (VECTORP (Vlatin_extra_code_table) |
2425 |
&& !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c])) |
&& !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c])) |
2426 |
{ |
{ |
2427 |
if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags |
if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1]) |
2428 |
& CODING_FLAG_ISO_LATIN_EXTRA) |
& CODING_ISO_FLAG_LATIN_EXTRA) |
2429 |
newmask |= CODING_CATEGORY_MASK_ISO_8_1; |
newmask |= CATEGORY_MASK_ISO_8_1; |
2430 |
if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags |
if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_2]) |
2431 |
& CODING_FLAG_ISO_LATIN_EXTRA) |
& CODING_ISO_FLAG_LATIN_EXTRA) |
2432 |
newmask |= CODING_CATEGORY_MASK_ISO_8_2; |
newmask |= CATEGORY_MASK_ISO_8_2; |
2433 |
} |
} |
2434 |
mask &= newmask; |
mask_iso &= newmask; |
2435 |
mask_found |= newmask; |
mask_found |= newmask; |
2436 |
} |
} |
2437 |
break; |
break; |
2445 |
else if (c < 0xA0) |
else if (c < 0xA0) |
2446 |
{ |
{ |
2447 |
single_shifting = 0; |
single_shifting = 0; |
2448 |
|
mask_8bit_found = 1; |
2449 |
if (VECTORP (Vlatin_extra_code_table) |
if (VECTORP (Vlatin_extra_code_table) |
2450 |
&& !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c])) |
&& !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c])) |
2451 |
{ |
{ |
2452 |
int newmask = 0; |
int newmask = 0; |
2453 |
|
|
2454 |
if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags |
if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1]) |
2455 |
& CODING_FLAG_ISO_LATIN_EXTRA) |
& CODING_ISO_FLAG_LATIN_EXTRA) |
2456 |
newmask |= CODING_CATEGORY_MASK_ISO_8_1; |
newmask |= CATEGORY_MASK_ISO_8_1; |
2457 |
if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags |
if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_2]) |
2458 |
& CODING_FLAG_ISO_LATIN_EXTRA) |
& CODING_ISO_FLAG_LATIN_EXTRA) |
2459 |
newmask |= CODING_CATEGORY_MASK_ISO_8_2; |
newmask |= CATEGORY_MASK_ISO_8_2; |
2460 |
mask &= newmask; |
mask_iso &= newmask; |
2461 |
mask_found |= newmask; |
mask_found |= newmask; |
2462 |
} |
} |
2463 |
else |
else |
2465 |
} |
} |
2466 |
else |
else |
2467 |
{ |
{ |
2468 |
mask &= ~(CODING_CATEGORY_MASK_ISO_7BIT |
mask_iso &= ~(CATEGORY_MASK_ISO_7BIT |
2469 |
| CODING_CATEGORY_MASK_ISO_7_ELSE); |
| CATEGORY_MASK_ISO_7_ELSE); |
2470 |
mask_found |= CODING_CATEGORY_MASK_ISO_8_1; |
mask_found |= CATEGORY_MASK_ISO_8_1; |
2471 |
|
mask_8bit_found = 1; |
2472 |
/* Check the length of succeeding codes of the range |
/* Check the length of succeeding codes of the range |
2473 |
0xA0..0FF. If the byte length is odd, we exclude |
0xA0..0FF. If the byte length is odd, we exclude |
2474 |
CODING_CATEGORY_MASK_ISO_8_2. We can check this only |
CATEGORY_MASK_ISO_8_2. We can check this only |
2475 |
when we are not single shifting. */ |
when we are not single shifting. */ |
2476 |
if (!single_shifting |
if (!single_shifting |
2477 |
&& mask & CODING_CATEGORY_MASK_ISO_8_2) |
&& mask_iso & CATEGORY_MASK_ISO_8_2) |
2478 |
{ |
{ |
2479 |
int i = 1; |
int i = 1; |
2480 |
while (src < src_end) |
while (src < src_end) |
2481 |
{ |
{ |
2482 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
ONE_MORE_BYTE (c); |
2483 |
if (c < 0xA0) |
if (c < 0xA0) |
2484 |
break; |
break; |
2485 |
i++; |
i++; |
2486 |
} |
} |
2487 |
|
|
2488 |
if (i & 1 && src < src_end) |
if (i & 1 && src < src_end) |
2489 |
mask &= ~CODING_CATEGORY_MASK_ISO_8_2; |
mask_iso &= ~CATEGORY_MASK_ISO_8_2; |
2490 |
else |
else |
2491 |
mask_found |= CODING_CATEGORY_MASK_ISO_8_2; |
mask_found |= CATEGORY_MASK_ISO_8_2; |
2492 |
} |
} |
2493 |
} |
} |
2494 |
break; |
break; |
2495 |
} |
} |
2496 |
} |
} |
2497 |
label_end_of_loop: |
no_more_source: |
2498 |
return (mask & mask_found); |
if (!mask_iso) |
2499 |
|
{ |
2500 |
|
*mask &= ~CATEGORY_MASK_ISO; |
2501 |
|
return 0; |
2502 |
|
} |
2503 |
|
if (!mask_found) |
2504 |
|
return 0; |
2505 |
|
*mask &= mask_iso & mask_found; |
2506 |
|
if (! mask_8bit_found) |
2507 |
|
*mask &= ~(CATEGORY_MASK_ISO_8BIT | CATEGORY_MASK_ISO_8_ELSE); |
2508 |
|
return 1; |
2509 |
} |
} |
2510 |
|
|
|
/* 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)) |
|
2511 |
|
|
2512 |
/* Set designation state into CODING. */ |
/* Set designation state into CODING. */ |
2513 |
#define DECODE_DESIGNATION(reg, dimension, chars, final_char) \ |
#define DECODE_DESIGNATION(reg, dim, chars_96, final) \ |
2514 |
do { \ |
do { \ |
2515 |
int charset, c; \ |
int id, prev; \ |
2516 |
\ |
\ |
2517 |
if (final_char < '0' || final_char >= 128) \ |
if (final < '0' || final >= 128 \ |
2518 |
goto label_invalid_code; \ |
|| ((id = ISO_CHARSET_TABLE (dim, chars_96, final)) < 0) \ |
2519 |
charset = ISO_CHARSET_TABLE (make_number (dimension), \ |
|| !SAFE_CHARSET_P (coding, id)) \ |
2520 |
make_number (chars), \ |
{ \ |
2521 |
make_number (final_char)); \ |
CODING_ISO_DESIGNATION (coding, reg) = -2; \ |
2522 |
c = MAKE_CHAR (charset, 0, 0); \ |
goto invalid_code; \ |
2523 |
if (charset >= 0 \ |
} \ |
2524 |
&& (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) == reg \ |
prev = CODING_ISO_DESIGNATION (coding, reg); \ |
2525 |
|| CODING_SAFE_CHAR_P (safe_chars, c))) \ |
CODING_ISO_DESIGNATION (coding, reg) = id; \ |
2526 |
{ \ |
/* If there was an invalid designation to REG previously, and this \ |
2527 |
if (coding->spec.iso2022.last_invalid_designation_register == 0 \ |
designation is ASCII to REG, we should keep this designation \ |
2528 |
&& reg == 0 \ |
sequence. */ \ |
2529 |
&& charset == CHARSET_ASCII) \ |
if (prev == -2 && id == charset_ascii) \ |
2530 |
{ \ |
goto invalid_code; \ |
|
/* We should insert this designation sequence as is so \ |
|
|
that it is surely written back to a file. */ \ |
|
|
coding->spec.iso2022.last_invalid_designation_register = -1; \ |
|
|
goto label_invalid_code; \ |
|
|
} \ |
|
|
coding->spec.iso2022.last_invalid_designation_register = -1; \ |
|
|
if ((coding->mode & CODING_MODE_DIRECTION) \ |
|
|
&& CHARSET_REVERSE_CHARSET (charset) >= 0) \ |
|
|
charset = CHARSET_REVERSE_CHARSET (charset); \ |
|
|
CODING_SPEC_ISO_DESIGNATION (coding, reg) = charset; \ |
|
|
} \ |
|
|
else \ |
|
|
{ \ |
|
|
coding->spec.iso2022.last_invalid_designation_register = reg; \ |
|
|
goto label_invalid_code; \ |
|
|
} \ |
|
2531 |
} while (0) |
} while (0) |
2532 |
|
|
|
/* Allocate a memory block for storing information about compositions. |
|
|
The block is chained to the already allocated blocks. */ |
|
2533 |
|
|
2534 |
void |
#define MAYBE_FINISH_COMPOSITION() \ |
2535 |
coding_allocate_composition_data (coding, char_offset) |
do { \ |
2536 |
struct coding_system *coding; |
int i; \ |
2537 |
int char_offset; |
if (composition_state == COMPOSING_NO) \ |
2538 |
{ |
break; \ |
2539 |
struct composition_data *cmp_data |
/* It is assured that we have enough room for producing \ |
2540 |
= (struct composition_data *) xmalloc (sizeof *cmp_data); |
characters stored in the table `components'. */ \ |
2541 |
|
if (charbuf + component_idx > charbuf_end) \ |
2542 |
|
goto no_more_source; \ |
2543 |
|
composition_state = COMPOSING_NO; \ |
2544 |
|
if (method == COMPOSITION_RELATIVE \ |
2545 |
|
|| method == COMPOSITION_WITH_ALTCHARS) \ |
2546 |
|
{ \ |
2547 |
|
for (i = 0; i < component_idx; i++) \ |
2548 |
|
*charbuf++ = components[i]; \ |
2549 |
|
char_offset += component_idx; \ |
2550 |
|
} \ |
2551 |
|
else \ |
2552 |
|
{ \ |
2553 |
|
for (i = 0; i < component_idx; i += 2) \ |
2554 |
|
*charbuf++ = components[i]; \ |
2555 |
|
char_offset += (component_idx / 2) + 1; \ |
2556 |
|
} \ |
2557 |
|
} while (0) |
2558 |
|
|
|
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; |
|
|
} |
|
2559 |
|
|
2560 |
/* 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. |
2561 |
ESC 0 : relative composition : ESC 0 CHAR ... ESC 1 |
ESC 0 : relative composition : ESC 0 CHAR ... ESC 1 |
2562 |
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 |
2563 |
ESC 3 : altchar composition : ESC 3 ALT ... ESC 0 CHAR ... ESC 1 |
ESC 3 : altchar composition : ESC 3 CHAR ... ESC 0 CHAR ... ESC 1 |
2564 |
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 |
2565 |
*/ |
*/ |
2566 |
|
|
2567 |
#define DECODE_COMPOSITION_START(c1) \ |
#define DECODE_COMPOSITION_START(c1) \ |
2568 |
do { \ |
do { \ |
2569 |
if (coding->composing == COMPOSITION_DISABLED) \ |
if (c1 == '0' \ |
2570 |
{ \ |
&& composition_state == COMPOSING_COMPONENT_CHAR) \ |
2571 |
*dst++ = ISO_CODE_ESC; \ |
{ \ |
2572 |
*dst++ = c1 & 0x7f; \ |
component_len = component_idx; \ |
2573 |
coding->produced_char += 2; \ |
composition_state = COMPOSING_CHAR; \ |
2574 |
} \ |
} \ |
2575 |
else if (!COMPOSING_P (coding)) \ |
else \ |
2576 |
{ \ |
{ \ |
2577 |
/* This is surely the start of a composition. We must be sure \ |
unsigned char *p; \ |
2578 |
that coding->cmp_data has enough space to store the \ |
\ |
2579 |
information about the composition. If not, terminate the \ |
MAYBE_FINISH_COMPOSITION (); \ |
2580 |
current decoding loop, allocate one more memory block for \ |
if (charbuf + MAX_COMPOSITION_COMPONENTS > charbuf_end) \ |
2581 |
coding->cmp_data in the caller, then start the decoding \ |
goto no_more_source; \ |
2582 |
loop again. We can't allocate memory here directly because \ |
for (p = src; p < src_end - 1; p++) \ |
2583 |
it may cause buffer/string relocation. */ \ |
if (*p == ISO_CODE_ESC && p[1] == '1') \ |
2584 |
if (!coding->cmp_data \ |
break; \ |
2585 |
|| (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH \ |
if (p == src_end - 1) \ |
2586 |
>= COMPOSITION_DATA_SIZE)) \ |
{ \ |
2587 |
{ \ |
if (coding->mode & CODING_MODE_LAST_BLOCK) \ |
2588 |
coding->result = CODING_FINISH_INSUFFICIENT_CMP; \ |
goto invalid_code; \ |
2589 |
goto label_end_of_loop; \ |
goto no_more_source; \ |
2590 |
} \ |
} \ |
2591 |
coding->composing = (c1 == '0' ? COMPOSITION_RELATIVE \ |
\ |
2592 |
: c1 == '2' ? COMPOSITION_WITH_RULE \ |
/* This is surely the start of a composition. */ \ |
2593 |
: c1 == '3' ? COMPOSITION_WITH_ALTCHARS \ |
method = (c1 == '0' ? COMPOSITION_RELATIVE \ |
2594 |
: COMPOSITION_WITH_RULE_ALTCHARS); \ |
: c1 == '2' ? COMPOSITION_WITH_RULE \ |
2595 |
CODING_ADD_COMPOSITION_START (coding, coding->produced_char, \ |
: c1 == '3' ? COMPOSITION_WITH_ALTCHARS \ |
2596 |
coding->composing); \ |
: COMPOSITION_WITH_RULE_ALTCHARS); \ |
2597 |
coding->composition_rule_follows = 0; \ |
composition_state = (c1 <= '2' ? COMPOSING_CHAR \ |
2598 |
} \ |
: COMPOSING_COMPONENT_CHAR); \ |
2599 |
else \ |
component_idx = component_len = 0; \ |
2600 |
{ \ |
} \ |
|
/* 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; \ |
|
|
} \ |
|
|
} \ |
|
2601 |
} while (0) |
} while (0) |
2602 |
|
|
|
/* Handle composition end sequence ESC 1. */ |
|
2603 |
|
|
2604 |
#define DECODE_COMPOSITION_END(c1) \ |
/* Handle compositoin end sequence ESC 1. */ |
2605 |
|
|
2606 |
|
#define DECODE_COMPOSITION_END() \ |
2607 |
do { \ |
do { \ |
2608 |
if (! COMPOSING_P (coding)) \ |
int nchars = (component_len > 0 ? component_idx - component_len \ |
2609 |
|
: method == COMPOSITION_RELATIVE ? component_idx \ |
2610 |
|
: (component_idx + 1) / 2); \ |
2611 |
|
int i; \ |
2612 |
|
int *saved_charbuf = charbuf; \ |
2613 |
|
\ |
2614 |
|
ADD_COMPOSITION_DATA (charbuf, method, nchars); \ |
2615 |
|
if (method != COMPOSITION_RELATIVE) \ |
2616 |
{ \ |
{ \ |
2617 |
*dst++ = ISO_CODE_ESC; \ |
if (component_len == 0) \ |
2618 |
*dst++ = c1; \ |
for (i = 0; i < component_idx; i++) \ |
2619 |
coding->produced_char += 2; \ |
*charbuf++ = components[i]; \ |
2620 |
|
else \ |
2621 |
|
for (i = 0; i < component_len; i++) \ |
2622 |
|
*charbuf++ = components[i]; \ |
2623 |
|
*saved_charbuf = saved_charbuf - charbuf; \ |
2624 |
} \ |
} \ |
2625 |
|
if (method == COMPOSITION_WITH_RULE) \ |
2626 |
|
for (i = 0; i < component_idx; i += 2, char_offset++) \ |
2627 |
|
*charbuf++ = components[i]; \ |
2628 |
else \ |
else \ |
2629 |
{ \ |
for (i = component_len; i < component_idx; i++, char_offset++) \ |
2630 |
CODING_ADD_COMPOSITION_END (coding, coding->produced_char); \ |
*charbuf++ = components[i]; \ |
2631 |
coding->composing = COMPOSITION_NO; \ |
coding->annotated = 1; \ |
2632 |
} \ |
composition_state = COMPOSING_NO; \ |
2633 |
} while (0) |
} while (0) |
2634 |
|
|
2635 |
|
|
2636 |
/* 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 |
2637 |
from SRC) and store one encoded composition rule in |
from SRC) and store one encoded composition rule in |
2638 |
coding->cmp_data. */ |
coding->cmp_data. */ |
2639 |
|
|
2640 |
#define DECODE_COMPOSITION_RULE(c1) \ |
#define DECODE_COMPOSITION_RULE(c1) \ |
2641 |
do { \ |
do { \ |
|
int rule = 0; \ |
|
2642 |
(c1) -= 32; \ |
(c1) -= 32; \ |
2643 |
if (c1 < 81) /* old format (before ver.21) */ \ |
if (c1 < 81) /* old format (before ver.21) */ \ |
2644 |
{ \ |
{ \ |
2646 |
int nref = (c1) % 9; \ |
int nref = (c1) % 9; \ |
2647 |
if (gref == 4) gref = 10; \ |
if (gref == 4) gref = 10; \ |
2648 |
if (nref == 4) nref = 10; \ |
if (nref == 4) nref = 10; \ |
2649 |
rule = COMPOSITION_ENCODE_RULE (gref, nref); \ |
c1 = COMPOSITION_ENCODE_RULE (gref, nref); \ |
2650 |
} \ |
} \ |
2651 |
else if (c1 < 93) /* new format (after ver.21) */ \ |
else if (c1 < 93) /* new format (after ver.21) */ \ |
2652 |
{ \ |
{ \ |
2653 |
ONE_MORE_BYTE (c2); \ |
ONE_MORE_BYTE (c2); \ |
2654 |
rule = COMPOSITION_ENCODE_RULE (c1 - 81, c2 - 32); \ |
c1 = COMPOSITION_ENCODE_RULE (c1 - 81, c2 - 32); \ |
2655 |
} \ |
} \ |
2656 |
CODING_ADD_COMPOSITION_COMPONENT (coding, rule); \ |
else \ |
2657 |
coding->composition_rule_follows = 0; \ |
c1 = 0; \ |
2658 |
} while (0) |
} while (0) |
2659 |
|
|
2660 |
|
|
2661 |
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". */ |
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". */ |
2662 |
|
|
2663 |
static void |
static void |
2664 |
decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes) |
decode_coding_iso_2022 (coding) |
2665 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
2666 |
{ |
{ |
2667 |
unsigned char *src = source; |
unsigned char *src = coding->source + coding->consumed; |
2668 |
unsigned char *src_end = source + src_bytes; |
unsigned char *src_end = coding->source + coding->src_bytes; |
|
unsigned char *dst = destination; |
|
|
unsigned char *dst_end = destination + dst_bytes; |
|
|
/* Charsets invoked to graphic plane 0 and 1 respectively. */ |
|
|
int charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0); |
|
|
int charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1); |
|
|
/* SRC_BASE remembers the start position in source in each loop. |
|
|
The loop will be exited when there's not enough source code |
|
|
(within macro ONE_MORE_BYTE), or when there's not enough |
|
|
destination area to produce a character (within macro |
|
|
EMIT_CHAR). */ |
|
2669 |
unsigned char *src_base; |
unsigned char *src_base; |
2670 |
int c, charset; |
int *charbuf = coding->charbuf; |
2671 |
Lisp_Object translation_table; |
int *charbuf_end = charbuf + coding->charbuf_size - 4; |
2672 |
Lisp_Object safe_chars; |
int consumed_chars = 0, consumed_chars_base; |
2673 |
|
int char_offset = 0; |
2674 |
safe_chars = coding_safe_chars (coding); |
int multibytep = coding->src_multibyte; |
2675 |
|
/* Charsets invoked to graphic plane 0 and 1 respectively. */ |
2676 |
if (NILP (Venable_character_translation)) |
int charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0); |
2677 |
translation_table = Qnil; |
int charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1); |
2678 |
else |
struct charset *charset; |
2679 |
{ |
int c; |
2680 |
translation_table = coding->translation_table_for_decode; |
/* For handling composition sequence. */ |
2681 |
if (NILP (translation_table)) |
#define COMPOSING_NO 0 |
2682 |
translation_table = Vstandard_translation_table_for_decode; |
#define COMPOSING_CHAR 1 |
2683 |
} |
#define COMPOSING_RULE 2 |
2684 |
|
#define COMPOSING_COMPONENT_CHAR 3 |
2685 |
|
#define COMPOSING_COMPONENT_RULE 4 |
2686 |
|
|
2687 |
|
int composition_state = COMPOSING_NO; |
2688 |
|
enum composition_method method; |
2689 |
|
int components[MAX_COMPOSITION_COMPONENTS * 2 + 1]; |
2690 |
|
int component_idx; |
2691 |
|
int component_len; |
2692 |
|
Lisp_Object attrs, eol_type, charset_list; |
2693 |
|
|
2694 |
coding->result = CODING_FINISH_NORMAL; |
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
2695 |
|
setup_iso_safe_charsets (attrs); |
2696 |
|
|
2697 |
while (1) |
while (1) |
2698 |
{ |
{ |
2699 |
int c1, c2; |
int c1, c2; |
2700 |
|
|
2701 |
src_base = src; |
src_base = src; |
2702 |
|
consumed_chars_base = consumed_chars; |
2703 |
|
|
2704 |
|
if (charbuf >= charbuf_end) |
2705 |
|
break; |
2706 |
|
|
2707 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2708 |
|
|
2709 |
/* We produce no character or one character. */ |
/* We produce no character or one character. */ |
2710 |
switch (iso_code_class [c1]) |
switch (iso_code_class [c1]) |
2711 |
{ |
{ |
2712 |
case ISO_0x20_or_0x7F: |
case ISO_0x20_or_0x7F: |
2713 |
if (COMPOSING_P (coding) && coding->composition_rule_follows) |
if (composition_state != COMPOSING_NO) |
2714 |
{ |
{ |
2715 |
DECODE_COMPOSITION_RULE (c1); |
if (composition_state == COMPOSING_RULE |
2716 |
continue; |
|| composition_state == COMPOSING_COMPONENT_RULE) |
2717 |
|
{ |
2718 |
|
DECODE_COMPOSITION_RULE (c1); |
2719 |
|
components[component_idx++] = c1; |
2720 |
|
composition_state--; |
2721 |
|
continue; |
2722 |
|
} |
2723 |
|
else if (method == COMPOSITION_WITH_RULE) |
2724 |
|
composition_state = COMPOSING_RULE; |
2725 |
|
else if (method == COMPOSITION_WITH_RULE_ALTCHARS |
2726 |
|
&& composition_state == COMPOSING_COMPONENT_CHAR) |
2727 |
|
composition_state = COMPOSING_COMPONENT_CHAR; |
2728 |
} |
} |
2729 |
if (charset0 < 0 || CHARSET_CHARS (charset0) == 94) |
if (charset_id_0 < 0 |
2730 |
|
|| ! CHARSET_ISO_CHARS_96 (CHARSET_FROM_ID (charset_id_0))) |
2731 |
{ |
{ |
2732 |
/* This is SPACE or DEL. */ |
/* This is SPACE or DEL. */ |
2733 |
charset = CHARSET_ASCII; |
charset = CHARSET_FROM_ID (charset_ascii); |
2734 |
break; |
break; |
2735 |
} |
} |
2736 |
/* This is a graphic character, we fall down ... */ |
/* This is a graphic character, we fall down ... */ |
2737 |
|
|
2738 |
case ISO_graphic_plane_0: |
case ISO_graphic_plane_0: |
2739 |
if (COMPOSING_P (coding) && coding->composition_rule_follows) |
if (composition_state == COMPOSING_RULE) |
2740 |
{ |
{ |
2741 |
DECODE_COMPOSITION_RULE (c1); |
DECODE_COMPOSITION_RULE (c1); |
2742 |
continue; |
components[component_idx++] = c1; |
2743 |
|
composition_state = COMPOSING_CHAR; |
2744 |
} |
} |
2745 |
charset = charset0; |
charset = CHARSET_FROM_ID (charset_id_0); |
2746 |
break; |
break; |
2747 |
|
|
2748 |
case ISO_0xA0_or_0xFF: |
case ISO_0xA0_or_0xFF: |
2749 |
if (charset1 < 0 || CHARSET_CHARS (charset1) == 94 |
if (charset_id_1 < 0 |
2750 |
|| coding->flags & CODING_FLAG_ISO_SEVEN_BITS) |
|| ! CHARSET_ISO_CHARS_96 (CHARSET_FROM_ID (charset_id_1)) |
2751 |
goto label_invalid_code; |
|| CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS) |
2752 |
|
goto invalid_code; |
2753 |
/* This is a graphic character, we fall down ... */ |
/* This is a graphic character, we fall down ... */ |
2754 |
|
|
2755 |
case ISO_graphic_plane_1: |
case ISO_graphic_plane_1: |
2756 |
if (charset1 < 0) |
if (charset_id_1 < 0) |
2757 |
goto label_invalid_code; |
goto invalid_code; |
2758 |
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; |
|
2759 |
break; |
break; |
2760 |
|
|
|
case ISO_control_1: |
|
|
if (COMPOSING_P (coding)) |
|
|
DECODE_COMPOSITION_END ('1'); |
|
|
goto label_invalid_code; |
|
|
|
|
2761 |
case ISO_carriage_return: |
case ISO_carriage_return: |
2762 |
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) |
|
2763 |
{ |
{ |
2764 |
ONE_MORE_BYTE (c1); |
if (EQ (eol_type, Qdos)) |
|
if (c1 != ISO_CODE_LF) |
|
2765 |
{ |
{ |
2766 |
if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL) |
if (src == src_end) |
2767 |
{ |
goto no_more_source; |
2768 |
coding->result = CODING_FINISH_INCONSISTENT_EOL; |
if (*src == '\n') |
2769 |
goto label_end_of_loop; |
ONE_MORE_BYTE (c1); |
|
} |
|
|
src--; |
|
|
c1 = '\r'; |
|
2770 |
} |
} |
2771 |
|
else if (EQ (eol_type, Qmac)) |
2772 |
|
c1 = '\n'; |
2773 |
} |
} |
2774 |
charset = CHARSET_ASCII; |
/* fall through */ |
2775 |
|
|
2776 |
|
case ISO_control_0: |
2777 |
|
MAYBE_FINISH_COMPOSITION (); |
2778 |
|
charset = CHARSET_FROM_ID (charset_ascii); |
2779 |
break; |
break; |
2780 |
|
|
2781 |
|
case ISO_control_1: |
2782 |
|
MAYBE_FINISH_COMPOSITION (); |
2783 |
|
goto invalid_code; |
2784 |
|
|
2785 |
case ISO_shift_out: |
case ISO_shift_out: |
2786 |
if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT) |
2787 |
|| CODING_SPEC_ISO_DESIGNATION (coding, 1) < 0) |
|| CODING_ISO_DESIGNATION (coding, 1) < 0) |
2788 |
goto label_invalid_code; |
goto invalid_code; |
2789 |
CODING_SPEC_ISO_INVOCATION (coding, 0) = 1; |
CODING_ISO_INVOCATION (coding, 0) = 1; |
2790 |
charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0); |
charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0); |
2791 |
continue; |
continue; |
2792 |
|
|
2793 |
case ISO_shift_in: |
case ISO_shift_in: |
2794 |
if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT)) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT)) |
2795 |
goto label_invalid_code; |
goto invalid_code; |
2796 |
CODING_SPEC_ISO_INVOCATION (coding, 0) = 0; |
CODING_ISO_INVOCATION (coding, 0) = 0; |
2797 |
charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0); |
charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0); |
2798 |
continue; |
continue; |
2799 |
|
|
2800 |
case ISO_single_shift_2_7: |
case ISO_single_shift_2_7: |
2801 |
case ISO_single_shift_2: |
case ISO_single_shift_2: |
2802 |
if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)) |
2803 |
goto label_invalid_code; |
goto invalid_code; |
2804 |
/* SS2 is handled as an escape sequence of ESC 'N' */ |
/* SS2 is handled as an escape sequence of ESC 'N' */ |
2805 |
c1 = 'N'; |
c1 = 'N'; |
2806 |
goto label_escape_sequence; |
goto label_escape_sequence; |
2807 |
|
|
2808 |
case ISO_single_shift_3: |
case ISO_single_shift_3: |
2809 |
if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)) |
2810 |
goto label_invalid_code; |
goto invalid_code; |
2811 |
/* SS2 is handled as an escape sequence of ESC 'O' */ |
/* SS2 is handled as an escape sequence of ESC 'O' */ |
2812 |
c1 = 'O'; |
c1 = 'O'; |
2813 |
goto label_escape_sequence; |
goto label_escape_sequence; |
2820 |
case ISO_escape: |
case ISO_escape: |
2821 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2822 |
label_escape_sequence: |
label_escape_sequence: |
2823 |
/* Escape sequences handled by Emacs are invocation, |
/* Escape sequences handled here are invocation, |
2824 |
designation, direction specification, and character |
designation, direction specification, and character |
2825 |
composition specification. */ |
composition specification. */ |
2826 |
switch (c1) |
switch (c1) |
2828 |
case '&': /* revision of following character set */ |
case '&': /* revision of following character set */ |
2829 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2830 |
if (!(c1 >= '@' && c1 <= '~')) |
if (!(c1 >= '@' && c1 <= '~')) |
2831 |
goto label_invalid_code; |
goto invalid_code; |
2832 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2833 |
if (c1 != ISO_CODE_ESC) |
if (c1 != ISO_CODE_ESC) |
2834 |
goto label_invalid_code; |
goto invalid_code; |
2835 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2836 |
goto label_escape_sequence; |
goto label_escape_sequence; |
2837 |
|
|
2838 |
case '$': /* designation of 2-byte character set */ |
case '$': /* designation of 2-byte character set */ |
2839 |
if (! (coding->flags & CODING_FLAG_ISO_DESIGNATION)) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATION)) |
2840 |
goto label_invalid_code; |
goto invalid_code; |
2841 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2842 |
if (c1 >= '@' && c1 <= 'B') |
if (c1 >= '@' && c1 <= 'B') |
2843 |
{ /* designation of JISX0208.1978, GB2312.1980, |
{ /* designation of JISX0208.1978, GB2312.1980, |
2844 |
or JISX0208.1980 */ |
or JISX0208.1980 */ |
2845 |
DECODE_DESIGNATION (0, 2, 94, c1); |
DECODE_DESIGNATION (0, 2, 0, c1); |
2846 |
} |
} |
2847 |
else if (c1 >= 0x28 && c1 <= 0x2B) |
else if (c1 >= 0x28 && c1 <= 0x2B) |
2848 |
{ /* designation of DIMENSION2_CHARS94 character set */ |
{ /* designation of DIMENSION2_CHARS94 character set */ |
2849 |
ONE_MORE_BYTE (c2); |
ONE_MORE_BYTE (c2); |
2850 |
DECODE_DESIGNATION (c1 - 0x28, 2, 94, c2); |
DECODE_DESIGNATION (c1 - 0x28, 2, 0, c2); |
2851 |
} |
} |
2852 |
else if (c1 >= 0x2C && c1 <= 0x2F) |
else if (c1 >= 0x2C && c1 <= 0x2F) |
2853 |
{ /* designation of DIMENSION2_CHARS96 character set */ |
{ /* designation of DIMENSION2_CHARS96 character set */ |
2854 |
ONE_MORE_BYTE (c2); |
ONE_MORE_BYTE (c2); |
2855 |
DECODE_DESIGNATION (c1 - 0x2C, 2, 96, c2); |
DECODE_DESIGNATION (c1 - 0x2C, 2, 1, c2); |
2856 |
} |
} |
2857 |
else |
else |
2858 |
goto label_invalid_code; |
goto invalid_code; |
2859 |
/* We must update these variables now. */ |
/* We must update these variables now. */ |
2860 |
charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0); |
charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0); |
2861 |
charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1); |
charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1); |
2862 |
continue; |
continue; |
2863 |
|
|
2864 |
case 'n': /* invocation of locking-shift-2 */ |
case 'n': /* invocation of locking-shift-2 */ |
2865 |
if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT) |
2866 |
|| CODING_SPEC_ISO_DESIGNATION (coding, 2) < 0) |
|| CODING_ISO_DESIGNATION (coding, 2) < 0) |
2867 |
goto label_invalid_code; |
goto invalid_code; |
2868 |
CODING_SPEC_ISO_INVOCATION (coding, 0) = 2; |
CODING_ISO_INVOCATION (coding, 0) = 2; |
2869 |
charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0); |
charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0); |
2870 |
continue; |
continue; |
2871 |
|
|
2872 |
case 'o': /* invocation of locking-shift-3 */ |
case 'o': /* invocation of locking-shift-3 */ |
2873 |
if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT) |
2874 |
|| CODING_SPEC_ISO_DESIGNATION (coding, 3) < 0) |
|| CODING_ISO_DESIGNATION (coding, 3) < 0) |
2875 |
goto label_invalid_code; |
goto invalid_code; |
2876 |
CODING_SPEC_ISO_INVOCATION (coding, 0) = 3; |
CODING_ISO_INVOCATION (coding, 0) = 3; |
2877 |
charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0); |
charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0); |
2878 |
continue; |
continue; |
2879 |
|
|
2880 |
case 'N': /* invocation of single-shift-2 */ |
case 'N': /* invocation of single-shift-2 */ |
2881 |
if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT) |
2882 |
|| CODING_SPEC_ISO_DESIGNATION (coding, 2) < 0) |
|| CODING_ISO_DESIGNATION (coding, 2) < 0) |
2883 |
goto label_invalid_code; |
goto invalid_code; |
2884 |
charset = CODING_SPEC_ISO_DESIGNATION (coding, 2); |
charset = CHARSET_FROM_ID (CODING_ISO_DESIGNATION (coding, 2)); |
2885 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2886 |
if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)) |
if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)) |
2887 |
goto label_invalid_code; |
goto invalid_code; |
2888 |
break; |
break; |
2889 |
|
|
2890 |
case 'O': /* invocation of single-shift-3 */ |
case 'O': /* invocation of single-shift-3 */ |
2891 |
if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT) |
2892 |
|| CODING_SPEC_ISO_DESIGNATION (coding, 3) < 0) |
|| CODING_ISO_DESIGNATION (coding, 3) < 0) |
2893 |
goto label_invalid_code; |
goto invalid_code; |
2894 |
charset = CODING_SPEC_ISO_DESIGNATION (coding, 3); |
charset = CHARSET_FROM_ID (CODING_ISO_DESIGNATION (coding, 3)); |
2895 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2896 |
if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)) |
if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)) |
2897 |
goto label_invalid_code; |
goto invalid_code; |
2898 |
break; |
break; |
2899 |
|
|
2900 |
case '0': case '2': case '3': case '4': /* start composition */ |
case '0': case '2': case '3': case '4': /* start composition */ |
2901 |
|
if (! (coding->common_flags & CODING_ANNOTATE_COMPOSITION_MASK)) |
2902 |
|
goto invalid_code; |
2903 |
DECODE_COMPOSITION_START (c1); |
DECODE_COMPOSITION_START (c1); |
2904 |
continue; |
continue; |
2905 |
|
|
2906 |
case '1': /* end composition */ |
case '1': /* end composition */ |
2907 |
DECODE_COMPOSITION_END (c1); |
if (composition_state == COMPOSING_NO) |
2908 |
|
goto invalid_code; |
2909 |
|
DECODE_COMPOSITION_END (); |
2910 |
continue; |
continue; |
2911 |
|
|
2912 |
case '[': /* specification of direction */ |
case '[': /* specification of direction */ |
2913 |
if (coding->flags & CODING_FLAG_ISO_NO_DIRECTION) |
if (! CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DIRECTION) |
2914 |
goto label_invalid_code; |
goto invalid_code; |
2915 |
/* For the moment, nested direction is not supported. |
/* For the moment, nested direction is not supported. |
2916 |
So, `coding->mode & CODING_MODE_DIRECTION' zero means |
So, `coding->mode & CODING_MODE_DIRECTION' zero means |
2917 |
left-to-right, and nonzero means right-to-left. */ |
left-to-right, and nozero means right-to-left. */ |
2918 |
ONE_MORE_BYTE (c1); |
ONE_MORE_BYTE (c1); |
2919 |
switch (c1) |
switch (c1) |
2920 |
{ |
{ |
2927 |
if (c1 == ']') |
if (c1 == ']') |
2928 |
coding->mode &= ~CODING_MODE_DIRECTION; |
coding->mode &= ~CODING_MODE_DIRECTION; |
2929 |
else |
else |
2930 |
goto label_invalid_code; |
goto invalid_code; |
2931 |
break; |
break; |
2932 |
|
|
2933 |
case '2': /* start of right-to-left direction */ |
case '2': /* start of right-to-left direction */ |
2935 |
if (c1 == ']') |
if (c1 == ']') |
2936 |
coding->mode |= CODING_MODE_DIRECTION; |
coding->mode |= CODING_MODE_DIRECTION; |
2937 |
else |
else |
2938 |
goto label_invalid_code; |
goto invalid_code; |
2939 |
break; |
break; |
2940 |
|
|
2941 |
default: |
default: |
2942 |
goto label_invalid_code; |
goto invalid_code; |
2943 |
} |
} |
2944 |
continue; |
continue; |
2945 |
|
|
2946 |
default: |
default: |
2947 |
if (! (coding->flags & CODING_FLAG_ISO_DESIGNATION)) |
if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATION)) |
2948 |
goto label_invalid_code; |
goto invalid_code; |
2949 |
if (c1 >= 0x28 && c1 <= 0x2B) |
if (c1 >= 0x28 && c1 <= 0x2B) |
2950 |
{ /* designation of DIMENSION1_CHARS94 character set */ |
{ /* designation of DIMENSION1_CHARS94 character set */ |
2951 |
ONE_MORE_BYTE (c2); |
ONE_MORE_BYTE (c2); |
2952 |
DECODE_DESIGNATION (c1 - 0x28, 1, 94, c2); |
DECODE_DESIGNATION (c1 - 0x28, 1, 0, c2); |
2953 |
} |
} |
2954 |
else if (c1 >= 0x2C && c1 <= 0x2F) |
else if (c1 >= 0x2C && c1 <= 0x2F) |
2955 |
{ /* designation of DIMENSION1_CHARS96 character set */ |
{ /* designation of DIMENSION1_CHARS96 character set */ |
2956 |
ONE_MORE_BYTE (c2); |
ONE_MORE_BYTE (c2); |
2957 |
DECODE_DESIGNATION (c1 - 0x2C, 1, 96, c2); |
DECODE_DESIGNATION (c1 - 0x2C, 1, 1, c2); |
2958 |
} |
} |
2959 |
else |
else |
2960 |
goto label_invalid_code; |
goto invalid_code; |
2961 |
/* We must update these variables now. */ |
/* We must update these variables now. */ |
2962 |
charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0); |
charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0); |
2963 |
charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1); |
charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1); |
2964 |
continue; |
continue; |
2965 |
} |
} |
2966 |
} |
} |
2967 |
|
|
2968 |
/* Now we know CHARSET and 1st position code C1 of a character. |
/* Now we know CHARSET and 1st position code C1 of a character. |
2969 |
Produce a multibyte sequence for that character while getting |
Produce a decoded character while getting 2nd position code |
2970 |
2nd position code C2 if necessary. */ |
C2 if necessary. */ |
2971 |
if (CHARSET_DIMENSION (charset) == 2) |
c1 &= 0x7F; |
2972 |
|
if (CHARSET_DIMENSION (charset) > 1) |
2973 |
{ |
{ |
2974 |
ONE_MORE_BYTE (c2); |
ONE_MORE_BYTE (c2); |
2975 |
if (c1 < 0x80 ? c2 < 0x20 || c2 >= 0x80 : c2 < 0xA0) |
if (c2 < 0x20 || (c2 >= 0x80 && c2 < 0xA0)) |
2976 |
/* C2 is not in a valid range. */ |
/* C2 is not in a valid range. */ |
2977 |
goto label_invalid_code; |
goto invalid_code; |
2978 |
|
c1 = (c1 << 8) | (c2 & 0x7F); |
2979 |
|
if (CHARSET_DIMENSION (charset) > 2) |
2980 |
|
{ |
2981 |
|
ONE_MORE_BYTE (c2); |
2982 |
|
if (c2 < 0x20 || (c2 >= 0x80 && c2 < 0xA0)) |
2983 |
|
/* C2 is not in a valid range. */ |
2984 |
|
goto invalid_code; |
2985 |
|
c1 = (c1 << 8) | (c2 & 0x7F); |
2986 |
|
} |
2987 |
|
} |
2988 |
|
|
2989 |
|
CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c1, c); |
2990 |
|
if (c < 0) |
2991 |
|
{ |
2992 |
|
MAYBE_FINISH_COMPOSITION (); |
2993 |
|
for (; src_base < src; src_base++, char_offset++) |
2994 |
|
{ |
2995 |
|
if (ASCII_BYTE_P (*src_base)) |
2996 |
|
*charbuf++ = *src_base; |
2997 |
|
else |
2998 |
|
*charbuf++ = BYTE8_TO_CHAR (*src_base); |
2999 |
|
} |
3000 |
|
} |
3001 |
|
else if (composition_state == COMPOSING_NO) |
3002 |
|
{ |
3003 |
|
*charbuf++ = c; |
3004 |
|
char_offset++; |
3005 |
} |
} |
3006 |
c = DECODE_ISO_CHARACTER (charset, c1, c2); |
else |
3007 |
EMIT_CHAR (c); |
components[component_idx++] = c; |
3008 |
continue; |
continue; |
3009 |
|
|
3010 |
label_invalid_code: |
invalid_code: |
3011 |
coding->errors++; |
MAYBE_FINISH_COMPOSITION (); |
|
if (COMPOSING_P (coding)) |
|
|
DECODE_COMPOSITION_END ('1'); |
|
3012 |
src = src_base; |
src = src_base; |
3013 |
c = *src++; |
consumed_chars = consumed_chars_base; |
3014 |
EMIT_CHAR (c); |
ONE_MORE_BYTE (c); |
3015 |
|
*charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c); |
3016 |
|
coding->errors++; |
3017 |
} |
} |
3018 |
|
|
3019 |
label_end_of_loop: |
no_more_source: |
3020 |
coding->consumed = coding->consumed_char = src_base - source; |
coding->consumed_char += consumed_chars_base; |
3021 |
coding->produced = dst - destination; |
coding->consumed = src_base - coding->source; |
3022 |
return; |
coding->charbuf_used = charbuf - coding->charbuf; |
3023 |
} |
} |
3024 |
|
|
3025 |
|
|
3027 |
|
|
3028 |
/* |
/* |
3029 |
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 |
3030 |
specify more details. In Emacs, each ISO2022 coding system |
specify more details. In Emacs, each coding system of ISO2022 |
3031 |
variant has the following specifications: |
variant has the following specifications: |
3032 |
1. Initial designation to G0 through G3. |
1. Initial designation to G0 thru G3. |
3033 |
2. Allows short-form designation? |
2. Allows short-form designation? |
3034 |
3. ASCII should be designated to G0 before control characters? |
3. ASCII should be designated to G0 before control characters? |
3035 |
4. ASCII should be designated to G0 at end of line? |
4. ASCII should be designated to G0 at end of line? |
3039 |
And the following two are only for Japanese: |
And the following two are only for Japanese: |
3040 |
8. Use ASCII in place of JIS0201-1976-Roman? |
8. Use ASCII in place of JIS0201-1976-Roman? |
3041 |
9. Use JISX0208-1983 in place of JISX0208-1978? |
9. Use JISX0208-1983 in place of JISX0208-1978? |
3042 |
These specifications are encoded in `coding->flags' as flag bits |
These specifications are encoded in CODING_ISO_FLAGS (coding) as flag bits |
3043 |
defined by macros CODING_FLAG_ISO_XXX. See `coding.h' for more |
defined by macros CODING_ISO_FLAG_XXX. See `coding.h' for more |
3044 |
details. |
details. |
3045 |
*/ |
*/ |
3046 |
|
|
3051 |
|
|
3052 |
#define ENCODE_DESIGNATION(charset, reg, coding) \ |
#define ENCODE_DESIGNATION(charset, reg, coding) \ |
3053 |
do { \ |
do { \ |
3054 |
unsigned char final_char = CHARSET_ISO_FINAL_CHAR (charset); \ |
unsigned char final_char = CHARSET_ISO_FINAL (charset); \ |
3055 |
char *intermediate_char_94 = "()*+"; \ |
char *intermediate_char_94 = "()*+"; \ |
3056 |
char *intermediate_char_96 = ",-./"; \ |
char *intermediate_char_96 = ",-./"; \ |
3057 |
int revision = CODING_SPEC_ISO_REVISION_NUMBER(coding, charset); \ |
int revision = -1; \ |
3058 |
\ |
int c; \ |
3059 |
if (revision < 255) \ |
\ |
3060 |
|
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_REVISION) \ |
3061 |
|
revision = XINT (CHARSET_ISO_REVISION (charset)); \ |
3062 |
|
\ |
3063 |
|
if (revision >= 0) \ |
3064 |
{ \ |
{ \ |
3065 |
*dst++ = ISO_CODE_ESC; \ |
EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, '&'); \ |
3066 |
*dst++ = '&'; \ |
EMIT_ONE_BYTE ('@' + revision); \ |
|
*dst++ = '@' + revision; \ |
|
3067 |
} \ |
} \ |
3068 |
*dst++ = ISO_CODE_ESC; \ |
EMIT_ONE_ASCII_BYTE (ISO_CODE_ESC); \ |
3069 |
if (CHARSET_DIMENSION (charset) == 1) \ |
if (CHARSET_DIMENSION (charset) == 1) \ |
3070 |
{ \ |
{ \ |
3071 |
if (CHARSET_CHARS (charset) == 94) \ |
if (! CHARSET_ISO_CHARS_96 (charset)) \ |
3072 |
*dst++ = (unsigned char) (intermediate_char_94[reg]); \ |
c = intermediate_char_94[reg]; \ |
3073 |
else \ |
else \ |
3074 |
*dst++ = (unsigned char) (intermediate_char_96[reg]); \ |
c = intermediate_char_96[reg]; \ |
3075 |
|
EMIT_ONE_ASCII_BYTE (c); \ |
3076 |
} \ |
} \ |
3077 |
else \ |
else \ |
3078 |
{ \ |
{ \ |
3079 |
*dst++ = '$'; \ |
EMIT_ONE_ASCII_BYTE ('$'); \ |
3080 |
if (CHARSET_CHARS (charset) == 94) \ |
if (! CHARSET_ISO_CHARS_96 (charset)) \ |
3081 |
{ \ |
{ \ |
3082 |
if (! (coding->flags & CODING_FLAG_ISO_SHORT_FORM) \ |
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LONG_FORM \ |
3083 |
|| reg != 0 \ |
|| reg != 0 \ |
3084 |
|| final_char < '@' || final_char > 'B') \ |
|| final_char < '@' || final_char > 'B') \ |
3085 |
*dst++ = (unsigned char) (intermediate_char_94[reg]); \ |
EMIT_ONE_ASCII_BYTE (intermediate_char_94[reg]); \ |
3086 |
} \ |
} \ |
3087 |
else \ |
else \ |
3088 |
*dst++ = (unsigned char) (intermediate_char_96[reg]); \ |
EMIT_ONE_ASCII_BYTE (intermediate_char_96[reg]); \ |
3089 |
} \ |
} \ |
3090 |
*dst++ = final_char; \ |
EMIT_ONE_ASCII_BYTE (final_char); \ |
3091 |
CODING_SPEC_ISO_DESIGNATION (coding, reg) = charset; \ |
\ |
3092 |
|
CODING_ISO_DESIGNATION (coding, reg) = CHARSET_ID (charset); \ |
3093 |
} while (0) |
} while (0) |
3094 |
|
|
3095 |
|
|
3096 |
/* The following two macros produce codes (control character or escape |
/* The following two macros produce codes (control character or escape |
3097 |
sequence) for ISO2022 single-shift functions (single-shift-2 and |
sequence) for ISO2022 single-shift functions (single-shift-2 and |
3098 |
single-shift-3). */ |
single-shift-3). */ |
3099 |
|
|
3100 |
#define ENCODE_SINGLE_SHIFT_2 \ |
#define ENCODE_SINGLE_SHIFT_2 \ |
3101 |
do { \ |
do { \ |
3102 |
if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS) \ |
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS) \ |
3103 |
*dst++ = ISO_CODE_ESC, *dst++ = 'N'; \ |
EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'N'); \ |
3104 |
else \ |
else \ |
3105 |
*dst++ = ISO_CODE_SS2; \ |
EMIT_ONE_BYTE (ISO_CODE_SS2); \ |
3106 |
CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 1; \ |
CODING_ISO_SINGLE_SHIFTING (coding) = 1; \ |
3107 |
} while (0) |
} while (0) |
3108 |
|
|
3109 |
#define ENCODE_SINGLE_SHIFT_3 \ |
|
3110 |
do { \ |
#define ENCODE_SINGLE_SHIFT_3 \ |
3111 |
if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS) \ |
do { \ |
3112 |
*dst++ = ISO_CODE_ESC, *dst++ = 'O'; \ |
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS) \ |
3113 |
else \ |
EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'O'); \ |
3114 |
*dst++ = ISO_CODE_SS3; \ |
else \ |
3115 |
CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 1; \ |
EMIT_ONE_BYTE (ISO_CODE_SS3); \ |
3116 |
|
CODING_ISO_SINGLE_SHIFTING (coding) = 1; \ |
3117 |
} while (0) |
} while (0) |
3118 |
|
|
3119 |
|
|
3120 |
/* The following four macros produce codes (control character or |
/* The following four macros produce codes (control character or |
3121 |
escape sequence) for ISO2022 locking-shift functions (shift-in, |
escape sequence) for ISO2022 locking-shift functions (shift-in, |
3122 |
shift-out, locking-shift-2, and locking-shift-3). */ |
shift-out, locking-shift-2, and locking-shift-3). */ |
3123 |
|
|
3124 |
#define ENCODE_SHIFT_IN \ |
#define ENCODE_SHIFT_IN \ |
3125 |
do { \ |
do { \ |
3126 |
*dst++ = ISO_CODE_SI; \ |
EMIT_ONE_ASCII_BYTE (ISO_CODE_SI); \ |
3127 |
CODING_SPEC_ISO_INVOCATION (coding, 0) = 0; \ |
CODING_ISO_INVOCATION (coding, 0) = 0; \ |
3128 |
} while (0) |
} while (0) |
3129 |
|
|
3130 |
#define ENCODE_SHIFT_OUT \ |
|
3131 |
do { \ |
#define ENCODE_SHIFT_OUT \ |
3132 |
*dst++ = ISO_CODE_SO; \ |
do { \ |
3133 |
CODING_SPEC_ISO_INVOCATION (coding, 0) = 1; \ |
EMIT_ONE_ASCII_BYTE (ISO_CODE_SO); \ |
3134 |
|
CODING_ISO_INVOCATION (coding, 0) = 1; \ |
3135 |
} while (0) |
} while (0) |
3136 |
|
|
3137 |
#define ENCODE_LOCKING_SHIFT_2 \ |
|
3138 |
do { \ |
#define ENCODE_LOCKING_SHIFT_2 \ |
3139 |
*dst++ = ISO_CODE_ESC, *dst++ = 'n'; \ |
do { \ |
3140 |
CODING_SPEC_ISO_INVOCATION (coding, 0) = 2; \ |
EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'n'); \ |
3141 |
|
CODING_ISO_INVOCATION (coding, 0) = 2; \ |
3142 |
} while (0) |
} while (0) |
3143 |
|
|
3144 |
#define ENCODE_LOCKING_SHIFT_3 \ |
|
3145 |
do { \ |
#define ENCODE_LOCKING_SHIFT_3 \ |
3146 |
*dst++ = ISO_CODE_ESC, *dst++ = 'o'; \ |
do { \ |
3147 |
CODING_SPEC_ISO_INVOCATION (coding, 0) = 3; \ |
EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'n'); \ |
3148 |
|
CODING_ISO_INVOCATION (coding, 0) = 3; \ |
3149 |
} while (0) |
} while (0) |
3150 |
|
|
3151 |
|
|
3152 |
/* Produce codes for a DIMENSION1 character whose character set is |
/* Produce codes for a DIMENSION1 character whose character set is |
3153 |
CHARSET and whose position-code is C1. Designation and invocation |
CHARSET and whose position-code is C1. Designation and invocation |
3154 |
sequences are also produced in advance if necessary. */ |
sequences are also produced in advance if necessary. */ |
3155 |
|
|
3156 |
#define ENCODE_ISO_CHARACTER_DIMENSION1(charset, c1) \ |
#define ENCODE_ISO_CHARACTER_DIMENSION1(charset, c1) \ |
3157 |
do { \ |
do { \ |
3158 |
if (CODING_SPEC_ISO_SINGLE_SHIFTING (coding)) \ |
int id = CHARSET_ID (charset); \ |
3159 |
|
if (CODING_ISO_SINGLE_SHIFTING (coding)) \ |
3160 |
{ \ |
{ \ |
3161 |
if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS) \ |
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS) \ |
3162 |
*dst++ = c1 & 0x7F; \ |
EMIT_ONE_ASCII_BYTE (c1 & 0x7F); \ |
3163 |
else \ |
else \ |
3164 |
*dst++ = c1 | 0x80; \ |
EMIT_ONE_BYTE (c1 | 0x80); \ |
3165 |
CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 0; \ |
CODING_ISO_SINGLE_SHIFTING (coding) = 0; \ |
3166 |
break; \ |
break; \ |
3167 |
} \ |
} \ |
3168 |
else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 0)) \ |
else if (id == CODING_ISO_INVOKED_CHARSET (coding, 0)) \ |
3169 |
{ \ |
{ \ |
3170 |
*dst++ = c1 & 0x7F; \ |
EMIT_ONE_ASCII_BYTE (c1 & 0x7F); \ |
3171 |
break; \ |
break; \ |
3172 |
} \ |
} \ |
3173 |
else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 1)) \ |
else if (id == CODING_ISO_INVOKED_CHARSET (coding, 1)) \ |
3174 |
{ \ |
{ \ |
3175 |
*dst++ = c1 | 0x80; \ |
EMIT_ONE_BYTE (c1 | 0x80); \ |
3176 |
break; \ |
break; \ |
3177 |
} \ |
} \ |
3178 |
else \ |
else \ |
3180 |
must invoke it, or, at first, designate it to some graphic \ |
must invoke it, or, at first, designate it to some graphic \ |
3181 |
register. Then repeat the loop to actually produce the \ |
register. Then repeat the loop to actually produce the \ |
3182 |
character. */ \ |
character. */ \ |
3183 |
dst = encode_invocation_designation (charset, coding, dst); \ |
dst = encode_invocation_designation (charset, coding, dst, \ |
3184 |
|
&produced_chars); \ |
3185 |
} while (1) |
} while (1) |
3186 |
|
|
3187 |
|
|
3188 |
/* Produce codes for a DIMENSION2 character whose character set is |
/* Produce codes for a DIMENSION2 character whose character set is |
3189 |
CHARSET and whose position-codes are C1 and C2. Designation and |
CHARSET and whose position-codes are C1 and C2. Designation and |
3190 |
invocation codes are also produced in advance if necessary. */ |
invocation codes are also produced in advance if necessary. */ |
3191 |
|
|
3192 |
#define ENCODE_ISO_CHARACTER_DIMENSION2(charset, c1, c2) \ |
#define ENCODE_ISO_CHARACTER_DIMENSION2(charset, c1, c2) \ |
3193 |
do { \ |
do { \ |
3194 |
if (CODING_SPEC_ISO_SINGLE_SHIFTING (coding)) \ |
int id = CHARSET_ID (charset); \ |
3195 |
|
if (CODING_ISO_SINGLE_SHIFTING (coding)) \ |
3196 |
{ \ |
{ \ |
3197 |
if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS) \ |
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS) \ |
3198 |
*dst++ = c1 & 0x7F, *dst++ = c2 & 0x7F; \ |
EMIT_TWO_ASCII_BYTES ((c1) & 0x7F, (c2) & 0x7F); \ |
3199 |
else \ |
else \ |
3200 |
*dst++ = c1 | 0x80, *dst++ = c2 | 0x80; \ |
EMIT_TWO_BYTES ((c1) | 0x80, (c2) | 0x80); \ |
3201 |
CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 0; \ |
CODING_ISO_SINGLE_SHIFTING (coding) = 0; \ |
3202 |
break; \ |
break; \ |
3203 |
} \ |
} \ |
3204 |
else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 0)) \ |
else if (id == CODING_ISO_INVOKED_CHARSET (coding, 0)) \ |
3205 |
{ \ |
{ \ |
3206 |
*dst++ = c1 & 0x7F, *dst++= c2 & 0x7F; \ |
EMIT_TWO_ASCII_BYTES ((c1) & 0x7F, (c2) & 0x7F); \ |
3207 |
break; \ |
break; \ |
3208 |
} \ |
} \ |
3209 |
else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 1)) \ |
else if (id == CODING_ISO_INVOKED_CHARSET (coding, 1)) \ |
3210 |
{ \ |
{ \ |
3211 |
*dst++ = c1 | 0x80, *dst++= c2 | 0x80; \ |
EMIT_TWO_BYTES ((c1) | 0x80, (c2) | 0x80); \ |
3212 |
break; \ |
break; \ |
3213 |
} \ |
} \ |
3214 |
else \ |
else \ |
3216 |
must invoke it, or, at first, designate it to some graphic \ |
must invoke it, or, at first, designate it to some graphic \ |
3217 |
register. Then repeat the loop to actually produce the \ |
register. Then repeat the loop to actually produce the \ |
3218 |
character. */ \ |
character. */ \ |
3219 |
dst = encode_invocation_designation (charset, coding, dst); \ |
dst = encode_invocation_designation (charset, coding, dst, \ |
3220 |
|
&produced_chars); \ |
3221 |
} while (1) |
} while (1) |
3222 |
|
|
|
#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. */ |
|
3223 |
|
|
3224 |
#define ENCODE_UNSAFE_CHARACTER(c) \ |
#define ENCODE_ISO_CHARACTER(charset, c) \ |
3225 |
do { \ |
do { \ |
3226 |
ENCODE_ISO_CHARACTER (CODING_INHIBIT_CHARACTER_SUBSTITUTION); \ |
int code = ENCODE_CHAR ((charset),(c)); \ |
3227 |
if (CHARSET_WIDTH (CHAR_CHARSET (c)) > 1) \ |
\ |
3228 |
ENCODE_ISO_CHARACTER (CODING_INHIBIT_CHARACTER_SUBSTITUTION); \ |
if (CHARSET_DIMENSION (charset) == 1) \ |
3229 |
|
ENCODE_ISO_CHARACTER_DIMENSION1 ((charset), code); \ |
3230 |
|
else \ |
3231 |
|
ENCODE_ISO_CHARACTER_DIMENSION2 ((charset), code >> 8, code & 0xFF); \ |
3232 |
} while (0) |
} while (0) |
3233 |
|
|
3234 |
|
|
3235 |
/* Produce designation and invocation codes at a place pointed by DST |
/* Produce designation and invocation codes at a place pointed by DST |
3236 |
to use CHARSET. The element `spec.iso2022' of *CODING is updated. |
to use CHARSET. The element `spec.iso_2022' of *CODING is updated. |
3237 |
Return new DST. */ |
Return new DST. */ |
3238 |
|
|
3239 |
unsigned char * |
unsigned char * |
3240 |
encode_invocation_designation (charset, coding, dst) |
encode_invocation_designation (charset, coding, dst, p_nchars) |
3241 |
int charset; |
struct charset *charset; |
3242 |
struct coding_system *coding; |
struct coding_system *coding; |
3243 |
unsigned char *dst; |
unsigned char *dst; |
3244 |
|
int *p_nchars; |
3245 |
{ |
{ |
3246 |
|
int multibytep = coding->dst_multibyte; |
3247 |
|
int produced_chars = *p_nchars; |
3248 |
int reg; /* graphic register number */ |
int reg; /* graphic register number */ |
3249 |
|
int id = CHARSET_ID (charset); |
3250 |
|
|
3251 |
/* At first, check designations. */ |
/* At first, check designations. */ |
3252 |
for (reg = 0; reg < 4; reg++) |
for (reg = 0; reg < 4; reg++) |
3253 |
if (charset == CODING_SPEC_ISO_DESIGNATION (coding, reg)) |
if (id == CODING_ISO_DESIGNATION (coding, reg)) |
3254 |
break; |
break; |
3255 |
|
|
3256 |
if (reg >= 4) |
if (reg >= 4) |
3257 |
{ |
{ |
3258 |
/* CHARSET is not yet designated to any graphic registers. */ |
/* CHARSET is not yet designated to any graphic registers. */ |
3259 |
/* At first check the requested designation. */ |
/* At first check the requested designation. */ |
3260 |
reg = CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset); |
reg = CODING_ISO_REQUEST (coding, id); |
3261 |
if (reg == CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION) |
if (reg < 0) |
3262 |
/* Since CHARSET requests no special designation, designate it |
/* Since CHARSET requests no special designation, designate it |
3263 |
to graphic register 0. */ |
to graphic register 0. */ |
3264 |
reg = 0; |
reg = 0; |
3266 |
ENCODE_DESIGNATION (charset, reg, coding); |
ENCODE_DESIGNATION (charset, reg, coding); |
3267 |
} |
} |
3268 |
|
|
3269 |
if (CODING_SPEC_ISO_INVOCATION (coding, 0) != reg |
if (CODING_ISO_INVOCATION (coding, 0) != reg |
3270 |
&& CODING_SPEC_ISO_INVOCATION (coding, 1) != reg) |
&& CODING_ISO_INVOCATION (coding, 1) != reg) |
3271 |
{ |
{ |
3272 |
/* Since the graphic register REG is not invoked to any graphic |
/* Since the graphic register REG is not invoked to any graphic |
3273 |
planes, invoke it to graphic plane 0. */ |
planes, invoke it to graphic plane 0. */ |
3282 |
break; |
break; |
3283 |
|
|
3284 |
case 2: /* graphic register 2 */ |
case 2: /* graphic register 2 */ |
3285 |
if (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT) |
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT) |
3286 |
ENCODE_SINGLE_SHIFT_2; |
ENCODE_SINGLE_SHIFT_2; |
3287 |
else |
else |
3288 |
ENCODE_LOCKING_SHIFT_2; |
ENCODE_LOCKING_SHIFT_2; |
3289 |
break; |
break; |
3290 |
|
|
3291 |
case 3: /* graphic register 3 */ |
case 3: /* graphic register 3 */ |
3292 |
if (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT) |
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT) |
3293 |
ENCODE_SINGLE_SHIFT_3; |
ENCODE_SINGLE_SHIFT_3; |
3294 |
else |
else |
3295 |
ENCODE_LOCKING_SHIFT_3; |
ENCODE_LOCKING_SHIFT_3; |
3297 |
} |
} |
3298 |
} |
} |
3299 |
|
|
3300 |
|
*p_nchars = produced_chars; |
3301 |
return dst; |
return dst; |
3302 |
} |
} |
3303 |
|
|
3304 |
/* Produce 2-byte codes for encoded composition rule RULE. */ |
/* The following three macros produce codes for indicating direction |
3305 |
|
of text. */ |
3306 |
#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) \ |
|
3307 |
do { \ |
do { \ |
3308 |
coding->composing = data[3]; \ |
if (CODING_ISO_FLAGS (coding) == CODING_ISO_FLAG_SEVEN_BITS) \ |
3309 |
*dst++ = ISO_CODE_ESC; \ |
EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, '['); \ |
|
if (coding->composing == COMPOSITION_RELATIVE) \ |
|
|
*dst++ = '0'; \ |
|
3310 |
else \ |
else \ |
3311 |
{ \ |
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; \ |
|
|
} \ |
|
3312 |
} while (0) |
} while (0) |
3313 |
|
|
|
/* Produce codes for indicating the end of the current composition. */ |
|
3314 |
|
|
3315 |
#define ENCODE_COMPOSITION_END(coding, data) \ |
#define ENCODE_DIRECTION_R2L() \ |
3316 |
do { \ |
do { \ |
3317 |
*dst++ = ISO_CODE_ESC; \ |
ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst); \ |
3318 |
*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; \ |
|
|
} \ |
|
3319 |
} while (0) |
} while (0) |
3320 |
|
|
|
/* 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. */ |
|
3321 |
|
|
3322 |
#define ENCODE_COMPOSITION_FAKE_START(coding) \ |
#define ENCODE_DIRECTION_L2R() \ |
3323 |
do { \ |
do { \ |
3324 |
*dst++ = ISO_CODE_ESC; \ |
ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst); \ |
3325 |
*dst++ = '0'; \ |
EMIT_TWO_ASCII_BYTES ('0', ']'); \ |
|
coding->composing = COMPOSITION_RELATIVE; \ |
|
|
} while (0) |
|
|
|
|
|
/* 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; \ |
|
3326 |
} while (0) |
} while (0) |
3327 |
|
|
|
#define ENCODE_DIRECTION_R2L \ |
|
|
ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst), *dst++ = '2', *dst++ = ']' |
|
|
|
|
|
#define ENCODE_DIRECTION_L2R \ |
|
|
ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst), *dst++ = '0', *dst++ = ']' |
|
3328 |
|
|
3329 |
/* Produce codes for designation and invocation to reset the graphic |
/* Produce codes for designation and invocation to reset the graphic |
3330 |
planes and registers to initial state. */ |
planes and registers to initial state. */ |
3331 |
#define ENCODE_RESET_PLANE_AND_REGISTER \ |
#define ENCODE_RESET_PLANE_AND_REGISTER() \ |
3332 |
do { \ |
do { \ |
3333 |
int reg; \ |
int reg; \ |
3334 |
if (CODING_SPEC_ISO_INVOCATION (coding, 0) != 0) \ |
struct charset *charset; \ |
3335 |
ENCODE_SHIFT_IN; \ |
\ |
3336 |
for (reg = 0; reg < 4; reg++) \ |
if (CODING_ISO_INVOCATION (coding, 0) != 0) \ |
3337 |
if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg) >= 0 \ |
ENCODE_SHIFT_IN; \ |
3338 |
&& (CODING_SPEC_ISO_DESIGNATION (coding, reg) \ |
for (reg = 0; reg < 4; reg++) \ |
3339 |
!= CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg))) \ |
if (CODING_ISO_INITIAL (coding, reg) >= 0 \ |
3340 |
ENCODE_DESIGNATION \ |
&& (CODING_ISO_DESIGNATION (coding, reg) \ |
3341 |
(CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg), reg, coding); \ |
!= CODING_ISO_INITIAL (coding, reg))) \ |
3342 |
|
{ \ |
3343 |
|
charset = CHARSET_FROM_ID (CODING_ISO_INITIAL (coding, reg)); \ |
3344 |
|
ENCODE_DESIGNATION (charset, reg, coding); \ |
3345 |
|
} \ |
3346 |
} while (0) |
} while (0) |
3347 |
|
|
3348 |
|
|
3349 |
/* Produce designation sequences of charsets in the line started from |
/* Produce designation sequences of charsets in the line started from |
3350 |
SRC to a place pointed by DST, and return updated DST. |
SRC to a place pointed by DST, and return updated DST. |
3351 |
|
|
3353 |
find all the necessary designations. */ |
find all the necessary designations. */ |
3354 |
|
|
3355 |
static unsigned char * |
static unsigned char * |
3356 |
encode_designation_at_bol (coding, translation_table, src, src_end, dst) |
encode_designation_at_bol (coding, charbuf, charbuf_end, dst) |
3357 |
struct coding_system *coding; |
struct coding_system *coding; |
3358 |
Lisp_Object translation_table; |
int *charbuf, *charbuf_end; |
3359 |
unsigned char *src, *src_end, *dst; |
unsigned char *dst; |
3360 |
{ |
{ |
3361 |
int charset, c, found = 0, reg; |
struct charset *charset; |
3362 |
/* Table of charsets to be designated to each graphic register. */ |
/* Table of charsets to be designated to each graphic register. */ |
3363 |
int r[4]; |
int r[4]; |
3364 |
|
int c, found = 0, reg; |
3365 |
|
int produced_chars = 0; |
3366 |
|
int multibytep = coding->dst_multibyte; |
3367 |
|
Lisp_Object attrs; |
3368 |
|
Lisp_Object charset_list; |
3369 |
|
|
3370 |
|
attrs = CODING_ID_ATTRS (coding->id); |
3371 |
|
charset_list = CODING_ATTR_CHARSET_LIST (attrs); |
3372 |
|
if (EQ (charset_list, Qiso_2022)) |
3373 |
|
charset_list = Viso_2022_charset_list; |
3374 |
|
|
3375 |
for (reg = 0; reg < 4; reg++) |
for (reg = 0; reg < 4; reg++) |
3376 |
r[reg] = -1; |
r[reg] = -1; |
3377 |
|
|
3378 |
while (found < 4) |
while (found < 4) |
3379 |
{ |
{ |
3380 |
ONE_MORE_CHAR (c); |
int id; |
3381 |
|
|
3382 |
|
c = *charbuf++; |
3383 |
if (c == '\n') |
if (c == '\n') |
3384 |
break; |
break; |
3385 |
|
charset = char_charset (c, charset_list, NULL); |
3386 |
charset = CHAR_CHARSET (c); |
id = CHARSET_ID (charset); |
3387 |
reg = CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset); |
reg = CODING_ISO_REQUEST (coding, id); |
3388 |
if (reg != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION && r[reg] < 0) |
if (reg >= 0 && r[reg] < 0) |
3389 |
{ |
{ |
3390 |
found++; |
found++; |
3391 |
r[reg] = charset; |
r[reg] = id; |
3392 |
} |
} |
3393 |
} |
} |
3394 |
|
|
|
label_end_of_loop: |
|
3395 |
if (found) |
if (found) |
3396 |
{ |
{ |
3397 |
for (reg = 0; reg < 4; reg++) |
for (reg = 0; reg < 4; reg++) |
3398 |
if (r[reg] >= 0 |
if (r[reg] >= 0 |
3399 |
&& CODING_SPEC_ISO_DESIGNATION (coding, reg) != r[reg]) |
&& CODING_ISO_DESIGNATION (coding, reg) != r[reg]) |
3400 |
ENCODE_DESIGNATION (r[reg], reg, coding); |
ENCODE_DESIGNATION (CHARSET_FROM_ID (r[reg]), reg, coding); |
3401 |
} |
} |
3402 |
|
|
3403 |
return dst; |
return dst; |
3405 |
|
|
3406 |
/* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions". */ |
/* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions". */ |
3407 |
|
|
3408 |
static void |
static int |
3409 |
encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes) |
encode_coding_iso_2022 (coding) |
3410 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
3411 |
{ |
{ |
3412 |
unsigned char *src = source; |
int multibytep = coding->dst_multibyte; |
3413 |
unsigned char *src_end = source + src_bytes; |
int *charbuf = coding->charbuf; |
3414 |
unsigned char *dst = destination; |
int *charbuf_end = charbuf + coding->charbuf_used; |
3415 |
unsigned char *dst_end = destination + dst_bytes; |
unsigned char *dst = coding->destination + coding->produced; |
3416 |
/* Since the maximum bytes produced by each loop is 20, we subtract 19 |
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
3417 |
from DST_END to assure overflow checking is necessary only at the |
int safe_room = 16; |
3418 |
head of loop. */ |
int bol_designation |
3419 |
unsigned char *adjusted_dst_end = dst_end - 19; |
= (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATE_AT_BOL |
3420 |
/* SRC_BASE remembers the start position in source in each loop. |
&& CODING_ISO_BOL (coding)); |
3421 |
The loop will be exited when there's not enough source text to |
int produced_chars = 0; |
3422 |
analyze multi-byte codes (within macro ONE_MORE_CHAR), or when |
Lisp_Object attrs, eol_type, charset_list; |
3423 |
there's not enough destination area to produce encoded codes |
int ascii_compatible; |
|
(within macro EMIT_BYTES). */ |
|
|
unsigned char *src_base; |
|
3424 |
int c; |
int c; |
|
Lisp_Object translation_table; |
|
|
Lisp_Object safe_chars; |
|
3425 |
|
|
3426 |
safe_chars = coding_safe_chars (coding); |
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
3427 |
|
|
3428 |
if (NILP (Venable_character_translation)) |
ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)); |
|
translation_table = Qnil; |
|
|
else |
|
|
{ |
|
|
translation_table = coding->translation_table_for_encode; |
|
|
if (NILP (translation_table)) |
|
|
translation_table = Vstandard_translation_table_for_encode; |
|
|
} |
|
3429 |
|
|
3430 |
coding->consumed_char = 0; |
while (charbuf < charbuf_end) |
|
coding->errors = 0; |
|
|
while (1) |
|
3431 |
{ |
{ |
3432 |
src_base = src; |
ASSURE_DESTINATION (safe_room); |
3433 |
|
|
3434 |
if (dst >= (dst_bytes ? adjusted_dst_end : (src - 19))) |
if (bol_designation) |
3435 |
{ |
{ |
3436 |
coding->result = CODING_FINISH_INSUFFICIENT_DST; |
unsigned char *dst_prev = dst; |
|
break; |
|
|
} |
|
3437 |
|
|
|
if (coding->flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL |
|
|
&& CODING_SPEC_ISO_BOL (coding)) |
|
|
{ |
|
3438 |
/* We have to produce designation sequences if any now. */ |
/* We have to produce designation sequences if any now. */ |
3439 |
dst = encode_designation_at_bol (coding, translation_table, |
dst = encode_designation_at_bol (coding, charbuf, charbuf_end, dst); |
3440 |
src, src_end, dst); |
bol_designation = 0; |
3441 |
CODING_SPEC_ISO_BOL (coding) = 0; |
/* We are sure that designation sequences are all ASCII bytes. */ |
3442 |
} |
produced_chars += dst - dst_prev; |
|
|
|
|
/* Check composition start and end. */ |
|
|
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; |
|
|
|
|
|
if (coding->composing == COMPOSITION_RELATIVE) |
|
|
{ |
|
|
if (this_pos == data[2]) |
|
|
{ |
|
|
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->flags & CODING_FLAG_ISO_SAFE |
|
|
&& ! 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)) |
|
|
{ |
|
|
if (this_pos == data[1]) |
|
|
{ |
|
|
ENCODE_COMPOSITION_START (coding, data); |
|
|
continue; |
|
|
} |
|
|
} |
|
3443 |
} |
} |
3444 |
|
|
3445 |
ONE_MORE_CHAR (c); |
c = *charbuf++; |
3446 |
|
|
3447 |
/* Now encode the character C. */ |
/* Now encode the character C. */ |
3448 |
if (c < 0x20 || c == 0x7F) |
if (c < 0x20 || c == 0x7F) |
3449 |
{ |
{ |
3450 |
if (c == '\r') |
if (c == '\n' |
3451 |
|
|| (c == '\r' && EQ (eol_type, Qmac))) |
3452 |
{ |
{ |
3453 |
if (! (coding->mode & CODING_MODE_SELECTIVE_DISPLAY)) |
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_EOL) |
3454 |
|
ENCODE_RESET_PLANE_AND_REGISTER (); |
3455 |
|
if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_INIT_AT_BOL) |
3456 |
{ |
{ |
3457 |
if (coding->flags & CODING_FLAG_ISO_RESET_AT_CNTL) |
int i; |
3458 |
ENCODE_RESET_PLANE_AND_REGISTER; |
|
3459 |
*dst++ = c; |
for (i = 0; i < 4; i++) |
3460 |
continue; |
CODING_ISO_DESIGNATION (coding, i) |
3461 |
|
= CODING_ISO_INITIAL (coding, i); |
3462 |
} |
} |
3463 |
/* fall down to treat '\r' as '\n' ... */ |
bol_designation |
3464 |
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; |
|
3465 |
} |
} |
3466 |
|
else if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_CNTL) |
3467 |
|
ENCODE_RESET_PLANE_AND_REGISTER (); |
3468 |
|
EMIT_ONE_ASCII_BYTE (c); |
3469 |
|
} |
3470 |
|
else if (ASCII_CHAR_P (c)) |
3471 |
|
{ |
3472 |
|
if (ascii_compatible) |
3473 |
|
EMIT_ONE_ASCII_BYTE (c); |
3474 |
else |
else |
3475 |
{ |
ENCODE_ISO_CHARACTER (CHARSET_FROM_ID (charset_ascii), c); |
|
if (coding->flags & CODING_FLAG_ISO_RESET_AT_CNTL) |
|
|
ENCODE_RESET_PLANE_AND_REGISTER; |
|
|
*dst++ = c; |
|
|
} |
|
3476 |
} |
} |
|
else if (ASCII_BYTE_P (c)) |
|
|
ENCODE_ISO_CHARACTER (c); |
|
|
else if (SINGLE_BYTE_CHAR_P (c)) |
|
|
{ |
|
|
*dst++ = c; |
|
|
coding->errors++; |
|
|
} |
|
|
else if (coding->flags & CODING_FLAG_ISO_SAFE |
|
|
&& ! CODING_SAFE_CHAR_P (safe_chars, c)) |
|
|
ENCODE_UNSAFE_CHARACTER (c); |
|
3477 |
else |
else |
3478 |
ENCODE_ISO_CHARACTER (c); |
{ |
3479 |
|
struct charset *charset = char_charset (c, charset_list, NULL); |
3480 |
|
|
3481 |
coding->consumed_char++; |
if (!charset) |
3482 |
|
{ |
3483 |
|
c = coding->default_char; |
3484 |
|
charset = char_charset (c, charset_list, NULL); |
3485 |
|
} |
3486 |
|
ENCODE_ISO_CHARACTER (charset, c); |
3487 |
|
} |
3488 |
} |
} |
3489 |
|
|
3490 |
label_end_of_loop: |
if (coding->mode & CODING_MODE_LAST_BLOCK |
3491 |
coding->consumed = src_base - source; |
&& CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_EOL) |
3492 |
coding->produced = coding->produced_char = dst - destination; |
{ |
3493 |
|
ASSURE_DESTINATION (safe_room); |
3494 |
|
ENCODE_RESET_PLANE_AND_REGISTER (); |
3495 |
|
} |
3496 |
|
coding->result = CODING_RESULT_SUCCESS; |
3497 |
|
CODING_ISO_BOL (coding) = bol_designation; |
3498 |
|
coding->produced_char += produced_chars; |
3499 |
|
coding->produced = dst - coding->destination; |
3500 |
|
return 0; |
3501 |
} |
} |
3502 |
|
|
3503 |
|
|
3504 |
/*** 4. SJIS and BIG5 handlers ***/ |
/*** 8,9. SJIS and BIG5 handlers ***/ |
3505 |
|
|
3506 |
/* 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 |
3507 |
quite widely. So, for the moment, Emacs supports them in the bare |
quite widely. So, for the moment, Emacs supports them in the bare |
3508 |
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. */ |
3509 |
|
|
3512 |
as is. A character of charset katakana-jisx0201 is encoded by |
as is. A character of charset katakana-jisx0201 is encoded by |
3513 |
"position-code + 0x80". A character of charset japanese-jisx0208 |
"position-code + 0x80". A character of charset japanese-jisx0208 |
3514 |
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 |
3515 |
so that it fits in the range below. |
so that it fit in the range below. |
3516 |
|
|
3517 |
--- CODE RANGE of SJIS --- |
--- CODE RANGE of SJIS --- |
3518 |
(character set) (range) |
(character set) (range) |
3519 |
ASCII 0x00 .. 0x7F |
ASCII 0x00 .. 0x7F |
3520 |
KATAKANA-JISX0201 0xA1 .. 0xDF |
KATAKANA-JISX0201 0xA0 .. 0xDF |
3521 |
JISX0208 (1st byte) 0x81 .. 0x9F and 0xE0 .. 0xEF |
JISX0208 (1st byte) 0x81 .. 0x9F and 0xE0 .. 0xEF |
3522 |
(2nd byte) 0x40 .. 0x7E and 0x80 .. 0xFC |
(2nd byte) 0x40 .. 0x7E and 0x80 .. 0xFC |
3523 |
------------------------------- |
------------------------------- |
3526 |
|
|
3527 |
/* BIG5 is a coding system encoding two character sets: ASCII and |
/* BIG5 is a coding system encoding two character sets: ASCII and |
3528 |
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 |
3529 |
character set and is encoded in two bytes. |
character set and is encoded in two-byte. |
3530 |
|
|
3531 |
--- CODE RANGE of BIG5 --- |
--- CODE RANGE of BIG5 --- |
3532 |
(character set) (range) |
(character set) (range) |
3535 |
(2nd byte) 0x40 .. 0x7E and 0xA1 .. 0xFE |
(2nd byte) 0x40 .. 0x7E and 0xA1 .. 0xFE |
3536 |
-------------------------- |
-------------------------- |
3537 |
|
|
3538 |
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 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) |
|
3539 |
|
|
3540 |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
3541 |
Check if a text is encoded in SJIS. If it is, return |
Check if a text is encoded in SJIS. If it is, return |
3542 |
CODING_CATEGORY_MASK_SJIS, else return 0. */ |
CATEGORY_MASK_SJIS, else return 0. */ |
3543 |
|
|
3544 |
static int |
static int |
3545 |
detect_coding_sjis (src, src_end, multibytep) |
detect_coding_sjis (coding, mask) |
3546 |
unsigned char *src, *src_end; |
struct coding_system *coding; |
3547 |
int multibytep; |
int *mask; |
3548 |
{ |
{ |
3549 |
|
unsigned char *src = coding->source, *src_base = src; |
3550 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
3551 |
|
int multibytep = coding->src_multibyte; |
3552 |
|
int consumed_chars = 0; |
3553 |
|
int found = 0; |
3554 |
int c; |
int c; |
3555 |
/* Dummy for ONE_MORE_BYTE. */ |
|
3556 |
struct coding_system dummy_coding; |
/* A coding system of this category is always ASCII compatible. */ |
3557 |
struct coding_system *coding = &dummy_coding; |
src += coding->head_ascii; |
3558 |
|
|
3559 |
while (1) |
while (1) |
3560 |
{ |
{ |
3561 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
ONE_MORE_BYTE (c); |
3562 |
if (c < 0x80) |
if (c < 0x80) |
3563 |
continue; |
continue; |
3564 |
if (c == 0x80 || c == 0xA0 || c > 0xEF) |
if ((c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xEF)) |
|
return 0; |
|
|
if (c <= 0x9F || c >= 0xE0) |
|
3565 |
{ |
{ |
3566 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
ONE_MORE_BYTE (c); |
3567 |
if (c < 0x40 || c == 0x7F || c > 0xFC) |
if (c < 0x40 || c == 0x7F || c > 0xFC) |
3568 |
return 0; |
break; |
3569 |
|
found = 1; |
3570 |
} |
} |
3571 |
|
else if (c >= 0xA0 && c < 0xE0) |
3572 |
|
found = 1; |
3573 |
|
else |
3574 |
|
break; |
3575 |
} |
} |
3576 |
label_end_of_loop: |
*mask &= ~CATEGORY_MASK_SJIS; |
3577 |
return CODING_CATEGORY_MASK_SJIS; |
return 0; |
3578 |
|
|
3579 |
|
no_more_source: |
3580 |
|
if (!found) |
3581 |
|
return 0; |
3582 |
|
*mask &= CATEGORY_MASK_SJIS; |
3583 |
|
return 1; |
3584 |
} |
} |
3585 |
|
|
3586 |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
3587 |
Check if a text is encoded in BIG5. If it is, return |
Check if a text is encoded in BIG5. If it is, return |
3588 |
CODING_CATEGORY_MASK_BIG5, else return 0. */ |
CATEGORY_MASK_BIG5, else return 0. */ |
3589 |
|
|
3590 |
static int |
static int |
3591 |
detect_coding_big5 (src, src_end, multibytep) |
detect_coding_big5 (coding, mask) |
3592 |
unsigned char *src, *src_end; |
struct coding_system *coding; |
3593 |
int multibytep; |
int *mask; |
3594 |
{ |
{ |
3595 |
|
unsigned char *src = coding->source, *src_base = src; |
3596 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
3597 |
|
int multibytep = coding->src_multibyte; |
3598 |
|
int consumed_chars = 0; |
3599 |
|
int found = 0; |
3600 |
int c; |
int c; |
|
/* Dummy for ONE_MORE_BYTE. */ |
|
|
struct coding_system dummy_coding; |
|
|
struct coding_system *coding = &dummy_coding; |
|
|
|
|
|
while (1) |
|
|
{ |
|
|
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
|
|
if (c < 0x80) |
|
|
continue; |
|
|
if (c < 0xA1 || c > 0xFE) |
|
|
return 0; |
|
|
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
|
|
if (c < 0x40 || (c > 0x7F && c < 0xA1) || c > 0xFE) |
|
|
return 0; |
|
|
} |
|
|
label_end_of_loop: |
|
|
return CODING_CATEGORY_MASK_BIG5; |
|
|
} |
|
|
|
|
|
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
|
|
Check if a text is encoded in UTF-8. If it is, return |
|
|
CODING_CATEGORY_MASK_UTF_8, else return 0. */ |
|
|
|
|
|
#define UTF_8_1_OCTET_P(c) ((c) < 0x80) |
|
|
#define UTF_8_EXTRA_OCTET_P(c) (((c) & 0xC0) == 0x80) |
|
|
#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) |
|
3601 |
|
|
3602 |
static int |
/* A coding system of this category is always ASCII compatible. */ |
3603 |
detect_coding_utf_8 (src, src_end, multibytep) |
src += coding->head_ascii; |
|
unsigned char *src, *src_end; |
|
|
int multibytep; |
|
|
{ |
|
|
unsigned char c; |
|
|
int seq_maybe_bytes; |
|
|
/* Dummy for ONE_MORE_BYTE. */ |
|
|
struct coding_system dummy_coding; |
|
|
struct coding_system *coding = &dummy_coding; |
|
3604 |
|
|
3605 |
while (1) |
while (1) |
3606 |
{ |
{ |
3607 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
ONE_MORE_BYTE (c); |
3608 |
if (UTF_8_1_OCTET_P (c)) |
if (c < 0x80) |
3609 |
continue; |
continue; |
3610 |
else if (UTF_8_2_OCTET_LEADING_P (c)) |
if (c >= 0xA1) |
|
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 |
|
3611 |
{ |
{ |
3612 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
ONE_MORE_BYTE (c); |
3613 |
if (!UTF_8_EXTRA_OCTET_P (c)) |
if (c < 0x40 || (c >= 0x7F && c <= 0xA0)) |
3614 |
return 0; |
return 0; |
3615 |
seq_maybe_bytes--; |
found = 1; |
3616 |
} |
} |
3617 |
while (seq_maybe_bytes > 0); |
else |
3618 |
|
break; |
3619 |
} |
} |
3620 |
|
*mask &= ~CATEGORY_MASK_BIG5; |
|
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. */ |
|
|
|
|
|
#define UTF_16_INVALID_P(val) \ |
|
|
(((val) == 0xFFFE) \ |
|
|
|| ((val) == 0xFFFF)) |
|
|
|
|
|
#define UTF_16_HIGH_SURROGATE_P(val) \ |
|
|
(((val) & 0xD800) == 0xD800) |
|
|
|
|
|
#define UTF_16_LOW_SURROGATE_P(val) \ |
|
|
(((val) & 0xDC00) == 0xDC00) |
|
|
|
|
|
static int |
|
|
detect_coding_utf_16 (src, src_end, multibytep) |
|
|
unsigned char *src, *src_end; |
|
|
int multibytep; |
|
|
{ |
|
|
unsigned char c1, c2; |
|
|
/* Dummy for TWO_MORE_BYTES. */ |
|
|
struct coding_system dummy_coding; |
|
|
struct coding_system *coding = &dummy_coding; |
|
|
|
|
|
ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep); |
|
|
ONE_MORE_BYTE_CHECK_MULTIBYTE (c2, multibytep); |
|
|
|
|
|
if ((c1 == 0xFF) && (c2 == 0xFE)) |
|
|
return CODING_CATEGORY_MASK_UTF_16_LE; |
|
|
else if ((c1 == 0xFE) && (c2 == 0xFF)) |
|
|
return CODING_CATEGORY_MASK_UTF_16_BE; |
|
|
|
|
|
label_end_of_loop: |
|
3621 |
return 0; |
return 0; |
3622 |
|
|
3623 |
|
no_more_source: |
3624 |
|
if (!found) |
3625 |
|
return 0; |
3626 |
|
*mask &= CATEGORY_MASK_BIG5; |
3627 |
|
return 1; |
3628 |
} |
} |
3629 |
|
|
3630 |
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". |
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". |
3631 |
If SJIS_P is 1, decode SJIS text, else decode BIG5 test. */ |
If SJIS_P is 1, decode SJIS text, else decode BIG5 test. */ |
3632 |
|
|
3633 |
static void |
static void |
3634 |
decode_coding_sjis_big5 (coding, source, destination, |
decode_coding_sjis (coding) |
|
src_bytes, dst_bytes, sjis_p) |
|
3635 |
struct coding_system *coding; |
struct coding_system *coding; |
3636 |
unsigned char *source, *destination; |
{ |
3637 |
int src_bytes, dst_bytes; |
unsigned char *src = coding->source + coding->consumed; |
3638 |
int sjis_p; |
unsigned char *src_end = coding->source + coding->src_bytes; |
|
{ |
|
|
unsigned char *src = source; |
|
|
unsigned char *src_end = source + src_bytes; |
|
|
unsigned char *dst = destination; |
|
|
unsigned char *dst_end = destination + dst_bytes; |
|
|
/* SRC_BASE remembers the start position in source in each loop. |
|
|
The loop will be exited when there's not enough source code |
|
|
(within macro ONE_MORE_BYTE), or when there's not enough |
|
|
destination area to produce a character (within macro |
|
|
EMIT_CHAR). */ |
|
3639 |
unsigned char *src_base; |
unsigned char *src_base; |
3640 |
Lisp_Object translation_table; |
int *charbuf = coding->charbuf; |
3641 |
|
int *charbuf_end = charbuf + coding->charbuf_size; |
3642 |
|
int consumed_chars = 0, consumed_chars_base; |
3643 |
|
int multibytep = coding->src_multibyte; |
3644 |
|
struct charset *charset_roman, *charset_kanji, *charset_kana; |
3645 |
|
Lisp_Object attrs, eol_type, charset_list, val; |
3646 |
|
|
3647 |
|
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
3648 |
|
|
3649 |
|
val = charset_list; |
3650 |
|
charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
3651 |
|
charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
3652 |
|
charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))); |
3653 |
|
|
|
if (NILP (Venable_character_translation)) |
|
|
translation_table = Qnil; |
|
|
else |
|
|
{ |
|
|
translation_table = coding->translation_table_for_decode; |
|
|
if (NILP (translation_table)) |
|
|
translation_table = Vstandard_translation_table_for_decode; |
|
|
} |
|
|
|
|
|
coding->produced_char = 0; |
|
3654 |
while (1) |
while (1) |
3655 |
{ |
{ |
3656 |
int c, charset, c1, c2; |
int c, c1; |
3657 |
|
|
3658 |
src_base = src; |
src_base = src; |
3659 |
ONE_MORE_BYTE (c1); |
consumed_chars_base = consumed_chars; |
3660 |
|
|
3661 |
|
if (charbuf >= charbuf_end) |
3662 |
|
break; |
3663 |
|
|
3664 |
if (c1 < 0x80) |
ONE_MORE_BYTE (c); |
3665 |
|
|
3666 |
|
if (c == '\r') |
3667 |
{ |
{ |
3668 |
charset = CHARSET_ASCII; |
if (EQ (eol_type, Qdos)) |
|
if (c1 < 0x20) |
|
3669 |
{ |
{ |
3670 |
if (c1 == '\r') |
if (src == src_end) |
3671 |
{ |
goto no_more_source; |
3672 |
if (coding->eol_type == CODING_EOL_CRLF) |
if (*src == '\n') |
3673 |
{ |
ONE_MORE_BYTE (c); |
|
ONE_MORE_BYTE (c2); |
|
|
if (c2 == '\n') |
|
|
c1 = c2; |
|
|
else if (coding->mode |
|
|
& CODING_MODE_INHIBIT_INCONSISTENT_EOL) |
|
|
{ |
|
|
coding->result = CODING_FINISH_INCONSISTENT_EOL; |
|
|
goto label_end_of_loop; |
|
|
} |
|
|
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)) |
|
|
{ |
|
|
coding->result = CODING_FINISH_INCONSISTENT_EOL; |
|
|
goto label_end_of_loop; |
|
|
} |
|
3674 |
} |
} |
3675 |
|
else if (EQ (eol_type, Qmac)) |
3676 |
|
c = '\n'; |
3677 |
} |
} |
3678 |
else |
else |
3679 |
{ |
{ |
3680 |
if (sjis_p) |
struct charset *charset; |
3681 |
|
|
3682 |
|
if (c < 0x80) |
3683 |
|
charset = charset_roman; |
3684 |
|
else |
3685 |
{ |
{ |
3686 |
if (c1 == 0x80 || c1 == 0xA0 || c1 > 0xEF) |
if (c >= 0xF0) |
3687 |
goto label_invalid_code; |
goto invalid_code; |
3688 |
if (c1 <= 0x9F || c1 >= 0xE0) |
if (c < 0xA0 || c >= 0xE0) |
3689 |
{ |
{ |
3690 |
/* SJIS -> JISX0208 */ |
/* SJIS -> JISX0208 */ |
3691 |
ONE_MORE_BYTE (c2); |
ONE_MORE_BYTE (c1); |
3692 |
if (c2 < 0x40 || c2 == 0x7F || c2 > 0xFC) |
if (c1 < 0x40 || c1 == 0x7F || c1 > 0xFC) |
3693 |
goto label_invalid_code; |
goto invalid_code; |
3694 |
DECODE_SJIS (c1, c2, c1, c2); |
c = (c << 8) | c1; |
3695 |
charset = charset_jisx0208; |
SJIS_TO_JIS (c); |
3696 |
|
charset = charset_kanji; |
3697 |
} |
} |
3698 |
else |
else |
3699 |
/* SJIS -> JISX0201-Kana */ |
/* SJIS -> JISX0201-Kana */ |
3700 |
charset = charset_katakana_jisx0201; |
charset = charset_kana; |
3701 |
} |
} |
3702 |
|
CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c, c); |
3703 |
|
} |
3704 |
|
*charbuf++ = c; |
3705 |
|
continue; |
3706 |
|
|
3707 |
|
invalid_code: |
3708 |
|
src = src_base; |
3709 |
|
consumed_chars = consumed_chars_base; |
3710 |
|
ONE_MORE_BYTE (c); |
3711 |
|
*charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c); |
3712 |
|
coding->errors++; |
3713 |
|
} |
3714 |
|
|
3715 |
|
no_more_source: |
3716 |
|
coding->consumed_char += consumed_chars_base; |
3717 |
|
coding->consumed = src_base - coding->source; |
3718 |
|
coding->charbuf_used = charbuf - coding->charbuf; |
3719 |
|
} |
3720 |
|
|
3721 |
|
static void |
3722 |
|
decode_coding_big5 (coding) |
3723 |
|
struct coding_system *coding; |
3724 |
|
{ |
3725 |
|
unsigned char *src = coding->source + coding->consumed; |
3726 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
3727 |
|
unsigned char *src_base; |
3728 |
|
int *charbuf = coding->charbuf; |
3729 |
|
int *charbuf_end = charbuf + coding->charbuf_size; |
3730 |
|
int consumed_chars = 0, consumed_chars_base; |
3731 |
|
int multibytep = coding->src_multibyte; |
3732 |
|
struct charset *charset_roman, *charset_big5; |
3733 |
|
Lisp_Object attrs, eol_type, charset_list, val; |
3734 |
|
|
3735 |
|
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
3736 |
|
val = charset_list; |
3737 |
|
charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
3738 |
|
charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val))); |
3739 |
|
|
3740 |
|
while (1) |
3741 |
|
{ |
3742 |
|
int c, c1; |
3743 |
|
|
3744 |
|
src_base = src; |
3745 |
|
consumed_chars_base = consumed_chars; |
3746 |
|
|
3747 |
|
if (charbuf >= charbuf_end) |
3748 |
|
break; |
3749 |
|
|
3750 |
|
ONE_MORE_BYTE (c); |
3751 |
|
|
3752 |
|
if (c == '\r') |
3753 |
|
{ |
3754 |
|
if (EQ (eol_type, Qdos)) |
3755 |
|
{ |
3756 |
|
if (src == src_end) |
3757 |
|
goto no_more_source; |
3758 |
|
if (*src == '\n') |
3759 |
|
ONE_MORE_BYTE (c); |
3760 |
|
} |
3761 |
|
else if (EQ (eol_type, Qmac)) |
3762 |
|
c = '\n'; |
3763 |
|
} |
3764 |
|
else |
3765 |
|
{ |
3766 |
|
struct charset *charset; |
3767 |
|
if (c < 0x80) |
3768 |
|
charset = charset_roman; |
3769 |
else |
else |
3770 |
{ |
{ |
3771 |
/* BIG5 -> Big5 */ |
/* BIG5 -> Big5 */ |
3772 |
if (c1 < 0xA0 || c1 > 0xFE) |
if (c < 0xA1 || c > 0xFE) |
3773 |
goto label_invalid_code; |
goto invalid_code; |
3774 |
ONE_MORE_BYTE (c2); |
ONE_MORE_BYTE (c1); |
3775 |
if (c2 < 0x40 || (c2 > 0x7E && c2 < 0xA1) || c2 > 0xFE) |
if (c1 < 0x40 || (c1 > 0x7E && c1 < 0xA1) || c1 > 0xFE) |
3776 |
goto label_invalid_code; |
goto invalid_code; |
3777 |
DECODE_BIG5 (c1, c2, charset, c1, c2); |
c = c << 8 | c1; |
3778 |
|
charset = charset_big5; |
3779 |
} |
} |
3780 |
|
CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c, c); |
3781 |
} |
} |
3782 |
|
|
3783 |
c = DECODE_ISO_CHARACTER (charset, c1, c2); |
*charbuf++ = c; |
|
EMIT_CHAR (c); |
|
3784 |
continue; |
continue; |
3785 |
|
|
3786 |
label_invalid_code: |
invalid_code: |
|
coding->errors++; |
|
3787 |
src = src_base; |
src = src_base; |
3788 |
c = *src++; |
consumed_chars = consumed_chars_base; |
3789 |
EMIT_CHAR (c); |
ONE_MORE_BYTE (c); |
3790 |
|
*charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c); |
3791 |
|
coding->errors++; |
3792 |
} |
} |
3793 |
|
|
3794 |
label_end_of_loop: |
no_more_source: |
3795 |
coding->consumed = coding->consumed_char = src_base - source; |
coding->consumed_char += consumed_chars_base; |
3796 |
coding->produced = dst - destination; |
coding->consumed = src_base - coding->source; |
3797 |
return; |
coding->charbuf_used = charbuf - coding->charbuf; |
3798 |
} |
} |
3799 |
|
|
3800 |
/* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions". |
/* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions". |
3805 |
charsets are produced without any encoding. If SJIS_P is 1, encode |
charsets are produced without any encoding. If SJIS_P is 1, encode |
3806 |
SJIS text, else encode BIG5 text. */ |
SJIS text, else encode BIG5 text. */ |
3807 |
|
|
3808 |
static void |
static int |
3809 |
encode_coding_sjis_big5 (coding, source, destination, |
encode_coding_sjis (coding) |
|
src_bytes, dst_bytes, sjis_p) |
|
3810 |
struct coding_system *coding; |
struct coding_system *coding; |
3811 |
unsigned char *source, *destination; |
{ |
3812 |
int src_bytes, dst_bytes; |
int multibytep = coding->dst_multibyte; |
3813 |
int sjis_p; |
int *charbuf = coding->charbuf; |
3814 |
{ |
int *charbuf_end = charbuf + coding->charbuf_used; |
3815 |
unsigned char *src = source; |
unsigned char *dst = coding->destination + coding->produced; |
3816 |
unsigned char *src_end = source + src_bytes; |
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
3817 |
unsigned char *dst = destination; |
int safe_room = 4; |
3818 |
unsigned char *dst_end = destination + dst_bytes; |
int produced_chars = 0; |
3819 |
/* SRC_BASE remembers the start position in source in each loop. |
Lisp_Object attrs, eol_type, charset_list, val; |
3820 |
The loop will be exited when there's not enough source text to |
int ascii_compatible; |
3821 |
analyze multi-byte codes (within macro ONE_MORE_CHAR), or when |
struct charset *charset_roman, *charset_kanji, *charset_kana; |
3822 |
there's not enough destination area to produce encoded codes |
int c; |
|
(within macro EMIT_BYTES). */ |
|
|
unsigned char *src_base; |
|
|
Lisp_Object translation_table; |
|
|
|
|
|
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; |
|
|
} |
|
3823 |
|
|
3824 |
while (1) |
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
3825 |
{ |
val = charset_list; |
3826 |
int c, charset, c1, c2; |
charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
3827 |
|
charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
3828 |
|
charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val))); |
3829 |
|
|
3830 |
src_base = src; |
ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)); |
|
ONE_MORE_CHAR (c); |
|
3831 |
|
|
3832 |
|
while (charbuf < charbuf_end) |
3833 |
|
{ |
3834 |
|
ASSURE_DESTINATION (safe_room); |
3835 |
|
c = *charbuf++; |
3836 |
/* Now encode the character C. */ |
/* Now encode the character C. */ |
3837 |
if (SINGLE_BYTE_CHAR_P (c)) |
if (ASCII_CHAR_P (c) && ascii_compatible) |
3838 |
|
EMIT_ONE_ASCII_BYTE (c); |
3839 |
|
else |
3840 |
{ |
{ |
3841 |
switch (c) |
unsigned code; |
3842 |
|
struct charset *charset = char_charset (c, charset_list, &code); |
3843 |
|
|
3844 |
|
if (!charset) |
3845 |
{ |
{ |
3846 |
case '\r': |
c = coding->default_char; |
3847 |
if (!coding->mode & CODING_MODE_SELECTIVE_DISPLAY) |
charset = char_charset (c, charset_list, &code); |
3848 |
{ |
} |
3849 |
EMIT_ONE_BYTE (c); |
if (code == CHARSET_INVALID_CODE (charset)) |
3850 |
break; |
abort (); |
3851 |
} |
if (charset == charset_kanji) |
3852 |
c = '\n'; |
{ |
3853 |
case '\n': |
int c1, c2; |
3854 |
if (coding->eol_type == CODING_EOL_CRLF) |
JIS_TO_SJIS (code); |
3855 |
{ |
c1 = code >> 8, c2 = code & 0xFF; |
3856 |
EMIT_TWO_BYTES ('\r', c); |
EMIT_TWO_BYTES (c1, c2); |
|
break; |
|
|
} |
|
|
else if (coding->eol_type == CODING_EOL_CR) |
|
|
c = '\r'; |
|
|
default: |
|
|
EMIT_ONE_BYTE (c); |
|
3857 |
} |
} |
3858 |
|
else if (charset == charset_kana) |
3859 |
|
EMIT_ONE_BYTE (code | 0x80); |
3860 |
|
else |
3861 |
|
EMIT_ONE_ASCII_BYTE (code & 0x7F); |
3862 |
} |
} |
3863 |
|
} |
3864 |
|
coding->result = CODING_RESULT_SUCCESS; |
3865 |
|
coding->produced_char += produced_chars; |
3866 |
|
coding->produced = dst - coding->destination; |
3867 |
|
return 0; |
3868 |
|
} |
3869 |
|
|
3870 |
|
static int |
3871 |
|
encode_coding_big5 (coding) |
3872 |
|
struct coding_system *coding; |
3873 |
|
{ |
3874 |
|
int multibytep = coding->dst_multibyte; |
3875 |
|
int *charbuf = coding->charbuf; |
3876 |
|
int *charbuf_end = charbuf + coding->charbuf_used; |
3877 |
|
unsigned char *dst = coding->destination + coding->produced; |
3878 |
|
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
3879 |
|
int safe_room = 4; |
3880 |
|
int produced_chars = 0; |
3881 |
|
Lisp_Object attrs, eol_type, charset_list, val; |
3882 |
|
int ascii_compatible; |
3883 |
|
struct charset *charset_roman, *charset_big5; |
3884 |
|
int c; |
3885 |
|
|
3886 |
|
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
3887 |
|
val = charset_list; |
3888 |
|
charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
3889 |
|
charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val))); |
3890 |
|
ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)); |
3891 |
|
|
3892 |
|
while (charbuf < charbuf_end) |
3893 |
|
{ |
3894 |
|
ASSURE_DESTINATION (safe_room); |
3895 |
|
c = *charbuf++; |
3896 |
|
/* Now encode the character C. */ |
3897 |
|
if (ASCII_CHAR_P (c) && ascii_compatible) |
3898 |
|
EMIT_ONE_ASCII_BYTE (c); |
3899 |
else |
else |
3900 |
{ |
{ |
3901 |
SPLIT_CHAR (c, charset, c1, c2); |
unsigned code; |
3902 |
if (sjis_p) |
struct charset *charset = char_charset (c, charset_list, &code); |
3903 |
|
|
3904 |
|
if (! charset) |
3905 |
{ |
{ |
3906 |
if (charset == charset_jisx0208 |
c = coding->default_char; |
3907 |
|| charset == charset_jisx0208_1978) |
charset = char_charset (c, charset_list, &code); |
|
{ |
|
|
ENCODE_SJIS (c1, c2, c1, c2); |
|
|
EMIT_TWO_BYTES (c1, c2); |
|
|
} |
|
|
else if (charset == charset_katakana_jisx0201) |
|
|
EMIT_ONE_BYTE (c1 | 0x80); |
|
|
else if (charset == charset_latin_jisx0201) |
|
|
EMIT_ONE_BYTE (c1); |
|
|
else |
|
|
/* There's no way other than producing the internal |
|
|
codes as is. */ |
|
|
EMIT_BYTES (src_base, src); |
|
3908 |
} |
} |
3909 |
else |
if (code == CHARSET_INVALID_CODE (charset)) |
3910 |
|
abort (); |
3911 |
|
if (charset == charset_big5) |
3912 |
{ |
{ |
3913 |
if (charset == charset_big5_1 || charset == charset_big5_2) |
int c1, c2; |
3914 |
{ |
|
3915 |
ENCODE_BIG5 (charset, c1, c2, c1, c2); |
c1 = code >> 8, c2 = code & 0xFF; |
3916 |
EMIT_TWO_BYTES (c1, c2); |
EMIT_TWO_BYTES (c1, c2); |
|
} |
|
|
else |
|
|
/* There's no way other than producing the internal |
|
|
codes as is. */ |
|
|
EMIT_BYTES (src_base, src); |
|
3917 |
} |
} |
3918 |
|
else |
3919 |
|
EMIT_ONE_ASCII_BYTE (code & 0x7F); |
3920 |
} |
} |
|
coding->consumed_char++; |
|
3921 |
} |
} |
3922 |
|
coding->result = CODING_RESULT_SUCCESS; |
3923 |
label_end_of_loop: |
coding->produced_char += produced_chars; |
3924 |
coding->consumed = src_base - source; |
coding->produced = dst - coding->destination; |
3925 |
coding->produced = coding->produced_char = dst - destination; |
return 0; |
3926 |
} |
} |
3927 |
|
|
3928 |
|
|
3929 |
/*** 5. CCL handlers ***/ |
/*** 10. CCL handlers ***/ |
3930 |
|
|
3931 |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions". |
3932 |
Check if a text is encoded in a coding system of which |
Check if a text is encoded in a coding system of which |
3933 |
encoder/decoder are written in CCL program. If it is, return |
encoder/decoder are written in CCL program. If it is, return |
3934 |
CODING_CATEGORY_MASK_CCL, else return 0. */ |
CATEGORY_MASK_CCL, else return 0. */ |
3935 |
|
|
3936 |
static int |
static int |
3937 |
detect_coding_ccl (src, src_end, multibytep) |
detect_coding_ccl (coding, mask) |
3938 |
unsigned char *src, *src_end; |
struct coding_system *coding; |
3939 |
int multibytep; |
int *mask; |
3940 |
{ |
{ |
3941 |
unsigned char *valid; |
unsigned char *src = coding->source, *src_base = src; |
3942 |
int c; |
unsigned char *src_end = coding->source + coding->src_bytes; |
3943 |
/* Dummy for ONE_MORE_BYTE. */ |
int multibytep = coding->src_multibyte; |
3944 |
struct coding_system dummy_coding; |
int consumed_chars = 0; |
3945 |
struct coding_system *coding = &dummy_coding; |
int found = 0; |
3946 |
|
unsigned char *valids = CODING_CCL_VALIDS (coding); |
3947 |
/* No coding system is assigned to coding-category-ccl. */ |
int head_ascii = coding->head_ascii; |
3948 |
if (!coding_system_table[CODING_CATEGORY_IDX_CCL]) |
Lisp_Object attrs; |
3949 |
return 0; |
|
3950 |
|
coding = &coding_categories[coding_category_ccl]; |
3951 |
|
attrs = CODING_ID_ATTRS (coding->id); |
3952 |
|
if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs))) |
3953 |
|
src += head_ascii; |
3954 |
|
|
|
valid = coding_system_table[CODING_CATEGORY_IDX_CCL]->spec.ccl.valid_codes; |
|
3955 |
while (1) |
while (1) |
3956 |
{ |
{ |
3957 |
ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep); |
int c; |
3958 |
if (! valid[c]) |
ONE_MORE_BYTE (c); |
3959 |
return 0; |
if (! valids[c]) |
3960 |
|
break; |
3961 |
|
if (!found && valids[c] > 1) |
3962 |
|
found = 1; |
3963 |
} |
} |
3964 |
label_end_of_loop: |
*mask &= ~CATEGORY_MASK_CCL; |
3965 |
return CODING_CATEGORY_MASK_CCL; |
return 0; |
|
} |
|
|
|
|
|
|
|
|
/*** 6. End-of-line handlers ***/ |
|
3966 |
|
|
3967 |
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". */ |
no_more_source: |
3968 |
|
if (!found) |
3969 |
|
return 0; |
3970 |
|
*mask &= CATEGORY_MASK_CCL; |
3971 |
|
return 1; |
3972 |
|
} |
3973 |
|
|
3974 |
static void |
static void |
3975 |
decode_eol (coding, source, destination, src_bytes, dst_bytes) |
decode_coding_ccl (coding) |
3976 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
3977 |
{ |
{ |
3978 |
unsigned char *src = source; |
unsigned char *src = coding->source + coding->consumed; |
3979 |
unsigned char *dst = destination; |
unsigned char *src_end = coding->source + coding->src_bytes; |
3980 |
unsigned char *src_end = src + src_bytes; |
int *charbuf = coding->charbuf; |
3981 |
unsigned char *dst_end = dst + dst_bytes; |
int *charbuf_end = charbuf + coding->charbuf_size; |
3982 |
Lisp_Object translation_table; |
int consumed_chars = 0; |
3983 |
/* SRC_BASE remembers the start position in source in each loop. |
int multibytep = coding->src_multibyte; |
3984 |
The loop will be exited when there's not enough source code |
struct ccl_program ccl; |
3985 |
(within macro ONE_MORE_BYTE), or when there's not enough |
int source_charbuf[1024]; |
3986 |
destination area to produce a character (within macro |
int source_byteidx[1024]; |
3987 |
EMIT_CHAR). */ |
|
3988 |
unsigned char *src_base; |
setup_ccl_program (&ccl, CODING_CCL_DECODER (coding)); |
3989 |
int c; |
|
3990 |
|
while (src < src_end) |
3991 |
|
{ |
3992 |
|
unsigned char *p = src; |
3993 |
|
int *source, *source_end; |
3994 |
|
int i = 0; |
3995 |
|
|
3996 |
translation_table = Qnil; |
if (multibytep) |
3997 |
switch (coding->eol_type) |
while (i < 1024 && p < src_end) |
3998 |
{ |
{ |
3999 |
case CODING_EOL_CRLF: |
source_byteidx[i] = p - src; |
4000 |
while (1) |
source_charbuf[i++] = STRING_CHAR_ADVANCE (p); |
4001 |
{ |
} |
4002 |
src_base = src; |
else |
4003 |
ONE_MORE_BYTE (c); |
while (i < 1024 && p < src_end) |
4004 |
if (c == '\r') |
source_charbuf[i++] = *p++; |
4005 |
{ |
|
4006 |
ONE_MORE_BYTE (c); |
if (p == src_end && coding->mode & CODING_MODE_LAST_BLOCK) |
4007 |
if (c != '\n') |
ccl.last_block = 1; |
4008 |
{ |
|
4009 |
if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL) |
source = source_charbuf; |
4010 |
{ |
source_end = source + i; |
4011 |
coding->result = CODING_FINISH_INCONSISTENT_EOL; |
while (source < source_end) |
4012 |
goto label_end_of_loop; |
{ |
4013 |
} |
ccl_driver (&ccl, source, charbuf, |
4014 |
src--; |
source_end - source, charbuf_end - charbuf); |
4015 |
c = '\r'; |
source += ccl.consumed; |
4016 |
} |
charbuf += ccl.produced; |
4017 |
} |
if (ccl.status != CCL_STAT_SUSPEND_BY_DST) |
4018 |
else if (c == '\n' |
break; |
|
&& (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)) |
|
|
{ |
|
|
coding->result = CODING_FINISH_INCONSISTENT_EOL; |
|
|
goto label_end_of_loop; |
|
|
} |
|
|
EMIT_CHAR (c); |
|
4019 |
} |
} |
4020 |
break; |
if (source < source_end) |
4021 |
|
src += source_byteidx[source - source_charbuf]; |
4022 |
|
else |
4023 |
|
src = p; |
4024 |
|
consumed_chars += source - source_charbuf; |
4025 |
|
|
4026 |
case CODING_EOL_CR: |
if (ccl.status != CCL_STAT_SUSPEND_BY_SRC |
4027 |
while (1) |
&& ccl.status != CODING_RESULT_INSUFFICIENT_SRC) |
4028 |
{ |
break; |
4029 |
src_base = src; |
} |
4030 |
ONE_MORE_BYTE (c); |
|
4031 |
if (c == '\n') |
switch (ccl.status) |
4032 |
{ |
{ |
4033 |
if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL) |
case CCL_STAT_SUSPEND_BY_SRC: |
4034 |
{ |
coding->result = CODING_RESULT_INSUFFICIENT_SRC; |
4035 |
coding->result = CODING_FINISH_INCONSISTENT_EOL; |
break; |
4036 |
goto label_end_of_loop; |
case CCL_STAT_SUSPEND_BY_DST: |
4037 |
} |
break; |
4038 |
} |
case CCL_STAT_QUIT: |
4039 |
else if (c == '\r') |
case CCL_STAT_INVALID_CMD: |
4040 |
c = '\n'; |
coding->result = CODING_RESULT_INTERRUPT; |
|
EMIT_CHAR (c); |
|
|
} |
|
4041 |
break; |
break; |
4042 |
|
default: |
4043 |
|
coding->result = CODING_RESULT_SUCCESS; |
4044 |
|
break; |
4045 |
|
} |
4046 |
|
coding->consumed_char += consumed_chars; |
4047 |
|
coding->consumed = src - coding->source; |
4048 |
|
coding->charbuf_used = charbuf - coding->charbuf; |
4049 |
|
} |
4050 |
|
|
4051 |
default: /* no need for EOL handling */ |
static int |
4052 |
while (1) |
encode_coding_ccl (coding) |
4053 |
|
struct coding_system *coding; |
4054 |
|
{ |
4055 |
|
struct ccl_program ccl; |
4056 |
|
int multibytep = coding->dst_multibyte; |
4057 |
|
int *charbuf = coding->charbuf; |
4058 |
|
int *charbuf_end = charbuf + coding->charbuf_used; |
4059 |
|
unsigned char *dst = coding->destination + coding->produced; |
4060 |
|
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
4061 |
|
unsigned char *adjusted_dst_end = dst_end - 1; |
4062 |
|
int destination_charbuf[1024]; |
4063 |
|
int i, produced_chars = 0; |
4064 |
|
|
4065 |
|
setup_ccl_program (&ccl, CODING_CCL_ENCODER (coding)); |
4066 |
|
|
4067 |
|
ccl.last_block = coding->mode & CODING_MODE_LAST_BLOCK; |
4068 |
|
ccl.dst_multibyte = coding->dst_multibyte; |
4069 |
|
|
4070 |
|
while (charbuf < charbuf_end && dst < adjusted_dst_end) |
4071 |
|
{ |
4072 |
|
int dst_bytes = dst_end - dst; |
4073 |
|
if (dst_bytes > 1024) |
4074 |
|
dst_bytes = 1024; |
4075 |
|
|
4076 |
|
ccl_driver (&ccl, charbuf, destination_charbuf, |
4077 |
|
charbuf_end - charbuf, dst_bytes); |
4078 |
|
charbuf += ccl.consumed; |
4079 |
|
if (multibytep) |
4080 |
|
for (i = 0; i < ccl.produced; i++) |
4081 |
|
EMIT_ONE_BYTE (destination_charbuf[i] & 0xFF); |
4082 |
|
else |
4083 |
{ |
{ |
4084 |
src_base = src; |
for (i = 0; i < ccl.produced; i++) |
4085 |
ONE_MORE_BYTE (c); |
*dst++ = destination_charbuf[i] & 0xFF; |
4086 |
EMIT_CHAR (c); |
produced_chars += ccl.produced; |
4087 |
} |
} |
4088 |
} |
} |
4089 |
|
|
4090 |
label_end_of_loop: |
switch (ccl.status) |
4091 |
coding->consumed = coding->consumed_char = src_base - source; |
{ |
4092 |
coding->produced = dst - destination; |
case CCL_STAT_SUSPEND_BY_SRC: |
4093 |
return; |
coding->result = CODING_RESULT_INSUFFICIENT_SRC; |
4094 |
|
break; |
4095 |
|
case CCL_STAT_SUSPEND_BY_DST: |
4096 |
|
coding->result = CODING_RESULT_INSUFFICIENT_DST; |
4097 |
|
break; |
4098 |
|
case CCL_STAT_QUIT: |
4099 |
|
case CCL_STAT_INVALID_CMD: |
4100 |
|
coding->result = CODING_RESULT_INTERRUPT; |
4101 |
|
break; |
4102 |
|
default: |
4103 |
|
coding->result = CODING_RESULT_SUCCESS; |
4104 |
|
break; |
4105 |
|
} |
4106 |
|
|
4107 |
|
coding->produced_char += produced_chars; |
4108 |
|
coding->produced = dst - coding->destination; |
4109 |
|
return 0; |
4110 |
} |
} |
4111 |
|
|
4112 |
/* See "GENERAL NOTES about `encode_coding_XXX ()' functions". Encode |
|
4113 |
format of end-of-line according to `coding->eol_type'. It also |
|
4114 |
convert multibyte form 8-bit characters to unibyte if |
/*** 10, 11. no-conversion handlers ***/ |
4115 |
CODING->src_multibyte is nonzero. If `coding->mode & |
|
4116 |
CODING_MODE_SELECTIVE_DISPLAY' is nonzero, code '\r' in source text |
/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions". */ |
|
also means end-of-line. */ |
|
4117 |
|
|
4118 |
static void |
static void |
4119 |
encode_eol (coding, source, destination, src_bytes, dst_bytes) |
decode_coding_raw_text (coding) |
4120 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
4121 |
{ |
{ |
4122 |
unsigned char *src = source; |
coding->chars_at_source = 1; |
4123 |
unsigned char *dst = destination; |
coding->consumed_char = coding->src_chars; |
4124 |
unsigned char *src_end = src + src_bytes; |
coding->consumed = coding->src_bytes; |
4125 |
unsigned char *dst_end = dst + dst_bytes; |
coding->result = CODING_RESULT_SUCCESS; |
4126 |
Lisp_Object translation_table; |
} |
4127 |
/* SRC_BASE remembers the start position in source in each loop. |
|
4128 |
The loop will be exited when there's not enough source text to |
static int |
4129 |
analyze multi-byte codes (within macro ONE_MORE_CHAR), or when |
encode_coding_raw_text (coding) |
4130 |
there's not enough destination area to produce encoded codes |
struct coding_system *coding; |
4131 |
(within macro EMIT_BYTES). */ |
{ |
4132 |
unsigned char *src_base; |
int multibytep = coding->dst_multibyte; |
4133 |
|
int *charbuf = coding->charbuf; |
4134 |
|
int *charbuf_end = coding->charbuf + coding->charbuf_used; |
4135 |
|
unsigned char *dst = coding->destination + coding->produced; |
4136 |
|
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
4137 |
|
int produced_chars = 0; |
4138 |
int c; |
int c; |
|
int selective_display = coding->mode & CODING_MODE_SELECTIVE_DISPLAY; |
|
4139 |
|
|
4140 |
translation_table = Qnil; |
if (multibytep) |
|
if (coding->src_multibyte |
|
|
&& *(src_end - 1) == LEADING_CODE_8_BIT_CONTROL) |
|
4141 |
{ |
{ |
4142 |
src_end--; |
int safe_room = MAX_MULTIBYTE_LENGTH * 2; |
|
src_bytes--; |
|
|
coding->result = CODING_FINISH_INSUFFICIENT_SRC; |
|
|
} |
|
4143 |
|
|
4144 |
if (coding->eol_type == CODING_EOL_CRLF) |
if (coding->src_multibyte) |
4145 |
{ |
while (charbuf < charbuf_end) |
4146 |
while (src < src_end) |
{ |
4147 |
{ |
ASSURE_DESTINATION (safe_room); |
4148 |
src_base = src; |
c = *charbuf++; |
4149 |
c = *src++; |
if (ASCII_CHAR_P (c)) |
4150 |
if (c >= 0x20) |
EMIT_ONE_ASCII_BYTE (c); |
4151 |
EMIT_ONE_BYTE (c); |
else if (CHAR_BYTE8_P (c)) |
4152 |
else if (c == '\n' || (c == '\r' && selective_display)) |
{ |
4153 |
EMIT_TWO_BYTES ('\r', '\n'); |
c = CHAR_TO_BYTE8 (c); |
4154 |
else |
EMIT_ONE_BYTE (c); |
4155 |
|
} |
4156 |
|
else |
4157 |
|
{ |
4158 |
|
unsigned char str[MAX_MULTIBYTE_LENGTH], *p0 = str, *p1 = str; |
4159 |
|
|
4160 |
|
CHAR_STRING_ADVANCE (c, p1); |
4161 |
|
while (p0 < p1) |
4162 |
|
EMIT_ONE_BYTE (*p0); |
4163 |
|
} |
4164 |
|
} |
4165 |
|
else |
4166 |
|
while (charbuf < charbuf_end) |
4167 |
|
{ |
4168 |
|
ASSURE_DESTINATION (safe_room); |
4169 |
|
c = *charbuf++; |
4170 |
EMIT_ONE_BYTE (c); |
EMIT_ONE_BYTE (c); |
4171 |
} |
} |
|
src_base = src; |
|
|
label_end_of_loop: |
|
|
; |
|
4172 |
} |
} |
4173 |
else |
else |
4174 |
{ |
{ |
4175 |
if (!dst_bytes || src_bytes <= dst_bytes) |
if (coding->src_multibyte) |
4176 |
{ |
{ |
4177 |
safe_bcopy (src, dst, src_bytes); |
int safe_room = MAX_MULTIBYTE_LENGTH; |
4178 |
src_base = src_end; |
|
4179 |
dst += src_bytes; |
while (charbuf < charbuf_end) |
4180 |
|
{ |
4181 |
|
ASSURE_DESTINATION (safe_room); |
4182 |
|
c = *charbuf++; |
4183 |
|
if (ASCII_CHAR_P (c)) |
4184 |
|
*dst++ = c; |
4185 |
|
else if (CHAR_BYTE8_P (c)) |
4186 |
|
*dst++ = CHAR_TO_BYTE8 (c); |
4187 |
|
else |
4188 |
|
CHAR_STRING_ADVANCE (c, dst); |
4189 |
|
produced_chars++; |
4190 |
|
} |
4191 |
} |
} |
4192 |
else |
else |
4193 |
{ |
{ |
4194 |
if (coding->src_multibyte |
ASSURE_DESTINATION (charbuf_end - charbuf); |
4195 |
&& *(src + dst_bytes - 1) == LEADING_CODE_8_BIT_CONTROL) |
while (charbuf < charbuf_end && dst < dst_end) |
4196 |
dst_bytes--; |
*dst++ = *charbuf++; |
4197 |
safe_bcopy (src, dst, dst_bytes); |
produced_chars = dst - (coding->destination + coding->dst_bytes); |
4198 |
src_base = src + dst_bytes; |
} |
4199 |
dst = destination + dst_bytes; |
} |
4200 |
coding->result = CODING_FINISH_INSUFFICIENT_DST; |
coding->result = CODING_RESULT_SUCCESS; |
4201 |
} |
coding->produced_char += produced_chars; |
4202 |
if (coding->eol_type == CODING_EOL_CR) |
coding->produced = dst - coding->destination; |
4203 |
|
return 0; |
4204 |
|
} |
4205 |
|
|
4206 |
|
static int |
4207 |
|
detect_coding_charset (coding, mask) |
4208 |
|
struct coding_system *coding; |
4209 |
|
int *mask; |
4210 |
|
{ |
4211 |
|
unsigned char *src = coding->source, *src_base = src; |
4212 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
4213 |
|
int multibytep = coding->src_multibyte; |
4214 |
|
int consumed_chars = 0; |
4215 |
|
Lisp_Object attrs, valids; |
4216 |
|
|
4217 |
|
coding = &coding_categories[coding_category_charset]; |
4218 |
|
attrs = CODING_ID_ATTRS (coding->id); |
4219 |
|
valids = AREF (attrs, coding_attr_charset_valids); |
4220 |
|
|
4221 |
|
if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs))) |
4222 |
|
src += coding->head_ascii; |
4223 |
|
|
4224 |
|
while (1) |
4225 |
|
{ |
4226 |
|
int c; |
4227 |
|
|
4228 |
|
ONE_MORE_BYTE (c); |
4229 |
|
if (NILP (AREF (valids, c))) |
4230 |
|
break; |
4231 |
|
} |
4232 |
|
*mask &= ~CATEGORY_MASK_CHARSET; |
4233 |
|
return 0; |
4234 |
|
|
4235 |
|
no_more_source: |
4236 |
|
*mask &= CATEGORY_MASK_CHARSET; |
4237 |
|
return 1; |
4238 |
|
} |
4239 |
|
|
4240 |
|
static void |
4241 |
|
decode_coding_charset (coding) |
4242 |
|
struct coding_system *coding; |
4243 |
|
{ |
4244 |
|
unsigned char *src = coding->source + coding->consumed; |
4245 |
|
unsigned char *src_end = coding->source + coding->src_bytes; |
4246 |
|
unsigned char *src_base; |
4247 |
|
int *charbuf = coding->charbuf; |
4248 |
|
int *charbuf_end = charbuf + coding->charbuf_size; |
4249 |
|
int consumed_chars = 0, consumed_chars_base; |
4250 |
|
int multibytep = coding->src_multibyte; |
4251 |
|
struct charset *charset; |
4252 |
|
Lisp_Object attrs, eol_type, charset_list; |
4253 |
|
|
4254 |
|
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
4255 |
|
charset = CHARSET_FROM_ID (XINT (XCAR (charset_list))); |
4256 |
|
|
4257 |
|
while (1) |
4258 |
|
{ |
4259 |
|
int c, c1; |
4260 |
|
|
4261 |
|
src_base = src; |
4262 |
|
consumed_chars_base = consumed_chars; |
4263 |
|
|
4264 |
|
if (charbuf >= charbuf_end) |
4265 |
|
break; |
4266 |
|
|
4267 |
|
ONE_MORE_BYTE (c1); |
4268 |
|
if (c == '\r') |
4269 |
{ |
{ |
4270 |
for (src = destination; src < dst; src++) |
if (EQ (eol_type, Qdos)) |
4271 |
if (*src == '\n') *src = '\r'; |
{ |
4272 |
|
if (src == src_end) |
4273 |
|
goto no_more_source; |
4274 |
|
if (*src == '\n') |
4275 |
|
ONE_MORE_BYTE (c); |
4276 |
|
} |
4277 |
|
else if (EQ (eol_type, Qmac)) |
4278 |
|
c = '\n'; |
4279 |
} |
} |
4280 |
else if (selective_display) |
else |
4281 |
{ |
{ |
4282 |
for (src = destination; src < dst; src++) |
CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c1, c); |
4283 |
if (*src == '\r') *src = '\n'; |
if (c < 0) |
4284 |
|
goto invalid_code; |
4285 |
} |
} |
4286 |
|
*charbuf++ = c; |
4287 |
|
continue; |
4288 |
|
|
4289 |
|
invalid_code: |
4290 |
|
src = src_base; |
4291 |
|
consumed_chars = consumed_chars_base; |
4292 |
|
ONE_MORE_BYTE (c); |
4293 |
|
*charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c); |
4294 |
|
coding->errors++; |
4295 |
} |
} |
|
if (coding->src_multibyte) |
|
|
dst = destination + str_as_unibyte (destination, dst - destination); |
|
4296 |
|
|
4297 |
coding->consumed = src_base - source; |
no_more_source: |
4298 |
coding->produced = dst - destination; |
coding->consumed_char += consumed_chars_base; |
4299 |
coding->produced_char = coding->produced; |
coding->consumed = src_base - coding->source; |
4300 |
|
coding->charbuf_used = charbuf - coding->charbuf; |
4301 |
|
} |
4302 |
|
|
4303 |
|
static int |
4304 |
|
encode_coding_charset (coding) |
4305 |
|
struct coding_system *coding; |
4306 |
|
{ |
4307 |
|
int multibytep = coding->dst_multibyte; |
4308 |
|
int *charbuf = coding->charbuf; |
4309 |
|
int *charbuf_end = charbuf + coding->charbuf_used; |
4310 |
|
unsigned char *dst = coding->destination + coding->produced; |
4311 |
|
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
4312 |
|
int safe_room = MAX_MULTIBYTE_LENGTH; |
4313 |
|
int produced_chars = 0; |
4314 |
|
struct charset *charset; |
4315 |
|
Lisp_Object attrs, eol_type, charset_list; |
4316 |
|
int ascii_compatible; |
4317 |
|
int c; |
4318 |
|
|
4319 |
|
CODING_GET_INFO (coding, attrs, eol_type, charset_list); |
4320 |
|
charset = CHARSET_FROM_ID (XINT (XCAR (charset_list))); |
4321 |
|
ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)); |
4322 |
|
|
4323 |
|
while (charbuf < charbuf_end) |
4324 |
|
{ |
4325 |
|
unsigned code; |
4326 |
|
|
4327 |
|
ASSURE_DESTINATION (safe_room); |
4328 |
|
c = *charbuf++; |
4329 |
|
if (ascii_compatible && ASCII_CHAR_P (c)) |
4330 |
|
EMIT_ONE_ASCII_BYTE (c); |
4331 |
|
else if ((code = ENCODE_CHAR (charset, c)) |
4332 |
|
!= CHARSET_INVALID_CODE (charset)) |
4333 |
|
EMIT_ONE_BYTE (code); |
4334 |
|
else |
4335 |
|
EMIT_ONE_BYTE (coding->default_char); |
4336 |
|
} |
4337 |
|
|
4338 |
|
coding->result = CODING_RESULT_SUCCESS; |
4339 |
|
coding->produced_char += produced_chars; |
4340 |
|
coding->produced = dst - coding->destination; |
4341 |
|
return 0; |
4342 |
} |
} |
4343 |
|
|
4344 |
|
|
4345 |
/*** 7. C library functions ***/ |
/*** 7. C library functions ***/ |
4346 |
|
|
4347 |
/* In Emacs Lisp, a coding system is represented by a Lisp symbol which |
/* In Emacs Lisp, coding system is represented by a Lisp symbol which |
4348 |
has a property `coding-system'. The value of this property is a |
has a property `coding-system'. The value of this property is a |
4349 |
vector of length 5 (called the coding-vector). Among elements of |
vector of length 5 (called as coding-vector). Among elements of |
4350 |
this vector, the first (element[0]) and the fifth (element[4]) |
this vector, the first (element[0]) and the fifth (element[4]) |
4351 |
carry important information for decoding/encoding. Before |
carry important information for decoding/encoding. Before |
4352 |
decoding/encoding, this information should be set in fields of a |
decoding/encoding, this information should be set in fields of a |
4353 |
structure of type `coding_system'. |
structure of type `coding_system'. |
4354 |
|
|
4355 |
The value of the property `coding-system' can be a symbol of another |
A value of property `coding-system' can be a symbol of another |
4356 |
subsidiary coding-system. In that case, Emacs gets coding-vector |
subsidiary coding-system. In that case, Emacs gets coding-vector |
4357 |
from that symbol. |
from that symbol. |
4358 |
|
|
4361 |
|
|
4362 |
0 -- coding_type_emacs_mule |
0 -- coding_type_emacs_mule |
4363 |
1 -- coding_type_sjis |
1 -- coding_type_sjis |
4364 |
2 -- coding_type_iso2022 |
2 -- coding_type_iso_2022 |
4365 |
3 -- coding_type_big5 |
3 -- coding_type_big5 |
4366 |
4 -- coding_type_ccl encoder/decoder written in CCL |
4 -- coding_type_ccl encoder/decoder written in CCL |
4367 |
nil -- coding_type_no_conversion |
nil -- coding_type_no_conversion |
4371 |
`element[4]' contains information to be set in `coding->flags' and |
`element[4]' contains information to be set in `coding->flags' and |
4372 |
`coding->spec'. The meaning varies by `coding->type'. |
`coding->spec'. The meaning varies by `coding->type'. |
4373 |
|
|
4374 |
If `coding->type' is `coding_type_iso2022', element[4] is a vector |
If `coding->type' is `coding_type_iso_2022', element[4] is a vector |
4375 |
of length 32 (of which the first 13 sub-elements are used now). |
of length 32 (of which the first 13 sub-elements are used now). |
4376 |
Meanings of these sub-elements are: |
Meanings of these sub-elements are: |
4377 |
|
|
4378 |
sub-element[N] where N is 0 through 3: to be set in `coding->spec.iso2022' |
sub-element[N] where N is 0 through 3: to be set in `coding->spec.iso_2022' |
4379 |
If the value is an integer of valid charset, the charset is |
If the value is an integer of valid charset, the charset is |
4380 |
assumed to be designated to graphic register N initially. |
assumed to be designated to graphic register N initially. |
4381 |
|
|
4386 |
|
|
4387 |
If the value is nil, graphic register N is never used on |
If the value is nil, graphic register N is never used on |
4388 |
encoding. |
encoding. |
4389 |
|
|
4390 |
sub-element[N] where N is 4 through 11: to be set in `coding->flags' |
sub-element[N] where N is 4 through 11: to be set in `coding->flags' |
4391 |
Each value takes t or nil. See the section ISO2022 of |
Each value takes t or nil. See the section ISO2022 of |
4392 |
`coding.h' for more information. |
`coding.h' for more information. |
4396 |
|
|
4397 |
If `coding->type' takes the other value, element[4] is ignored. |
If `coding->type' takes the other value, element[4] is ignored. |
4398 |
|
|
4399 |
Emacs Lisp's coding systems also carry information about format of |
Emacs Lisp's coding system also carries information about format of |
4400 |
end-of-line in a value of property `eol-type'. If the value is |
end-of-line in a value of property `eol-type'. If the value is |
4401 |
integer, 0 means CODING_EOL_LF, 1 means CODING_EOL_CRLF, and 2 |
integer, 0 means eol_lf, 1 means eol_crlf, and 2 means eol_cr. If |
4402 |
means CODING_EOL_CR. If it is not integer, it should be a vector |
it is not integer, it should be a vector of subsidiary coding |
4403 |
of subsidiary coding systems of which property `eol-type' has one |
systems of which property `eol-type' has one of above values. |
|
of the above values. |
|
4404 |
|
|
4405 |
*/ |
*/ |
4406 |
|
|
4407 |
/* Extract information for decoding/encoding from CODING_SYSTEM_SYMBOL |
/* Setup coding context CODING from information about CODING_SYSTEM. |
4408 |
and set it in CODING. If CODING_SYSTEM_SYMBOL is invalid, CODING |
If CODING_SYSTEM is nil, `no-conversion' is assumed. If |
4409 |
is setup so that no conversion is necessary and return -1, else |
CODING_SYSTEM is invalid, signal an error. */ |
|
return 0. */ |
|
4410 |
|
|
4411 |
int |
void |
4412 |
setup_coding_system (coding_system, coding) |
setup_coding_system (coding_system, coding) |
4413 |
Lisp_Object coding_system; |
Lisp_Object coding_system; |
4414 |
struct coding_system *coding; |
struct coding_system *coding; |
4415 |
{ |
{ |
4416 |
Lisp_Object coding_spec, coding_type, eol_type, plist; |
int id; |
4417 |
|
Lisp_Object attrs; |
4418 |
|
Lisp_Object eol_type; |
4419 |
|
Lisp_Object coding_type; |
4420 |
Lisp_Object val; |
Lisp_Object val; |
4421 |
|
|
4422 |
/* At first, zero clear all members. */ |
if (NILP (coding_system)) |
4423 |
bzero (coding, sizeof (struct coding_system)); |
coding_system = Qno_conversion; |
4424 |
|
|
4425 |
/* Initialize some fields required for all kinds of coding systems. */ |
CHECK_CODING_SYSTEM_GET_ID (coding_system, coding->id); |
|
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; |
|
4426 |
|
|
4427 |
if (NILP (coding_system)) |
attrs = CODING_ID_ATTRS (coding->id); |
4428 |
goto label_invalid_coding_system; |
eol_type = CODING_ID_EOL_TYPE (coding->id); |
4429 |
|
|
4430 |
coding_spec = Fget (coding_system, Qcoding_system); |
coding->mode = 0; |
4431 |
|
coding->head_ascii = -1; |
4432 |
|
coding->common_flags |
4433 |
|
= (VECTORP (eol_type) ? CODING_REQUIRE_DETECTION_MASK : 0); |
4434 |
|
|
4435 |
if (!VECTORP (coding_spec) |
val = CODING_ATTR_SAFE_CHARSETS (attrs); |
4436 |
|| XVECTOR (coding_spec)->size != 5 |
coding->max_charset_id = XSTRING (val)->size - 1; |
4437 |
|| !CONSP (XVECTOR (coding_spec)->contents[3])) |
coding->safe_charsets = (char *) XSTRING (val)->data; |
4438 |
goto label_invalid_coding_system; |
coding->default_char = XINT (CODING_ATTR_DEFAULT_CHAR (attrs)); |
4439 |
|
|
4440 |
eol_type = inhibit_eol_conversion ? Qnil : Fget (coding_system, Qeol_type); |
coding_type = CODING_ATTR_TYPE (attrs); |
4441 |
if (VECTORP (eol_type)) |
if (EQ (coding_type, Qundecided)) |
4442 |
{ |
{ |
4443 |
coding->eol_type = CODING_EOL_UNDECIDED; |
coding->detector = NULL; |
4444 |
coding->common_flags = CODING_REQUIRE_DETECTION_MASK; |
coding->decoder = decode_coding_raw_text; |
4445 |
|
coding->encoder = encode_coding_raw_text; |
4446 |
|
coding->common_flags |= CODING_REQUIRE_DETECTION_MASK; |
4447 |
} |
} |
4448 |
else if (XFASTINT (eol_type) == 1) |
else if (EQ (coding_type, Qiso_2022)) |
4449 |
{ |
{ |
4450 |
coding->eol_type = CODING_EOL_CRLF; |
int i; |
4451 |
|
int flags = XINT (AREF (attrs, coding_attr_iso_flags)); |
4452 |
|
|
4453 |
|
/* Invoke graphic register 0 to plane 0. */ |
4454 |
|
CODING_ISO_INVOCATION (coding, 0) = 0; |
4455 |
|
/* Invoke graphic register 1 to plane 1 if we can use 8-bit. */ |
4456 |
|
CODING_ISO_INVOCATION (coding, 1) |
4457 |
|
= (flags & CODING_ISO_FLAG_SEVEN_BITS ? -1 : 1); |
4458 |
|
/* Setup the initial status of designation. */ |
4459 |
|
for (i = 0; i < 4; i++) |
4460 |
|
CODING_ISO_DESIGNATION (coding, i) = CODING_ISO_INITIAL (coding, i); |
4461 |
|
/* Not single shifting initially. */ |
4462 |
|
CODING_ISO_SINGLE_SHIFTING (coding) = 0; |
4463 |
|
/* Beginning of buffer should also be regarded as bol. */ |
4464 |
|
CODING_ISO_BOL (coding) = 1; |
4465 |
|
coding->detector = detect_coding_iso_2022; |
4466 |
|
coding->decoder = decode_coding_iso_2022; |
4467 |
|
coding->encoder = encode_coding_iso_2022; |
4468 |
|
if (flags & CODING_ISO_FLAG_SAFE) |
4469 |
|
coding->mode |= CODING_MODE_SAFE_ENCODING; |
4470 |
|
coding->common_flags |
4471 |
|
|= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK |
4472 |
|
| CODING_REQUIRE_FLUSHING_MASK); |
4473 |
|
if (flags & CODING_ISO_FLAG_COMPOSITION) |
4474 |
|
coding->common_flags |= CODING_ANNOTATE_COMPOSITION_MASK; |
4475 |
|
if (flags & CODING_ISO_FLAG_FULL_SUPPORT) |
4476 |
|
{ |
4477 |
|
setup_iso_safe_charsets (attrs); |
4478 |
|
val = CODING_ATTR_SAFE_CHARSETS (attrs); |
4479 |
|
coding->max_charset_id = XSTRING (val)->size - 1; |
4480 |
|
coding->safe_charsets = (char *) XSTRING (val)->data; |
4481 |
|
} |
4482 |
|
CODING_ISO_FLAGS (coding) = flags; |
4483 |
|
} |
4484 |
|
else if (EQ (coding_type, Qcharset)) |
4485 |
|
{ |
4486 |
|
coding->detector = detect_coding_charset; |
4487 |
|
coding->decoder = decode_coding_charset; |
4488 |
|
coding->encoder = encode_coding_charset; |
4489 |
coding->common_flags |
coding->common_flags |
4490 |
= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK; |
|= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK); |
4491 |
} |
} |
4492 |
else if (XFASTINT (eol_type) == 2) |
else if (EQ (coding_type, Qutf_8)) |
4493 |
{ |
{ |
4494 |
coding->eol_type = CODING_EOL_CR; |
coding->detector = detect_coding_utf_8; |
4495 |
|
coding->decoder = decode_coding_utf_8; |
4496 |
|
coding->encoder = encode_coding_utf_8; |
4497 |
coding->common_flags |
coding->common_flags |
4498 |
= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK; |
|= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK); |
4499 |
} |
} |
4500 |
else |
else if (EQ (coding_type, Qutf_16)) |
|
coding->eol_type = CODING_EOL_LF; |
|
|
|
|
|
coding_type = XVECTOR (coding_spec)->contents[0]; |
|
|
/* Try short cut. */ |
|
|
if (SYMBOLP (coding_type)) |
|
4501 |
{ |
{ |
4502 |
if (EQ (coding_type, Qt)) |
val = AREF (attrs, coding_attr_utf_16_bom); |
4503 |
{ |
CODING_UTF_16_BOM (coding) = (CONSP (val) ? utf_16_detect_bom |
4504 |
coding->type = coding_type_undecided; |
: EQ (val, Qt) ? utf_16_with_bom |
4505 |
coding->common_flags |= CODING_REQUIRE_DETECTION_MASK; |
: utf_16_without_bom); |
4506 |
} |
val = AREF (attrs, coding_attr_utf_16_endian); |
4507 |
else |
CODING_UTF_16_ENDIAN (coding) = (NILP (val) ? utf_16_big_endian |
4508 |
coding->type = coding_type_no_conversion; |
: utf_16_little_endian); |
4509 |
/* Initialize this member. Any thing other than |
coding->detector = detect_coding_utf_16; |
4510 |
CODING_CATEGORY_IDX_UTF_16_BE and |
coding->decoder = decode_coding_utf_16; |
4511 |
CODING_CATEGORY_IDX_UTF_16_LE are ok because they have |
coding->encoder = encode_coding_utf_16; |
4512 |
special treatment in detect_eol. */ |
coding->common_flags |
4513 |
coding->category_idx = CODING_CATEGORY_IDX_EMACS_MULE; |
|= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK); |
|
|
|
|
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; |
|
4514 |
} |
} |
4515 |
else |
else if (EQ (coding_type, Qccl)) |
|
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)) |
|
4516 |
{ |
{ |
4517 |
case 0: |
coding->detector = detect_coding_ccl; |
4518 |
coding->type = coding_type_emacs_mule; |
coding->decoder = decode_coding_ccl; |
4519 |
|
coding->encoder = encode_coding_ccl; |
4520 |
coding->common_flags |
coding->common_flags |
4521 |
|= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK; |
|= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK |
4522 |
coding->composing = COMPOSITION_NO; |
| CODING_REQUIRE_FLUSHING_MASK); |
4523 |
if (!NILP (coding->post_read_conversion)) |
} |
4524 |
coding->common_flags |= CODING_REQUIRE_DECODING_MASK; |
else if (EQ (coding_type, Qemacs_mule)) |
4525 |
if (!NILP (coding->pre_write_conversion)) |
{ |
4526 |
coding->common_flags |= CODING_REQUIRE_ENCODING_MASK; |
coding->detector = detect_coding_emacs_mule; |
4527 |
break; |
coding->decoder = decode_coding_emacs_mule; |
4528 |
|
coding->encoder = encode_coding_emacs_mule; |
|
case 1: |
|
|
coding->type = coding_type_sjis; |
|
|
coding->common_flags |
|
|
|= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK; |
|
|
break; |
|
|
|
|
|
case 2: |
|
|
coding->type = coding_type_iso2022; |
|
4529 |
coding->common_flags |
coding->common_flags |
4530 |
|= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK; |
|= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK); |
4531 |
{ |
if (! NILP (AREF (attrs, coding_attr_emacs_mule_full)) |
4532 |
Lisp_Object val, temp; |
&& ! EQ (CODING_ATTR_CHARSET_LIST (attrs), Vemacs_mule_charset_list)) |
4533 |
Lisp_Object *flags; |
{ |
4534 |
int i, charset, reg_bits = 0; |
Lisp_Object tail, safe_charsets; |
4535 |
|
int max_charset_id = 0; |
4536 |
val = XVECTOR (coding_spec)->contents[4]; |
|
4537 |
|
for (tail = Vemacs_mule_charset_list; CONSP (tail); |
4538 |
if (!VECTORP (val) || XVECTOR (val)->size != 32) |
tail = XCDR (tail)) |
4539 |
goto label_invalid_coding_system; |
if (max_charset_id < XFASTINT (XCAR (tail))) |
4540 |
|
max_charset_id = XFASTINT (XCAR (tail)); |
4541 |
flags = XVECTOR (val)->contents; |
safe_charsets = Fmake_string (make_number (max_charset_id + 1), |
4542 |
coding->flags |
make_number (255)); |
4543 |
= ((NILP (flags[4]) ? 0 : CODING_FLAG_ISO_SHORT_FORM) |
for (tail = Vemacs_mule_charset_list; CONSP (tail); |
4544 |
| (NILP (flags[5]) ? 0 : CODING_FLAG_ISO_RESET_AT_EOL) |
tail = XCDR (tail)) |
4545 |
| (NILP (flags[6]) ? 0 : CODING_FLAG_ISO_RESET_AT_CNTL) |
XSTRING (safe_charsets)->data[XFASTINT (XCAR (tail))] = 0; |
4546 |
| (NILP (flags[7]) ? 0 : CODING_FLAG_ISO_SEVEN_BITS) |
coding->max_charset_id = max_charset_id; |
4547 |
| (NILP (flags[8]) ? 0 : CODING_FLAG_ISO_LOCKING_SHIFT) |
coding->safe_charsets = (char *) XSTRING (safe_charsets)->data; |
4548 |
| (NILP (flags[9]) ? 0 : CODING_FLAG_ISO_SINGLE_SHIFT) |
} |
4549 |
| (NILP (flags[10]) ? 0 : CODING_FLAG_ISO_USE_ROMAN) |
} |
4550 |
| (NILP (flags[11]) ? 0 : CODING_FLAG_ISO_USE_OLDJIS) |
else if (EQ (coding_type, Qshift_jis)) |
4551 |
| (NILP (flags[12]) ? 0 : CODING_FLAG_ISO_NO_DIRECTION) |
{ |
4552 |
| (NILP (flags[13]) ? 0 : CODING_FLAG_ISO_INIT_AT_BOL) |
coding->detector = detect_coding_sjis; |
4553 |
| (NILP (flags[14]) ? 0 : CODING_FLAG_ISO_DESIGNATE_AT_BOL) |
coding->decoder = decode_coding_sjis; |
4554 |
| (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; |
|
4555 |
coding->common_flags |
coding->common_flags |
4556 |
|= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK; |
|= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK); |
4557 |
coding->flags |
} |
4558 |
= (NILP (XVECTOR (coding_spec)->contents[4]) |
else if (EQ (coding_type, Qbig5)) |
4559 |
? CODING_FLAG_BIG5_HKU |
{ |
4560 |
: CODING_FLAG_BIG5_ETEN); |
coding->detector = detect_coding_big5; |
4561 |
break; |
coding->decoder = decode_coding_big5; |
4562 |
|
coding->encoder = encode_coding_big5; |
|
case 4: |
|
|
coding->type = coding_type_ccl; |
|
4563 |
coding->common_flags |
coding->common_flags |
4564 |
|= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK; |
|= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK); |
|
{ |
|
|
val = XVECTOR (coding_spec)->contents[4]; |
|
|
if (! CONSP (val) |
|
|
|| setup_ccl_program (&(coding->spec.ccl.decoder), |
|
|
XCAR (val)) < 0 |
|
|
|| setup_ccl_program (&(coding->spec.ccl.encoder), |
|
|
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; |
|
4565 |
} |
} |
4566 |
return 0; |
else /* EQ (coding_type, Qraw_text) */ |
|
|
|
|
label_invalid_coding_system: |
|
|
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; |
|
|
} |
|
|
|
|
|
/* Free memory blocks allocated for storing composition information. */ |
|
|
|
|
|
void |
|
|
coding_free_composition_data (coding) |
|
|
struct coding_system *coding; |
|
|
{ |
|
|
struct composition_data *cmp_data = coding->cmp_data, *next; |
|
|
|
|
|
if (!cmp_data) |
|
|
return; |
|
|
/* Memory blocks are chained. At first, rewind to the first, then, |
|
|
free blocks one by one. */ |
|
|
while (cmp_data->prev) |
|
|
cmp_data = cmp_data->prev; |
|
|
while (cmp_data) |
|
4567 |
{ |
{ |
4568 |
next = cmp_data->next; |
coding->detector = NULL; |
4569 |
xfree (cmp_data); |
coding->decoder = decode_coding_raw_text; |
4570 |
cmp_data = next; |
coding->encoder = encode_coding_raw_text; |
4571 |
|
coding->common_flags |= CODING_FOR_UNIBYTE_MASK; |
4572 |
} |
} |
4573 |
coding->cmp_data = NULL; |
|
4574 |
|
return; |
4575 |
} |
} |
4576 |
|
|
4577 |
/* Set `char_offset' member of all memory blocks pointed by |
/* Return raw-text or one of its subsidiaries that has the same |
4578 |
coding->cmp_data to POS. */ |
eol_type as CODING-SYSTEM. */ |
4579 |
|
|
4580 |
void |
Lisp_Object |
4581 |
coding_adjust_composition_offset (coding, pos) |
raw_text_coding_system (coding_system) |
4582 |
struct coding_system *coding; |
Lisp_Object coding_system; |
|
int pos; |
|
4583 |
{ |
{ |
4584 |
struct composition_data *cmp_data; |
Lisp_Object spec, attrs, coding_type; |
4585 |
|
Lisp_Object eol_type, raw_text_eol_type; |
4586 |
|
|
4587 |
|
spec = CODING_SYSTEM_SPEC (coding_system); |
4588 |
|
attrs = AREF (spec, 0); |
4589 |
|
|
4590 |
|
if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text)) |
4591 |
|
return coding_system; |
4592 |
|
|
4593 |
for (cmp_data = coding->cmp_data; cmp_data; cmp_data = cmp_data->next) |
eol_type = AREF (spec, 2); |
4594 |
cmp_data->char_offset = pos; |
if (VECTORP (eol_type)) |
4595 |
|
return Qraw_text; |
4596 |
|
spec = CODING_SYSTEM_SPEC (Qraw_text); |
4597 |
|
raw_text_eol_type = AREF (spec, 2); |
4598 |
|
return (EQ (eol_type, Qunix) ? AREF (raw_text_eol_type, 0) |
4599 |
|
: EQ (eol_type, Qdos) ? AREF (raw_text_eol_type, 1) |
4600 |
|
: AREF (raw_text_eol_type, 2)); |
4601 |
} |
} |
4602 |
|
|
|
/* 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. */ |
|
4603 |
|
|
4604 |
void |
/* If CODING_SYSTEM doesn't specify end-of-line format but PARENT |
4605 |
setup_raw_text_coding_system (coding) |
does, return one of the subsidiary that has the same eol-spec as |
4606 |
struct coding_system *coding; |
PARENT. Otherwise, return CODING_SYSTEM. */ |
4607 |
|
|
4608 |
|
Lisp_Object |
4609 |
|
coding_inherit_eol_type (coding_system, parent) |
4610 |
{ |
{ |
4611 |
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); |
|
4612 |
|
|
4613 |
if (VECTORP (subsidiaries) |
spec = CODING_SYSTEM_SPEC (coding_system); |
4614 |
&& XVECTOR (subsidiaries)->size == 3) |
attrs = AREF (spec, 0); |
4615 |
coding->symbol |
eol_type = AREF (spec, 2); |
4616 |
= XVECTOR (subsidiaries)->contents[coding->eol_type]; |
if (VECTORP (eol_type)) |
4617 |
} |
{ |
4618 |
setup_coding_system (coding->symbol, coding); |
Lisp_Object parent_spec; |
4619 |
|
Lisp_Object parent_attrs; |
4620 |
|
Lisp_Object parent_eol_type; |
4621 |
|
|
4622 |
|
parent_spec |
4623 |
|
= CODING_SYSTEM_SPEC (buffer_defaults.buffer_file_coding_system); |
4624 |
|
parent_eol_type = AREF (parent_spec, 2); |
4625 |
|
if (EQ (parent_eol_type, Qunix)) |
4626 |
|
coding_system = AREF (eol_type, 0); |
4627 |
|
else if (EQ (parent_eol_type, Qdos)) |
4628 |
|
coding_system = AREF (eol_type, 1); |
4629 |
|
else if (EQ (parent_eol_type, Qmac)) |
4630 |
|
coding_system = AREF (eol_type, 2); |
4631 |
} |
} |
4632 |
return; |
return coding_system; |
4633 |
} |
} |
4634 |
|
|
4635 |
/* Emacs has a mechanism to automatically detect a coding system if it |
/* Emacs has a mechanism to automatically detect a coding system if it |
4682 |
o coding-category-iso-7-else |
o coding-category-iso-7-else |
4683 |
|
|
4684 |
The category for a coding system which has the same code range |
The category for a coding system which has the same code range |
4685 |
as ISO2022 of 7-bit environment but uses locking shift or |
as ISO2022 of 7-bit environemnt but uses locking shift or |
4686 |
single shift functions. Assigned the coding-system (Lisp |
single shift functions. Assigned the coding-system (Lisp |
4687 |
symbol) `iso-2022-7bit-lock' by default. |
symbol) `iso-2022-7bit-lock' by default. |
4688 |
|
|
4689 |
o coding-category-iso-8-else |
o coding-category-iso-8-else |
4690 |
|
|
4691 |
The category for a coding system which has the same code range |
The category for a coding system which has the same code range |
4692 |
as ISO2022 of 8-bit environment but uses locking shift or |
as ISO2022 of 8-bit environemnt but uses locking shift or |
4693 |
single shift functions. Assigned the coding-system (Lisp |
single shift functions. Assigned the coding-system (Lisp |
4694 |
symbol) `iso-2022-8bit-ss2' by default. |
symbol) `iso-2022-8bit-ss2' by default. |
4695 |
|
|
4732 |
`no-conversion' by default. |
`no-conversion' by default. |
4733 |
|
|
4734 |
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 |
4735 |
`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. |
4736 |
What Emacs does actually is to detect a category of coding system. |
What Emacs does actually is to detect a category of coding system. |
4737 |
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 |
4738 |
decide a single possible category, it selects a category of the |
decide only one possible category, it selects a category of the |
4739 |
highest priority. Priorities of categories are also specified by a |
highest priority. Priorities of categories are also specified by a |
4740 |
user in a Lisp variable `coding-category-list'. |
user in a Lisp variable `coding-category-list'. |
4741 |
|
|
4742 |
*/ |
*/ |
4743 |
|
|
4744 |
static |
#define EOL_SEEN_NONE 0 |
4745 |
int ascii_skip_code[256]; |
#define EOL_SEEN_LF 1 |
4746 |
|
#define EOL_SEEN_CR 2 |
4747 |
/* Detect how a text of length SRC_BYTES pointed by SOURCE is encoded. |
#define EOL_SEEN_CRLF 4 |
4748 |
If it detects possible coding systems, return an integer in which |
|
4749 |
appropriate flag bits are set. Flag bits are defined by macros |
/* Detect how end-of-line of a text of length CODING->src_bytes |
4750 |
CODING_CATEGORY_MASK_XXX in `coding.h'. If PRIORITIES is non-NULL, |
pointed by CODING->source is encoded. Return one of |
4751 |
it should point the table `coding_priorities'. In that case, only |
EOL_SEEN_XXX. */ |
|
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. |
|
4752 |
|
|
4753 |
How many ASCII characters are at the head is returned as *SKIP. */ |
#define MAX_EOL_CHECK_COUNT 3 |
4754 |
|
|
4755 |
static int |
static int |
4756 |
detect_coding_mask (source, src_bytes, priorities, skip, multibytep) |
detect_eol (coding, source, src_bytes) |
4757 |
|
struct coding_system *coding; |
4758 |
unsigned char *source; |
unsigned char *source; |
4759 |
int src_bytes, *priorities, *skip; |
EMACS_INT src_bytes; |
|
int multibytep; |
|
4760 |
{ |
{ |
4761 |
register unsigned char c; |
Lisp_Object attrs, coding_type; |
4762 |
unsigned char *src = source, *src_end = source + src_bytes; |
unsigned char *src = source, *src_end = src + src_bytes; |
4763 |
unsigned int mask, utf16_examined_p, iso2022_examined_p; |
unsigned char c; |
4764 |
int i; |
int total = 0; |
4765 |
|
int eol_seen = EOL_SEEN_NONE; |
4766 |
|
int first_eol_seen; |
4767 |
|
|
4768 |
/* At first, skip all ASCII characters and control characters except |
attrs = CODING_ID_ATTRS (coding->id); |
4769 |
for three ISO2022 specific control characters. */ |
coding_type = CODING_ATTR_TYPE (attrs); |
|
ascii_skip_code[ISO_CODE_SO] = 0; |
|
|
ascii_skip_code[ISO_CODE_SI] = 0; |
|
|
ascii_skip_code[ISO_CODE_ESC] = 0; |
|
|
|
|
|
label_loop_detect_coding: |
|
|
while (src < src_end && ascii_skip_code[*src]) src++; |
|
|
*skip = src - source; |
|
4770 |
|
|
4771 |
if (src >= src_end) |
if (EQ (coding_type, Qccl)) |
4772 |
/* We found nothing other than ASCII. There's nothing to do. */ |
{ |
4773 |
return 0; |
int msb, lsb; |
4774 |
|
|
4775 |
c = *src; |
msb = coding->spec.utf_16.endian == utf_16_little_endian; |
4776 |
/* The text seems to be encoded in some multilingual coding system. |
lsb = 1 - msb; |
4777 |
Now, try to find in which coding system the text is encoded. */ |
|
4778 |
if (c < 0x80) |
while (src + 1 < src_end) |
|
{ |
|
|
/* 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) |
|
4779 |
{ |
{ |
4780 |
for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++) |
c = src[lsb]; |
4781 |
|
if (src[msb] == 0 && (c == '\n' || c == '\r')) |
4782 |
{ |
{ |
4783 |
if (mask & priorities[i]) |
int this_eol; |
4784 |
return priorities[i]; |
|
4785 |
|
if (c == '\n') |
4786 |
|
this_eol = EOL_SEEN_LF; |
4787 |
|
else if (src + 3 >= src_end |
4788 |
|
|| src[msb + 2] != 0 |
4789 |
|
|| src[lsb + 2] != '\n') |
4790 |
|
this_eol = EOL_SEEN_CR; |
4791 |
|
else |
4792 |
|
this_eol = EOL_SEEN_CRLF; |
4793 |
|
|
4794 |
|
if (eol_seen == EOL_SEEN_NONE) |
4795 |
|
/* This is the first end-of-line. */ |
4796 |
|
eol_seen = this_eol; |
4797 |
|
else if (eol_seen != this_eol) |
4798 |
|
{ |
4799 |
|
/* The found type is different from what found before. */ |
4800 |
|
eol_seen = EOL_SEEN_LF; |
4801 |
|
break; |
4802 |
|
} |
4803 |
|
if (++total == MAX_EOL_CHECK_COUNT) |
4804 |
|
break; |
4805 |
} |
} |
4806 |
return CODING_CATEGORY_MASK_RAW_TEXT; |
src += 2; |
4807 |
} |
} |
4808 |
} |
} |
4809 |
else |
else |
4810 |
{ |
{ |
4811 |
int try; |
while (src < src_end) |
|
|
|
|
if (multibytep && c == LEADING_CODE_8_BIT_CONTROL) |
|
|
c = src[1] - 0x20; |
|
|
|
|
|
if (c < 0xA0) |
|
|
{ |
|
|
/* C is the first byte of SJIS character code, |
|
|
or a leading-code of Emacs' internal format (emacs-mule), |
|
|
or the first byte of UTF-16. */ |
|
|
try = (CODING_CATEGORY_MASK_SJIS |
|
|
| CODING_CATEGORY_MASK_EMACS_MULE |
|
|
| CODING_CATEGORY_MASK_UTF_16_BE |
|
|
| CODING_CATEGORY_MASK_UTF_16_LE); |
|
|
|
|
|
/* Or, if C is a special latin extra code, |
|
|
or is an ISO2022 specific control code of C1 (SS2 or SS3), |
|
|
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) |
|
4812 |
{ |
{ |
4813 |
for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++) |
c = *src++; |
4814 |
|
if (c == '\n' || c == '\r') |
4815 |
{ |
{ |
4816 |
if (!iso2022_examined_p |
int this_eol; |
4817 |
&& (priorities[i] & try & CODING_CATEGORY_MASK_ISO)) |
|
4818 |
{ |
if (c == '\n') |
4819 |
mask |= detect_coding_iso2022 (src, src_end, multibytep); |
this_eol = EOL_SEEN_LF; |
4820 |
iso2022_examined_p = 1; |
else if (src >= src_end || *src != '\n') |
4821 |
} |
this_eol = EOL_SEEN_CR; |
4822 |
else if (priorities[i] & try & CODING_CATEGORY_MASK_SJIS) |
else |
4823 |
mask |= detect_coding_sjis (src, src_end, multibytep); |
this_eol = EOL_SEEN_CRLF, src++; |
4824 |
else if (priorities[i] & try & CODING_CATEGORY_MASK_UTF_8) |
|
4825 |
mask |= detect_coding_utf_8 (src, src_end, multibytep); |
if (eol_seen == EOL_SEEN_NONE) |
4826 |
else if (!utf16_examined_p |
/* This is the first end-of-line. */ |
4827 |
&& (priorities[i] & try & |
eol_seen = this_eol; |
4828 |
CODING_CATEGORY_MASK_UTF_16_BE_LE)) |
else if (eol_seen != this_eol) |
4829 |
{ |
{ |
4830 |
mask |= detect_coding_utf_16 (src, src_end, multibytep); |
/* The found type is different from what found before. */ |
4831 |
utf16_examined_p = 1; |
eol_seen = EOL_SEEN_LF; |
4832 |
|
break; |
4833 |
} |
} |
4834 |
else if (priorities[i] & try & CODING_CATEGORY_MASK_BIG5) |
if (++total == MAX_EOL_CHECK_COUNT) |
4835 |
mask |= detect_coding_big5 (src, src_end, multibytep); |
break; |
4836 |
else if (priorities[i] & try & CODING_CATEGORY_MASK_EMACS_MULE) |
} |
4837 |
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); |
|
4838 |
} |
} |
4839 |
return (mask | CODING_CATEGORY_MASK_RAW_TEXT | CODING_CATEGORY_MASK_BINARY); |
return eol_seen; |
4840 |
} |
} |
4841 |
|
|
|
/* Detect how a text of length SRC_BYTES pointed by SRC is encoded. |
|
|
The information of the detected coding system is set in CODING. */ |
|
4842 |
|
|
4843 |
void |
static void |
4844 |
detect_coding (coding, src, src_bytes) |
adjust_coding_eol_type (coding, eol_seen) |
4845 |
struct coding_system *coding; |
struct coding_system *coding; |
4846 |
unsigned char *src; |
int eol_seen; |
|
int src_bytes; |
|
4847 |
{ |
{ |
4848 |
unsigned int idx; |
Lisp_Object eol_type, coding_system; |
4849 |
int skip, mask; |
|
4850 |
Lisp_Object val; |
eol_type = CODING_ID_EOL_TYPE (coding->id); |
4851 |
|
if (eol_seen & EOL_SEEN_LF) |
4852 |
val = Vcoding_category_list; |
coding->id = CODING_SYSTEM_ID (AREF (eol_type, 0)); |
4853 |
mask = detect_coding_mask (src, src_bytes, coding_priorities, &skip, |
else if (eol_type & EOL_SEEN_CRLF) |
4854 |
coding->src_multibyte); |
coding->id = CODING_SYSTEM_ID (AREF (eol_type, 1)); |
4855 |
coding->heading_ascii = skip; |
else if (eol_type & EOL_SEEN_CR) |
4856 |
|
coding->id = CODING_SYSTEM_ID (AREF (eol_type, 2)); |
4857 |
|
} |
4858 |
|
|
4859 |
|
/* Detect how a text specified in CODING is encoded. If a coding |
4860 |
|
system is detected, update fields of CODING by the detected coding |
4861 |
|
system. */ |
4862 |
|
|
4863 |
if (!mask) return; |
void |
4864 |
|
detect_coding (coding) |
4865 |
|
struct coding_system *coding; |
4866 |
|
{ |
4867 |
|
unsigned char *src, *src_end; |
4868 |
|
Lisp_Object attrs, coding_type; |
4869 |
|
|
4870 |
/* We found a single coding system of the highest priority in MASK. */ |
coding->consumed = coding->consumed_char = 0; |
4871 |
idx = 0; |
coding->produced = coding->produced_char = 0; |
4872 |
while (mask && ! (mask & 1)) mask >>= 1, idx++; |
coding_set_source (coding); |
|
if (! mask) |
|
|
idx = CODING_CATEGORY_IDX_RAW_TEXT; |
|
4873 |
|
|
4874 |
val = SYMBOL_VALUE (XVECTOR (Vcoding_category_table)->contents[idx]); |
src_end = coding->source + coding->src_bytes; |
4875 |
|
|
4876 |
if (coding->eol_type != CODING_EOL_UNDECIDED) |
/* If we have not yet decided the text encoding type, detect it |
4877 |
|
now. */ |
4878 |
|
if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qundecided)) |
4879 |
{ |
{ |
4880 |
Lisp_Object tmp; |
int mask = CATEGORY_MASK_ANY; |
4881 |
|
int c, i; |
|
tmp = Fget (val, Qeol_type); |
|
|
if (VECTORP (tmp)) |
|
|
val = XVECTOR (tmp)->contents[coding->eol_type]; |
|
|
} |
|
4882 |
|
|
4883 |
/* Setup this new coding system while preserving some slots. */ |
for (src = coding->source; src < src_end; src++) |
|
{ |
|
|
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; |
|
|
|
|
|
while (src < src_end && total < MAX_EOL_CHECK_COUNT) |
|
|
{ |
|
|
c = *src++; |
|
|
if (c == '\n' || c == '\r') |
|
4884 |
{ |
{ |
4885 |
if (*skip == 0) |
c = *src; |
4886 |
*skip = src - 1 - source; |
if (c & 0x80 || (c < 0x20 && (c == ISO_CODE_ESC |
4887 |
total++; |
|| c == ISO_CODE_SI |
4888 |
if (c == '\n') |
|| c == ISO_CODE_SO))) |
4889 |
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; |
|
|
} |
|
4890 |
} |
} |
4891 |
} |
coding->head_ascii = src - (coding->source + coding->consumed); |
4892 |
|
|
4893 |
if (*skip == 0) |
if (coding->head_ascii < coding->src_bytes) |
4894 |
*skip = src_end - source; |
{ |
4895 |
return eol_type; |
int detected = 0; |
|
} |
|
|
|
|
|
/* 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; |
|
4896 |
|
|
4897 |
*skip = 0; |
for (i = 0; i < coding_category_raw_text; i++) |
4898 |
|
{ |
4899 |
|
enum coding_category category = coding_priorities[i]; |
4900 |
|
struct coding_system *this = coding_categories + category; |
4901 |
|
|
4902 |
while ((src + 1) < src_end && total < MAX_EOL_CHECK_COUNT) |
if (category >= coding_category_raw_text |
4903 |
{ |
|| detected & (1 << category)) |
4904 |
c1 = (src[msb] << 8) | (src[lsb]); |
continue; |
|
src += 2; |
|
4905 |
|
|
4906 |
if (c1 == '\n' || c1 == '\r') |
if (this->id < 0) |
|
{ |
|
|
if (*skip == 0) |
|
|
*skip = src - 2 - source; |
|
|
total++; |
|
|
if (c1 == '\n') |
|
|
{ |
|
|
this_eol_type = CODING_EOL_LF; |
|
|
} |
|
|
else |
|
|
{ |
|
|
if ((src + 1) >= src_end) |
|
4907 |
{ |
{ |
4908 |
this_eol_type = CODING_EOL_CR; |
/* No coding system of this category is defined. */ |
4909 |
|
mask &= ~(1 << category); |
4910 |
} |
} |
4911 |
else |
else |
4912 |
{ |
{ |
4913 |
c2 = (src[msb] << 8) | (src[lsb]); |
detected |= detected_mask[category]; |
4914 |
if (c2 == '\n') |
if ((*(this->detector)) (coding, &mask)) |
4915 |
this_eol_type = CODING_EOL_CRLF, src += 2; |
break; |
|
else |
|
|
this_eol_type = CODING_EOL_CR; |
|
4916 |
} |
} |
4917 |
} |
} |
4918 |
|
if (! mask) |
4919 |
|
setup_coding_system (Qraw_text, coding); |
4920 |
|
else if (mask != CATEGORY_MASK_ANY) |
4921 |
|
for (i = 0; i < coding_category_raw_text; i++) |
4922 |
|
{ |
4923 |
|
enum coding_category category = coding_priorities[i]; |
4924 |
|
struct coding_system *this = coding_categories + category; |
4925 |
|
|
4926 |
if (eol_type == CODING_EOL_UNDECIDED) |
if (mask & (1 << category)) |
4927 |
/* This is the first end-of-line. */ |
{ |
4928 |
eol_type = this_eol_type; |
setup_coding_system (CODING_ID_NAME (this->id), coding); |
4929 |
else if (eol_type != this_eol_type) |
break; |
4930 |
{ |
} |
4931 |
/* The found type is different from what found before. */ |
} |
|
eol_type = CODING_EOL_INCONSISTENT; |
|
|
break; |
|
|
} |
|
4932 |
} |
} |
4933 |
} |
} |
4934 |
|
|
4935 |
if (*skip == 0) |
attrs = CODING_ID_ATTRS (coding->id); |
4936 |
*skip = src_end - source; |
coding_type = CODING_ATTR_TYPE (attrs); |
|
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. */ |
|
4937 |
|
|
4938 |
void |
/* If we have not yet decided the EOL type, detect it now. But, the |
4939 |
detect_eol (coding, src, src_bytes) |
detection is impossible for a CCL based coding system, in which |
4940 |
struct coding_system *coding; |
case, we detct the EOL type after decoding. */ |
4941 |
unsigned char *src; |
if (VECTORP (CODING_ID_EOL_TYPE (coding->id)) |
4942 |
int src_bytes; |
&& ! EQ (coding_type, Qccl)) |
|
{ |
|
|
Lisp_Object val; |
|
|
int skip; |
|
|
int eol_type; |
|
|
|
|
|
switch (coding->category_idx) |
|
4943 |
{ |
{ |
4944 |
case CODING_CATEGORY_IDX_UTF_16_BE: |
int eol_seen = detect_eol (coding, coding->source, coding->src_bytes); |
4945 |
eol_type = detect_eol_type_in_2_octet_form (src, src_bytes, &skip, 1); |
|
4946 |
break; |
if (eol_seen != EOL_SEEN_NONE) |
4947 |
case CODING_CATEGORY_IDX_UTF_16_LE: |
adjust_coding_eol_type (coding, eol_seen); |
|
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; |
|
4948 |
} |
} |
4949 |
|
} |
4950 |
|
|
|
if (coding->heading_ascii > skip) |
|
|
coding->heading_ascii = skip; |
|
|
else |
|
|
skip = coding->heading_ascii; |
|
4951 |
|
|
4952 |
if (eol_type == CODING_EOL_UNDECIDED) |
static void |
4953 |
return; |
decode_eol (coding) |
4954 |
if (eol_type == CODING_EOL_INCONSISTENT) |
struct coding_system *coding; |
4955 |
|
{ |
4956 |
|
if (VECTORP (CODING_ID_EOL_TYPE (coding->id))) |
4957 |
{ |
{ |
4958 |
#if 0 |
unsigned char *p = CHAR_POS_ADDR (coding->dst_pos); |
4959 |
/* This code is suppressed until we find a better way to |
unsigned char *pend = p + coding->produced; |
4960 |
distinguish raw text file and binary file. */ |
int eol_seen = EOL_SEEN_NONE; |
4961 |
|
|
4962 |
/* If we have already detected that the coding is raw-text, the |
for (; p < pend; p++) |
|
coding should actually be no-conversion. */ |
|
|
if (coding->type == coding_type_raw_text) |
|
4963 |
{ |
{ |
4964 |
setup_coding_system (Qno_conversion, coding); |
if (*p == '\n') |
4965 |
return; |
eol_seen |= EOL_SEEN_LF; |
4966 |
|
else if (*p == '\r') |
4967 |
|
{ |
4968 |
|
if (p + 1 < pend && *(p + 1) == '\n') |
4969 |
|
{ |
4970 |
|
eol_seen |= EOL_SEEN_CRLF; |
4971 |
|
p++; |
4972 |
|
} |
4973 |
|
else |
4974 |
|
eol_seen |= EOL_SEEN_CR; |
4975 |
|
} |
4976 |
} |
} |
4977 |
/* Else, let's decode only text code anyway. */ |
if (eol_seen != EOL_SEEN_NONE) |
4978 |
#endif /* 0 */ |
adjust_coding_eol_type (coding, eol_seen); |
|
eol_type = CODING_EOL_LF; |
|
4979 |
} |
} |
4980 |
|
|
4981 |
val = Fget (coding->symbol, Qeol_type); |
if (EQ (CODING_ID_EOL_TYPE (coding->id), Qmac)) |
|
if (VECTORP (val) && XVECTOR (val)->size == 3) |
|
4982 |
{ |
{ |
4983 |
int src_multibyte = coding->src_multibyte; |
unsigned char *p = CHAR_POS_ADDR (coding->dst_pos); |
4984 |
int dst_multibyte = coding->dst_multibyte; |
unsigned char *pend = p + coding->produced; |
4985 |
|
|
4986 |
setup_coding_system (XVECTOR (val)->contents[eol_type], coding); |
for (; p < pend; p++) |
4987 |
coding->src_multibyte = src_multibyte; |
if (*p == '\r') |
4988 |
coding->dst_multibyte = dst_multibyte; |
*p = '\n'; |
|
coding->heading_ascii = skip; |
|
4989 |
} |
} |
4990 |
} |
else if (EQ (CODING_ID_EOL_TYPE (coding->id), Qdos)) |
4991 |
|
{ |
4992 |
#define CONVERSION_BUFFER_EXTRA_ROOM 256 |
unsigned char *p, *pbeg, *pend; |
4993 |
|
Lisp_Object undo_list; |
|
#define DECODING_BUFFER_MAG(coding) \ |
|
|
(coding->type == coding_type_iso2022 \ |
|
|
? 3 \ |
|
|
: (coding->type == coding_type_ccl \ |
|
|
? coding->spec.ccl.decoder.buf_magnification \ |
|
|
: 2)) |
|
4994 |
|
|
4995 |
/* Return maximum size (bytes) of a buffer enough for decoding |
move_gap_both (coding->dst_pos + coding->produced_char, |
4996 |
SRC_BYTES of text encoded in CODING. */ |
coding->dst_pos_byte + coding->produced); |
4997 |
|
undo_list = current_buffer->undo_list; |
4998 |
|
current_buffer->undo_list = Qt; |
4999 |
|
del_range_2 (coding->dst_pos, coding->dst_pos_byte, GPT, GPT_BYTE, Qnil); |
5000 |
|
current_buffer->undo_list = undo_list; |
5001 |
|
pbeg = GPT_ADDR; |
5002 |
|
pend = pbeg + coding->produced; |
5003 |
|
|
5004 |
int |
for (p = pend - 1; p >= pbeg; p--) |
5005 |
decoding_buffer_size (coding, src_bytes) |
if (*p == '\r') |
5006 |
struct coding_system *coding; |
{ |
5007 |
int src_bytes; |
safe_bcopy ((char *) (p + 1), (char *) p, pend - p - 1); |
5008 |
{ |
pend--; |
5009 |
return (src_bytes * DECODING_BUFFER_MAG (coding) |
} |
5010 |
+ CONVERSION_BUFFER_EXTRA_ROOM); |
coding->produced_char -= coding->produced - (pend - pbeg); |
5011 |
|
coding->produced = pend - pbeg; |
5012 |
|
insert_from_gap (coding->produced_char, coding->produced); |
5013 |
|
} |
5014 |
} |
} |
5015 |
|
|
5016 |
/* Return maximum size (bytes) of a buffer enough for encoding |
static void |
5017 |
SRC_BYTES of text to CODING. */ |
translate_chars (coding, table) |
|
|
|
|
int |
|
|
encoding_buffer_size (coding, src_bytes) |
|
5018 |
struct coding_system *coding; |
struct coding_system *coding; |
5019 |
int src_bytes; |
Lisp_Object table; |
5020 |
{ |
{ |
5021 |
int magnification; |
int *charbuf = coding->charbuf; |
5022 |
|
int *charbuf_end = charbuf + coding->charbuf_used; |
5023 |
|
int c; |
5024 |
|
|
5025 |
if (coding->type == coding_type_ccl) |
if (coding->chars_at_source) |
5026 |
magnification = coding->spec.ccl.encoder.buf_magnification; |
return; |
|
else if (CODING_REQUIRE_ENCODING (coding)) |
|
|
magnification = 3; |
|
|
else |
|
|
magnification = 1; |
|
5027 |
|
|
5028 |
return (src_bytes * magnification + CONVERSION_BUFFER_EXTRA_ROOM); |
while (charbuf < charbuf_end) |
5029 |
|
{ |
5030 |
|
c = *charbuf; |
5031 |
|
if (c < 0) |
5032 |
|
charbuf += c; |
5033 |
|
else |
5034 |
|
*charbuf++ = translate_char (table, c); |
5035 |
|
} |
5036 |
} |
} |
5037 |
|
|
5038 |
/* Working buffer for code conversion. */ |
static int |
5039 |
struct conversion_buffer |
produce_chars (coding) |
5040 |
{ |
struct coding_system *coding; |
|
int size; /* size of data. */ |
|
|
int on_stack; /* 1 if allocated by alloca. */ |
|
|
unsigned char *data; |
|
|
}; |
|
|
|
|
|
/* Don't use alloca for allocating memory space larger than this, lest |
|
|
we overflow their stack. */ |
|
|
#define MAX_ALLOCA 16*1024 |
|
|
|
|
|
/* Allocate LEN bytes of memory for BUF (struct conversion_buffer). */ |
|
|
#define allocate_conversion_buffer(buf, len) \ |
|
|
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) |
|
|
|
|
|
/* Double the allocated memory for *BUF. */ |
|
|
static void |
|
|
extend_conversion_buffer (buf) |
|
|
struct conversion_buffer *buf; |
|
5041 |
{ |
{ |
5042 |
if (buf->on_stack) |
unsigned char *dst = coding->destination + coding->produced; |
5043 |
{ |
unsigned char *dst_end = coding->destination + coding->dst_bytes; |
5044 |
unsigned char *save = buf->data; |
int produced; |
5045 |
buf->data = (unsigned char *) xmalloc (buf->size * 2); |
int produced_chars = 0; |
5046 |
bcopy (save, buf->data, buf->size); |
|
5047 |
buf->on_stack = 0; |
if (! coding->chars_at_source) |
5048 |
|
{ |
5049 |
|
/* Characters are in coding->charbuf. */ |
5050 |
|
int *buf = coding->charbuf; |
5051 |
|
int *buf_end = buf + coding->charbuf_used; |
5052 |
|
unsigned char *adjusted_dst_end; |
5053 |
|
|
5054 |
|
if (BUFFERP (coding->src_object) |
5055 |
|
&& EQ (coding->src_object, coding->dst_object)) |
5056 |
|
dst_end = coding->source + coding->consumed; |
5057 |
|
adjusted_dst_end = dst_end - MAX_MULTIBYTE_LENGTH; |
5058 |
|
|
5059 |
|
while (buf < buf_end) |
5060 |
|
{ |
5061 |
|
int c = *buf++; |
5062 |
|
|
5063 |
|
if (dst >= adjusted_dst_end) |
5064 |
|
{ |
5065 |
|
dst = alloc_destination (coding, |
5066 |
|
buf_end - buf + MAX_MULTIBYTE_LENGTH, |
5067 |
|
dst); |
5068 |
|
dst_end = coding->destination + coding->dst_bytes; |
5069 |
|
adjusted_dst_end = dst_end - MAX_MULTIBYTE_LENGTH; |
5070 |
|
} |
5071 |
|
if (c >= 0) |
5072 |
|
{ |
5073 |
|
if (coding->dst_multibyte |
5074 |
|
|| ! CHAR_BYTE8_P (c)) |
5075 |
|
CHAR_STRING_ADVANCE (c, dst); |
5076 |
|
else |
5077 |
|
*dst++ = CHAR_TO_BYTE8 (c); |
5078 |
|
produced_chars++; |
5079 |
|
} |
5080 |
|
else |
5081 |
|
/* This is an annotation data. */ |
5082 |
|
buf -= c + 1; |
5083 |
|
} |
5084 |
} |
} |
5085 |
else |
else |
5086 |
{ |
{ |
5087 |
buf->data = (unsigned char *) xrealloc (buf->data, buf->size * 2); |
int multibytep = coding->src_multibyte; |
5088 |
} |
unsigned char *src = coding->source; |
5089 |
buf->size *= 2; |
unsigned char *src_end = src + coding->src_bytes; |
5090 |
} |
Lisp_Object eol_type; |
5091 |
|
|
5092 |
/* Free the allocated memory for BUF if it is not on stack. */ |
eol_type = CODING_ID_EOL_TYPE (coding->id); |
|
static void |
|
|
free_conversion_buffer (buf) |
|
|
struct conversion_buffer *buf; |
|
|
{ |
|
|
if (!buf->on_stack) |
|
|
xfree (buf->data); |
|
|
} |
|
5093 |
|
|
5094 |
int |
if (coding->src_multibyte != coding->dst_multibyte) |
5095 |
ccl_coding_driver (coding, source, destination, src_bytes, dst_bytes, encodep) |
{ |
5096 |
struct coding_system *coding; |
if (coding->src_multibyte) |
5097 |
unsigned char *source, *destination; |
{ |
5098 |
int src_bytes, dst_bytes, encodep; |
int consumed_chars; |
|
{ |
|
|
struct ccl_program *ccl |
|
|
= encodep ? &coding->spec.ccl.encoder : &coding->spec.ccl.decoder; |
|
|
unsigned char *dst = destination; |
|
5099 |
|
|
5100 |
ccl->suppress_error = coding->suppress_error; |
while (1) |
5101 |
ccl->last_block = coding->mode & CODING_MODE_LAST_BLOCK; |
{ |
5102 |
if (encodep) |
unsigned char *src_base = src; |
5103 |
{ |
int c; |
|
/* On encoding, EOL format is converted within ccl_driver. For |
|
|
that, setup proper information in the structure CCL. */ |
|
|
ccl->eol_type = coding->eol_type; |
|
|
if (ccl->eol_type ==CODING_EOL_UNDECIDED) |
|
|
ccl->eol_type = CODING_EOL_LF; |
|
|
ccl->cr_consumed = coding->spec.ccl.cr_carryover; |
|
|
} |
|
|
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); |
|
5104 |
|
|
5105 |
if (encodep) |
ONE_MORE_BYTE (c); |
5106 |
{ |
if (c == '\r') |
5107 |
coding->produced_char = coding->produced; |
{ |
5108 |
coding->spec.ccl.cr_carryover = ccl->cr_consumed; |
if (EQ (eol_type, Qdos)) |
5109 |
} |
{ |
5110 |
else if (!ccl->eight_bit_control) |
if (src < src_end |
5111 |
{ |
&& *src == '\n') |
5112 |
/* The produced bytes forms a valid multibyte sequence. */ |
c = *src++; |
5113 |
coding->produced_char |
} |
5114 |
= multibyte_chars_in_text (destination, coding->produced); |
else if (EQ (eol_type, Qmac)) |
5115 |
coding->spec.ccl.eight_bit_carryover[0] = 0; |
c = '\n'; |
5116 |
} |
} |
5117 |
else |
if (dst == dst_end) |
5118 |
{ |
{ |
5119 |
/* On decoding, the destination should always multibyte. But, |
EMACS_INT offset = src - coding->source; |
5120 |
CCL program might have been generated an invalid multibyte |
|
5121 |
sequence. Here we make such a sequence valid as |
dst = alloc_destination (coding, src_end - src + 1, dst); |
5122 |
multibyte. */ |
dst_end = coding->destination + coding->dst_bytes; |
5123 |
int bytes |
coding_set_source (coding); |
5124 |
= dst_bytes ? dst_bytes : source + coding->consumed - destination; |
src = coding->source + offset; |
5125 |
|
src_end = coding->source + coding->src_bytes; |
5126 |
if ((coding->consumed < src_bytes |
} |
5127 |
|| !ccl->last_block) |
*dst++ = c; |
5128 |
&& coding->produced >= 1 |
produced_chars++; |
5129 |
&& destination[coding->produced - 1] >= 0x80) |
} |
5130 |
{ |
no_more_source: |
5131 |
/* We should not convert the tailing 8-bit codes to |
; |
5132 |
multibyte form even if they doesn't form a valid |
} |
5133 |
multibyte sequence. They may form a valid sequence in |
else |
5134 |
the next call. */ |
while (src < src_end) |
5135 |
int carryover = 0; |
{ |
5136 |
|
int c = *src++; |
5137 |
if (destination[coding->produced - 1] < 0xA0) |
|
5138 |
carryover = 1; |
if (c == '\r') |
5139 |
else if (coding->produced >= 2) |
{ |
5140 |
|
if (EQ (eol_type, Qdos)) |
5141 |
|
{ |
5142 |
|
if (src < src_end |
5143 |
|
&& *src == '\n') |
5144 |
|
c = *src++; |
5145 |
|
} |
5146 |
|
else if (EQ (eol_type, Qmac)) |
5147 |
|
c = '\n'; |
5148 |
|
} |
5149 |
|
if (dst >= dst_end - 1) |
5150 |
|
{ |
5151 |
|
EMACS_INT offset = src - coding->source; |
5152 |
|
|
5153 |
|
dst = alloc_destination (coding, src_end - src + 2, dst); |
5154 |
|
dst_end = coding->destination + coding->dst_bytes; |
5155 |
|
coding_set_source (coding); |
5156 |
|
src = coding->source + offset; |
5157 |
|
src_end = coding->source + coding->src_bytes; |
5158 |
|
} |
5159 |
|
EMIT_ONE_BYTE (c); |
5160 |
|
} |
5161 |
|
} |
5162 |
|
else |
5163 |
|
{ |
5164 |
|
if (!EQ (coding->src_object, coding->dst_object)) |
5165 |
{ |
{ |
5166 |
if (destination[coding->produced - 2] >= 0x80) |
int require = coding->src_bytes - coding->dst_bytes; |
5167 |
|
|
5168 |
|
if (require > 0) |
5169 |
{ |
{ |
5170 |
if (destination[coding->produced - 2] < 0xA0) |
EMACS_INT offset = src - coding->source; |
5171 |
carryover = 2; |
|
5172 |
else if (coding->produced >= 3 |
dst = alloc_destination (coding, require, dst); |
5173 |
&& destination[coding->produced - 3] >= 0x80 |
coding_set_source (coding); |
5174 |
&& destination[coding->produced - 3] < 0xA0) |
src = coding->source + offset; |
5175 |
carryover = 3; |
src_end = coding->source + coding->src_bytes; |
5176 |
} |
} |
5177 |
} |
} |
5178 |
if (carryover > 0) |
produced_chars = coding->src_chars; |
5179 |
|
while (src < src_end) |
5180 |
{ |
{ |
5181 |
BCOPY_SHORT (destination + coding->produced - carryover, |
int c = *src++; |
5182 |
coding->spec.ccl.eight_bit_carryover, |
|
5183 |
carryover); |
if (c == '\r') |
5184 |
coding->spec.ccl.eight_bit_carryover[carryover] = 0; |
{ |
5185 |
coding->produced -= carryover; |
if (EQ (eol_type, Qdos)) |
5186 |
|
{ |
5187 |
|
if (src < src_end |
5188 |
|
&& *src == '\n') |
5189 |
|
c = *src++; |
5190 |
|
produced_chars--; |
5191 |
|
} |
5192 |
|
else if (EQ (eol_type, Qmac)) |
5193 |
|
c = '\n'; |
5194 |
|
} |
5195 |
|
*dst++ = c; |
5196 |
} |
} |
5197 |
} |
} |
|
coding->produced = str_as_multibyte (destination, bytes, |
|
|
coding->produced, |
|
|
&(coding->produced_char)); |
|
5198 |
} |
} |
5199 |
|
|
5200 |
switch (ccl->status) |
produced = dst - (coding->destination + coding->produced); |
5201 |
{ |
if (BUFFERP (coding->dst_object)) |
5202 |
case CCL_STAT_SUSPEND_BY_SRC: |
insert_from_gap (produced_chars, produced); |
5203 |
coding->result = CODING_FINISH_INSUFFICIENT_SRC; |
coding->produced += produced; |
5204 |
break; |
coding->produced_char += produced_chars; |
5205 |
case CCL_STAT_SUSPEND_BY_DST: |
return produced_chars; |
|
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; |
|
5206 |
} |
} |
5207 |
|
|
5208 |
/* Decode EOL format of the text at PTR of BYTES length destructively |
/* [ -LENGTH CHAR_POS_OFFSET MASK METHOD COMP_LEN ] |
5209 |
according to CODING->eol_type. This is called after the CCL |
or |
5210 |
program produced a decoded text at PTR. If we do CRLF->LF |
[ -LENGTH CHAR_POS_OFFSET MASK METHOD COMP_LEN COMPONENTS... ] |
5211 |
conversion, update CODING->produced and CODING->produced_char. */ |
*/ |
5212 |
|
|
5213 |
static void |
static INLINE void |
5214 |
decode_eol_post_ccl (coding, ptr, bytes) |
produce_composition (coding, charbuf) |
5215 |
struct coding_system *coding; |
struct coding_system *coding; |
5216 |
unsigned char *ptr; |
int *charbuf; |
|
int bytes; |
|
5217 |
{ |
{ |
5218 |
Lisp_Object val, saved_coding_symbol; |
Lisp_Object buffer; |
5219 |
unsigned char *pend = ptr + bytes; |
int len; |
5220 |
int dummy; |
EMACS_INT pos; |
5221 |
|
enum composition_method method; |
5222 |
/* Remember the current coding system symbol. We set it back when |
int cmp_len; |
5223 |
an inconsistent EOL is found so that `last-coding-system-used' is |
Lisp_Object components; |
5224 |
set to the coding system that doesn't specify EOL conversion. */ |
|
5225 |
saved_coding_symbol = coding->symbol; |
buffer = coding->dst_object; |
5226 |
|
len = -charbuf[0]; |
5227 |
|
pos = coding->dst_pos + charbuf[1]; |
5228 |
|
method = (enum composition_method) (charbuf[3]); |
5229 |
|
cmp_len = charbuf[4]; |
5230 |
|
|
5231 |
coding->spec.ccl.cr_carryover = 0; |
if (method == COMPOSITION_RELATIVE) |
5232 |
if (coding->eol_type == CODING_EOL_UNDECIDED) |
components = Qnil; |
5233 |
|
else |
5234 |
{ |
{ |
5235 |
/* Here, to avoid the call of setup_coding_system, we directly |
Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1]; |
5236 |
call detect_eol_type. */ |
int i; |
|
coding->eol_type = detect_eol_type (ptr, bytes, &dummy); |
|
|
if (coding->eol_type == CODING_EOL_INCONSISTENT) |
|
|
coding->eol_type = CODING_EOL_LF; |
|
|
if (coding->eol_type != CODING_EOL_UNDECIDED) |
|
|
{ |
|
|
val = Fget (coding->symbol, Qeol_type); |
|
|
if (VECTORP (val) && XVECTOR (val)->size == 3) |
|
|
coding->symbol = XVECTOR (val)->contents[coding->eol_type]; |
|
|
} |
|
|
coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL; |
|
|
} |
|
5237 |
|
|
5238 |
if (coding->eol_type == CODING_EOL_LF |
len -= 5; |
5239 |
|| coding->eol_type == CODING_EOL_UNDECIDED) |
charbuf += 5; |
5240 |
{ |
for (i = 0; i < len; i++) |
5241 |
/* We have nothing to do. */ |
args[i] = make_number (charbuf[i]); |
5242 |
ptr = pend; |
components = (method == COMPOSITION_WITH_ALTCHARS |
5243 |
|
? Fstring (len, args) : Fvector (len, args)); |
5244 |
} |
} |
5245 |
else if (coding->eol_type == CODING_EOL_CRLF) |
compose_text (pos, pos + cmp_len, components, Qnil, Qnil); |
5246 |
|
} |
5247 |
|
|
5248 |
|
static int * |
5249 |
|
save_composition_data (buf, buf_end, prop) |
5250 |
|
int *buf, *buf_end; |
5251 |
|
Lisp_Object prop; |
5252 |
|
{ |
5253 |
|
enum composition_method method = COMPOSITION_METHOD (prop); |
5254 |
|
int cmp_len = COMPOSITION_LENGTH (prop); |
5255 |
|
|
5256 |
|
if (buf + 4 + (MAX_COMPOSITION_COMPONENTS * 2 - 1) > buf_end) |
5257 |
|
return NULL; |
5258 |
|
|
5259 |
|
buf[1] = CODING_ANNOTATE_COMPOSITION_MASK; |
5260 |
|
buf[2] = method; |
5261 |
|
buf[3] = cmp_len; |
5262 |
|
|
5263 |
|
if (method == COMPOSITION_RELATIVE) |
5264 |
|
buf[0] = 4; |
5265 |
|
else |
5266 |
{ |
{ |
5267 |
unsigned char *pstart = ptr, *p = ptr; |
Lisp_Object components; |
5268 |
|
int len, i; |
5269 |
|
|
5270 |
if (! (coding->mode & CODING_MODE_LAST_BLOCK) |
components = COMPOSITION_COMPONENTS (prop); |
5271 |
&& *(pend - 1) == '\r') |
if (VECTORP (components)) |
5272 |
{ |
{ |
5273 |
/* If the last character is CR, we can't handle it here |
len = XVECTOR (components)->size; |
5274 |
because LF will be in the not-yet-decoded source text. |
for (i = 0; i < len; i++) |
5275 |
Recorded that the CR is not yet processed. */ |
buf[4 + i] = XINT (AREF (components, i)); |
|
coding->spec.ccl.cr_carryover = 1; |
|
|
coding->produced--; |
|
|
coding->produced_char--; |
|
|
pend--; |
|
5276 |
} |
} |
5277 |
while (ptr < pend) |
else if (STRINGP (components)) |
5278 |
{ |
{ |
5279 |
if (*ptr == '\r') |
int i_byte; |
|
{ |
|
|
if (ptr + 1 < pend && *(ptr + 1) == '\n') |
|
|
{ |
|
|
*p++ = '\n'; |
|
|
ptr += 2; |
|
|
} |
|
|
else |
|
|
{ |
|
|
if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL) |
|
|
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; |
|
5280 |
|
|
5281 |
undo_eol_conversion: |
len = XSTRING (components)->size; |
5282 |
/* We have faced with inconsistent EOL format at PTR. |
i = i_byte = 0; |
5283 |
Convert all LFs before PTR back to CRLFs. */ |
while (i < len) |
5284 |
for (p--, ptr--; p >= pstart; p--) |
FETCH_STRING_CHAR_ADVANCE (buf[4 + i], components, i, i_byte); |
|
{ |
|
|
if (*p == '\n') |
|
|
*ptr-- = '\n', *ptr-- = '\r'; |
|
|
else |
|
|
*ptr-- = *p; |
|
|
} |
|
|
/* If carryover is recorded, cancel it because we don't |
|
|
convert CRLF anymore. */ |
|
|
if (coding->spec.ccl.cr_carryover) |
|
|
{ |
|
|
coding->spec.ccl.cr_carryover = 0; |
|
|
coding->produced++; |
|
|
coding->produced_char++; |
|
|
pend++; |
|
|
} |
|
|
p = ptr = pend; |
|
|
coding->eol_type = CODING_EOL_LF; |
|
|
coding->symbol = saved_coding_symbol; |
|
5285 |
} |
} |
5286 |
if (p < pend) |
else if (INTEGERP (components)) |
5287 |
{ |
{ |
5288 |
/* As each two-byte sequence CRLF was converted to LF, (PEND |
len = 1; |
5289 |
- P) is the number of deleted characters. */ |
buf[4] = XINT (components); |
|
coding->produced -= pend - p; |
|
|
coding->produced_char -= pend - p; |
|
5290 |
} |
} |
5291 |
} |
else if (CONSP (components)) |
|
else /* i.e. coding->eol_type == CODING_EOL_CR */ |
|
|
{ |
|
|
unsigned char *p = ptr; |
|
|
|
|
|
for (; ptr < pend; ptr++) |
|
5292 |
{ |
{ |
5293 |
if (*ptr == '\r') |
for (len = 0; CONSP (components); |
5294 |
*ptr = '\n'; |
len++, components = XCDR (components)) |
5295 |
else if (*ptr == '\n' |
buf[4 + len] = XINT (XCAR (components)); |
|
&& coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL) |
|
|
{ |
|
|
for (; p < ptr; p++) |
|
|
{ |
|
|
if (*p == '\n') |
|
|
*p = '\r'; |
|
|
} |
|
|
ptr = pend; |
|
|
coding->eol_type = CODING_EOL_LF; |
|
|
coding->symbol = saved_coding_symbol; |
|
|
} |
|
5296 |
} |
} |
5297 |
|
else |
5298 |
|
abort (); |
5299 |
|
buf[0] = 4 + len; |
5300 |
} |
} |
5301 |
|
return (buf + buf[0]); |
5302 |
} |
} |
5303 |
|
|
5304 |
/* See "GENERAL NOTES about `decode_coding_XXX ()' functions". Before |
#define CHARBUF_SIZE 0x4000 |
|
decoding, it may detect coding system and format of end-of-line if |
|
|
those are not yet decided. The source should be unibyte, the |
|
|
result is multibyte if CODING->dst_multibyte is nonzero, else |
|
|
unibyte. */ |
|
5305 |
|
|
5306 |
int |
#define ALLOC_CONVERSION_WORK_AREA(coding) \ |
5307 |
decode_coding (coding, source, destination, src_bytes, dst_bytes) |
do { \ |
5308 |
|
int size = CHARBUF_SIZE;; \ |
5309 |
|
\ |
5310 |
|
coding->charbuf = NULL; \ |
5311 |
|
while (size > 1024) \ |
5312 |
|
{ \ |
5313 |
|
coding->charbuf = (int *) alloca (sizeof (int) * size); \ |
5314 |
|
if (coding->charbuf) \ |
5315 |
|
break; \ |
5316 |
|
size >>= 1; \ |
5317 |
|
} \ |
5318 |
|
if (! coding->charbuf) \ |
5319 |
|
{ \ |
5320 |
|
coding->result = CODING_RESULT_INSUFFICIENT_MEM; \ |
5321 |
|
return coding->result; \ |
5322 |
|
} \ |
5323 |
|
coding->charbuf_size = size; \ |
5324 |
|
} while (0) |
5325 |
|
|
5326 |
|
|
5327 |
|
static void |
5328 |
|
produce_annotation (coding) |
5329 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
5330 |
{ |
{ |
5331 |
if (coding->type == coding_type_undecided) |
int *charbuf = coding->charbuf; |
5332 |
detect_coding (coding, source, src_bytes); |
int *charbuf_end = charbuf + coding->charbuf_used; |
5333 |
|
|
5334 |
if (coding->eol_type == CODING_EOL_UNDECIDED |
while (charbuf < charbuf_end) |
|
&& coding->type != coding_type_ccl) |
|
5335 |
{ |
{ |
5336 |
detect_eol (coding, source, src_bytes); |
if (*charbuf >= 0) |
5337 |
/* We had better recover the original eol format if we |
charbuf++; |
5338 |
encounter an inconsistent eol format while decoding. */ |
else |
5339 |
coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL; |
{ |
5340 |
|
int len = -*charbuf; |
5341 |
|
switch (charbuf[2]) |
5342 |
|
{ |
5343 |
|
case CODING_ANNOTATE_COMPOSITION_MASK: |
5344 |
|
produce_composition (coding, charbuf); |
5345 |
|
break; |
5346 |
|
default: |
5347 |
|
abort (); |
5348 |
|
} |
5349 |
|
charbuf += len; |
5350 |
|
} |
5351 |
} |
} |
5352 |
|
} |
5353 |
|
|
5354 |
coding->produced = coding->produced_char = 0; |
/* Decode the data at CODING->src_object into CODING->dst_object. |
5355 |
coding->consumed = coding->consumed_char = 0; |
CODING->src_object is a buffer, a string, or nil. |
5356 |
coding->errors = 0; |
CODING->dst_object is a buffer. |
|
coding->result = CODING_FINISH_NORMAL; |
|
5357 |
|
|
5358 |
switch (coding->type) |
If CODING->src_object is a buffer, it must be the current buffer. |
5359 |
{ |
In this case, if CODING->src_pos is positive, it is a position of |
5360 |
case coding_type_sjis: |
the source text in the buffer, otherwise, the source text is in the |
5361 |
decode_coding_sjis_big5 (coding, source, destination, |
gap area of the buffer, and CODING->src_pos specifies the offset of |
5362 |
src_bytes, dst_bytes, 1); |
the text from GPT (which must be the same as PT). If this is the |
5363 |
break; |
same buffer as CODING->dst_object, CODING->src_pos must be |
5364 |
|
negative. |
5365 |
|
|
5366 |
case coding_type_iso2022: |
If CODING->src_object is a string, CODING->src_pos in an index to |
5367 |
decode_coding_iso2022 (coding, source, destination, |
that string. |
|
src_bytes, dst_bytes); |
|
|
break; |
|
5368 |
|
|
5369 |
case coding_type_big5: |
If CODING->src_object is nil, CODING->source must already point to |
5370 |
decode_coding_sjis_big5 (coding, source, destination, |
the non-relocatable memory area. In this case, CODING->src_pos is |
5371 |
src_bytes, dst_bytes, 0); |
an offset from CODING->source. |
|
break; |
|
5372 |
|
|
5373 |
case coding_type_emacs_mule: |
The decoded data is inserted at the current point of the buffer |
5374 |
decode_coding_emacs_mule (coding, source, destination, |
CODING->dst_object. |
5375 |
src_bytes, dst_bytes); |
*/ |
|
break; |
|
5376 |
|
|
5377 |
case coding_type_ccl: |
static int |
5378 |
if (coding->spec.ccl.cr_carryover) |
decode_coding (coding) |
5379 |
{ |
struct coding_system *coding; |
5380 |
/* Set the CR which is not processed by the previous call of |
{ |
5381 |
decode_eol_post_ccl in DESTINATION. */ |
Lisp_Object attrs; |
|
*destination = '\r'; |
|
|
coding->produced++; |
|
|
coding->produced_char++; |
|
|
dst_bytes--; |
|
|
} |
|
|
ccl_coding_driver (coding, source, |
|
|
destination + coding->spec.ccl.cr_carryover, |
|
|
src_bytes, dst_bytes, 0); |
|
|
if (coding->eol_type != CODING_EOL_LF) |
|
|
decode_eol_post_ccl (coding, destination, coding->produced); |
|
|
break; |
|
5382 |
|
|
5383 |
default: |
if (BUFFERP (coding->src_object) |
5384 |
decode_eol (coding, source, destination, src_bytes, dst_bytes); |
&& coding->src_pos > 0 |
5385 |
|
&& coding->src_pos < GPT |
5386 |
|
&& coding->src_pos + coding->src_chars > GPT) |
5387 |
|
move_gap_both (coding->src_pos, coding->src_pos_byte); |
5388 |
|
|
5389 |
|
if (BUFFERP (coding->dst_object)) |
5390 |
|
{ |
5391 |
|
if (current_buffer != XBUFFER (coding->dst_object)) |
5392 |
|
set_buffer_internal (XBUFFER (coding->dst_object)); |
5393 |
|
if (GPT != PT) |
5394 |
|
move_gap_both (PT, PT_BYTE); |
5395 |
} |
} |
5396 |
|
|
5397 |
if (coding->result == CODING_FINISH_INSUFFICIENT_SRC |
coding->consumed = coding->consumed_char = 0; |
5398 |
&& coding->mode & CODING_MODE_LAST_BLOCK |
coding->produced = coding->produced_char = 0; |
5399 |
&& coding->consumed == src_bytes) |
coding->chars_at_source = 0; |
5400 |
coding->result = CODING_FINISH_NORMAL; |
coding->result = CODING_RESULT_SUCCESS; |
5401 |
|
coding->errors = 0; |
5402 |
|
|
5403 |
if (coding->mode & CODING_MODE_LAST_BLOCK |
ALLOC_CONVERSION_WORK_AREA (coding); |
5404 |
&& coding->result == CODING_FINISH_INSUFFICIENT_SRC) |
|
5405 |
|
attrs = CODING_ID_ATTRS (coding->id); |
5406 |
|
|
5407 |
|
do |
5408 |
{ |
{ |
5409 |
unsigned char *src = source + coding->consumed; |
coding_set_source (coding); |
5410 |
unsigned char *dst = destination + coding->produced; |
coding->annotated = 0; |
5411 |
|
(*(coding->decoder)) (coding); |
5412 |
|
if (!NILP (CODING_ATTR_DECODE_TBL (attrs))) |
5413 |
|
translate_chars (CODING_ATTR_DECODE_TBL (attrs), coding); |
5414 |
|
coding_set_destination (coding); |
5415 |
|
produce_chars (coding); |
5416 |
|
if (coding->annotated) |
5417 |
|
produce_annotation (coding); |
5418 |
|
} |
5419 |
|
while (coding->consumed < coding->src_bytes |
5420 |
|
&& ! coding->result); |
5421 |
|
|
5422 |
|
if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qccl) |
5423 |
|
&& SYMBOLP (CODING_ID_EOL_TYPE (coding->id)) |
5424 |
|
&& ! EQ (CODING_ID_EOL_TYPE (coding->id), Qunix)) |
5425 |
|
decode_eol (coding); |
5426 |
|
|
5427 |
|
coding->carryover_bytes = 0; |
5428 |
|
if (coding->consumed < coding->src_bytes) |
5429 |
|
{ |
5430 |
|
int nbytes = coding->src_bytes - coding->consumed; |
5431 |
|
unsigned char *src; |
5432 |
|
|
5433 |
|
coding_set_source (coding); |
5434 |
|
coding_set_destination (coding); |
5435 |
|
src = coding->source + coding->consumed; |
5436 |
|
|
5437 |
|
if (coding->mode & CODING_MODE_LAST_BLOCK) |
5438 |
|
{ |
5439 |
|
/* Flush out unprocessed data as binary chars. We are sure |
5440 |
|
that the number of data is less than the size of |
5441 |
|
coding->charbuf. */ |
5442 |
|
int *charbuf = coding->charbuf; |
5443 |
|
|
5444 |
src_bytes -= coding->consumed; |
while (nbytes-- > 0) |
5445 |
coding->errors++; |
{ |
5446 |
if (COMPOSING_P (coding)) |
int c = *src++; |
5447 |
DECODE_COMPOSITION_END ('1'); |
*charbuf++ = (c & 0x80 ? - c : c); |
5448 |
while (src_bytes--) |
} |
5449 |
|
produce_chars (coding); |
5450 |
|
} |
5451 |
|
else |
5452 |
{ |
{ |
5453 |
int c = *src++; |
/* Record unprocessed bytes in coding->carryover. We are |
5454 |
dst += CHAR_STRING (c, dst); |
sure that the number of data is less than the size of |
5455 |
coding->produced_char++; |
coding->carryover. */ |
5456 |
|
unsigned char *p = coding->carryover; |
5457 |
|
|
5458 |
|
coding->carryover_bytes = nbytes; |
5459 |
|
while (nbytes-- > 0) |
5460 |
|
*p++ = *src++; |
5461 |
} |
} |
5462 |
coding->consumed = coding->consumed_char = src - source; |
coding->consumed = coding->src_bytes; |
|
coding->produced = dst - destination; |
|
|
coding->result = CODING_FINISH_NORMAL; |
|
5463 |
} |
} |
5464 |
|
|
5465 |
if (!coding->dst_multibyte) |
if (BUFFERP (coding->dst_object)) |
5466 |
{ |
{ |
5467 |
coding->produced = str_as_unibyte (destination, coding->produced); |
record_insert (coding->dst_pos, coding->produced_char); |
|
coding->produced_char = coding->produced; |
|
5468 |
} |
} |
5469 |
|
|
5470 |
return coding->result; |
return coding->result; |
5471 |
} |
} |
5472 |
|
|
5473 |
/* See "GENERAL NOTES about `encode_coding_XXX ()' functions". The |
static void |
5474 |
multibyteness of the source is CODING->src_multibyte, the |
consume_chars (coding) |
|
multibyteness of the result is always unibyte. */ |
|
|
|
|
|
int |
|
|
encode_coding (coding, source, destination, src_bytes, dst_bytes) |
|
5475 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *source, *destination; |
|
|
int src_bytes, dst_bytes; |
|
5476 |
{ |
{ |
5477 |
coding->produced = coding->produced_char = 0; |
int *buf = coding->charbuf; |
5478 |
coding->consumed = coding->consumed_char = 0; |
/* -1 is to compensate for CRLF. */ |
5479 |
coding->errors = 0; |
int *buf_end = coding->charbuf + coding->charbuf_size - 1; |
5480 |
coding->result = CODING_FINISH_NORMAL; |
unsigned char *src = coding->source + coding->consumed; |
5481 |
|
int pos = coding->src_pos + coding->consumed_char; |
5482 |
switch (coding->type) |
int end_pos = coding->src_pos + coding->src_chars; |
5483 |
{ |
int multibytep = coding->src_multibyte; |
5484 |
case coding_type_sjis: |
Lisp_Object eol_type; |
5485 |
encode_coding_sjis_big5 (coding, source, destination, |
int c; |
5486 |
src_bytes, dst_bytes, 1); |
int start, end, stop; |
5487 |
break; |
Lisp_Object object, prop; |
|
|
|
|
case coding_type_iso2022: |
|
|
encode_coding_iso2022 (coding, source, destination, |
|
|
src_bytes, dst_bytes); |
|
|
break; |
|
5488 |
|
|
5489 |
case coding_type_big5: |
eol_type = CODING_ID_EOL_TYPE (coding->id); |
5490 |
encode_coding_sjis_big5 (coding, source, destination, |
if (VECTORP (eol_type)) |
5491 |
src_bytes, dst_bytes, 0); |
eol_type = Qunix; |
|
break; |
|
5492 |
|
|
5493 |
case coding_type_emacs_mule: |
object = coding->src_object; |
|
encode_coding_emacs_mule (coding, source, destination, |
|
|
src_bytes, dst_bytes); |
|
|
break; |
|
5494 |
|
|
5495 |
case coding_type_ccl: |
/* Note: composition handling is not yet implemented. */ |
5496 |
ccl_coding_driver (coding, source, destination, |
coding->common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK; |
|
src_bytes, dst_bytes, 1); |
|
|
break; |
|
5497 |
|
|
5498 |
default: |
if (coding->common_flags & CODING_ANNOTATE_COMPOSITION_MASK |
5499 |
encode_eol (coding, source, destination, src_bytes, dst_bytes); |
&& find_composition (pos, end_pos, &start, &end, &prop, object) |
5500 |
} |
&& end <= end_pos |
5501 |
|
&& (start >= pos |
5502 |
|
|| (find_composition (end, end_pos, &start, &end, &prop, object) |
5503 |
|
&& end <= end_pos))) |
5504 |
|
stop = start; |
5505 |
|
else |
5506 |
|
stop = end_pos; |
5507 |
|
|
5508 |
if (coding->mode & CODING_MODE_LAST_BLOCK |
while (buf < buf_end) |
|
&& coding->result == CODING_FINISH_INSUFFICIENT_SRC) |
|
5509 |
{ |
{ |
5510 |
unsigned char *src = source + coding->consumed; |
if (pos == stop) |
|
unsigned char *dst = destination + coding->produced; |
|
|
|
|
|
if (coding->type == coding_type_iso2022) |
|
|
ENCODE_RESET_PLANE_AND_REGISTER; |
|
|
if (COMPOSING_P (coding)) |
|
|
*dst++ = ISO_CODE_ESC, *dst++ = '1'; |
|
|
if (coding->consumed < src_bytes) |
|
5511 |
{ |
{ |
5512 |
int len = src_bytes - coding->consumed; |
int *p; |
5513 |
|
|
5514 |
BCOPY_SHORT (src, dst, len); |
if (pos == end_pos) |
5515 |
if (coding->src_multibyte) |
break; |
5516 |
len = str_as_unibyte (dst, len); |
p = save_composition_data (buf, buf_end, prop); |
5517 |
dst += len; |
if (p == NULL) |
5518 |
coding->consumed = src_bytes; |
break; |
5519 |
|
buf = p; |
5520 |
|
if (find_composition (end, end_pos, &start, &end, &prop, object) |
5521 |
|
&& end <= end_pos) |
5522 |
|
stop = start; |
5523 |
|
else |
5524 |
|
stop = end_pos; |
5525 |
} |
} |
|
coding->produced = coding->produced_char = dst - destination; |
|
|
coding->result = CODING_FINISH_NORMAL; |
|
|
} |
|
5526 |
|
|
5527 |
if (coding->result == CODING_FINISH_INSUFFICIENT_SRC |
if (! multibytep) |
5528 |
&& coding->consumed == src_bytes) |
c = *src++; |
5529 |
coding->result = CODING_FINISH_NORMAL; |
else |
5530 |
|
c = STRING_CHAR_ADVANCE (src); |
5531 |
|
if ((c == '\r') && (coding->mode & CODING_MODE_SELECTIVE_DISPLAY)) |
5532 |
|
c = '\n'; |
5533 |
|
if (! EQ (eol_type, Qunix)) |
5534 |
|
{ |
5535 |
|
if (c == '\n') |
5536 |
|
{ |
5537 |
|
if (EQ (eol_type, Qdos)) |
5538 |
|
*buf++ = '\r'; |
5539 |
|
else |
5540 |
|
c = '\r'; |
5541 |
|
} |
5542 |
|
} |
5543 |
|
*buf++ = c; |
5544 |
|
pos++; |
5545 |
|
} |
5546 |
|
|
5547 |
return coding->result; |
coding->consumed = src - coding->source; |
5548 |
|
coding->consumed_char = pos - coding->src_pos; |
5549 |
|
coding->charbuf_used = buf - coding->charbuf; |
5550 |
|
coding->chars_at_source = 0; |
5551 |
} |
} |
5552 |
|
|
|
/* 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. |
|
5553 |
|
|
5554 |
If STR is not NULL, *BEG and *END are indices into STR. */ |
/* Encode the text at CODING->src_object into CODING->dst_object. |
5555 |
|
CODING->src_object is a buffer or a string. |
5556 |
|
CODING->dst_object is a buffer or nil. |
5557 |
|
|
5558 |
static void |
If CODING->src_object is a buffer, it must be the current buffer. |
5559 |
shrink_decoding_region (beg, end, coding, str) |
In this case, if CODING->src_pos is positive, it is a position of |
5560 |
int *beg, *end; |
the source text in the buffer, otherwise. the source text is in the |
5561 |
|
gap area of the buffer, and coding->src_pos specifies the offset of |
5562 |
|
the text from GPT (which must be the same as PT). If this is the |
5563 |
|
same buffer as CODING->dst_object, CODING->src_pos must be |
5564 |
|
negative and CODING should not have `pre-write-conversion'. |
5565 |
|
|
5566 |
|
If CODING->src_object is a string, CODING should not have |
5567 |
|
`pre-write-conversion'. |
5568 |
|
|
5569 |
|
If CODING->dst_object is a buffer, the encoded data is inserted at |
5570 |
|
the current point of that buffer. |
5571 |
|
|
5572 |
|
If CODING->dst_object is nil, the encoded data is placed at the |
5573 |
|
memory area specified by CODING->destination. */ |
5574 |
|
|
5575 |
|
static int |
5576 |
|
encode_coding (coding) |
5577 |
struct coding_system *coding; |
struct coding_system *coding; |
|
unsigned char *str; |
|
5578 |
{ |
{ |
5579 |
unsigned char *begp_orig, *begp, *endp_orig, *endp, c; |
int error = 0; |
5580 |
int eol_conversion; |
Lisp_Object attrs; |
|
Lisp_Object translation_table; |
|
5581 |
|
|
5582 |
if (coding->type == coding_type_ccl |
attrs = CODING_ID_ATTRS (coding->id); |
|
|| 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; |
|
|
} |
|
5583 |
|
|
5584 |
translation_table = coding->translation_table_for_decode; |
if (BUFFERP (coding->dst_object)) |
|
if (NILP (translation_table) && !NILP (Venable_character_translation)) |
|
|
translation_table = Vstandard_translation_table_for_decode; |
|
|
if (CHAR_TABLE_P (translation_table)) |
|
5585 |
{ |
{ |
5586 |
int i; |
set_buffer_internal (XBUFFER (coding->dst_object)); |
5587 |
for (i = 0; i < 128; i++) |
coding->dst_multibyte |
5588 |
if (!NILP (CHAR_TABLE_REF (translation_table, i))) |
= ! NILP (current_buffer->enable_multibyte_characters); |
|
break; |
|
|
if (i < 128) |
|
|
/* Some ASCII character should be translated. We give up |
|
|
shrinking. */ |
|
|
return; |
|
5589 |
} |
} |
5590 |
|
|
5591 |
if (coding->heading_ascii >= 0) |
coding->consumed = coding->consumed_char = 0; |
5592 |
/* Detection routine has already found how much we can skip at the |
coding->produced = coding->produced_char = 0; |
5593 |
head. */ |
coding->result = CODING_RESULT_SUCCESS; |
5594 |
*beg += coding->heading_ascii; |
coding->errors = 0; |
5595 |
|
|
5596 |
if (str) |
ALLOC_CONVERSION_WORK_AREA (coding); |
|
{ |
|
|
begp_orig = begp = str + *beg; |
|
|
endp_orig = endp = str + *end; |
|
|
} |
|
|
else |
|
|
{ |
|
|
begp_orig = begp = BYTE_POS_ADDR (*beg); |
|
|
endp_orig = endp = begp + *end - *beg; |
|
|
} |
|
5597 |
|
|
5598 |
eol_conversion = (coding->eol_type == CODING_EOL_CR |
do { |
5599 |
|| coding->eol_type == CODING_EOL_CRLF); |
coding_set_source (coding); |
5600 |
|
consume_chars (coding); |
5601 |
|
|
5602 |
switch (coding->type) |
if (!NILP (CODING_ATTR_ENCODE_TBL (attrs))) |
5603 |
{ |
translate_chars (CODING_ATTR_ENCODE_TBL (attrs), coding); |
|
case coding_type_sjis: |
|
|
case coding_type_big5: |
|
|
/* We can skip all ASCII characters at the head. */ |
|
|
if (coding->heading_ascii < 0) |
|
|
{ |
|
|
if (eol_conversion) |
|
|
while (begp < endp && *begp < 0x80 && *begp != '\r') begp++; |
|
|
else |
|
|
while (begp < endp && *begp < 0x80) begp++; |
|
|
} |
|
|
/* 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; |
|
5604 |
|
|
5605 |
case coding_type_iso2022: |
coding_set_destination (coding); |
5606 |
if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, 0) != CHARSET_ASCII) |
(*(coding->encoder)) (coding); |
5607 |
/* We can't skip any data. */ |
} while (coding->consumed_char < coding->src_chars); |
|
break; |
|
|
if (coding->heading_ascii < 0) |
|
|
{ |
|
|
/* 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; |
|
5608 |
|
|
5609 |
case CODING_CATEGORY_IDX_ISO_7: |
if (BUFFERP (coding->dst_object)) |
5610 |
case CODING_CATEGORY_IDX_ISO_7_TIGHT: |
insert_from_gap (coding->produced_char, coding->produced); |
|
{ |
|
|
/* 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') |
|
|
{ |
|
|
if (!eight_bit && c & 0x80) eight_bit = endp; |
|
|
endp--; |
|
|
} |
|
|
else |
|
|
while (begp < endp |
|
|
&& (c = endp[-1]) != ISO_CODE_ESC) |
|
|
{ |
|
|
if (!eight_bit && c & 0x80) eight_bit = endp; |
|
|
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[-1] == ISO_CODE_ESC) |
|
|
{ |
|
|
if (endp + 1 < endp_orig && end[0] == '(' && end[1] == 'B') |
|
|
/* This is an ASCII designation sequence. We can |
|
|
surely skip the tail. But, if we have |
|
|
encountered an 8-bit code, skip only the codes |
|
|
after that. */ |
|
|
endp = eight_bit ? eight_bit : endp + 2; |
|
|
else |
|
|
/* Hmmm, we can't skip the tail. */ |
|
|
endp = endp_orig; |
|
|
} |
|
|
else if (eight_bit) |
|
|
endp = eight_bit; |
|
|
} |
|
|
} |
|
|
break; |
|
5611 |
|
|
5612 |
default: |
return (coding->result); |
|
abort (); |
|
|
} |
|
|
*beg += begp - begp_orig; |
|
|
*end += endp - endp_orig; |
|
|
return; |
|
5613 |
} |
} |
5614 |
|
|
5615 |
/* Like shrink_decoding_region but for encoding. */ |
/* Work buffer */ |
5616 |
|
|
5617 |
static void |
/* List of currently used working buffer. */ |
5618 |
shrink_encoding_region (beg, end, coding, str) |
Lisp_Object Vcode_conversion_work_buf_list; |
|
int *beg, *end; |
|
|
struct coding_system *coding; |
|
|
unsigned char *str; |
|
|
{ |
|
|
unsigned char *begp_orig, *begp, *endp_orig, *endp; |
|
|
int eol_conversion; |
|
|
Lisp_Object translation_table; |
|
5619 |
|
|
5620 |
if (coding->type == coding_type_ccl |
/* A working buffer used by the top level conversion. */ |
5621 |
|| coding->eol_type == CODING_EOL_CRLF |
Lisp_Object Vcode_conversion_reused_work_buf; |
|
|| coding->eol_type == CODING_EOL_CR |
|
|
|| (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; |
|
|
} |
|
5622 |
|
|
|
translation_table = coding->translation_table_for_encode; |
|
|
if (NILP (translation_table) && !NILP (Venable_character_translation)) |
|
|
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; |
|
|
} |
|
5623 |
|
|
5624 |
if (str) |
/* Return a working buffer that can be freely used by the following |
5625 |
|
code conversion. MULTIBYTEP specifies the multibyteness of the |
5626 |
|
buffer. */ |
5627 |
|
|
5628 |
|
Lisp_Object |
5629 |
|
make_conversion_work_buffer (multibytep) |
5630 |
|
int multibytep; |
5631 |
|
{ |
5632 |
|
struct buffer *current = current_buffer; |
5633 |
|
Lisp_Object buf; |
5634 |
|
|
5635 |
|
if (NILP (Vcode_conversion_work_buf_list)) |
5636 |
{ |
{ |
5637 |
begp_orig = begp = str + *beg; |
if (NILP (Vcode_conversion_reused_work_buf)) |
5638 |
endp_orig = endp = str + *end; |
Vcode_conversion_reused_work_buf |
5639 |
|
= Fget_buffer_create (build_string (" *code-conversion-work*")); |
5640 |
|
Vcode_conversion_work_buf_list |
5641 |
|
= Fcons (Vcode_conversion_reused_work_buf, Qnil); |
5642 |
} |
} |
5643 |
else |
else |
5644 |
{ |
{ |
5645 |
begp_orig = begp = BYTE_POS_ADDR (*beg); |
int depth = Flength (Vcode_conversion_work_buf_list); |
5646 |
endp_orig = endp = begp + *end - *beg; |
char str[128]; |
5647 |
|
|
5648 |
|
sprintf (str, " *code-conversion-work*<%d>", depth); |
5649 |
|
Vcode_conversion_work_buf_list |
5650 |
|
= Fcons (Fget_buffer_create (build_string (str)), |
5651 |
|
Vcode_conversion_work_buf_list); |
5652 |
} |
} |
5653 |
|
|
5654 |
eol_conversion = (coding->eol_type == CODING_EOL_CR |
buf = XCAR (Vcode_conversion_work_buf_list); |
5655 |
|| coding->eol_type == CODING_EOL_CRLF); |
set_buffer_internal (XBUFFER (buf)); |
5656 |
|
current_buffer->undo_list = Qt; |
5657 |
|
Ferase_buffer (); |
5658 |
|
Fset_buffer_multibyte (multibytep ? Qt : Qnil); |
5659 |
|
set_buffer_internal (current); |
5660 |
|
return buf; |
5661 |
|
} |
5662 |
|
|
5663 |
/* Here, we don't have to check coding->pre_write_conversion because |
static struct coding_system *saved_coding; |
|
the caller is expected to have handled it already. */ |
|
|
switch (coding->type) |
|
|
{ |
|
|
case coding_type_iso2022: |
|
|
if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, 0) != CHARSET_ASCII) |
|
|
/* We can't skip any data. */ |
|
|
break; |
|
|
if (coding->flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL) |
|
|
{ |
|
|
unsigned char *bol = begp; |
|
|
while (begp < endp && *begp < 0x80) |
|
|
{ |
|
|
begp++; |
|
|
if (begp[-1] == '\n') |
|
|
bol = begp; |
|
|
} |
|
|
begp = bol; |
|
|
goto label_skip_tail; |
|
|
} |
|
|
/* fall down ... */ |
|
5664 |
|
|
5665 |
case coding_type_sjis: |
Lisp_Object |
5666 |
case coding_type_big5: |
code_conversion_restore (info) |
5667 |
/* We can skip all ASCII characters at the head and tail. */ |
Lisp_Object info; |
5668 |
if (eol_conversion) |
{ |
5669 |
while (begp < endp && *begp < 0x80 && *begp != '\n') begp++; |
int depth = Flength (Vcode_conversion_work_buf_list); |
5670 |
else |
Lisp_Object buf; |
|
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; |
|
5671 |
|
|
5672 |
default: |
if (depth > 0) |
5673 |
abort (); |
{ |
5674 |
|
buf = XCAR (Vcode_conversion_work_buf_list); |
5675 |
|
Vcode_conversion_work_buf_list = XCDR (Vcode_conversion_work_buf_list); |
5676 |
|
if (depth > 1 && !NILP (Fbuffer_live_p (buf))) |
5677 |
|
Fkill_buffer (buf); |
5678 |
} |
} |
5679 |
|
|
5680 |
*beg += begp - begp_orig; |
if (saved_coding->dst_object == Qt |
5681 |
*end += endp - endp_orig; |
&& saved_coding->destination) |
5682 |
return; |
xfree (saved_coding->destination); |
|
} |
|
|
|
|
|
/* 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; |
|
5683 |
|
|
5684 |
#define SHRINK_CONVERSION_REGION(beg, end, coding, str, encodep) \ |
return save_excursion_restore (info); |
|
do { \ |
|
|
if (*(end) - *(beg) > shrink_conversion_region_threshhold) \ |
|
|
{ \ |
|
|
if (encodep) shrink_encoding_region (beg, end, coding, str); \ |
|
|
else shrink_decoding_region (beg, end, coding, str); \ |
|
|
} \ |
|
|
} while (0) |
|
|
|
|
|
static Lisp_Object |
|
|
code_convert_region_unwind (dummy) |
|
|
Lisp_Object dummy; |
|
|
{ |
|
|
inhibit_pre_post_conversion = 0; |
|
|
return Qnil; |
|
5685 |
} |
} |
5686 |
|
|
|
/* Store information about all compositions in the range FROM and TO |
|
|
of OBJ in memory blocks pointed by CODING->cmp_data. OBJ is a |
|
|
buffer or a string, defaults to the current buffer. */ |
|
5687 |
|
|
5688 |
void |
int |
5689 |
coding_save_composition (coding, from, to, obj) |
decode_coding_gap (coding, chars, bytes) |
5690 |
struct coding_system *coding; |
struct coding_system *coding; |
5691 |
int from, to; |
EMACS_INT chars, bytes; |
|
Lisp_Object obj; |
|
5692 |
{ |
{ |
5693 |
Lisp_Object prop; |
int count = specpdl_ptr - specpdl; |
|
int start, end; |
|
5694 |
|
|
5695 |
if (coding->composing == COMPOSITION_DISABLED) |
saved_coding = coding; |
5696 |
return; |
record_unwind_protect (code_conversion_restore, save_excursion_save ()); |
|
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; |
|
5697 |
|
|
5698 |
val = COMPOSITION_COMPONENTS (prop); |
coding->src_object = Fcurrent_buffer (); |
5699 |
if (CONSP (val)) |
coding->src_chars = chars; |
5700 |
while (CONSP (val)) |
coding->src_bytes = bytes; |
5701 |
{ |
coding->src_pos = -chars; |
5702 |
ch = XCAR (val), val = XCDR (val); |
coding->src_pos_byte = -bytes; |
5703 |
CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (ch)); |
coding->src_multibyte = chars < bytes; |
5704 |
} |
coding->dst_object = coding->src_object; |
5705 |
else if (VECTORP (val) || STRINGP (val)) |
coding->dst_pos = PT; |
5706 |
{ |
coding->dst_pos_byte = PT_BYTE; |
|
int len = (VECTORP (val) |
|
|
? XVECTOR (val)->size : XSTRING (val)->size); |
|
|
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; |
|
|
} |
|
|
while (start < to |
|
|
&& find_composition (start, to, &start, &end, &prop, obj) |
|
|
&& end <= to); |
|
5707 |
|
|
5708 |
/* Make coding->cmp_data point to the first memory block. */ |
if (CODING_REQUIRE_DETECTION (coding)) |
5709 |
while (coding->cmp_data->prev) |
detect_coding (coding); |
5710 |
coding->cmp_data = coding->cmp_data->prev; |
|
5711 |
coding->cmp_data_start = 0; |
decode_coding (coding); |
|
} |
|
5712 |
|
|
5713 |
/* Reflect the saved information about compositions to OBJ. |
unbind_to (count, Qnil); |
5714 |
CODING->cmp_data points to a memory block for the information. OBJ |
return coding->result; |
5715 |
is a buffer or a string, defaults to the current buffer. */ |
} |
5716 |
|
|
5717 |
void |
int |
5718 |
coding_restore_composition (coding, obj) |
encode_coding_gap (coding, chars, bytes) |
5719 |
struct coding_system *coding; |
struct coding_system *coding; |
5720 |
Lisp_Object obj; |
EMACS_INT chars, bytes; |
5721 |
{ |
{ |
5722 |
struct composition_data *cmp_data = coding->cmp_data; |
int count = specpdl_ptr - specpdl; |
5723 |
|
Lisp_Object buffer; |
5724 |
|
|
5725 |
if (!cmp_data) |
saved_coding = coding; |
5726 |
return; |
record_unwind_protect (code_conversion_restore, save_excursion_save ()); |
5727 |
|
|
5728 |
while (cmp_data->prev) |
buffer = Fcurrent_buffer (); |
5729 |
cmp_data = cmp_data->prev; |
coding->src_object = buffer; |
5730 |
|
coding->src_chars = chars; |
5731 |
|
coding->src_bytes = bytes; |
5732 |
|
coding->src_pos = -chars; |
5733 |
|
coding->src_pos_byte = -bytes; |
5734 |
|
coding->src_multibyte = chars < bytes; |
5735 |
|
coding->dst_object = coding->src_object; |
5736 |
|
coding->dst_pos = PT; |
5737 |
|
coding->dst_pos_byte = PT_BYTE; |
5738 |
|
|
5739 |
while (cmp_data) |
encode_coding (coding); |
|
{ |
|
|
int i; |
|
5740 |
|
|
5741 |
for (i = 0; i < cmp_data->used && cmp_data->data[i] > 0; |
unbind_to (count, Qnil); |
5742 |
i += cmp_data->data[i]) |
return coding->result; |
5743 |
{ |
} |
|
int *data = cmp_data->data + i; |
|
|
enum composition_method method = (enum composition_method) data[3]; |
|
|
Lisp_Object components; |
|
5744 |
|
|
|
if (method == COMPOSITION_RELATIVE) |
|
|
components = Qnil; |
|
|
else |
|
|
{ |
|
|
int len = data[0] - 4, j; |
|
|
Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1]; |
|
5745 |
|
|
5746 |
for (j = 0; j < len; j++) |
/* Decode the text in the range FROM/FROM_BYTE and TO/TO_BYTE in |
5747 |
args[j] = make_number (data[4 + j]); |
SRC_OBJECT into DST_OBJECT by coding context CODING. |
|
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; |
|
|
} |
|
|
} |
|
5748 |
|
|
5749 |
/* Decode (if ENCODEP is zero) or encode (if ENCODEP is nonzero) the |
SRC_OBJECT is a buffer, a string, or Qnil. |
|
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). |
|
5750 |
|
|
5751 |
How many characters (and bytes) are converted to how many |
If it is a buffer, the text is at point of the buffer. FROM and TO |
5752 |
characters (and bytes) are recorded in members of the structure |
are positions in the buffer. |
|
CODING. |
|
5753 |
|
|
5754 |
If REPLACE is nonzero, we do various things as if the original text |
If it is a string, the text is at the beginning of the string. |
5755 |
is deleted and a new text is inserted. See the comments in |
FROM and TO are indices to the string. |
|
replace_range (insdel.c) to know what we are doing. |
|
5756 |
|
|
5757 |
If REPLACE is zero, it is assumed that the source text is unibyte. |
If it is nil, the text is at coding->source. FROM and TO are |
5758 |
Otherwise, it is assumed that the source text is multibyte. */ |
indices to coding->source. |
5759 |
|
|
5760 |
int |
DST_OBJECT is a buffer, Qt, or Qnil. |
5761 |
code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace) |
|
5762 |
int from, from_byte, to, to_byte, encodep, replace; |
If it is a buffer, the decoded text is inserted at point of the |
5763 |
|
buffer. If the buffer is the same as SRC_OBJECT, the source text |
5764 |
|
is deleted. |
5765 |
|
|
5766 |
|
If it is Qt, a string is made from the decoded text, and |
5767 |
|
set in CODING->dst_object. |
5768 |
|
|
5769 |
|
If it is Qnil, the decoded text is stored at CODING->destination. |
5770 |
|
The called must allocate CODING->dst_bytes bytes at |
5771 |
|
CODING->destination by xmalloc. If the decoded text is longer than |
5772 |
|
CODING->dst_bytes, CODING->destination is relocated by xrealloc. |
5773 |
|
*/ |
5774 |
|
|
5775 |
|
void |
5776 |
|
decode_coding_object (coding, src_object, from, from_byte, to, to_byte, |
5777 |
|
dst_object) |
5778 |
struct coding_system *coding; |
struct coding_system *coding; |
5779 |
|
Lisp_Object src_object; |
5780 |
|
EMACS_INT from, from_byte, to, to_byte; |
5781 |
|
Lisp_Object dst_object; |
5782 |
{ |
{ |
5783 |
int len = to - from, len_byte = to_byte - from_byte; |
int count = specpdl_ptr - specpdl; |
5784 |
int nchars_del = 0, nbytes_del = 0; |
unsigned char *destination; |
5785 |
int require, inserted, inserted_byte; |
EMACS_INT dst_bytes; |
5786 |
int head_skip, tail_skip, total_skip = 0; |
EMACS_INT chars = to - from; |
5787 |
Lisp_Object saved_coding_symbol; |
EMACS_INT bytes = to_byte - from_byte; |
5788 |
int first = 1; |
Lisp_Object attrs; |
|
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); |
|
5789 |
|
|
5790 |
deletion = Qnil; |
saved_coding = coding; |
5791 |
saved_coding_symbol = coding->symbol; |
record_unwind_protect (code_conversion_restore, save_excursion_save ()); |
5792 |
|
|
5793 |
if (from < PT && PT < to) |
if (NILP (dst_object)) |
5794 |
{ |
{ |
5795 |
TEMP_SET_PT_BOTH (from, from_byte); |
destination = coding->destination; |
5796 |
orig_point = from; |
dst_bytes = coding->dst_bytes; |
5797 |
} |
} |
5798 |
|
|
5799 |
if (replace) |
coding->src_object = src_object; |
5800 |
{ |
coding->src_chars = chars; |
5801 |
int saved_from = from; |
coding->src_bytes = bytes; |
5802 |
int saved_inhibit_modification_hooks; |
coding->src_multibyte = chars < bytes; |
|
|
|
|
prepare_to_modify_buffer (from, to, &from); |
|
|
if (saved_from != from) |
|
|
{ |
|
|
to = from + len; |
|
|
from_byte = CHAR_TO_BYTE (from), to_byte = CHAR_TO_BYTE (to); |
|
|
len_byte = to_byte - from_byte; |
|
|
} |
|
5803 |
|
|
5804 |
/* The code conversion routine can not preserve text properties |
if (STRINGP (src_object)) |
5805 |
for now. So, we must remove all text properties in the |
{ |
5806 |
region. Here, we must suppress all modification hooks. */ |
coding->src_pos = from; |
5807 |
saved_inhibit_modification_hooks = inhibit_modification_hooks; |
coding->src_pos_byte = from_byte; |
|
inhibit_modification_hooks = 1; |
|
|
Fset_text_properties (make_number (from), make_number (to), Qnil, Qnil); |
|
|
inhibit_modification_hooks = saved_inhibit_modification_hooks; |
|
5808 |
} |
} |
5809 |
|
else if (BUFFERP (src_object)) |
|
if (! encodep && CODING_REQUIRE_DETECTION (coding)) |
|
5810 |
{ |
{ |
5811 |
/* We must detect encoding of text and eol format. */ |
set_buffer_internal (XBUFFER (src_object)); |
5812 |
|
if (from != GPT) |
|
if (from < GPT && to > GPT) |
|
5813 |
move_gap_both (from, from_byte); |
move_gap_both (from, from_byte); |
5814 |
if (coding->type == coding_type_undecided) |
if (EQ (src_object, dst_object)) |
5815 |
{ |
{ |
|
detect_coding (coding, BYTE_POS_ADDR (from_byte), len_byte); |
|
|
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; |
|
|
} |
|
|
} |
|
|
|
|
|
/* Now we convert the text. */ |
|
|
|
|
|
/* 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, Qnil); |
|
|
/* 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; |
|
5816 |
TEMP_SET_PT_BOTH (from, from_byte); |
TEMP_SET_PT_BOTH (from, from_byte); |
5817 |
|
del_range_both (from, from_byte, to, to_byte, 1); |
5818 |
|
coding->src_pos = -chars; |
5819 |
|
coding->src_pos_byte = -bytes; |
5820 |
} |
} |
|
} |
|
|
|
|
|
if (replace) |
|
|
{ |
|
|
if (! EQ (current_buffer->undo_list, Qt)) |
|
|
deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1); |
|
5821 |
else |
else |
5822 |
{ |
{ |
5823 |
nchars_del = to - from; |
coding->src_pos = from; |
5824 |
nbytes_del = to_byte - from_byte; |
coding->src_pos_byte = from_byte; |
5825 |
} |
} |
5826 |
} |
} |
5827 |
|
|
5828 |
if (coding->composing != COMPOSITION_DISABLED) |
if (CODING_REQUIRE_DETECTION (coding)) |
5829 |
|
detect_coding (coding); |
5830 |
|
attrs = CODING_ID_ATTRS (coding->id); |
5831 |
|
|
5832 |
|
if (! NILP (CODING_ATTR_POST_READ (attrs)) |
5833 |
|
|| EQ (dst_object, Qt)) |
5834 |
{ |
{ |
5835 |
if (encodep) |
coding->dst_object = make_conversion_work_buffer (1); |
5836 |
coding_save_composition (coding, from, to, Fcurrent_buffer ()); |
coding->dst_pos = BEG; |
5837 |
else |
coding->dst_pos_byte = BEG_BYTE; |
5838 |
coding_allocate_composition_data (coding, from); |
coding->dst_multibyte = 1; |
5839 |
|
} |
5840 |
|
else if (BUFFERP (dst_object)) |
5841 |
|
{ |
5842 |
|
coding->dst_object = dst_object; |
5843 |
|
coding->dst_pos = BUF_PT (XBUFFER (dst_object)); |
5844 |
|
coding->dst_pos_byte = BUF_PT_BYTE (XBUFFER (dst_object)); |
5845 |
|
coding->dst_multibyte |
5846 |
|
= ! NILP (XBUFFER (dst_object)->enable_multibyte_characters); |
5847 |
} |
} |
5848 |
|
else |
|
/* Try to skip the heading and tailing ASCIIs. */ |
|
|
if (coding->type != coding_type_ccl) |
|
5849 |
{ |
{ |
5850 |
int from_byte_orig = from_byte, to_byte_orig = to_byte; |
coding->dst_object = Qnil; |
5851 |
|
coding->dst_multibyte = 1; |
5852 |
if (from < GPT && GPT < to) |
} |
|
move_gap_both (from, from_byte); |
|
|
SHRINK_CONVERSION_REGION (&from_byte, &to_byte, coding, NULL, encodep); |
|
|
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; |
|
|
} |
|
|
|
|
|
head_skip = from_byte - from_byte_orig; |
|
|
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; |
|
|
} |
|
|
|
|
|
/* For conversion, we must put the gap before the text in addition to |
|
|
making the gap larger for efficient decoding. The required gap |
|
|
size starts from 2000 which is the magic number used in make_gap. |
|
|
But, after one batch of conversion, it will be incremented if we |
|
|
find that it is not enough . */ |
|
|
require = 2000; |
|
|
|
|
|
if (GAP_SIZE < require) |
|
|
make_gap (require - GAP_SIZE); |
|
|
move_gap_both (from, from_byte); |
|
|
|
|
|
inserted = inserted_byte = 0; |
|
|
|
|
|
GAP_SIZE += len_byte; |
|
|
ZV -= len; |
|
|
Z -= len; |
|
|
ZV_BYTE -= len_byte; |
|
|
Z_BYTE -= len_byte; |
|
|
|
|
|
if (GPT - BEG < BEG_UNCHANGED) |
|
|
BEG_UNCHANGED = GPT - BEG; |
|
|
if (Z - GPT < END_UNCHANGED) |
|
|
END_UNCHANGED = Z - GPT; |
|
|
|
|
|
if (!encodep && coding->src_multibyte) |
|
|
{ |
|
|
/* Decoding routines expects that the source text is unibyte. |
|
|
We must convert 8-bit characters of multibyte form to |
|
|
unibyte. */ |
|
|
int len_byte_orig = len_byte; |
|
|
len_byte = str_as_unibyte (GAP_END_ADDR - len_byte, len_byte); |
|
|
if (len_byte < len_byte_orig) |
|
|
safe_bcopy (GAP_END_ADDR - len_byte_orig, GAP_END_ADDR - len_byte, |
|
|
len_byte); |
|
|
coding->src_multibyte = 0; |
|
|
} |
|
|
|
|
|
for (;;) |
|
|
{ |
|
|
int result; |
|
|
|
|
|
/* The buffer memory is now: |
|
|
+--------+converted-text+---------+-------original-text-------+---+ |
|
|
|<-from->|<--inserted-->|---------|<--------len_byte--------->|---| |
|
|
|<---------------------- GAP ----------------------->| */ |
|
|
src = GAP_END_ADDR - len_byte; |
|
|
dst = GPT_ADDR + inserted_byte; |
|
|
|
|
|
if (encodep) |
|
|
result = encode_coding (coding, src, dst, len_byte, 0); |
|
|
else |
|
|
{ |
|
|
if (coding->composing != COMPOSITION_DISABLED) |
|
|
coding->cmp_data->char_offset = from + inserted; |
|
|
result = decode_coding (coding, src, dst, len_byte, 0); |
|
|
} |
|
5853 |
|
|
5854 |
/* The buffer memory is now: |
decode_coding (coding); |
|
+--------+-------converted-text----+--+------original-text----+---+ |
|
|
|<-from->|<-inserted->|<-produced->|--|<-(len_byte-consumed)->|---| |
|
|
|<---------------------- GAP ----------------------->| */ |
|
5855 |
|
|
5856 |
inserted += coding->produced_char; |
if (BUFFERP (coding->dst_object)) |
5857 |
inserted_byte += coding->produced; |
set_buffer_internal (XBUFFER (coding->dst_object)); |
|
len_byte -= coding->consumed; |
|
5858 |
|
|
5859 |
if (result == CODING_FINISH_INSUFFICIENT_CMP) |
if (! NILP (CODING_ATTR_POST_READ (attrs))) |
5860 |
{ |
{ |
5861 |
coding_allocate_composition_data (coding, from + inserted); |
struct gcpro gcpro1, gcpro2; |
5862 |
continue; |
EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE; |
5863 |
} |
Lisp_Object val; |
5864 |
|
|
5865 |
src += coding->consumed; |
GCPRO2 (coding->src_object, coding->dst_object); |
5866 |
dst += coding->produced; |
val = call1 (CODING_ATTR_POST_READ (attrs), |
5867 |
|
make_number (coding->produced_char)); |
5868 |
|
UNGCPRO; |
5869 |
|
CHECK_NATNUM (val); |
5870 |
|
coding->produced_char += Z - prev_Z; |
5871 |
|
coding->produced += Z_BYTE - prev_Z_BYTE; |
5872 |
|
} |
5873 |
|
|
5874 |
if (result == CODING_FINISH_NORMAL) |
if (EQ (dst_object, Qt)) |
5875 |
{ |
{ |
5876 |
src += len_byte; |
coding->dst_object = Fbuffer_string (); |
5877 |
break; |
} |
5878 |
} |
else if (NILP (dst_object) && BUFFERP (coding->dst_object)) |
5879 |
if (! encodep && result == CODING_FINISH_INCONSISTENT_EOL) |
{ |
5880 |
|
set_buffer_internal (XBUFFER (coding->dst_object)); |
5881 |
|
if (dst_bytes < coding->produced) |
5882 |
{ |
{ |
5883 |
unsigned char *pend = dst, *p = pend - inserted_byte; |
destination |
5884 |
Lisp_Object eol_type; |
= (unsigned char *) xrealloc (destination, coding->produced); |
5885 |
|
if (! destination) |
|
/* Encode LFs back to the original eol format (CR or CRLF). */ |
|
|
if (coding->eol_type == CODING_EOL_CR) |
|
5886 |
{ |
{ |
5887 |
while (p < pend) if (*p++ == '\n') p[-1] = '\r'; |
coding->result = CODING_RESULT_INSUFFICIENT_DST; |
5888 |
|
unbind_to (count, Qnil); |
5889 |
|
return; |
5890 |
} |
} |
5891 |
else |
if (BEGV < GPT && GPT < BEGV + coding->produced_char) |
5892 |
{ |
move_gap_both (BEGV, BEGV_BYTE); |
5893 |
int count = 0; |
bcopy (BEGV_ADDR, destination, coding->produced); |
5894 |
|
coding->destination = destination; |
5895 |
|
} |
5896 |
|
} |
5897 |
|
|
5898 |
while (p < pend) if (*p++ == '\n') count++; |
unbind_to (count, Qnil); |
5899 |
if (src - dst < count) |
} |
|
{ |
|
|
/* 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'; |
|
|
} |
|
|
} |
|
5900 |
|
|
|
/* Suppress eol-format conversion in the further conversion. */ |
|
|
coding->eol_type = CODING_EOL_LF; |
|
5901 |
|
|
5902 |
/* Set the coding system symbol to that for Unix-like EOL. */ |
void |
5903 |
eol_type = Fget (saved_coding_symbol, Qeol_type); |
encode_coding_object (coding, src_object, from, from_byte, to, to_byte, |
5904 |
if (VECTORP (eol_type) |
dst_object) |
5905 |
&& XVECTOR (eol_type)->size == 3 |
struct coding_system *coding; |
5906 |
&& SYMBOLP (XVECTOR (eol_type)->contents[CODING_EOL_LF])) |
Lisp_Object src_object; |
5907 |
coding->symbol = XVECTOR (eol_type)->contents[CODING_EOL_LF]; |
EMACS_INT from, from_byte, to, to_byte; |
5908 |
else |
Lisp_Object dst_object; |
5909 |
coding->symbol = saved_coding_symbol; |
{ |
5910 |
|
int count = specpdl_ptr - specpdl; |
5911 |
|
EMACS_INT chars = to - from; |
5912 |
|
EMACS_INT bytes = to_byte - from_byte; |
5913 |
|
Lisp_Object attrs; |
5914 |
|
|
5915 |
continue; |
saved_coding = coding; |
5916 |
} |
record_unwind_protect (code_conversion_restore, save_excursion_save ()); |
|
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; |
|
5917 |
|
|
5918 |
inserted += len_byte; |
coding->src_object = src_object; |
5919 |
while (len_byte--) |
coding->src_chars = chars; |
5920 |
{ |
coding->src_bytes = bytes; |
5921 |
int c = *src++; |
coding->src_multibyte = chars < bytes; |
|
dst += CHAR_STRING (c, dst); |
|
|
} |
|
5922 |
|
|
5923 |
inserted_byte += dst - start; |
attrs = CODING_ID_ATTRS (coding->id); |
|
} |
|
|
else |
|
|
{ |
|
|
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 = coding->produced - coding->consumed; |
|
|
ratio /= 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; |
|
|
|
|
|
GAP_SIZE -= add; |
|
|
ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add; |
|
|
GPT += inserted_byte; GPT_BYTE += inserted_byte; |
|
|
make_gap (require + 2000); |
|
|
GAP_SIZE += add; |
|
|
ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add; |
|
|
GPT -= inserted_byte; GPT_BYTE -= inserted_byte; |
|
|
} |
|
|
} |
|
|
if (src - dst > 0) *dst = 0; /* Put an anchor. */ |
|
|
|
|
|
if (encodep && coding->dst_multibyte) |
|
|
{ |
|
|
/* The output is unibyte. We must convert 8-bit characters to |
|
|
multibyte form. */ |
|
|
if (inserted_byte * 2 > 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; |
|
|
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; |
|
|
} |
|
|
inserted_byte = str_to_multibyte (GPT_ADDR, GAP_SIZE, inserted_byte); |
|
|
} |
|
|
|
|
|
/* If we shrank the conversion area, adjust it now. */ |
|
|
if (total_skip > 0) |
|
|
{ |
|
|
if (tail_skip > 0) |
|
|
safe_bcopy (GAP_END_ADDR, GPT_ADDR + inserted_byte, tail_skip); |
|
|
inserted += total_skip; inserted_byte += total_skip; |
|
|
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; |
|
|
} |
|
|
|
|
|
prev_Z = Z; |
|
|
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); |
|
5924 |
|
|
5925 |
if (! inhibit_pre_post_conversion |
if (! NILP (CODING_ATTR_PRE_WRITE (attrs))) |
|
&& ! encodep && ! NILP (coding->post_read_conversion)) |
|
5926 |
{ |
{ |
5927 |
Lisp_Object val; |
Lisp_Object val; |
5928 |
|
|
5929 |
if (from != PT) |
coding->src_object = make_conversion_work_buffer (coding->src_multibyte); |
5930 |
TEMP_SET_PT_BOTH (from, from_byte); |
set_buffer_internal (XBUFFER (coding->src_object)); |
5931 |
prev_Z = Z; |
if (STRINGP (src_object)) |
5932 |
record_unwind_protect (code_convert_region_unwind, Qnil); |
insert_from_string (src_object, from, from_byte, chars, bytes, 0); |
5933 |
/* We should not call any more pre-write/post-read-conversion |
else if (BUFFERP (src_object)) |
5934 |
functions while this post-read-conversion is running. */ |
insert_from_buffer (XBUFFER (src_object), from, chars, 0); |
|
inhibit_pre_post_conversion = 1; |
|
|
val = call1 (coding->post_read_conversion, make_number (inserted)); |
|
|
inhibit_pre_post_conversion = 0; |
|
|
/* 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; |
|
5935 |
else |
else |
5936 |
orig_point = from; |
insert_1_both (coding->source + from, chars, bytes, 0, 0, 0); |
|
TEMP_SET_PT (orig_point); |
|
|
} |
|
|
|
|
|
if (replace) |
|
|
{ |
|
|
signal_after_change (from, to - from, inserted); |
|
|
update_compositions (from, from + inserted, CHECK_BORDER); |
|
|
} |
|
5937 |
|
|
5938 |
{ |
if (EQ (src_object, dst_object)) |
5939 |
coding->consumed = to_byte - from_byte; |
{ |
5940 |
coding->consumed_char = to - from; |
set_buffer_internal (XBUFFER (src_object)); |
5941 |
coding->produced = inserted_byte; |
del_range_both (from, from_byte, to, to_byte, 1); |
5942 |
coding->produced_char = inserted; |
set_buffer_internal (XBUFFER (coding->src_object)); |
5943 |
} |
} |
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
Lisp_Object |
|
|
run_pre_post_conversion_on_str (str, coding, encodep) |
|
|
Lisp_Object str; |
|
|
struct coding_system *coding; |
|
|
int encodep; |
|
|
{ |
|
|
int count = specpdl_ptr - specpdl; |
|
|
struct gcpro gcpro1; |
|
|
int multibyte = STRING_MULTIBYTE (str); |
|
5944 |
|
|
5945 |
record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); |
val = call2 (CODING_ATTR_PRE_WRITE (attrs), |
5946 |
record_unwind_protect (code_convert_region_unwind, Qnil); |
make_number (1), make_number (chars)); |
5947 |
GCPRO1 (str); |
CHECK_NATNUM (val); |
5948 |
temp_output_buffer_setup (" *code-converting-work*"); |
if (BEG != GPT) |
5949 |
set_buffer_internal (XBUFFER (Vstandard_output)); |
move_gap_both (BEG, BEG_BYTE); |
5950 |
/* We must insert the contents of STR as is without |
coding->src_chars = Z - BEG; |
5951 |
unibyte<->multibyte conversion. For that, we adjust the |
coding->src_bytes = Z_BYTE - BEG_BYTE; |
5952 |
multibyteness of the working buffer to that of STR. */ |
coding->src_pos = BEG; |
5953 |
Ferase_buffer (); |
coding->src_pos_byte = BEG_BYTE; |
5954 |
current_buffer->enable_multibyte_characters = multibyte ? Qt : Qnil; |
coding->src_multibyte = Z < Z_BYTE; |
5955 |
insert_from_string (str, 0, 0, |
} |
5956 |
XSTRING (str)->size, STRING_BYTES (XSTRING (str)), 0); |
else if (STRINGP (src_object)) |
|
UNGCPRO; |
|
|
inhibit_pre_post_conversion = 1; |
|
|
if (encodep) |
|
|
call2 (coding->pre_write_conversion, make_number (BEG), make_number (Z)); |
|
|
else |
|
5957 |
{ |
{ |
5958 |
TEMP_SET_PT_BOTH (BEG, BEG_BYTE); |
coding->src_pos = from; |
5959 |
call1 (coding->post_read_conversion, make_number (Z - BEG)); |
coding->src_pos_byte = from_byte; |
5960 |
} |
} |
5961 |
inhibit_pre_post_conversion = 0; |
else if (BUFFERP (src_object)) |
|
str = make_buffer_string (BEG, Z, 1); |
|
|
return unbind_to (count, str); |
|
|
} |
|
|
|
|
|
Lisp_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 = STRING_BYTES (XSTRING (str)); |
|
|
|
|
|
saved_coding_symbol = coding->symbol; |
|
|
coding->src_multibyte = STRING_MULTIBYTE (str); |
|
|
coding->dst_multibyte = 1; |
|
|
if (CODING_REQUIRE_DETECTION (coding)) |
|
5962 |
{ |
{ |
5963 |
/* See the comments in code_convert_region. */ |
set_buffer_internal (XBUFFER (src_object)); |
5964 |
if (coding->type == coding_type_undecided) |
if (from != GPT) |
5965 |
|
move_gap_both (from, from_byte); |
5966 |
|
if (EQ (src_object, dst_object)) |
5967 |
{ |
{ |
5968 |
detect_coding (coding, XSTRING (str)->data, to_byte); |
del_range_both (from, from_byte, to, to_byte, 1); |
5969 |
if (coding->type == coding_type_undecided) |
coding->src_pos = -chars; |
5970 |
{ |
coding->src_pos_byte = -bytes; |
|
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; |
|
|
} |
|
5971 |
} |
} |
5972 |
if (coding->eol_type == CODING_EOL_UNDECIDED |
else |
|
&& coding->type != coding_type_ccl) |
|
5973 |
{ |
{ |
5974 |
saved_coding_symbol = coding->symbol; |
coding->src_pos = from; |
5975 |
detect_eol (coding, XSTRING (str)->data, to_byte); |
coding->src_pos_byte = from_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; |
|
5976 |
} |
} |
5977 |
} |
} |
5978 |
|
|
5979 |
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)) |
|
5980 |
{ |
{ |
5981 |
/* Decoding routines expect the source text to be unibyte. */ |
coding->dst_object = dst_object; |
5982 |
str = Fstring_as_unibyte (str); |
coding->dst_pos = BUF_PT (XBUFFER (dst_object)); |
5983 |
to_byte = STRING_BYTES (XSTRING (str)); |
coding->dst_pos_byte = BUF_PT_BYTE (XBUFFER (dst_object)); |
5984 |
nocopy = 1; |
coding->dst_multibyte |
5985 |
coding->src_multibyte = 0; |
= ! NILP (XBUFFER (dst_object)->enable_multibyte_characters); |
5986 |
} |
} |
5987 |
|
else if (EQ (dst_object, Qt)) |
|
/* Try to skip the heading and tailing ASCIIs. */ |
|
|
if (require_decoding && coding->type != coding_type_ccl) |
|
5988 |
{ |
{ |
5989 |
SHRINK_CONVERSION_REGION (&from, &to_byte, coding, XSTRING (str)->data, |
coding->dst_object = Qnil; |
5990 |
0); |
coding->destination = (unsigned char *) xmalloc (coding->src_chars); |
5991 |
if (from == to_byte) |
coding->dst_bytes = coding->src_chars; |
5992 |
require_decoding = 0; |
coding->dst_multibyte = 0; |
|
shrinked_bytes = from + (STRING_BYTES (XSTRING (str)) - to_byte); |
|
5993 |
} |
} |
5994 |
|
else |
|
if (!require_decoding) |
|
5995 |
{ |
{ |
5996 |
coding->consumed = STRING_BYTES (XSTRING (str)); |
coding->dst_object = Qnil; |
5997 |
coding->consumed_char = XSTRING (str)->size; |
coding->dst_multibyte = 0; |
|
if (coding->dst_multibyte) |
|
|
{ |
|
|
str = Fstring_as_multibyte (str); |
|
|
nocopy = 1; |
|
|
} |
|
|
coding->produced = STRING_BYTES (XSTRING (str)); |
|
|
coding->produced_char = XSTRING (str)->size; |
|
|
return (nocopy ? str : Fcopy_sequence (str)); |
|
5998 |
} |
} |
5999 |
|
|
6000 |
if (coding->composing != COMPOSITION_DISABLED) |
encode_coding (coding); |
|
coding_allocate_composition_data (coding, from); |
|
|
len = decoding_buffer_size (coding, to_byte - from); |
|
|
allocate_conversion_buffer (buf, len); |
|
6001 |
|
|
6002 |
consumed = consumed_char = produced = produced_char = 0; |
if (EQ (dst_object, Qt)) |
|
while (1) |
|
6003 |
{ |
{ |
6004 |
result = decode_coding (coding, XSTRING (str)->data + from + consumed, |
if (BUFFERP (coding->dst_object)) |
6005 |
buf.data + produced, to_byte - from - consumed, |
coding->dst_object = Fbuffer_string (); |
6006 |
buf.size - produced); |
else |
6007 |
consumed += coding->consumed; |
{ |
6008 |
consumed_char += coding->consumed_char; |
coding->dst_object |
6009 |
produced += coding->produced; |
= make_unibyte_string ((char *) coding->destination, |
6010 |
produced_char += coding->produced_char; |
coding->produced); |
6011 |
if (result == CODING_FINISH_NORMAL |
xfree (coding->destination); |
|
|| (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; |
|
|
|
|
|
|
|
6012 |
} |
} |
6013 |
} |
} |
6014 |
|
|
6015 |
coding->consumed = consumed; |
unbind_to (count, Qnil); |
|
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); |
|
|
else |
|
|
newstr = make_uninit_string (produced + shrinked_bytes); |
|
|
if (from > 0) |
|
|
bcopy (XSTRING (str)->data, XSTRING (newstr)->data, from); |
|
|
bcopy (buf.data, XSTRING (newstr)->data + from, produced); |
|
|
if (shrinked_bytes > from) |
|
|
bcopy (XSTRING (str)->data + to_byte, |
|
|
XSTRING (newstr)->data + from + produced, |
|
|
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; |
|
6016 |
} |
} |
6017 |
|
|
6018 |
|
|
6019 |
Lisp_Object |
Lisp_Object |
6020 |
encode_coding_string (str, coding, nocopy) |
preferred_coding_system () |
|
Lisp_Object str; |
|
|
struct coding_system *coding; |
|
|
int nocopy; |
|
6021 |
{ |
{ |
6022 |
int len; |
int id = coding_categories[coding_priorities[0]].id; |
|
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); |
|
|
|
|
|
from = 0; |
|
|
to = XSTRING (str)->size; |
|
|
to_byte = STRING_BYTES (XSTRING (str)); |
|
6023 |
|
|
6024 |
/* Encoding routines determine the multibyteness of the source text |
return CODING_ID_NAME (id); |
|
by coding->src_multibyte. */ |
|
|
coding->src_multibyte = STRING_MULTIBYTE (str); |
|
|
coding->dst_multibyte = 0; |
|
|
if (! CODING_REQUIRE_ENCODING (coding)) |
|
|
{ |
|
|
coding->consumed = STRING_BYTES (XSTRING (str)); |
|
|
coding->consumed_char = XSTRING (str)->size; |
|
|
if (STRING_MULTIBYTE (str)) |
|
|
{ |
|
|
str = Fstring_as_unibyte (str); |
|
|
nocopy = 1; |
|
|
} |
|
|
coding->produced = STRING_BYTES (XSTRING (str)); |
|
|
coding->produced_char = XSTRING (str)->size; |
|
|
return (nocopy ? str : Fcopy_sequence (str)); |
|
|
} |
|
|
|
|
|
if (coding->composing != COMPOSITION_DISABLED) |
|
|
coding_save_composition (coding, from, to, str); |
|
|
|
|
|
/* Try to skip the heading and tailing ASCIIs. */ |
|
|
if (coding->type != coding_type_ccl) |
|
|
{ |
|
|
SHRINK_CONVERSION_REGION (&from, &to_byte, coding, XSTRING (str)->data, |
|
|
1); |
|
|
if (from == to_byte) |
|
|
return (nocopy ? str : Fcopy_sequence (str)); |
|
|
shrinked_bytes = from + (STRING_BYTES (XSTRING (str)) - to_byte); |
|
|
} |
|
|
|
|
|
len = encoding_buffer_size (coding, to_byte - from); |
|
|
allocate_conversion_buffer (buf, len); |
|
|
|
|
|
consumed = consumed_char = produced = produced_char = 0; |
|
|
while (1) |
|
|
{ |
|
|
result = encode_coding (coding, XSTRING (str)->data + 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); |
|
|
} |
|
|
|
|
|
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) |
|
|
bcopy (XSTRING (str)->data, XSTRING (newstr)->data, from); |
|
|
bcopy (buf.data, XSTRING (newstr)->data + from, produced); |
|
|
if (shrinked_bytes > from) |
|
|
bcopy (XSTRING (str)->data + to_byte, |
|
|
XSTRING (newstr)->data + from + produced, |
|
|
shrinked_bytes - from); |
|
|
|
|
|
free_conversion_buffer (&buf); |
|
|
coding_free_composition_data (coding); |
|
|
|
|
|
return newstr; |
|
6025 |
} |
} |
6026 |
|
|
6027 |
|
|
6030 |
|
|
6031 |
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, |
6032 |
doc: /* Return t if OBJECT is nil or a coding-system. |
doc: /* Return t if OBJECT is nil or a coding-system. |
6033 |
See the documentation of `make-coding-system' for information |
See the documentation of `define-coding-system' for information |
6034 |
about coding-system objects. */) |
about coding-system objects. */) |
6035 |
(obj) |
(obj) |
6036 |
Lisp_Object obj; |
Lisp_Object obj; |
6037 |
{ |
{ |
6038 |
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); |
|
6039 |
} |
} |
6040 |
|
|
6041 |
DEFUN ("read-non-nil-coding-system", Fread_non_nil_coding_system, |
DEFUN ("read-non-nil-coding-system", Fread_non_nil_coding_system, |
6075 |
If valid, return CODING-SYSTEM, else signal a `coding-system-error' error. |
If valid, return CODING-SYSTEM, else signal a `coding-system-error' error. |
6076 |
It is valid if it is a symbol with a non-nil `coding-system' property. |
It is valid if it is a symbol with a non-nil `coding-system' property. |
6077 |
The value of property should be a vector of length 5. */) |
The value of property should be a vector of length 5. */) |
6078 |
(coding_system) |
(coding_system) |
6079 |
Lisp_Object coding_system; |
Lisp_Object coding_system; |
6080 |
{ |
{ |
6081 |
CHECK_SYMBOL (coding_system); |
CHECK_SYMBOL (coding_system); |
6084 |
while (1) |
while (1) |
6085 |
Fsignal (Qcoding_system_error, Fcons (coding_system, Qnil)); |
Fsignal (Qcoding_system_error, Fcons (coding_system, Qnil)); |
6086 |
} |
} |
6087 |
|
|
6088 |
|
|
6089 |
Lisp_Object |
Lisp_Object |
6090 |
detect_coding_system (src, src_bytes, highest, multibytep) |
detect_coding_system (src, src_bytes, highest, multibytep, coding_system) |
6091 |
unsigned char *src; |
unsigned char *src; |
6092 |
int src_bytes, highest; |
int src_bytes, highest; |
6093 |
int multibytep; |
int multibytep; |
6094 |
|
Lisp_Object coding_system; |
6095 |
{ |
{ |
6096 |
int coding_mask, eol_type; |
unsigned char *src_end = src + src_bytes; |
6097 |
Lisp_Object val, tmp; |
int mask = CATEGORY_MASK_ANY; |
6098 |
int dummy; |
int detected = 0; |
6099 |
|
int c, i; |
6100 |
|
Lisp_Object attrs, eol_type; |
6101 |
|
Lisp_Object val; |
6102 |
|
struct coding_system coding; |
6103 |
|
|
6104 |
coding_mask = detect_coding_mask (src, src_bytes, NULL, &dummy, multibytep); |
if (NILP (coding_system)) |
6105 |
eol_type = detect_eol_type (src, src_bytes, &dummy); |
coding_system = Qundecided; |
6106 |
if (eol_type == CODING_EOL_INCONSISTENT) |
setup_coding_system (coding_system, &coding); |
6107 |
eol_type = CODING_EOL_UNDECIDED; |
attrs = CODING_ID_ATTRS (coding.id); |
6108 |
|
eol_type = CODING_ID_EOL_TYPE (coding.id); |
6109 |
|
|
6110 |
|
coding.source = src; |
6111 |
|
coding.src_bytes = src_bytes; |
6112 |
|
coding.src_multibyte = multibytep; |
6113 |
|
coding.consumed = 0; |
6114 |
|
|
6115 |
if (!coding_mask) |
if (XINT (CODING_ATTR_CATEGORY (attrs)) != coding_category_undecided) |
6116 |
{ |
{ |
6117 |
val = Qundecided; |
mask = 1 << XINT (CODING_ATTR_CATEGORY (attrs)); |
|
if (eol_type != CODING_EOL_UNDECIDED) |
|
|
{ |
|
|
Lisp_Object val2; |
|
|
val2 = Fget (Qundecided, Qeol_type); |
|
|
if (VECTORP (val2)) |
|
|
val = XVECTOR (val2)->contents[eol_type]; |
|
|
} |
|
|
return (highest ? val : Fcons (val, Qnil)); |
|
6118 |
} |
} |
6119 |
|
else |
|
/* At first, gather possible coding systems in VAL. */ |
|
|
val = Qnil; |
|
|
for (tmp = Vcoding_category_list; CONSP (tmp); tmp = XCDR (tmp)) |
|
6120 |
{ |
{ |
6121 |
Lisp_Object category_val, category_index; |
coding_system = Qnil; |
6122 |
|
for (; src < src_end; src++) |
|
category_index = Fget (XCAR (tmp), Qcoding_category_index); |
|
|
category_val = Fsymbol_value (XCAR (tmp)); |
|
|
if (!NILP (category_val) |
|
|
&& NATNUMP (category_index) |
|
|
&& (coding_mask & (1 << XFASTINT (category_index)))) |
|
6123 |
{ |
{ |
6124 |
val = Fcons (category_val, val); |
c = *src; |
6125 |
if (highest) |
if (c & 0x80 || (c < 0x20 && (c == ISO_CODE_ESC |
6126 |
|
|| c == ISO_CODE_SI |
6127 |
|
|| c == ISO_CODE_SO))) |
6128 |
break; |
break; |
6129 |
} |
} |
6130 |
|
coding.head_ascii = src - coding.source; |
6131 |
|
|
6132 |
|
if (src < src_end) |
6133 |
|
for (i = 0; i < coding_category_raw_text; i++) |
6134 |
|
{ |
6135 |
|
enum coding_category category = coding_priorities[i]; |
6136 |
|
struct coding_system *this = coding_categories + category; |
6137 |
|
|
6138 |
|
if (category >= coding_category_raw_text |
6139 |
|
|| detected & (1 << category)) |
6140 |
|
continue; |
6141 |
|
|
6142 |
|
if (this->id < 0) |
6143 |
|
{ |
6144 |
|
/* No coding system of this category is defined. */ |
6145 |
|
mask &= ~(1 << category); |
6146 |
|
} |
6147 |
|
else |
6148 |
|
{ |
6149 |
|
detected |= detected_mask[category]; |
6150 |
|
if ((*(coding_categories[category].detector)) (&coding, &mask) |
6151 |
|
&& highest) |
6152 |
|
{ |
6153 |
|
mask &= detected_mask[category]; |
6154 |
|
break; |
6155 |
|
} |
6156 |
|
} |
6157 |
|
} |
6158 |
} |
} |
|
if (!highest) |
|
|
val = Fnreverse (val); |
|
6159 |
|
|
6160 |
/* Then, replace the elements with subsidiary coding systems. */ |
if (!mask) |
6161 |
for (tmp = val; CONSP (tmp); tmp = XCDR (tmp)) |
val = Fcons (make_number (coding_category_raw_text), Qnil); |
6162 |
|
else if (mask == CATEGORY_MASK_ANY) |
6163 |
|
val = Fcons (make_number (coding_category_undecided), Qnil); |
6164 |
|
else if (highest) |
6165 |
{ |
{ |
6166 |
if (eol_type != CODING_EOL_UNDECIDED |
for (i = 0; i < coding_category_raw_text; i++) |
6167 |
&& eol_type != CODING_EOL_INCONSISTENT) |
if (mask & (1 << coding_priorities[i])) |
6168 |
{ |
{ |
6169 |
Lisp_Object eol; |
val = Fcons (make_number (coding_priorities[i]), Qnil); |
6170 |
eol = Fget (XCAR (tmp), Qeol_type); |
break; |
6171 |
if (VECTORP (eol)) |
} |
6172 |
XSETCAR (tmp, XVECTOR (eol)->contents[eol_type]); |
} |
6173 |
} |
else |
6174 |
|
{ |
6175 |
|
val = Qnil; |
6176 |
|
for (i = coding_category_raw_text - 1; i >= 0; i--) |
6177 |
|
if (mask & (1 << coding_priorities[i])) |
6178 |
|
val = Fcons (make_number (coding_priorities[i]), val); |
6179 |
} |
} |
6180 |
|
|
6181 |
|
{ |
6182 |
|
int one_byte_eol = -1, two_byte_eol = -1; |
6183 |
|
Lisp_Object tail; |
6184 |
|
|
6185 |
|
for (tail = val; CONSP (tail); tail = XCDR (tail)) |
6186 |
|
{ |
6187 |
|
struct coding_system *this |
6188 |
|
= (NILP (coding_system) ? coding_categories + XINT (XCAR (tail)) |
6189 |
|
: &coding); |
6190 |
|
int this_eol; |
6191 |
|
|
6192 |
|
attrs = CODING_ID_ATTRS (this->id); |
6193 |
|
eol_type = CODING_ID_EOL_TYPE (this->id); |
6194 |
|
XSETCAR (tail, CODING_ID_NAME (this->id)); |
6195 |
|
if (VECTORP (eol_type)) |
6196 |
|
{ |
6197 |
|
if (EQ (CODING_ATTR_TYPE (attrs), Qutf_16)) |
6198 |
|
{ |
6199 |
|
if (two_byte_eol < 0) |
6200 |
|
two_byte_eol = detect_eol (this, coding.source, src_bytes); |
6201 |
|
this_eol = two_byte_eol; |
6202 |
|
} |
6203 |
|
else |
6204 |
|
{ |
6205 |
|
if (one_byte_eol < 0) |
6206 |
|
one_byte_eol =detect_eol (this, coding.source, src_bytes); |
6207 |
|
this_eol = one_byte_eol; |
6208 |
|
} |
6209 |
|
if (this_eol == EOL_SEEN_LF) |
6210 |
|
XSETCAR (tail, AREF (eol_type, 0)); |
6211 |
|
else if (this_eol == EOL_SEEN_CRLF) |
6212 |
|
XSETCAR (tail, AREF (eol_type, 1)); |
6213 |
|
else if (this_eol == EOL_SEEN_CR) |
6214 |
|
XSETCAR (tail, AREF (eol_type, 2)); |
6215 |
|
} |
6216 |
|
} |
6217 |
|
} |
6218 |
|
|
6219 |
return (highest ? XCAR (val) : val); |
return (highest ? XCAR (val) : val); |
6220 |
} |
} |
6221 |
|
|
6222 |
|
|
6223 |
DEFUN ("detect-coding-region", Fdetect_coding_region, Sdetect_coding_region, |
DEFUN ("detect-coding-region", Fdetect_coding_region, Sdetect_coding_region, |
6224 |
2, 3, 0, |
2, 3, 0, |
6225 |
doc: /* Detect coding system of the text in the region between START and END. |
doc: /* Detect coding system of the text in the region between START and END. |
6236 |
{ |
{ |
6237 |
int from, to; |
int from, to; |
6238 |
int from_byte, to_byte; |
int from_byte, to_byte; |
|
int include_anchor_byte = 0; |
|
6239 |
|
|
6240 |
CHECK_NUMBER_COERCE_MARKER (start); |
CHECK_NUMBER_COERCE_MARKER (start); |
6241 |
CHECK_NUMBER_COERCE_MARKER (end); |
CHECK_NUMBER_COERCE_MARKER (end); |
6247 |
|
|
6248 |
if (from < GPT && to >= GPT) |
if (from < GPT && to >= GPT) |
6249 |
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. |
|
6250 |
|
|
|
Fix me: This is not an 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; |
|
6251 |
return detect_coding_system (BYTE_POS_ADDR (from_byte), |
return detect_coding_system (BYTE_POS_ADDR (from_byte), |
6252 |
to_byte - from_byte + include_anchor_byte, |
to_byte - from_byte, |
6253 |
!NILP (highest), |
!NILP (highest), |
6254 |
!NILP (current_buffer |
!NILP (current_buffer |
6255 |
->enable_multibyte_characters)); |
->enable_multibyte_characters), |
6256 |
|
Qnil); |
6257 |
} |
} |
6258 |
|
|
6259 |
DEFUN ("detect-coding-string", Fdetect_coding_string, Sdetect_coding_string, |
DEFUN ("detect-coding-string", Fdetect_coding_string, Sdetect_coding_string, |
6273 |
CHECK_STRING (string); |
CHECK_STRING (string); |
6274 |
|
|
6275 |
return detect_coding_system (XSTRING (string)->data, |
return detect_coding_system (XSTRING (string)->data, |
6276 |
/* "+ 1" is to include the anchor byte |
STRING_BYTES (XSTRING (string)), |
|
`\0'. With this, code detectors can |
|
|
handle the tailing bytes more |
|
|
accurately. */ |
|
|
STRING_BYTES (XSTRING (string)) + 1, |
|
6277 |
!NILP (highest), |
!NILP (highest), |
6278 |
STRING_MULTIBYTE (string)); |
STRING_MULTIBYTE (string), |
6279 |
|
Qnil); |
6280 |
} |
} |
6281 |
|
|
|
/* Return an intersection of lists L1 and L2. */ |
|
6282 |
|
|
6283 |
static Lisp_Object |
static INLINE int |
6284 |
intersection (l1, l2) |
char_encodable_p (c, attrs) |
6285 |
Lisp_Object l1, l2; |
int c; |
6286 |
{ |
Lisp_Object attrs; |
6287 |
Lisp_Object val; |
{ |
6288 |
|
Lisp_Object tail; |
6289 |
|
int id; |
6290 |
|
struct charset *charset; |
6291 |
|
|
6292 |
for (val = Qnil; CONSP (l1); l1 = XCDR (l1)) |
for (tail = CODING_ATTR_CHARSET_LIST (attrs); |
6293 |
|
CONSP (tail); tail = XCDR (tail)) |
6294 |
{ |
{ |
6295 |
if (!NILP (Fmemq (XCAR (l1), l2))) |
charset = CHARSET_FROM_ID (XINT (XCAR (tail))); |
6296 |
val = Fcons (XCAR (l1), val); |
if (CHAR_CHARSET_P (c, charset)) |
6297 |
|
break; |
6298 |
} |
} |
6299 |
return val; |
return (! NILP (tail)); |
6300 |
} |
} |
6301 |
|
|
6302 |
|
|
6303 |
/* Subroutine for Fsafe_coding_systems_region_internal. |
/* Return a list of coding systems that safely encode the text between |
6304 |
|
START and END. If EXCLUDE is non-nil, it is a list of coding |
6305 |
|
systems not to check. The returned list doesn't contain any such |
6306 |
|
coding systems. In any case, If the text contains only ASCII or is |
6307 |
|
unibyte, return t. */ |
6308 |
|
|
6309 |
Return a list of coding systems that safely encode the multibyte |
DEFUN ("find-coding-systems-region-internal", |
6310 |
text between P and PEND. SAFE_CODINGS, if non-nil, is a list of |
Ffind_coding_systems_region_internal, |
6311 |
possible coding systems. If it is nil, it means that we have not |
Sfind_coding_systems_region_internal, 2, 3, 0, |
6312 |
yet found any coding systems. |
doc: /* Internal use only. */) |
6313 |
|
(start, end, exclude) |
6314 |
|
Lisp_Object start, end, exclude; |
6315 |
|
{ |
6316 |
|
Lisp_Object coding_attrs_list, safe_codings; |
6317 |
|
EMACS_INT start_byte, end_byte; |
6318 |
|
unsigned char *p, *pbeg, *pend; |
6319 |
|
int c; |
6320 |
|
Lisp_Object tail, elt; |
6321 |
|
|
6322 |
WORK_TABLE is a copy of the char-table Vchar_coding_system_table. An |
if (STRINGP (start)) |
6323 |
element of WORK_TABLE is set to t once the element is looked up. |
{ |
6324 |
|
if (!STRING_MULTIBYTE (start) |
6325 |
|
&& XSTRING (start)->size != STRING_BYTES (XSTRING (start))) |
6326 |
|
return Qt; |
6327 |
|
start_byte = 0; |
6328 |
|
end_byte = STRING_BYTES (XSTRING (start)); |
6329 |
|
} |
6330 |
|
else |
6331 |
|
{ |
6332 |
|
CHECK_NUMBER_COERCE_MARKER (start); |
6333 |
|
CHECK_NUMBER_COERCE_MARKER (end); |
6334 |
|
if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end)) |
6335 |
|
args_out_of_range (start, end); |
6336 |
|
if (NILP (current_buffer->enable_multibyte_characters)) |
6337 |
|
return Qt; |
6338 |
|
start_byte = CHAR_TO_BYTE (XINT (start)); |
6339 |
|
end_byte = CHAR_TO_BYTE (XINT (end)); |
6340 |
|
if (XINT (end) - XINT (start) == end_byte - start_byte) |
6341 |
|
return Qt; |
6342 |
|
|
6343 |
|
if (start < GPT && end > GPT) |
6344 |
|
{ |
6345 |
|
if ((GPT - start) < (end - GPT)) |
6346 |
|
move_gap_both (start, start_byte); |
6347 |
|
else |
6348 |
|
move_gap_both (end, end_byte); |
6349 |
|
} |
6350 |
|
} |
6351 |
|
|
6352 |
If a non-ASCII single byte char is found, set |
coding_attrs_list = Qnil; |
6353 |
*single_byte_char_found to 1. */ |
for (tail = Vcoding_system_list; CONSP (tail); tail = XCDR (tail)) |
6354 |
|
if (NILP (exclude) |
6355 |
|
|| NILP (Fmemq (XCAR (tail), exclude))) |
6356 |
|
{ |
6357 |
|
Lisp_Object attrs; |
6358 |
|
|
6359 |
static Lisp_Object |
attrs = AREF (CODING_SYSTEM_SPEC (XCAR (tail)), 0); |
6360 |
find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found) |
if (EQ (XCAR (tail), CODING_ATTR_BASE_NAME (attrs)) |
6361 |
unsigned char *p, *pend; |
&& ! EQ (CODING_ATTR_TYPE (attrs), Qundecided)) |
6362 |
Lisp_Object safe_codings, work_table; |
coding_attrs_list = Fcons (attrs, coding_attrs_list); |
6363 |
int *single_byte_char_found; |
} |
6364 |
{ |
|
6365 |
int c, len, idx; |
if (STRINGP (start)) |
6366 |
Lisp_Object val; |
p = pbeg = XSTRING (start)->data; |
6367 |
|
else |
6368 |
|
p = pbeg = BYTE_POS_ADDR (start_byte); |
6369 |
|
pend = p + (end_byte - start_byte); |
6370 |
|
|
6371 |
|
while (p < pend && ASCII_BYTE_P (*p)) p++; |
6372 |
|
while (p < pend && ASCII_BYTE_P (*(pend - 1))) pend--; |
6373 |
|
|
6374 |
while (p < pend) |
while (p < pend) |
6375 |
{ |
{ |
6376 |
c = STRING_CHAR_AND_LENGTH (p, pend - p, len); |
if (ASCII_BYTE_P (*p)) |
6377 |
p += len; |
p++; |
6378 |
if (ASCII_BYTE_P (c)) |
else |
6379 |
/* We can ignore ASCII characters here. */ |
{ |
6380 |
continue; |
c = STRING_CHAR_ADVANCE (p); |
|
if (SINGLE_BYTE_CHAR_P (c)) |
|
|
*single_byte_char_found = 1; |
|
|
if (NILP (safe_codings)) |
|
|
continue; |
|
|
/* Check the safe coding systems for C. */ |
|
|
val = char_table_ref_and_index (work_table, c, &idx); |
|
|
if (EQ (val, Qt)) |
|
|
/* This element was already checked. Ignore it. */ |
|
|
continue; |
|
|
/* Remember that we checked this element. */ |
|
|
CHAR_TABLE_SET (work_table, make_number (idx), Qt); |
|
6381 |
|
|
6382 |
/* If there are some safe coding systems for C and we have |
charset_map_loaded = 0; |
6383 |
already found the other set of coding systems for the |
for (tail = coding_attrs_list; CONSP (tail);) |
6384 |
different characters, get the intersection of them. */ |
{ |
6385 |
if (!EQ (safe_codings, Qt) && !NILP (val)) |
elt = XCAR (tail); |
6386 |
val = intersection (safe_codings, val); |
if (NILP (elt)) |
6387 |
safe_codings = val; |
tail = XCDR (tail); |
6388 |
|
else if (char_encodable_p (c, elt)) |
6389 |
|
tail = XCDR (tail); |
6390 |
|
else if (CONSP (XCDR (tail))) |
6391 |
|
{ |
6392 |
|
XSETCAR (tail, XCAR (XCDR (tail))); |
6393 |
|
XSETCDR (tail, XCDR (XCDR (tail))); |
6394 |
|
} |
6395 |
|
else |
6396 |
|
{ |
6397 |
|
XSETCAR (tail, Qnil); |
6398 |
|
tail = XCDR (tail); |
6399 |
|
} |
6400 |
|
} |
6401 |
|
if (charset_map_loaded) |
6402 |
|
{ |
6403 |
|
EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg; |
6404 |
|
|
6405 |
|
if (STRINGP (start)) |
6406 |
|
pbeg = XSTRING (start)->data; |
6407 |
|
else |
6408 |
|
pbeg = BYTE_POS_ADDR (start_byte); |
6409 |
|
p = pbeg + p_offset; |
6410 |
|
pend = pbeg + pend_offset; |
6411 |
|
} |
6412 |
|
} |
6413 |
} |
} |
6414 |
|
|
6415 |
|
safe_codings = Qnil; |
6416 |
|
for (tail = coding_attrs_list; CONSP (tail); tail = XCDR (tail)) |
6417 |
|
if (! NILP (XCAR (tail))) |
6418 |
|
safe_codings = Fcons (CODING_ATTR_BASE_NAME (XCAR (tail)), safe_codings); |
6419 |
|
|
6420 |
return safe_codings; |
return safe_codings; |
6421 |
} |
} |
6422 |
|
|
6423 |
|
|
6424 |
/* Return a list of coding systems that safely encode the text between |
DEFUN ("check-coding-systems-region", Fcheck_coding_systems_region, |
6425 |
START and END. If the text contains only ASCII or is unibyte, |
Scheck_coding_systems_region, 3, 3, 0, |
6426 |
return t. */ |
doc: /* Check if the region is encodable by coding systems. |
6427 |
|
|
6428 |
DEFUN ("find-coding-systems-region-internal", |
START and END are buffer positions specifying the region. |
6429 |
Ffind_coding_systems_region_internal, |
CODING-SYSTEM-LIST is a list of coding systems to check. |
6430 |
Sfind_coding_systems_region_internal, 2, 2, 0, |
|
6431 |
doc: /* Internal use only. */) |
The value is an alist ((CODING-SYSTEM POS0 POS1 ...) ...), where |
6432 |
(start, end) |
CODING-SYSTEM is a member of CODING-SYSTEM-LIst and can't encode the |
6433 |
Lisp_Object start, end; |
whole region, POS0, POS1, ... are buffer positions where non-encodable |
6434 |
{ |
characters are found. |
6435 |
Lisp_Object work_table, safe_codings; |
|
6436 |
int non_ascii_p = 0; |
If all coding systems in CODING-SYSTEM-LIST can encode the region, the |
6437 |
int single_byte_char_found = 0; |
value is nil. |
6438 |
unsigned char *p1, *p1end, *p2, *p2end, *p; |
|
6439 |
|
START may be a string. In that case, check if the string is |
6440 |
|
encodable, and the value contains indices to the string instead of |
6441 |
|
buffer positions. END is ignored. */) |
6442 |
|
(start, end, coding_system_list) |
6443 |
|
Lisp_Object start, end, coding_system_list; |
6444 |
|
{ |
6445 |
|
Lisp_Object list; |
6446 |
|
EMACS_INT start_byte, end_byte; |
6447 |
|
int pos; |
6448 |
|
unsigned char *p, *pbeg, *pend; |
6449 |
|
int c; |
6450 |
|
Lisp_Object tail, elt; |
6451 |
|
|
6452 |
if (STRINGP (start)) |
if (STRINGP (start)) |
6453 |
{ |
{ |
6454 |
if (!STRING_MULTIBYTE (start)) |
if (!STRING_MULTIBYTE (start) |
6455 |
return Qt; |
&& XSTRING (start)->size != STRING_BYTES (XSTRING (start))) |
6456 |
p1 = XSTRING (start)->data, p1end = p1 + STRING_BYTES (XSTRING (start)); |
return Qnil; |
6457 |
p2 = p2end = p1end; |
start_byte = 0; |
6458 |
if (XSTRING (start)->size != STRING_BYTES (XSTRING (start))) |
end_byte = STRING_BYTES (XSTRING (start)); |
6459 |
non_ascii_p = 1; |
pos = 0; |
6460 |
} |
} |
6461 |
else |
else |
6462 |
{ |
{ |
|
int from, to, stop; |
|
|
|
|
6463 |
CHECK_NUMBER_COERCE_MARKER (start); |
CHECK_NUMBER_COERCE_MARKER (start); |
6464 |
CHECK_NUMBER_COERCE_MARKER (end); |
CHECK_NUMBER_COERCE_MARKER (end); |
6465 |
if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end)) |
if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end)) |
6466 |
args_out_of_range (start, end); |
args_out_of_range (start, end); |
6467 |
if (NILP (current_buffer->enable_multibyte_characters)) |
if (NILP (current_buffer->enable_multibyte_characters)) |
6468 |
|
return Qnil; |
6469 |
|
start_byte = CHAR_TO_BYTE (XINT (start)); |
6470 |
|
end_byte = CHAR_TO_BYTE (XINT (end)); |
6471 |
|
if (XINT (end) - XINT (start) == end_byte - start_byte) |
6472 |
return Qt; |
return Qt; |
6473 |
from = CHAR_TO_BYTE (XINT (start)); |
|
6474 |
to = CHAR_TO_BYTE (XINT (end)); |
if (start < GPT && end > GPT) |
6475 |
stop = from < GPT_BYTE && GPT_BYTE < to ? GPT_BYTE : to; |
{ |
6476 |
p1 = BYTE_POS_ADDR (from), p1end = p1 + (stop - from); |
if ((GPT - start) < (end - GPT)) |
6477 |
if (stop == to) |
move_gap_both (start, start_byte); |
6478 |
p2 = p2end = p1end; |
else |
6479 |
else |
move_gap_both (end, end_byte); |
|
p2 = BYTE_POS_ADDR (stop), p2end = p2 + (to - stop); |
|
|
if (XINT (end) - XINT (start) != to - from) |
|
|
non_ascii_p = 1; |
|
|
} |
|
|
|
|
|
if (!non_ascii_p) |
|
|
{ |
|
|
/* 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) |
|
|
{ |
|
|
for (p = p2; p < p2end && ASCII_BYTE_P (*p); p++); |
|
|
if (p == p2end) |
|
|
return Qt; |
|
6480 |
} |
} |
6481 |
|
pos = start; |
6482 |
} |
} |
6483 |
|
|
6484 |
/* The text contains non-ASCII characters. */ |
list = Qnil; |
6485 |
work_table = Fcopy_sequence (Vchar_coding_system_table); |
for (tail = coding_system_list; CONSP (tail); tail = XCDR (tail)) |
6486 |
safe_codings = find_safe_codings (p1, p1end, Qt, work_table, |
{ |
6487 |
&single_byte_char_found); |
elt = XCAR (tail); |
6488 |
if (p2 < p2end) |
list = Fcons (Fcons (elt, Fcons (AREF (CODING_SYSTEM_SPEC (elt), 0), |
6489 |
safe_codings = find_safe_codings (p2, p2end, safe_codings, work_table, |
Qnil)), |
6490 |
&single_byte_char_found); |
list); |
|
|
|
|
if (EQ (safe_codings, Qt)) |
|
|
; /* Nothing to be done. */ |
|
|
else if (!single_byte_char_found) |
|
|
{ |
|
|
/* Append generic coding systems. */ |
|
|
Lisp_Object args[2]; |
|
|
args[0] = safe_codings; |
|
|
args[1] = Fchar_table_extra_slot (Vchar_coding_system_table, |
|
|
make_number (0)); |
|
|
safe_codings = Fappend (2, args); |
|
6491 |
} |
} |
6492 |
|
|
6493 |
|
if (STRINGP (start)) |
6494 |
|
p = pbeg = XSTRING (start)->data; |
6495 |
else |
else |
6496 |
safe_codings = Fcons (Qraw_text, |
p = pbeg = BYTE_POS_ADDR (start_byte); |
6497 |
Fcons (Qemacs_mule, |
pend = p + (end_byte - start_byte); |
6498 |
Fcons (Qno_conversion, safe_codings))); |
|
6499 |
return safe_codings; |
while (p < pend && ASCII_BYTE_P (*p)) p++, pos++; |
6500 |
|
while (p < pend && ASCII_BYTE_P (*(pend - 1))) pend--; |
6501 |
|
|
6502 |
|
while (p < pend) |
6503 |
|
{ |
6504 |
|
if (ASCII_BYTE_P (*p)) |
6505 |
|
p++; |
6506 |
|
else |
6507 |
|
{ |
6508 |
|
c = STRING_CHAR_ADVANCE (p); |
6509 |
|
|
6510 |
|
charset_map_loaded = 0; |
6511 |
|
for (tail = list; CONSP (tail); tail = XCDR (tail)) |
6512 |
|
{ |
6513 |
|
elt = XCDR (XCAR (tail)); |
6514 |
|
if (! char_encodable_p (c, XCAR (elt))) |
6515 |
|
XSETCDR (elt, Fcons (make_number (pos), XCDR (elt))); |
6516 |
|
} |
6517 |
|
if (charset_map_loaded) |
6518 |
|
{ |
6519 |
|
EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg; |
6520 |
|
|
6521 |
|
if (STRINGP (start)) |
6522 |
|
pbeg = XSTRING (start)->data; |
6523 |
|
else |
6524 |
|
pbeg = BYTE_POS_ADDR (start_byte); |
6525 |
|
p = pbeg + p_offset; |
6526 |
|
pend = pbeg + pend_offset; |
6527 |
|
} |
6528 |
|
} |
6529 |
|
pos++; |
6530 |
|
} |
6531 |
|
|
6532 |
|
tail = list; |
6533 |
|
list = Qnil; |
6534 |
|
for (; CONSP (tail); tail = XCDR (tail)) |
6535 |
|
{ |
6536 |
|
elt = XCAR (tail); |
6537 |
|
if (CONSP (XCDR (XCDR (elt)))) |
6538 |
|
list = Fcons (Fcons (XCAR (elt), Fnreverse (XCDR (XCDR (elt)))), |
6539 |
|
list); |
6540 |
|
} |
6541 |
|
|
6542 |
|
return list; |
6543 |
} |
} |
6544 |
|
|
6545 |
|
|
6546 |
|
|
6547 |
Lisp_Object |
Lisp_Object |
6548 |
code_convert_region1 (start, end, coding_system, encodep) |
code_convert_region (start, end, coding_system, dst_object, encodep, norecord) |
6549 |
Lisp_Object start, end, coding_system; |
Lisp_Object start, end, coding_system, dst_object; |
6550 |
int encodep; |
int encodep, norecord; |
6551 |
{ |
{ |
6552 |
struct coding_system coding; |
struct coding_system coding; |
6553 |
int from, to; |
EMACS_INT from, from_byte, to, to_byte; |
6554 |
|
Lisp_Object src_object; |
6555 |
|
|
6556 |
CHECK_NUMBER_COERCE_MARKER (start); |
CHECK_NUMBER_COERCE_MARKER (start); |
6557 |
CHECK_NUMBER_COERCE_MARKER (end); |
CHECK_NUMBER_COERCE_MARKER (end); |
6558 |
CHECK_SYMBOL (coding_system); |
if (NILP (coding_system)) |
6559 |
|
coding_system = Qno_conversion; |
6560 |
|
else |
6561 |
|
CHECK_CODING_SYSTEM (coding_system); |
6562 |
|
src_object = Fcurrent_buffer (); |
6563 |
|
if (NILP (dst_object)) |
6564 |
|
dst_object = src_object; |
6565 |
|
else if (! EQ (dst_object, Qt)) |
6566 |
|
CHECK_BUFFER (dst_object); |
6567 |
|
|
6568 |
validate_region (&start, &end); |
validate_region (&start, &end); |
6569 |
from = XFASTINT (start); |
from = XFASTINT (start); |
6570 |
|
from_byte = CHAR_TO_BYTE (from); |
6571 |
to = XFASTINT (end); |
to = XFASTINT (end); |
6572 |
|
to_byte = CHAR_TO_BYTE (to); |
6573 |
|
|
6574 |
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", XSYMBOL (coding_system)->name->data); |
|
|
|
|
6575 |
coding.mode |= CODING_MODE_LAST_BLOCK; |
coding.mode |= CODING_MODE_LAST_BLOCK; |
6576 |
coding.src_multibyte = coding.dst_multibyte |
|
6577 |
= !NILP (current_buffer->enable_multibyte_characters); |
if (encodep) |
6578 |
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, |
6579 |
&coding, encodep, 1); |
dst_object); |
6580 |
Vlast_coding_system_used = coding.symbol; |
else |
6581 |
return make_number (coding.produced_char); |
decode_coding_object (&coding, src_object, from, from_byte, to, to_byte, |
6582 |
|
dst_object); |
6583 |
|
if (! norecord) |
6584 |
|
Vlast_coding_system_used = CODING_ID_NAME (coding.id); |
6585 |
|
|
6586 |
|
if (coding.result != CODING_RESULT_SUCCESS) |
6587 |
|
error ("Code conversion error: %d", coding.result); |
6588 |
|
|
6589 |
|
return (BUFFERP (dst_object) |
6590 |
|
? make_number (coding.produced_char) |
6591 |
|
: coding.dst_object); |
6592 |
} |
} |
6593 |
|
|
6594 |
|
|
6595 |
DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region, |
DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region, |
6596 |
3, 3, "r\nzCoding system: ", |
3, 4, "r\nzCoding system: ", |
6597 |
doc: /* Decode the current region from the specified coding system. |
doc: /* Decode the current region from the specified coding system. |
6598 |
When called from a program, takes three arguments: |
When called from a program, takes four arguments: |
6599 |
START, END, and CODING-SYSTEM. START and END are buffer positions. |
START, END, CODING-SYSTEM, and DESTINATION. |
6600 |
|
START and END are buffer positions. |
6601 |
|
|
6602 |
|
Optional 4th arguments DESTINATION specifies where the decoded text goes. |
6603 |
|
If nil, the region between START and END is replace by the decoded text. |
6604 |
|
If buffer, the decoded text is inserted in the buffer. |
6605 |
|
If t, the decoded text is returned. |
6606 |
|
|
6607 |
This function sets `last-coding-system-used' to the precise coding system |
This function sets `last-coding-system-used' to the precise coding system |
6608 |
used (which may be different from CODING-SYSTEM if CODING-SYSTEM is |
used (which may be different from CODING-SYSTEM if CODING-SYSTEM is |
6609 |
not fully specified.) |
not fully specified.) |
6610 |
It returns the length of the decoded text. */) |
It returns the length of the decoded text. */) |
6611 |
(start, end, coding_system) |
(start, end, coding_system, destination) |
6612 |
Lisp_Object start, end, coding_system; |
Lisp_Object start, end, coding_system, destination; |
6613 |
{ |
{ |
6614 |
return code_convert_region1 (start, end, coding_system, 0); |
return code_convert_region (start, end, coding_system, destination, 0, 0); |
6615 |
} |
} |
6616 |
|
|
6617 |
DEFUN ("encode-coding-region", Fencode_coding_region, Sencode_coding_region, |
DEFUN ("encode-coding-region", Fencode_coding_region, Sencode_coding_region, |
6618 |
3, 3, "r\nzCoding system: ", |
3, 4, "r\nzCoding system: ", |
6619 |
doc: /* Encode the current region into the specified coding system. |
doc: /* Encode the current region by specified coding system. |
6620 |
When called from a program, takes three arguments: |
When called from a program, takes three arguments: |
6621 |
START, END, and CODING-SYSTEM. START and END are buffer positions. |
START, END, and CODING-SYSTEM. START and END are buffer positions. |
6622 |
|
|
6623 |
|
Optional 4th arguments DESTINATION specifies where the encoded text goes. |
6624 |
|
If nil, the region between START and END is replace by the encoded text. |
6625 |
|
If buffer, the encoded text is inserted in the buffer. |
6626 |
|
If t, the encoded text is returned. |
6627 |
|
|
6628 |
This function sets `last-coding-system-used' to the precise coding system |
This function sets `last-coding-system-used' to the precise coding system |
6629 |
used (which may be different from CODING-SYSTEM if CODING-SYSTEM is |
used (which may be different from CODING-SYSTEM if CODING-SYSTEM is |
6630 |
not fully specified.) |
not fully specified.) |
6631 |
It returns the length of the encoded text. */) |
It returns the length of the encoded text. */) |
6632 |
(start, end, coding_system) |
(start, end, coding_system, destination) |
6633 |
Lisp_Object start, end, coding_system; |
Lisp_Object start, end, coding_system, destination; |
6634 |
{ |
{ |
6635 |
return code_convert_region1 (start, end, coding_system, 1); |
return code_convert_region (start, end, coding_system, destination, 1, 0); |
6636 |
} |
} |
6637 |
|
|
6638 |
Lisp_Object |
Lisp_Object |
6639 |
code_convert_string1 (string, coding_system, nocopy, encodep) |
code_convert_string (string, coding_system, dst_object, |
6640 |
Lisp_Object string, coding_system, nocopy; |
encodep, nocopy, norecord) |
6641 |
int encodep; |
Lisp_Object string, coding_system, dst_object; |
6642 |
|
int encodep, nocopy, norecord; |
6643 |
{ |
{ |
6644 |
struct coding_system coding; |
struct coding_system coding; |
6645 |
|
EMACS_INT chars, bytes; |
6646 |
|
|
6647 |
CHECK_STRING (string); |
CHECK_STRING (string); |
|
CHECK_SYMBOL (coding_system); |
|
|
|
|
6648 |
if (NILP (coding_system)) |
if (NILP (coding_system)) |
6649 |
return (NILP (nocopy) ? Fcopy_sequence (string) : string); |
{ |
6650 |
|
if (! norecord) |
6651 |
|
Vlast_coding_system_used = Qno_conversion; |
6652 |
|
if (NILP (dst_object)) |
6653 |
|
return (nocopy ? Fcopy_sequence (string) : string); |
6654 |
|
} |
6655 |
|
|
6656 |
if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0) |
if (NILP (coding_system)) |
6657 |
error ("Invalid coding system: %s", XSYMBOL (coding_system)->name->data); |
coding_system = Qno_conversion; |
6658 |
|
else |
6659 |
|
CHECK_CODING_SYSTEM (coding_system); |
6660 |
|
if (NILP (dst_object)) |
6661 |
|
dst_object = Qt; |
6662 |
|
else if (! EQ (dst_object, Qt)) |
6663 |
|
CHECK_BUFFER (dst_object); |
6664 |
|
|
6665 |
|
setup_coding_system (coding_system, &coding); |
6666 |
coding.mode |= CODING_MODE_LAST_BLOCK; |
coding.mode |= CODING_MODE_LAST_BLOCK; |
6667 |
string = (encodep |
chars = XSTRING (string)->size; |
6668 |
? encode_coding_string (string, &coding, !NILP (nocopy)) |
bytes = STRING_BYTES (XSTRING (string)); |
6669 |
: decode_coding_string (string, &coding, !NILP (nocopy))); |
if (encodep) |
6670 |
Vlast_coding_system_used = coding.symbol; |
encode_coding_object (&coding, string, 0, 0, chars, bytes, dst_object); |
6671 |
|
else |
6672 |
return string; |
decode_coding_object (&coding, string, 0, 0, chars, bytes, dst_object); |
6673 |
|
if (! norecord) |
6674 |
|
Vlast_coding_system_used = CODING_ID_NAME (coding.id); |
6675 |
|
|
6676 |
|
if (coding.result != CODING_RESULT_SUCCESS) |
6677 |
|
error ("Code conversion error: %d", coding.result); |
6678 |
|
|
6679 |
|
return (BUFFERP (dst_object) |
6680 |
|
? make_number (coding.produced_char) |
6681 |
|
: coding.dst_object); |
6682 |
} |
} |
6683 |
|
|
|
DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string, |
|
|
2, 3, 0, |
|
|
doc: /* Decode STRING which is encoded in CODING-SYSTEM, and return the result. |
|
|
Optional arg NOCOPY non-nil means it is OK to return STRING itself |
|
|
if the decoding 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, 0); |
|
|
} |
|
|
|
|
|
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); |
|
|
} |
|
6684 |
|
|
6685 |
/* Encode or decode STRING according to CODING_SYSTEM. |
/* Encode or decode STRING according to CODING_SYSTEM. |
6686 |
Do not set Vlast_coding_system_used. |
Do not set Vlast_coding_system_used. |
6693 |
Lisp_Object string, coding_system; |
Lisp_Object string, coding_system; |
6694 |
int encodep; |
int encodep; |
6695 |
{ |
{ |
6696 |
struct coding_system coding; |
code_convert_string (string, coding_system, Qt, encodep, 0, 1); |
6697 |
|
} |
6698 |
|
|
|
CHECK_STRING (string); |
|
|
CHECK_SYMBOL (coding_system); |
|
6699 |
|
|
6700 |
if (NILP (coding_system)) |
DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string, |
6701 |
return string; |
2, 4, 0, |
6702 |
|
doc: /* Decode STRING which is encoded in CODING-SYSTEM, and return the result. |
6703 |
|
|
6704 |
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 |
6705 |
error ("Invalid coding system: %s", XSYMBOL (coding_system)->name->data); |
if the decoding operation is trivial. |
6706 |
|
|
6707 |
coding.composing = COMPOSITION_DISABLED; |
Optional fourth arg BUFFER non-nil meant that the decoded text is |
6708 |
coding.mode |= CODING_MODE_LAST_BLOCK; |
inserted in BUFFER instead of returned as a astring. In this case, |
6709 |
return (encodep |
the return value is BUFFER. |
6710 |
? encode_coding_string (string, &coding, 1) |
|
6711 |
: decode_coding_string (string, &coding, 1)); |
This function sets `last-coding-system-used' to the precise coding system |
6712 |
|
used (which may be different from CODING-SYSTEM if CODING-SYSTEM is |
6713 |
|
not fully specified. */) |
6714 |
|
(string, coding_system, nocopy, buffer) |
6715 |
|
Lisp_Object string, coding_system, nocopy, buffer; |
6716 |
|
{ |
6717 |
|
return code_convert_string (string, coding_system, buffer, |
6718 |
|
0, ! NILP (nocopy), 0); |
6719 |
} |
} |
6720 |
|
|
6721 |
|
DEFUN ("encode-coding-string", Fencode_coding_string, Sencode_coding_string, |
6722 |
|
2, 4, 0, |
6723 |
|
doc: /* Encode STRING to CODING-SYSTEM, and return the result. |
6724 |
|
|
6725 |
|
Optional third arg NOCOPY non-nil means it is OK to return STRING |
6726 |
|
itself if the encoding operation is trivial. |
6727 |
|
|
6728 |
|
Optional fourth arg BUFFER non-nil meant that the encoded text is |
6729 |
|
inserted in BUFFER instead of returned as a astring. In this case, |
6730 |
|
the return value is BUFFER. |
6731 |
|
|
6732 |
|
This function sets `last-coding-system-used' to the precise coding system |
6733 |
|
used (which may be different from CODING-SYSTEM if CODING-SYSTEM is |
6734 |
|
not fully specified.) */) |
6735 |
|
(string, coding_system, nocopy, buffer) |
6736 |
|
Lisp_Object string, coding_system, nocopy, buffer; |
6737 |
|
{ |
6738 |
|
return code_convert_string (string, coding_system, buffer, |
6739 |
|
nocopy, ! NILP (nocopy), 1); |
6740 |
|
} |
6741 |
|
|
6742 |
|
|
6743 |
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, |
6744 |
doc: /* Decode a Japanese character which has CODE in shift_jis encoding. |
doc: /* Decode a Japanese character which has CODE in shift_jis encoding. |
6746 |
(code) |
(code) |
6747 |
Lisp_Object code; |
Lisp_Object code; |
6748 |
{ |
{ |
6749 |
unsigned char c1, c2, s1, s2; |
Lisp_Object spec, attrs, val; |
6750 |
Lisp_Object val; |
struct charset *charset_roman, *charset_kanji, *charset_kana, *charset; |
6751 |
|
int c; |
6752 |
|
|
6753 |
CHECK_NUMBER (code); |
CHECK_NATNUM (code); |
6754 |
s1 = (XFASTINT (code)) >> 8, s2 = (XFASTINT (code)) & 0xFF; |
c = XFASTINT (code); |
6755 |
if (s1 == 0) |
CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec); |
6756 |
{ |
attrs = AREF (spec, 0); |
6757 |
if (s2 < 0x80) |
|
6758 |
XSETFASTINT (val, s2); |
if (ASCII_BYTE_P (c) |
6759 |
else if (s2 >= 0xA0 || s2 <= 0xDF) |
&& ! NILP (CODING_ATTR_ASCII_COMPAT (attrs))) |
6760 |
XSETFASTINT (val, MAKE_CHAR (charset_katakana_jisx0201, s2, 0)); |
return code; |
6761 |
else |
|
6762 |
error ("Invalid Shift JIS code: %x", XFASTINT (code)); |
val = CODING_ATTR_CHARSET_LIST (attrs); |
6763 |
|
charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
6764 |
|
charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
6765 |
|
charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))); |
6766 |
|
|
6767 |
|
if (c <= 0x7F) |
6768 |
|
charset = charset_roman; |
6769 |
|
else if (c >= 0xA0 && c < 0xDF) |
6770 |
|
{ |
6771 |
|
charset = charset_kana; |
6772 |
|
c -= 0x80; |
6773 |
} |
} |
6774 |
else |
else |
6775 |
{ |
{ |
6776 |
if ((s1 < 0x80 || (s1 > 0x9F && s1 < 0xE0) || s1 > 0xEF) |
int s1 = c >> 8, s2 = c & 0x7F; |
6777 |
|| (s2 < 0x40 || s2 == 0x7F || s2 > 0xFC)) |
|
6778 |
error ("Invalid Shift JIS code: %x", XFASTINT (code)); |
if (s1 < 0x81 || (s1 > 0x9F && s1 < 0xE0) || s1 > 0xEF |
6779 |
DECODE_SJIS (s1, s2, c1, c2); |
|| s2 < 0x40 || s2 == 0x7F || s2 > 0xFC) |
6780 |
XSETFASTINT (val, MAKE_CHAR (charset_jisx0208, c1, c2)); |
error ("Invalid code: %d", code); |
6781 |
} |
SJIS_TO_JIS (c); |
6782 |
return val; |
charset = charset_kanji; |
6783 |
|
} |
6784 |
|
c = DECODE_CHAR (charset, c); |
6785 |
|
if (c < 0) |
6786 |
|
error ("Invalid code: %d", code); |
6787 |
|
return make_number (c); |
6788 |
} |
} |
6789 |
|
|
6790 |
|
|
6791 |
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, |
6792 |
doc: /* Encode a Japanese character CHAR to shift_jis encoding. |
doc: /* Encode a Japanese character CHAR to shift_jis encoding. |
6793 |
Return the corresponding code in SJIS. */) |
Return the corresponding code in SJIS. */) |
6794 |
(ch) |
(ch) |
6795 |
Lisp_Object ch; |
Lisp_Object ch; |
6796 |
{ |
{ |
6797 |
int charset, c1, c2, s1, s2; |
Lisp_Object spec, attrs, charset_list; |
6798 |
Lisp_Object val; |
int c; |
6799 |
|
struct charset *charset; |
6800 |
|
unsigned code; |
6801 |
|
|
6802 |
CHECK_NUMBER (ch); |
CHECK_CHARACTER (ch); |
6803 |
SPLIT_CHAR (XFASTINT (ch), charset, c1, c2); |
c = XFASTINT (ch); |
6804 |
if (charset == CHARSET_ASCII) |
CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec); |
6805 |
{ |
attrs = AREF (spec, 0); |
6806 |
val = ch; |
|
6807 |
} |
if (ASCII_CHAR_P (c) |
6808 |
else if (charset == charset_jisx0208 |
&& ! NILP (CODING_ATTR_ASCII_COMPAT (attrs))) |
6809 |
&& c1 > 0x20 && c1 < 0x7F && c2 > 0x20 && c2 < 0x7F) |
return ch; |
6810 |
{ |
|
6811 |
ENCODE_SJIS (c1, c2, s1, s2); |
charset_list = CODING_ATTR_CHARSET_LIST (attrs); |
6812 |
XSETFASTINT (val, (s1 << 8) | s2); |
charset = char_charset (c, charset_list, &code); |
6813 |
} |
if (code == CHARSET_INVALID_CODE (charset)) |
6814 |
else if (charset == charset_katakana_jisx0201 |
error ("Can't encode by shift_jis encoding: %d", c); |
6815 |
&& c1 > 0x20 && c2 < 0xE0) |
JIS_TO_SJIS (code); |
6816 |
{ |
|
6817 |
XSETFASTINT (val, c1 | 0x80); |
return make_number (code); |
|
} |
|
|
else |
|
|
error ("Can't encode to shift_jis: %d", XFASTINT (ch)); |
|
|
return val; |
|
6818 |
} |
} |
6819 |
|
|
6820 |
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, |
6823 |
(code) |
(code) |
6824 |
Lisp_Object code; |
Lisp_Object code; |
6825 |
{ |
{ |
6826 |
int charset; |
Lisp_Object spec, attrs, val; |
6827 |
unsigned char b1, b2, c1, c2; |
struct charset *charset_roman, *charset_big5, *charset; |
6828 |
Lisp_Object val; |
int c; |
6829 |
|
|
6830 |
CHECK_NUMBER (code); |
CHECK_NATNUM (code); |
6831 |
b1 = (XFASTINT (code)) >> 8, b2 = (XFASTINT (code)) & 0xFF; |
c = XFASTINT (code); |
6832 |
if (b1 == 0) |
CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec); |
6833 |
{ |
attrs = AREF (spec, 0); |
6834 |
if (b2 >= 0x80) |
|
6835 |
error ("Invalid BIG5 code: %x", XFASTINT (code)); |
if (ASCII_BYTE_P (c) |
6836 |
val = code; |
&& ! NILP (CODING_ATTR_ASCII_COMPAT (attrs))) |
6837 |
} |
return code; |
6838 |
|
|
6839 |
|
val = CODING_ATTR_CHARSET_LIST (attrs); |
6840 |
|
charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val); |
6841 |
|
charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val))); |
6842 |
|
|
6843 |
|
if (c <= 0x7F) |
6844 |
|
charset = charset_roman; |
6845 |
else |
else |
6846 |
{ |
{ |
6847 |
if ((b1 < 0xA1 || b1 > 0xFE) |
int b1 = c >> 8, b2 = c & 0x7F; |
6848 |
|| (b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE)) |
if (b1 < 0xA1 || b1 > 0xFE |
6849 |
error ("Invalid BIG5 code: %x", XFASTINT (code)); |
|| b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE) |
6850 |
DECODE_BIG5 (b1, b2, charset, c1, c2); |
error ("Invalid code: %d", code); |
6851 |
XSETFASTINT (val, MAKE_CHAR (charset, c1, c2)); |
charset = charset_big5; |
6852 |
} |
} |
6853 |
return val; |
c = DECODE_CHAR (charset, (unsigned )c); |
6854 |
|
if (c < 0) |
6855 |
|
error ("Invalid code: %d", code); |
6856 |
|
return make_number (c); |
6857 |
} |
} |
6858 |
|
|
6859 |
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, |
6862 |
(ch) |
(ch) |
6863 |
Lisp_Object ch; |
Lisp_Object ch; |
6864 |
{ |
{ |
6865 |
int charset, c1, c2, b1, b2; |
Lisp_Object spec, attrs, charset_list; |
6866 |
Lisp_Object val; |
struct charset *charset; |
6867 |
|
int c; |
6868 |
|
unsigned code; |
6869 |
|
|
6870 |
CHECK_NUMBER (ch); |
CHECK_CHARACTER (ch); |
6871 |
SPLIT_CHAR (XFASTINT (ch), charset, c1, c2); |
c = XFASTINT (ch); |
6872 |
if (charset == CHARSET_ASCII) |
CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec); |
6873 |
{ |
attrs = AREF (spec, 0); |
6874 |
val = ch; |
if (ASCII_CHAR_P (c) |
6875 |
} |
&& ! NILP (CODING_ATTR_ASCII_COMPAT (attrs))) |
6876 |
else if ((charset == charset_big5_1 |
return ch; |
6877 |
&& (XFASTINT (ch) >= 0x250a1 && XFASTINT (ch) <= 0x271ec)) |
|
6878 |
|| (charset == charset_big5_2 |
charset_list = CODING_ATTR_CHARSET_LIST (attrs); |
6879 |
&& XFASTINT (ch) >= 0x290a1 && XFASTINT (ch) <= 0x2bdb2)) |
charset = char_charset (c, charset_list, &code); |
6880 |
{ |
if (code == CHARSET_INVALID_CODE (charset)) |
6881 |
ENCODE_BIG5 (charset, c1, c2, b1, b2); |
error ("Can't encode by Big5 encoding: %d", c); |
6882 |
XSETFASTINT (val, (b1 << 8) | b2); |
|
6883 |
} |
return make_number (code); |
|
else |
|
|
error ("Can't encode to Big5: %d", XFASTINT (ch)); |
|
|
return val; |
|
6884 |
} |
} |
6885 |
|
|
6886 |
|
|
6887 |
DEFUN ("set-terminal-coding-system-internal", |
DEFUN ("set-terminal-coding-system-internal", |
6888 |
Fset_terminal_coding_system_internal, |
Fset_terminal_coding_system_internal, |
6889 |
Sset_terminal_coding_system_internal, 1, 1, 0, |
Sset_terminal_coding_system_internal, 1, 1, 0, |
6890 |
doc: /* Internal use only. */) |
doc: /* Internal use only. */) |
6891 |
(coding_system) |
(coding_system) |
|
Lisp_Object coding_system; |
|
6892 |
{ |
{ |
6893 |
CHECK_SYMBOL (coding_system); |
CHECK_SYMBOL (coding_system); |
6894 |
setup_coding_system (Fcheck_coding_system (coding_system), &terminal_coding); |
setup_coding_system (Fcheck_coding_system (coding_system), |
6895 |
|
&terminal_coding); |
6896 |
|
|
6897 |
/* We had better not send unsafe characters to terminal. */ |
/* We had better not send unsafe characters to terminal. */ |
6898 |
terminal_coding.flags |= CODING_FLAG_ISO_SAFE; |
terminal_coding.mode |= CODING_MODE_SAFE_ENCODING; |
6899 |
/* Character composition should be disabled. */ |
/* Characer composition should be disabled. */ |
6900 |
terminal_coding.composing = COMPOSITION_DISABLED; |
terminal_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK; |
|
/* Error notification should be suppressed. */ |
|
|
terminal_coding.suppress_error = 1; |
|
6901 |
terminal_coding.src_multibyte = 1; |
terminal_coding.src_multibyte = 1; |
6902 |
terminal_coding.dst_multibyte = 0; |
terminal_coding.dst_multibyte = 0; |
6903 |
return Qnil; |
return Qnil; |
6908 |
Sset_safe_terminal_coding_system_internal, 1, 1, 0, |
Sset_safe_terminal_coding_system_internal, 1, 1, 0, |
6909 |
doc: /* Internal use only. */) |
doc: /* Internal use only. */) |
6910 |
(coding_system) |
(coding_system) |
|
Lisp_Object coding_system; |
|
6911 |
{ |
{ |
6912 |
CHECK_SYMBOL (coding_system); |
CHECK_SYMBOL (coding_system); |
6913 |
setup_coding_system (Fcheck_coding_system (coding_system), |
setup_coding_system (Fcheck_coding_system (coding_system), |
6914 |
&safe_terminal_coding); |
&safe_terminal_coding); |
6915 |
/* Character composition should be disabled. */ |
/* Characer composition should be disabled. */ |
6916 |
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; |
|
6917 |
safe_terminal_coding.src_multibyte = 1; |
safe_terminal_coding.src_multibyte = 1; |
6918 |
safe_terminal_coding.dst_multibyte = 0; |
safe_terminal_coding.dst_multibyte = 0; |
6919 |
return Qnil; |
return Qnil; |
6924 |
doc: /* Return coding system specified for terminal output. */) |
doc: /* Return coding system specified for terminal output. */) |
6925 |
() |
() |
6926 |
{ |
{ |
6927 |
return terminal_coding.symbol; |
return CODING_ID_NAME (terminal_coding.id); |
6928 |
} |
} |
6929 |
|
|
6930 |
DEFUN ("set-keyboard-coding-system-internal", |
DEFUN ("set-keyboard-coding-system-internal", |
6935 |
Lisp_Object coding_system; |
Lisp_Object coding_system; |
6936 |
{ |
{ |
6937 |
CHECK_SYMBOL (coding_system); |
CHECK_SYMBOL (coding_system); |
6938 |
setup_coding_system (Fcheck_coding_system (coding_system), &keyboard_coding); |
setup_coding_system (Fcheck_coding_system (coding_system), |
6939 |
/* Character composition should be disabled. */ |
&keyboard_coding); |
6940 |
keyboard_coding.composing = COMPOSITION_DISABLED; |
/* Characer composition should be disabled. */ |
6941 |
|
keyboard_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK; |
6942 |
return Qnil; |
return Qnil; |
6943 |
} |
} |
6944 |
|
|
6947 |
doc: /* Return coding system specified for decoding keyboard input. */) |
doc: /* Return coding system specified for decoding keyboard input. */) |
6948 |
() |
() |
6949 |
{ |
{ |
6950 |
return keyboard_coding.symbol; |
return CODING_ID_NAME (keyboard_coding.id); |
6951 |
} |
} |
6952 |
|
|
6953 |
|
|
6995 |
operation = args[0]; |
operation = args[0]; |
6996 |
if (!SYMBOLP (operation) |
if (!SYMBOLP (operation) |
6997 |
|| !INTEGERP (target_idx = Fget (operation, Qtarget_idx))) |
|| !INTEGERP (target_idx = Fget (operation, Qtarget_idx))) |
6998 |
error ("Invalid first argument"); |
error ("Invalid first arguement"); |
6999 |
if (nargs < 1 + XINT (target_idx)) |
if (nargs < 1 + XINT (target_idx)) |
7000 |
error ("Too few arguments for operation: %s", |
error ("Too few arguments for operation: %s", |
7001 |
XSYMBOL (operation)->name->data); |
XSYMBOL (operation)->name->data); |
7002 |
target = args[XINT (target_idx) + 1]; |
target = args[XINT (target_idx) + 1]; |
7003 |
if (!(STRINGP (target) |
if (!(STRINGP (target) |
7004 |
|| (EQ (operation, Qopen_network_stream) && INTEGERP (target)))) |
|| (EQ (operation, Qopen_network_stream) && INTEGERP (target)))) |
7005 |
error ("Invalid argument %d", XINT (target_idx) + 1); |
error ("Invalid %dth argument", XINT (target_idx) + 1); |
7006 |
|
|
7007 |
chain = ((EQ (operation, Qinsert_file_contents) |
chain = ((EQ (operation, Qinsert_file_contents) |
7008 |
|| EQ (operation, Qwrite_region)) |
|| EQ (operation, Qwrite_region)) |
7016 |
for (; CONSP (chain); chain = XCDR (chain)) |
for (; CONSP (chain); chain = XCDR (chain)) |
7017 |
{ |
{ |
7018 |
Lisp_Object elt; |
Lisp_Object elt; |
|
elt = XCAR (chain); |
|
7019 |
|
|
7020 |
|
elt = XCAR (chain); |
7021 |
if (CONSP (elt) |
if (CONSP (elt) |
7022 |
&& ((STRINGP (target) |
&& ((STRINGP (target) |
7023 |
&& STRINGP (XCAR (elt)) |
&& STRINGP (XCAR (elt)) |
7047 |
return Qnil; |
return Qnil; |
7048 |
} |
} |
7049 |
|
|
7050 |
DEFUN ("update-coding-systems-internal", Fupdate_coding_systems_internal, |
DEFUN ("set-coding-system-priority", Fset_coding_system_priority, |
7051 |
Supdate_coding_systems_internal, 0, 0, 0, |
Sset_coding_system_priority, 1, MANY, 0, |
7052 |
doc: /* Update internal database for ISO2022 and CCL based coding systems. |
doc: /* Put higher priority to coding systems of the arguments. */) |
7053 |
When values of any coding categories are changed, you must |
(nargs, args) |
7054 |
call this function. */) |
int nargs; |
7055 |
() |
Lisp_Object *args; |
7056 |
|
{ |
7057 |
|
int i, j; |
7058 |
|
int changed[coding_category_max]; |
7059 |
|
enum coding_category priorities[coding_category_max]; |
7060 |
|
|
7061 |
|
bzero (changed, sizeof changed); |
7062 |
|
|
7063 |
|
for (i = j = 0; i < nargs; i++) |
7064 |
|
{ |
7065 |
|
enum coding_category category; |
7066 |
|
Lisp_Object spec, attrs; |
7067 |
|
|
7068 |
|
CHECK_CODING_SYSTEM_GET_SPEC (args[i], spec); |
7069 |
|
attrs = AREF (spec, 0); |
7070 |
|
category = XINT (CODING_ATTR_CATEGORY (attrs)); |
7071 |
|
if (changed[category]) |
7072 |
|
/* Ignore this coding system because a coding system of the |
7073 |
|
same category already had a higher priority. */ |
7074 |
|
continue; |
7075 |
|
changed[category] = 1; |
7076 |
|
priorities[j++] = category; |
7077 |
|
if (coding_categories[category].id >= 0 |
7078 |
|
&& ! EQ (args[i], CODING_ID_NAME (coding_categories[category].id))) |
7079 |
|
setup_coding_system (args[i], &coding_categories[category]); |
7080 |
|
} |
7081 |
|
|
7082 |
|
/* Now we have decided top J priorities. Reflect the order of the |
7083 |
|
original priorities to the remaining priorities. */ |
7084 |
|
|
7085 |
|
for (i = j, j = 0; i < coding_category_max; i++, j++) |
7086 |
|
{ |
7087 |
|
while (j < coding_category_max |
7088 |
|
&& changed[coding_priorities[j]]) |
7089 |
|
j++; |
7090 |
|
if (j == coding_category_max) |
7091 |
|
abort (); |
7092 |
|
priorities[i] = coding_priorities[j]; |
7093 |
|
} |
7094 |
|
|
7095 |
|
bcopy (priorities, coding_priorities, sizeof priorities); |
7096 |
|
return Qnil; |
7097 |
|
} |
7098 |
|
|
7099 |
|
DEFUN ("coding-system-priority-list", Fcoding_system_priority_list, |
7100 |
|
Scoding_system_priority_list, 0, 1, 0, |
7101 |
|
doc: /* Return a list of coding systems ordered by their priorities. */) |
7102 |
|
(highestp) |
7103 |
|
Lisp_Object highestp; |
7104 |
{ |
{ |
7105 |
int i; |
int i; |
7106 |
|
Lisp_Object val; |
7107 |
|
|
7108 |
for (i = CODING_CATEGORY_IDX_EMACS_MULE; i < CODING_CATEGORY_IDX_MAX; i++) |
for (i = 0, val = Qnil; i < coding_category_max; i++) |
7109 |
{ |
{ |
7110 |
Lisp_Object val; |
enum coding_category category = coding_priorities[i]; |
7111 |
|
int id = coding_categories[category].id; |
7112 |
|
Lisp_Object attrs; |
7113 |
|
|
7114 |
|
if (id < 0) |
7115 |
|
continue; |
7116 |
|
attrs = CODING_ID_ATTRS (id); |
7117 |
|
if (! NILP (highestp)) |
7118 |
|
return CODING_ATTR_BASE_NAME (attrs); |
7119 |
|
val = Fcons (CODING_ATTR_BASE_NAME (attrs), val); |
7120 |
|
} |
7121 |
|
return Fnreverse (val); |
7122 |
|
} |
7123 |
|
|
7124 |
|
static Lisp_Object |
7125 |
|
make_subsidiaries (base) |
7126 |
|
Lisp_Object base; |
7127 |
|
{ |
7128 |
|
Lisp_Object subsidiaries; |
7129 |
|
char *suffixes[] = { "-unix", "-dos", "-mac" }; |
7130 |
|
int base_name_len = STRING_BYTES (XSYMBOL (base)->name); |
7131 |
|
char *buf = (char *) alloca (base_name_len + 6); |
7132 |
|
int i; |
7133 |
|
|
7134 |
|
bcopy (XSYMBOL (base)->name->data, buf, base_name_len); |
7135 |
|
subsidiaries = Fmake_vector (make_number (3), Qnil); |
7136 |
|
for (i = 0; i < 3; i++) |
7137 |
|
{ |
7138 |
|
bcopy (suffixes[i], buf + base_name_len, strlen (suffixes[i]) + 1); |
7139 |
|
ASET (subsidiaries, i, intern (buf)); |
7140 |
|
} |
7141 |
|
return subsidiaries; |
7142 |
|
} |
7143 |
|
|
7144 |
val = SYMBOL_VALUE (XVECTOR (Vcoding_category_table)->contents[i]); |
|
7145 |
if (!NILP (val)) |
DEFUN ("define-coding-system-internal", Fdefine_coding_system_internal, |
7146 |
|
Sdefine_coding_system_internal, coding_arg_max, MANY, 0, |
7147 |
|
doc: /* For internal use only. */) |
7148 |
|
(nargs, args) |
7149 |
|
int nargs; |
7150 |
|
Lisp_Object *args; |
7151 |
|
{ |
7152 |
|
Lisp_Object name; |
7153 |
|
Lisp_Object spec_vec; /* [ ATTRS ALIASE EOL_TYPE ] */ |
7154 |
|
Lisp_Object attrs; /* Vector of attributes. */ |
7155 |
|
Lisp_Object eol_type; |
7156 |
|
Lisp_Object aliases; |
7157 |
|
Lisp_Object coding_type, charset_list, safe_charsets; |
7158 |
|
enum coding_category category; |
7159 |
|
Lisp_Object tail, val; |
7160 |
|
int max_charset_id = 0; |
7161 |
|
int i; |
7162 |
|
|
7163 |
|
if (nargs < coding_arg_max) |
7164 |
|
goto short_args; |
7165 |
|
|
7166 |
|
attrs = Fmake_vector (make_number (coding_attr_last_index), Qnil); |
7167 |
|
|
7168 |
|
name = args[coding_arg_name]; |
7169 |
|
CHECK_SYMBOL (name); |
7170 |
|
CODING_ATTR_BASE_NAME (attrs) = name; |
7171 |
|
|
7172 |
|
val = args[coding_arg_mnemonic]; |
7173 |
|
if (! STRINGP (val)) |
7174 |
|
CHECK_CHARACTER (val); |
7175 |
|
CODING_ATTR_MNEMONIC (attrs) = val; |
7176 |
|
|
7177 |
|
coding_type = args[coding_arg_coding_type]; |
7178 |
|
CHECK_SYMBOL (coding_type); |
7179 |
|
CODING_ATTR_TYPE (attrs) = coding_type; |
7180 |
|
|
7181 |
|
charset_list = args[coding_arg_charset_list]; |
7182 |
|
if (SYMBOLP (charset_list)) |
7183 |
|
{ |
7184 |
|
if (EQ (charset_list, Qiso_2022)) |
7185 |
{ |
{ |
7186 |
if (! coding_system_table[i]) |
if (! EQ (coding_type, Qiso_2022)) |
7187 |
coding_system_table[i] = ((struct coding_system *) |
error ("Invalid charset-list"); |
7188 |
xmalloc (sizeof (struct coding_system))); |
charset_list = Viso_2022_charset_list; |
|
setup_coding_system (val, coding_system_table[i]); |
|
7189 |
} |
} |
7190 |
else if (coding_system_table[i]) |
else if (EQ (charset_list, Qemacs_mule)) |
7191 |
{ |
{ |
7192 |
xfree (coding_system_table[i]); |
if (! EQ (coding_type, Qemacs_mule)) |
7193 |
coding_system_table[i] = NULL; |
error ("Invalid charset-list"); |
7194 |
|
charset_list = Vemacs_mule_charset_list; |
7195 |
} |
} |
7196 |
|
for (tail = charset_list; CONSP (tail); tail = XCDR (tail)) |
7197 |
|
if (max_charset_id < XFASTINT (XCAR (tail))) |
7198 |
|
max_charset_id = XFASTINT (XCAR (tail)); |
7199 |
} |
} |
7200 |
|
else |
7201 |
|
{ |
7202 |
|
charset_list = Fcopy_sequence (charset_list); |
7203 |
|
for (tail = charset_list; !NILP (tail); tail = Fcdr (tail)) |
7204 |
|
{ |
7205 |
|
struct charset *charset; |
7206 |
|
|
7207 |
return Qnil; |
val = Fcar (tail); |
7208 |
} |
CHECK_CHARSET_GET_CHARSET (val, charset); |
7209 |
|
if (EQ (coding_type, Qiso_2022) |
7210 |
|
? CHARSET_ISO_FINAL (charset) < 0 |
7211 |
|
: EQ (coding_type, Qemacs_mule) |
7212 |
|
? CHARSET_EMACS_MULE_ID (charset) < 0 |
7213 |
|
: 0) |
7214 |
|
error ("Can't handle charset `%s'", |
7215 |
|
XSYMBOL (CHARSET_NAME (charset))->name->data); |
7216 |
|
|
7217 |
|
XCAR (tail) = make_number (charset->id); |
7218 |
|
if (max_charset_id < charset->id) |
7219 |
|
max_charset_id = charset->id; |
7220 |
|
} |
7221 |
|
} |
7222 |
|
CODING_ATTR_CHARSET_LIST (attrs) = charset_list; |
7223 |
|
|
7224 |
|
safe_charsets = Fmake_string (make_number (max_charset_id + 1), |
7225 |
|
make_number (255)); |
7226 |
|
for (tail = charset_list; CONSP (tail); tail = XCDR (tail)) |
7227 |
|
XSTRING (safe_charsets)->data[XFASTINT (XCAR (tail))] = 0; |
7228 |
|
CODING_ATTR_SAFE_CHARSETS (attrs) = safe_charsets; |
7229 |
|
|
7230 |
|
val = args[coding_arg_decode_translation_table]; |
7231 |
|
if (! NILP (val)) |
7232 |
|
CHECK_CHAR_TABLE (val); |
7233 |
|
CODING_ATTR_DECODE_TBL (attrs) = val; |
7234 |
|
|
7235 |
|
val = args[coding_arg_encode_translation_table]; |
7236 |
|
if (! NILP (val)) |
7237 |
|
CHECK_CHAR_TABLE (val); |
7238 |
|
CODING_ATTR_ENCODE_TBL (attrs) = val; |
7239 |
|
|
7240 |
|
val = args[coding_arg_post_read_conversion]; |
7241 |
|
CHECK_SYMBOL (val); |
7242 |
|
CODING_ATTR_POST_READ (attrs) = val; |
7243 |
|
|
7244 |
|
val = args[coding_arg_pre_write_conversion]; |
7245 |
|
CHECK_SYMBOL (val); |
7246 |
|
CODING_ATTR_PRE_WRITE (attrs) = val; |
7247 |
|
|
7248 |
|
val = args[coding_arg_default_char]; |
7249 |
|
if (NILP (val)) |
7250 |
|
CODING_ATTR_DEFAULT_CHAR (attrs) = make_number (' '); |
7251 |
|
else |
7252 |
|
{ |
7253 |
|
CHECK_CHARACTER (val); |
7254 |
|
CODING_ATTR_DEFAULT_CHAR (attrs) = val; |
7255 |
|
} |
7256 |
|
|
7257 |
DEFUN ("set-coding-priority-internal", Fset_coding_priority_internal, |
val = args[coding_arg_plist]; |
7258 |
Sset_coding_priority_internal, 0, 0, 0, |
CHECK_LIST (val); |
7259 |
doc: /* Update internal database for the current value of `coding-category-list'. |
CODING_ATTR_PLIST (attrs) = val; |
7260 |
This function is internal use only. */) |
|
7261 |
() |
if (EQ (coding_type, Qcharset)) |
7262 |
{ |
{ |
7263 |
int i = 0, idx; |
val = Fmake_vector (make_number (256), Qnil); |
|
Lisp_Object val; |
|
7264 |
|
|
7265 |
val = Vcoding_category_list; |
for (tail = charset_list; CONSP (tail); tail = XCDR (tail)) |
7266 |
|
{ |
7267 |
|
struct charset *charset = CHARSET_FROM_ID (XINT (XCAR (tail))); |
7268 |
|
|
7269 |
while (CONSP (val) && i < CODING_CATEGORY_IDX_MAX) |
for (i = charset->code_space[0]; i <= charset->code_space[1]; i++) |
7270 |
|
if (NILP (AREF (val, i))) |
7271 |
|
ASET (val, i, XCAR (tail)); |
7272 |
|
} |
7273 |
|
ASET (attrs, coding_attr_charset_valids, val); |
7274 |
|
category = coding_category_charset; |
7275 |
|
} |
7276 |
|
else if (EQ (coding_type, Qccl)) |
7277 |
{ |
{ |
7278 |
if (! SYMBOLP (XCAR (val))) |
Lisp_Object valids; |
7279 |
break; |
|
7280 |
idx = XFASTINT (Fget (XCAR (val), Qcoding_category_index)); |
if (nargs < coding_arg_ccl_max) |
7281 |
if (idx >= CODING_CATEGORY_IDX_MAX) |
goto short_args; |
7282 |
break; |
|
7283 |
coding_priorities[i++] = (1 << idx); |
val = args[coding_arg_ccl_decoder]; |
7284 |
val = XCDR (val); |
CHECK_CCL_PROGRAM (val); |
7285 |
|
if (VECTORP (val)) |
7286 |
|
val = Fcopy_sequence (val); |
7287 |
|
ASET (attrs, coding_attr_ccl_decoder, val); |
7288 |
|
|
7289 |
|
val = args[coding_arg_ccl_encoder]; |
7290 |
|
CHECK_CCL_PROGRAM (val); |
7291 |
|
if (VECTORP (val)) |
7292 |
|
val = Fcopy_sequence (val); |
7293 |
|
ASET (attrs, coding_attr_ccl_encoder, val); |
7294 |
|
|
7295 |
|
val = args[coding_arg_ccl_valids]; |
7296 |
|
valids = Fmake_string (make_number (256), make_number (0)); |
7297 |
|
for (tail = val; !NILP (tail); tail = Fcdr (tail)) |
7298 |
|
{ |
7299 |
|
val = Fcar (tail); |
7300 |
|
if (INTEGERP (val)) |
7301 |
|
ASET (valids, XINT (val), 1); |
7302 |
|
else |
7303 |
|
{ |
7304 |
|
int from, to; |
7305 |
|
|
7306 |
|
CHECK_CONS (val); |
7307 |
|
CHECK_NUMBER (XCAR (val)); |
7308 |
|
CHECK_NUMBER (XCDR (val)); |
7309 |
|
from = XINT (XCAR (val)); |
7310 |
|
to = XINT (XCDR (val)); |
7311 |
|
for (i = from; i <= to; i++) |
7312 |
|
ASET (valids, i, 1); |
7313 |
|
} |
7314 |
|
} |
7315 |
|
ASET (attrs, coding_attr_ccl_valids, valids); |
7316 |
|
|
7317 |
|
category = coding_category_ccl; |
7318 |
|
} |
7319 |
|
else if (EQ (coding_type, Qutf_16)) |
7320 |
|
{ |
7321 |
|
Lisp_Object bom, endian; |
7322 |
|
|
7323 |
|
if (nargs < coding_arg_utf16_max) |
7324 |
|
goto short_args; |
7325 |
|
|
7326 |
|
bom = args[coding_arg_utf16_bom]; |
7327 |
|
if (! NILP (bom) && ! EQ (bom, Qt)) |
7328 |
|
{ |
7329 |
|
CHECK_CONS (bom); |
7330 |
|
CHECK_CODING_SYSTEM (XCAR (bom)); |
7331 |
|
CHECK_CODING_SYSTEM (XCDR (bom)); |
7332 |
|
} |
7333 |
|
ASET (attrs, coding_attr_utf_16_bom, bom); |
7334 |
|
|
7335 |
|
endian = args[coding_arg_utf16_endian]; |
7336 |
|
ASET (attrs, coding_attr_utf_16_endian, endian); |
7337 |
|
|
7338 |
|
category = (CONSP (bom) |
7339 |
|
? coding_category_utf_16_auto |
7340 |
|
: NILP (bom) |
7341 |
|
? (NILP (endian) |
7342 |
|
? coding_category_utf_16_be_nosig |
7343 |
|
: coding_category_utf_16_le_nosig) |
7344 |
|
: (NILP (endian) |
7345 |
|
? coding_category_utf_16_be |
7346 |
|
: coding_category_utf_16_le)); |
7347 |
} |
} |
7348 |
/* If coding-category-list is valid and contains all coding |
else if (EQ (coding_type, Qiso_2022)) |
7349 |
categories, `i' should be CODING_CATEGORY_IDX_MAX now. If not, |
{ |
7350 |
the following code saves Emacs from crashing. */ |
Lisp_Object initial, reg_usage, request, flags; |
7351 |
while (i < CODING_CATEGORY_IDX_MAX) |
struct charset *charset; |
7352 |
coding_priorities[i++] = CODING_CATEGORY_MASK_RAW_TEXT; |
int i, id, max_id = -1; |
7353 |
|
|
7354 |
|
if (nargs < coding_arg_iso2022_max) |
7355 |
|
goto short_args; |
7356 |
|
|
7357 |
|
initial = Fcopy_sequence (args[coding_arg_iso2022_initial]); |
7358 |
|
CHECK_VECTOR (initial); |
7359 |
|
for (i = 0; i < 4; i++) |
7360 |
|
{ |
7361 |
|
val = Faref (initial, make_number (i)); |
7362 |
|
if (! NILP (val)) |
7363 |
|
{ |
7364 |
|
CHECK_CHARSET_GET_ID (val, id); |
7365 |
|
ASET (initial, i, make_number (id)); |
7366 |
|
} |
7367 |
|
else |
7368 |
|
ASET (initial, i, make_number (-1)); |
7369 |
|
} |
7370 |
|
|
7371 |
|
reg_usage = args[coding_arg_iso2022_reg_usage]; |
7372 |
|
CHECK_CONS (reg_usage); |
7373 |
|
CHECK_NATNUM (XCAR (reg_usage)); |
7374 |
|
CHECK_NATNUM (XCDR (reg_usage)); |
7375 |
|
|
7376 |
|
request = Fcopy_sequence (args[coding_arg_iso2022_request]); |
7377 |
|
for (tail = request; ! NILP (tail); tail = Fcdr (tail)) |
7378 |
|
{ |
7379 |
|
int id; |
7380 |
|
|
7381 |
|
val = Fcar (tail); |
7382 |
|
CHECK_CONS (val); |
7383 |
|
CHECK_CHARSET_GET_ID (XCAR (val), id); |
7384 |
|
CHECK_NATNUM (XCDR (val)); |
7385 |
|
if (XINT (XCDR (val)) >= 4) |
7386 |
|
error ("Invalid graphic register number: %d", XINT (XCDR (val))); |
7387 |
|
XCAR (val) = make_number (id); |
7388 |
|
} |
7389 |
|
|
7390 |
|
flags = args[coding_arg_iso2022_flags]; |
7391 |
|
CHECK_NATNUM (flags); |
7392 |
|
i = XINT (flags); |
7393 |
|
if (EQ (args[coding_arg_charset_list], Qiso_2022)) |
7394 |
|
flags = make_number (i | CODING_ISO_FLAG_FULL_SUPPORT); |
7395 |
|
|
7396 |
|
ASET (attrs, coding_attr_iso_initial, initial); |
7397 |
|
ASET (attrs, coding_attr_iso_usage, reg_usage); |
7398 |
|
ASET (attrs, coding_attr_iso_request, request); |
7399 |
|
ASET (attrs, coding_attr_iso_flags, flags); |
7400 |
|
setup_iso_safe_charsets (attrs); |
7401 |
|
|
7402 |
|
if (i & CODING_ISO_FLAG_SEVEN_BITS) |
7403 |
|
category = ((i & (CODING_ISO_FLAG_LOCKING_SHIFT |
7404 |
|
| CODING_ISO_FLAG_SINGLE_SHIFT)) |
7405 |
|
? coding_category_iso_7_else |
7406 |
|
: EQ (args[coding_arg_charset_list], Qiso_2022) |
7407 |
|
? coding_category_iso_7 |
7408 |
|
: coding_category_iso_7_tight); |
7409 |
|
else |
7410 |
|
{ |
7411 |
|
int id = XINT (AREF (initial, 1)); |
7412 |
|
|
7413 |
|
category = (((i & (CODING_ISO_FLAG_LOCKING_SHIFT |
7414 |
|
| CODING_ISO_FLAG_SINGLE_SHIFT)) |
7415 |
|
|| EQ (args[coding_arg_charset_list], Qiso_2022) |
7416 |
|
|| id < 0) |
7417 |
|
? coding_category_iso_8_else |
7418 |
|
: (CHARSET_DIMENSION (CHARSET_FROM_ID (id)) == 1) |
7419 |
|
? coding_category_iso_8_1 |
7420 |
|
: coding_category_iso_8_2); |
7421 |
|
} |
7422 |
|
} |
7423 |
|
else if (EQ (coding_type, Qemacs_mule)) |
7424 |
|
{ |
7425 |
|
if (EQ (args[coding_arg_charset_list], Qemacs_mule)) |
7426 |
|
ASET (attrs, coding_attr_emacs_mule_full, Qt); |
7427 |
|
|
7428 |
|
category = coding_category_emacs_mule; |
7429 |
|
} |
7430 |
|
else if (EQ (coding_type, Qshift_jis)) |
7431 |
|
{ |
7432 |
|
|
7433 |
|
struct charset *charset; |
7434 |
|
|
7435 |
|
if (XINT (Flength (charset_list)) != 3) |
7436 |
|
error ("There should be just three charsets"); |
7437 |
|
|
7438 |
|
charset = CHARSET_FROM_ID (XINT (XCAR (charset_list))); |
7439 |
|
if (CHARSET_DIMENSION (charset) != 1) |
7440 |
|
error ("Dimension of charset %s is not one", |
7441 |
|
XSYMBOL (CHARSET_NAME (charset))->name->data); |
7442 |
|
|
7443 |
|
charset_list = XCDR (charset_list); |
7444 |
|
charset = CHARSET_FROM_ID (XINT (XCAR (charset_list))); |
7445 |
|
if (CHARSET_DIMENSION (charset) != 1) |
7446 |
|
error ("Dimension of charset %s is not one", |
7447 |
|
XSYMBOL (CHARSET_NAME (charset))->name->data); |
7448 |
|
|
7449 |
|
charset_list = XCDR (charset_list); |
7450 |
|
charset = CHARSET_FROM_ID (XINT (XCAR (charset_list))); |
7451 |
|
if (CHARSET_DIMENSION (charset) != 2) |
7452 |
|
error ("Dimension of charset %s is not two", |
7453 |
|
XSYMBOL (CHARSET_NAME (charset))->name->data); |
7454 |
|
|
7455 |
|
category = coding_category_sjis; |
7456 |
|
Vsjis_coding_system = name; |
7457 |
|
} |
7458 |
|
else if (EQ (coding_type, Qbig5)) |
7459 |
|
{ |
7460 |
|
struct charset *charset; |
7461 |
|
|
7462 |
|
if (XINT (Flength (charset_list)) != 2) |
7463 |
|
error ("There should be just two charsets"); |
7464 |
|
|
7465 |
|
charset = CHARSET_FROM_ID (XINT (XCAR (charset_list))); |
7466 |
|
if (CHARSET_DIMENSION (charset) != 1) |
7467 |
|
error ("Dimension of charset %s is not one", |
7468 |
|
XSYMBOL (CHARSET_NAME (charset))->name->data); |
7469 |
|
|
7470 |
|
charset_list = XCDR (charset_list); |
7471 |
|
charset = CHARSET_FROM_ID (XINT (XCAR (charset_list))); |
7472 |
|
if (CHARSET_DIMENSION (charset) != 2) |
7473 |
|
error ("Dimension of charset %s is not two", |
7474 |
|
XSYMBOL (CHARSET_NAME (charset))->name->data); |
7475 |
|
|
7476 |
|
category = coding_category_big5; |
7477 |
|
Vbig5_coding_system = name; |
7478 |
|
} |
7479 |
|
else if (EQ (coding_type, Qraw_text)) |
7480 |
|
category = coding_category_raw_text; |
7481 |
|
else if (EQ (coding_type, Qutf_8)) |
7482 |
|
category = coding_category_utf_8; |
7483 |
|
else if (EQ (coding_type, Qundecided)) |
7484 |
|
category = coding_category_undecided; |
7485 |
|
else |
7486 |
|
error ("Invalid coding system type: %s", |
7487 |
|
XSYMBOL (coding_type)->name->data); |
7488 |
|
|
7489 |
|
CODING_ATTR_CATEGORY (attrs) = make_number (category); |
7490 |
|
|
7491 |
|
eol_type = args[coding_arg_eol_type]; |
7492 |
|
if (! NILP (eol_type) |
7493 |
|
&& ! EQ (eol_type, Qunix) |
7494 |
|
&& ! EQ (eol_type, Qdos) |
7495 |
|
&& ! EQ (eol_type, Qmac)) |
7496 |
|
error ("Invalid eol-type"); |
7497 |
|
|
7498 |
|
aliases = Fcons (name, Qnil); |
7499 |
|
|
7500 |
|
if (NILP (eol_type)) |
7501 |
|
{ |
7502 |
|
eol_type = make_subsidiaries (name); |
7503 |
|
for (i = 0; i < 3; i++) |
7504 |
|
{ |
7505 |
|
Lisp_Object this_spec, this_name, this_aliases, this_eol_type; |
7506 |
|
|
7507 |
|
this_name = AREF (eol_type, i); |
7508 |
|
this_aliases = Fcons (this_name, Qnil); |
7509 |
|
this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac); |
7510 |
|
this_spec = Fmake_vector (make_number (3), attrs); |
7511 |
|
ASET (this_spec, 1, this_aliases); |
7512 |
|
ASET (this_spec, 2, this_eol_type); |
7513 |
|
Fputhash (this_name, this_spec, Vcoding_system_hash_table); |
7514 |
|
Vcoding_system_list = Fcons (this_name, Vcoding_system_list); |
7515 |
|
Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (this_name), Qnil), |
7516 |
|
Vcoding_system_alist); |
7517 |
|
} |
7518 |
|
} |
7519 |
|
|
7520 |
|
spec_vec = Fmake_vector (make_number (3), attrs); |
7521 |
|
ASET (spec_vec, 1, aliases); |
7522 |
|
ASET (spec_vec, 2, eol_type); |
7523 |
|
|
7524 |
|
Fputhash (name, spec_vec, Vcoding_system_hash_table); |
7525 |
|
Vcoding_system_list = Fcons (name, Vcoding_system_list); |
7526 |
|
Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (name), Qnil), |
7527 |
|
Vcoding_system_alist); |
7528 |
|
|
7529 |
|
{ |
7530 |
|
int id = coding_categories[category].id; |
7531 |
|
|
7532 |
|
if (id < 0 || EQ (name, CODING_ID_NAME (id))) |
7533 |
|
setup_coding_system (name, &coding_categories[category]); |
7534 |
|
} |
7535 |
|
|
7536 |
return Qnil; |
return Qnil; |
7537 |
|
|
7538 |
|
short_args: |
7539 |
|
return Fsignal (Qwrong_number_of_arguments, |
7540 |
|
Fcons (intern ("define-coding-system-internal"), |
7541 |
|
make_number (nargs))); |
7542 |
|
} |
7543 |
|
|
7544 |
|
DEFUN ("define-coding-system-alias", Fdefine_coding_system_alias, |
7545 |
|
Sdefine_coding_system_alias, 2, 2, 0, |
7546 |
|
doc: /* Define ALIAS as an alias for CODING-SYSTEM. */) |
7547 |
|
(alias, coding_system) |
7548 |
|
Lisp_Object alias, coding_system; |
7549 |
|
{ |
7550 |
|
Lisp_Object spec, aliases, eol_type; |
7551 |
|
|
7552 |
|
CHECK_SYMBOL (alias); |
7553 |
|
CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec); |
7554 |
|
aliases = AREF (spec, 1); |
7555 |
|
while (!NILP (XCDR (aliases))) |
7556 |
|
aliases = XCDR (aliases); |
7557 |
|
XCDR (aliases) = Fcons (alias, Qnil); |
7558 |
|
|
7559 |
|
eol_type = AREF (spec, 2); |
7560 |
|
if (VECTORP (eol_type)) |
7561 |
|
{ |
7562 |
|
Lisp_Object subsidiaries; |
7563 |
|
int i; |
7564 |
|
|
7565 |
|
subsidiaries = make_subsidiaries (alias); |
7566 |
|
for (i = 0; i < 3; i++) |
7567 |
|
Fdefine_coding_system_alias (AREF (subsidiaries, i), |
7568 |
|
AREF (eol_type, i)); |
7569 |
|
|
7570 |
|
ASET (spec, 2, subsidiaries); |
7571 |
|
} |
7572 |
|
|
7573 |
|
Fputhash (alias, spec, Vcoding_system_hash_table); |
7574 |
|
|
7575 |
|
return Qnil; |
7576 |
|
} |
7577 |
|
|
7578 |
|
DEFUN ("coding-system-base", Fcoding_system_base, Scoding_system_base, |
7579 |
|
1, 1, 0, |
7580 |
|
doc: /* Return the base of CODING-SYSTEM. |
7581 |
|
Any alias or subsidiary coding systems are not base coding system. */) |
7582 |
|
(coding_system) |
7583 |
|
Lisp_Object coding_system; |
7584 |
|
{ |
7585 |
|
Lisp_Object spec, attrs; |
7586 |
|
|
7587 |
|
if (NILP (coding_system)) |
7588 |
|
return (Qno_conversion); |
7589 |
|
CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec); |
7590 |
|
attrs = AREF (spec, 0); |
7591 |
|
return CODING_ATTR_BASE_NAME (attrs); |
7592 |
|
} |
7593 |
|
|
7594 |
|
DEFUN ("coding-system-plist", Fcoding_system_plist, Scoding_system_plist, |
7595 |
|
1, 1, 0, |
7596 |
|
doc: "Return the property list of CODING-SYSTEM.") |
7597 |
|
(coding_system) |
7598 |
|
Lisp_Object coding_system; |
7599 |
|
{ |
7600 |
|
Lisp_Object spec, attrs; |
7601 |
|
|
7602 |
|
if (NILP (coding_system)) |
7603 |
|
coding_system = Qno_conversion; |
7604 |
|
CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec); |
7605 |
|
attrs = AREF (spec, 0); |
7606 |
|
return CODING_ATTR_PLIST (attrs); |
7607 |
|
} |
7608 |
|
|
7609 |
|
|
7610 |
|
DEFUN ("coding-system-aliases", Fcoding_system_aliases, Scoding_system_aliases, |
7611 |
|
1, 1, 0, |
7612 |
|
doc: /* Return the list of aliases of CODING-SYSTEM. |
7613 |
|
A base coding system is what made by `define-coding-system'. |
7614 |
|
Any alias nor subsidiary coding systems are not base coding system. */) |
7615 |
|
(coding_system) |
7616 |
|
Lisp_Object coding_system; |
7617 |
|
{ |
7618 |
|
Lisp_Object spec; |
7619 |
|
|
7620 |
|
if (NILP (coding_system)) |
7621 |
|
coding_system = Qno_conversion; |
7622 |
|
CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec); |
7623 |
|
return AREF (spec, 2); |
7624 |
|
} |
7625 |
|
|
7626 |
|
DEFUN ("coding-system-eol-type", Fcoding_system_eol_type, |
7627 |
|
Scoding_system_eol_type, 1, 1, 0, |
7628 |
|
doc: /* Return eol-type of CODING-SYSTEM. |
7629 |
|
An eol-type is integer 0, 1, 2, or a vector of coding systems. |
7630 |
|
|
7631 |
|
Integer values 0, 1, and 2 indicate a format of end-of-line; LF, CRLF, |
7632 |
|
and CR respectively. |
7633 |
|
|
7634 |
|
A vector value indicates that a format of end-of-line should be |
7635 |
|
detected automatically. Nth element of the vector is the subsidiary |
7636 |
|
coding system whose eol-type is N. */) |
7637 |
|
(coding_system) |
7638 |
|
Lisp_Object coding_system; |
7639 |
|
{ |
7640 |
|
Lisp_Object spec, eol_type; |
7641 |
|
int n; |
7642 |
|
|
7643 |
|
if (NILP (coding_system)) |
7644 |
|
coding_system = Qno_conversion; |
7645 |
|
if (! CODING_SYSTEM_P (coding_system)) |
7646 |
|
return Qnil; |
7647 |
|
spec = CODING_SYSTEM_SPEC (coding_system); |
7648 |
|
eol_type = AREF (spec, 2); |
7649 |
|
if (VECTORP (eol_type)) |
7650 |
|
return Fcopy_sequence (eol_type); |
7651 |
|
n = EQ (eol_type, Qunix) ? 0 : EQ (eol_type, Qdos) ? 1 : 2; |
7652 |
|
return make_number (n); |
7653 |
} |
} |
7654 |
|
|
7655 |
#endif /* emacs */ |
#endif /* emacs */ |
7662 |
{ |
{ |
7663 |
int i; |
int i; |
7664 |
|
|
7665 |
/* Emacs' internal format specific initialize routine. */ |
for (i = 0; i < coding_category_max; i++) |
7666 |
for (i = 0; i <= 0x20; i++) |
{ |
7667 |
emacs_code_class[i] = EMACS_control_code; |
coding_categories[i].id = -1; |
7668 |
emacs_code_class[0x0A] = EMACS_linefeed_code; |
coding_priorities[i] = i; |
7669 |
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; |
|
7670 |
|
|
7671 |
/* ISO2022 specific initialize routine. */ |
/* ISO2022 specific initialize routine. */ |
7672 |
for (i = 0; i < 0x20; i++) |
for (i = 0; i < 0x20; i++) |
7688 |
iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3; |
iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3; |
7689 |
iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer; |
iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer; |
7690 |
|
|
|
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 |
|
|
|
|
7691 |
inhibit_pre_post_conversion = 0; |
inhibit_pre_post_conversion = 0; |
7692 |
|
|
7693 |
|
for (i = 0; i < 256; i++) |
7694 |
|
{ |
7695 |
|
emacs_mule_bytes[i] = 1; |
7696 |
|
} |
7697 |
} |
} |
7698 |
|
|
7699 |
#ifdef emacs |
#ifdef emacs |
7701 |
void |
void |
7702 |
syms_of_coding () |
syms_of_coding () |
7703 |
{ |
{ |
7704 |
Qtarget_idx = intern ("target-idx"); |
staticpro (&Vcoding_system_hash_table); |
7705 |
staticpro (&Qtarget_idx); |
Vcoding_system_hash_table = Fmakehash (Qeq); |
7706 |
|
|
7707 |
Qcoding_system_history = intern ("coding-system-history"); |
staticpro (&Vsjis_coding_system); |
7708 |
staticpro (&Qcoding_system_history); |
Vsjis_coding_system = Qnil; |
7709 |
|
|
7710 |
|
staticpro (&Vbig5_coding_system); |
7711 |
|
Vbig5_coding_system = Qnil; |
7712 |
|
|
7713 |
|
staticpro (&Vcode_conversion_work_buf_list); |
7714 |
|
Vcode_conversion_work_buf_list = Qnil; |
7715 |
|
|
7716 |
|
staticpro (&Vcode_conversion_reused_work_buf); |
7717 |
|
Vcode_conversion_reused_work_buf = Qnil; |
7718 |
|
|
7719 |
|
DEFSYM (Qcharset, "charset"); |
7720 |
|
DEFSYM (Qtarget_idx, "target-idx"); |
7721 |
|
DEFSYM (Qcoding_system_history, "coding-system-history"); |
7722 |
Fset (Qcoding_system_history, Qnil); |
Fset (Qcoding_system_history, Qnil); |
7723 |
|
|
7724 |
/* Target FILENAME is the first argument. */ |
/* Target FILENAME is the first argument. */ |
7726 |
/* Target FILENAME is the third argument. */ |
/* Target FILENAME is the third argument. */ |
7727 |
Fput (Qwrite_region, Qtarget_idx, make_number (2)); |
Fput (Qwrite_region, Qtarget_idx, make_number (2)); |
7728 |
|
|
7729 |
Qcall_process = intern ("call-process"); |
DEFSYM (Qcall_process, "call-process"); |
|
staticpro (&Qcall_process); |
|
7730 |
/* Target PROGRAM is the first argument. */ |
/* Target PROGRAM is the first argument. */ |
7731 |
Fput (Qcall_process, Qtarget_idx, make_number (0)); |
Fput (Qcall_process, Qtarget_idx, make_number (0)); |
7732 |
|
|
7733 |
Qcall_process_region = intern ("call-process-region"); |
DEFSYM (Qcall_process_region, "call-process-region"); |
|
staticpro (&Qcall_process_region); |
|
7734 |
/* Target PROGRAM is the third argument. */ |
/* Target PROGRAM is the third argument. */ |
7735 |
Fput (Qcall_process_region, Qtarget_idx, make_number (2)); |
Fput (Qcall_process_region, Qtarget_idx, make_number (2)); |
7736 |
|
|
7737 |
Qstart_process = intern ("start-process"); |
DEFSYM (Qstart_process, "start-process"); |
|
staticpro (&Qstart_process); |
|
7738 |
/* Target PROGRAM is the third argument. */ |
/* Target PROGRAM is the third argument. */ |
7739 |
Fput (Qstart_process, Qtarget_idx, make_number (2)); |
Fput (Qstart_process, Qtarget_idx, make_number (2)); |
7740 |
|
|
7741 |
Qopen_network_stream = intern ("open-network-stream"); |
DEFSYM (Qopen_network_stream, "open-network-stream"); |
|
staticpro (&Qopen_network_stream); |
|
7742 |
/* Target SERVICE is the fourth argument. */ |
/* Target SERVICE is the fourth argument. */ |
7743 |
Fput (Qopen_network_stream, Qtarget_idx, make_number (3)); |
Fput (Qopen_network_stream, Qtarget_idx, make_number (3)); |
7744 |
|
|
7745 |
Qcoding_system = intern ("coding-system"); |
DEFSYM (Qcoding_system, "coding-system"); |
7746 |
staticpro (&Qcoding_system); |
DEFSYM (Qcoding_aliases, "coding-aliases"); |
|
|
|
|
Qeol_type = intern ("eol-type"); |
|
|
staticpro (&Qeol_type); |
|
7747 |
|
|
7748 |
Qbuffer_file_coding_system = intern ("buffer-file-coding-system"); |
DEFSYM (Qeol_type, "eol-type"); |
7749 |
staticpro (&Qbuffer_file_coding_system); |
DEFSYM (Qunix, "unix"); |
7750 |
|
DEFSYM (Qdos, "dos"); |
7751 |
|
DEFSYM (Qmac, "mac"); |
7752 |
|
|
7753 |
|
DEFSYM (Qbuffer_file_coding_system, "buffer-file-coding-system"); |
7754 |
|
DEFSYM (Qpost_read_conversion, "post-read-conversion"); |
7755 |
|
DEFSYM (Qpre_write_conversion, "pre-write-conversion"); |
7756 |
|
DEFSYM (Qdefault_char, "default-char"); |
7757 |
|
DEFSYM (Qundecided, "undecided"); |
7758 |
|
DEFSYM (Qno_conversion, "no-conversion"); |
7759 |
|
DEFSYM (Qraw_text, "raw-text"); |
7760 |
|
|
7761 |
|
DEFSYM (Qiso_2022, "iso-2022"); |
7762 |
|
|
7763 |
|
DEFSYM (Qutf_8, "utf-8"); |
7764 |
|
|
7765 |
|
DEFSYM (Qutf_16, "utf-16"); |
7766 |
|
DEFSYM (Qutf_16_be, "utf-16-be"); |
7767 |
|
DEFSYM (Qutf_16_be_nosig, "utf-16-be-nosig"); |
7768 |
|
DEFSYM (Qutf_16_le, "utf-16-l3"); |
7769 |
|
DEFSYM (Qutf_16_le_nosig, "utf-16-le-nosig"); |
7770 |
|
DEFSYM (Qsignature, "signature"); |
7771 |
|
DEFSYM (Qendian, "endian"); |
7772 |
|
DEFSYM (Qbig, "big"); |
7773 |
|
DEFSYM (Qlittle, "little"); |
7774 |
|
|
7775 |
Qpost_read_conversion = intern ("post-read-conversion"); |
DEFSYM (Qshift_jis, "shift-jis"); |
7776 |
staticpro (&Qpost_read_conversion); |
DEFSYM (Qbig5, "big5"); |
7777 |
|
|
7778 |
Qpre_write_conversion = intern ("pre-write-conversion"); |
DEFSYM (Qcoding_system_p, "coding-system-p"); |
|
staticpro (&Qpre_write_conversion); |
|
|
|
|
|
Qno_conversion = intern ("no-conversion"); |
|
|
staticpro (&Qno_conversion); |
|
|
|
|
|
Qundecided = intern ("undecided"); |
|
|
staticpro (&Qundecided); |
|
|
|
|
|
Qcoding_system_p = intern ("coding-system-p"); |
|
|
staticpro (&Qcoding_system_p); |
|
|
|
|
|
Qcoding_system_error = intern ("coding-system-error"); |
|
|
staticpro (&Qcoding_system_error); |
|
7779 |
|
|
7780 |
|
DEFSYM (Qcoding_system_error, "coding-system-error"); |
7781 |
Fput (Qcoding_system_error, Qerror_conditions, |
Fput (Qcoding_system_error, Qerror_conditions, |
7782 |
Fcons (Qcoding_system_error, Fcons (Qerror, Qnil))); |
Fcons (Qcoding_system_error, Fcons (Qerror, Qnil))); |
7783 |
Fput (Qcoding_system_error, Qerror_message, |
Fput (Qcoding_system_error, Qerror_message, |
7784 |
build_string ("Invalid coding system")); |
build_string ("Invalid coding system")); |
7785 |
|
|
7786 |
Qcoding_category = intern ("coding-category"); |
/* Intern this now in case it isn't already done. |
7787 |
staticpro (&Qcoding_category); |
Setting this variable twice is harmless. |
7788 |
Qcoding_category_index = intern ("coding-category-index"); |
But don't staticpro it here--that is done in alloc.c. */ |
7789 |
staticpro (&Qcoding_category_index); |
Qchar_table_extra_slots = intern ("char-table-extra-slots"); |
|
|
|
|
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)); |
|
|
} |
|
|
} |
|
7790 |
|
|
7791 |
Qtranslation_table = intern ("translation-table"); |
DEFSYM (Qtranslation_table, "translation-table"); |
|
staticpro (&Qtranslation_table); |
|
7792 |
Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (1)); |
Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (1)); |
7793 |
|
DEFSYM (Qtranslation_table_id, "translation-table-id"); |
7794 |
|
DEFSYM (Qtranslation_table_for_decode, "translation-table-for-decode"); |
7795 |
|
DEFSYM (Qtranslation_table_for_encode, "translation-table-for-encode"); |
7796 |
|
|
7797 |
Qtranslation_table_id = intern ("translation-table-id"); |
DEFSYM (Qchar_coding_system, "char-coding-system"); |
|
staticpro (&Qtranslation_table_id); |
|
7798 |
|
|
7799 |
Qtranslation_table_for_decode = intern ("translation-table-for-decode"); |
Fput (Qchar_coding_system, Qchar_table_extra_slots, make_number (2)); |
|
staticpro (&Qtranslation_table_for_decode); |
|
7800 |
|
|
7801 |
Qtranslation_table_for_encode = intern ("translation-table-for-encode"); |
DEFSYM (Qvalid_codes, "valid-codes"); |
|
staticpro (&Qtranslation_table_for_encode); |
|
7802 |
|
|
7803 |
Qsafe_chars = intern ("safe-chars"); |
DEFSYM (Qemacs_mule, "emacs-mule"); |
|
staticpro (&Qsafe_chars); |
|
7804 |
|
|
7805 |
Qchar_coding_system = intern ("char-coding-system"); |
Vcoding_category_table |
7806 |
staticpro (&Qchar_coding_system); |
= Fmake_vector (make_number (coding_category_max), Qnil); |
7807 |
|
staticpro (&Vcoding_category_table); |
7808 |
|
/* Followings are target of code detection. */ |
7809 |
|
ASET (Vcoding_category_table, coding_category_iso_7, |
7810 |
|
intern ("coding-category-iso-7")); |
7811 |
|
ASET (Vcoding_category_table, coding_category_iso_7_tight, |
7812 |
|
intern ("coding-category-iso-7-tight")); |
7813 |
|
ASET (Vcoding_category_table, coding_category_iso_8_1, |
7814 |
|
intern ("coding-category-iso-8-1")); |
7815 |
|
ASET (Vcoding_category_table, coding_category_iso_8_2, |
7816 |
|
intern ("coding-category-iso-8-2")); |
7817 |
|
ASET (Vcoding_category_table, coding_category_iso_7_else, |
7818 |
|
intern ("coding-category-iso-7-else")); |
7819 |
|
ASET (Vcoding_category_table, coding_category_iso_8_else, |
7820 |
|
intern ("coding-category-iso-8-else")); |
7821 |
|
ASET (Vcoding_category_table, coding_category_utf_8, |
7822 |
|
intern ("coding-category-utf-8")); |
7823 |
|
ASET (Vcoding_category_table, coding_category_utf_16_be, |
7824 |
|
intern ("coding-category-utf-16-be")); |
7825 |
|
ASET (Vcoding_category_table, coding_category_utf_16_le, |
7826 |
|
intern ("coding-category-utf-16-le")); |
7827 |
|
ASET (Vcoding_category_table, coding_category_utf_16_be_nosig, |
7828 |
|
intern ("coding-category-utf-16-be-nosig")); |
7829 |
|
ASET (Vcoding_category_table, coding_category_utf_16_le_nosig, |
7830 |
|
intern ("coding-category-utf-16-le-nosig")); |
7831 |
|
ASET (Vcoding_category_table, coding_category_charset, |
7832 |
|
intern ("coding-category-charset")); |
7833 |
|
ASET (Vcoding_category_table, coding_category_sjis, |
7834 |
|
intern ("coding-category-sjis")); |
7835 |
|
ASET (Vcoding_category_table, coding_category_big5, |
7836 |
|
intern ("coding-category-big5")); |
7837 |
|
ASET (Vcoding_category_table, coding_category_ccl, |
7838 |
|
intern ("coding-category-ccl")); |
7839 |
|
ASET (Vcoding_category_table, coding_category_emacs_mule, |
7840 |
|
intern ("coding-category-emacs-mule")); |
7841 |
|
/* Followings are NOT target of code detection. */ |
7842 |
|
ASET (Vcoding_category_table, coding_category_raw_text, |
7843 |
|
intern ("coding-category-raw-text")); |
7844 |
|
ASET (Vcoding_category_table, coding_category_undecided, |
7845 |
|
intern ("coding-category-undecided")); |
7846 |
|
|
7847 |
/* Intern this now in case it isn't already done. |
{ |
7848 |
Setting this variable twice is harmless. |
Lisp_Object args[coding_arg_max]; |
7849 |
But don't staticpro it here--that is done in alloc.c. */ |
Lisp_Object plist[14]; |
7850 |
Qchar_table_extra_slots = intern ("char-table-extra-slots"); |
int i; |
|
Fput (Qsafe_chars, Qchar_table_extra_slots, make_number (0)); |
|
|
Fput (Qchar_coding_system, Qchar_table_extra_slots, make_number (2)); |
|
7851 |
|
|
7852 |
Qvalid_codes = intern ("valid-codes"); |
for (i = 0; i < coding_arg_max; i++) |
7853 |
staticpro (&Qvalid_codes); |
args[i] = Qnil; |
7854 |
|
|
7855 |
Qemacs_mule = intern ("emacs-mule"); |
plist[0] = intern (":name"); |
7856 |
staticpro (&Qemacs_mule); |
plist[1] = args[coding_arg_name] = Qno_conversion; |
7857 |
|
plist[2] = intern (":mnemonic"); |
7858 |
|
plist[3] = args[coding_arg_mnemonic] = make_number ('='); |
7859 |
|
plist[4] = intern (":coding-type"); |
7860 |
|
plist[5] = args[coding_arg_coding_type] = Qraw_text; |
7861 |
|
plist[6] = intern (":ascii-compatible-p"); |
7862 |
|
plist[7] = args[coding_arg_ascii_compatible_p] = Qt; |
7863 |
|
plist[8] = intern (":default-char"); |
7864 |
|
plist[9] = args[coding_arg_default_char] = make_number (0); |
7865 |
|
plist[10] = intern (":docstring"); |
7866 |
|
plist[11] = build_string ("Do no conversion.\n\ |
7867 |
|
\n\ |
7868 |
|
When you visit a file with this coding, the file is read into a\n\ |
7869 |
|
unibyte buffer as is, thus each byte of a file is treated as a\n\ |
7870 |
|
character."); |
7871 |
|
plist[12] = intern (":eol-type"); |
7872 |
|
plist[13] = args[coding_arg_eol_type] = Qunix; |
7873 |
|
args[coding_arg_plist] = Flist (14, plist); |
7874 |
|
Fdefine_coding_system_internal (coding_arg_max, args); |
7875 |
|
} |
7876 |
|
|
7877 |
Qraw_text = intern ("raw-text"); |
setup_coding_system (Qno_conversion, &keyboard_coding); |
7878 |
staticpro (&Qraw_text); |
setup_coding_system (Qno_conversion, &terminal_coding); |
7879 |
|
setup_coding_system (Qno_conversion, &safe_terminal_coding); |
7880 |
|
|
7881 |
defsubr (&Scoding_system_p); |
defsubr (&Scoding_system_p); |
7882 |
defsubr (&Sread_coding_system); |
defsubr (&Sread_coding_system); |
7885 |
defsubr (&Sdetect_coding_region); |
defsubr (&Sdetect_coding_region); |
7886 |
defsubr (&Sdetect_coding_string); |
defsubr (&Sdetect_coding_string); |
7887 |
defsubr (&Sfind_coding_systems_region_internal); |
defsubr (&Sfind_coding_systems_region_internal); |
7888 |
|
defsubr (&Scheck_coding_systems_region); |
7889 |
defsubr (&Sdecode_coding_region); |
defsubr (&Sdecode_coding_region); |
7890 |
defsubr (&Sencode_coding_region); |
defsubr (&Sencode_coding_region); |
7891 |
defsubr (&Sdecode_coding_string); |
defsubr (&Sdecode_coding_string); |
7900 |
defsubr (&Sset_keyboard_coding_system_internal); |
defsubr (&Sset_keyboard_coding_system_internal); |
7901 |
defsubr (&Skeyboard_coding_system); |
defsubr (&Skeyboard_coding_system); |
7902 |
defsubr (&Sfind_operation_coding_system); |
defsubr (&Sfind_operation_coding_system); |
7903 |
defsubr (&Supdate_coding_systems_internal); |
defsubr (&Sset_coding_system_priority); |
7904 |
defsubr (&Sset_coding_priority_internal); |
defsubr (&Sdefine_coding_system_internal); |
7905 |
|
defsubr (&Sdefine_coding_system_alias); |
7906 |
|
defsubr (&Scoding_system_base); |
7907 |
|
defsubr (&Scoding_system_plist); |
7908 |
|
defsubr (&Scoding_system_aliases); |
7909 |
|
defsubr (&Scoding_system_eol_type); |
7910 |
|
defsubr (&Scoding_system_priority_list); |
7911 |
|
|
7912 |
DEFVAR_LISP ("coding-system-list", &Vcoding_system_list, |
DEFVAR_LISP ("coding-system-list", &Vcoding_system_list, |
7913 |
doc: /* List of coding systems. |
doc: /* List of coding systems. |
7914 |
|
|
7915 |
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 |
7916 |
updated by the functions `make-coding-system' and |
updated by the functions `define-coding-system' and |
7917 |
`define-coding-system-alias'. */); |
`define-coding-system-alias'. */); |
7918 |
Vcoding_system_list = Qnil; |
Vcoding_system_list = Qnil; |
7919 |
|
|
7938 |
int i; |
int i; |
7939 |
|
|
7940 |
Vcoding_category_list = Qnil; |
Vcoding_category_list = Qnil; |
7941 |
for (i = CODING_CATEGORY_IDX_MAX - 1; i >= 0; i--) |
for (i = coding_category_max - 1; i >= 0; i--) |
7942 |
Vcoding_category_list |
Vcoding_category_list |
7943 |
= Fcons (XVECTOR (Vcoding_category_table)->contents[i], |
= Fcons (XVECTOR (Vcoding_category_table)->contents[i], |
7944 |
Vcoding_category_list); |
Vcoding_category_list); |
7968 |
Vcoding_system_for_write = Qnil; |
Vcoding_system_for_write = Qnil; |
7969 |
|
|
7970 |
DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used, |
DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used, |
7971 |
doc: /* Coding system used in the latest file or process I/O. */); |
doc: /* |
7972 |
|
Coding system used in the latest file or process I/O. */); |
7973 |
Vlast_coding_system_used = Qnil; |
Vlast_coding_system_used = Qnil; |
7974 |
|
|
7975 |
DEFVAR_BOOL ("inhibit-eol-conversion", &inhibit_eol_conversion, |
DEFVAR_BOOL ("inhibit-eol-conversion", &inhibit_eol_conversion, |
7976 |
doc: /* *Non-nil means always inhibit code conversion of end-of-line format. |
doc: /* |
7977 |
|
*Non-nil means always inhibit code conversion of end-of-line format. |
7978 |
See info node `Coding Systems' and info node `Text and Binary' concerning |
See info node `Coding Systems' and info node `Text and Binary' concerning |
7979 |
such conversion. */); |
such conversion. */); |
7980 |
inhibit_eol_conversion = 0; |
inhibit_eol_conversion = 0; |
7981 |
|
|
7982 |
DEFVAR_BOOL ("inherit-process-coding-system", &inherit_process_coding_system, |
DEFVAR_BOOL ("inherit-process-coding-system", &inherit_process_coding_system, |
7983 |
doc: /* Non-nil means process buffer inherits coding system of process output. |
doc: /* |
7984 |
|
Non-nil means process buffer inherits coding system of process output. |
7985 |
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 |
7986 |
read from some filesystem. */); |
read from some filesystem. */); |
7987 |
inherit_process_coding_system = 0; |
inherit_process_coding_system = 0; |
7988 |
|
|
7989 |
DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist, |
DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist, |
7990 |
doc: /* Alist to decide a coding system to use for a file I/O operation. |
doc: /* |
7991 |
|
Alist to decide a coding system to use for a file I/O operation. |
7992 |
The format is ((PATTERN . VAL) ...), |
The format is ((PATTERN . VAL) ...), |
7993 |
where PATTERN is a regular expression matching a file name, |
where PATTERN is a regular expression matching a file name, |
7994 |
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. |
8005 |
Vfile_coding_system_alist = Qnil; |
Vfile_coding_system_alist = Qnil; |
8006 |
|
|
8007 |
DEFVAR_LISP ("process-coding-system-alist", &Vprocess_coding_system_alist, |
DEFVAR_LISP ("process-coding-system-alist", &Vprocess_coding_system_alist, |
8008 |
doc: /* Alist to decide a coding system to use for a process I/O operation. |
doc: /* |
8009 |
|
Alist to decide a coding system to use for a process I/O operation. |
8010 |
The format is ((PATTERN . VAL) ...), |
The format is ((PATTERN . VAL) ...), |
8011 |
where PATTERN is a regular expression matching a program name, |
where PATTERN is a regular expression matching a program name, |
8012 |
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. |
8021 |
Vprocess_coding_system_alist = Qnil; |
Vprocess_coding_system_alist = Qnil; |
8022 |
|
|
8023 |
DEFVAR_LISP ("network-coding-system-alist", &Vnetwork_coding_system_alist, |
DEFVAR_LISP ("network-coding-system-alist", &Vnetwork_coding_system_alist, |
8024 |
doc: /* Alist to decide a coding system to use for a network I/O operation. |
doc: /* |
8025 |
|
Alist to decide a coding system to use for a network I/O operation. |
8026 |
The format is ((PATTERN . VAL) ...), |
The format is ((PATTERN . VAL) ...), |
8027 |
where PATTERN is a regular expression matching a network service name |
where PATTERN is a regular expression matching a network service name |
8028 |
or is a port number to connect to, |
or is a port number to connect to, |
8044 |
|
|
8045 |
/* The eol mnemonics are reset in startup.el system-dependently. */ |
/* The eol mnemonics are reset in startup.el system-dependently. */ |
8046 |
DEFVAR_LISP ("eol-mnemonic-unix", &eol_mnemonic_unix, |
DEFVAR_LISP ("eol-mnemonic-unix", &eol_mnemonic_unix, |
8047 |
doc: /* *String displayed in mode line for UNIX-like (LF) end-of-line format. */); |
doc: /* |
8048 |
|
*String displayed in mode line for UNIX-like (LF) end-of-line format. */); |
8049 |
eol_mnemonic_unix = build_string (":"); |
eol_mnemonic_unix = build_string (":"); |
8050 |
|
|
8051 |
DEFVAR_LISP ("eol-mnemonic-dos", &eol_mnemonic_dos, |
DEFVAR_LISP ("eol-mnemonic-dos", &eol_mnemonic_dos, |
8052 |
doc: /* *String displayed in mode line for DOS-like (CRLF) end-of-line format. */); |
doc: /* |
8053 |
|
*String displayed in mode line for DOS-like (CRLF) end-of-line format. */); |
8054 |
eol_mnemonic_dos = build_string ("\\"); |
eol_mnemonic_dos = build_string ("\\"); |
8055 |
|
|
8056 |
DEFVAR_LISP ("eol-mnemonic-mac", &eol_mnemonic_mac, |
DEFVAR_LISP ("eol-mnemonic-mac", &eol_mnemonic_mac, |
8057 |
doc: /* *String displayed in mode line for MAC-like (CR) end-of-line format. */); |
doc: /* |
8058 |
|
*String displayed in mode line for MAC-like (CR) end-of-line format. */); |
8059 |
eol_mnemonic_mac = build_string ("/"); |
eol_mnemonic_mac = build_string ("/"); |
8060 |
|
|
8061 |
DEFVAR_LISP ("eol-mnemonic-undecided", &eol_mnemonic_undecided, |
DEFVAR_LISP ("eol-mnemonic-undecided", &eol_mnemonic_undecided, |
8062 |
doc: /* *String displayed in mode line when end-of-line format is not yet determined. */); |
doc: /* |
8063 |
|
*String displayed in mode line when end-of-line format is not yet determined. */); |
8064 |
eol_mnemonic_undecided = build_string (":"); |
eol_mnemonic_undecided = build_string (":"); |
8065 |
|
|
8066 |
DEFVAR_LISP ("enable-character-translation", &Venable_character_translation, |
DEFVAR_LISP ("enable-character-translation", &Venable_character_translation, |
8067 |
doc: /* *Non-nil enables character translation while encoding and decoding. */); |
doc: /* |
8068 |
|
*Non-nil enables character translation while encoding and decoding. */); |
8069 |
Venable_character_translation = Qt; |
Venable_character_translation = Qt; |
8070 |
|
|
8071 |
DEFVAR_LISP ("standard-translation-table-for-decode", |
DEFVAR_LISP ("standard-translation-table-for-decode", |
8078 |
doc: /* Table for translating characters while encoding. */); |
doc: /* Table for translating characters while encoding. */); |
8079 |
Vstandard_translation_table_for_encode = Qnil; |
Vstandard_translation_table_for_encode = Qnil; |
8080 |
|
|
8081 |
DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_alist, |
DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_table, |
8082 |
doc: /* Alist of charsets vs revision numbers. |
doc: /* Alist of charsets vs revision numbers. |
8083 |
While encoding, if a charset (car part of an element) is found, |
While encoding, if a charset (car part of an element) is found, |
8084 |
designate it with the escape sequence identifying revision (cdr part of the element). */); |
designate it with the escape sequence identifying revision (cdr part |
8085 |
Vcharset_revision_alist = Qnil; |
of the element). */); |
8086 |
|
Vcharset_revision_table = Qnil; |
8087 |
|
|
8088 |
DEFVAR_LISP ("default-process-coding-system", |
DEFVAR_LISP ("default-process-coding-system", |
8089 |
&Vdefault_process_coding_system, |
&Vdefault_process_coding_system, |
8093 |
Vdefault_process_coding_system = Qnil; |
Vdefault_process_coding_system = Qnil; |
8094 |
|
|
8095 |
DEFVAR_LISP ("latin-extra-code-table", &Vlatin_extra_code_table, |
DEFVAR_LISP ("latin-extra-code-table", &Vlatin_extra_code_table, |
8096 |
doc: /* Table of extra Latin codes in the range 128..159 (inclusive). |
doc: /* |
8097 |
|
Table of extra Latin codes in the range 128..159 (inclusive). |
8098 |
This is a vector of length 256. |
This is a vector of length 256. |
8099 |
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 |
8100 |
\(or output of subprocess) doesn't prevent it to be detected as |
\(or output of subprocess) doesn't prevent it to be detected as |
8106 |
|
|
8107 |
DEFVAR_LISP ("select-safe-coding-system-function", |
DEFVAR_LISP ("select-safe-coding-system-function", |
8108 |
&Vselect_safe_coding_system_function, |
&Vselect_safe_coding_system_function, |
8109 |
doc: /* Function to call to select safe coding system for encoding a text. |
doc: /* |
8110 |
|
Function to call to select safe coding system for encoding a text. |
8111 |
|
|
8112 |
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 |
8113 |
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 |
8117 |
Vselect_safe_coding_system_function = Qnil; |
Vselect_safe_coding_system_function = Qnil; |
8118 |
|
|
8119 |
DEFVAR_LISP ("char-coding-system-table", &Vchar_coding_system_table, |
DEFVAR_LISP ("char-coding-system-table", &Vchar_coding_system_table, |
8120 |
doc: /* Char-table containing safe coding systems of each characters. |
doc: /* |
8121 |
|
Char-table containing safe coding systems of each characters. |
8122 |
Each element doesn't include such generic coding systems that can |
Each element doesn't include such generic coding systems that can |
8123 |
encode any characters. They are in the first extra slot. */); |
encode any characters. They are in the first extra slot. */); |
8124 |
Vchar_coding_system_table = Fmake_char_table (Qchar_coding_system, Qnil); |
Vchar_coding_system_table = Fmake_char_table (Qchar_coding_system, Qnil); |
8125 |
|
|
8126 |
DEFVAR_BOOL ("inhibit-iso-escape-detection", |
DEFVAR_BOOL ("inhibit-iso-escape-detection", |
8127 |
&inhibit_iso_escape_detection, |
&inhibit_iso_escape_detection, |
8128 |
doc: /* If non-nil, Emacs ignores ISO2022's escape sequence on code detection. |
doc: /* |
8129 |
|
If non-nil, Emacs ignores ISO2022's escape sequence on code detection. |
8130 |
|
|
8131 |
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 |
8132 |
encoded. This code detection is sensitive to escape sequences. If |
encoded. This code detection is sensitive to escape sequences. If |
8173 |
} |
} |
8174 |
|
|
8175 |
#endif /* emacs */ |
#endif /* emacs */ |
|
|
|