Mercurial > hg > xemacs-beta
annotate src/mule-ccl.c @ 5643:611a6845ebee
Remove un-needed include of process.h in sysproc.h under cygwin.
author | Vin Shelton <acs@xemacs.org> |
---|---|
date | Mon, 13 Feb 2012 08:00:23 -0500 |
parents | 56144c8593a8 |
children |
rev | line source |
---|---|
428 | 1 /* CCL (Code Conversion Language) interpreter. |
444 | 2 Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN. |
826 | 3 Copyright (C) 2002 Ben Wing. |
428 | 4 Licensed to the Free Software Foundation. |
5 | |
613 | 6 This file is part of XEmacs. |
428 | 7 |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
8 XEmacs is free software: you can redistribute it and/or modify it |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
9 under the terms of the GNU General Public License as published by the |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
10 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
11 option) any later version. |
428 | 12 |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
16 for more details. |
428 | 17 |
18 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5183
diff
changeset
|
19 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 20 |
444 | 21 /* Synched up with : FSF Emacs 21.0.90 except TranslateCharacter */ |
428 | 22 |
23 #include <config.h> | |
771 | 24 #include "lisp.h" |
444 | 25 |
428 | 26 #include "buffer.h" |
771 | 27 #include "charset.h" |
428 | 28 #include "mule-ccl.h" |
29 #include "file-coding.h" | |
4072 | 30 #include "elhash.h" |
428 | 31 |
565 | 32 Lisp_Object Qccl_error; |
33 | |
428 | 34 /* This contains all code conversion map available to CCL. */ |
35 Lisp_Object Vcode_conversion_map_vector; | |
36 | |
444 | 37 /* This symbol is a property which associates with ccl program vector. |
3452 | 38 Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector. |
39 Moved to general-slots.h. */ | |
40 /* Lisp_Object Qccl_program; */ | |
428 | 41 |
42 /* These symbols are properties which associate with code conversion | |
43 map and their ID respectively. */ | |
44 Lisp_Object Qcode_conversion_map; | |
45 Lisp_Object Qcode_conversion_map_id; | |
46 | |
47 /* Symbols of ccl program have this property, a value of the property | |
444 | 48 is an index for Vccl_program_table. */ |
428 | 49 Lisp_Object Qccl_program_idx; |
50 | |
444 | 51 /* Table of registered CCL programs. Each element is a vector of |
52 NAME, CCL_PROG, and RESOLVEDP where NAME (symbol) is the name of | |
53 the program, CCL_PROG (vector) is the compiled code of the program, | |
54 RESOLVEDP (t or nil) is the flag to tell if symbols in CCL_PROG is | |
55 already resolved to index numbers or not. */ | |
428 | 56 Lisp_Object Vccl_program_table; |
57 | |
4072 | 58 /* Vector of registered hash tables for translation. */ |
59 Lisp_Object Vtranslation_hash_table_vector; | |
60 | |
61 /* Return a hash table of id number ID. */ | |
62 #define GET_HASH_TABLE(id) \ | |
63 (XHASH_TABLE (XCDR(XVECTOR(Vtranslation_hash_table_vector)->contents[(id)]))) | |
64 /* Copied from fns.c. */ | |
65 #define HASH_VALUE(H, IDX) AREF ((H)->key_and_value, 2 * (IDX) + 1) | |
66 | |
428 | 67 /* CCL (Code Conversion Language) is a simple language which has |
68 operations on one input buffer, one output buffer, and 7 registers. | |
69 The syntax of CCL is described in `ccl.el'. Emacs Lisp function | |
70 `ccl-compile' compiles a CCL program and produces a CCL code which | |
71 is a vector of integers. The structure of this vector is as | |
72 follows: The 1st element: buffer-magnification, a factor for the | |
73 size of output buffer compared with the size of input buffer. The | |
74 2nd element: address of CCL code to be executed when encountered | |
75 with end of input stream. The 3rd and the remaining elements: CCL | |
76 codes. */ | |
77 | |
78 /* Header of CCL compiled code */ | |
79 #define CCL_HEADER_BUF_MAG 0 | |
80 #define CCL_HEADER_EOF 1 | |
81 #define CCL_HEADER_MAIN 2 | |
82 | |
83 /* CCL code is a sequence of 28-bit non-negative integers (i.e. the | |
84 MSB is always 0), each contains CCL command and/or arguments in the | |
85 following format: | |
86 | |
87 |----------------- integer (28-bit) ------------------| | |
88 |------- 17-bit ------|- 3-bit --|- 3-bit --|- 5-bit -| | |
89 |--constant argument--|-register-|-register-|-command-| | |
90 ccccccccccccccccc RRR rrr XXXXX | |
91 or | |
92 |------- relative address -------|-register-|-command-| | |
93 cccccccccccccccccccc rrr XXXXX | |
94 or | |
95 |------------- constant or other args ----------------| | |
96 cccccccccccccccccccccccccccc | |
97 | |
98 where, `cc...c' is a non-negative integer indicating constant value | |
99 (the left most `c' is always 0) or an absolute jump address, `RRR' | |
100 and `rrr' are CCL register number, `XXXXX' is one of the following | |
101 CCL commands. */ | |
102 | |
103 /* CCL commands | |
104 | |
105 Each comment fields shows one or more lines for command syntax and | |
106 the following lines for semantics of the command. In semantics, IC | |
107 stands for Instruction Counter. */ | |
108 | |
109 #define CCL_SetRegister 0x00 /* Set register a register value: | |
110 1:00000000000000000RRRrrrXXXXX | |
111 ------------------------------ | |
112 reg[rrr] = reg[RRR]; | |
113 */ | |
114 | |
115 #define CCL_SetShortConst 0x01 /* Set register a short constant value: | |
116 1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX | |
117 ------------------------------ | |
118 reg[rrr] = CCCCCCCCCCCCCCCCCCC; | |
119 */ | |
120 | |
121 #define CCL_SetConst 0x02 /* Set register a constant value: | |
122 1:00000000000000000000rrrXXXXX | |
123 2:CONSTANT | |
124 ------------------------------ | |
125 reg[rrr] = CONSTANT; | |
126 IC++; | |
127 */ | |
128 | |
129 #define CCL_SetArray 0x03 /* Set register an element of array: | |
130 1:CCCCCCCCCCCCCCCCCRRRrrrXXXXX | |
131 2:ELEMENT[0] | |
132 3:ELEMENT[1] | |
133 ... | |
134 ------------------------------ | |
135 if (0 <= reg[RRR] < CC..C) | |
136 reg[rrr] = ELEMENT[reg[RRR]]; | |
137 IC += CC..C; | |
138 */ | |
139 | |
140 #define CCL_Jump 0x04 /* Jump: | |
141 1:A--D--D--R--E--S--S-000XXXXX | |
142 ------------------------------ | |
143 IC += ADDRESS; | |
144 */ | |
145 | |
146 /* Note: If CC..C is greater than 0, the second code is omitted. */ | |
147 | |
148 #define CCL_JumpCond 0x05 /* Jump conditional: | |
149 1:A--D--D--R--E--S--S-rrrXXXXX | |
150 ------------------------------ | |
151 if (!reg[rrr]) | |
152 IC += ADDRESS; | |
153 */ | |
154 | |
155 | |
156 #define CCL_WriteRegisterJump 0x06 /* Write register and jump: | |
157 1:A--D--D--R--E--S--S-rrrXXXXX | |
158 ------------------------------ | |
159 write (reg[rrr]); | |
160 IC += ADDRESS; | |
161 */ | |
162 | |
163 #define CCL_WriteRegisterReadJump 0x07 /* Write register, read, and jump: | |
164 1:A--D--D--R--E--S--S-rrrXXXXX | |
165 2:A--D--D--R--E--S--S-rrrYYYYY | |
166 ----------------------------- | |
167 write (reg[rrr]); | |
168 IC++; | |
169 read (reg[rrr]); | |
170 IC += ADDRESS; | |
171 */ | |
172 /* Note: If read is suspended, the resumed execution starts from the | |
173 second code (YYYYY == CCL_ReadJump). */ | |
174 | |
175 #define CCL_WriteConstJump 0x08 /* Write constant and jump: | |
176 1:A--D--D--R--E--S--S-000XXXXX | |
444 | 177 2:CONST |
428 | 178 ------------------------------ |
444 | 179 write (CONST); |
428 | 180 IC += ADDRESS; |
181 */ | |
182 | |
183 #define CCL_WriteConstReadJump 0x09 /* Write constant, read, and jump: | |
184 1:A--D--D--R--E--S--S-rrrXXXXX | |
444 | 185 2:CONST |
428 | 186 3:A--D--D--R--E--S--S-rrrYYYYY |
187 ----------------------------- | |
444 | 188 write (CONST); |
428 | 189 IC += 2; |
190 read (reg[rrr]); | |
191 IC += ADDRESS; | |
192 */ | |
193 /* Note: If read is suspended, the resumed execution starts from the | |
194 second code (YYYYY == CCL_ReadJump). */ | |
195 | |
196 #define CCL_WriteStringJump 0x0A /* Write string and jump: | |
197 1:A--D--D--R--E--S--S-000XXXXX | |
198 2:LENGTH | |
199 3:0000STRIN[0]STRIN[1]STRIN[2] | |
200 ... | |
201 ------------------------------ | |
202 write_string (STRING, LENGTH); | |
203 IC += ADDRESS; | |
204 */ | |
205 | |
206 #define CCL_WriteArrayReadJump 0x0B /* Write an array element, read, and jump: | |
207 1:A--D--D--R--E--S--S-rrrXXXXX | |
208 2:LENGTH | |
209 3:ELEMENET[0] | |
210 4:ELEMENET[1] | |
211 ... | |
212 N:A--D--D--R--E--S--S-rrrYYYYY | |
213 ------------------------------ | |
214 if (0 <= reg[rrr] < LENGTH) | |
215 write (ELEMENT[reg[rrr]]); | |
216 IC += LENGTH + 2; (... pointing at N+1) | |
217 read (reg[rrr]); | |
218 IC += ADDRESS; | |
219 */ | |
220 /* Note: If read is suspended, the resumed execution starts from the | |
221 Nth code (YYYYY == CCL_ReadJump). */ | |
222 | |
223 #define CCL_ReadJump 0x0C /* Read and jump: | |
224 1:A--D--D--R--E--S--S-rrrYYYYY | |
225 ----------------------------- | |
226 read (reg[rrr]); | |
227 IC += ADDRESS; | |
228 */ | |
229 | |
230 #define CCL_Branch 0x0D /* Jump by branch table: | |
231 1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX | |
232 2:A--D--D--R--E-S-S[0]000XXXXX | |
233 3:A--D--D--R--E-S-S[1]000XXXXX | |
234 ... | |
235 ------------------------------ | |
236 if (0 <= reg[rrr] < CC..C) | |
237 IC += ADDRESS[reg[rrr]]; | |
238 else | |
239 IC += ADDRESS[CC..C]; | |
240 */ | |
241 | |
242 #define CCL_ReadRegister 0x0E /* Read bytes into registers: | |
243 1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX | |
244 2:CCCCCCCCCCCCCCCCCCCCrrrXXXXX | |
245 ... | |
246 ------------------------------ | |
247 while (CCC--) | |
248 read (reg[rrr]); | |
249 */ | |
250 | |
251 #define CCL_WriteExprConst 0x0F /* write result of expression: | |
252 1:00000OPERATION000RRR000XXXXX | |
253 2:CONSTANT | |
254 ------------------------------ | |
255 write (reg[RRR] OPERATION CONSTANT); | |
256 IC++; | |
257 */ | |
258 | |
259 /* Note: If the Nth read is suspended, the resumed execution starts | |
260 from the Nth code. */ | |
261 | |
262 #define CCL_ReadBranch 0x10 /* Read one byte into a register, | |
263 and jump by branch table: | |
264 1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX | |
265 2:A--D--D--R--E-S-S[0]000XXXXX | |
266 3:A--D--D--R--E-S-S[1]000XXXXX | |
267 ... | |
268 ------------------------------ | |
269 read (read[rrr]); | |
270 if (0 <= reg[rrr] < CC..C) | |
271 IC += ADDRESS[reg[rrr]]; | |
272 else | |
273 IC += ADDRESS[CC..C]; | |
274 */ | |
275 | |
276 #define CCL_WriteRegister 0x11 /* Write registers: | |
277 1:CCCCCCCCCCCCCCCCCCCrrrXXXXX | |
278 2:CCCCCCCCCCCCCCCCCCCrrrXXXXX | |
279 ... | |
280 ------------------------------ | |
281 while (CCC--) | |
282 write (reg[rrr]); | |
283 ... | |
284 */ | |
285 | |
286 /* Note: If the Nth write is suspended, the resumed execution | |
287 starts from the Nth code. */ | |
288 | |
289 #define CCL_WriteExprRegister 0x12 /* Write result of expression | |
290 1:00000OPERATIONRrrRRR000XXXXX | |
291 ------------------------------ | |
292 write (reg[RRR] OPERATION reg[Rrr]); | |
293 */ | |
294 | |
295 #define CCL_Call 0x13 /* Call the CCL program whose ID is | |
444 | 296 CC..C or cc..c. |
297 1:CCCCCCCCCCCCCCCCCCCCFFFXXXXX | |
298 [2:00000000cccccccccccccccccccc] | |
428 | 299 ------------------------------ |
444 | 300 if (FFF) |
301 call (cc..c) | |
302 IC++; | |
303 else | |
304 call (CC..C) | |
428 | 305 */ |
306 | |
307 #define CCL_WriteConstString 0x14 /* Write a constant or a string: | |
308 1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX | |
309 [2:0000STRIN[0]STRIN[1]STRIN[2]] | |
310 [...] | |
311 ----------------------------- | |
312 if (!rrr) | |
313 write (CC..C) | |
314 else | |
315 write_string (STRING, CC..C); | |
316 IC += (CC..C + 2) / 3; | |
317 */ | |
318 | |
319 #define CCL_WriteArray 0x15 /* Write an element of array: | |
320 1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX | |
321 2:ELEMENT[0] | |
322 3:ELEMENT[1] | |
323 ... | |
324 ------------------------------ | |
325 if (0 <= reg[rrr] < CC..C) | |
326 write (ELEMENT[reg[rrr]]); | |
327 IC += CC..C; | |
328 */ | |
329 | |
330 #define CCL_End 0x16 /* Terminate: | |
331 1:00000000000000000000000XXXXX | |
332 ------------------------------ | |
333 terminate (); | |
334 */ | |
335 | |
336 /* The following two codes execute an assignment arithmetic/logical | |
337 operation. The form of the operation is like REG OP= OPERAND. */ | |
338 | |
339 #define CCL_ExprSelfConst 0x17 /* REG OP= constant: | |
340 1:00000OPERATION000000rrrXXXXX | |
341 2:CONSTANT | |
342 ------------------------------ | |
343 reg[rrr] OPERATION= CONSTANT; | |
344 */ | |
345 | |
346 #define CCL_ExprSelfReg 0x18 /* REG1 OP= REG2: | |
347 1:00000OPERATION000RRRrrrXXXXX | |
348 ------------------------------ | |
349 reg[rrr] OPERATION= reg[RRR]; | |
350 */ | |
351 | |
352 /* The following codes execute an arithmetic/logical operation. The | |
353 form of the operation is like REG_X = REG_Y OP OPERAND2. */ | |
354 | |
355 #define CCL_SetExprConst 0x19 /* REG_X = REG_Y OP constant: | |
356 1:00000OPERATION000RRRrrrXXXXX | |
357 2:CONSTANT | |
358 ------------------------------ | |
359 reg[rrr] = reg[RRR] OPERATION CONSTANT; | |
360 IC++; | |
361 */ | |
362 | |
363 #define CCL_SetExprReg 0x1A /* REG1 = REG2 OP REG3: | |
364 1:00000OPERATIONRrrRRRrrrXXXXX | |
365 ------------------------------ | |
366 reg[rrr] = reg[RRR] OPERATION reg[Rrr]; | |
367 */ | |
368 | |
369 #define CCL_JumpCondExprConst 0x1B /* Jump conditional according to | |
370 an operation on constant: | |
371 1:A--D--D--R--E--S--S-rrrXXXXX | |
372 2:OPERATION | |
373 3:CONSTANT | |
374 ----------------------------- | |
375 reg[7] = reg[rrr] OPERATION CONSTANT; | |
376 if (!(reg[7])) | |
377 IC += ADDRESS; | |
378 else | |
379 IC += 2 | |
380 */ | |
381 | |
382 #define CCL_JumpCondExprReg 0x1C /* Jump conditional according to | |
383 an operation on register: | |
384 1:A--D--D--R--E--S--S-rrrXXXXX | |
385 2:OPERATION | |
386 3:RRR | |
387 ----------------------------- | |
388 reg[7] = reg[rrr] OPERATION reg[RRR]; | |
389 if (!reg[7]) | |
390 IC += ADDRESS; | |
391 else | |
392 IC += 2; | |
393 */ | |
394 | |
395 #define CCL_ReadJumpCondExprConst 0x1D /* Read and jump conditional according | |
396 to an operation on constant: | |
397 1:A--D--D--R--E--S--S-rrrXXXXX | |
398 2:OPERATION | |
399 3:CONSTANT | |
400 ----------------------------- | |
401 read (reg[rrr]); | |
402 reg[7] = reg[rrr] OPERATION CONSTANT; | |
403 if (!reg[7]) | |
404 IC += ADDRESS; | |
405 else | |
406 IC += 2; | |
407 */ | |
408 | |
409 #define CCL_ReadJumpCondExprReg 0x1E /* Read and jump conditional according | |
410 to an operation on register: | |
411 1:A--D--D--R--E--S--S-rrrXXXXX | |
412 2:OPERATION | |
413 3:RRR | |
414 ----------------------------- | |
415 read (reg[rrr]); | |
416 reg[7] = reg[rrr] OPERATION reg[RRR]; | |
417 if (!reg[7]) | |
418 IC += ADDRESS; | |
419 else | |
420 IC += 2; | |
421 */ | |
422 | |
456 | 423 #define CCL_Extension 0x1F /* Extended CCL code |
428 | 424 1:ExtendedCOMMNDRrrRRRrrrXXXXX |
444 | 425 2:ARGUMENT |
428 | 426 3:... |
427 ------------------------------ | |
428 extended_command (rrr,RRR,Rrr,ARGS) | |
429 */ | |
430 | |
442 | 431 /* |
428 | 432 Here after, Extended CCL Instructions. |
433 Bit length of extended command is 14. | |
434 Therefore, the instruction code range is 0..16384(0x3fff). | |
435 */ | |
436 | |
437 /* Read a multibyte characeter. | |
438 A code point is stored into reg[rrr]. A charset ID is stored into | |
439 reg[RRR]. */ | |
440 | |
441 #define CCL_ReadMultibyteChar2 0x00 /* Read Multibyte Character | |
442 1:ExtendedCOMMNDRrrRRRrrrXXXXX */ | |
443 | |
444 /* Write a multibyte character. | |
445 Write a character whose code point is reg[rrr] and the charset ID | |
446 is reg[RRR]. */ | |
447 | |
448 #define CCL_WriteMultibyteChar2 0x01 /* Write Multibyte Character | |
449 1:ExtendedCOMMNDRrrRRRrrrXXXXX */ | |
450 | |
451 /* Translate a character whose code point is reg[rrr] and the charset | |
452 ID is reg[RRR] by a translation table whose ID is reg[Rrr]. | |
453 | |
454 A translated character is set in reg[rrr] (code point) and reg[RRR] | |
455 (charset ID). */ | |
456 | |
457 #define CCL_TranslateCharacter 0x02 /* Translate a multibyte character | |
458 1:ExtendedCOMMNDRrrRRRrrrXXXXX */ | |
459 | |
460 /* Translate a character whose code point is reg[rrr] and the charset | |
461 ID is reg[RRR] by a translation table whose ID is ARGUMENT. | |
462 | |
463 A translated character is set in reg[rrr] (code point) and reg[RRR] | |
464 (charset ID). */ | |
465 | |
466 #define CCL_TranslateCharacterConstTbl 0x03 /* Translate a multibyte character | |
467 1:ExtendedCOMMNDRrrRRRrrrXXXXX | |
468 2:ARGUMENT(Translation Table ID) | |
469 */ | |
3439 | 470 /* Translate a character whose code point is reg[rrr] and charset ID is |
471 reg[RRR], into its Unicode code point, which will be written into | |
472 reg[rrr]. */ | |
473 | |
474 #define CCL_MuleToUnicode 0x04 | |
475 | |
476 /* Translate a Unicode code point, in reg[rrr], into a Mule character, | |
477 writing the charset ID into reg[RRR] and the code point into reg[Rrr]. */ | |
478 | |
479 #define CCL_UnicodeToMule 0x05 | |
428 | 480 |
481 /* Iterate looking up MAPs for reg[rrr] starting from the Nth (N = | |
482 reg[RRR]) MAP until some value is found. | |
483 | |
484 Each MAP is a Lisp vector whose element is number, nil, t, or | |
485 lambda. | |
486 If the element is nil, ignore the map and proceed to the next map. | |
487 If the element is t or lambda, finish without changing reg[rrr]. | |
488 If the element is a number, set reg[rrr] to the number and finish. | |
489 | |
444 | 490 Detail of the map structure is described in the comment for |
428 | 491 CCL_MapMultiple below. */ |
492 | |
493 #define CCL_IterateMultipleMap 0x10 /* Iterate multiple maps | |
494 1:ExtendedCOMMNDXXXRRRrrrXXXXX | |
495 2:NUMBER of MAPs | |
496 3:MAP-ID1 | |
497 4:MAP-ID2 | |
498 ... | |
442 | 499 */ |
428 | 500 |
501 /* Map the code in reg[rrr] by MAPs starting from the Nth (N = | |
502 reg[RRR]) map. | |
503 | |
504 MAPs are supplied in the succeeding CCL codes as follows: | |
505 | |
506 When CCL program gives this nested structure of map to this command: | |
507 ((MAP-ID11 | |
508 MAP-ID12 | |
509 (MAP-ID121 MAP-ID122 MAP-ID123) | |
510 MAP-ID13) | |
511 (MAP-ID21 | |
512 (MAP-ID211 (MAP-ID2111) MAP-ID212) | |
513 MAP-ID22)), | |
444 | 514 the compiled CCL code has this sequence: |
428 | 515 CCL_MapMultiple (CCL code of this command) |
516 16 (total number of MAPs and SEPARATORs) | |
517 -7 (1st SEPARATOR) | |
518 MAP-ID11 | |
519 MAP-ID12 | |
520 -3 (2nd SEPARATOR) | |
521 MAP-ID121 | |
522 MAP-ID122 | |
523 MAP-ID123 | |
524 MAP-ID13 | |
525 -7 (3rd SEPARATOR) | |
526 MAP-ID21 | |
527 -4 (4th SEPARATOR) | |
528 MAP-ID211 | |
529 -1 (5th SEPARATOR) | |
530 MAP_ID2111 | |
531 MAP-ID212 | |
532 MAP-ID22 | |
533 | |
534 A value of each SEPARATOR follows this rule: | |
535 MAP-SET := SEPARATOR [(MAP-ID | MAP-SET)]+ | |
536 SEPARATOR := -(number of MAP-IDs and SEPARATORs in the MAP-SET) | |
537 | |
538 (*)....Nest level of MAP-SET must not be over than MAX_MAP_SET_LEVEL. | |
539 | |
540 When some map fails to map (i.e. it doesn't have a value for | |
541 reg[rrr]), the mapping is treated as identity. | |
542 | |
543 The mapping is iterated for all maps in each map set (set of maps | |
544 separated by SEPARATOR) except in the case that lambda is | |
545 encountered. More precisely, the mapping proceeds as below: | |
546 | |
547 At first, VAL0 is set to reg[rrr], and it is translated by the | |
548 first map to VAL1. Then, VAL1 is translated by the next map to | |
549 VAL2. This mapping is iterated until the last map is used. The | |
444 | 550 result of the mapping is the last value of VAL?. When the mapping |
551 process reached to the end of the map set, it moves to the next | |
552 map set. If the next does not exit, the mapping process terminates, | |
553 and regard the last value as a result. | |
428 | 554 |
555 But, when VALm is mapped to VALn and VALn is not a number, the | |
444 | 556 mapping proceeds as follows: |
428 | 557 |
558 If VALn is nil, the lastest map is ignored and the mapping of VALm | |
444 | 559 proceeds to the next map. |
428 | 560 |
561 In VALn is t, VALm is reverted to reg[rrr] and the mapping of VALm | |
444 | 562 proceeds to the next map. |
428 | 563 |
444 | 564 If VALn is lambda, move to the next map set like reaching to the |
565 end of the current map set. | |
566 | |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5307
diff
changeset
|
567 If VALn is a symbol, call the CCL program referred to by it. |
444 | 568 Then, use reg[rrr] as a mapped value except for -1, -2 and -3. |
569 Such special values are regarded as nil, t, and lambda respectively. | |
428 | 570 |
571 Each map is a Lisp vector of the following format (a) or (b): | |
572 (a)......[STARTPOINT VAL1 VAL2 ...] | |
573 (b)......[t VAL STARTPOINT ENDPOINT], | |
574 where | |
575 STARTPOINT is an offset to be used for indexing a map, | |
576 ENDPOINT is a maximum index number of a map, | |
442 | 577 VAL and VALn is a number, nil, t, or lambda. |
428 | 578 |
579 Valid index range of a map of type (a) is: | |
580 STARTPOINT <= index < STARTPOINT + map_size - 1 | |
581 Valid index range of a map of type (b) is: | |
582 STARTPOINT <= index < ENDPOINT */ | |
583 | |
584 #define CCL_MapMultiple 0x11 /* Mapping by multiple code conversion maps | |
585 1:ExtendedCOMMNDXXXRRRrrrXXXXX | |
586 2:N-2 | |
587 3:SEPARATOR_1 (< 0) | |
588 4:MAP-ID_1 | |
589 5:MAP-ID_2 | |
590 ... | |
591 M:SEPARATOR_x (< 0) | |
592 M+1:MAP-ID_y | |
593 ... | |
594 N:SEPARATOR_z (< 0) | |
595 */ | |
444 | 596 #define MAX_MAP_SET_LEVEL 30 |
428 | 597 |
598 typedef struct | |
599 { | |
600 int rest_length; | |
601 int orig_val; | |
602 } tr_stack; | |
603 | |
604 static tr_stack mapping_stack[MAX_MAP_SET_LEVEL]; | |
605 static tr_stack *mapping_stack_pointer; | |
444 | 606 |
607 /* If this variable is non-zero, it indicates the stack_idx | |
608 of immediately called by CCL_MapMultiple. */ | |
450 | 609 static int stack_idx_of_map_multiple; |
444 | 610 |
611 #define PUSH_MAPPING_STACK(restlen, orig) \ | |
612 do { \ | |
613 mapping_stack_pointer->rest_length = (restlen); \ | |
614 mapping_stack_pointer->orig_val = (orig); \ | |
615 mapping_stack_pointer++; \ | |
616 } while (0) | |
617 | |
618 #define POP_MAPPING_STACK(restlen, orig) \ | |
619 do { \ | |
620 mapping_stack_pointer--; \ | |
621 (restlen) = mapping_stack_pointer->rest_length; \ | |
622 (orig) = mapping_stack_pointer->orig_val; \ | |
623 } while (0) | |
428 | 624 |
444 | 625 #define CCL_CALL_FOR_MAP_INSTRUCTION(symbol, ret_ic) \ |
626 do { \ | |
627 struct ccl_program called_ccl; \ | |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
628 /* We shouldn't ever call setup_ccl_program on a vector in \ |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
629 this context: */ \ |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
630 text_checking_assert (SYMBOLP (symbol)); \ |
444 | 631 if (stack_idx >= 256 \ |
632 || (setup_ccl_program (&called_ccl, (symbol)) != 0)) \ | |
633 { \ | |
634 if (stack_idx > 0) \ | |
635 { \ | |
636 ccl_prog = ccl_prog_stack_struct[0].ccl_prog; \ | |
637 ic = ccl_prog_stack_struct[0].ic; \ | |
4193 | 638 eof_ic = ccl_prog_stack_struct[0].eof_ic; \ |
444 | 639 } \ |
640 CCL_INVALID_CMD; \ | |
641 } \ | |
642 ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog; \ | |
643 ccl_prog_stack_struct[stack_idx].ic = (ret_ic); \ | |
4193 | 644 ccl_prog_stack_struct[stack_idx].eof_ic = eof_ic; \ |
444 | 645 stack_idx++; \ |
646 ccl_prog = called_ccl.prog; \ | |
647 ic = CCL_HEADER_MAIN; \ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
648 eof_ic = XFIXNUM (ccl_prog[CCL_HEADER_EOF]); \ |
456 | 649 /* The "if (1)" prevents warning \ |
650 "end-of loop code not reached" */ \ | |
651 if (1) goto ccl_repeat; \ | |
444 | 652 } while (0) |
428 | 653 |
654 #define CCL_MapSingle 0x12 /* Map by single code conversion map | |
655 1:ExtendedCOMMNDXXXRRRrrrXXXXX | |
656 2:MAP-ID | |
657 ------------------------------ | |
658 Map reg[rrr] by MAP-ID. | |
659 If some valid mapping is found, | |
660 set reg[rrr] to the result, | |
661 else | |
662 set reg[RRR] to -1. | |
663 */ | |
664 | |
4072 | 665 #define CCL_LookupIntConstTbl 0x13 /* Lookup multibyte character by |
666 integer key. Afterwards R7 set | |
667 to 1 iff lookup succeeded. | |
668 1:ExtendedCOMMNDRrrRRRXXXXXXXX | |
669 2:ARGUMENT(Hash table ID) */ | |
670 | |
671 #define CCL_LookupCharConstTbl 0x14 /* Lookup integer by multibyte | |
672 character key. Afterwards R7 set | |
673 to 1 iff lookup succeeded. | |
674 1:ExtendedCOMMNDRrrRRRrrrXXXXX | |
675 2:ARGUMENT(Hash table ID) */ | |
676 | |
677 | |
428 | 678 /* CCL arithmetic/logical operators. */ |
679 #define CCL_PLUS 0x00 /* X = Y + Z */ | |
680 #define CCL_MINUS 0x01 /* X = Y - Z */ | |
681 #define CCL_MUL 0x02 /* X = Y * Z */ | |
682 #define CCL_DIV 0x03 /* X = Y / Z */ | |
683 #define CCL_MOD 0x04 /* X = Y % Z */ | |
684 #define CCL_AND 0x05 /* X = Y & Z */ | |
685 #define CCL_OR 0x06 /* X = Y | Z */ | |
686 #define CCL_XOR 0x07 /* X = Y ^ Z */ | |
687 #define CCL_LSH 0x08 /* X = Y << Z */ | |
688 #define CCL_RSH 0x09 /* X = Y >> Z */ | |
689 #define CCL_LSH8 0x0A /* X = (Y << 8) | Z */ | |
690 #define CCL_RSH8 0x0B /* X = Y >> 8, r[7] = Y & 0xFF */ | |
691 #define CCL_DIVMOD 0x0C /* X = Y / Z, r[7] = Y % Z */ | |
692 #define CCL_LS 0x10 /* X = (X < Y) */ | |
693 #define CCL_GT 0x11 /* X = (X > Y) */ | |
694 #define CCL_EQ 0x12 /* X = (X == Y) */ | |
695 #define CCL_LE 0x13 /* X = (X <= Y) */ | |
696 #define CCL_GE 0x14 /* X = (X >= Y) */ | |
697 #define CCL_NE 0x15 /* X = (X != Y) */ | |
698 | |
699 #define CCL_DECODE_SJIS 0x16 /* X = HIGHER_BYTE (DE-SJIS (Y, Z)) | |
700 r[7] = LOWER_BYTE (DE-SJIS (Y, Z)) */ | |
701 #define CCL_ENCODE_SJIS 0x17 /* X = HIGHER_BYTE (SJIS (Y, Z)) | |
702 r[7] = LOWER_BYTE (SJIS (Y, Z) */ | |
703 | |
444 | 704 /* Terminate CCL program successfully. */ |
462 | 705 #define CCL_SUCCESS \ |
706 do { \ | |
707 ccl->status = CCL_STAT_SUCCESS; \ | |
456 | 708 /* The "if (1)" inhibits the warning \ |
709 "end-of loop code not reached" */ \ | |
710 if (1) goto ccl_finish; \ | |
462 | 711 } while (0) |
444 | 712 |
428 | 713 /* Suspend CCL program because of reading from empty input buffer or |
714 writing to full output buffer. When this program is resumed, the | |
444 | 715 same I/O command is executed. */ |
462 | 716 #define CCL_SUSPEND(stat) \ |
717 do { \ | |
718 ic--; \ | |
456 | 719 ccl->status = (stat); \ |
720 /* The "if (1)" inhibits the warning \ | |
721 "end-of loop code not reached" */ \ | |
722 if (1) goto ccl_finish; \ | |
462 | 723 } while (0) |
428 | 724 |
725 /* Terminate CCL program because of invalid command. Should not occur | |
444 | 726 in the normal case. */ |
771 | 727 #define CCL_INVALID_CMD \ |
728 do { \ | |
729 ccl->status = CCL_STAT_INVALID_CMD; \ | |
730 /* enable this to debug invalid cmd errors */ \ | |
731 /* debug_break (); */ \ | |
732 /* The "if (1)" inhibits the warning \ | |
733 "end-of loop code not reached" */ \ | |
734 if (1) goto ccl_error_handler; \ | |
462 | 735 } while (0) |
428 | 736 |
737 /* Encode one character CH to multibyte form and write to the current | |
444 | 738 output buffer. At encoding time, if CH is less than 256, CH is |
739 written as is. At decoding time, if CH cannot be regarded as an | |
740 ASCII character, write it in multibyte form. */ | |
741 #define CCL_WRITE_CHAR(ch) \ | |
742 do { \ | |
743 if (!destination) \ | |
744 CCL_INVALID_CMD; \ | |
745 if (conversion_mode == CCL_MODE_ENCODING) \ | |
746 { \ | |
456 | 747 if ((ch) == '\n') \ |
444 | 748 { \ |
749 if (ccl->eol_type == CCL_CODING_EOL_CRLF) \ | |
750 { \ | |
751 Dynarr_add (destination, '\r'); \ | |
752 Dynarr_add (destination, '\n'); \ | |
753 } \ | |
754 else if (ccl->eol_type == CCL_CODING_EOL_CR) \ | |
755 Dynarr_add (destination, '\r'); \ | |
756 else \ | |
757 Dynarr_add (destination, '\n'); \ | |
758 } \ | |
456 | 759 else if ((ch) < 0x100) \ |
444 | 760 { \ |
761 Dynarr_add (destination, ch); \ | |
762 } \ | |
763 else \ | |
764 { \ | |
2286 | 765 Ibyte work[MAX_ICHAR_LEN]; \ |
444 | 766 int len; \ |
2286 | 767 len = non_ascii_set_itext_ichar (work, ch); \ |
444 | 768 Dynarr_add_many (destination, work, len); \ |
769 } \ | |
770 } \ | |
771 else \ | |
772 { \ | |
867 | 773 if (!ichar_multibyte_p(ch)) \ |
444 | 774 { \ |
775 Dynarr_add (destination, ch); \ | |
776 } \ | |
777 else \ | |
778 { \ | |
2286 | 779 Ibyte work[MAX_ICHAR_LEN]; \ |
444 | 780 int len; \ |
2286 | 781 len = non_ascii_set_itext_ichar (work, ch); \ |
444 | 782 Dynarr_add_many (destination, work, len); \ |
783 } \ | |
784 } \ | |
785 } while (0) | |
428 | 786 |
787 /* Write a string at ccl_prog[IC] of length LEN to the current output | |
444 | 788 buffer. But this macro treat this string as a binary. Therefore, |
789 cannot handle a multibyte string except for Control-1 characters. */ | |
790 #define CCL_WRITE_STRING(len) \ | |
791 do { \ | |
2286 | 792 Ibyte work[MAX_ICHAR_LEN]; \ |
793 int ch; \ | |
444 | 794 if (!destination) \ |
795 CCL_INVALID_CMD; \ | |
796 else if (conversion_mode == CCL_MODE_ENCODING) \ | |
797 { \ | |
456 | 798 for (i = 0; i < (len); i++) \ |
444 | 799 { \ |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
800 ch = ((XCHAR_OR_FIXNUM (ccl_prog[ic + (i / 3)])) \ |
444 | 801 >> ((2 - (i % 3)) * 8)) & 0xFF; \ |
802 if (ch == '\n') \ | |
803 { \ | |
804 if (ccl->eol_type == CCL_CODING_EOL_CRLF) \ | |
805 { \ | |
806 Dynarr_add (destination, '\r'); \ | |
807 Dynarr_add (destination, '\n'); \ | |
808 } \ | |
809 else if (ccl->eol_type == CCL_CODING_EOL_CR) \ | |
810 Dynarr_add (destination, '\r'); \ | |
811 else \ | |
812 Dynarr_add (destination, '\n'); \ | |
813 } \ | |
814 if (ch < 0x100) \ | |
815 { \ | |
816 Dynarr_add (destination, ch); \ | |
817 } \ | |
818 else \ | |
819 { \ | |
2286 | 820 non_ascii_set_itext_ichar (work, ch); \ |
444 | 821 Dynarr_add_many (destination, work, len); \ |
822 } \ | |
823 } \ | |
824 } \ | |
825 else \ | |
826 { \ | |
456 | 827 for (i = 0; i < (len); i++) \ |
444 | 828 { \ |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
829 ch = ((XCHAR_OR_FIXNUM (ccl_prog[ic + (i / 3)])) \ |
444 | 830 >> ((2 - (i % 3)) * 8)) & 0xFF; \ |
867 | 831 if (!ichar_multibyte_p(ch)) \ |
444 | 832 { \ |
833 Dynarr_add (destination, ch); \ | |
834 } \ | |
835 else \ | |
836 { \ | |
2286 | 837 non_ascii_set_itext_ichar (work, ch); \ |
444 | 838 Dynarr_add_many (destination, work, len); \ |
839 } \ | |
840 } \ | |
841 } \ | |
842 } while (0) | |
428 | 843 |
844 /* Read one byte from the current input buffer into Rth register. */ | |
444 | 845 #define CCL_READ_CHAR(r) \ |
846 do { \ | |
847 if (!src) \ | |
848 CCL_INVALID_CMD; \ | |
849 if (src < src_end) \ | |
456 | 850 (r) = *src++; \ |
444 | 851 else \ |
852 { \ | |
853 if (ccl->last_block) \ | |
854 { \ | |
855 ic = ccl->eof_ic; \ | |
856 goto ccl_repeat; \ | |
857 } \ | |
858 else \ | |
859 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC); \ | |
860 } \ | |
861 } while (0) | |
862 | |
2830 | 863 #define POSSIBLE_LEADING_BYTE_P(leading_byte) \ |
4072 | 864 ((leading_byte >= MIN_LEADING_BYTE) && \ |
2829 | 865 (leading_byte - MIN_LEADING_BYTE) < NUM_LEADING_BYTES) |
444 | 866 |
867 /* Set C to the character code made from CHARSET and CODE. This is | |
867 | 868 like make_ichar but check the validity of CHARSET and CODE. If they |
444 | 869 are not valid, set C to (CODE & 0xFF) because that is usually the |
870 case that CCL_ReadMultibyteChar2 read an invalid code and it set | |
871 CODE to that invalid byte. */ | |
872 | |
873 /* On XEmacs, TranslateCharacter is not supported. Thus, this | |
3439 | 874 macro is only used in the MuleToUnicode transformation. */ |
444 | 875 #define CCL_MAKE_CHAR(charset, code, c) \ |
876 do { \ | |
3690 | 877 \ |
878 if (!POSSIBLE_LEADING_BYTE_P(charset)) \ | |
879 CCL_INVALID_CMD; \ | |
880 \ | |
3439 | 881 if ((charset) == LEADING_BYTE_ASCII) \ |
882 { \ | |
883 c = (code) & 0xFF; \ | |
884 } \ | |
885 else if ((charset) == LEADING_BYTE_CONTROL_1) \ | |
886 { \ | |
3690 | 887 c = ((code) & 0x1F) + 0x80; \ |
3439 | 888 } \ |
889 else if (!NILP(charset_by_leading_byte(charset)) \ | |
890 && ((code) >= 32) \ | |
4072 | 891 && ((code) < 256 || ((code >> 7) & 0x7F) >= 32)) \ |
444 | 892 { \ |
3439 | 893 int c1, c2 = 0; \ |
444 | 894 \ |
3439 | 895 if ((code) < 256) \ |
896 { \ | |
897 c1 = (code) & 0x7F; \ | |
898 c2 = 0; \ | |
899 } \ | |
900 else \ | |
901 { \ | |
4072 | 902 c1 = ((code) >> 7) & 0x7F; \ |
3439 | 903 c2 = (code) & 0x7F; \ |
904 } \ | |
905 c = make_ichar (charset_by_leading_byte(charset), \ | |
906 c1, c2); \ | |
444 | 907 } \ |
908 else \ | |
3439 | 909 { \ |
910 c = (code) & 0xFF; \ | |
911 } \ | |
912 } while (0) | |
428 | 913 |
914 | |
915 /* Execute CCL code on SRC_BYTES length text at SOURCE. The resulting | |
444 | 916 text goes to a place pointed by DESTINATION, the length of which |
917 should not exceed DST_BYTES. The bytes actually processed is | |
918 returned as *CONSUMED. The return value is the length of the | |
919 resulting text. As a side effect, the contents of CCL registers | |
428 | 920 are updated. If SOURCE or DESTINATION is NULL, only operations on |
921 registers are permitted. */ | |
922 | |
923 #ifdef CCL_DEBUG | |
924 #define CCL_DEBUG_BACKTRACE_LEN 256 | |
4072 | 925 int ccl_backtrace_table[CCL_DEBUG_BACKTRACE_LEN]; |
428 | 926 int ccl_backtrace_idx; |
927 #endif | |
928 | |
929 struct ccl_prog_stack | |
930 { | |
931 Lisp_Object *ccl_prog; /* Pointer to an array of CCL code. */ | |
932 int ic; /* Instruction Counter. */ | |
4193 | 933 int eof_ic; /* Instruction Counter to jump on EOF. */ |
428 | 934 }; |
935 | |
442 | 936 /* For the moment, we only support depth 256 of stack. */ |
428 | 937 static struct ccl_prog_stack ccl_prog_stack_struct[256]; |
938 | |
939 int | |
444 | 940 ccl_driver (struct ccl_program *ccl, |
941 const unsigned char *source, | |
942 unsigned_char_dynarr *destination, | |
943 int src_bytes, | |
944 int *consumed, | |
945 int conversion_mode) | |
428 | 946 { |
444 | 947 register int *reg = ccl->reg; |
948 register int ic = ccl->ic; | |
949 register int code = -1; | |
950 register int field1, field2; | |
951 register Lisp_Object *ccl_prog = ccl->prog; | |
442 | 952 const unsigned char *src = source, *src_end = src + src_bytes; |
444 | 953 int jump_address; |
5183
f283b08ff0c9
Avoid build failure, Apple's g++-4.0.1, Mac OS 10.4.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4967
diff
changeset
|
954 int i = 0, j, op; |
428 | 955 int stack_idx = ccl->stack_idx; |
956 /* Instruction counter of the current CCL code. */ | |
957 int this_ic = 0; | |
4193 | 958 int eof_ic = ccl->eof_ic; |
959 int eof_hit = 0; | |
428 | 960 |
4193 | 961 if (ic >= eof_ic) |
428 | 962 ic = CCL_HEADER_MAIN; |
963 | |
964 if (ccl->buf_magnification ==0) /* We can't produce any bytes. */ | |
444 | 965 destination = NULL; |
966 | |
967 /* Set mapping stack pointer. */ | |
968 mapping_stack_pointer = mapping_stack; | |
428 | 969 |
970 #ifdef CCL_DEBUG | |
971 ccl_backtrace_idx = 0; | |
972 #endif | |
973 | |
974 for (;;) | |
975 { | |
976 ccl_repeat: | |
977 #ifdef CCL_DEBUG | |
978 ccl_backtrace_table[ccl_backtrace_idx++] = ic; | |
979 if (ccl_backtrace_idx >= CCL_DEBUG_BACKTRACE_LEN) | |
980 ccl_backtrace_idx = 0; | |
981 ccl_backtrace_table[ccl_backtrace_idx] = 0; | |
982 #endif | |
983 | |
984 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) | |
985 { | |
986 /* We can't just signal Qquit, instead break the loop as if | |
987 the whole data is processed. Don't reset Vquit_flag, it | |
988 must be handled later at a safer place. */ | |
989 if (consumed) | |
990 src = source + src_bytes; | |
991 ccl->status = CCL_STAT_QUIT; | |
992 break; | |
993 } | |
994 | |
995 this_ic = ic; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
996 code = XCHAR_OR_FIXNUM (ccl_prog[ic]); ic++; |
428 | 997 field1 = code >> 8; |
998 field2 = (code & 0xFF) >> 5; | |
999 | |
1000 #define rrr field2 | |
1001 #define RRR (field1 & 7) | |
1002 #define Rrr ((field1 >> 3) & 7) | |
1003 #define ADDR field1 | |
1004 #define EXCMD (field1 >> 6) | |
1005 | |
1006 switch (code & 0x1F) | |
1007 { | |
1008 case CCL_SetRegister: /* 00000000000000000RRRrrrXXXXX */ | |
1009 reg[rrr] = reg[RRR]; | |
1010 break; | |
1011 | |
1012 case CCL_SetShortConst: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ | |
1013 reg[rrr] = field1; | |
1014 break; | |
1015 | |
1016 case CCL_SetConst: /* 00000000000000000000rrrXXXXX */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1017 reg[rrr] = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1018 ic++; |
1019 break; | |
1020 | |
1021 case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */ | |
1022 i = reg[RRR]; | |
1023 j = field1 >> 3; | |
647 | 1024 /* #### it's non-obvious to me that we need these casts, |
1025 but the left one was already there so clearly the intention | |
1026 was an unsigned comparison. --ben */ | |
1027 if ((unsigned int) i < (unsigned int) j) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1028 reg[rrr] = XCHAR_OR_FIXNUM (ccl_prog[ic + i]); |
428 | 1029 ic += j; |
1030 break; | |
1031 | |
1032 case CCL_Jump: /* A--D--D--R--E--S--S-000XXXXX */ | |
1033 ic += ADDR; | |
1034 break; | |
1035 | |
1036 case CCL_JumpCond: /* A--D--D--R--E--S--S-rrrXXXXX */ | |
1037 if (!reg[rrr]) | |
1038 ic += ADDR; | |
1039 break; | |
1040 | |
1041 case CCL_WriteRegisterJump: /* A--D--D--R--E--S--S-rrrXXXXX */ | |
1042 i = reg[rrr]; | |
1043 CCL_WRITE_CHAR (i); | |
1044 ic += ADDR; | |
1045 break; | |
1046 | |
1047 case CCL_WriteRegisterReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ | |
1048 i = reg[rrr]; | |
1049 CCL_WRITE_CHAR (i); | |
1050 ic++; | |
1051 CCL_READ_CHAR (reg[rrr]); | |
1052 ic += ADDR - 1; | |
1053 break; | |
1054 | |
1055 case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1056 i = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1057 CCL_WRITE_CHAR (i); |
1058 ic += ADDR; | |
1059 break; | |
1060 | |
1061 case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1062 i = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1063 CCL_WRITE_CHAR (i); |
1064 ic++; | |
1065 CCL_READ_CHAR (reg[rrr]); | |
1066 ic += ADDR - 1; | |
1067 break; | |
1068 | |
1069 case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1070 j = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1071 ic++; |
1072 CCL_WRITE_STRING (j); | |
1073 ic += ADDR - 1; | |
1074 break; | |
1075 | |
1076 case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ | |
1077 i = reg[rrr]; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1078 j = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
647 | 1079 /* #### see comment at CCL_SetArray */ |
1080 if ((unsigned int) i < (unsigned int) j) | |
428 | 1081 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1082 i = XCHAR_OR_FIXNUM (ccl_prog[ic + 1 + i]); |
428 | 1083 CCL_WRITE_CHAR (i); |
1084 } | |
1085 ic += j + 2; | |
1086 CCL_READ_CHAR (reg[rrr]); | |
1087 ic += ADDR - (j + 2); | |
1088 break; | |
1089 | |
1090 case CCL_ReadJump: /* A--D--D--R--E--S--S-rrrYYYYY */ | |
1091 CCL_READ_CHAR (reg[rrr]); | |
1092 ic += ADDR; | |
1093 break; | |
1094 | |
1095 case CCL_ReadBranch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ | |
1096 CCL_READ_CHAR (reg[rrr]); | |
1097 /* fall through ... */ | |
1098 case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ | |
647 | 1099 /* #### see comment at CCL_SetArray */ |
1100 if ((unsigned int) reg[rrr] < (unsigned int) field1) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1101 ic += XCHAR_OR_FIXNUM (ccl_prog[ic + reg[rrr]]); |
428 | 1102 else |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1103 ic += XCHAR_OR_FIXNUM (ccl_prog[ic + field1]); |
428 | 1104 break; |
1105 | |
1106 case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */ | |
1107 while (1) | |
1108 { | |
1109 CCL_READ_CHAR (reg[rrr]); | |
1110 if (!field1) break; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1111 code = XCHAR_OR_FIXNUM (ccl_prog[ic]); ic++; |
428 | 1112 field1 = code >> 8; |
1113 field2 = (code & 0xFF) >> 5; | |
1114 } | |
1115 break; | |
1116 | |
1117 case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */ | |
1118 rrr = 7; | |
1119 i = reg[RRR]; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1120 j = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1121 op = field1 >> 6; |
444 | 1122 jump_address = ic + 1; |
428 | 1123 goto ccl_set_expr; |
1124 | |
1125 case CCL_WriteRegister: /* CCCCCCCCCCCCCCCCCCCrrrXXXXX */ | |
1126 while (1) | |
1127 { | |
1128 i = reg[rrr]; | |
1129 CCL_WRITE_CHAR (i); | |
1130 if (!field1) break; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1131 code = XCHAR_OR_FIXNUM (ccl_prog[ic]); ic++; |
428 | 1132 field1 = code >> 8; |
1133 field2 = (code & 0xFF) >> 5; | |
1134 } | |
1135 break; | |
1136 | |
1137 case CCL_WriteExprRegister: /* 1:00000OPERATIONRrrRRR000XXXXX */ | |
1138 rrr = 7; | |
1139 i = reg[RRR]; | |
1140 j = reg[Rrr]; | |
1141 op = field1 >> 6; | |
444 | 1142 jump_address = ic; |
428 | 1143 goto ccl_set_expr; |
1144 | |
444 | 1145 case CCL_Call: /* 1:CCCCCCCCCCCCCCCCCCCCFFFXXXXX */ |
428 | 1146 { |
1147 Lisp_Object slot; | |
444 | 1148 int prog_id; |
1149 | |
1150 /* If FFF is nonzero, the CCL program ID is in the | |
1151 following code. */ | |
1152 if (rrr) | |
1153 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1154 prog_id = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
444 | 1155 ic++; |
1156 } | |
1157 else | |
1158 prog_id = field1; | |
428 | 1159 |
1160 if (stack_idx >= 256 | |
444 | 1161 || prog_id < 0 |
1162 || prog_id >= XVECTOR (Vccl_program_table)->size | |
1163 || (slot = XVECTOR (Vccl_program_table)->contents[prog_id], | |
1164 !VECTORP (slot)) | |
1165 || !VECTORP (XVECTOR (slot)->contents[1])) | |
428 | 1166 { |
1167 if (stack_idx > 0) | |
1168 { | |
1169 ccl_prog = ccl_prog_stack_struct[0].ccl_prog; | |
1170 ic = ccl_prog_stack_struct[0].ic; | |
4193 | 1171 eof_ic = ccl_prog_stack_struct[0].eof_ic; |
428 | 1172 } |
444 | 1173 CCL_INVALID_CMD; |
428 | 1174 } |
1175 | |
1176 ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog; | |
1177 ccl_prog_stack_struct[stack_idx].ic = ic; | |
4193 | 1178 ccl_prog_stack_struct[stack_idx].eof_ic = eof_ic; |
428 | 1179 stack_idx++; |
444 | 1180 ccl_prog = XVECTOR (XVECTOR (slot)->contents[1])->contents; |
428 | 1181 ic = CCL_HEADER_MAIN; |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1182 eof_ic = XFIXNUM (ccl_prog[CCL_HEADER_EOF]); |
428 | 1183 } |
1184 break; | |
1185 | |
1186 case CCL_WriteConstString: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ | |
1187 if (!rrr) | |
1188 CCL_WRITE_CHAR (field1); | |
1189 else | |
1190 { | |
1191 CCL_WRITE_STRING (field1); | |
1192 ic += (field1 + 2) / 3; | |
1193 } | |
1194 break; | |
1195 | |
1196 case CCL_WriteArray: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ | |
1197 i = reg[rrr]; | |
647 | 1198 /* #### see comment at CCL_SetArray */ |
1199 if ((unsigned int) i < (unsigned int) field1) | |
428 | 1200 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1201 j = XCHAR_OR_FIXNUM (ccl_prog[ic + i]); |
428 | 1202 CCL_WRITE_CHAR (j); |
1203 } | |
1204 ic += field1; | |
1205 break; | |
1206 | |
1207 case CCL_End: /* 0000000000000000000000XXXXX */ | |
444 | 1208 if (stack_idx > 0) |
428 | 1209 { |
444 | 1210 stack_idx--; |
428 | 1211 ccl_prog = ccl_prog_stack_struct[stack_idx].ccl_prog; |
1212 ic = ccl_prog_stack_struct[stack_idx].ic; | |
4193 | 1213 eof_ic = ccl_prog_stack_struct[stack_idx].eof_ic; |
1214 if (eof_hit) | |
1215 ic = eof_ic; | |
428 | 1216 break; |
1217 } | |
1218 if (src) | |
1219 src = src_end; | |
1220 /* ccl->ic should points to this command code again to | |
1221 suppress further processing. */ | |
1222 ic--; | |
444 | 1223 CCL_SUCCESS; |
428 | 1224 |
1225 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1226 i = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1227 ic++; |
1228 op = field1 >> 6; | |
1229 goto ccl_expr_self; | |
1230 | |
1231 case CCL_ExprSelfReg: /* 00000OPERATION000RRRrrrXXXXX */ | |
1232 i = reg[RRR]; | |
1233 op = field1 >> 6; | |
1234 | |
1235 ccl_expr_self: | |
1236 switch (op) | |
1237 { | |
1238 case CCL_PLUS: reg[rrr] += i; break; | |
1239 case CCL_MINUS: reg[rrr] -= i; break; | |
1240 case CCL_MUL: reg[rrr] *= i; break; | |
1241 case CCL_DIV: reg[rrr] /= i; break; | |
1242 case CCL_MOD: reg[rrr] %= i; break; | |
1243 case CCL_AND: reg[rrr] &= i; break; | |
1244 case CCL_OR: reg[rrr] |= i; break; | |
1245 case CCL_XOR: reg[rrr] ^= i; break; | |
1246 case CCL_LSH: reg[rrr] <<= i; break; | |
1247 case CCL_RSH: reg[rrr] >>= i; break; | |
1248 case CCL_LSH8: reg[rrr] <<= 8; reg[rrr] |= i; break; | |
1249 case CCL_RSH8: reg[7] = reg[rrr] & 0xFF; reg[rrr] >>= 8; break; | |
1250 case CCL_DIVMOD: reg[7] = reg[rrr] % i; reg[rrr] /= i; break; | |
1251 case CCL_LS: reg[rrr] = reg[rrr] < i; break; | |
1252 case CCL_GT: reg[rrr] = reg[rrr] > i; break; | |
1253 case CCL_EQ: reg[rrr] = reg[rrr] == i; break; | |
1254 case CCL_LE: reg[rrr] = reg[rrr] <= i; break; | |
1255 case CCL_GE: reg[rrr] = reg[rrr] >= i; break; | |
1256 case CCL_NE: reg[rrr] = reg[rrr] != i; break; | |
444 | 1257 default: CCL_INVALID_CMD; |
428 | 1258 } |
1259 break; | |
1260 | |
1261 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */ | |
1262 i = reg[RRR]; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1263 j = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1264 op = field1 >> 6; |
1265 jump_address = ++ic; | |
1266 goto ccl_set_expr; | |
1267 | |
1268 case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */ | |
1269 i = reg[RRR]; | |
1270 j = reg[Rrr]; | |
1271 op = field1 >> 6; | |
1272 jump_address = ic; | |
1273 goto ccl_set_expr; | |
1274 | |
1275 case CCL_ReadJumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ | |
1276 CCL_READ_CHAR (reg[rrr]); | |
1277 case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ | |
1278 i = reg[rrr]; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1279 op = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1280 jump_address = ic++ + ADDR; |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1281 j = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1282 ic++; |
1283 rrr = 7; | |
1284 goto ccl_set_expr; | |
1285 | |
1286 case CCL_ReadJumpCondExprReg: /* A--D--D--R--E--S--S-rrrXXXXX */ | |
1287 CCL_READ_CHAR (reg[rrr]); | |
1288 case CCL_JumpCondExprReg: | |
1289 i = reg[rrr]; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1290 op = XCHAR_OR_FIXNUM (ccl_prog[ic]); |
428 | 1291 jump_address = ic++ + ADDR; |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1292 j = reg[XCHAR_OR_FIXNUM (ccl_prog[ic])]; |
428 | 1293 ic++; |
1294 rrr = 7; | |
1295 | |
1296 ccl_set_expr: | |
1297 switch (op) | |
1298 { | |
1299 case CCL_PLUS: reg[rrr] = i + j; break; | |
1300 case CCL_MINUS: reg[rrr] = i - j; break; | |
1301 case CCL_MUL: reg[rrr] = i * j; break; | |
1302 case CCL_DIV: reg[rrr] = i / j; break; | |
1303 case CCL_MOD: reg[rrr] = i % j; break; | |
1304 case CCL_AND: reg[rrr] = i & j; break; | |
1305 case CCL_OR: reg[rrr] = i | j; break; | |
444 | 1306 case CCL_XOR: reg[rrr] = i ^ j;; break; |
428 | 1307 case CCL_LSH: reg[rrr] = i << j; break; |
1308 case CCL_RSH: reg[rrr] = i >> j; break; | |
1309 case CCL_LSH8: reg[rrr] = (i << 8) | j; break; | |
1310 case CCL_RSH8: reg[rrr] = i >> 8; reg[7] = i & 0xFF; break; | |
1311 case CCL_DIVMOD: reg[rrr] = i / j; reg[7] = i % j; break; | |
1312 case CCL_LS: reg[rrr] = i < j; break; | |
1313 case CCL_GT: reg[rrr] = i > j; break; | |
1314 case CCL_EQ: reg[rrr] = i == j; break; | |
1315 case CCL_LE: reg[rrr] = i <= j; break; | |
1316 case CCL_GE: reg[rrr] = i >= j; break; | |
1317 case CCL_NE: reg[rrr] = i != j; break; | |
444 | 1318 case CCL_DECODE_SJIS: |
771 | 1319 /* DECODE_SHIFT_JIS set MSB for internal format |
444 | 1320 as opposed to Emacs. */ |
771 | 1321 DECODE_SHIFT_JIS (i, j, reg[rrr], reg[7]); |
444 | 1322 reg[rrr] &= 0x7F; |
1323 reg[7] &= 0x7F; | |
1324 break; | |
1325 case CCL_ENCODE_SJIS: | |
771 | 1326 /* ENCODE_SHIFT_JIS assumes MSB of SHIFT-JIS-char is set |
444 | 1327 as opposed to Emacs. */ |
771 | 1328 ENCODE_SHIFT_JIS (i | 0x80, j | 0x80, reg[rrr], reg[7]); |
444 | 1329 break; |
1330 default: CCL_INVALID_CMD; | |
428 | 1331 } |
1332 code &= 0x1F; | |
1333 if (code == CCL_WriteExprConst || code == CCL_WriteExprRegister) | |
1334 { | |
1335 i = reg[rrr]; | |
1336 CCL_WRITE_CHAR (i); | |
444 | 1337 ic = jump_address; |
428 | 1338 } |
1339 else if (!reg[rrr]) | |
1340 ic = jump_address; | |
1341 break; | |
1342 | |
456 | 1343 case CCL_Extension: |
428 | 1344 switch (EXCMD) |
1345 { | |
1346 case CCL_ReadMultibyteChar2: | |
1347 if (!src) | |
1348 CCL_INVALID_CMD; | |
1349 | |
462 | 1350 if (src >= src_end) |
1351 { | |
1352 src++; | |
456 | 1353 goto ccl_read_multibyte_character_suspend; |
462 | 1354 } |
1355 | |
1356 i = *src++; | |
1357 if (i < 0x80) | |
1358 { | |
1359 /* ASCII */ | |
1360 reg[rrr] = i; | |
1361 reg[RRR] = LEADING_BYTE_ASCII; | |
1362 } | |
2829 | 1363 /* Previously, these next two elses were reversed in order, |
1364 which should have worked fine, but is more fragile than | |
1365 this order. */ | |
1366 else if (LEADING_BYTE_CONTROL_1 == i) | |
1367 { | |
1368 if (src >= src_end) | |
1369 goto ccl_read_multibyte_character_suspend; | |
1370 reg[RRR] = i; | |
1371 reg[rrr] = (*src++ - 0xA0); | |
1372 } | |
462 | 1373 else if (i <= MAX_LEADING_BYTE_OFFICIAL_1) |
1374 { | |
1375 if (src >= src_end) | |
1376 goto ccl_read_multibyte_character_suspend; | |
1377 reg[RRR] = i; | |
1378 reg[rrr] = (*src++ & 0x7F); | |
1379 } | |
1380 else if (i <= MAX_LEADING_BYTE_OFFICIAL_2) | |
1381 { | |
1382 if ((src + 1) >= src_end) | |
1383 goto ccl_read_multibyte_character_suspend; | |
1384 reg[RRR] = i; | |
1385 i = (*src++ & 0x7F); | |
1386 reg[rrr] = ((i << 7) | (*src & 0x7F)); | |
1387 src++; | |
1388 } | |
1389 else if (i == PRE_LEADING_BYTE_PRIVATE_1) | |
1390 { | |
1391 if ((src + 1) >= src_end) | |
1392 goto ccl_read_multibyte_character_suspend; | |
1393 reg[RRR] = *src++; | |
4072 | 1394 reg[rrr] = (*src++ & 0xFF); |
462 | 1395 } |
1396 else if (i == PRE_LEADING_BYTE_PRIVATE_2) | |
1397 { | |
1398 if ((src + 2) >= src_end) | |
1399 goto ccl_read_multibyte_character_suspend; | |
1400 reg[RRR] = *src++; | |
1401 i = (*src++ & 0x7F); | |
1402 reg[rrr] = ((i << 7) | (*src & 0x7F)); | |
1403 src++; | |
1404 } | |
1405 else | |
1406 { | |
1407 /* INVALID CODE. Return a single byte character. */ | |
1408 reg[RRR] = LEADING_BYTE_ASCII; | |
1409 reg[rrr] = i; | |
1410 } | |
428 | 1411 break; |
1412 | |
1413 ccl_read_multibyte_character_suspend: | |
4193 | 1414 if (src <= src_end && ccl->last_block) |
1415 { | |
1416 /* #### Unclear when this happens. GNU use | |
1417 CHARSET_8_BIT_CONTROL here, which we can't. */ | |
1418 if (i < 0x80) | |
1419 { | |
1420 reg[RRR] = LEADING_BYTE_ASCII; | |
1421 reg[rrr] = i; | |
1422 } | |
1423 else if (i < 0xA0) | |
1424 { | |
1425 reg[RRR] = LEADING_BYTE_CONTROL_1; | |
1426 reg[rrr] = i - 0xA0; | |
1427 } | |
1428 else | |
1429 { | |
1430 reg[RRR] = LEADING_BYTE_LATIN_ISO8859_1; | |
1431 reg[rrr] = i & 0x7F; | |
1432 } | |
1433 break; | |
1434 } | |
428 | 1435 src--; |
1436 if (ccl->last_block) | |
1437 { | |
4193 | 1438 ic = eof_ic; |
1439 eof_hit = 1; | |
428 | 1440 goto ccl_repeat; |
1441 } | |
1442 else | |
1443 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC); | |
1444 | |
1445 break; | |
1446 | |
1447 case CCL_WriteMultibyteChar2: | |
1448 i = reg[RRR]; /* charset */ | |
2829 | 1449 if (i == LEADING_BYTE_ASCII) |
428 | 1450 i = reg[rrr] & 0xFF; |
2829 | 1451 else if (LEADING_BYTE_CONTROL_1 == i) |
3690 | 1452 i = ((reg[rrr] & 0x1F) + 0x80); |
2829 | 1453 else if (POSSIBLE_LEADING_BYTE_P(i) && |
2830 | 1454 !NILP(charset_by_leading_byte(i))) |
2829 | 1455 { |
1456 if (XCHARSET_DIMENSION (charset_by_leading_byte (i)) == 1) | |
1457 i = (((i - FIELD2_TO_OFFICIAL_LEADING_BYTE) << 7) | |
1458 | (reg[rrr] & 0x7F)); | |
4525
d64f1060cd65
Fix off-by-one error in ccl_driver. <87iqr7v7p0.fsf@uwakimon.sk.tsukuba.ac.jp>
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4295
diff
changeset
|
1459 else if (i <= MAX_LEADING_BYTE_OFFICIAL_2) |
2829 | 1460 i = ((i - FIELD1_TO_OFFICIAL_LEADING_BYTE) << 14) |
1461 | reg[rrr]; | |
1462 else | |
1463 i = ((i - FIELD1_TO_PRIVATE_LEADING_BYTE) << 14) | reg[rrr]; | |
1464 } | |
1465 else | |
1466 { | |
1467 /* No charset we know about; use U+3012 GETA MARK */ | |
1468 i = make_ichar | |
1469 (charset_by_leading_byte(LEADING_BYTE_JAPANESE_JISX0208), | |
1470 34, 46); | |
1471 } | |
428 | 1472 |
1473 CCL_WRITE_CHAR (i); | |
1474 | |
1475 break; | |
1476 | |
444 | 1477 case CCL_TranslateCharacter: |
428 | 1478 #if 0 |
3439 | 1479 /* XEmacs does not have translate_char, nor an |
1480 equivalent. We do nothing on this operation. */ | |
1481 CCL_MAKE_CHAR(reg[RRR], reg[rrr], op); | |
428 | 1482 op = translate_char (GET_TRANSLATION_TABLE (reg[Rrr]), |
1483 i, -1, 0, 0); | |
1484 SPLIT_CHAR (op, reg[RRR], i, j); | |
1485 if (j != -1) | |
1486 i = (i << 7) | j; | |
442 | 1487 |
428 | 1488 reg[rrr] = i; |
444 | 1489 #endif |
428 | 1490 break; |
1491 | |
1492 case CCL_TranslateCharacterConstTbl: | |
444 | 1493 #if 0 |
771 | 1494 /* XEmacs does not have translate_char or an equivalent. We |
1495 do nothing on this operation. */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1496 op = XCHAR_OR_FIXNUM (ccl_prog[ic]); /* table */ |
428 | 1497 ic++; |
444 | 1498 CCL_MAKE_CHAR (reg[RRR], reg[rrr], i); |
428 | 1499 op = translate_char (GET_TRANSLATION_TABLE (op), i, -1, 0, 0); |
1500 SPLIT_CHAR (op, reg[RRR], i, j); | |
1501 if (j != -1) | |
1502 i = (i << 7) | j; | |
442 | 1503 |
428 | 1504 reg[rrr] = i; |
444 | 1505 #endif |
428 | 1506 break; |
1507 | |
3439 | 1508 case CCL_MuleToUnicode: |
1509 { | |
1510 Lisp_Object ucs; | |
1511 | |
4072 | 1512 CCL_MAKE_CHAR (reg[rrr], reg[RRR], op); |
1513 | |
3439 | 1514 ucs = Fchar_to_unicode(make_char(op)); |
1515 | |
1516 if (NILP(ucs)) | |
1517 { | |
1518 /* Uhh, char-to-unicode doesn't return nil at the | |
1519 moment, only ever -1. */ | |
1520 reg[rrr] = 0xFFFD; /* REPLACEMENT CHARACTER */ | |
1521 } | |
1522 else | |
1523 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1524 reg[rrr] = XCHAR_OR_FIXNUM(ucs); |
3439 | 1525 if (-1 == reg[rrr]) |
1526 { | |
1527 reg[rrr] = 0xFFFD; /* REPLACEMENT CHARACTER */ | |
1528 } | |
1529 } | |
1530 break; | |
1531 } | |
1532 | |
1533 case CCL_UnicodeToMule: | |
1534 { | |
1535 Lisp_Object scratch; | |
1536 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1537 scratch = Funicode_to_char(make_fixnum(reg[rrr]), Qnil); |
3439 | 1538 |
1539 if (!NILP(scratch)) | |
1540 { | |
1541 op = XCHAR(scratch); | |
1542 BREAKUP_ICHAR (op, scratch, i, j); | |
1543 reg[RRR] = XCHARSET_ID(scratch); | |
1544 | |
1545 if (j != 0) | |
1546 { | |
4072 | 1547 i = (i << 7) | j; |
3439 | 1548 } |
1549 | |
1550 reg[rrr] = i; | |
1551 } | |
1552 else | |
1553 { | |
1554 reg[rrr] = reg[RRR] = 0; | |
1555 } | |
1556 break; | |
1557 } | |
1558 | |
4072 | 1559 case CCL_LookupIntConstTbl: |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1560 op = XCHAR_OR_FIXNUM (ccl_prog[ic]); /* table */ |
4072 | 1561 ic++; |
1562 { | |
1563 struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1564 htentry *e = find_htentry(make_fixnum (reg[RRR]), h); |
4072 | 1565 Lisp_Object scratch; |
1566 | |
1567 if (!HTENTRY_CLEAR_P(e)) | |
1568 { | |
1569 op = XCHARVAL (e->value); | |
1570 if (!valid_ichar_p(op)) | |
1571 { | |
1572 CCL_INVALID_CMD; | |
1573 } | |
1574 | |
1575 BREAKUP_ICHAR (op, scratch, i, j); | |
1576 reg[RRR] = XCHARSET_ID(scratch); | |
1577 | |
1578 if (j != 0) | |
1579 { | |
1580 i = (i << 7) | j; | |
1581 } | |
1582 reg[rrr] = i; | |
1583 reg[7] = 1; /* r7 true for success */ | |
1584 } | |
1585 else | |
1586 reg[7] = 0; | |
1587 } | |
1588 break; | |
1589 | |
1590 case CCL_LookupCharConstTbl: | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1591 op = XCHAR_OR_FIXNUM (ccl_prog[ic]); /* table */ |
4072 | 1592 ic++; |
1593 CCL_MAKE_CHAR (reg[RRR], reg[rrr], i); | |
1594 { | |
1595 struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1596 htentry *e = find_htentry(make_fixnum(i), h); |
4072 | 1597 |
1598 if (!HTENTRY_CLEAR_P(e)) | |
1599 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1600 if (!FIXNUMP (e->value)) |
4072 | 1601 CCL_INVALID_CMD; |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1602 reg[RRR] = XCHAR_OR_FIXNUM (e->value); |
4072 | 1603 reg[7] = 1; /* r7 true for success */ |
1604 } | |
1605 else | |
1606 reg[7] = 0; | |
1607 } | |
1608 break; | |
1609 | |
1610 | |
428 | 1611 case CCL_IterateMultipleMap: |
1612 { | |
1613 Lisp_Object map, content, attrib, value; | |
1614 int point, size, fin_ic; | |
1615 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1616 j = XCHAR_OR_FIXNUM (ccl_prog[ic++]); /* number of maps. */ |
428 | 1617 fin_ic = ic + j; |
1618 op = reg[rrr]; | |
1619 if ((j > reg[RRR]) && (j >= 0)) | |
1620 { | |
1621 ic += reg[RRR]; | |
1622 i = reg[RRR]; | |
1623 } | |
1624 else | |
1625 { | |
1626 reg[RRR] = -1; | |
1627 ic = fin_ic; | |
1628 break; | |
1629 } | |
1630 | |
1631 for (;i < j;i++) | |
1632 { | |
1633 size = XVECTOR (Vcode_conversion_map_vector)->size; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1634 point = XCHAR_OR_FIXNUM (ccl_prog[ic++]); |
428 | 1635 if (point >= size) continue; |
1636 map = | |
1637 XVECTOR (Vcode_conversion_map_vector)->contents[point]; | |
1638 | |
444 | 1639 /* Check map validity. */ |
428 | 1640 if (!CONSP (map)) continue; |
444 | 1641 map = XCDR (map); |
428 | 1642 if (!VECTORP (map)) continue; |
1643 size = XVECTOR (map)->size; | |
1644 if (size <= 1) continue; | |
1645 | |
1646 content = XVECTOR (map)->contents[0]; | |
1647 | |
1648 /* check map type, | |
1649 [STARTPOINT VAL1 VAL2 ...] or | |
444 | 1650 [t ELEMENT STARTPOINT ENDPOINT] */ |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1651 if (FIXNUMP (content)) |
428 | 1652 { |
1653 point = XUINT (content); | |
1654 point = op - point + 1; | |
1655 if (!((point >= 1) && (point < size))) continue; | |
1656 content = XVECTOR (map)->contents[point]; | |
1657 } | |
1658 else if (EQ (content, Qt)) | |
1659 { | |
1660 if (size != 4) continue; | |
647 | 1661 /* #### see comment at CCL_SetArray; in this |
1662 case the casts are added but the XUINT was | |
1663 already present */ | |
1664 if (((unsigned int) op >= | |
1665 XUINT (XVECTOR (map)->contents[2])) | |
1666 && ((unsigned int) op < | |
1667 XUINT (XVECTOR (map)->contents[3]))) | |
428 | 1668 content = XVECTOR (map)->contents[1]; |
1669 else | |
1670 continue; | |
1671 } | |
442 | 1672 else |
428 | 1673 continue; |
1674 | |
1675 if (NILP (content)) | |
1676 continue; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1677 else if (FIXNUMP (content)) |
428 | 1678 { |
1679 reg[RRR] = i; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1680 reg[rrr] = XCHAR_OR_FIXNUM(content); |
428 | 1681 break; |
1682 } | |
1683 else if (EQ (content, Qt) || EQ (content, Qlambda)) | |
1684 { | |
1685 reg[RRR] = i; | |
1686 break; | |
1687 } | |
1688 else if (CONSP (content)) | |
1689 { | |
444 | 1690 attrib = XCAR (content); |
1691 value = XCDR (content); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1692 if (!FIXNUMP (attrib) || !FIXNUMP (value)) |
428 | 1693 continue; |
1694 reg[RRR] = i; | |
1695 reg[rrr] = XUINT (value); | |
1696 break; | |
1697 } | |
444 | 1698 else if (SYMBOLP (content)) |
1699 CCL_CALL_FOR_MAP_INSTRUCTION (content, fin_ic); | |
1700 else | |
1701 CCL_INVALID_CMD; | |
428 | 1702 } |
1703 if (i == j) | |
1704 reg[RRR] = -1; | |
1705 ic = fin_ic; | |
1706 } | |
1707 break; | |
442 | 1708 |
428 | 1709 case CCL_MapMultiple: |
1710 { | |
1711 Lisp_Object map, content, attrib, value; | |
1712 int point, size, map_vector_size; | |
1713 int map_set_rest_length, fin_ic; | |
444 | 1714 int current_ic = this_ic; |
1715 | |
1716 /* inhibit recursive call on MapMultiple. */ | |
1717 if (stack_idx_of_map_multiple > 0) | |
1718 { | |
1719 if (stack_idx_of_map_multiple <= stack_idx) | |
1720 { | |
1721 stack_idx_of_map_multiple = 0; | |
1722 mapping_stack_pointer = mapping_stack; | |
1723 CCL_INVALID_CMD; | |
1724 } | |
1725 } | |
1726 else | |
1727 mapping_stack_pointer = mapping_stack; | |
1728 stack_idx_of_map_multiple = 0; | |
428 | 1729 |
1730 map_set_rest_length = | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1731 XCHAR_OR_FIXNUM (ccl_prog[ic++]); /* number of maps and separators. */ |
428 | 1732 fin_ic = ic + map_set_rest_length; |
444 | 1733 op = reg[rrr]; |
1734 | |
428 | 1735 if ((map_set_rest_length > reg[RRR]) && (reg[RRR] >= 0)) |
1736 { | |
1737 ic += reg[RRR]; | |
1738 i = reg[RRR]; | |
1739 map_set_rest_length -= i; | |
1740 } | |
1741 else | |
1742 { | |
1743 ic = fin_ic; | |
1744 reg[RRR] = -1; | |
444 | 1745 mapping_stack_pointer = mapping_stack; |
428 | 1746 break; |
1747 } | |
444 | 1748 |
1749 if (mapping_stack_pointer <= (mapping_stack + 1)) | |
428 | 1750 { |
444 | 1751 /* Set up initial state. */ |
1752 mapping_stack_pointer = mapping_stack; | |
1753 PUSH_MAPPING_STACK (0, op); | |
1754 reg[RRR] = -1; | |
1755 } | |
1756 else | |
1757 { | |
1758 /* Recover after calling other ccl program. */ | |
1759 int orig_op; | |
428 | 1760 |
444 | 1761 POP_MAPPING_STACK (map_set_rest_length, orig_op); |
1762 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); | |
1763 switch (op) | |
428 | 1764 { |
444 | 1765 case -1: |
1766 /* Regard it as Qnil. */ | |
1767 op = orig_op; | |
1768 i++; | |
1769 ic++; | |
1770 map_set_rest_length--; | |
1771 break; | |
1772 case -2: | |
1773 /* Regard it as Qt. */ | |
1774 op = reg[rrr]; | |
1775 i++; | |
1776 ic++; | |
1777 map_set_rest_length--; | |
1778 break; | |
1779 case -3: | |
1780 /* Regard it as Qlambda. */ | |
1781 op = orig_op; | |
428 | 1782 i += map_set_rest_length; |
444 | 1783 ic += map_set_rest_length; |
1784 map_set_rest_length = 0; | |
1785 break; | |
1786 default: | |
1787 /* Regard it as normal mapping. */ | |
428 | 1788 i += map_set_rest_length; |
444 | 1789 ic += map_set_rest_length; |
428 | 1790 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); |
1791 break; | |
1792 } | |
1793 } | |
444 | 1794 map_vector_size = XVECTOR (Vcode_conversion_map_vector)->size; |
1795 | |
1796 do { | |
1797 for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--) | |
1798 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1799 point = XCHAR_OR_FIXNUM(ccl_prog[ic]); |
444 | 1800 if (point < 0) |
1801 { | |
1802 /* +1 is for including separator. */ | |
1803 point = -point + 1; | |
1804 if (mapping_stack_pointer | |
460 | 1805 >= mapping_stack + countof (mapping_stack)) |
444 | 1806 CCL_INVALID_CMD; |
1807 PUSH_MAPPING_STACK (map_set_rest_length - point, | |
1808 reg[rrr]); | |
1809 map_set_rest_length = point; | |
1810 reg[rrr] = op; | |
1811 continue; | |
1812 } | |
1813 | |
1814 if (point >= map_vector_size) continue; | |
1815 map = (XVECTOR (Vcode_conversion_map_vector) | |
1816 ->contents[point]); | |
1817 | |
1818 /* Check map validity. */ | |
1819 if (!CONSP (map)) continue; | |
1820 map = XCDR (map); | |
1821 if (!VECTORP (map)) continue; | |
1822 size = XVECTOR (map)->size; | |
1823 if (size <= 1) continue; | |
1824 | |
1825 content = XVECTOR (map)->contents[0]; | |
1826 | |
1827 /* check map type, | |
1828 [STARTPOINT VAL1 VAL2 ...] or | |
1829 [t ELEMENT STARTPOINT ENDPOINT] */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1830 if (FIXNUMP (content)) |
444 | 1831 { |
1832 point = XUINT (content); | |
1833 point = op - point + 1; | |
1834 if (!((point >= 1) && (point < size))) continue; | |
1835 content = XVECTOR (map)->contents[point]; | |
1836 } | |
1837 else if (EQ (content, Qt)) | |
1838 { | |
1839 if (size != 4) continue; | |
647 | 1840 /* #### see comment at CCL_SetArray; in this |
1841 case the casts are added but the XUINT was | |
1842 already present */ | |
1843 if (((unsigned int) op >= | |
1844 XUINT (XVECTOR (map)->contents[2])) && | |
1845 ((unsigned int) op < | |
1846 XUINT (XVECTOR (map)->contents[3]))) | |
444 | 1847 content = XVECTOR (map)->contents[1]; |
1848 else | |
1849 continue; | |
1850 } | |
1851 else | |
1852 continue; | |
1853 | |
1854 if (NILP (content)) | |
1855 continue; | |
1856 | |
1857 reg[RRR] = i; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1858 if (FIXNUMP (content)) |
444 | 1859 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1860 op = XCHAR_OR_FIXNUM (content); |
444 | 1861 i += map_set_rest_length - 1; |
1862 ic += map_set_rest_length - 1; | |
1863 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); | |
1864 map_set_rest_length++; | |
1865 } | |
1866 else if (CONSP (content)) | |
1867 { | |
1868 attrib = XCAR (content); | |
1869 value = XCDR (content); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1870 if (!FIXNUMP (attrib) || !FIXNUMP (value)) |
444 | 1871 continue; |
1872 op = XUINT (value); | |
1873 i += map_set_rest_length - 1; | |
1874 ic += map_set_rest_length - 1; | |
1875 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); | |
1876 map_set_rest_length++; | |
1877 } | |
1878 else if (EQ (content, Qt)) | |
1879 { | |
1880 op = reg[rrr]; | |
1881 } | |
1882 else if (EQ (content, Qlambda)) | |
1883 { | |
1884 i += map_set_rest_length; | |
1885 ic += map_set_rest_length; | |
1886 break; | |
1887 } | |
1888 else if (SYMBOLP (content)) | |
1889 { | |
1890 if (mapping_stack_pointer | |
460 | 1891 >= mapping_stack + countof (mapping_stack)) |
444 | 1892 CCL_INVALID_CMD; |
1893 PUSH_MAPPING_STACK (map_set_rest_length, reg[rrr]); | |
1894 PUSH_MAPPING_STACK (map_set_rest_length, op); | |
1895 stack_idx_of_map_multiple = stack_idx + 1; | |
1896 CCL_CALL_FOR_MAP_INSTRUCTION (content, current_ic); | |
1897 } | |
1898 else | |
1899 CCL_INVALID_CMD; | |
1900 } | |
1901 if (mapping_stack_pointer <= (mapping_stack + 1)) | |
1902 break; | |
1903 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); | |
1904 i += map_set_rest_length; | |
1905 ic += map_set_rest_length; | |
1906 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); | |
1907 } while (1); | |
1908 | |
428 | 1909 ic = fin_ic; |
1910 } | |
1911 reg[rrr] = op; | |
1912 break; | |
1913 | |
1914 case CCL_MapSingle: | |
1915 { | |
1916 Lisp_Object map, attrib, value, content; | |
1917 int size, point; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1918 j = XCHAR_OR_FIXNUM (ccl_prog[ic++]); /* map_id */ |
428 | 1919 op = reg[rrr]; |
1920 if (j >= XVECTOR (Vcode_conversion_map_vector)->size) | |
1921 { | |
1922 reg[RRR] = -1; | |
1923 break; | |
1924 } | |
1925 map = XVECTOR (Vcode_conversion_map_vector)->contents[j]; | |
1926 if (!CONSP (map)) | |
1927 { | |
1928 reg[RRR] = -1; | |
1929 break; | |
1930 } | |
444 | 1931 map = XCDR (map); |
428 | 1932 if (!VECTORP (map)) |
1933 { | |
1934 reg[RRR] = -1; | |
1935 break; | |
1936 } | |
1937 size = XVECTOR (map)->size; | |
1938 point = XUINT (XVECTOR (map)->contents[0]); | |
1939 point = op - point + 1; | |
1940 reg[RRR] = 0; | |
1941 if ((size <= 1) || | |
1942 (!((point >= 1) && (point < size)))) | |
1943 reg[RRR] = -1; | |
1944 else | |
1945 { | |
444 | 1946 reg[RRR] = 0; |
428 | 1947 content = XVECTOR (map)->contents[point]; |
1948 if (NILP (content)) | |
1949 reg[RRR] = -1; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1950 else if (FIXNUMP (content)) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1951 reg[rrr] = XCHAR_OR_FIXNUM (content); |
444 | 1952 else if (EQ (content, Qt)); |
428 | 1953 else if (CONSP (content)) |
1954 { | |
444 | 1955 attrib = XCAR (content); |
1956 value = XCDR (content); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1957 if (!FIXNUMP (attrib) || !FIXNUMP (value)) |
428 | 1958 continue; |
1959 reg[rrr] = XUINT(value); | |
1960 break; | |
1961 } | |
444 | 1962 else if (SYMBOLP (content)) |
1963 CCL_CALL_FOR_MAP_INSTRUCTION (content, ic); | |
428 | 1964 else |
1965 reg[RRR] = -1; | |
1966 } | |
1967 } | |
1968 break; | |
442 | 1969 |
428 | 1970 default: |
1971 CCL_INVALID_CMD; | |
1972 } | |
1973 break; | |
1974 | |
1975 default: | |
444 | 1976 CCL_INVALID_CMD; |
428 | 1977 } |
1978 } | |
1979 | |
1980 ccl_error_handler: | |
1981 if (destination) | |
1982 { | |
1983 /* We can insert an error message only if DESTINATION is | |
1984 specified and we still have a room to store the message | |
1985 there. */ | |
1986 char msg[256]; | |
1987 | |
1988 switch (ccl->status) | |
1989 { | |
1990 case CCL_STAT_INVALID_CMD: | |
1991 sprintf(msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", | |
1992 code & 0x1F, code, this_ic); | |
1993 #ifdef CCL_DEBUG | |
1994 { | |
1995 int i = ccl_backtrace_idx - 1; | |
1996 int j; | |
1997 | |
1998 Dynarr_add_many (destination, (unsigned char *) msg, strlen (msg)); | |
1999 | |
2000 for (j = 0; j < CCL_DEBUG_BACKTRACE_LEN; j++, i--) | |
2001 { | |
2002 if (i < 0) i = CCL_DEBUG_BACKTRACE_LEN - 1; | |
2003 if (ccl_backtrace_table[i] == 0) | |
2004 break; | |
2005 sprintf(msg, " %d", ccl_backtrace_table[i]); | |
2006 Dynarr_add_many (destination, (unsigned char *) msg, strlen (msg)); | |
2007 } | |
2008 goto ccl_finish; | |
2009 } | |
2010 #endif | |
2011 break; | |
2012 | |
2013 case CCL_STAT_QUIT: | |
444 | 2014 sprintf(msg, "\nCCL: Exited."); |
428 | 2015 break; |
2016 | |
2017 default: | |
2018 sprintf(msg, "\nCCL: Unknown error type (%d).", ccl->status); | |
2019 } | |
2020 | |
2021 Dynarr_add_many (destination, (unsigned char *) msg, strlen (msg)); | |
2022 } | |
2023 | |
2024 ccl_finish: | |
2025 ccl->ic = ic; | |
2026 ccl->stack_idx = stack_idx; | |
2027 ccl->prog = ccl_prog; | |
2028 if (consumed) *consumed = src - source; | |
444 | 2029 if (!destination) |
428 | 2030 return 0; |
444 | 2031 return Dynarr_length (destination); |
2032 } | |
2033 | |
2034 /* Resolve symbols in the specified CCL code (Lisp vector). This | |
2035 function converts symbols of code conversion maps and character | |
2036 translation tables embedded in the CCL code into their ID numbers. | |
2037 | |
2038 The return value is a vector (CCL itself or a new vector in which | |
2039 all symbols are resolved), Qt if resolving of some symbol failed, | |
2040 or nil if CCL contains invalid data. */ | |
2041 | |
2042 static Lisp_Object | |
2043 resolve_symbol_ccl_program (Lisp_Object ccl) | |
2044 { | |
2045 int i, veclen, unresolved = 0; | |
2046 Lisp_Object result, contents, val; | |
2047 | |
2048 result = ccl; | |
2049 veclen = XVECTOR (result)->size; | |
2050 | |
2051 for (i = 0; i < veclen; i++) | |
2052 { | |
2053 contents = XVECTOR (result)->contents[i]; | |
4072 | 2054 /* XEmacs change; accept characters as well as integers, on the basis |
2055 that most CCL code written doesn't make a distinction. */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2056 if (FIXNUMP (contents) || CHARP(contents)) |
444 | 2057 continue; |
2058 else if (CONSP (contents) | |
2059 && SYMBOLP (XCAR (contents)) | |
2060 && SYMBOLP (XCDR (contents))) | |
2061 { | |
2062 /* This is the new style for embedding symbols. The form is | |
2063 (SYMBOL . PROPERTY). (get SYMBOL PROPERTY) should give | |
2064 an index number. */ | |
2065 | |
2066 if (EQ (result, ccl)) | |
2067 result = Fcopy_sequence (ccl); | |
2068 | |
2069 val = Fget (XCAR (contents), XCDR (contents), Qnil); | |
2070 if (NATNUMP (val)) | |
2071 XVECTOR (result)->contents[i] = val; | |
2072 else | |
2073 unresolved = 1; | |
2074 continue; | |
2075 } | |
2076 else if (SYMBOLP (contents)) | |
2077 { | |
2078 /* This is the old style for embedding symbols. This style | |
2079 may lead to a bug if, for instance, a translation table | |
2080 and a code conversion map have the same name. */ | |
2081 if (EQ (result, ccl)) | |
2082 result = Fcopy_sequence (ccl); | |
2083 | |
2084 val = Fget (contents, Qcode_conversion_map_id, Qnil); | |
2085 if (NATNUMP (val)) | |
2086 XVECTOR (result)->contents[i] = val; | |
2087 else | |
2088 { | |
2089 val = Fget (contents, Qccl_program_idx, Qnil); | |
2090 if (NATNUMP (val)) | |
2091 XVECTOR (result)->contents[i] = val; | |
2092 else | |
2093 unresolved = 1; | |
2094 } | |
2095 continue; | |
2096 } | |
2097 return Qnil; | |
2098 } | |
2099 | |
2100 return (unresolved ? Qt : result); | |
2101 } | |
2102 | |
2103 /* Return the compiled code (vector) of CCL program CCL_PROG. | |
2104 CCL_PROG is a name (symbol) of the program or already compiled | |
2105 code. If necessary, resolve symbols in the compiled code to index | |
2106 numbers. If we failed to get the compiled code or to resolve | |
2107 symbols, return Qnil. */ | |
2108 | |
2109 static Lisp_Object | |
2110 ccl_get_compiled_code (Lisp_Object ccl_prog) | |
2111 { | |
2112 Lisp_Object val, slot; | |
2113 | |
2114 if (VECTORP (ccl_prog)) | |
2115 { | |
2116 val = resolve_symbol_ccl_program (ccl_prog); | |
2117 return (VECTORP (val) ? val : Qnil); | |
2118 } | |
2119 if (!SYMBOLP (ccl_prog)) | |
2120 return Qnil; | |
2121 | |
2122 val = Fget (ccl_prog, Qccl_program_idx, Qnil); | |
2123 if (! NATNUMP (val) | |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5183
diff
changeset
|
2124 || -1 != bytecode_arithcompare (val, Flength (Vccl_program_table))) |
444 | 2125 return Qnil; |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2126 slot = XVECTOR_DATA (Vccl_program_table)[XFIXNUM (val)]; |
444 | 2127 if (! VECTORP (slot) |
2128 || XVECTOR (slot)->size != 3 | |
2129 || ! VECTORP (XVECTOR_DATA (slot)[1])) | |
2130 return Qnil; | |
2131 if (NILP (XVECTOR_DATA (slot)[2])) | |
2132 { | |
2133 val = resolve_symbol_ccl_program (XVECTOR_DATA (slot)[1]); | |
2134 if (! VECTORP (val)) | |
2135 return Qnil; | |
2136 XVECTOR_DATA (slot)[1] = val; | |
2137 XVECTOR_DATA (slot)[2] = Qt; | |
2138 } | |
2139 return XVECTOR_DATA (slot)[1]; | |
428 | 2140 } |
2141 | |
2142 /* Setup fields of the structure pointed by CCL appropriately for the | |
444 | 2143 execution of CCL program CCL_PROG. CCL_PROG is the name (symbol) |
2144 of the CCL program or the already compiled code (vector). | |
2145 Return 0 if we succeed this setup, else return -1. | |
2146 | |
2147 If CCL_PROG is nil, we just reset the structure pointed by CCL. */ | |
2148 int | |
2149 setup_ccl_program (struct ccl_program *ccl, Lisp_Object ccl_prog) | |
428 | 2150 { |
771 | 2151 xzero (*ccl); /* XEmacs change */ |
444 | 2152 if (! NILP (ccl_prog)) |
428 | 2153 { |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2154 Lisp_Object new_prog = ccl_get_compiled_code (ccl_prog); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2155 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2156 if (VECTORP (ccl_prog)) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2157 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2158 /* Make sure we're not allocating unreachable memory in this |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2159 function: */ |
4748
27b09b4219b1
Fix the union build, setup_ccl_program; thank you Robert Delius Royar.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4745
diff
changeset
|
2160 assert (EQ (ccl_prog, new_prog)); |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2161 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2162 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2163 ccl_prog = new_prog; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2164 |
444 | 2165 if (! VECTORP (ccl_prog)) |
2166 return -1; | |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2167 |
444 | 2168 ccl->size = XVECTOR_LENGTH (ccl_prog); |
2169 ccl->prog = XVECTOR_DATA (ccl_prog); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2170 ccl->eof_ic = XFIXNUM (XVECTOR_DATA (ccl_prog)[CCL_HEADER_EOF]); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2171 ccl->buf_magnification = XFIXNUM (XVECTOR_DATA (ccl_prog)[CCL_HEADER_BUF_MAG]); |
428 | 2172 } |
2173 ccl->ic = CCL_HEADER_MAIN; | |
444 | 2174 ccl->eol_type = CCL_CODING_EOL_LF; |
2175 return 0; | |
428 | 2176 } |
2177 | |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2178 static Lisp_Object |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2179 find_ccl_program (Lisp_Object object, int *unresolved_symbols) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2180 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2181 struct ccl_program test_ccl; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2182 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2183 if (NULL != unresolved_symbols) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2184 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2185 *unresolved_symbols = 0; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2186 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2187 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2188 if (VECTORP (object)) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2189 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2190 object = resolve_symbol_ccl_program (object); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2191 if (EQ (Qt, object)) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2192 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2193 if (NULL != unresolved_symbols) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2194 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2195 *unresolved_symbols = 1; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2196 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2197 return Qnil; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2198 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2199 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2200 else if (!SYMBOLP (object)) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2201 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2202 return Qnil; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2203 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2204 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2205 if (setup_ccl_program (&test_ccl, object) < 0) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2206 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2207 return Qnil; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2208 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2209 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2210 return object; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2211 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2212 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2213 Lisp_Object |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2214 get_ccl_program (Lisp_Object object) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2215 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2216 int unresolved_symbols = 0; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2217 Lisp_Object val = find_ccl_program (object, &unresolved_symbols); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2218 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2219 if (unresolved_symbols) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2220 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2221 invalid_argument ("Unresolved symbol(s) in CCL program", object); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2222 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2223 else if (NILP (val)) |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2224 { |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2225 invalid_argument ("Invalid CCL program", object); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2226 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2227 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2228 return val; |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2229 } |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2230 |
444 | 2231 #ifdef emacs |
428 | 2232 |
444 | 2233 DEFUN ("ccl-program-p", Fccl_program_p, 1, 1, 0, /* |
2234 Return t if OBJECT is a CCL program name or a compiled CCL program code. | |
2235 See the documentation of `define-ccl-program' for the detail of CCL program. | |
2236 */ | |
2237 (object)) | |
2238 { | |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2239 return NILP (find_ccl_program (object, NULL)) ? Qnil : Qt; |
428 | 2240 } |
2241 | |
2242 DEFUN ("ccl-execute", Fccl_execute, 2, 2, 0, /* | |
2243 Execute CCL-PROGRAM with registers initialized by REGISTERS. | |
2244 | |
444 | 2245 CCL-PROGRAM is a CCL program name (symbol) |
428 | 2246 or a compiled code generated by `ccl-compile' (for backward compatibility, |
444 | 2247 in this case, the overhead of the execution is bigger than the former case). |
428 | 2248 No I/O commands should appear in CCL-PROGRAM. |
2249 | |
2250 REGISTERS is a vector of [R0 R1 ... R7] where RN is an initial value | |
2251 of Nth register. | |
2252 | |
444 | 2253 As side effect, each element of REGISTERS holds the value of |
428 | 2254 corresponding register after the execution. |
444 | 2255 |
2256 See the documentation of `define-ccl-program' for the detail of CCL program. | |
428 | 2257 */ |
444 | 2258 (ccl_prog, reg)) |
428 | 2259 { |
2260 struct ccl_program ccl; | |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2261 struct gcpro gcpro1; |
428 | 2262 int i; |
2263 | |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2264 ccl_prog = get_ccl_program (ccl_prog); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2265 /* get_ccl_program may have consed. GCPROing shouldn't be necessary at the |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2266 moment, but maybe someday CCL will call Lisp: */ |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2267 GCPRO1 (ccl_prog); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2268 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2269 i = setup_ccl_program (&ccl, ccl_prog); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2270 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2271 text_checking_assert (i >= 0); |
428 | 2272 |
2273 CHECK_VECTOR (reg); | |
2274 if (XVECTOR_LENGTH (reg) != 8) | |
563 | 2275 syntax_error ("Length of vector REGISTERS is not 8", Qunbound); |
428 | 2276 |
2277 for (i = 0; i < 8; i++) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2278 ccl.reg[i] = (FIXNUMP (XVECTOR_DATA (reg)[i]) || CHARP (XVECTOR_DATA (reg)[i]) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2279 ? XCHAR_OR_FIXNUM (XVECTOR_DATA (reg)[i]) |
428 | 2280 : 0); |
2281 | |
444 | 2282 ccl_driver (&ccl, (const unsigned char *)0, |
2283 (unsigned_char_dynarr *)0, 0, (int *)0, | |
2284 CCL_MODE_ENCODING); | |
428 | 2285 QUIT; |
2286 if (ccl.status != CCL_STAT_SUCCESS) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2287 signal_error (Qccl_error, "Error in CCL program at code numbered ...", make_fixnum (ccl.ic)); |
428 | 2288 |
2289 for (i = 0; i < 8; i++) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2290 XVECTOR (reg)->contents[i] = make_fixnum (ccl.reg[i]); |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2291 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2292 RETURN_UNGCPRO (Qnil); |
428 | 2293 } |
2294 | |
444 | 2295 DEFUN ("ccl-execute-on-string", Fccl_execute_on_string, |
2296 3, 4, 0, /* | |
428 | 2297 Execute CCL-PROGRAM with initial STATUS on STRING. |
2298 | |
2299 CCL-PROGRAM is a symbol registered by register-ccl-program, | |
2300 or a compiled code generated by `ccl-compile' (for backward compatibility, | |
2301 in this case, the execution is slower). | |
2302 | |
2303 Read buffer is set to STRING, and write buffer is allocated automatically. | |
2304 | |
2305 STATUS is a vector of [R0 R1 ... R7 IC], where | |
2306 R0..R7 are initial values of corresponding registers, | |
2307 IC is the instruction counter specifying from where to start the program. | |
2308 If R0..R7 are nil, they are initialized to 0. | |
2309 If IC is nil, it is initialized to head of the CCL program. | |
2310 | |
2311 If optional 4th arg CONTINUE is non-nil, keep IC on read operation | |
444 | 2312 when read buffer is exhausted, else, IC is always set to the end of |
428 | 2313 CCL-PROGRAM on exit. |
2314 | |
2315 It returns the contents of write buffer as a string, | |
2316 and as side effect, STATUS is updated. | |
444 | 2317 |
2318 See the documentation of `define-ccl-program' for the detail of CCL program. | |
428 | 2319 */ |
444 | 2320 (ccl_prog, status, string, continue_)) |
428 | 2321 { |
2322 Lisp_Object val; | |
2323 struct ccl_program ccl; | |
2324 int i, produced; | |
2325 unsigned_char_dynarr *outbuf; | |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2326 struct gcpro gcpro1, gcpro2, gcpro3; |
428 | 2327 |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2328 ccl_prog = get_ccl_program (ccl_prog); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2329 i = setup_ccl_program (&ccl, ccl_prog); |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2330 |
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2331 text_checking_assert (i >= 0); |
428 | 2332 |
2333 CHECK_VECTOR (status); | |
444 | 2334 if (XVECTOR (status)->size != 9) |
563 | 2335 syntax_error ("Length of vector STATUS is not 9", Qunbound); |
444 | 2336 CHECK_STRING (string); |
428 | 2337 |
4745
0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
Aidan Kehoe <kehoea@parhasard.net>
parents:
4525
diff
changeset
|
2338 GCPRO3 (status, string, ccl_prog); |
444 | 2339 |
428 | 2340 for (i = 0; i < 8; i++) |
2341 { | |
2342 if (NILP (XVECTOR_DATA (status)[i])) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2343 XVECTOR_DATA (status)[i] = make_fixnum (0); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2344 if (FIXNUMP (XVECTOR_DATA (status)[i])) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2345 ccl.reg[i] = XFIXNUM (XVECTOR_DATA (status)[i]); |
4072 | 2346 if (CHARP (XVECTOR_DATA (status)[i])) |
2347 ccl.reg[i] = XCHAR (XVECTOR_DATA (status)[i]); | |
428 | 2348 } |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2349 if (FIXNUMP (XVECTOR (status)->contents[i]) || |
4072 | 2350 CHARP (XVECTOR (status)->contents[i])) |
428 | 2351 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2352 i = XCHAR_OR_FIXNUM (XVECTOR_DATA (status)[8]); |
428 | 2353 if (ccl.ic < i && i < ccl.size) |
2354 ccl.ic = i; | |
2355 } | |
2356 outbuf = Dynarr_new (unsigned_char); | |
444 | 2357 ccl.last_block = NILP (continue_); |
2358 produced = ccl_driver (&ccl, XSTRING_DATA (string), outbuf, | |
2359 XSTRING_LENGTH (string), | |
2360 (int *) 0, | |
2361 CCL_MODE_DECODING); | |
428 | 2362 for (i = 0; i < 8; i++) |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2363 XVECTOR_DATA (status)[i] = make_fixnum (ccl.reg[i]); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2364 XVECTOR_DATA (status)[8] = make_fixnum (ccl.ic); |
428 | 2365 UNGCPRO; |
2366 | |
4967 | 2367 val = make_string (Dynarr_begin (outbuf), produced); |
428 | 2368 Dynarr_free (outbuf); |
2369 QUIT; | |
444 | 2370 if (ccl.status == CCL_STAT_SUSPEND_BY_DST) |
563 | 2371 signal_error (Qccl_error, "Output buffer for the CCL programs overflow", Qunbound); |
428 | 2372 if (ccl.status != CCL_STAT_SUCCESS |
444 | 2373 && ccl.status != CCL_STAT_SUSPEND_BY_SRC) |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2374 signal_error (Qccl_error, "Error in CCL program at code numbered...", make_fixnum (ccl.ic)); |
428 | 2375 |
2376 return val; | |
2377 } | |
2378 | |
444 | 2379 DEFUN ("register-ccl-program", Fregister_ccl_program, |
2380 2, 2, 0, /* | |
2381 Register CCL program CCL-PROG as NAME in `ccl-program-table'. | |
2382 CCL-PROG should be a compiled CCL program (vector), or nil. | |
2383 If it is nil, just reserve NAME as a CCL program name. | |
428 | 2384 Return index number of the registered CCL program. |
2385 */ | |
444 | 2386 (name, ccl_prog)) |
428 | 2387 { |
2388 int len = XVECTOR_LENGTH (Vccl_program_table); | |
444 | 2389 int idx; |
2390 Lisp_Object resolved; | |
428 | 2391 |
2392 CHECK_SYMBOL (name); | |
444 | 2393 resolved = Qnil; |
428 | 2394 if (!NILP (ccl_prog)) |
2395 { | |
2396 CHECK_VECTOR (ccl_prog); | |
444 | 2397 resolved = resolve_symbol_ccl_program (ccl_prog); |
2398 if (! NILP (resolved)) | |
428 | 2399 { |
444 | 2400 ccl_prog = resolved; |
2401 resolved = Qt; | |
428 | 2402 } |
2403 } | |
2404 | |
444 | 2405 for (idx = 0; idx < len; idx++) |
428 | 2406 { |
444 | 2407 Lisp_Object slot; |
2408 | |
2409 slot = XVECTOR_DATA (Vccl_program_table)[idx]; | |
2410 if (!VECTORP (slot)) | |
2411 /* This is the first unused slot. Register NAME here. */ | |
2412 break; | |
2413 | |
2414 if (EQ (name, XVECTOR_DATA (slot)[0])) | |
2415 { | |
2416 /* Update this slot. */ | |
2417 XVECTOR_DATA (slot)[1] = ccl_prog; | |
2418 XVECTOR_DATA (slot)[2] = resolved; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2419 return make_fixnum (idx); |
444 | 2420 } |
2421 } | |
2422 | |
2423 if (idx == len) | |
2424 { | |
2425 /* Extend the table. */ | |
2426 Lisp_Object new_table; | |
428 | 2427 int j; |
2428 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2429 new_table = Fmake_vector (make_fixnum (len * 2), Qnil); |
428 | 2430 for (j = 0; j < len; j++) |
2431 XVECTOR_DATA (new_table)[j] | |
2432 = XVECTOR_DATA (Vccl_program_table)[j]; | |
2433 Vccl_program_table = new_table; | |
2434 } | |
2435 | |
444 | 2436 { |
2437 Lisp_Object elt; | |
2438 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2439 elt = Fmake_vector (make_fixnum (3), Qnil); |
444 | 2440 XVECTOR_DATA (elt)[0] = name; |
2441 XVECTOR_DATA (elt)[1] = ccl_prog; | |
2442 XVECTOR_DATA (elt)[2] = resolved; | |
2443 XVECTOR_DATA (Vccl_program_table)[idx] = elt; | |
2444 } | |
2445 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2446 Fput (name, Qccl_program_idx, make_fixnum (idx)); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2447 return make_fixnum (idx); |
428 | 2448 } |
2449 | |
2450 /* Register code conversion map. | |
2451 A code conversion map consists of numbers, Qt, Qnil, and Qlambda. | |
2452 The first element is start code point. | |
2453 The rest elements are mapped numbers. | |
2454 Symbol t means to map to an original number before mapping. | |
2455 Symbol nil means that the corresponding element is empty. | |
442 | 2456 Symbol lambda means to terminate mapping here. |
428 | 2457 */ |
2458 | |
2459 DEFUN ("register-code-conversion-map", Fregister_code_conversion_map, | |
444 | 2460 2, 2, 0, /* |
2461 Register SYMBOL as code conversion map MAP. | |
2462 Return index number of the registered map. | |
2463 */ | |
2464 (symbol, map)) | |
428 | 2465 { |
444 | 2466 int len = XVECTOR_LENGTH (Vcode_conversion_map_vector); |
428 | 2467 int i; |
444 | 2468 Lisp_Object idx; |
428 | 2469 |
444 | 2470 CHECK_SYMBOL (symbol); |
2471 CHECK_VECTOR (map); | |
442 | 2472 |
428 | 2473 for (i = 0; i < len; i++) |
2474 { | |
444 | 2475 Lisp_Object slot = XVECTOR_DATA (Vcode_conversion_map_vector)[i]; |
428 | 2476 |
2477 if (!CONSP (slot)) | |
2478 break; | |
2479 | |
444 | 2480 if (EQ (symbol, XCAR (slot))) |
428 | 2481 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2482 idx = make_fixnum (i); |
444 | 2483 XCDR (slot) = map; |
428 | 2484 Fput (symbol, Qcode_conversion_map, map); |
444 | 2485 Fput (symbol, Qcode_conversion_map_id, idx); |
2486 return idx; | |
428 | 2487 } |
2488 } | |
2489 | |
2490 if (i == len) | |
2491 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2492 Lisp_Object new_vector = Fmake_vector (make_fixnum (len * 2), Qnil); |
428 | 2493 int j; |
2494 | |
2495 for (j = 0; j < len; j++) | |
444 | 2496 XVECTOR_DATA (new_vector)[j] |
2497 = XVECTOR_DATA (Vcode_conversion_map_vector)[j]; | |
428 | 2498 Vcode_conversion_map_vector = new_vector; |
2499 } | |
2500 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2501 idx = make_fixnum (i); |
428 | 2502 Fput (symbol, Qcode_conversion_map, map); |
444 | 2503 Fput (symbol, Qcode_conversion_map_id, idx); |
2504 XVECTOR_DATA (Vcode_conversion_map_vector)[i] = Fcons (symbol, map); | |
2505 return idx; | |
428 | 2506 } |
2507 | |
2508 | |
2509 void | |
2510 syms_of_mule_ccl (void) | |
2511 { | |
565 | 2512 DEFERROR_STANDARD (Qccl_error, Qconversion_error); |
2513 | |
444 | 2514 DEFSUBR (Fccl_program_p); |
428 | 2515 DEFSUBR (Fccl_execute); |
2516 DEFSUBR (Fccl_execute_on_string); | |
2517 DEFSUBR (Fregister_ccl_program); | |
444 | 2518 DEFSUBR (Fregister_code_conversion_map); |
428 | 2519 } |
2520 | |
2521 void | |
2522 vars_of_mule_ccl (void) | |
2523 { | |
4072 | 2524 |
428 | 2525 staticpro (&Vccl_program_table); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2526 Vccl_program_table = Fmake_vector (make_fixnum (32), Qnil); |
428 | 2527 |
4072 | 2528 #ifdef DEBUG_XEMACS |
2529 DEFVAR_LISP ("ccl-program-table", | |
2530 &Vccl_program_table /* | |
2531 Vector containing all registered CCL programs. | |
2532 */ ); | |
2533 #endif | |
563 | 2534 DEFSYMBOL (Qccl_program); |
2535 DEFSYMBOL (Qccl_program_idx); | |
2536 DEFSYMBOL (Qcode_conversion_map); | |
2537 DEFSYMBOL (Qcode_conversion_map_id); | |
428 | 2538 |
2539 DEFVAR_LISP ("code-conversion-map-vector", &Vcode_conversion_map_vector /* | |
444 | 2540 Vector of code conversion maps. |
2541 */ ); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2542 Vcode_conversion_map_vector = Fmake_vector (make_fixnum (16), Qnil); |
428 | 2543 |
4072 | 2544 DEFVAR_LISP ("translation-hash-table-vector", |
2545 &Vtranslation_hash_table_vector /* | |
2546 Vector containing all translation hash tables ever defined. | |
2547 Comprises pairs (SYMBOL . TABLE) where SYMBOL and TABLE were set up by calls | |
2548 to `define-translation-hash-table'. The vector is indexed by the table id | |
2549 used by CCL. | |
428 | 2550 */ ); |
4072 | 2551 Vtranslation_hash_table_vector = Qnil; |
2552 | |
428 | 2553 } |
2554 | |
2555 #endif /* emacs */ |