771 |
CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC); \ |
CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC); \ |
772 |
} while (0) |
} while (0) |
773 |
|
|
774 |
|
/* Decode CODE by a charset whose id is ID. If ID is 0, return CODE |
775 |
|
as is for backward compatibility. Assume that we can use the |
776 |
|
variable `charset'. */ |
777 |
|
|
778 |
|
#define CCL_DECODE_CHAR(id, code) \ |
779 |
|
((id) == 0 ? (code) \ |
780 |
|
: (charset = CHARSET_FROM_ID ((id)), DECODE_CHAR (charset, (code)))) |
781 |
|
|
782 |
|
|
783 |
|
/* Encode character C by some of charsets in CHARSET_LIST. Set ID to |
784 |
|
the id of the used charset, ENCODED to the resulf of encoding. |
785 |
|
Assume that we can use the variable `charset'. */ |
786 |
|
|
787 |
|
#define CCL_ENCODE_CHAR(c, charset_list, id, encoded) \ |
788 |
|
do { \ |
789 |
|
unsigned code; \ |
790 |
|
\ |
791 |
|
charset = char_charset ((c), (charset_list), &code); \ |
792 |
|
if (! charset && ! NILP (charset_list)) \ |
793 |
|
charset = char_charset ((c), Qnil, &code); \ |
794 |
|
if (charset) \ |
795 |
|
{ \ |
796 |
|
(id) = CHARSET_ID (charset); \ |
797 |
|
(encoded) = code; \ |
798 |
|
} \ |
799 |
|
} while (0) |
800 |
|
|
801 |
|
|
802 |
|
|
803 |
/* Execute CCL code on characters at SOURCE (length SRC_SIZE). The |
/* Execute CCL code on characters at SOURCE (length SRC_SIZE). The |
804 |
resulting text goes to a place pointed by DESTINATION, the length |
resulting text goes to a place pointed by DESTINATION, the length |
824 |
static struct ccl_prog_stack ccl_prog_stack_struct[256]; |
static struct ccl_prog_stack ccl_prog_stack_struct[256]; |
825 |
|
|
826 |
void |
void |
827 |
ccl_driver (ccl, source, destination, src_size, dst_size) |
ccl_driver (ccl, source, destination, src_size, dst_size, charset_list) |
828 |
struct ccl_program *ccl; |
struct ccl_program *ccl; |
829 |
int *source, *destination; |
int *source, *destination; |
830 |
int src_size, dst_size; |
int src_size, dst_size; |
831 |
|
Lisp_Object charset_list; |
832 |
{ |
{ |
833 |
register int *reg = ccl->reg; |
register int *reg = ccl->reg; |
834 |
register int ic = ccl->ic; |
register int ic = ccl->ic; |
1223 |
if (!src) |
if (!src) |
1224 |
CCL_INVALID_CMD; |
CCL_INVALID_CMD; |
1225 |
CCL_READ_CHAR (i); |
CCL_READ_CHAR (i); |
1226 |
charset = CHAR_CHARSET (i); |
CCL_ENCODE_CHAR (i, charset_list, reg[RRR], reg[rrr]); |
|
reg[rrr] = CHARSET_ID (charset); |
|
|
reg[RRR] = ENCODE_CHAR (charset, i); |
|
1227 |
break; |
break; |
1228 |
|
|
1229 |
case CCL_WriteMultibyteChar2: |
case CCL_WriteMultibyteChar2: |
1230 |
if (! dst) |
if (! dst) |
1231 |
CCL_INVALID_CMD; |
CCL_INVALID_CMD; |
1232 |
charset = CHARSET_FROM_ID (reg[RRR]); |
i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); |
|
i = DECODE_CHAR (charset, reg[rrr]); |
|
1233 |
CCL_WRITE_CHAR (i); |
CCL_WRITE_CHAR (i); |
1234 |
break; |
break; |
1235 |
|
|
1236 |
case CCL_TranslateCharacter: |
case CCL_TranslateCharacter: |
1237 |
charset = CHARSET_FROM_ID (reg[RRR]); |
i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); |
|
i = DECODE_CHAR (charset, reg[rrr]); |
|
1238 |
op = translate_char (GET_TRANSLATION_TABLE (reg[Rrr]), i); |
op = translate_char (GET_TRANSLATION_TABLE (reg[Rrr]), i); |
1239 |
charset = CHAR_CHARSET (op); |
CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]); |
|
reg[RRR] = CHARSET_ID (charset); |
|
|
reg[rrr] = ENCODE_CHAR (charset, op); |
|
1240 |
break; |
break; |
1241 |
|
|
1242 |
case CCL_TranslateCharacterConstTbl: |
case CCL_TranslateCharacterConstTbl: |
1243 |
op = XINT (ccl_prog[ic]); /* table */ |
op = XINT (ccl_prog[ic]); /* table */ |
1244 |
ic++; |
ic++; |
1245 |
charset = CHARSET_FROM_ID (reg[RRR]); |
i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); |
|
i = DECODE_CHAR (charset, reg[rrr]); |
|
1246 |
op = translate_char (GET_TRANSLATION_TABLE (op), i); |
op = translate_char (GET_TRANSLATION_TABLE (op), i); |
1247 |
charset = CHAR_CHARSET (op); |
CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]); |
|
reg[RRR] = CHARSET_ID (charset); |
|
|
reg[rrr] = ENCODE_CHAR (charset, op); |
|
1248 |
break; |
break; |
1249 |
|
|
1250 |
case CCL_LookupIntConstTbl: |
case CCL_LookupIntConstTbl: |
1260 |
opl = HASH_VALUE (h, op); |
opl = HASH_VALUE (h, op); |
1261 |
if (!CHARACTERP (opl)) |
if (!CHARACTERP (opl)) |
1262 |
CCL_INVALID_CMD; |
CCL_INVALID_CMD; |
1263 |
reg[rrr] = ENCODE_CHAR (CHAR_CHARSET (charset_unicode), |
reg[RRR] = charset_unicode; |
1264 |
op); |
reg[rrr] = op; |
1265 |
reg[7] = 1; /* r7 true for success */ |
reg[7] = 1; /* r7 true for success */ |
1266 |
} |
} |
1267 |
else |
else |
1272 |
case CCL_LookupCharConstTbl: |
case CCL_LookupCharConstTbl: |
1273 |
op = XINT (ccl_prog[ic]); /* table */ |
op = XINT (ccl_prog[ic]); /* table */ |
1274 |
ic++; |
ic++; |
1275 |
charset = CHARSET_FROM_ID (reg[RRR]); |
i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); |
|
i = DECODE_CHAR (charset, reg[rrr]); |
|
1276 |
{ |
{ |
1277 |
struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); |
struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); |
1278 |
|
|
1928 |
? XINT (AREF (reg, i)) |
? XINT (AREF (reg, i)) |
1929 |
: 0); |
: 0); |
1930 |
|
|
1931 |
ccl_driver (&ccl, NULL, NULL, 0, 0); |
ccl_driver (&ccl, NULL, NULL, 0, 0, Qnil); |
1932 |
QUIT; |
QUIT; |
1933 |
if (ccl.status != CCL_STAT_SUCCESS) |
if (ccl.status != CCL_STAT_SUCCESS) |
1934 |
error ("Error in CCL program at %dth code", ccl.ic); |
error ("Error in CCL program at %dth code", ccl.ic); |
2030 |
src_size = i; |
src_size = i; |
2031 |
while (1) |
while (1) |
2032 |
{ |
{ |
2033 |
ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE); |
ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE, |
2034 |
|
Qnil); |
2035 |
if (ccl.status != CCL_STAT_SUSPEND_BY_DST) |
if (ccl.status != CCL_STAT_SUSPEND_BY_DST) |
2036 |
break; |
break; |
2037 |
produced_chars += ccl.produced; |
produced_chars += ccl.produced; |