}
else
{
- bytes = CHAR_STRING (*src, tmp);
- p = tmp;
+ int i, c;
+
+ bytes = BYTES_BY_CHAR_HEAD (*src);
src++;
+ for (i = 1; i < bytes; i++)
+ {
+ ONE_MORE_BYTE (c);
+ if (CHAR_HEAD_P (c))
+ break;
+ }
+ if (i < bytes)
+ {
+ bytes = CHAR_STRING (*src_base, tmp);
+ p = tmp;
+ src = src_base + 1;
+ }
+ else
+ {
+ p = src_base;
+ }
}
if (dst + bytes >= (dst_bytes ? dst_end : src))
{
int dim, M, L;
int size, required;
int produced_chars;
-
+
ONE_MORE_BYTE (dim);
ONE_MORE_BYTE (M);
ONE_MORE_BYTE (L);
o coding-category-utf-8
The category for a coding system which has the same code range
- as UTF-8 (cf. RFC2279). Assigned the coding-system (Lisp
+ as UTF-8 (cf. RFC3629). Assigned the coding-system (Lisp
symbol) `utf-8' by default.
o coding-category-utf-16-be
unsigned char *data;
};
-/* Don't use alloca for allocating memory space larger than this, lest
- we overflow their stack. */
-#define MAX_ALLOCA 16*1024
-
/* Allocate LEN bytes of memory for BUF (struct conversion_buffer). */
#define allocate_conversion_buffer(buf, len) \
do { \
if (method == COMPOSITION_WITH_RULE_ALTCHARS
&& len % 2 == 0)
len --;
+ if (len < 1)
+ /* Invalid composition data. */
+ break;
for (j = 0; j < len; j++)
args[j] = make_number (data[4 + j]);
components = (method == COMPOSITION_WITH_ALTCHARS
coding_allocate_composition_data (coding, from);
}
- /* Try to skip the heading and tailing ASCIIs. */
- if (coding->type != coding_type_ccl)
+ /* Try to skip the heading and tailing ASCIIs. We can't skip them
+ if we must run CCL program or there are compositions to
+ encode. */
+ if (coding->type != coding_type_ccl
+ && (! coding->cmp_data || coding->cmp_data->used == 0))
{
int from_byte_orig = from_byte, to_byte_orig = to_byte;
if (!replace)
/* We must record and adjust for this new text now. */
adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len);
+ coding_free_composition_data (coding);
return 0;
}
return 0;
}
+/* Name (or base name) of work buffer for code conversion. */
+static Lisp_Object Vcode_conversion_workbuf_name;
+
+/* Set the current buffer to the working buffer prepared for
+ code-conversion. MULTIBYTE specifies the multibyteness of the
+ buffer. */
+
+static struct buffer *
+set_conversion_work_buffer (multibyte)
+ int multibyte;
+{
+ Lisp_Object buffer;
+ struct buffer *buf;
+
+ buffer = Fget_buffer_create (Vcode_conversion_workbuf_name);
+ buf = XBUFFER (buffer);
+ delete_all_overlays (buf);
+ buf->directory = current_buffer->directory;
+ buf->read_only = Qnil;
+ buf->filename = Qnil;
+ buf->undo_list = Qt;
+ eassert (buf->overlays_before == NULL);
+ eassert (buf->overlays_after == NULL);
+ set_buffer_internal (buf);
+ if (BEG != BEGV || Z != ZV)
+ Fwiden ();
+ del_range_2 (BEG, BEG_BYTE, Z, Z_BYTE, 0);
+ buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
+ return buf;
+}
+
Lisp_Object
run_pre_post_conversion_on_str (str, coding, encodep)
Lisp_Object str;
int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2;
int multibyte = STRING_MULTIBYTE (str);
- Lisp_Object buffer;
struct buffer *buf;
Lisp_Object old_deactivate_mark;
old_deactivate_mark = Vdeactivate_mark;
GCPRO2 (str, old_deactivate_mark);
- buffer = Fget_buffer_create (build_string (" *code-converting-work*"));
- buf = XBUFFER (buffer);
-
- delete_all_overlays (buf);
- buf->directory = current_buffer->directory;
- buf->read_only = Qnil;
- buf->filename = Qnil;
- buf->undo_list = Qt;
- eassert (buf->overlays_before == NULL);
- eassert (buf->overlays_after == NULL);
-
- set_buffer_internal (buf);
/* We must insert the contents of STR as is without
unibyte<->multibyte conversion. For that, we adjust the
multibyteness of the working buffer to that of STR. */
- Ferase_buffer ();
- buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
+ set_conversion_work_buffer (multibyte);
insert_from_string (str, 0, 0,
SCHARS (str), SBYTES (str), 0);
return unbind_to (count, str);
}
+
+/* Run pre-write-conversion function of CODING on NCHARS/NBYTES
+ text in *STR. *SIZE is the allocated bytes for STR. As it
+ is intended that this function is called from encode_terminal_code,
+ the pre-write-conversion function is run by safe_call and thus
+ "Error during redisplay: ..." is logged when an error occurs.
+
+ Store the resulting text in *STR and set CODING->produced_char and
+ CODING->produced to the number of characters and bytes
+ respectively. If the size of *STR is too small, enlarge it by
+ xrealloc and update *STR and *SIZE. */
+
+void
+run_pre_write_conversin_on_c_str (str, size, nchars, nbytes, coding)
+ unsigned char **str;
+ int *size, nchars, nbytes;
+ struct coding_system *coding;
+{
+ struct gcpro gcpro1, gcpro2;
+ struct buffer *cur = current_buffer;
+ Lisp_Object old_deactivate_mark, old_last_coding_system_used;
+ Lisp_Object args[3];
+
+ /* It is not crucial to specbind this. */
+ old_deactivate_mark = Vdeactivate_mark;
+ old_last_coding_system_used = Vlast_coding_system_used;
+ GCPRO2 (old_deactivate_mark, old_last_coding_system_used);
+
+ /* We must insert the contents of STR as is without
+ unibyte<->multibyte conversion. For that, we adjust the
+ multibyteness of the working buffer to that of STR. */
+ set_conversion_work_buffer (coding->src_multibyte);
+ insert_1_both (*str, nchars, nbytes, 0, 0, 0);
+ UNGCPRO;
+ inhibit_pre_post_conversion = 1;
+ args[0] = coding->pre_write_conversion;
+ args[1] = make_number (BEG);
+ args[2] = make_number (Z);
+ safe_call (3, args);
+ inhibit_pre_post_conversion = 0;
+ Vdeactivate_mark = old_deactivate_mark;
+ Vlast_coding_system_used = old_last_coding_system_used;
+ coding->produced_char = Z - BEG;
+ coding->produced = Z_BYTE - BEG_BYTE;
+ if (coding->produced > *size)
+ {
+ *size = coding->produced;
+ *str = xrealloc (*str, *size);
+ }
+ if (BEG < GPT && GPT < Z)
+ move_gap (BEG);
+ bcopy (BEG_ADDR, *str, coding->produced);
+ coding->src_multibyte
+ = ! NILP (current_buffer->enable_multibyte_characters);
+ set_buffer_internal (cur);
+}
+
+
Lisp_Object
decode_coding_string (str, coding, nocopy)
Lisp_Object str;
shrinked_bytes - from);
free_conversion_buffer (&buf);
+ coding->consumed += shrinked_bytes;
+ coding->consumed_char += shrinked_bytes;
+ coding->produced += shrinked_bytes;
+ coding->produced_char += shrinked_bytes;
+
if (coding->cmp_data && coding->cmp_data->used)
coding_restore_composition (coding, newstr);
coding_free_composition_data (coding);
if (coding->composing != COMPOSITION_DISABLED)
coding_save_composition (coding, from, to, str);
- /* Try to skip the heading and tailing ASCIIs. */
- if (coding->type != coding_type_ccl)
+ /* Try to skip the heading and tailing ASCIIs. We can't skip them
+ if we must run CCL program or there are compositions to
+ encode. */
+ if (coding->type != coding_type_ccl
+ && (! coding->cmp_data || coding->cmp_data->used == 0))
{
SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),
1);
if (from == to_byte)
- return (nocopy ? str : Fcopy_sequence (str));
+ {
+ coding_free_composition_data (coding);
+ return (nocopy ? str : Fcopy_sequence (str));
+ }
shrinked_bytes = from + (SBYTES (str) - to_byte);
}
produced += coding->produced;
produced_char += coding->produced_char;
if (result == CODING_FINISH_NORMAL
+ || result == CODING_FINISH_INTERRUPT
|| (result == CODING_FINISH_INSUFFICIENT_SRC
&& coding->consumed == 0))
break;
doc: /* Check validity of CODING-SYSTEM.
If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.
It is valid if it is nil or a symbol with a non-nil `coding-system' property.
-The value of property should be a vector of length 5. */)
+The value of this property should be a vector of length 5. */)
(coding_system)
Lisp_Object coding_system;
{
possible coding systems. If it is nil, it means that we have not
yet found any coding systems.
- WORK_TABLE is a copy of the char-table Vchar_coding_system_table. An
- element of WORK_TABLE is set to t once the element is looked up.
+ WORK_TABLE a char-table of which element is set to t once the
+ element is looked up.
If a non-ASCII single byte char is found, set
*single_byte_char_found to 1. */
Lisp_Object val, ch;
Lisp_Object prev, tail;
+ if (NILP (safe_codings))
+ goto done_safe_codings;
while (p < pend)
{
c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
continue;
if (SINGLE_BYTE_CHAR_P (c))
*single_byte_char_found = 1;
- if (NILP (safe_codings))
- /* Already all coding systems are excluded. But, we can't
- terminate the loop here because non-ASCII single-byte char
- must be found. */
- continue;
/* Check the safe coding systems for C. */
ch = make_number (c);
val = Faref (work_table, ch);
accept_latin_extra));
}
}
-
+
if (! encodable
&& ((CHAR_TABLE_P (translation_table)
&& ! NILP (Faref (translation_table, ch)))
{
/* Exclude this coding system from SAFE_CODINGS. */
if (EQ (tail, safe_codings))
- safe_codings = XCDR (safe_codings);
+ {
+ safe_codings = XCDR (safe_codings);
+ if (NILP (safe_codings))
+ goto done_safe_codings;
+ }
else
XSETCDR (prev, XCDR (tail));
}
}
}
+
+ done_safe_codings:
+ /* If the above loop was terminated before P reaches PEND, it means
+ SAFE_CODINGS was set to nil. If we have not yet found an
+ non-ASCII single-byte char, check it now. */
+ if (! *single_byte_char_found)
+ while (p < pend)
+ {
+ c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
+ p += len;
+ if (! ASCII_BYTE_P (c)
+ && SINGLE_BYTE_CHAR_P (c))
+ {
+ *single_byte_char_found = 1;
+ break;
+ }
+ }
return safe_codings;
}
/* Character composition should be disabled. */
safe_terminal_coding.composing = COMPOSITION_DISABLED;
/* Error notification should be suppressed. */
- terminal_coding.suppress_error = 1;
+ safe_terminal_coding.suppress_error = 1;
safe_terminal_coding.src_multibyte = 1;
safe_terminal_coding.dst_multibyte = 0;
return Qnil;
void
syms_of_coding ()
{
+ staticpro (&Vcode_conversion_workbuf_name);
+ Vcode_conversion_workbuf_name = build_string (" *code-conversion-work*");
+
Qtarget_idx = intern ("target-idx");
staticpro (&Qtarget_idx);