diff options
Diffstat (limited to 'src/ccl.c')
| -rw-r--r-- | src/ccl.c | 83 |
1 files changed, 41 insertions, 42 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* CCL (Code Conversion Language) interpreter. | 1 | /* CCL (Code Conversion Language) interpreter. |
| 2 | Copyright (C) 2001-2011 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | 5 | National Institute of Advanced Industrial Science and Technology (AIST) |
| @@ -47,7 +47,7 @@ static Lisp_Object Qcode_conversion_map; | |||
| 47 | static Lisp_Object Qcode_conversion_map_id; | 47 | static Lisp_Object Qcode_conversion_map_id; |
| 48 | 48 | ||
| 49 | /* Symbols of ccl program have this property, a value of the property | 49 | /* Symbols of ccl program have this property, a value of the property |
| 50 | is an index for Vccl_protram_table. */ | 50 | is an index for Vccl_program_table. */ |
| 51 | static Lisp_Object Qccl_program_idx; | 51 | static Lisp_Object Qccl_program_idx; |
| 52 | 52 | ||
| 53 | /* Table of registered CCL programs. Each element is a vector of | 53 | /* Table of registered CCL programs. Each element is a vector of |
| @@ -61,7 +61,7 @@ static Lisp_Object Vccl_program_table; | |||
| 61 | 61 | ||
| 62 | /* Return a hash table of id number ID. */ | 62 | /* Return a hash table of id number ID. */ |
| 63 | #define GET_HASH_TABLE(id) \ | 63 | #define GET_HASH_TABLE(id) \ |
| 64 | (XHASH_TABLE (XCDR(XVECTOR(Vtranslation_hash_table_vector)->contents[(id)]))) | 64 | (XHASH_TABLE (XCDR (XVECTOR (Vtranslation_hash_table_vector)->contents[(id)]))) |
| 65 | 65 | ||
| 66 | /* CCL (Code Conversion Language) is a simple language which has | 66 | /* CCL (Code Conversion Language) is a simple language which has |
| 67 | operations on one input buffer, one output buffer, and 7 registers. | 67 | operations on one input buffer, one output buffer, and 7 registers. |
| @@ -210,8 +210,8 @@ static Lisp_Object Vccl_program_table; | |||
| 210 | #define CCL_WriteArrayReadJump 0x0B /* Write an array element, read, and jump: | 210 | #define CCL_WriteArrayReadJump 0x0B /* Write an array element, read, and jump: |
| 211 | 1:A--D--D--R--E--S--S-rrrXXXXX | 211 | 1:A--D--D--R--E--S--S-rrrXXXXX |
| 212 | 2:LENGTH | 212 | 2:LENGTH |
| 213 | 3:ELEMENET[0] | 213 | 3:ELEMENT[0] |
| 214 | 4:ELEMENET[1] | 214 | 4:ELEMENT[1] |
| 215 | ... | 215 | ... |
| 216 | N:A--D--D--R--E--S--S-rrrYYYYY | 216 | N:A--D--D--R--E--S--S-rrrYYYYY |
| 217 | ------------------------------ | 217 | ------------------------------ |
| @@ -429,7 +429,7 @@ static Lisp_Object Vccl_program_table; | |||
| 429 | 429 | ||
| 430 | #define CCL_Extension 0x1F /* Extended CCL code | 430 | #define CCL_Extension 0x1F /* Extended CCL code |
| 431 | 1:ExtendedCOMMNDRrrRRRrrrXXXXX | 431 | 1:ExtendedCOMMNDRrrRRRrrrXXXXX |
| 432 | 2:ARGUEMENT | 432 | 2:ARGUMENT |
| 433 | 3:... | 433 | 3:... |
| 434 | ------------------------------ | 434 | ------------------------------ |
| 435 | extended_command (rrr,RRR,Rrr,ARGS) | 435 | extended_command (rrr,RRR,Rrr,ARGS) |
| @@ -484,7 +484,7 @@ static Lisp_Object Vccl_program_table; | |||
| 484 | If the element is t or lambda, finish without changing reg[rrr]. | 484 | If the element is t or lambda, finish without changing reg[rrr]. |
| 485 | If the element is a number, set reg[rrr] to the number and finish. | 485 | If the element is a number, set reg[rrr] to the number and finish. |
| 486 | 486 | ||
| 487 | Detail of the map structure is descibed in the comment for | 487 | Detail of the map structure is described in the comment for |
| 488 | CCL_MapMultiple below. */ | 488 | CCL_MapMultiple below. */ |
| 489 | 489 | ||
| 490 | #define CCL_IterateMultipleMap 0x10 /* Iterate multiple maps | 490 | #define CCL_IterateMultipleMap 0x10 /* Iterate multiple maps |
| @@ -552,7 +552,7 @@ static Lisp_Object Vccl_program_table; | |||
| 552 | But, when VALm is mapped to VALn and VALn is not a number, the | 552 | But, when VALm is mapped to VALn and VALn is not a number, the |
| 553 | mapping proceed as below: | 553 | mapping proceed as below: |
| 554 | 554 | ||
| 555 | If VALn is nil, the lastest map is ignored and the mapping of VALm | 555 | If VALn is nil, the last map is ignored and the mapping of VALm |
| 556 | proceed to the next map. | 556 | proceed to the next map. |
| 557 | 557 | ||
| 558 | In VALn is t, VALm is reverted to reg[rrr] and the mapping of VALm | 558 | In VALn is t, VALm is reverted to reg[rrr] and the mapping of VALm |
| @@ -561,7 +561,7 @@ static Lisp_Object Vccl_program_table; | |||
| 561 | If VALn is lambda, move to the next map set like reaching to the | 561 | If VALn is lambda, move to the next map set like reaching to the |
| 562 | end of the current map set. | 562 | end of the current map set. |
| 563 | 563 | ||
| 564 | If VALn is a symbol, call the CCL program refered by it. | 564 | If VALn is a symbol, call the CCL program referred by it. |
| 565 | Then, use reg[rrr] as a mapped value except for -1, -2 and -3. | 565 | Then, use reg[rrr] as a mapped value except for -1, -2 and -3. |
| 566 | Such special values are regarded as nil, t, and lambda respectively. | 566 | Such special values are regarded as nil, t, and lambda respectively. |
| 567 | 567 | ||
| @@ -706,7 +706,7 @@ do \ | |||
| 706 | ccl->status = CCL_STAT_SUCCESS; \ | 706 | ccl->status = CCL_STAT_SUCCESS; \ |
| 707 | goto ccl_finish; \ | 707 | goto ccl_finish; \ |
| 708 | } \ | 708 | } \ |
| 709 | while(0) | 709 | while (0) |
| 710 | 710 | ||
| 711 | /* Suspend CCL program because of reading from empty input buffer or | 711 | /* Suspend CCL program because of reading from empty input buffer or |
| 712 | writing to full output buffer. When this program is resumed, the | 712 | writing to full output buffer. When this program is resumed, the |
| @@ -730,7 +730,7 @@ do \ | |||
| 730 | ccl->status = CCL_STAT_INVALID_CMD; \ | 730 | ccl->status = CCL_STAT_INVALID_CMD; \ |
| 731 | goto ccl_error_handler; \ | 731 | goto ccl_error_handler; \ |
| 732 | } \ | 732 | } \ |
| 733 | while(0) | 733 | while (0) |
| 734 | 734 | ||
| 735 | #else | 735 | #else |
| 736 | 736 | ||
| @@ -741,7 +741,7 @@ do \ | |||
| 741 | ccl->status = CCL_STAT_INVALID_CMD; \ | 741 | ccl->status = CCL_STAT_INVALID_CMD; \ |
| 742 | goto ccl_error_handler; \ | 742 | goto ccl_error_handler; \ |
| 743 | } \ | 743 | } \ |
| 744 | while(0) | 744 | while (0) |
| 745 | 745 | ||
| 746 | #endif | 746 | #endif |
| 747 | 747 | ||
| @@ -826,7 +826,7 @@ while(0) | |||
| 826 | : (charset = CHARSET_FROM_ID ((id)), DECODE_CHAR (charset, (code)))) | 826 | : (charset = CHARSET_FROM_ID ((id)), DECODE_CHAR (charset, (code)))) |
| 827 | 827 | ||
| 828 | /* Encode character C by some of charsets in CHARSET_LIST. Set ID to | 828 | /* Encode character C by some of charsets in CHARSET_LIST. Set ID to |
| 829 | the id of the used charset, ENCODED to the resulf of encoding. | 829 | the id of the used charset, ENCODED to the result of encoding. |
| 830 | Assume that we can use the variable `charset'. */ | 830 | Assume that we can use the variable `charset'. */ |
| 831 | 831 | ||
| 832 | #define CCL_ENCODE_CHAR(c, charset_list, id, encoded) \ | 832 | #define CCL_ENCODE_CHAR(c, charset_list, id, encoded) \ |
| @@ -1303,7 +1303,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1303 | 1303 | ||
| 1304 | case CCL_LookupIntConstTbl: | 1304 | case CCL_LookupIntConstTbl: |
| 1305 | { | 1305 | { |
| 1306 | EMACS_INT eop; | 1306 | ptrdiff_t eop; |
| 1307 | struct Lisp_Hash_Table *h; | 1307 | struct Lisp_Hash_Table *h; |
| 1308 | GET_CCL_RANGE (eop, ccl_prog, ic++, 0, | 1308 | GET_CCL_RANGE (eop, ccl_prog, ic++, 0, |
| 1309 | (VECTORP (Vtranslation_hash_table_vector) | 1309 | (VECTORP (Vtranslation_hash_table_vector) |
| @@ -1329,7 +1329,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1329 | 1329 | ||
| 1330 | case CCL_LookupCharConstTbl: | 1330 | case CCL_LookupCharConstTbl: |
| 1331 | { | 1331 | { |
| 1332 | EMACS_INT eop; | 1332 | ptrdiff_t eop; |
| 1333 | struct Lisp_Hash_Table *h; | 1333 | struct Lisp_Hash_Table *h; |
| 1334 | GET_CCL_RANGE (eop, ccl_prog, ic++, 0, | 1334 | GET_CCL_RANGE (eop, ccl_prog, ic++, 0, |
| 1335 | (VECTORP (Vtranslation_hash_table_vector) | 1335 | (VECTORP (Vtranslation_hash_table_vector) |
| @@ -1419,7 +1419,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1419 | else if (INTEGERP (content) && IN_INT_RANGE (XINT (content))) | 1419 | else if (INTEGERP (content) && IN_INT_RANGE (XINT (content))) |
| 1420 | { | 1420 | { |
| 1421 | reg[RRR] = i; | 1421 | reg[RRR] = i; |
| 1422 | reg[rrr] = XINT(content); | 1422 | reg[rrr] = XINT (content); |
| 1423 | break; | 1423 | break; |
| 1424 | } | 1424 | } |
| 1425 | else if (EQ (content, Qt) || EQ (content, Qlambda)) | 1425 | else if (EQ (content, Qt) || EQ (content, Qlambda)) |
| @@ -1692,7 +1692,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1692 | value = XCDR (content); | 1692 | value = XCDR (content); |
| 1693 | if (!INTEGERP (attrib) || !INTEGERP (value)) | 1693 | if (!INTEGERP (attrib) || !INTEGERP (value)) |
| 1694 | continue; | 1694 | continue; |
| 1695 | reg[rrr] = XINT(value); | 1695 | reg[rrr] = XINT (value); |
| 1696 | break; | 1696 | break; |
| 1697 | } | 1697 | } |
| 1698 | else if (SYMBOLP (content)) | 1698 | else if (SYMBOLP (content)) |
| @@ -1729,8 +1729,8 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1729 | switch (ccl->status) | 1729 | switch (ccl->status) |
| 1730 | { | 1730 | { |
| 1731 | case CCL_STAT_INVALID_CMD: | 1731 | case CCL_STAT_INVALID_CMD: |
| 1732 | sprintf(msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", | 1732 | sprintf (msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", |
| 1733 | code & 0x1F, code, this_ic); | 1733 | code & 0x1F, code, this_ic); |
| 1734 | #ifdef CCL_DEBUG | 1734 | #ifdef CCL_DEBUG |
| 1735 | { | 1735 | { |
| 1736 | int i = ccl_backtrace_idx - 1; | 1736 | int i = ccl_backtrace_idx - 1; |
| @@ -1748,7 +1748,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1748 | if (i < 0) i = CCL_DEBUG_BACKTRACE_LEN - 1; | 1748 | if (i < 0) i = CCL_DEBUG_BACKTRACE_LEN - 1; |
| 1749 | if (ccl_backtrace_table[i] == 0) | 1749 | if (ccl_backtrace_table[i] == 0) |
| 1750 | break; | 1750 | break; |
| 1751 | sprintf(msg, " %d", ccl_backtrace_table[i]); | 1751 | sprintf (msg, " %d", ccl_backtrace_table[i]); |
| 1752 | msglen = strlen (msg); | 1752 | msglen = strlen (msg); |
| 1753 | if (dst + msglen > (dst_bytes ? dst_end : src)) | 1753 | if (dst + msglen > (dst_bytes ? dst_end : src)) |
| 1754 | break; | 1754 | break; |
| @@ -1762,15 +1762,15 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1762 | 1762 | ||
| 1763 | case CCL_STAT_QUIT: | 1763 | case CCL_STAT_QUIT: |
| 1764 | if (! ccl->quit_silently) | 1764 | if (! ccl->quit_silently) |
| 1765 | sprintf(msg, "\nCCL: Quited."); | 1765 | sprintf (msg, "\nCCL: Quitted."); |
| 1766 | break; | 1766 | break; |
| 1767 | 1767 | ||
| 1768 | default: | 1768 | default: |
| 1769 | sprintf(msg, "\nCCL: Unknown error type (%d)", ccl->status); | 1769 | sprintf (msg, "\nCCL: Unknown error type (%d)", ccl->status); |
| 1770 | } | 1770 | } |
| 1771 | 1771 | ||
| 1772 | msglen = strlen (msg); | 1772 | msglen = strlen (msg); |
| 1773 | if (dst + msglen <= dst_end) | 1773 | if (msglen <= dst_end - dst) |
| 1774 | { | 1774 | { |
| 1775 | for (i = 0; i < msglen; i++) | 1775 | for (i = 0; i < msglen; i++) |
| 1776 | *dst++ = msg[i]; | 1776 | *dst++ = msg[i]; |
| @@ -1808,7 +1808,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1808 | 1808 | ||
| 1809 | /* Resolve symbols in the specified CCL code (Lisp vector). This | 1809 | /* Resolve symbols in the specified CCL code (Lisp vector). This |
| 1810 | function converts symbols of code conversion maps and character | 1810 | function converts symbols of code conversion maps and character |
| 1811 | translation tables embeded in the CCL code into their ID numbers. | 1811 | translation tables embedded in the CCL code into their ID numbers. |
| 1812 | 1812 | ||
| 1813 | The return value is a vector (CCL itself or a new vector in which | 1813 | The return value is a vector (CCL itself or a new vector in which |
| 1814 | all symbols are resolved), Qt if resolving of some symbol failed, | 1814 | all symbols are resolved), Qt if resolving of some symbol failed, |
| @@ -2061,12 +2061,13 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY | |||
| 2061 | Lisp_Object val; | 2061 | Lisp_Object val; |
| 2062 | struct ccl_program ccl; | 2062 | struct ccl_program ccl; |
| 2063 | int i; | 2063 | int i; |
| 2064 | EMACS_INT outbufsize; | 2064 | ptrdiff_t outbufsize; |
| 2065 | unsigned char *outbuf, *outp; | 2065 | unsigned char *outbuf, *outp; |
| 2066 | EMACS_INT str_chars, str_bytes; | 2066 | ptrdiff_t str_chars, str_bytes; |
| 2067 | #define CCL_EXECUTE_BUF_SIZE 1024 | 2067 | #define CCL_EXECUTE_BUF_SIZE 1024 |
| 2068 | int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE]; | 2068 | int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE]; |
| 2069 | EMACS_INT consumed_chars, consumed_bytes, produced_chars; | 2069 | ptrdiff_t consumed_chars, consumed_bytes, produced_chars; |
| 2070 | int buf_magnification; | ||
| 2070 | 2071 | ||
| 2071 | if (setup_ccl_program (&ccl, ccl_prog) < 0) | 2072 | if (setup_ccl_program (&ccl, ccl_prog) < 0) |
| 2072 | error ("Invalid CCL program"); | 2073 | error ("Invalid CCL program"); |
| @@ -2093,6 +2094,10 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY | |||
| 2093 | ccl.ic = i; | 2094 | ccl.ic = i; |
| 2094 | } | 2095 | } |
| 2095 | 2096 | ||
| 2097 | buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1; | ||
| 2098 | |||
| 2099 | if ((min (PTRDIFF_MAX, SIZE_MAX) - 256) / buf_magnification < str_bytes) | ||
| 2100 | memory_full (SIZE_MAX); | ||
| 2096 | outbufsize = (ccl.buf_magnification | 2101 | outbufsize = (ccl.buf_magnification |
| 2097 | ? str_bytes * ccl.buf_magnification + 256 | 2102 | ? str_bytes * ccl.buf_magnification + 256 |
| 2098 | : str_bytes + 256); | 2103 | : str_bytes + 256); |
| @@ -2122,31 +2127,25 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY | |||
| 2122 | src_size = j; | 2127 | src_size = j; |
| 2123 | while (1) | 2128 | while (1) |
| 2124 | { | 2129 | { |
| 2130 | int max_expansion = NILP (unibyte_p) ? MAX_MULTIBYTE_LENGTH : 1; | ||
| 2131 | ptrdiff_t offset, shortfall; | ||
| 2125 | ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE, | 2132 | ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE, |
| 2126 | Qnil); | 2133 | Qnil); |
| 2127 | produced_chars += ccl.produced; | 2134 | produced_chars += ccl.produced; |
| 2135 | offset = outp - outbuf; | ||
| 2136 | shortfall = ccl.produced * max_expansion - (outbufsize - offset); | ||
| 2137 | if (0 < shortfall) | ||
| 2138 | { | ||
| 2139 | outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1); | ||
| 2140 | outp = outbuf + offset; | ||
| 2141 | } | ||
| 2128 | if (NILP (unibyte_p)) | 2142 | if (NILP (unibyte_p)) |
| 2129 | { | 2143 | { |
| 2130 | if (outp - outbuf + MAX_MULTIBYTE_LENGTH * ccl.produced | ||
| 2131 | > outbufsize) | ||
| 2132 | { | ||
| 2133 | EMACS_INT offset = outp - outbuf; | ||
| 2134 | outbufsize += MAX_MULTIBYTE_LENGTH * ccl.produced; | ||
| 2135 | outbuf = (unsigned char *) xrealloc (outbuf, outbufsize); | ||
| 2136 | outp = outbuf + offset; | ||
| 2137 | } | ||
| 2138 | for (j = 0; j < ccl.produced; j++) | 2144 | for (j = 0; j < ccl.produced; j++) |
| 2139 | CHAR_STRING_ADVANCE (destination[j], outp); | 2145 | CHAR_STRING_ADVANCE (destination[j], outp); |
| 2140 | } | 2146 | } |
| 2141 | else | 2147 | else |
| 2142 | { | 2148 | { |
| 2143 | if (outp - outbuf + ccl.produced > outbufsize) | ||
| 2144 | { | ||
| 2145 | EMACS_INT offset = outp - outbuf; | ||
| 2146 | outbufsize += ccl.produced; | ||
| 2147 | outbuf = (unsigned char *) xrealloc (outbuf, outbufsize); | ||
| 2148 | outp = outbuf + offset; | ||
| 2149 | } | ||
| 2150 | for (j = 0; j < ccl.produced; j++) | 2149 | for (j = 0; j < ccl.produced; j++) |
| 2151 | *outp++ = destination[j]; | 2150 | *outp++ = destination[j]; |
| 2152 | } | 2151 | } |