/* Coding system handler (conversion, detection, etc).
Copyright (C) 2001, 2002, 2003, 2004, 2005,
- 2006, 2007 Free Software Foundation, Inc.
+ 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007
+ 2005, 2006, 2007, 2008
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H14PRO021
Copyright (C) 2003
} while (0)
+/* If there are at least BYTES length of room at dst, allocate memory
+ for coding->destination and update dst and dst_end. We don't have
+ to take care of coding->source which will be relocated. It is
+ handled by calling coding_set_source in encode_coding. */
+
#define ASSURE_DESTINATION(bytes) \
do { \
if (dst + (bytes) >= dst_end) \
} while (0)
+/* Store multibyte form of the character C in P, and advance P to the
+ end of the multibyte form. This is like CHAR_STRING_ADVANCE but it
+ never calls MAYBE_UNIFY_CHAR. */
+
+#define CHAR_STRING_ADVANCE_NO_UNIFY(c, p) \
+ do { \
+ if ((c) <= MAX_1_BYTE_CHAR) \
+ *(p)++ = (c); \
+ else if ((c) <= MAX_2_BYTE_CHAR) \
+ *(p)++ = (0xC0 | ((c) >> 6)), \
+ *(p)++ = (0x80 | ((c) & 0x3F)); \
+ else if ((c) <= MAX_3_BYTE_CHAR) \
+ *(p)++ = (0xE0 | ((c) >> 12)), \
+ *(p)++ = (0x80 | (((c) >> 6) & 0x3F)), \
+ *(p)++ = (0x80 | ((c) & 0x3F)); \
+ else if ((c) <= MAX_4_BYTE_CHAR) \
+ *(p)++ = (0xF0 | (c >> 18)), \
+ *(p)++ = (0x80 | ((c >> 12) & 0x3F)), \
+ *(p)++ = (0x80 | ((c >> 6) & 0x3F)), \
+ *(p)++ = (0x80 | (c & 0x3F)); \
+ else if ((c) <= MAX_5_BYTE_CHAR) \
+ *(p)++ = 0xF8, \
+ *(p)++ = (0x80 | ((c >> 18) & 0x0F)), \
+ *(p)++ = (0x80 | ((c >> 12) & 0x3F)), \
+ *(p)++ = (0x80 | ((c >> 6) & 0x3F)), \
+ *(p)++ = (0x80 | (c & 0x3F)); \
+ else \
+ (p) += BYTE8_STRING ((c) - 0x3FFF80, p); \
+ } while (0)
+
+
+/* Return the character code of character whose multibyte form is at
+ P, and advance P to the end of the multibyte form. This is like
+ STRING_CHAR_ADVANCE, but it never calls MAYBE_UNIFY_CHAR. */
+
+#define STRING_CHAR_ADVANCE_NO_UNIFY(p) \
+ (!((p)[0] & 0x80) \
+ ? *(p)++ \
+ : ! ((p)[0] & 0x20) \
+ ? ((p) += 2, \
+ ((((p)[-2] & 0x1F) << 6) \
+ | ((p)[-1] & 0x3F) \
+ | ((unsigned char) ((p)[-2]) < 0xC2 ? 0x3FFF80 : 0))) \
+ : ! ((p)[0] & 0x10) \
+ ? ((p) += 3, \
+ ((((p)[-3] & 0x0F) << 12) \
+ | (((p)[-2] & 0x3F) << 6) \
+ | ((p)[-1] & 0x3F))) \
+ : ! ((p)[0] & 0x08) \
+ ? ((p) += 4, \
+ ((((p)[-4] & 0xF) << 18) \
+ | (((p)[-3] & 0x3F) << 12) \
+ | (((p)[-2] & 0x3F) << 6) \
+ | ((p)[-1] & 0x3F))) \
+ : ((p) += 5, \
+ ((((p)[-4] & 0x3F) << 18) \
+ | (((p)[-3] & 0x3F) << 12) \
+ | (((p)[-2] & 0x3F) << 6) \
+ | ((p)[-1] & 0x3F))))
+
static void
coding_set_source (coding)
{
if (coding->src_pos < 0)
{
- coding->destination = BEG_ADDR + coding->dst_pos_byte - 1;
+ coding->destination = BEG_ADDR + coding->dst_pos_byte - BEG_BYTE;
coding->dst_bytes = (GAP_END_ADDR
- (coding->src_bytes - coding->consumed)
- coding->destination);
/* We are sure that coding->dst_pos_byte is before the gap
of the buffer. */
coding->destination = (BUF_BEG_ADDR (XBUFFER (coding->dst_object))
- + coding->dst_pos_byte - 1);
+ + coding->dst_pos_byte - BEG_BYTE);
coding->dst_bytes = (BUF_GAP_END_ADDR (XBUFFER (coding->dst_object))
- coding->destination);
}
}
static void
-coding_alloc_by_making_gap (coding, offset, bytes)
+coding_alloc_by_making_gap (coding, gap_head_used, bytes)
struct coding_system *coding;
- EMACS_INT offset, bytes;
+ EMACS_INT gap_head_used, bytes;
{
- if (BUFFERP (coding->dst_object)
- && EQ (coding->src_object, coding->dst_object))
+ if (EQ (coding->src_object, coding->dst_object))
{
- EMACS_INT add = offset + (coding->src_bytes - coding->consumed);
+ /* The gap may contain the produced data at the head and not-yet
+ consumed data at the tail. To preserve those data, we at
+ first make the gap size to zero, then increase the gap
+ size. */
+ EMACS_INT add = GAP_SIZE;
- GPT += offset, GPT_BYTE += offset;
- GAP_SIZE -= add; ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
+ GPT += gap_head_used, GPT_BYTE += gap_head_used;
+ GAP_SIZE = 0; ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
make_gap (bytes);
GAP_SIZE += add; ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;
- GPT -= offset, GPT_BYTE -= offset;
+ GPT -= gap_head_used, GPT_BYTE -= gap_head_used;
}
else
{
EMACS_INT offset = dst - coding->destination;
if (BUFFERP (coding->dst_object))
- coding_alloc_by_making_gap (coding, offset, nbytes);
+ {
+ struct buffer *buf = XBUFFER (coding->dst_object);
+
+ coding_alloc_by_making_gap (coding, dst - BUF_GPT_ADDR (buf), nbytes);
+ }
else
coding_alloc_by_realloc (coding, nbytes);
record_conversion_result (coding, CODING_RESULT_SUCCESS);
int consumed_chars = 0, consumed_chars_base;
int multibytep = coding->src_multibyte;
Lisp_Object attr, charset_list;
+ int eol_crlf = EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
+ int byte_after_cr = -1;
CODING_GET_INFO (coding, attr, charset_list);
if (charbuf >= charbuf_end)
break;
- ONE_MORE_BYTE (c1);
+ if (byte_after_cr >= 0)
+ c1 = byte_after_cr, byte_after_cr = -1;
+ else
+ ONE_MORE_BYTE (c1);
if (c1 < 0)
{
c = - c1;
}
else if (UTF_8_1_OCTET_P(c1))
{
+ if (eol_crlf && c1 == '\r')
+ ONE_MORE_BYTE (byte_after_cr);
c = c1;
}
else
}
else
{
- CHAR_STRING_ADVANCE (c, pend);
+ CHAR_STRING_ADVANCE_NO_UNIFY (c, pend);
for (p = str; p < pend; p++)
EMIT_ONE_BYTE (*p);
}
if (CHAR_BYTE8_P (c))
*dst++ = CHAR_TO_BYTE8 (c);
else
- dst += CHAR_STRING (c, dst);
+ CHAR_STRING_ADVANCE_NO_UNIFY (c, dst);
produced_chars++;
}
}
enum utf_16_endian_type endian = CODING_UTF_16_ENDIAN (coding);
int surrogate = CODING_UTF_16_SURROGATE (coding);
Lisp_Object attr, charset_list;
+ int eol_crlf = EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
+ int byte_after_cr1 = -1, byte_after_cr2 = -1;
CODING_GET_INFO (coding, attr, charset_list);
if (charbuf + 2 >= charbuf_end)
break;
- ONE_MORE_BYTE (c1);
+ if (byte_after_cr1 >= 0)
+ c1 = byte_after_cr1, byte_after_cr1 = -1;
+ else
+ ONE_MORE_BYTE (c1);
if (c1 < 0)
{
*charbuf++ = -c1;
continue;
}
- ONE_MORE_BYTE (c2);
+ if (byte_after_cr2 >= 0)
+ c2 = byte_after_cr2, byte_after_cr2 = -1;
+ else
+ ONE_MORE_BYTE (c2);
if (c2 < 0)
{
*charbuf++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
}
c = (endian == utf_16_big_endian
? ((c1 << 8) | c2) : ((c2 << 8) | c1));
+
if (surrogate)
{
if (! UTF_16_LOW_SURROGATE_P (c))
if (UTF_16_HIGH_SURROGATE_P (c))
CODING_UTF_16_SURROGATE (coding) = surrogate = c;
else
- *charbuf++ = c;
+ {
+ if (eol_crlf && c == '\r')
+ {
+ ONE_MORE_BYTE (byte_after_cr1);
+ ONE_MORE_BYTE (byte_after_cr2);
+ }
+ *charbuf++ = c;
+ }
}
}
{
if (c >= 0xA0)
{
- /* Old style component character of a compostion. */
+ /* Old style component character of a composition. */
if (c == 0xA0)
{
ONE_MORE_BYTE (c);
value 0. */
#define DECODE_EMACS_MULE_COMPOSITION_CHAR(buf) \
- if (1) \
+ do \
{ \
int c; \
int nbytes, nchars; \
src += nbytes; \
consumed_chars += nchars; \
} \
- else
+ while (0)
/* Decode a composition rule represented as a component of composition
int char_offset = coding->produced_char;
int last_offset = char_offset;
int last_id = charset_ascii;
+ int eol_crlf = EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
+ int byte_after_cr = -1;
CODING_GET_INFO (coding, attrs, charset_list);
if (charbuf >= charbuf_end)
break;
- ONE_MORE_BYTE (c);
+ if (byte_after_cr >= 0)
+ c = byte_after_cr, byte_after_cr = -1;
+ else
+ ONE_MORE_BYTE (c);
if (c < 0)
{
*charbuf++ = -c;
}
else if (c < 0x80)
{
+ if (eol_crlf && c == '\r')
+ ONE_MORE_BYTE (byte_after_cr);
*charbuf++ = c;
char_offset++;
}
int char_offset = coding->produced_char;
int last_offset = char_offset;
int last_id = charset_ascii;
+ int eol_crlf = EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
+ int byte_after_cr = -1;
CODING_GET_INFO (coding, attrs, charset_list);
setup_iso_safe_charsets (attrs);
if (charbuf >= charbuf_end)
break;
- ONE_MORE_BYTE (c1);
+ if (byte_after_cr >= 0)
+ c1 = byte_after_cr, byte_after_cr = -1;
+ else
+ ONE_MORE_BYTE (c1);
if (c1 < 0)
goto invalid_code;
break;
case ISO_control_0:
+ if (eol_crlf && c1 == '\r')
+ ONE_MORE_BYTE (byte_after_cr);
MAYBE_FINISH_COMPOSITION ();
charset = CHARSET_FROM_ID (charset_ascii);
break;
int char_offset = coding->produced_char;
int last_offset = char_offset;
int last_id = charset_ascii;
+ int eol_crlf = EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
+ int byte_after_cr = -1;
CODING_GET_INFO (coding, attrs, charset_list);
if (charbuf >= charbuf_end)
break;
- ONE_MORE_BYTE (c);
+ if (byte_after_cr >= 0)
+ c = byte_after_cr, byte_after_cr = -1;
+ else
+ ONE_MORE_BYTE (c);
if (c < 0)
goto invalid_code;
if (c < 0x80)
- charset = charset_roman;
+ {
+ if (eol_crlf && c == '\r')
+ ONE_MORE_BYTE (byte_after_cr);
+ charset = charset_roman;
+ }
else if (c == 0x80 || c == 0xA0)
goto invalid_code;
else if (c >= 0xA1 && c <= 0xDF)
int char_offset = coding->produced_char;
int last_offset = char_offset;
int last_id = charset_ascii;
+ int eol_crlf = EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
+ int byte_after_cr = -1;
CODING_GET_INFO (coding, attrs, charset_list);
val = charset_list;
if (charbuf >= charbuf_end)
break;
- ONE_MORE_BYTE (c);
+ if (byte_after_cr >= 0)
+ c = byte_after_cr, byte_after_cr = -1;
+ else
+ ONE_MORE_BYTE (c);
if (c < 0)
goto invalid_code;
if (c < 0x80)
- charset = charset_roman;
+ {
+ if (eol_crlf && c == '\r')
+ ONE_MORE_BYTE (byte_after_cr);
+ charset = charset_roman;
+ }
else
{
/* BIG5 -> Big5 */
decode_coding_raw_text (coding)
struct coding_system *coding;
{
+ int eol_crlf = EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
+
coding->chars_at_source = 1;
- coding->consumed_char = 0;
- coding->consumed = 0;
- record_conversion_result (coding, CODING_RESULT_SUCCESS);
+ coding->consumed_char = coding->src_chars;
+ coding->consumed = coding->src_bytes;
+ if (eol_crlf && coding->source[coding->src_bytes - 1] == '\r')
+ {
+ coding->consumed_char--;
+ coding->consumed--;
+ record_conversion_result (coding, CODING_RESULT_INSUFFICIENT_SRC);
+ }
+ else
+ record_conversion_result (coding, CODING_RESULT_SUCCESS);
}
static int
int char_offset = coding->produced_char;
int last_offset = char_offset;
int last_id = charset_ascii;
+ int eol_crlf = EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
+ int byte_after_cr = -1;
CODING_GET_INFO (coding, attrs, charset_list);
valids = AREF (attrs, coding_attr_charset_valids);
if (charbuf >= charbuf_end)
break;
- ONE_MORE_BYTE (c);
+ if (byte_after_cr >= 0)
+ {
+ c = byte_after_cr;
+ byte_after_cr = -1;
+ }
+ else
+ {
+ ONE_MORE_BYTE (c);
+ if (eol_crlf && c == '\r')
+ ONE_MORE_BYTE (byte_after_cr);
+ }
if (c < 0)
goto invalid_code;
code = c;
pos_end--;
}
pos++;
- pos_byte += BYTES_BY_CHAR_HEAD (*p);
+ if (coding->dst_multibyte)
+ pos_byte += BYTES_BY_CHAR_HEAD (*p);
+ else
+ pos_byte++;
}
}
coding->produced -= n;
{
unsigned char *dst = coding->destination + coding->produced;
unsigned char *dst_end = coding->destination + coding->dst_bytes;
- int produced;
- int produced_chars = 0;
+ EMACS_INT produced;
+ EMACS_INT produced_chars = 0;
int carryover = 0;
if (! coding->chars_at_source)
{
- /* Characters are in coding->charbuf. */
+ /* Source characters are in coding->charbuf. */
int *buf = coding->charbuf;
int *buf_end = buf + coding->charbuf_used;
- if (BUFFERP (coding->src_object)
- && EQ (coding->src_object, coding->dst_object))
- dst_end = ((unsigned char *) coding->source) + coding->consumed;
+ if (EQ (coding->src_object, coding->dst_object))
+ {
+ coding_set_source (coding);
+ dst_end = ((unsigned char *) coding->source) + coding->consumed;
+ }
while (buf < buf_end)
{
buf_end - buf
+ MAX_MULTIBYTE_LENGTH * to_nchars,
dst);
- dst_end = coding->destination + coding->dst_bytes;
+ if (EQ (coding->src_object, coding->dst_object))
+ {
+ coding_set_source (coding);
+ dst_end = ((unsigned char *) coding->source) + coding->consumed;
+ }
+ else
+ dst_end = coding->destination + coding->dst_bytes;
}
for (i = 0; i < to_nchars; i++)
c = XINT (AREF (trans, i));
if (coding->dst_multibyte
|| ! CHAR_BYTE8_P (c))
- CHAR_STRING_ADVANCE (c, dst);
+ CHAR_STRING_ADVANCE_NO_UNIFY (c, dst);
else
*dst++ = CHAR_TO_BYTE8 (c);
}
}
else
{
+ /* Source characters are at coding->source. */
const unsigned char *src = coding->source;
- const unsigned char *src_end = src + coding->src_bytes;
- Lisp_Object eol_type;
-
- eol_type = CODING_ID_EOL_TYPE (coding->id);
+ const unsigned char *src_end = src + coding->consumed;
+ if (EQ (coding->dst_object, coding->src_object))
+ dst_end = (unsigned char *) src;
if (coding->src_multibyte != coding->dst_multibyte)
{
if (coding->src_multibyte)
{
int multibytep = 1;
- int consumed_chars;
+ EMACS_INT consumed_chars;
while (1)
{
int c;
ONE_MORE_BYTE (c);
- if (c == '\r')
+ if (dst == dst_end)
{
- if (EQ (eol_type, Qdos))
+ if (EQ (coding->src_object, coding->dst_object))
+ dst_end = (unsigned char *) src;
+ if (dst == dst_end)
{
- if (src == src_end)
- {
- record_conversion_result
- (coding, CODING_RESULT_INSUFFICIENT_SRC);
- goto no_more_source;
- }
- if (*src == '\n')
- c = *src++;
+ EMACS_INT offset = src - coding->source;
+
+ dst = alloc_destination (coding, src_end - src + 1,
+ dst);
+ dst_end = coding->destination + coding->dst_bytes;
+ coding_set_source (coding);
+ src = coding->source + offset;
+ src_end = coding->source + coding->src_bytes;
+ if (EQ (coding->src_object, coding->dst_object))
+ dst_end = (unsigned char *) src;
}
- else if (EQ (eol_type, Qmac))
- c = '\n';
- }
- if (dst == dst_end)
- {
- coding->consumed = src - coding->source;
-
- if (EQ (coding->src_object, coding->dst_object))
- dst_end = (unsigned char *) src;
- if (dst == dst_end)
- {
- dst = alloc_destination (coding, src_end - src + 1,
- dst);
- dst_end = coding->destination + coding->dst_bytes;
- coding_set_source (coding);
- src = coding->source + coding->consumed;
- src_end = coding->source + coding->src_bytes;
- }
}
*dst++ = c;
produced_chars++;
int multibytep = 1;
int c = *src++;
- if (c == '\r')
- {
- if (EQ (eol_type, Qdos))
- {
- if (src < src_end
- && *src == '\n')
- c = *src++;
- }
- else if (EQ (eol_type, Qmac))
- c = '\n';
- }
if (dst >= dst_end - 1)
{
- coding->consumed = src - coding->source;
-
if (EQ (coding->src_object, coding->dst_object))
dst_end = (unsigned char *) src;
if (dst >= dst_end - 1)
{
- dst = alloc_destination (coding, src_end - src + 2,
- dst);
+ EMACS_INT offset = src - coding->source;
+ EMACS_INT more_bytes;
+
+ if (EQ (coding->src_object, coding->dst_object))
+ more_bytes = ((src_end - src) / 2) + 2;
+ else
+ more_bytes = src_end - src + 2;
+ dst = alloc_destination (coding, more_bytes, dst);
dst_end = coding->destination + coding->dst_bytes;
coding_set_source (coding);
- src = coding->source + coding->consumed;
+ src = coding->source + offset;
src_end = coding->source + coding->src_bytes;
+ if (EQ (coding->src_object, coding->dst_object))
+ dst_end = (unsigned char *) src;
}
}
EMIT_ONE_BYTE (c);
{
if (!EQ (coding->src_object, coding->dst_object))
{
- int require = coding->src_bytes - coding->dst_bytes;
+ EMACS_INT require = coding->src_bytes - coding->dst_bytes;
if (require > 0)
{
src_end = coding->source + coding->src_bytes;
}
}
- produced_chars = coding->src_chars;
+ produced_chars = coding->consumed_char;
while (src < src_end)
- {
- int c = *src++;
-
- if (c == '\r')
- {
- if (EQ (eol_type, Qdos))
- {
- if (src < src_end
- && *src == '\n')
- c = *src++;
- produced_chars--;
- }
- else if (EQ (eol_type, Qmac))
- c = '\n';
- }
- *dst++ = c;
- }
+ *dst++ = *src++;
}
- coding->consumed = coding->src_bytes;
- coding->consumed_char = coding->src_chars;
}
produced = dst - (coding->destination + coding->produced);
if (coding->encoder == encode_coding_raw_text)
c = *src++, pos++;
else if ((bytes = MULTIBYTE_LENGTH (src, src_end)) > 0)
- c = STRING_CHAR_ADVANCE (src), pos += bytes;
+ c = STRING_CHAR_ADVANCE_NO_UNIFY (src), pos += bytes;
else
c = BYTE8_TO_CHAR (*src), src++, pos++;
}
else
- c = STRING_CHAR_ADVANCE (src), pos++;
+ c = STRING_CHAR_ADVANCE_NO_UNIFY (src), pos++;
if ((c == '\r') && (coding->mode & CODING_MODE_SELECTIVE_DISPLAY))
c = '\n';
if (! EQ (eol_type, Qunix))
EMACS_INT chars = to - from;
EMACS_INT bytes = to_byte - from_byte;
Lisp_Object attrs;
- Lisp_Object buffer;
int saved_pt = -1, saved_pt_byte;
+ int need_marker_adjustment = 0;
+ Lisp_Object old_deactivate_mark;
- buffer = Fcurrent_buffer ();
+ old_deactivate_mark = Vdeactivate_mark;
if (NILP (dst_object))
{
move_gap_both (from, from_byte);
if (EQ (src_object, dst_object))
{
+ struct Lisp_Marker *tail;
+
+ for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
+ {
+ tail->need_adjustment
+ = tail->charpos == (tail->insertion_type ? from : to);
+ need_marker_adjustment |= tail->need_adjustment;
+ }
saved_pt = PT, saved_pt_byte = PT_BYTE;
TEMP_SET_PT_BOTH (from, from_byte);
+ current_buffer->text->inhibit_shrinking = 1;
del_range_both (from, from_byte, to, to_byte, 1);
coding->src_pos = -chars;
coding->src_pos_byte = -bytes;
|| (! NILP (CODING_ATTR_POST_READ (attrs))
&& NILP (dst_object)))
{
- coding->dst_object = code_conversion_save (1, 1);
+ coding->dst_multibyte = !CODING_FOR_UNIBYTE (coding);
+ coding->dst_object = code_conversion_save (1, coding->dst_multibyte);
coding->dst_pos = BEG;
coding->dst_pos_byte = BEG_BYTE;
- coding->dst_multibyte = 1;
}
else if (BUFFERP (dst_object))
{
{
code_conversion_save (0, 0);
coding->dst_object = Qnil;
- coding->dst_multibyte = 1;
+ /* Most callers presume this will return a multibyte result, and they
+ won't use `binary' or `raw-text' anyway, so let's not worry about
+ CODING_FOR_UNIBYTE. */
+ coding->dst_multibyte = Qt;
}
decode_coding (coding);
if (! NILP (CODING_ATTR_POST_READ (attrs)))
{
- struct gcpro gcpro1, gcpro2;
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
Lisp_Object val;
TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
- GCPRO2 (coding->src_object, coding->dst_object);
+ GCPRO5 (coding->src_object, coding->dst_object, src_object, dst_object,
+ old_deactivate_mark);
val = safe_call1 (CODING_ATTR_POST_READ (attrs),
make_number (coding->produced_char));
UNGCPRO;
set_buffer_internal (XBUFFER (coding->dst_object));
if (dst_bytes < coding->produced)
{
- destination
- = (unsigned char *) xrealloc (destination, coding->produced);
+ destination = xrealloc (destination, coding->produced);
if (! destination)
{
record_conversion_result (coding,
As we have moved PT while replacing the original buffer
contents, we must recover it now. */
set_buffer_internal (XBUFFER (src_object));
+ current_buffer->text->inhibit_shrinking = 0;
if (saved_pt < from)
TEMP_SET_PT_BOTH (saved_pt, saved_pt_byte);
else if (saved_pt < from + chars)
else
TEMP_SET_PT_BOTH (saved_pt + (coding->produced - bytes),
saved_pt_byte + (coding->produced - bytes));
+
+ if (need_marker_adjustment)
+ {
+ struct Lisp_Marker *tail;
+
+ for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
+ if (tail->need_adjustment)
+ {
+ tail->need_adjustment = 0;
+ if (tail->insertion_type)
+ {
+ tail->bytepos = from_byte;
+ tail->charpos = from;
+ }
+ else
+ {
+ tail->bytepos = from_byte + coding->produced;
+ tail->charpos
+ = (NILP (current_buffer->enable_multibyte_characters)
+ ? tail->bytepos : from + coding->produced_char);
+ }
+ }
+ }
}
+ Vdeactivate_mark = old_deactivate_mark;
unbind_to (count, coding->dst_object);
}
EMACS_INT chars = to - from;
EMACS_INT bytes = to_byte - from_byte;
Lisp_Object attrs;
- Lisp_Object buffer;
int saved_pt = -1, saved_pt_byte;
+ int need_marker_adjustment = 0;
int kill_src_buffer = 0;
+ Lisp_Object old_deactivate_mark;
- buffer = Fcurrent_buffer ();
+ old_deactivate_mark = Vdeactivate_mark;
coding->src_object = src_object;
coding->src_chars = chars;
attrs = CODING_ID_ATTRS (coding->id);
+ if (EQ (src_object, dst_object))
+ {
+ struct Lisp_Marker *tail;
+
+ for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
+ {
+ tail->need_adjustment
+ = tail->charpos == (tail->insertion_type ? from : to);
+ need_marker_adjustment |= tail->need_adjustment;
+ }
+ }
+
if (! NILP (CODING_ATTR_PRE_WRITE (attrs)))
{
coding->src_object = code_conversion_save (1, coding->src_multibyte);
{
Lisp_Object args[3];
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
+ GCPRO5 (coding->src_object, coding->dst_object, src_object, dst_object,
+ old_deactivate_mark);
args[0] = CODING_ATTR_PRE_WRITE (attrs);
args[1] = make_number (BEG);
args[2] = make_number (Z);
safe_call (3, args);
+ UNGCPRO;
}
if (XBUFFER (coding->src_object) != current_buffer)
kill_src_buffer = 1;
else
TEMP_SET_PT_BOTH (saved_pt + (coding->produced - bytes),
saved_pt_byte + (coding->produced - bytes));
+
+ if (need_marker_adjustment)
+ {
+ struct Lisp_Marker *tail;
+
+ for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
+ if (tail->need_adjustment)
+ {
+ tail->need_adjustment = 0;
+ if (tail->insertion_type)
+ {
+ tail->bytepos = from_byte;
+ tail->charpos = from;
+ }
+ else
+ {
+ tail->bytepos = from_byte + coding->produced;
+ tail->charpos
+ = (NILP (current_buffer->enable_multibyte_characters)
+ ? tail->bytepos : from + coding->produced_char);
+ }
+ }
+ }
}
if (kill_src_buffer)
Fkill_buffer (coding->src_object);
+
+ Vdeactivate_mark = old_deactivate_mark;
unbind_to (count, Qnil);
}
detect_coding_system (src, src_chars, src_bytes, highest, multibytep,
coding_system)
const unsigned char *src;
- int src_chars, src_bytes, highest;
+ EMACS_INT src_chars, src_bytes;
+ int highest;
int multibytep;
Lisp_Object coding_system;
{
START and END are buffer positions.
Optional 4th arguments DESTINATION specifies where the decoded text goes.
-If nil, the region between START and END is replace by the decoded text.
+If nil, the region between START and END is replaced by the decoded text.
If buffer, the decoded text is inserted in the buffer.
If t, the decoded text is returned.
If set, this function is called to force a user to select a proper
coding system which can encode the text in the case that a default
-coding system used in each operation can't encode the text.
+coding system used in each operation can't encode the text. The
+function should take care that the buffer is not modified while
+the coding system is being selected.
The default value is `select-safe-coding-system' (which see). */);
Vselect_safe_coding_system_function = Qnil;