/* 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
#include "composite.h"
#include "coding.h"
#include "window.h"
+#include "frame.h"
+#include "termhooks.h"
Lisp_Object Vcoding_system_hash_table;
Lisp_Object Qinsufficient_source, Qinconsistent_eol, Qinvalid_source;
Lisp_Object Qinterrupted, Qinsufficient_memory;
+extern Lisp_Object Qcompletion_ignore_case;
+
/* If a symbol has this property, evaluate the value to define the
symbol as a coding system. */
static Lisp_Object Qcoding_system_define_form;
/* Flag to make buffer-file-coding-system inherit from process-coding. */
int inherit_process_coding_system;
-/* Coding system to be used to encode text for terminal display. */
-struct coding_system terminal_coding;
-
/* Coding system to be used to encode text for terminal display when
terminal coding system is nil. */
struct coding_system safe_terminal_coding;
-/* Coding system of what is sent from terminal keyboard. */
-struct coding_system keyboard_coding;
-
Lisp_Object Vfile_coding_system_alist;
Lisp_Object Vprocess_coding_system_alist;
Lisp_Object Vnetwork_coding_system_alist;
} 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);
}
DEFUN ("read-coding-system", Fread_coding_system, Sread_coding_system, 1, 2, 0,
doc: /* Read a coding system from the minibuffer, prompting with string PROMPT.
-If the user enters null input, return second argument DEFAULT-CODING-SYSTEM. */)
+If the user enters null input, return second argument DEFAULT-CODING-SYSTEM.
+Ignores case when completing coding systems (all Emacs coding systems
+are lower-case). */)
(prompt, default_coding_system)
Lisp_Object prompt, default_coding_system;
{
Lisp_Object val;
+ int count = SPECPDL_INDEX ();
+
if (SYMBOLP (default_coding_system))
- XSETSTRING (default_coding_system, XPNTR (SYMBOL_NAME (default_coding_system)));
+ default_coding_system = SYMBOL_NAME (default_coding_system);
+ specbind (Qcompletion_ignore_case, Qt);
val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,
Qt, Qnil, Qcoding_system_history,
default_coding_system, Qnil);
+ unbind_to (count, Qnil);
return (SCHARS (val) == 0 ? Qnil : Fintern (val, 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.
}
\f
-DEFUN ("set-terminal-coding-system-internal",
- Fset_terminal_coding_system_internal,
- Sset_terminal_coding_system_internal, 1, 1, 0,
+DEFUN ("set-terminal-coding-system-internal", Fset_terminal_coding_system_internal,
+ Sset_terminal_coding_system_internal, 1, 2, 0,
doc: /* Internal use only. */)
- (coding_system)
+ (coding_system, terminal)
Lisp_Object coding_system;
+ Lisp_Object terminal;
{
+ struct coding_system *terminal_coding = TERMINAL_TERMINAL_CODING (get_terminal (terminal, 1));
CHECK_SYMBOL (coding_system);
- setup_coding_system (Fcheck_coding_system (coding_system),
- &terminal_coding);
-
+ setup_coding_system (Fcheck_coding_system (coding_system), terminal_coding);
/* We had better not send unsafe characters to terminal. */
- terminal_coding.mode |= CODING_MODE_SAFE_ENCODING;
+ terminal_coding->mode |= CODING_MODE_SAFE_ENCODING;
/* Characer composition should be disabled. */
- terminal_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
- terminal_coding.src_multibyte = 1;
- terminal_coding.dst_multibyte = 0;
+ terminal_coding->common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
+ terminal_coding->src_multibyte = 1;
+ terminal_coding->dst_multibyte = 0;
return Qnil;
}
return Qnil;
}
-DEFUN ("terminal-coding-system",
- Fterminal_coding_system, Sterminal_coding_system, 0, 0, 0,
- doc: /* Return coding system specified for terminal output. */)
- ()
+DEFUN ("terminal-coding-system", Fterminal_coding_system,
+ Sterminal_coding_system, 0, 1, 0,
+ doc: /* Return coding system specified for terminal output on the given terminal.
+TERMINAL may be a terminal id, a frame, or nil for the selected
+frame's terminal device. */)
+ (terminal)
+ Lisp_Object terminal;
{
- Lisp_Object coding_system;
+ struct coding_system *terminal_coding
+ = TERMINAL_TERMINAL_CODING (get_terminal (terminal, 1));
+ Lisp_Object coding_system = CODING_ID_NAME (terminal_coding->id);
- coding_system = CODING_ID_NAME (terminal_coding.id);
/* For backward compatibility, return nil if it is `undecided'. */
return (! EQ (coding_system, Qundecided) ? coding_system : Qnil);
}
-DEFUN ("set-keyboard-coding-system-internal",
- Fset_keyboard_coding_system_internal,
- Sset_keyboard_coding_system_internal, 1, 1, 0,
+DEFUN ("set-keyboard-coding-system-internal", Fset_keyboard_coding_system_internal,
+ Sset_keyboard_coding_system_internal, 1, 2, 0,
doc: /* Internal use only. */)
- (coding_system)
+ (coding_system, terminal)
Lisp_Object coding_system;
+ Lisp_Object terminal;
{
+ struct terminal *t = get_terminal (terminal, 1);
CHECK_SYMBOL (coding_system);
setup_coding_system (Fcheck_coding_system (coding_system),
- &keyboard_coding);
+ TERMINAL_KEYBOARD_CODING (t));
/* Characer composition should be disabled. */
- keyboard_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
+ TERMINAL_KEYBOARD_CODING (t)->common_flags
+ &= ~CODING_ANNOTATE_COMPOSITION_MASK;
return Qnil;
}
DEFUN ("keyboard-coding-system",
- Fkeyboard_coding_system, Skeyboard_coding_system, 0, 0, 0,
+ Fkeyboard_coding_system, Skeyboard_coding_system, 0, 1, 0,
doc: /* Return coding system specified for decoding keyboard input. */)
- ()
+ (terminal)
+ Lisp_Object terminal;
{
- return CODING_ID_NAME (keyboard_coding.id);
+ return CODING_ID_NAME (TERMINAL_KEYBOARD_CODING
+ (get_terminal (terminal, 1))->id);
}
\f
else
{
charset_list = Fcopy_sequence (charset_list);
- for (tail = charset_list; !NILP (tail); tail = Fcdr (tail))
+ for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
{
struct charset *charset;
- val = Fcar (tail);
+ val = XCAR (tail);
CHECK_CHARSET_GET_CHARSET (val, charset);
if (EQ (coding_type, Qiso_2022)
? CHARSET_ISO_FINAL (charset) < 0
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;
Fdefine_coding_system_internal (coding_arg_max, args);
}
- setup_coding_system (Qno_conversion, &keyboard_coding);
- setup_coding_system (Qundecided, &terminal_coding);
setup_coding_system (Qno_conversion, &safe_terminal_coding);
{