comparison src/mule-ccl.c @ 4072:aa28d959af41

[xemacs-hg @ 2007-07-22 22:03:29 by aidan] Add support for non-ISO2022 8 bit fixed-width coding-systems
author aidan
date Sun, 22 Jul 2007 22:04:14 +0000
parents d6a215ad08b8
children 6f05405e63fc
comparison
equal deleted inserted replaced
4071:d607d13fca67 4072:aa28d959af41
27 27
28 #include "buffer.h" 28 #include "buffer.h"
29 #include "charset.h" 29 #include "charset.h"
30 #include "mule-ccl.h" 30 #include "mule-ccl.h"
31 #include "file-coding.h" 31 #include "file-coding.h"
32 #include "elhash.h"
32 33
33 Lisp_Object Qccl_error; 34 Lisp_Object Qccl_error;
34 35
35 /* This contains all code conversion map available to CCL. */ 36 /* This contains all code conversion map available to CCL. */
36 Lisp_Object Vcode_conversion_map_vector; 37 Lisp_Object Vcode_conversion_map_vector;
37
38 /* Alist of fontname patterns vs corresponding CCL program. */
39 Lisp_Object Vfont_ccl_encoder_alist;
40 38
41 /* This symbol is a property which associates with ccl program vector. 39 /* This symbol is a property which associates with ccl program vector.
42 Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector. 40 Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector.
43 Moved to general-slots.h. */ 41 Moved to general-slots.h. */
44 /* Lisp_Object Qccl_program; */ 42 /* Lisp_Object Qccl_program; */
56 NAME, CCL_PROG, and RESOLVEDP where NAME (symbol) is the name of 54 NAME, CCL_PROG, and RESOLVEDP where NAME (symbol) is the name of
57 the program, CCL_PROG (vector) is the compiled code of the program, 55 the program, CCL_PROG (vector) is the compiled code of the program,
58 RESOLVEDP (t or nil) is the flag to tell if symbols in CCL_PROG is 56 RESOLVEDP (t or nil) is the flag to tell if symbols in CCL_PROG is
59 already resolved to index numbers or not. */ 57 already resolved to index numbers or not. */
60 Lisp_Object Vccl_program_table; 58 Lisp_Object Vccl_program_table;
59
60 /* Vector of registered hash tables for translation. */
61 Lisp_Object Vtranslation_hash_table_vector;
62
63 /* Return a hash table of id number ID. */
64 #define GET_HASH_TABLE(id) \
65 (XHASH_TABLE (XCDR(XVECTOR(Vtranslation_hash_table_vector)->contents[(id)])))
66 /* Copied from fns.c. */
67 #define HASH_VALUE(H, IDX) AREF ((H)->key_and_value, 2 * (IDX) + 1)
61 68
62 /* CCL (Code Conversion Language) is a simple language which has 69 /* CCL (Code Conversion Language) is a simple language which has
63 operations on one input buffer, one output buffer, and 7 registers. 70 operations on one input buffer, one output buffer, and 7 registers.
64 The syntax of CCL is described in `ccl.el'. Emacs Lisp function 71 The syntax of CCL is described in `ccl.el'. Emacs Lisp function
65 `ccl-compile' compiles a CCL program and produces a CCL code which 72 `ccl-compile' compiles a CCL program and produces a CCL code which
648 If some valid mapping is found, 655 If some valid mapping is found,
649 set reg[rrr] to the result, 656 set reg[rrr] to the result,
650 else 657 else
651 set reg[RRR] to -1. 658 set reg[RRR] to -1.
652 */ 659 */
660
661 #define CCL_LookupIntConstTbl 0x13 /* Lookup multibyte character by
662 integer key. Afterwards R7 set
663 to 1 iff lookup succeeded.
664 1:ExtendedCOMMNDRrrRRRXXXXXXXX
665 2:ARGUMENT(Hash table ID) */
666
667 #define CCL_LookupCharConstTbl 0x14 /* Lookup integer by multibyte
668 character key. Afterwards R7 set
669 to 1 iff lookup succeeded.
670 1:ExtendedCOMMNDRrrRRRrrrXXXXX
671 2:ARGUMENT(Hash table ID) */
672
653 673
654 /* CCL arithmetic/logical operators. */ 674 /* CCL arithmetic/logical operators. */
655 #define CCL_PLUS 0x00 /* X = Y + Z */ 675 #define CCL_PLUS 0x00 /* X = Y + Z */
656 #define CCL_MINUS 0x01 /* X = Y - Z */ 676 #define CCL_MINUS 0x01 /* X = Y - Z */
657 #define CCL_MUL 0x02 /* X = Y * Z */ 677 #define CCL_MUL 0x02 /* X = Y * Z */
771 CCL_INVALID_CMD; \ 791 CCL_INVALID_CMD; \
772 else if (conversion_mode == CCL_MODE_ENCODING) \ 792 else if (conversion_mode == CCL_MODE_ENCODING) \
773 { \ 793 { \
774 for (i = 0; i < (len); i++) \ 794 for (i = 0; i < (len); i++) \
775 { \ 795 { \
776 ch = ((XINT (ccl_prog[ic + (i / 3)])) \ 796 ch = ((XCHAR_OR_INT (ccl_prog[ic + (i / 3)])) \
777 >> ((2 - (i % 3)) * 8)) & 0xFF; \ 797 >> ((2 - (i % 3)) * 8)) & 0xFF; \
778 if (ch == '\n') \ 798 if (ch == '\n') \
779 { \ 799 { \
780 if (ccl->eol_type == CCL_CODING_EOL_CRLF) \ 800 if (ccl->eol_type == CCL_CODING_EOL_CRLF) \
781 { \ 801 { \
800 } \ 820 } \
801 else \ 821 else \
802 { \ 822 { \
803 for (i = 0; i < (len); i++) \ 823 for (i = 0; i < (len); i++) \
804 { \ 824 { \
805 ch = ((XINT (ccl_prog[ic + (i / 3)])) \ 825 ch = ((XCHAR_OR_INT (ccl_prog[ic + (i / 3)])) \
806 >> ((2 - (i % 3)) * 8)) & 0xFF; \ 826 >> ((2 - (i % 3)) * 8)) & 0xFF; \
807 if (!ichar_multibyte_p(ch)) \ 827 if (!ichar_multibyte_p(ch)) \
808 { \ 828 { \
809 Dynarr_add (destination, ch); \ 829 Dynarr_add (destination, ch); \
810 } \ 830 } \
835 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC); \ 855 CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC); \
836 } \ 856 } \
837 } while (0) 857 } while (0)
838 858
839 #define POSSIBLE_LEADING_BYTE_P(leading_byte) \ 859 #define POSSIBLE_LEADING_BYTE_P(leading_byte) \
840 ((leading_byte > MIN_LEADING_BYTE) && \ 860 ((leading_byte >= MIN_LEADING_BYTE) && \
841 (leading_byte - MIN_LEADING_BYTE) < NUM_LEADING_BYTES) 861 (leading_byte - MIN_LEADING_BYTE) < NUM_LEADING_BYTES)
842 862
843 /* Set C to the character code made from CHARSET and CODE. This is 863 /* Set C to the character code made from CHARSET and CODE. This is
844 like make_ichar but check the validity of CHARSET and CODE. If they 864 like make_ichar but check the validity of CHARSET and CODE. If they
845 are not valid, set C to (CODE & 0xFF) because that is usually the 865 are not valid, set C to (CODE & 0xFF) because that is usually the
862 { \ 882 { \
863 c = ((code) & 0x1F) + 0x80; \ 883 c = ((code) & 0x1F) + 0x80; \
864 } \ 884 } \
865 else if (!NILP(charset_by_leading_byte(charset)) \ 885 else if (!NILP(charset_by_leading_byte(charset)) \
866 && ((code) >= 32) \ 886 && ((code) >= 32) \
867 && ((code) < 256 || ((code >> 8) & 0x7F) >= 32)) \ 887 && ((code) < 256 || ((code >> 7) & 0x7F) >= 32)) \
868 { \ 888 { \
869 int c1, c2 = 0; \ 889 int c1, c2 = 0; \
870 \ 890 \
871 if ((code) < 256) \ 891 if ((code) < 256) \
872 { \ 892 { \
873 c1 = (code) & 0x7F; \ 893 c1 = (code) & 0x7F; \
874 c2 = 0; \ 894 c2 = 0; \
875 } \ 895 } \
876 else \ 896 else \
877 { \ 897 { \
878 c1 = ((code) >> 8) & 0x7F; \ 898 c1 = ((code) >> 7) & 0x7F; \
879 c2 = (code) & 0x7F; \ 899 c2 = (code) & 0x7F; \
880 } \ 900 } \
881 c = make_ichar (charset_by_leading_byte(charset), \ 901 c = make_ichar (charset_by_leading_byte(charset), \
882 c1, c2); \ 902 c1, c2); \
883 } \ 903 } \
896 are updated. If SOURCE or DESTINATION is NULL, only operations on 916 are updated. If SOURCE or DESTINATION is NULL, only operations on
897 registers are permitted. */ 917 registers are permitted. */
898 918
899 #ifdef CCL_DEBUG 919 #ifdef CCL_DEBUG
900 #define CCL_DEBUG_BACKTRACE_LEN 256 920 #define CCL_DEBUG_BACKTRACE_LEN 256
901 int ccl_backtrace_table[CCL_BACKTRACE_TABLE]; 921 int ccl_backtrace_table[CCL_DEBUG_BACKTRACE_LEN];
902 int ccl_backtrace_idx; 922 int ccl_backtrace_idx;
903 #endif 923 #endif
904 924
905 struct ccl_prog_stack 925 struct ccl_prog_stack
906 { 926 {
964 ccl->status = CCL_STAT_QUIT; 984 ccl->status = CCL_STAT_QUIT;
965 break; 985 break;
966 } 986 }
967 987
968 this_ic = ic; 988 this_ic = ic;
969 code = XINT (ccl_prog[ic]); ic++; 989 code = XCHAR_OR_INT (ccl_prog[ic]); ic++;
970 field1 = code >> 8; 990 field1 = code >> 8;
971 field2 = (code & 0xFF) >> 5; 991 field2 = (code & 0xFF) >> 5;
972 992
973 #define rrr field2 993 #define rrr field2
974 #define RRR (field1 & 7) 994 #define RRR (field1 & 7)
985 case CCL_SetShortConst: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ 1005 case CCL_SetShortConst: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
986 reg[rrr] = field1; 1006 reg[rrr] = field1;
987 break; 1007 break;
988 1008
989 case CCL_SetConst: /* 00000000000000000000rrrXXXXX */ 1009 case CCL_SetConst: /* 00000000000000000000rrrXXXXX */
990 reg[rrr] = XINT (ccl_prog[ic]); 1010 reg[rrr] = XCHAR_OR_INT (ccl_prog[ic]);
991 ic++; 1011 ic++;
992 break; 1012 break;
993 1013
994 case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */ 1014 case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */
995 i = reg[RRR]; 1015 i = reg[RRR];
996 j = field1 >> 3; 1016 j = field1 >> 3;
997 /* #### it's non-obvious to me that we need these casts, 1017 /* #### it's non-obvious to me that we need these casts,
998 but the left one was already there so clearly the intention 1018 but the left one was already there so clearly the intention
999 was an unsigned comparison. --ben */ 1019 was an unsigned comparison. --ben */
1000 if ((unsigned int) i < (unsigned int) j) 1020 if ((unsigned int) i < (unsigned int) j)
1001 reg[rrr] = XINT (ccl_prog[ic + i]); 1021 reg[rrr] = XCHAR_OR_INT (ccl_prog[ic + i]);
1002 ic += j; 1022 ic += j;
1003 break; 1023 break;
1004 1024
1005 case CCL_Jump: /* A--D--D--R--E--S--S-000XXXXX */ 1025 case CCL_Jump: /* A--D--D--R--E--S--S-000XXXXX */
1006 ic += ADDR; 1026 ic += ADDR;
1024 CCL_READ_CHAR (reg[rrr]); 1044 CCL_READ_CHAR (reg[rrr]);
1025 ic += ADDR - 1; 1045 ic += ADDR - 1;
1026 break; 1046 break;
1027 1047
1028 case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */ 1048 case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */
1029 i = XINT (ccl_prog[ic]); 1049 i = XCHAR_OR_INT (ccl_prog[ic]);
1030 CCL_WRITE_CHAR (i); 1050 CCL_WRITE_CHAR (i);
1031 ic += ADDR; 1051 ic += ADDR;
1032 break; 1052 break;
1033 1053
1034 case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ 1054 case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */
1035 i = XINT (ccl_prog[ic]); 1055 i = XCHAR_OR_INT (ccl_prog[ic]);
1036 CCL_WRITE_CHAR (i); 1056 CCL_WRITE_CHAR (i);
1037 ic++; 1057 ic++;
1038 CCL_READ_CHAR (reg[rrr]); 1058 CCL_READ_CHAR (reg[rrr]);
1039 ic += ADDR - 1; 1059 ic += ADDR - 1;
1040 break; 1060 break;
1041 1061
1042 case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */ 1062 case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */
1043 j = XINT (ccl_prog[ic]); 1063 j = XCHAR_OR_INT (ccl_prog[ic]);
1044 ic++; 1064 ic++;
1045 CCL_WRITE_STRING (j); 1065 CCL_WRITE_STRING (j);
1046 ic += ADDR - 1; 1066 ic += ADDR - 1;
1047 break; 1067 break;
1048 1068
1049 case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ 1069 case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */
1050 i = reg[rrr]; 1070 i = reg[rrr];
1051 j = XINT (ccl_prog[ic]); 1071 j = XCHAR_OR_INT (ccl_prog[ic]);
1052 /* #### see comment at CCL_SetArray */ 1072 /* #### see comment at CCL_SetArray */
1053 if ((unsigned int) i < (unsigned int) j) 1073 if ((unsigned int) i < (unsigned int) j)
1054 { 1074 {
1055 i = XINT (ccl_prog[ic + 1 + i]); 1075 i = XCHAR_OR_INT (ccl_prog[ic + 1 + i]);
1056 CCL_WRITE_CHAR (i); 1076 CCL_WRITE_CHAR (i);
1057 } 1077 }
1058 ic += j + 2; 1078 ic += j + 2;
1059 CCL_READ_CHAR (reg[rrr]); 1079 CCL_READ_CHAR (reg[rrr]);
1060 ic += ADDR - (j + 2); 1080 ic += ADDR - (j + 2);
1069 CCL_READ_CHAR (reg[rrr]); 1089 CCL_READ_CHAR (reg[rrr]);
1070 /* fall through ... */ 1090 /* fall through ... */
1071 case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ 1091 case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
1072 /* #### see comment at CCL_SetArray */ 1092 /* #### see comment at CCL_SetArray */
1073 if ((unsigned int) reg[rrr] < (unsigned int) field1) 1093 if ((unsigned int) reg[rrr] < (unsigned int) field1)
1074 ic += XINT (ccl_prog[ic + reg[rrr]]); 1094 ic += XCHAR_OR_INT (ccl_prog[ic + reg[rrr]]);
1075 else 1095 else
1076 ic += XINT (ccl_prog[ic + field1]); 1096 ic += XCHAR_OR_INT (ccl_prog[ic + field1]);
1077 break; 1097 break;
1078 1098
1079 case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */ 1099 case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */
1080 while (1) 1100 while (1)
1081 { 1101 {
1082 CCL_READ_CHAR (reg[rrr]); 1102 CCL_READ_CHAR (reg[rrr]);
1083 if (!field1) break; 1103 if (!field1) break;
1084 code = XINT (ccl_prog[ic]); ic++; 1104 code = XCHAR_OR_INT (ccl_prog[ic]); ic++;
1085 field1 = code >> 8; 1105 field1 = code >> 8;
1086 field2 = (code & 0xFF) >> 5; 1106 field2 = (code & 0xFF) >> 5;
1087 } 1107 }
1088 break; 1108 break;
1089 1109
1090 case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */ 1110 case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */
1091 rrr = 7; 1111 rrr = 7;
1092 i = reg[RRR]; 1112 i = reg[RRR];
1093 j = XINT (ccl_prog[ic]); 1113 j = XCHAR_OR_INT (ccl_prog[ic]);
1094 op = field1 >> 6; 1114 op = field1 >> 6;
1095 jump_address = ic + 1; 1115 jump_address = ic + 1;
1096 goto ccl_set_expr; 1116 goto ccl_set_expr;
1097 1117
1098 case CCL_WriteRegister: /* CCCCCCCCCCCCCCCCCCCrrrXXXXX */ 1118 case CCL_WriteRegister: /* CCCCCCCCCCCCCCCCCCCrrrXXXXX */
1099 while (1) 1119 while (1)
1100 { 1120 {
1101 i = reg[rrr]; 1121 i = reg[rrr];
1102 CCL_WRITE_CHAR (i); 1122 CCL_WRITE_CHAR (i);
1103 if (!field1) break; 1123 if (!field1) break;
1104 code = XINT (ccl_prog[ic]); ic++; 1124 code = XCHAR_OR_INT (ccl_prog[ic]); ic++;
1105 field1 = code >> 8; 1125 field1 = code >> 8;
1106 field2 = (code & 0xFF) >> 5; 1126 field2 = (code & 0xFF) >> 5;
1107 } 1127 }
1108 break; 1128 break;
1109 1129
1122 1142
1123 /* If FFF is nonzero, the CCL program ID is in the 1143 /* If FFF is nonzero, the CCL program ID is in the
1124 following code. */ 1144 following code. */
1125 if (rrr) 1145 if (rrr)
1126 { 1146 {
1127 prog_id = XINT (ccl_prog[ic]); 1147 prog_id = XCHAR_OR_INT (ccl_prog[ic]);
1128 ic++; 1148 ic++;
1129 } 1149 }
1130 else 1150 else
1131 prog_id = field1; 1151 prog_id = field1;
1132 1152
1166 case CCL_WriteArray: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ 1186 case CCL_WriteArray: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
1167 i = reg[rrr]; 1187 i = reg[rrr];
1168 /* #### see comment at CCL_SetArray */ 1188 /* #### see comment at CCL_SetArray */
1169 if ((unsigned int) i < (unsigned int) field1) 1189 if ((unsigned int) i < (unsigned int) field1)
1170 { 1190 {
1171 j = XINT (ccl_prog[ic + i]); 1191 j = XCHAR_OR_INT (ccl_prog[ic + i]);
1172 CCL_WRITE_CHAR (j); 1192 CCL_WRITE_CHAR (j);
1173 } 1193 }
1174 ic += field1; 1194 ic += field1;
1175 break; 1195 break;
1176 1196
1188 suppress further processing. */ 1208 suppress further processing. */
1189 ic--; 1209 ic--;
1190 CCL_SUCCESS; 1210 CCL_SUCCESS;
1191 1211
1192 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */ 1212 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */
1193 i = XINT (ccl_prog[ic]); 1213 i = XCHAR_OR_INT (ccl_prog[ic]);
1194 ic++; 1214 ic++;
1195 op = field1 >> 6; 1215 op = field1 >> 6;
1196 goto ccl_expr_self; 1216 goto ccl_expr_self;
1197 1217
1198 case CCL_ExprSelfReg: /* 00000OPERATION000RRRrrrXXXXX */ 1218 case CCL_ExprSelfReg: /* 00000OPERATION000RRRrrrXXXXX */
1225 } 1245 }
1226 break; 1246 break;
1227 1247
1228 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */ 1248 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */
1229 i = reg[RRR]; 1249 i = reg[RRR];
1230 j = XINT (ccl_prog[ic]); 1250 j = XCHAR_OR_INT (ccl_prog[ic]);
1231 op = field1 >> 6; 1251 op = field1 >> 6;
1232 jump_address = ++ic; 1252 jump_address = ++ic;
1233 goto ccl_set_expr; 1253 goto ccl_set_expr;
1234 1254
1235 case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */ 1255 case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */
1241 1261
1242 case CCL_ReadJumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ 1262 case CCL_ReadJumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */
1243 CCL_READ_CHAR (reg[rrr]); 1263 CCL_READ_CHAR (reg[rrr]);
1244 case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ 1264 case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */
1245 i = reg[rrr]; 1265 i = reg[rrr];
1246 op = XINT (ccl_prog[ic]); 1266 op = XCHAR_OR_INT (ccl_prog[ic]);
1247 jump_address = ic++ + ADDR; 1267 jump_address = ic++ + ADDR;
1248 j = XINT (ccl_prog[ic]); 1268 j = XCHAR_OR_INT (ccl_prog[ic]);
1249 ic++; 1269 ic++;
1250 rrr = 7; 1270 rrr = 7;
1251 goto ccl_set_expr; 1271 goto ccl_set_expr;
1252 1272
1253 case CCL_ReadJumpCondExprReg: /* A--D--D--R--E--S--S-rrrXXXXX */ 1273 case CCL_ReadJumpCondExprReg: /* A--D--D--R--E--S--S-rrrXXXXX */
1254 CCL_READ_CHAR (reg[rrr]); 1274 CCL_READ_CHAR (reg[rrr]);
1255 case CCL_JumpCondExprReg: 1275 case CCL_JumpCondExprReg:
1256 i = reg[rrr]; 1276 i = reg[rrr];
1257 op = XINT (ccl_prog[ic]); 1277 op = XCHAR_OR_INT (ccl_prog[ic]);
1258 jump_address = ic++ + ADDR; 1278 jump_address = ic++ + ADDR;
1259 j = reg[XINT (ccl_prog[ic])]; 1279 j = reg[XCHAR_OR_INT (ccl_prog[ic])];
1260 ic++; 1280 ic++;
1261 rrr = 7; 1281 rrr = 7;
1262 1282
1263 ccl_set_expr: 1283 ccl_set_expr:
1264 switch (op) 1284 switch (op)
1356 else if (i == PRE_LEADING_BYTE_PRIVATE_1) 1376 else if (i == PRE_LEADING_BYTE_PRIVATE_1)
1357 { 1377 {
1358 if ((src + 1) >= src_end) 1378 if ((src + 1) >= src_end)
1359 goto ccl_read_multibyte_character_suspend; 1379 goto ccl_read_multibyte_character_suspend;
1360 reg[RRR] = *src++; 1380 reg[RRR] = *src++;
1361 reg[rrr] = (*src++ & 0x7F); 1381 reg[rrr] = (*src++ & 0xFF);
1362 } 1382 }
1363 else if (i == PRE_LEADING_BYTE_PRIVATE_2) 1383 else if (i == PRE_LEADING_BYTE_PRIVATE_2)
1364 { 1384 {
1365 if ((src + 2) >= src_end) 1385 if ((src + 2) >= src_end)
1366 goto ccl_read_multibyte_character_suspend; 1386 goto ccl_read_multibyte_character_suspend;
1436 1456
1437 case CCL_TranslateCharacterConstTbl: 1457 case CCL_TranslateCharacterConstTbl:
1438 #if 0 1458 #if 0
1439 /* XEmacs does not have translate_char or an equivalent. We 1459 /* XEmacs does not have translate_char or an equivalent. We
1440 do nothing on this operation. */ 1460 do nothing on this operation. */
1441 op = XINT (ccl_prog[ic]); /* table */ 1461 op = XCHAR_OR_INT (ccl_prog[ic]); /* table */
1442 ic++; 1462 ic++;
1443 CCL_MAKE_CHAR (reg[RRR], reg[rrr], i); 1463 CCL_MAKE_CHAR (reg[RRR], reg[rrr], i);
1444 op = translate_char (GET_TRANSLATION_TABLE (op), i, -1, 0, 0); 1464 op = translate_char (GET_TRANSLATION_TABLE (op), i, -1, 0, 0);
1445 SPLIT_CHAR (op, reg[RRR], i, j); 1465 SPLIT_CHAR (op, reg[RRR], i, j);
1446 if (j != -1) 1466 if (j != -1)
1452 1472
1453 case CCL_MuleToUnicode: 1473 case CCL_MuleToUnicode:
1454 { 1474 {
1455 Lisp_Object ucs; 1475 Lisp_Object ucs;
1456 1476
1457 CCL_MAKE_CHAR(reg[rrr], reg[RRR], op); 1477 CCL_MAKE_CHAR (reg[rrr], reg[RRR], op);
1478
1458 ucs = Fchar_to_unicode(make_char(op)); 1479 ucs = Fchar_to_unicode(make_char(op));
1459 1480
1460 if (NILP(ucs)) 1481 if (NILP(ucs))
1461 { 1482 {
1462 /* Uhh, char-to-unicode doesn't return nil at the 1483 /* Uhh, char-to-unicode doesn't return nil at the
1463 moment, only ever -1. */ 1484 moment, only ever -1. */
1464 reg[rrr] = 0xFFFD; /* REPLACEMENT CHARACTER */ 1485 reg[rrr] = 0xFFFD; /* REPLACEMENT CHARACTER */
1465 } 1486 }
1466 else 1487 else
1467 { 1488 {
1468 reg[rrr] = XINT(ucs); 1489 reg[rrr] = XCHAR_OR_INT(ucs);
1469 if (-1 == reg[rrr]) 1490 if (-1 == reg[rrr])
1470 { 1491 {
1471 reg[rrr] = 0xFFFD; /* REPLACEMENT CHARACTER */ 1492 reg[rrr] = 0xFFFD; /* REPLACEMENT CHARACTER */
1472 } 1493 }
1473 } 1494 }
1486 BREAKUP_ICHAR (op, scratch, i, j); 1507 BREAKUP_ICHAR (op, scratch, i, j);
1487 reg[RRR] = XCHARSET_ID(scratch); 1508 reg[RRR] = XCHARSET_ID(scratch);
1488 1509
1489 if (j != 0) 1510 if (j != 0)
1490 { 1511 {
1491 i = (i << 8) | j; 1512 i = (i << 7) | j;
1492 } 1513 }
1493 1514
1494 reg[rrr] = i; 1515 reg[rrr] = i;
1495 } 1516 }
1496 else 1517 else
1497 { 1518 {
1498 reg[rrr] = reg[RRR] = 0; 1519 reg[rrr] = reg[RRR] = 0;
1499 } 1520 }
1500 break; 1521 break;
1501 } 1522 }
1523
1524 case CCL_LookupIntConstTbl:
1525 op = XCHAR_OR_INT (ccl_prog[ic]); /* table */
1526 ic++;
1527 {
1528 struct Lisp_Hash_Table *h = GET_HASH_TABLE (op);
1529 htentry *e = find_htentry(make_int (reg[RRR]), h);
1530 Lisp_Object scratch;
1531
1532 if (!HTENTRY_CLEAR_P(e))
1533 {
1534 op = XCHARVAL (e->value);
1535 if (!valid_ichar_p(op))
1536 {
1537 CCL_INVALID_CMD;
1538 }
1539
1540 BREAKUP_ICHAR (op, scratch, i, j);
1541 reg[RRR] = XCHARSET_ID(scratch);
1542
1543 if (j != 0)
1544 {
1545 i = (i << 7) | j;
1546 }
1547 reg[rrr] = i;
1548 reg[7] = 1; /* r7 true for success */
1549 }
1550 else
1551 reg[7] = 0;
1552 }
1553 break;
1554
1555 case CCL_LookupCharConstTbl:
1556 op = XCHAR_OR_INT (ccl_prog[ic]); /* table */
1557 ic++;
1558 CCL_MAKE_CHAR (reg[RRR], reg[rrr], i);
1559 {
1560 struct Lisp_Hash_Table *h = GET_HASH_TABLE (op);
1561 htentry *e = find_htentry(make_int(i), h);
1562
1563 if (!HTENTRY_CLEAR_P(e))
1564 {
1565 op = e->value;
1566 if (!INTP (op))
1567 CCL_INVALID_CMD;
1568 reg[RRR] = XCHAR_OR_INT (op);
1569 reg[7] = 1; /* r7 true for success */
1570 }
1571 else
1572 reg[7] = 0;
1573 }
1574 break;
1575
1502 1576
1503 case CCL_IterateMultipleMap: 1577 case CCL_IterateMultipleMap:
1504 { 1578 {
1505 Lisp_Object map, content, attrib, value; 1579 Lisp_Object map, content, attrib, value;
1506 int point, size, fin_ic; 1580 int point, size, fin_ic;
1507 1581
1508 j = XINT (ccl_prog[ic++]); /* number of maps. */ 1582 j = XCHAR_OR_INT (ccl_prog[ic++]); /* number of maps. */
1509 fin_ic = ic + j; 1583 fin_ic = ic + j;
1510 op = reg[rrr]; 1584 op = reg[rrr];
1511 if ((j > reg[RRR]) && (j >= 0)) 1585 if ((j > reg[RRR]) && (j >= 0))
1512 { 1586 {
1513 ic += reg[RRR]; 1587 ic += reg[RRR];
1521 } 1595 }
1522 1596
1523 for (;i < j;i++) 1597 for (;i < j;i++)
1524 { 1598 {
1525 size = XVECTOR (Vcode_conversion_map_vector)->size; 1599 size = XVECTOR (Vcode_conversion_map_vector)->size;
1526 point = XINT (ccl_prog[ic++]); 1600 point = XCHAR_OR_INT (ccl_prog[ic++]);
1527 if (point >= size) continue; 1601 if (point >= size) continue;
1528 map = 1602 map =
1529 XVECTOR (Vcode_conversion_map_vector)->contents[point]; 1603 XVECTOR (Vcode_conversion_map_vector)->contents[point];
1530 1604
1531 /* Check map validity. */ 1605 /* Check map validity. */
1567 if (NILP (content)) 1641 if (NILP (content))
1568 continue; 1642 continue;
1569 else if (INTP (content)) 1643 else if (INTP (content))
1570 { 1644 {
1571 reg[RRR] = i; 1645 reg[RRR] = i;
1572 reg[rrr] = XINT(content); 1646 reg[rrr] = XCHAR_OR_INT(content);
1573 break; 1647 break;
1574 } 1648 }
1575 else if (EQ (content, Qt) || EQ (content, Qlambda)) 1649 else if (EQ (content, Qt) || EQ (content, Qlambda))
1576 { 1650 {
1577 reg[RRR] = i; 1651 reg[RRR] = i;
1618 else 1692 else
1619 mapping_stack_pointer = mapping_stack; 1693 mapping_stack_pointer = mapping_stack;
1620 stack_idx_of_map_multiple = 0; 1694 stack_idx_of_map_multiple = 0;
1621 1695
1622 map_set_rest_length = 1696 map_set_rest_length =
1623 XINT (ccl_prog[ic++]); /* number of maps and separators. */ 1697 XCHAR_OR_INT (ccl_prog[ic++]); /* number of maps and separators. */
1624 fin_ic = ic + map_set_rest_length; 1698 fin_ic = ic + map_set_rest_length;
1625 op = reg[rrr]; 1699 op = reg[rrr];
1626 1700
1627 if ((map_set_rest_length > reg[RRR]) && (reg[RRR] >= 0)) 1701 if ((map_set_rest_length > reg[RRR]) && (reg[RRR] >= 0))
1628 { 1702 {
1686 map_vector_size = XVECTOR (Vcode_conversion_map_vector)->size; 1760 map_vector_size = XVECTOR (Vcode_conversion_map_vector)->size;
1687 1761
1688 do { 1762 do {
1689 for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--) 1763 for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--)
1690 { 1764 {
1691 point = XINT(ccl_prog[ic]); 1765 point = XCHAR_OR_INT(ccl_prog[ic]);
1692 if (point < 0) 1766 if (point < 0)
1693 { 1767 {
1694 /* +1 is for including separator. */ 1768 /* +1 is for including separator. */
1695 point = -point + 1; 1769 point = -point + 1;
1696 if (mapping_stack_pointer 1770 if (mapping_stack_pointer
1747 continue; 1821 continue;
1748 1822
1749 reg[RRR] = i; 1823 reg[RRR] = i;
1750 if (INTP (content)) 1824 if (INTP (content))
1751 { 1825 {
1752 op = XINT (content); 1826 op = XCHAR_OR_INT (content);
1753 i += map_set_rest_length - 1; 1827 i += map_set_rest_length - 1;
1754 ic += map_set_rest_length - 1; 1828 ic += map_set_rest_length - 1;
1755 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); 1829 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
1756 map_set_rest_length++; 1830 map_set_rest_length++;
1757 } 1831 }
1805 1879
1806 case CCL_MapSingle: 1880 case CCL_MapSingle:
1807 { 1881 {
1808 Lisp_Object map, attrib, value, content; 1882 Lisp_Object map, attrib, value, content;
1809 int size, point; 1883 int size, point;
1810 j = XINT (ccl_prog[ic++]); /* map_id */ 1884 j = XCHAR_OR_INT (ccl_prog[ic++]); /* map_id */
1811 op = reg[rrr]; 1885 op = reg[rrr];
1812 if (j >= XVECTOR (Vcode_conversion_map_vector)->size) 1886 if (j >= XVECTOR (Vcode_conversion_map_vector)->size)
1813 { 1887 {
1814 reg[RRR] = -1; 1888 reg[RRR] = -1;
1815 break; 1889 break;
1838 reg[RRR] = 0; 1912 reg[RRR] = 0;
1839 content = XVECTOR (map)->contents[point]; 1913 content = XVECTOR (map)->contents[point];
1840 if (NILP (content)) 1914 if (NILP (content))
1841 reg[RRR] = -1; 1915 reg[RRR] = -1;
1842 else if (INTP (content)) 1916 else if (INTP (content))
1843 reg[rrr] = XINT (content); 1917 reg[rrr] = XCHAR_OR_INT (content);
1844 else if (EQ (content, Qt)); 1918 else if (EQ (content, Qt));
1845 else if (CONSP (content)) 1919 else if (CONSP (content))
1846 { 1920 {
1847 attrib = XCAR (content); 1921 attrib = XCAR (content);
1848 value = XCDR (content); 1922 value = XCDR (content);
1941 veclen = XVECTOR (result)->size; 2015 veclen = XVECTOR (result)->size;
1942 2016
1943 for (i = 0; i < veclen; i++) 2017 for (i = 0; i < veclen; i++)
1944 { 2018 {
1945 contents = XVECTOR (result)->contents[i]; 2019 contents = XVECTOR (result)->contents[i];
1946 if (INTP (contents)) 2020 /* XEmacs change; accept characters as well as integers, on the basis
2021 that most CCL code written doesn't make a distinction. */
2022 if (INTP (contents) || CHARP(contents))
1947 continue; 2023 continue;
1948 else if (CONSP (contents) 2024 else if (CONSP (contents)
1949 && SYMBOLP (XCAR (contents)) 2025 && SYMBOLP (XCAR (contents))
1950 && SYMBOLP (XCDR (contents))) 2026 && SYMBOLP (XCDR (contents)))
1951 { 2027 {
2105 CHECK_VECTOR (reg); 2181 CHECK_VECTOR (reg);
2106 if (XVECTOR_LENGTH (reg) != 8) 2182 if (XVECTOR_LENGTH (reg) != 8)
2107 syntax_error ("Length of vector REGISTERS is not 8", Qunbound); 2183 syntax_error ("Length of vector REGISTERS is not 8", Qunbound);
2108 2184
2109 for (i = 0; i < 8; i++) 2185 for (i = 0; i < 8; i++)
2110 ccl.reg[i] = (INTP (XVECTOR_DATA (reg)[i]) 2186 ccl.reg[i] = (INTP (XVECTOR_DATA (reg)[i]) || CHARP (XVECTOR_DATA (reg)[i])
2111 ? XINT (XVECTOR_DATA (reg)[i]) 2187 ? XCHAR_OR_INT (XVECTOR_DATA (reg)[i])
2112 : 0); 2188 : 0);
2113 2189
2114 ccl_driver (&ccl, (const unsigned char *)0, 2190 ccl_driver (&ccl, (const unsigned char *)0,
2115 (unsigned_char_dynarr *)0, 0, (int *)0, 2191 (unsigned_char_dynarr *)0, 0, (int *)0,
2116 CCL_MODE_ENCODING); 2192 CCL_MODE_ENCODING);
2170 { 2246 {
2171 if (NILP (XVECTOR_DATA (status)[i])) 2247 if (NILP (XVECTOR_DATA (status)[i]))
2172 XVECTOR_DATA (status)[i] = make_int (0); 2248 XVECTOR_DATA (status)[i] = make_int (0);
2173 if (INTP (XVECTOR_DATA (status)[i])) 2249 if (INTP (XVECTOR_DATA (status)[i]))
2174 ccl.reg[i] = XINT (XVECTOR_DATA (status)[i]); 2250 ccl.reg[i] = XINT (XVECTOR_DATA (status)[i]);
2251 if (CHARP (XVECTOR_DATA (status)[i]))
2252 ccl.reg[i] = XCHAR (XVECTOR_DATA (status)[i]);
2175 } 2253 }
2176 if (INTP (XVECTOR (status)->contents[i])) 2254 if (INTP (XVECTOR (status)->contents[i]) ||
2255 CHARP (XVECTOR (status)->contents[i]))
2177 { 2256 {
2178 i = XINT (XVECTOR_DATA (status)[8]); 2257 i = XCHAR_OR_INT (XVECTOR_DATA (status)[8]);
2179 if (ccl.ic < i && i < ccl.size) 2258 if (ccl.ic < i && i < ccl.size)
2180 ccl.ic = i; 2259 ccl.ic = i;
2181 } 2260 }
2182 outbuf = Dynarr_new (unsigned_char); 2261 outbuf = Dynarr_new (unsigned_char);
2183 ccl.last_block = NILP (continue_); 2262 ccl.last_block = NILP (continue_);
2345 } 2424 }
2346 2425
2347 void 2426 void
2348 vars_of_mule_ccl (void) 2427 vars_of_mule_ccl (void)
2349 { 2428 {
2429
2350 staticpro (&Vccl_program_table); 2430 staticpro (&Vccl_program_table);
2351 Vccl_program_table = Fmake_vector (make_int (32), Qnil); 2431 Vccl_program_table = Fmake_vector (make_int (32), Qnil);
2352 2432
2433 #ifdef DEBUG_XEMACS
2434 DEFVAR_LISP ("ccl-program-table",
2435 &Vccl_program_table /*
2436 Vector containing all registered CCL programs.
2437 */ );
2438 #endif
2353 DEFSYMBOL (Qccl_program); 2439 DEFSYMBOL (Qccl_program);
2354 DEFSYMBOL (Qccl_program_idx); 2440 DEFSYMBOL (Qccl_program_idx);
2355 DEFSYMBOL (Qcode_conversion_map); 2441 DEFSYMBOL (Qcode_conversion_map);
2356 DEFSYMBOL (Qcode_conversion_map_id); 2442 DEFSYMBOL (Qcode_conversion_map_id);
2357 2443
2358 DEFVAR_LISP ("code-conversion-map-vector", &Vcode_conversion_map_vector /* 2444 DEFVAR_LISP ("code-conversion-map-vector", &Vcode_conversion_map_vector /*
2359 Vector of code conversion maps. 2445 Vector of code conversion maps.
2360 */ ); 2446 */ );
2361 Vcode_conversion_map_vector = Fmake_vector (make_int (16), Qnil); 2447 Vcode_conversion_map_vector = Fmake_vector (make_int (16), Qnil);
2362 2448
2363 DEFVAR_LISP ("font-ccl-encoder-alist", &Vfont_ccl_encoder_alist /* 2449 DEFVAR_LISP ("translation-hash-table-vector",
2364 Alist of fontname patterns vs corresponding CCL program. 2450 &Vtranslation_hash_table_vector /*
2365 Each element looks like (REGEXP . CCL-CODE), 2451 Vector containing all translation hash tables ever defined.
2366 where CCL-CODE is a compiled CCL program. 2452 Comprises pairs (SYMBOL . TABLE) where SYMBOL and TABLE were set up by calls
2367 When a font whose name matches REGEXP is used for displaying a character, 2453 to `define-translation-hash-table'. The vector is indexed by the table id
2368 CCL-CODE is executed to calculate the code point in the font 2454 used by CCL.
2369 from the charset number and position code(s) of the character which are set
2370 in CCL registers R0, R1, and R2 before the execution.
2371 The code point in the font is set in CCL registers R1 and R2
2372 when the execution terminated.
2373 If the font is single-byte font, the register R2 is not used.
2374 */ ); 2455 */ );
2375 Vfont_ccl_encoder_alist = Qnil; 2456 Vtranslation_hash_table_vector = Qnil;
2457
2376 } 2458 }
2377 2459
2378 #endif /* emacs */ 2460 #endif /* emacs */