diff options
Diffstat (limited to 'src/ccl.c')
-rw-r--r-- | src/ccl.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/ccl.c b/src/ccl.c index 5eac485bf2c..71a08fdf7c7 100644 --- a/src/ccl.c +++ b/src/ccl.c @@ -634,14 +634,17 @@ do \ { \ ccl_prog = ccl_prog_stack_struct[0].ccl_prog; \ ic = ccl_prog_stack_struct[0].ic; \ + eof_ic = ccl_prog_stack_struct[0].eof_ic; \ } \ CCL_INVALID_CMD; \ } \ ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog; \ ccl_prog_stack_struct[stack_idx].ic = (ret_ic); \ + ccl_prog_stack_struct[stack_idx].eof_ic = eof_ic; \ stack_idx++; \ ccl_prog = called_ccl.prog; \ ic = CCL_HEADER_MAIN; \ + eof_ic = XFASTINT (ccl_prog[CCL_HEADER_EOF]); \ goto ccl_repeat; \ } \ while (0) @@ -718,14 +721,29 @@ while (0) /* Terminate CCL program because of invalid command. Should not occur in the normal case. */ +#ifndef CCL_DEBUG + +#define CCL_INVALID_CMD \ +do \ + { \ + ccl->status = CCL_STAT_INVALID_CMD; \ + goto ccl_error_handler; \ + } \ +while(0) + +#else + #define CCL_INVALID_CMD \ do \ { \ + ccl_debug_hook (this_ic); \ ccl->status = CCL_STAT_INVALID_CMD; \ goto ccl_error_handler; \ } \ while(0) +#endif + /* 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) \ @@ -762,6 +780,7 @@ while(0) r = *src++; \ else if (ccl->last_block) \ { \ + r = -1; \ ic = ccl->eof_ic; \ goto ccl_repeat; \ } \ @@ -807,12 +826,20 @@ while(0) #define CCL_DEBUG_BACKTRACE_LEN 256 int ccl_backtrace_table[CCL_DEBUG_BACKTRACE_LEN]; int ccl_backtrace_idx; + +int +ccl_debug_hook (int ic) +{ + return ic; +} + #endif struct ccl_prog_stack { Lisp_Object *ccl_prog; /* Pointer to an array of CCL code. */ int ic; /* Instruction Counter. */ + int eof_ic; /* Instruction Counter to jump on EOF. */ }; /* For the moment, we only support depth 256 of stack. */ @@ -837,8 +864,10 @@ ccl_driver (ccl, source, destination, src_size, dst_size, charset_list) /* Instruction counter of the current CCL code. */ int this_ic = 0; struct charset *charset; + int eof_ic = ccl->eof_ic; + int eof_hit = 0; - if (ic >= ccl->eof_ic) + if (ic >= eof_ic) ic = CCL_HEADER_MAIN; if (ccl->buf_magnification == 0) /* We can't read/produce any bytes. */ @@ -1042,15 +1071,18 @@ ccl_driver (ccl, source, destination, src_size, dst_size, charset_list) { ccl_prog = ccl_prog_stack_struct[0].ccl_prog; ic = ccl_prog_stack_struct[0].ic; + eof_ic = ccl_prog_stack_struct[0].eof_ic; } CCL_INVALID_CMD; } ccl_prog_stack_struct[stack_idx].ccl_prog = ccl_prog; ccl_prog_stack_struct[stack_idx].ic = ic; + ccl_prog_stack_struct[stack_idx].eof_ic = eof_ic; stack_idx++; ccl_prog = XVECTOR (AREF (slot, 1))->contents; ic = CCL_HEADER_MAIN; + eof_ic = XFASTINT (ccl_prog[CCL_HEADER_EOF]); } break; @@ -1080,6 +1112,9 @@ ccl_driver (ccl, source, destination, src_size, dst_size, charset_list) stack_idx--; ccl_prog = ccl_prog_stack_struct[stack_idx].ccl_prog; ic = ccl_prog_stack_struct[stack_idx].ic; + eof_ic = ccl_prog_stack_struct[stack_idx].eof_ic; + if (eof_hit) + ic = eof_ic; break; } if (src) |