diff options
| author | Kenichi Handa | 1998-01-22 01:26:45 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1998-01-22 01:26:45 +0000 |
| commit | e34b1164c1ff43ed56e7e7be516b8db4aa2b8c1f (patch) | |
| tree | 530378761827edddf10209946cb264e2a0f9386d /src | |
| parent | eacba2473efc95326c1af32f368d69c4863a7bad (diff) | |
| download | emacs-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.c | 688 |
1 files changed, 638 insertions, 50 deletions
| @@ -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. */ | ||
| 39 | Lisp_Object Vccl_translation_table_vector; | ||
| 40 | |||
| 38 | /* Alist of fontname patterns vs corresponding CCL program. */ | 41 | /* Alist of fontname patterns vs corresponding CCL program. */ |
| 39 | Lisp_Object Vfont_ccl_encoder_alist; | 42 | Lisp_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 */ | ||
| 46 | Lisp_Object Qccl_program; | ||
| 47 | |||
| 48 | /* These symbol is properties whish associate with ccl translation table and its id | ||
| 49 | respectively. */ | ||
| 50 | Lisp_Object Qccl_translation_table; | ||
| 51 | Lisp_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. */ |
| 42 | Lisp_Object Vccl_program_table; | 54 | Lisp_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 | |||
| 1643 | DEFUN ("register-ccl-translation-table", Fregister_ccl_translation_table, | ||
| 1644 | Sregister_ccl_translation_table, | ||
| 1645 | 2, 2, 0, | ||
| 1646 | "Register CCL translation table.\n\ | ||
| 1647 | TABLE should be a vector. SYMBOL is used for pointing the translation table out.\n\ | ||
| 1648 | Return 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 | |||
| 1122 | syms_of_ccl () | 1695 | syms_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\ | ||
| 1711 | Because 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\ |
| 1129 | Each element looks like (REGEXP . CCL-CODE),\n\ | 1716 | Each 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 */ |