case CODING_RESULT_INSUFFICIENT_MEM:
Vlast_code_conversion_error = Qinsufficient_memory;
break;
+ case CODING_RESULT_INSUFFICIENT_DST:
+ /* Don't record this error in Vlast_code_conversion_error
+ because it happens just temporarily and is resolved when the
+ whole conversion is finished. */
+ break;
case CODING_RESULT_SUCCESS:
break;
default:
}
}
+/* This wrapper macro is used to preserve validity of pointers into
+ buffer text across calls to decode_char, which could cause
+ relocation of buffers if it loads a charset map, because loading a
+ charset map allocates large structures. */
#define CODING_DECODE_CHAR(coding, src, src_base, src_end, charset, code, c) \
do { \
charset_map_loaded = 0; \
/* Parse emacs-mule multibyte sequence at SRC and return the decoded
character. If CMP_STATUS indicates that we must expect MSEQ or
RULE described above, decode it and return the negative value of
- the deocded character or rule. If an invalid byte is found, return
+ the decoded character or rule. If an invalid byte is found, return
-1. If SRC is too short, return -2. */
int
default:
abort ();
}
- c = DECODE_CHAR (charset, code);
+ CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, code, c);
if (c < 0)
goto invalid_code;
}
else
{
int nchars, nbytes;
+ /* emacs_mule_char can load a charset map from a file, which
+ allocates a large structure and might cause buffer text
+ to be relocated as result. Thus, we need to remember the
+ original pointer to buffer text, and fixup all related
+ pointers after the call. */
+ const unsigned char *orig = coding->source;
+ EMACS_INT offset;
c = emacs_mule_char (coding, src_base, &nbytes, &nchars, &id,
cmp_status);
+ offset = coding->source - orig;
+ if (offset)
+ {
+ src += offset;
+ src_base += offset;
+ src_end += offset;
+ }
if (c < 0)
{
if (c == -1)
int i = 1;
while (src < src_end)
{
+ src_base = src;
ONE_MORE_BYTE (c);
if (c < 0xA0)
- break;
+ {
+ src = src_base;
+ break;
+ }
i++;
}
int *charbuf_end = coding->charbuf + coding->charbuf_size;
int consumed_chars = 0;
int multibytep = coding->src_multibyte;
- struct ccl_program ccl;
+ struct ccl_program *ccl = &coding->spec.ccl->ccl;
int source_charbuf[1024];
- int source_byteidx[1024];
+ int source_byteidx[1025];
Lisp_Object attrs, charset_list;
CODING_GET_INFO (coding, attrs, charset_list);
- setup_ccl_program (&ccl, CODING_CCL_DECODER (coding));
- while (src < src_end)
+ while (1)
{
const unsigned char *p = src;
- int *source, *source_end;
int i = 0;
if (multibytep)
- while (i < 1024 && p < src_end)
- {
- source_byteidx[i] = p - src;
- source_charbuf[i++] = STRING_CHAR_ADVANCE (p);
- }
+ {
+ while (i < 1024 && p < src_end)
+ {
+ source_byteidx[i] = p - src;
+ source_charbuf[i++] = STRING_CHAR_ADVANCE (p);
+ }
+ source_byteidx[i] = p - src;
+ }
else
while (i < 1024 && p < src_end)
source_charbuf[i++] = *p++;
if (p == src_end && coding->mode & CODING_MODE_LAST_BLOCK)
- ccl.last_block = 1;
-
- source = source_charbuf;
- source_end = source + i;
- while (source < source_end)
- {
- ccl_driver (&ccl, source, charbuf,
- source_end - source, charbuf_end - charbuf,
- charset_list);
- source += ccl.consumed;
- charbuf += ccl.produced;
- if (ccl.status != CCL_STAT_SUSPEND_BY_DST)
- break;
- }
- if (source < source_end)
- src += source_byteidx[source - source_charbuf];
+ ccl->last_block = 1;
+ ccl_driver (ccl, source_charbuf, charbuf, i, charbuf_end - charbuf,
+ charset_list);
+ charbuf += ccl->produced;
+ if (multibytep)
+ src += source_byteidx[ccl->consumed];
else
- src = p;
- consumed_chars += source - source_charbuf;
-
- if (ccl.status != CCL_STAT_SUSPEND_BY_SRC
- && ccl.status != CODING_RESULT_INSUFFICIENT_SRC)
+ src += ccl->consumed;
+ consumed_chars += ccl->consumed;
+ if (p == src_end || ccl->status != CCL_STAT_SUSPEND_BY_SRC)
break;
}
- switch (ccl.status)
+ switch (ccl->status)
{
case CCL_STAT_SUSPEND_BY_SRC:
record_conversion_result (coding, CODING_RESULT_INSUFFICIENT_SRC);
break;
case CCL_STAT_SUSPEND_BY_DST:
+ record_conversion_result (coding, CODING_RESULT_INSUFFICIENT_DST);
break;
case CCL_STAT_QUIT:
case CCL_STAT_INVALID_CMD:
encode_coding_ccl (coding)
struct coding_system *coding;
{
- struct ccl_program ccl;
+ struct ccl_program *ccl = &coding->spec.ccl->ccl;
int multibytep = coding->dst_multibyte;
int *charbuf = coding->charbuf;
int *charbuf_end = charbuf + coding->charbuf_used;
Lisp_Object attrs, charset_list;
CODING_GET_INFO (coding, attrs, charset_list);
- setup_ccl_program (&ccl, CODING_CCL_ENCODER (coding));
-
- ccl.last_block = coding->mode & CODING_MODE_LAST_BLOCK;
- ccl.dst_multibyte = coding->dst_multibyte;
+ if (coding->consumed_char == coding->src_chars
+ && coding->mode & CODING_MODE_LAST_BLOCK)
+ ccl->last_block = 1;
while (charbuf < charbuf_end)
{
- ccl_driver (&ccl, charbuf, destination_charbuf,
+ ccl_driver (ccl, charbuf, destination_charbuf,
charbuf_end - charbuf, 1024, charset_list);
if (multibytep)
{
- ASSURE_DESTINATION (ccl.produced * 2);
- for (i = 0; i < ccl.produced; i++)
+ ASSURE_DESTINATION (ccl->produced * 2);
+ for (i = 0; i < ccl->produced; i++)
EMIT_ONE_BYTE (destination_charbuf[i] & 0xFF);
}
else
{
- ASSURE_DESTINATION (ccl.produced);
- for (i = 0; i < ccl.produced; i++)
+ ASSURE_DESTINATION (ccl->produced);
+ for (i = 0; i < ccl->produced; i++)
*dst++ = destination_charbuf[i] & 0xFF;
- produced_chars += ccl.produced;
+ produced_chars += ccl->produced;
}
- charbuf += ccl.consumed;
- if (ccl.status == CCL_STAT_QUIT
- || ccl.status == CCL_STAT_INVALID_CMD)
+ charbuf += ccl->consumed;
+ if (ccl->status == CCL_STAT_QUIT
+ || ccl->status == CCL_STAT_INVALID_CMD)
break;
}
- switch (ccl.status)
+ switch (ccl->status)
{
case CCL_STAT_SUSPEND_BY_SRC:
record_conversion_result (coding, CODING_RESULT_INSUFFICIENT_SRC);
{
/* We didn't find an 8-bit code. We may
have found a null-byte, but it's very
- rare that a binary file confirm to
+ rare that a binary file conforms to
ISO-2022. */
src = src_end;
coding->head_ascii = src - coding->source;
Lisp_Object attrs;
Lisp_Object undo_list;
Lisp_Object translation_table;
+ struct ccl_spec cclspec;
int carryover;
int i;
translation_table = get_translation_table (attrs, 0, NULL);
carryover = 0;
+ if (coding->decoder == decode_coding_ccl)
+ {
+ coding->spec.ccl = &cclspec;
+ setup_ccl_program (&cclspec.ccl, CODING_CCL_DECODER (coding));
+ }
do
{
EMACS_INT pos = coding->dst_pos + coding->produced_char;
coding->charbuf[i]
= coding->charbuf[coding->charbuf_used - carryover + i];
}
- while (coding->consumed < coding->src_bytes
- && (coding->result == CODING_RESULT_SUCCESS
- || coding->result == CODING_RESULT_INVALID_SRC));
+ while (coding->result == CODING_RESULT_INSUFFICIENT_DST
+ || (coding->consumed < coding->src_bytes
+ && (coding->result == CODING_RESULT_SUCCESS
+ || coding->result == CODING_RESULT_INVALID_SRC)));
if (carryover > 0)
{
{
EMACS_INT bytes;
- if (coding->encoder == encode_coding_raw_text)
+ if (coding->encoder == encode_coding_raw_text
+ || coding->encoder == encode_coding_ccl)
c = *src++, pos++;
else if ((bytes = MULTIBYTE_LENGTH (src, src_end)) > 0)
c = STRING_CHAR_ADVANCE_NO_UNIFY (src), pos += bytes;
Lisp_Object attrs;
Lisp_Object translation_table;
int max_lookup;
+ struct ccl_spec cclspec;
attrs = CODING_ID_ATTRS (coding->id);
if (coding->encoder == encode_coding_raw_text)
ALLOC_CONVERSION_WORK_AREA (coding);
+ if (coding->encoder == encode_coding_ccl)
+ {
+ coding->spec.ccl = &cclspec;
+ setup_ccl_program (&cclspec.ccl, CODING_CCL_ENCODER (coding));
+ }
do {
coding_set_source (coding);
consume_chars (coding, translation_table, max_lookup);
if (! destination)
{
record_conversion_result (coding,
- CODING_RESULT_INSUFFICIENT_DST);
+ CODING_RESULT_INSUFFICIENT_MEM);
unbind_to (count, Qnil);
return;
}