X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/cafdcef32d55cbb44389d7e322e7f973cbb72dfd..d3cfca60276d7d1e29cb2ee5e7729141b86b2fb5:/src/ccl.c diff --git a/src/ccl.c b/src/ccl.c index 5428e94c69..01943eddf5 100644 --- a/src/ccl.c +++ b/src/ccl.c @@ -27,6 +27,7 @@ along with GNU Emacs. If not, see . */ #include #include +#include #include "lisp.h" #include "character.h" @@ -38,16 +39,16 @@ Lisp_Object Qccl, Qcclp; /* This symbol is a property which associates with ccl program vector. Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector. */ -Lisp_Object Qccl_program; +static Lisp_Object Qccl_program; /* These symbols are properties which associate with code conversion map and their ID respectively. */ -Lisp_Object Qcode_conversion_map; -Lisp_Object Qcode_conversion_map_id; +static Lisp_Object Qcode_conversion_map; +static Lisp_Object Qcode_conversion_map_id; /* Symbols of ccl program have this property, a value of the property is an index for Vccl_protram_table. */ -Lisp_Object Qccl_program_idx; +static Lisp_Object Qccl_program_idx; /* Table of registered CCL programs. Each element is a vector of NAME, CCL_PROG, RESOLVEDP, and UPDATEDP, where NAME (symbol) is the @@ -56,11 +57,11 @@ Lisp_Object Qccl_program_idx; CCL_PROG is already resolved to index numbers or not, UPDATEDP (t or nil) is the flat to tell if the CCL program is updated after it was once used. */ -Lisp_Object Vccl_program_table; +static Lisp_Object Vccl_program_table; /* Return a hash table of id number ID. */ #define GET_HASH_TABLE(id) \ - (XHASH_TABLE (XCDR(XVECTOR(Vtranslation_hash_table_vector)->contents[(id)]))) + (XHASH_TABLE (XCDR (XVECTOR (Vtranslation_hash_table_vector)->contents[(id)]))) /* CCL (Code Conversion Language) is a simple language which has operations on one input buffer, one output buffer, and 7 registers. @@ -78,9 +79,8 @@ Lisp_Object Vccl_program_table; #define CCL_HEADER_EOF 1 #define CCL_HEADER_MAIN 2 -/* CCL code is a sequence of 28-bit non-negative integers (i.e. the - MSB is always 0), each contains CCL command and/or arguments in the - following format: +/* CCL code is a sequence of 28-bit integers. Each contains a CCL + command and/or arguments in the following format: |----------------- integer (28-bit) ------------------| |------- 17-bit ------|- 3-bit --|- 3-bit --|- 5-bit -| @@ -93,11 +93,14 @@ Lisp_Object Vccl_program_table; |------------- constant or other args ----------------| cccccccccccccccccccccccccccc - where, `cc...c' is a non-negative integer indicating constant value - (the left most `c' is always 0) or an absolute jump address, `RRR' + where `cc...c' is a 17-bit, 20-bit, or 28-bit integer indicating a + constant value or a relative/absolute jump address, `RRR' and `rrr' are CCL register number, `XXXXX' is one of the following CCL commands. */ +#define CCL_CODE_MAX ((1 << (28 - 1)) - 1) +#define CCL_CODE_MIN (-1 - CCL_CODE_MAX) + /* CCL commands Each comment fields shows one or more lines for command syntax and @@ -426,7 +429,7 @@ Lisp_Object Vccl_program_table; #define CCL_Extension 0x1F /* Extended CCL code 1:ExtendedCOMMNDRrrRRRrrrXXXXX - 2:ARGUEMENT + 2:ARGUMENT 3:... ------------------------------ extended_command (rrr,RRR,Rrr,ARGS) @@ -703,7 +706,7 @@ do \ ccl->status = CCL_STAT_SUCCESS; \ goto ccl_finish; \ } \ -while(0) +while (0) /* Suspend CCL program because of reading from empty input buffer or writing to full output buffer. When this program is resumed, the @@ -727,7 +730,7 @@ do \ ccl->status = CCL_STAT_INVALID_CMD; \ goto ccl_error_handler; \ } \ -while(0) +while (0) #else @@ -738,10 +741,32 @@ do \ ccl->status = CCL_STAT_INVALID_CMD; \ goto ccl_error_handler; \ } \ -while(0) +while (0) #endif +/* Use "&" rather than "&&" to suppress a bogus GCC warning; see + . */ +#define ASCENDING_ORDER(lo, med, hi) (((lo) <= (med)) & ((med) <= (hi))) + +#define GET_CCL_RANGE(var, ccl_prog, ic, lo, hi) \ + do \ + { \ + EMACS_INT prog_word = XINT ((ccl_prog)[ic]); \ + if (! ASCENDING_ORDER (lo, prog_word, hi)) \ + CCL_INVALID_CMD; \ + (var) = prog_word; \ + } \ + while (0) + +#define GET_CCL_CODE(code, ccl_prog, ic) \ + GET_CCL_RANGE (code, ccl_prog, ic, CCL_CODE_MIN, CCL_CODE_MAX) + +#define GET_CCL_INT(var, ccl_prog, ic) \ + GET_CCL_RANGE (var, ccl_prog, ic, INT_MIN, INT_MAX) + +#define IN_INT_RANGE(val) ASCENDING_ORDER (INT_MIN, val, INT_MAX) + /* Encode one character CH to multibyte form and write to the current output buffer. If CH is less than 256, CH is written as is. */ #define CCL_WRITE_CHAR(ch) \ @@ -899,7 +924,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size } this_ic = ic; - code = XINT (ccl_prog[ic]); ic++; + GET_CCL_CODE (code, ccl_prog, ic++); field1 = code >> 8; field2 = (code & 0xFF) >> 5; @@ -920,15 +945,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size break; case CCL_SetConst: /* 00000000000000000000rrrXXXXX */ - reg[rrr] = XINT (ccl_prog[ic]); - ic++; + GET_CCL_INT (reg[rrr], ccl_prog, ic++); break; case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */ i = reg[RRR]; j = field1 >> 3; - if ((unsigned int) i < j) - reg[rrr] = XINT (ccl_prog[ic + i]); + if (0 <= i && i < j) + GET_CCL_INT (reg[rrr], ccl_prog, ic + i); ic += j; break; @@ -956,13 +980,13 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size break; case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */ - i = XINT (ccl_prog[ic]); + GET_CCL_INT (i, ccl_prog, ic); CCL_WRITE_CHAR (i); ic += ADDR; break; case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ - i = XINT (ccl_prog[ic]); + GET_CCL_INT (i, ccl_prog, ic); CCL_WRITE_CHAR (i); ic++; CCL_READ_CHAR (reg[rrr]); @@ -970,18 +994,17 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size break; case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */ - j = XINT (ccl_prog[ic]); - ic++; + GET_CCL_INT (j, ccl_prog, ic++); CCL_WRITE_STRING (j); ic += ADDR - 1; break; case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ i = reg[rrr]; - j = XINT (ccl_prog[ic]); - if ((unsigned int) i < j) + GET_CCL_INT (j, ccl_prog, ic); + if (0 <= i && i < j) { - i = XINT (ccl_prog[ic + 1 + i]); + GET_CCL_INT (i, ccl_prog, ic + 1 + i); CCL_WRITE_CHAR (i); } ic += j + 2; @@ -998,10 +1021,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size CCL_READ_CHAR (reg[rrr]); /* fall through ... */ case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ - if ((unsigned int) reg[rrr] < field1) - ic += XINT (ccl_prog[ic + reg[rrr]]); - else - ic += XINT (ccl_prog[ic + field1]); + { + int incr; + GET_CCL_INT (incr, ccl_prog, + ic + (0 <= reg[rrr] && reg[rrr] < field1 + ? reg[rrr] + : field1)); + ic += incr; + } break; case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */ @@ -1009,7 +1036,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size { CCL_READ_CHAR (reg[rrr]); if (!field1) break; - code = XINT (ccl_prog[ic]); ic++; + GET_CCL_CODE (code, ccl_prog, ic++); field1 = code >> 8; field2 = (code & 0xFF) >> 5; } @@ -1018,7 +1045,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */ rrr = 7; i = reg[RRR]; - j = XINT (ccl_prog[ic]); + GET_CCL_INT (j, ccl_prog, ic); op = field1 >> 6; jump_address = ic + 1; goto ccl_set_expr; @@ -1029,7 +1056,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size i = reg[rrr]; CCL_WRITE_CHAR (i); if (!field1) break; - code = XINT (ccl_prog[ic]); ic++; + GET_CCL_CODE (code, ccl_prog, ic++); field1 = code >> 8; field2 = (code & 0xFF) >> 5; } @@ -1051,10 +1078,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size /* If FFF is nonzero, the CCL program ID is in the following code. */ if (rrr) - { - prog_id = XINT (ccl_prog[ic]); - ic++; - } + GET_CCL_INT (prog_id, ccl_prog, ic++); else prog_id = field1; @@ -1095,9 +1119,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_WriteArray: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ i = reg[rrr]; - if ((unsigned int) i < field1) + if (0 <= i && i < field1) { - j = XINT (ccl_prog[ic + i]); + GET_CCL_INT (j, ccl_prog, ic + i); CCL_WRITE_CHAR (j); } ic += field1; @@ -1122,8 +1146,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size CCL_SUCCESS; case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */ - i = XINT (ccl_prog[ic]); - ic++; + GET_CCL_INT (i, ccl_prog, ic++); op = field1 >> 6; goto ccl_expr_self; @@ -1159,9 +1182,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */ i = reg[RRR]; - j = XINT (ccl_prog[ic]); + GET_CCL_INT (j, ccl_prog, ic++); op = field1 >> 6; - jump_address = ++ic; + jump_address = ic; goto ccl_set_expr; case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */ @@ -1175,10 +1198,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size CCL_READ_CHAR (reg[rrr]); case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ i = reg[rrr]; - op = XINT (ccl_prog[ic]); - jump_address = ic++ + ADDR; - j = XINT (ccl_prog[ic]); - ic++; + jump_address = ic + ADDR; + GET_CCL_INT (op, ccl_prog, ic++); + GET_CCL_INT (j, ccl_prog, ic++); rrr = 7; goto ccl_set_expr; @@ -1186,10 +1208,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size CCL_READ_CHAR (reg[rrr]); case CCL_JumpCondExprReg: i = reg[rrr]; - op = XINT (ccl_prog[ic]); - jump_address = ic++ + ADDR; - j = reg[XINT (ccl_prog[ic])]; - ic++; + jump_address = ic + ADDR; + GET_CCL_INT (op, ccl_prog, ic++); + GET_CCL_RANGE (j, ccl_prog, ic++, 0, 7); + j = reg[j]; rrr = 7; ccl_set_expr: @@ -1267,28 +1289,37 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size break; case CCL_TranslateCharacterConstTbl: - op = XINT (ccl_prog[ic]); /* table */ - ic++; - i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); - op = translate_char (GET_TRANSLATION_TABLE (op), i); - CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]); + { + EMACS_INT eop; + GET_CCL_RANGE (eop, ccl_prog, ic++, 0, + (VECTORP (Vtranslation_table_vector) + ? ASIZE (Vtranslation_table_vector) + : -1)); + i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); + op = translate_char (GET_TRANSLATION_TABLE (eop), i); + CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]); + } break; case CCL_LookupIntConstTbl: - op = XINT (ccl_prog[ic]); /* table */ - ic++; { - struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); - - op = hash_lookup (h, make_number (reg[RRR]), NULL); - if (op >= 0) + ptrdiff_t eop; + struct Lisp_Hash_Table *h; + GET_CCL_RANGE (eop, ccl_prog, ic++, 0, + (VECTORP (Vtranslation_hash_table_vector) + ? ASIZE (Vtranslation_hash_table_vector) + : -1)); + h = GET_HASH_TABLE (eop); + + eop = hash_lookup (h, make_number (reg[RRR]), NULL); + if (eop >= 0) { Lisp_Object opl; - opl = HASH_VALUE (h, op); - if (! CHARACTERP (opl)) + opl = HASH_VALUE (h, eop); + if (! (IN_INT_RANGE (eop) && CHARACTERP (opl))) CCL_INVALID_CMD; reg[RRR] = charset_unicode; - reg[rrr] = op; + reg[rrr] = eop; reg[7] = 1; /* r7 true for success */ } else @@ -1297,18 +1328,22 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size break; case CCL_LookupCharConstTbl: - op = XINT (ccl_prog[ic]); /* table */ - ic++; - i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); { - struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); - - op = hash_lookup (h, make_number (i), NULL); - if (op >= 0) + ptrdiff_t eop; + struct Lisp_Hash_Table *h; + GET_CCL_RANGE (eop, ccl_prog, ic++, 0, + (VECTORP (Vtranslation_hash_table_vector) + ? ASIZE (Vtranslation_hash_table_vector) + : -1)); + i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); + h = GET_HASH_TABLE (eop); + + eop = hash_lookup (h, make_number (i), NULL); + if (eop >= 0) { Lisp_Object opl; - opl = HASH_VALUE (h, op); - if (!INTEGERP (opl)) + opl = HASH_VALUE (h, eop); + if (! (INTEGERP (opl) && IN_INT_RANGE (XINT (opl)))) CCL_INVALID_CMD; reg[RRR] = XINT (opl); reg[7] = 1; /* r7 true for success */ @@ -1321,9 +1356,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_IterateMultipleMap: { Lisp_Object map, content, attrib, value; - int point, size, fin_ic; + EMACS_INT point, size; + int fin_ic; - j = XINT (ccl_prog[ic++]); /* number of maps. */ + GET_CCL_INT (j, ccl_prog, ic++); /* number of maps. */ fin_ic = ic + j; op = reg[rrr]; if ((j > reg[RRR]) && (j >= 0)) @@ -1343,7 +1379,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size size = ASIZE (Vcode_conversion_map_vector); point = XINT (ccl_prog[ic++]); - if (point >= size) continue; + if (! (0 <= point && point < size)) continue; map = AREF (Vcode_conversion_map_vector, point); /* Check map validity. */ @@ -1358,18 +1394,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size /* check map type, [STARTPOINT VAL1 VAL2 ...] or [t ELEMENT STARTPOINT ENDPOINT] */ - if (NUMBERP (content)) + if (INTEGERP (content)) { - point = XUINT (content); - point = op - point + 1; - if (!((point >= 1) && (point < size))) continue; - content = AREF (map, point); + point = XINT (content); + if (!(point <= op && op - point + 1 < size)) continue; + content = AREF (map, op - point + 1); } else if (EQ (content, Qt)) { if (size != 4) continue; - if ((op >= XUINT (AREF (map, 2))) - && (op < XUINT (AREF (map, 3)))) + if (INTEGERP (AREF (map, 2)) + && XINT (AREF (map, 2)) <= op + && INTEGERP (AREF (map, 3)) + && op < XINT (AREF (map, 3))) content = AREF (map, 1); else continue; @@ -1379,10 +1416,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size if (NILP (content)) continue; - else if (NUMBERP (content)) + else if (INTEGERP (content) && IN_INT_RANGE (XINT (content))) { reg[RRR] = i; - reg[rrr] = XINT(content); + reg[rrr] = XINT (content); break; } else if (EQ (content, Qt) || EQ (content, Qlambda)) @@ -1394,10 +1431,11 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size { attrib = XCAR (content); value = XCDR (content); - if (!NUMBERP (attrib) || !NUMBERP (value)) + if (! (INTEGERP (attrib) && INTEGERP (value) + && IN_INT_RANGE (XINT (value)))) continue; reg[RRR] = i; - reg[rrr] = XUINT (value); + reg[rrr] = XINT (value); break; } else if (SYMBOLP (content)) @@ -1432,8 +1470,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size mapping_stack_pointer = mapping_stack; stack_idx_of_map_multiple = 0; - map_set_rest_length = - XINT (ccl_prog[ic++]); /* number of maps and separators. */ + /* Get number of maps and separators. */ + GET_CCL_INT (map_set_rest_length, ccl_prog, ic++); + fin_ic = ic + map_set_rest_length; op = reg[rrr]; @@ -1501,7 +1540,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size do { for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--) { - point = XINT(ccl_prog[ic]); + GET_CCL_INT (point, ccl_prog, ic); if (point < 0) { /* +1 is for including separator. */ @@ -1531,18 +1570,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size /* check map type, [STARTPOINT VAL1 VAL2 ...] or [t ELEMENT STARTPOINT ENDPOINT] */ - if (NUMBERP (content)) + if (INTEGERP (content)) { - point = XUINT (content); - point = op - point + 1; - if (!((point >= 1) && (point < size))) continue; - content = AREF (map, point); + point = XINT (content); + if (!(point <= op && op - point + 1 < size)) continue; + content = AREF (map, op - point + 1); } else if (EQ (content, Qt)) { if (size != 4) continue; - if ((op >= XUINT (AREF (map, 2))) && - (op < XUINT (AREF (map, 3)))) + if (INTEGERP (AREF (map, 2)) + && XINT (AREF (map, 2)) <= op + && INTEGERP (AREF (map, 3)) + && op < XINT (AREF (map, 3))) content = AREF (map, 1); else continue; @@ -1554,7 +1594,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size continue; reg[RRR] = i; - if (NUMBERP (content)) + if (INTEGERP (content) && IN_INT_RANGE (XINT (content))) { op = XINT (content); i += map_set_rest_length - 1; @@ -1566,9 +1606,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size { attrib = XCAR (content); value = XCDR (content); - if (!NUMBERP (attrib) || !NUMBERP (value)) + if (! (INTEGERP (attrib) && INTEGERP (value) + && IN_INT_RANGE (XINT (value)))) continue; - op = XUINT (value); + op = XINT (value); i += map_set_rest_length - 1; ic += map_set_rest_length - 1; POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); @@ -1613,7 +1654,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_MapSingle: { Lisp_Object map, attrib, value, content; - int size, point; + int point; j = XINT (ccl_prog[ic++]); /* map_id */ op = reg[rrr]; if (j >= ASIZE (Vcode_conversion_map_vector)) @@ -1628,41 +1669,36 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size break; } map = XCDR (map); - if (!VECTORP (map)) + if (! (VECTORP (map) + && INTEGERP (AREF (map, 0)) + && XINT (AREF (map, 0)) <= op + && op - XINT (AREF (map, 0)) + 1 < ASIZE (map))) { reg[RRR] = -1; break; } - size = ASIZE (map); - point = XUINT (AREF (map, 0)); + point = XINT (AREF (map, 0)); point = op - point + 1; reg[RRR] = 0; - if ((size <= 1) || - (!((point >= 1) && (point < size)))) + content = AREF (map, point); + if (NILP (content)) reg[RRR] = -1; - else + else if (INTEGERP (content)) + reg[rrr] = XINT (content); + else if (EQ (content, Qt)); + else if (CONSP (content)) { - reg[RRR] = 0; - content = AREF (map, point); - if (NILP (content)) - reg[RRR] = -1; - else if (NUMBERP (content)) - reg[rrr] = XINT (content); - else if (EQ (content, Qt)); - else if (CONSP (content)) - { - attrib = XCAR (content); - value = XCDR (content); - if (!NUMBERP (attrib) || !NUMBERP (value)) - continue; - reg[rrr] = XUINT(value); - break; - } - else if (SYMBOLP (content)) - CCL_CALL_FOR_MAP_INSTRUCTION (content, ic); - else - reg[RRR] = -1; + attrib = XCAR (content); + value = XCDR (content); + if (!INTEGERP (attrib) || !INTEGERP (value)) + continue; + reg[rrr] = XINT (value); + break; } + else if (SYMBOLP (content)) + CCL_CALL_FOR_MAP_INSTRUCTION (content, ic); + else + reg[RRR] = -1; } break; @@ -1693,8 +1729,8 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size switch (ccl->status) { case CCL_STAT_INVALID_CMD: - sprintf(msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", - code & 0x1F, code, this_ic); + sprintf (msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", + code & 0x1F, code, this_ic); #ifdef CCL_DEBUG { int i = ccl_backtrace_idx - 1; @@ -1712,7 +1748,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size if (i < 0) i = CCL_DEBUG_BACKTRACE_LEN - 1; if (ccl_backtrace_table[i] == 0) break; - sprintf(msg, " %d", ccl_backtrace_table[i]); + sprintf (msg, " %d", ccl_backtrace_table[i]); msglen = strlen (msg); if (dst + msglen > (dst_bytes ? dst_end : src)) break; @@ -1726,15 +1762,15 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_STAT_QUIT: if (! ccl->quit_silently) - sprintf(msg, "\nCCL: Quited."); + sprintf (msg, "\nCCL: Quited."); break; default: - sprintf(msg, "\nCCL: Unknown error type (%d)", ccl->status); + sprintf (msg, "\nCCL: Unknown error type (%d)", ccl->status); } msglen = strlen (msg); - if (dst + msglen <= dst_end) + if (msglen <= dst_end - dst) { for (i = 0; i < msglen; i++) *dst++ = msg[i]; @@ -1903,7 +1939,7 @@ setup_ccl_program (struct ccl_program *ccl, Lisp_Object ccl_prog) if (! VECTORP (ccl_prog)) return -1; vp = XVECTOR (ccl_prog); - ccl->size = vp->size; + ccl->size = vp->header.size; ccl->prog = vp->contents; ccl->eof_ic = XINT (vp->contents[CCL_HEADER_EOF]); ccl->buf_magnification = XINT (vp->contents[CCL_HEADER_BUF_MAG]); @@ -1929,30 +1965,6 @@ setup_ccl_program (struct ccl_program *ccl, Lisp_Object ccl_prog) } -/* Check if CCL is updated or not. If not, re-setup members of CCL. */ - -int -check_ccl_update (struct ccl_program *ccl) -{ - Lisp_Object slot, ccl_prog; - - if (ccl->idx < 0) - return 0; - slot = AREF (Vccl_program_table, ccl->idx); - if (NILP (AREF (slot, 3))) - return 0; - ccl_prog = ccl_get_compiled_code (AREF (slot, 0), &ccl->idx); - if (! VECTORP (ccl_prog)) - return -1; - ccl->size = ASIZE (ccl_prog); - ccl->prog = XVECTOR (ccl_prog)->contents; - ccl->eof_ic = XINT (AREF (ccl_prog, CCL_HEADER_EOF)); - ccl->buf_magnification = XINT (AREF (ccl_prog, CCL_HEADER_BUF_MAG)); - ASET (slot, 3, Qnil); - return 0; -} - - DEFUN ("ccl-program-p", Fccl_program_p, Sccl_program_p, 1, 1, 0, doc: /* Return t if OBJECT is a CCL program name or a compiled CCL program code. See the documentation of `define-ccl-program' for the detail of CCL program. */) @@ -2049,12 +2061,13 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY Lisp_Object val; struct ccl_program ccl; int i; - int outbufsize; + ptrdiff_t outbufsize; unsigned char *outbuf, *outp; - EMACS_INT str_chars, str_bytes; + ptrdiff_t str_chars, str_bytes; #define CCL_EXECUTE_BUF_SIZE 1024 int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE]; - EMACS_INT consumed_chars, consumed_bytes, produced_chars; + ptrdiff_t consumed_chars, consumed_bytes, produced_chars; + int buf_magnification; if (setup_ccl_program (&ccl, ccl_prog) < 0) error ("Invalid CCL program"); @@ -2081,6 +2094,10 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY ccl.ic = i; } + buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1; + + if ((min (PTRDIFF_MAX, SIZE_MAX) - 256) / buf_magnification < str_bytes) + memory_full (SIZE_MAX); outbufsize = (ccl.buf_magnification ? str_bytes * ccl.buf_magnification + 256 : str_bytes + 256); @@ -2110,31 +2127,25 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY src_size = j; while (1) { + int max_expansion = NILP (unibyte_p) ? MAX_MULTIBYTE_LENGTH : 1; + ptrdiff_t offset, shortfall; ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE, Qnil); produced_chars += ccl.produced; + offset = outp - outbuf; + shortfall = ccl.produced * max_expansion - (outbufsize - offset); + if (0 < shortfall) + { + outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1); + outp = outbuf + offset; + } if (NILP (unibyte_p)) { - if (outp - outbuf + MAX_MULTIBYTE_LENGTH * ccl.produced - > outbufsize) - { - EMACS_INT offset = outp - outbuf; - outbufsize += MAX_MULTIBYTE_LENGTH * ccl.produced; - outbuf = (unsigned char *) xrealloc (outbuf, outbufsize); - outp = outbuf + offset; - } for (j = 0; j < ccl.produced; j++) CHAR_STRING_ADVANCE (destination[j], outp); } else { - if (outp - outbuf + ccl.produced > outbufsize) - { - EMACS_INT offset = outp - outbuf; - outbufsize += ccl.produced; - outbuf = (unsigned char *) xrealloc (outbuf, outbufsize); - outp = outbuf + offset; - } for (j = 0; j < ccl.produced; j++) *outp++ = destination[j]; } @@ -2293,23 +2304,12 @@ syms_of_ccl (void) staticpro (&Vccl_program_table); Vccl_program_table = Fmake_vector (make_number (32), Qnil); - Qccl = intern_c_string ("ccl"); - staticpro (&Qccl); - - Qcclp = intern_c_string ("cclp"); - staticpro (&Qcclp); - - Qccl_program = intern_c_string ("ccl-program"); - staticpro (&Qccl_program); - - Qccl_program_idx = intern_c_string ("ccl-program-idx"); - staticpro (&Qccl_program_idx); - - Qcode_conversion_map = intern_c_string ("code-conversion-map"); - staticpro (&Qcode_conversion_map); - - Qcode_conversion_map_id = intern_c_string ("code-conversion-map-id"); - staticpro (&Qcode_conversion_map_id); + DEFSYM (Qccl, "ccl"); + DEFSYM (Qcclp, "cclp"); + DEFSYM (Qccl_program, "ccl-program"); + DEFSYM (Qccl_program_idx, "ccl-program-idx"); + DEFSYM (Qcode_conversion_map, "code-conversion-map"); + DEFSYM (Qcode_conversion_map_id, "code-conversion-map-id"); DEFVAR_LISP ("code-conversion-map-vector", Vcode_conversion_map_vector, doc: /* Vector of code conversion maps. */);