aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa1998-01-22 01:26:45 +0000
committerKenichi Handa1998-01-22 01:26:45 +0000
commite34b1164c1ff43ed56e7e7be516b8db4aa2b8c1f (patch)
tree530378761827edddf10209946cb264e2a0f9386d /src
parenteacba2473efc95326c1af32f368d69c4863a7bad (diff)
downloademacs-e34b1164c1ff43ed56e7e7be516b8db4aa2b8c1f.tar.gz
emacs-e34b1164c1ff43ed56e7e7be516b8db4aa2b8c1f.zip
(Vccl_translation_table_vector, Qccl_program,
Qccl_translation_table, Qccl_translation_table_id): New variables. append new symbols. Qccl_translation_table and Qccl_translation_table_id. (CCL_Call): Fix the comment. (CCL_ReadMultibyteCharacter, CCL_WriteMultibyteCharacter, CCL_UnifyCharacter, CCL_UnifyCharacterConstTbl, CCL_IterateMultipleMap, CCL_TranslateMultipleMap): New macros for CCL Commands. (EXCMD): New macro. (ccl_driver): New case lable `CCL_Extention'. (setup_ccl_program): Initialize the member `private_state' of CCL. (Fregister_ccl_program): Delete unused variable IDX. (Fregister_ccl_translation_table): New function. (syms_of_ccl): Intern and staticpro Qccl_program, Qccl_translation_table, and Qccl_translation_table_id. Declare `ccl-translation-table-vector' as a Lisp variable. Declare register-ccl-translation-table as a Lisp function.
Diffstat (limited to 'src')
-rw-r--r--src/ccl.c688
1 files changed, 638 insertions, 50 deletions
diff --git a/src/ccl.c b/src/ccl.c
index df58bb55a03..3a65ee815a2 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -35,9 +35,21 @@ Boston, MA 02111-1307, USA. */
35 35
36#endif /* not emacs */ 36#endif /* not emacs */
37 37
38/* Where is stored translation tables for CCL program. */
39Lisp_Object Vccl_translation_table_vector;
40
38/* Alist of fontname patterns vs corresponding CCL program. */ 41/* Alist of fontname patterns vs corresponding CCL program. */
39Lisp_Object Vfont_ccl_encoder_alist; 42Lisp_Object Vfont_ccl_encoder_alist;
40 43
44/* This symbol is property which assocate with ccl program vector. e.g.
45 (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector */
46Lisp_Object Qccl_program;
47
48/* These symbol is properties whish associate with ccl translation table and its id
49 respectively. */
50Lisp_Object Qccl_translation_table;
51Lisp_Object Qccl_translation_table_id;
52
41/* Vector of CCL program names vs corresponding program data. */ 53/* Vector of CCL program names vs corresponding program data. */
42Lisp_Object Vccl_program_table; 54Lisp_Object Vccl_program_table;
43 55
@@ -269,7 +281,8 @@ Lisp_Object Vccl_program_table;
269 write (reg[RRR] OPERATION reg[Rrr]); 281 write (reg[RRR] OPERATION reg[Rrr]);
270 */ 282 */
271 283
272#define CCL_Call 0x13 /* Write a constant: 284#define CCL_Call 0x13 /* Call the CCL program whose ID is
285 (CC..C).
273 1:CCCCCCCCCCCCCCCCCCCC000XXXXX 286 1:CCCCCCCCCCCCCCCCCCCC000XXXXX
274 ------------------------------ 287 ------------------------------
275 call (CC..C) 288 call (CC..C)
@@ -399,6 +412,129 @@ Lisp_Object Vccl_program_table;
399 extended_command (rrr,RRR,Rrr,ARGS) 412 extended_command (rrr,RRR,Rrr,ARGS)
400 */ 413 */
401 414
415/*
416 From here, Extended CCL Instruction.
417 Bit length of extended command is 14.
418 Therefore the instruction code begins from 0 to 16384(0x3fff).
419 */
420
421#define CCL_ReadMultibyteCharacter 0x00 /* Read Multibyte Character
422 1:ExtendedCOMMNDRrrRRRrrrXXXXX
423
424 Read a multibyte characeter.
425 A code point is stored
426 into rrr register.
427 A charset ID is stored
428 into RRR register.
429 */
430#define CCL_WriteMultibyteCharacter 0x01 /* Write Multibyte Character
431 1:ExtendedCOMMNDRrrRRRrrrXXXXX
432
433 Write a multibyte character.
434 Write a character whose code point
435 is in rrr register, and its charset ID
436 is in RRR charset.
437 */
438#define CCL_UnifyCharacter 0x02 /* Unify Multibyte Character
439 1:ExtendedCOMMNDRrrRRRrrrXXXXX
440
441 Unify a character where its code point
442 is in rrr register, and its charset ID
443 is in RRR register with the table of
444 the unification table ID
445 in Rrr register.
446
447 Return a unified character where its
448 code point is in rrr register, and its
449 charset ID is in RRR register.
450 */
451#define CCL_UnifyCharacterConstTbl 0x03 /* Unify Multibyte Character
452 1:ExtendedCOMMNDRrrRRRrrrXXXXX
453 2:ARGUMENT(Unification Table ID)
454
455 Unify a character where its code point
456 is in rrr register, and its charset ID
457 is in RRR register with the table of
458 the unification table ID
459 in 2nd argument.
460
461 Return a unified character where its
462 code point is in rrr register, and its
463 charset ID is in RRR register.
464 */
465#define CCL_IterateMultipleMap 0x10 /* Iterate Multiple Map
466 1:ExtendedCOMMNDXXXRRRrrrXXXXX
467 2:NUMBER of TABLES
468 3:TABLE-ID1
469 4:TABLE-ID2
470 ...
471
472 iterate to lookup tables from a number
473 until finding a value.
474
475 Each table consists of a vector
476 whose element is number or
477 nil or t or lambda.
478 If the element is nil,
479 its table is neglected.
480 In the case of t or lambda,
481 return the original value.
482
483 */
484#define CCL_TranslateMultipleMap 0x11 /* Translate Multiple Map
485 1:ExtendedCOMMNDXXXRRRrrrXXXXX
486 2:NUMBER of TABLE-IDs and SEPARATERs
487 (i.e. m1+m2+m3+...mk+k-1)
488 3:TABLE-ID 1,1
489 4:TABLE-ID 1,2
490 ...
491 m1+2:TABLE-ID 1,m1
492 m1+3: -1 (SEPARATOR)
493 m1+4:TABLE-ID 2,1
494 ...
495 m1+m2+4:TABLE-ID 2,m2
496 m1+m2+5: -1
497 ...
498 m1+m2+...+mk+k+1:TABLE-ID k,mk
499
500 Translate the code point in
501 rrr register by tables.
502 Translation starts from the table
503 where RRR register points out.
504
505 We translate the given value
506 from the tables which are separated
507 by -1.
508 When each translation is failed to find
509 any values, we regard the traslation
510 as identity.
511
512 We iterate to traslate by using each
513 table set(tables separated by -1)
514 until lookup the last table except
515 lookup lambda.
516
517 Each table consists of a vector
518 whose element is number
519 or nil or t or lambda.
520 If the element is nil,
521 it is neglected and use the next table.
522 In the case of t,
523 it is translated to the original value.
524 In the case of lambda,
525 it cease the translation and return the
526 current value.
527
528 */
529#define CCL_TranslateSingleMap 0x12 /* Translate Single Map
530 1:ExtendedCOMMNDXXXRRRrrrXXXXX
531 2:TABLE-ID
532
533 Translate a number in rrr register.
534 If it is not found any translation,
535 set RRR register -1 but rrr register
536 is not changed.
537 */
402 538
403/* CCL arithmetic/logical operators. */ 539/* CCL arithmetic/logical operators. */
404#define CCL_PLUS 0x00 /* X = Y + Z */ 540#define CCL_PLUS 0x00 /* X = Y + Z */
@@ -426,14 +562,6 @@ Lisp_Object Vccl_program_table;
426#define CCL_DECODE_SJIS 0x17 /* X = HIGHER_BYTE (DE-SJIS (Y, Z)) 562#define CCL_DECODE_SJIS 0x17 /* X = HIGHER_BYTE (DE-SJIS (Y, Z))
427 r[7] = LOWER_BYTE (DE-SJIS (Y, Z)) */ 563 r[7] = LOWER_BYTE (DE-SJIS (Y, Z)) */
428 564
429/* Macros for exit status of CCL program. */
430#define CCL_STAT_SUCCESS 0 /* Terminated successfully. */
431#define CCL_STAT_SUSPEND 1 /* Terminated because of empty input
432 buffer or full output buffer. */
433#define CCL_STAT_INVALID_CMD 2 /* Terminated because of invalid
434 command. */
435#define CCL_STAT_QUIT 3 /* Terminated because of quit. */
436
437/* Terminate CCL program successfully. */ 565/* Terminate CCL program successfully. */
438#define CCL_SUCCESS \ 566#define CCL_SUCCESS \
439 do { \ 567 do { \
@@ -445,11 +573,11 @@ Lisp_Object Vccl_program_table;
445/* Suspend CCL program because of reading from empty input buffer or 573/* Suspend CCL program because of reading from empty input buffer or
446 writing to full output buffer. When this program is resumed, the 574 writing to full output buffer. When this program is resumed, the
447 same I/O command is executed. */ 575 same I/O command is executed. */
448#define CCL_SUSPEND \ 576#define CCL_SUSPEND(stat) \
449 do { \ 577 do { \
450 ic--; \ 578 ic--; \
451 ccl->status = CCL_STAT_SUSPEND; \ 579 ccl->status = stat; \
452 goto ccl_finish; \ 580 goto ccl_finish; \
453 } while (0) 581 } while (0)
454 582
455/* Terminate CCL program because of invalid command. Should not occur 583/* Terminate CCL program because of invalid command. Should not occur
@@ -462,22 +590,22 @@ Lisp_Object Vccl_program_table;
462 590
463/* Encode one character CH to multibyte form and write to the current 591/* Encode one character CH to multibyte form and write to the current
464 output buffer. If CH is less than 256, CH is written as is. */ 592 output buffer. If CH is less than 256, CH is written as is. */
465#define CCL_WRITE_CHAR(ch) \ 593#define CCL_WRITE_CHAR(ch) \
466 do { \ 594 do { \
467 if (!dst) \ 595 if (!dst) \
468 CCL_INVALID_CMD; \ 596 CCL_INVALID_CMD; \
469 else \ 597 else \
470 { \ 598 { \
471 unsigned char work[4], *str; \ 599 unsigned char work[4], *str; \
472 int len = CHAR_STRING (ch, work, str); \ 600 int len = CHAR_STRING (ch, work, str); \
473 if (dst + len <= dst_end) \ 601 if (dst + len <= (dst_bytes ? dst_end : src)) \
474 { \ 602 { \
475 bcopy (str, dst, len); \ 603 bcopy (str, dst, len); \
476 dst += len; \ 604 dst += len; \
477 } \ 605 } \
478 else \ 606 else \
479 CCL_SUSPEND; \ 607 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST); \
480 } \ 608 } \
481 } while (0) 609 } while (0)
482 610
483/* Write a string at ccl_prog[IC] of length LEN to the current output 611/* Write a string at ccl_prog[IC] of length LEN to the current output
@@ -486,28 +614,28 @@ Lisp_Object Vccl_program_table;
486 do { \ 614 do { \
487 if (!dst) \ 615 if (!dst) \
488 CCL_INVALID_CMD; \ 616 CCL_INVALID_CMD; \
489 else if (dst + len <= dst_end) \ 617 else if (dst + len <= (dst_bytes ? dst_end : src)) \
490 for (i = 0; i < len; i++) \ 618 for (i = 0; i < len; i++) \
491 *dst++ = ((XFASTINT (ccl_prog[ic + (i / 3)])) \ 619 *dst++ = ((XFASTINT (ccl_prog[ic + (i / 3)])) \
492 >> ((2 - (i % 3)) * 8)) & 0xFF; \ 620 >> ((2 - (i % 3)) * 8)) & 0xFF; \
493 else \ 621 else \
494 CCL_SUSPEND; \ 622 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST); \
495 } while (0) 623 } while (0)
496 624
497/* Read one byte from the current input buffer into Rth register. */ 625/* Read one byte from the current input buffer into Rth register. */
498#define CCL_READ_CHAR(r) \ 626#define CCL_READ_CHAR(r) \
499 do { \ 627 do { \
500 if (!src) \ 628 if (!src) \
501 CCL_INVALID_CMD; \ 629 CCL_INVALID_CMD; \
502 else if (src < src_end) \ 630 else if (src < src_end) \
503 r = *src++; \ 631 r = *src++; \
504 else if (ccl->last_block) \ 632 else if (ccl->last_block) \
505 { \ 633 { \
506 ic = ccl->eof_ic; \ 634 ic = ccl->eof_ic; \
507 goto ccl_finish; \ 635 goto ccl_finish; \
508 } \ 636 } \
509 else \ 637 else \
510 CCL_SUSPEND; \ 638 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC); \
511 } while (0) 639 } while (0)
512 640
513 641
@@ -584,6 +712,7 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
584#define RRR (field1 & 7) 712#define RRR (field1 & 7)
585#define Rrr ((field1 >> 3) & 7) 713#define Rrr ((field1 >> 3) & 7)
586#define ADDR field1 714#define ADDR field1
715#define EXCMD (field1 >> 6)
587 716
588 switch (code & 0x1F) 717 switch (code & 0x1F)
589 { 718 {
@@ -881,6 +1010,387 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
881 ic = jump_address; 1010 ic = jump_address;
882 break; 1011 break;
883 1012
1013 case CCL_Extention:
1014 switch (EXCMD)
1015 {
1016 case CCL_ReadMultibyteCharacter:
1017 if (!src)
1018 CCL_INVALID_CMD;
1019 do {
1020 if (src >= src_end)
1021 goto ccl_read_multibyte_character_suspend;
1022
1023 i = *src++;
1024 if (i == LEADING_CODE_COMPOSITION)
1025 {
1026 if (src >= src_end)
1027 goto ccl_read_multibyte_character_suspend;
1028 if (*src == 0xFF)
1029 {
1030 ccl->private_state = COMPOSING_WITH_RULE_HEAD;
1031 src++;
1032 }
1033 else
1034 ccl->private_state = COMPOSING_NO_RULE_HEAD;
1035 }
1036 if (ccl->private_state != 0)
1037 {
1038 /* composite character */
1039 if (*src < 0xA0)
1040 ccl->private_state = 0;
1041 else
1042 {
1043 if (i == 0xA0)
1044 {
1045 if (src >= src_end)
1046 goto ccl_read_multibyte_character_suspend;
1047 i = *src++ & 0x7F;
1048 }
1049 else
1050 i -= 0x20;
1051
1052 if (COMPOSING_WITH_RULE_RULE == ccl->private_state)
1053 {
1054 ccl->private_state = COMPOSING_WITH_RULE_HEAD;
1055 continue;
1056 }
1057 else if (COMPOSING_WITH_RULE_HEAD == ccl->private_state)
1058 ccl->private_state = COMPOSING_WITH_RULE_RULE;
1059 }
1060 }
1061 if (i < 0x80)
1062 {
1063 /* ASCII */
1064 reg[rrr] = i;
1065 reg[RRR] = CHARSET_ASCII;
1066 }
1067 else if (i <= MAX_CHARSET_OFFICIAL_DIMENSION1)
1068 {
1069 if (src >= src_end)
1070 goto ccl_read_multibyte_character_suspend;
1071 reg[RRR] = i;
1072 reg[rrr] = (*src++ & 0x7F);
1073 }
1074 else if (i <= MAX_CHARSET_OFFICIAL_DIMENSION2)
1075 {
1076 if ((src + 1) >= src_end)
1077 goto ccl_read_multibyte_character_suspend;
1078 reg[RRR] = i;
1079 i = (*src++ & 0x7F);
1080 reg[rrr] = ((i << 7) | (*src & 0x7F));
1081 src++;
1082 }
1083 else if ((i == LEADING_CODE_PRIVATE_11) ||
1084 (i == LEADING_CODE_PRIVATE_12))
1085 {
1086 if ((src + 1) >= src_end)
1087 goto ccl_read_multibyte_character_suspend;
1088 reg[RRR] = *src++;
1089 reg[rrr] = (*src++ & 0x7F);
1090 }
1091 else if ((i == LEADING_CODE_PRIVATE_21) ||
1092 (i == LEADING_CODE_PRIVATE_22))
1093 {
1094 if ((src + 2) >= src_end)
1095 goto ccl_read_multibyte_character_suspend;
1096 reg[RRR] = *src++;
1097 i = (*src++ & 0x7F);
1098 reg[rrr] = ((i << 7) | (*src & 0x7F));
1099 src++;
1100 }
1101 else
1102 {
1103 /* INVALID CODE
1104 Returned charset is -1.*/
1105 reg[RRR] = -1;
1106 }
1107 } while (0);
1108 break;
1109
1110 ccl_read_multibyte_character_suspend:
1111 src--;
1112 if (ccl->last_block)
1113 {
1114 ic = ccl->eof_ic;
1115 goto ccl_finish;
1116 }
1117 else
1118 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);
1119
1120 break;
1121
1122 case CCL_WriteMultibyteCharacter:
1123 i = reg[RRR]; /* charset */
1124 if (i == CHARSET_ASCII)
1125 i = reg[rrr] & 0x7F;
1126 else if (i == CHARSET_COMPOSITION)
1127 i = MAKE_COMPOSITE_CHAR (reg[rrr]);
1128 else if (CHARSET_DIMENSION (i) == 1)
1129 i = ((i - 0x70) << 7) | (reg[rrr] & 0x7F);
1130 else if (i < MIN_CHARSET_PRIVATE_DIMENSION2)
1131 i = ((i - 0x8F) << 14) | reg[rrr];
1132 else
1133 i = ((i - 0xE0) << 14) | reg[rrr];
1134
1135 CCL_WRITE_CHAR (i);
1136
1137 break;
1138
1139 case CCL_UnifyCharacter:
1140 i = reg[RRR]; /* charset */
1141 if (i == CHARSET_ASCII)
1142 i = reg[rrr] & 0x7F;
1143 else if (i == CHARSET_COMPOSITION)
1144 {
1145 reg[RRR] = -1;
1146 break;
1147 }
1148 else if (CHARSET_DIMENSION (i) == 1)
1149 i = ((i - 0x70) << 7) | (reg[rrr] & 0x7F);
1150 else if (i < MIN_CHARSET_PRIVATE_DIMENSION2)
1151 i = ((i - 0x8F) << 14) | (reg[rrr] & 0x3FFF);
1152 else
1153 i = ((i - 0xE0) << 14) | (reg[rrr] & 0x3FFF);
1154
1155 op = unify_char (UNIFICATION_ID_TABLE (reg[Rrr]), i, -1, 0, 0);
1156 SPLIT_CHAR (op, reg[RRR], i, j);
1157 if (j != -1)
1158 i = (i << 7) | j;
1159
1160 reg[rrr] = i;
1161 break;
1162
1163 case CCL_UnifyCharacterConstTbl:
1164 op = XINT (ccl_prog[ic]); /* table */
1165 ic++;
1166 i = reg[RRR]; /* charset */
1167 if (i == CHARSET_ASCII)
1168 i = reg[rrr] & 0x7F;
1169 else if (i == CHARSET_COMPOSITION)
1170 {
1171 reg[RRR] = -1;
1172 break;
1173 }
1174 else if (CHARSET_DIMENSION (i) == 1)
1175 i = ((i - 0x70) << 7) | (reg[rrr] & 0x7F);
1176 else if (i < MIN_CHARSET_PRIVATE_DIMENSION2)
1177 i = ((i - 0x8F) << 14) | (reg[rrr] & 0x3FFF);
1178 else
1179 i = ((i - 0xE0) << 14) | (reg[rrr] & 0x3FFF);
1180
1181 op = unify_char (UNIFICATION_ID_TABLE (op), i, -1, 0, 0);
1182 SPLIT_CHAR (op, reg[RRR], i, j);
1183 if (j != -1)
1184 i = (i << 7) | j;
1185
1186 reg[rrr] = i;
1187 break;
1188
1189 case CCL_IterateMultipleMap:
1190 {
1191 Lisp_Object table, content, attrib, value;
1192 int point, size, fin_ic;
1193
1194 j = XINT (ccl_prog[ic++]); /* number of tables. */
1195 fin_ic = ic + j;
1196 op = reg[rrr];
1197 if ((j > reg[RRR]) && (j >= 0))
1198 {
1199 ic += reg[RRR];
1200 i = reg[RRR];
1201 }
1202 else
1203 {
1204 reg[RRR] = -1;
1205 ic = fin_ic;
1206 break;
1207 }
1208
1209 for (;i < j;i++)
1210 {
1211
1212 size = XVECTOR (Vccl_translation_table_vector)->size;
1213 point = ccl_prog[ic++];
1214 if (point >= size) continue;
1215 table = XVECTOR (Vccl_translation_table_vector)->
1216 contents[point];
1217 if (!CONSP (table)) continue;
1218 table = XCONS(table)->cdr;
1219 if (!VECTORP (table)) continue;
1220 size = XVECTOR (table)->size;
1221 if (size <= 1) continue;
1222 point = XUINT (XVECTOR (table)->contents[0]);
1223 point = op - point + 1;
1224 if (!((point >= 1) && (point < size))) continue;
1225 content = XVECTOR (table)->contents[point];
1226
1227 if (NILP (content))
1228 continue;
1229 else if (NUMBERP (content))
1230 {
1231 reg[RRR] = i;
1232 reg[rrr] = XUINT(content);
1233 break;
1234 }
1235 else if (EQ (content, Qt) || EQ (content, Qlambda))
1236 {
1237 reg[RRR] = i;
1238 break;
1239 }
1240 else if (CONSP (content))
1241 {
1242 attrib = XCONS (content)->car;
1243 value = XCONS (content)->cdr;
1244 if (!NUMBERP (attrib) || !NUMBERP (value))
1245 continue;
1246 reg[RRR] = i;
1247 reg[rrr] = XUINT(value);
1248 break;
1249 }
1250 }
1251 if (i == j)
1252 reg[RRR] = -1;
1253 ic = fin_ic;
1254 }
1255 break;
1256
1257 case CCL_TranslateMultipleMap:
1258 {
1259 Lisp_Object table, content, attrib, value;
1260 int point, size, table_vector_size;
1261 int skip_to_next, fin_ic;
1262
1263 j = XINT (ccl_prog[ic++]); /* number of tables and separators. */
1264 fin_ic = ic + j;
1265 if ((j > reg[RRR]) && (j >= 0))
1266 {
1267 ic += reg[RRR];
1268 i = reg[RRR];
1269 }
1270 else
1271 {
1272 ic = fin_ic;
1273 reg[RRR] = -1;
1274 break;
1275 }
1276 op = reg[rrr];
1277 reg[RRR] = -1;
1278 skip_to_next = 0;
1279 table_vector_size = XVECTOR (Vccl_translation_table_vector)->size;
1280 for (;i < j;i++)
1281 {
1282 point = ccl_prog[ic++];
1283 if (XINT(point) == -1)
1284 {
1285 skip_to_next = 0;
1286 continue;
1287 }
1288 if (skip_to_next) continue;
1289 if (point >= table_vector_size) continue;
1290 table = XVECTOR (Vccl_translation_table_vector)->
1291 contents[point];
1292 if (!CONSP (table)) continue;
1293 table = XCONS (table)->cdr;
1294 if (!VECTORP (table)) continue;
1295 size = XVECTOR (table)->size;
1296 if (size <= 1) continue;
1297 point = XUINT (XVECTOR (table)->contents[0]);
1298 point = op - point + 1;
1299 if (!((point >= 1) && (point < size))) continue;
1300 content = XVECTOR (table)->contents[point];
1301
1302 if (NILP (content))
1303 continue;
1304 else if (NUMBERP (content))
1305 {
1306 op = XUINT (content);
1307 reg[RRR] = i;
1308 skip_to_next = 1;
1309 }
1310 else if (CONSP (content))
1311 {
1312 attrib = XCONS (content)->car;
1313 value = XCONS (content)->cdr;
1314 if (!NUMBERP (attrib) || !NUMBERP (value))
1315 continue;
1316 reg[RRR] = i;
1317 op = XUINT (value);
1318
1319 }
1320 else if (EQ (content, Qt))
1321 {
1322 reg[RRR] = i;
1323 op = reg[rrr];
1324 skip_to_next = 1;
1325 }
1326 else if (EQ (content, Qlambda))
1327 break;
1328 }
1329 ic = fin_ic;
1330 }
1331 reg[rrr] = op;
1332 break;
1333
1334 case CCL_TranslateSingleMap:
1335 {
1336 Lisp_Object table, attrib, value, content;
1337 int size, point;
1338 j = XINT (ccl_prog[ic++]); /* table_id */
1339 op = reg[rrr];
1340 if (j >= XVECTOR (Vccl_translation_table_vector)->size)
1341 {
1342 reg[RRR] = -1;
1343 break;
1344 }
1345 table = XVECTOR (Vccl_translation_table_vector)->
1346 contents[j];
1347 if (!CONSP (table))
1348 {
1349 reg[RRR] = -1;
1350 break;
1351 }
1352 table = XCONS(table)->cdr;
1353 if (!VECTORP (table))
1354 {
1355 reg[RRR] = -1;
1356 break;
1357 }
1358 size = XVECTOR (table)->size;
1359 point = XUINT (XVECTOR (table)->contents[0]);
1360 point = op - point + 1;
1361 reg[RRR] = 0;
1362 if ((size <= 1) ||
1363 (!((point >= 1) && (point < size))))
1364 reg[RRR] = -1;
1365 else
1366 {
1367 content = XVECTOR (table)->contents[point];
1368 if (NILP (content))
1369 reg[RRR] = -1;
1370 else if (NUMBERP (content))
1371 reg[rrr] = XUINT (content);
1372 else if (EQ (content, Qt))
1373 reg[RRR] = i;
1374 else if (CONSP (content))
1375 {
1376 attrib = XCONS (content)->car;
1377 value = XCONS (content)->cdr;
1378 if (!NUMBERP (attrib) || !NUMBERP (value))
1379 continue;
1380 reg[rrr] = XUINT(value);
1381 break;
1382 }
1383 else
1384 reg[RRR] = -1;
1385 }
1386 }
1387 break;
1388
1389 default:
1390 CCL_INVALID_CMD;
1391 }
1392 break;
1393
884 default: 1394 default:
885 CCL_INVALID_CMD; 1395 CCL_INVALID_CMD;
886 } 1396 }
@@ -906,7 +1416,7 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
906 int j; 1416 int j;
907 1417
908 msglen = strlen (msg); 1418 msglen = strlen (msg);
909 if (dst + msglen <= dst_end) 1419 if (dst + msglen <= (dst_bytes ? dst_end : src))
910 { 1420 {
911 bcopy (msg, dst, msglen); 1421 bcopy (msg, dst, msglen);
912 dst += msglen; 1422 dst += msglen;
@@ -919,7 +1429,7 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
919 break; 1429 break;
920 sprintf(msg, " %d", ccl_backtrace_table[i]); 1430 sprintf(msg, " %d", ccl_backtrace_table[i]);
921 msglen = strlen (msg); 1431 msglen = strlen (msg);
922 if (dst + msglen > dst_end) 1432 if (dst + msglen > (dst_bytes ? dst_end : src))
923 break; 1433 break;
924 bcopy (msg, dst, msglen); 1434 bcopy (msg, dst, msglen);
925 dst += msglen; 1435 dst += msglen;
@@ -937,7 +1447,7 @@ ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
937 } 1447 }
938 1448
939 msglen = strlen (msg); 1449 msglen = strlen (msg);
940 if (dst + msglen <= dst_end) 1450 if (dst + msglen <= (dst_bytes ? dst_end : src))
941 { 1451 {
942 bcopy (msg, dst, msglen); 1452 bcopy (msg, dst, msglen);
943 dst += msglen; 1453 dst += msglen;
@@ -967,6 +1477,7 @@ setup_ccl_program (ccl, vec)
967 for (i = 0; i < 8; i++) 1477 for (i = 0; i < 8; i++)
968 ccl->reg[i] = 0; 1478 ccl->reg[i] = 0;
969 ccl->last_block = 0; 1479 ccl->last_block = 0;
1480 ccl->private_state = 0;
970 ccl->status = 0; 1481 ccl->status = 0;
971} 1482}
972 1483
@@ -1069,7 +1580,8 @@ CCL-PROGRAM on exit.")
1069 free (outbuf); 1580 free (outbuf);
1070 QUIT; 1581 QUIT;
1071 if (ccl.status != CCL_STAT_SUCCESS 1582 if (ccl.status != CCL_STAT_SUCCESS
1072 && ccl.status != CCL_STAT_SUSPEND) 1583 && ccl.status != CCL_STAT_SUSPEND_BY_SRC
1584 && ccl.status != CCL_STAT_SUSPEND_BY_DST)
1073 error ("Error in CCL program at %dth code", ccl.ic); 1585 error ("Error in CCL program at %dth code", ccl.ic);
1074 1586
1075 return val; 1587 return val;
@@ -1084,7 +1596,7 @@ Return index number of the registered CCL program.")
1084 Lisp_Object name, ccl_prog; 1596 Lisp_Object name, ccl_prog;
1085{ 1597{
1086 int len = XVECTOR (Vccl_program_table)->size; 1598 int len = XVECTOR (Vccl_program_table)->size;
1087 int i, idx; 1599 int i;
1088 1600
1089 CHECK_SYMBOL (name, 0); 1601 CHECK_SYMBOL (name, 0);
1090 if (!NILP (ccl_prog)) 1602 if (!NILP (ccl_prog))
@@ -1119,11 +1631,86 @@ Return index number of the registered CCL program.")
1119 return make_number (i); 1631 return make_number (i);
1120} 1632}
1121 1633
1634/* register CCL translation table.
1635 CCL translation table consists of numbers and Qt and Qnil and Qlambda.
1636 The first element is start code point.
1637 The rest elements are translated numbers.
1638 Qt shows that an original number before translation.
1639 Qnil shows that an empty element.
1640 Qlambda makes translation stopped.
1641*/
1642
1643DEFUN ("register-ccl-translation-table", Fregister_ccl_translation_table,
1644 Sregister_ccl_translation_table,
1645 2, 2, 0,
1646 "Register CCL translation table.\n\
1647TABLE should be a vector. SYMBOL is used for pointing the translation table out.\n\
1648Return index number of the registered translation table.")
1649 (symbol, table)
1650 Lisp_Object symbol, table;
1651{
1652 int len = XVECTOR (Vccl_translation_table_vector)->size;
1653 int i;
1654 Lisp_Object index;
1655
1656 CHECK_SYMBOL (symbol, 0);
1657 CHECK_VECTOR (table, 1);
1658
1659 for (i = 0; i < len; i++)
1660 {
1661 Lisp_Object slot = XVECTOR (Vccl_translation_table_vector)->contents[i];
1662
1663 if (!CONSP (slot))
1664 break;
1665
1666 if (EQ (symbol, XCONS (slot)->car))
1667 {
1668 index = make_number (i);
1669 XCONS (slot)->cdr = table;
1670 Fput (symbol, Qccl_translation_table, table);
1671 Fput (symbol, Qccl_translation_table_id, index);
1672 return index;
1673 }
1674 }
1675
1676 if (i == len)
1677 {
1678 Lisp_Object new_vector = Fmake_vector (make_number (len * 2), Qnil);
1679 int j;
1680
1681 for (j = 0; j < len; j++)
1682 XVECTOR (new_vector)->contents[j]
1683 = XVECTOR (Vccl_translation_table_vector)->contents[j];
1684 Vccl_translation_table_vector = new_vector;
1685 }
1686
1687 index = make_number (i);
1688 Fput (symbol, Qccl_translation_table, table);
1689 Fput (symbol, Qccl_translation_table_id, index);
1690 XVECTOR (Vccl_translation_table_vector)->contents[i] = Fcons (symbol, table);
1691 return index;
1692}
1693
1694
1122syms_of_ccl () 1695syms_of_ccl ()
1123{ 1696{
1124 staticpro (&Vccl_program_table); 1697 staticpro (&Vccl_program_table);
1125 Vccl_program_table = Fmake_vector (make_number (32), Qnil); 1698 Vccl_program_table = Fmake_vector (make_number (32), Qnil);
1126 1699
1700 Qccl_program = intern("ccl-program");
1701 staticpro(&Qccl_program);
1702
1703 Qccl_translation_table = intern ("ccl-translation-table");
1704 staticpro (&Qccl_translation_table);
1705
1706 Qccl_translation_table_id = intern ("ccl-translation-table-id");
1707 staticpro (&Qccl_translation_table_id);
1708
1709 DEFVAR_LISP ("ccl-translation-table-vector", &Vccl_translation_table_vector,
1710 "Where is stored translation tables for CCL program.\n\
1711Because CCL program can't access these tables except by the index of the vector.");
1712 Vccl_translation_table_vector = Fmake_vector (XFASTINT (16), Qnil);
1713
1127 DEFVAR_LISP ("font-ccl-encoder-alist", &Vfont_ccl_encoder_alist, 1714 DEFVAR_LISP ("font-ccl-encoder-alist", &Vfont_ccl_encoder_alist,
1128 "Alist of fontname patterns vs corresponding CCL program.\n\ 1715 "Alist of fontname patterns vs corresponding CCL program.\n\
1129Each element looks like (REGEXP . CCL-CODE),\n\ 1716Each element looks like (REGEXP . CCL-CODE),\n\
@@ -1140,6 +1727,7 @@ If the font is single-byte font, the register R2 is not used.");
1140 defsubr (&Sccl_execute); 1727 defsubr (&Sccl_execute);
1141 defsubr (&Sccl_execute_on_string); 1728 defsubr (&Sccl_execute_on_string);
1142 defsubr (&Sregister_ccl_program); 1729 defsubr (&Sregister_ccl_program);
1730 defsubr (&Sregister_ccl_translation_table);
1143} 1731}
1144 1732
1145#endif /* emacs */ 1733#endif /* emacs */