summaryrefslogtreecommitdiff
path: root/src/coding.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/coding.c')
-rw-r--r--src/coding.c97
1 files changed, 67 insertions, 30 deletions
diff --git a/src/coding.c b/src/coding.c
index a2b3ad9a49b..c51ceb95475 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -314,9 +314,9 @@ static Lisp_Object Vbig5_coding_system;
/* ISO2022 section */
#define CODING_ISO_INITIAL(coding, reg) \
- (XFIXNUM (AREF (AREF (CODING_ID_ATTRS ((coding)->id), \
- coding_attr_iso_initial), \
- reg)))
+ XFIXNUM (AREF (AREF (CODING_ID_ATTRS ((coding)->id), \
+ coding_attr_iso_initial), \
+ reg))
#define CODING_ISO_REQUEST(coding, charset_id) \
@@ -466,7 +466,7 @@ enum iso_code_class_type
#define CODING_CCL_ENCODER(coding) \
AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_encoder)
#define CODING_CCL_VALIDS(coding) \
- (SDATA (AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_valids)))
+ SDATA (AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_valids))
/* Index for each coding category in `coding_categories' */
@@ -614,10 +614,11 @@ inhibit_flag (int encoded_flag, bool var)
static bool
growable_destination (struct coding_system *coding)
{
- return STRINGP (coding->dst_object) || BUFFERP (coding->dst_object);
+ return (STRINGP (coding->dst_object)
+ || BUFFERP (coding->dst_object)
+ || NILP (coding->dst_object));
}
-
/* Safely get one byte from the source text pointed by SRC which ends
at SRC_END, and set C to that byte. If there are not enough bytes
in the source, it jumps to 'no_more_source'. If MULTIBYTEP,
@@ -651,6 +652,12 @@ growable_destination (struct coding_system *coding)
consumed_chars++; \
} while (0)
+/* Suppress clang warnings about consumed_chars never being used.
+ Although correct, the warnings are too much trouble to code around. */
+#if 13 <= __clang_major__ - defined __apple_build_version__
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
/* Safely get two bytes from the source text pointed by SRC which ends
at SRC_END, and set C1 and C2 to those bytes while skipping the
heading multibyte characters. If there are not enough bytes in the
@@ -983,7 +990,7 @@ static void
coding_alloc_by_realloc (struct coding_system *coding, ptrdiff_t bytes)
{
ptrdiff_t newbytes;
- if (INT_ADD_WRAPV (coding->dst_bytes, bytes, &newbytes)
+ if (ckd_add (&newbytes, coding->dst_bytes, bytes)
|| SIZE_MAX < newbytes)
string_overflow ();
coding->destination = xrealloc (coding->destination, newbytes);
@@ -4192,12 +4199,12 @@ decode_coding_iso_2022 (struct coding_system *coding)
#define ENCODE_ISO_CHARACTER(charset, c) \
do { \
unsigned code; \
- CODING_ENCODE_CHAR (coding, dst, dst_end, (charset), (c), code); \
+ CODING_ENCODE_CHAR (coding, dst, dst_end, charset, c, code); \
\
if (CHARSET_DIMENSION (charset) == 1) \
- ENCODE_ISO_CHARACTER_DIMENSION1 ((charset), code); \
+ ENCODE_ISO_CHARACTER_DIMENSION1 (charset, code); \
else \
- ENCODE_ISO_CHARACTER_DIMENSION2 ((charset), code >> 8, code & 0xFF); \
+ ENCODE_ISO_CHARACTER_DIMENSION2 (charset, code >> 8, code & 0xFF); \
} while (0)
@@ -5482,7 +5489,7 @@ decode_coding_charset (struct coding_system *coding)
{
int c;
Lisp_Object val;
- struct charset *charset;
+ struct charset *charset UNINIT;
int dim;
int len = 1;
unsigned code;
@@ -6999,7 +7006,6 @@ get_translation (Lisp_Object trans, int *buf, int *buf_end, ptrdiff_t *nchars)
return Qnil;
}
-
static int
produce_chars (struct coding_system *coding, Lisp_Object translation_table,
bool last_block)
@@ -7053,12 +7059,14 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
{
eassert (growable_destination (coding));
ptrdiff_t dst_size;
- if (INT_MULTIPLY_WRAPV (to_nchars, MAX_MULTIBYTE_LENGTH,
- &dst_size)
- || INT_ADD_WRAPV (buf_end - buf, dst_size, &dst_size))
+ if (ckd_mul (&dst_size, to_nchars, MAX_MULTIBYTE_LENGTH)
+ || ckd_add (&dst_size, dst_size, buf_end - buf))
memory_full (SIZE_MAX);
dst = alloc_destination (coding, dst_size, dst);
- if (EQ (coding->src_object, coding->dst_object))
+ if (EQ (coding->src_object, coding->dst_object)
+ /* Input and output are not C buffers, which are safe to
+ assume to be different. */
+ && !NILP (coding->src_object))
{
coding_set_source (coding);
dst_end = (((unsigned char *) coding->source)
@@ -7093,7 +7101,10 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
const unsigned char *src = coding->source;
const unsigned char *src_end = src + coding->consumed;
- if (EQ (coding->dst_object, coding->src_object))
+ if (EQ (coding->dst_object, coding->src_object)
+ /* Input and output are not C buffers, which are safe to
+ assume to be different. */
+ && !NILP (coding->src_object))
{
eassert (growable_destination (coding));
dst_end = (unsigned char *) src;
@@ -7114,7 +7125,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
if (dst == dst_end)
{
eassert (growable_destination (coding));
- if (EQ (coding->src_object, coding->dst_object))
+ if (EQ (coding->src_object, coding->dst_object)
+ && !NILP (coding->src_object))
dst_end = (unsigned char *) src;
if (dst == dst_end)
{
@@ -7126,7 +7138,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
coding_set_source (coding);
src = coding->source + offset;
src_end = coding->source + coding->consumed;
- if (EQ (coding->src_object, coding->dst_object))
+ if (EQ (coding->src_object, coding->dst_object)
+ && !NILP (coding->src_object))
dst_end = (unsigned char *) src;
}
}
@@ -7145,14 +7158,16 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
if (dst >= dst_end - 1)
{
eassert (growable_destination (coding));
- if (EQ (coding->src_object, coding->dst_object))
+ if (EQ (coding->src_object, coding->dst_object)
+ && !NILP (coding->src_object))
dst_end = (unsigned char *) src;
if (dst >= dst_end - 1)
{
ptrdiff_t offset = src - coding->source;
ptrdiff_t more_bytes;
- if (EQ (coding->src_object, coding->dst_object))
+ if (EQ (coding->src_object, coding->dst_object)
+ && !NILP (coding->src_object))
more_bytes = ((src_end - src) / 2) + 2;
else
more_bytes = src_end - src + 2;
@@ -7161,7 +7176,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
coding_set_source (coding);
src = coding->source + offset;
src_end = coding->source + coding->consumed;
- if (EQ (coding->src_object, coding->dst_object))
+ if (EQ (coding->src_object, coding->dst_object)
+ && !NILP (coding->src_object))
dst_end = (unsigned char *) src;
}
}
@@ -7170,7 +7186,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
}
else
{
- if (!EQ (coding->src_object, coding->dst_object))
+ if (!(EQ (coding->src_object, coding->dst_object)
+ && !NILP (coding->src_object)))
{
ptrdiff_t require = coding->src_bytes - coding->dst_bytes;
@@ -7653,8 +7670,7 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
if (pos == stop_charset)
buf = handle_charset_annotation (pos, end_pos, coding,
buf, &stop_charset);
- stop = (stop_composition < stop_charset
- ? stop_composition : stop_charset);
+ stop = min (stop_composition, stop_charset);
}
if (! multibytep)
@@ -8165,7 +8181,7 @@ decode_coding_object (struct coding_system *coding,
Fcons (undo_list, Fcurrent_buffer ()));
bset_undo_list (current_buffer, Qt);
TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
- val = safe_call1 (CODING_ATTR_POST_READ (attrs),
+ val = safe_calln (CODING_ATTR_POST_READ (attrs),
make_fixnum (coding->produced_char));
CHECK_FIXNAT (val);
coding->produced_char += Z - prev_Z;
@@ -8331,7 +8347,7 @@ encode_coding_object (struct coding_system *coding,
set_buffer_internal (XBUFFER (coding->src_object));
}
- safe_call2 (CODING_ATTR_PRE_WRITE (attrs),
+ safe_calln (CODING_ATTR_PRE_WRITE (attrs),
make_fixnum (BEG), make_fixnum (Z));
if (XBUFFER (coding->src_object) != current_buffer)
kill_src_buffer = 1;
@@ -8489,7 +8505,7 @@ preferred_coding_system (void)
return CODING_ID_NAME (id);
}
-#if defined (WINDOWSNT) || defined (CYGWIN)
+#if defined (WINDOWSNT) || defined (CYGWIN) || defined HAVE_ANDROID
Lisp_Object
from_unicode (Lisp_Object str)
@@ -8507,10 +8523,31 @@ from_unicode (Lisp_Object str)
Lisp_Object
from_unicode_buffer (const wchar_t *wstr)
{
+#if defined WINDOWSNT || defined CYGWIN
/* We get one of the two final null bytes for free. */
ptrdiff_t len = 1 + sizeof (wchar_t) * wcslen (wstr);
AUTO_STRING_WITH_LEN (str, (char *) wstr, len);
return from_unicode (str);
+#else
+ /* This code is used only on Android, where little endian UTF-16
+ strings are extended to 32-bit wchar_t. */
+
+ uint16_t *words;
+ size_t length, i;
+
+ length = wcslen (wstr) + 1;
+
+ USE_SAFE_ALLOCA;
+ SAFE_NALLOCA (words, sizeof *words, length);
+
+ for (i = 0; i < length - 1; ++i)
+ words[i] = wstr[i];
+
+ words[i] = '\0';
+ AUTO_STRING_WITH_LEN (str, (char *) words,
+ (length - 1) * sizeof *words);
+ return unbind_to (sa_count, from_unicode (str));
+#endif
}
wchar_t *
@@ -8530,7 +8567,7 @@ to_unicode (Lisp_Object str, Lisp_Object *buf)
return WCSDATA (*buf);
}
-#endif /* WINDOWSNT || CYGWIN */
+#endif /* WINDOWSNT || CYGWIN || HAVE_ANDROID */
/*** 8. Emacs Lisp library functions ***/
@@ -11740,7 +11777,7 @@ syms_of_coding (void)
DEFSYM (Qutf_8_unix, "utf-8-unix");
DEFSYM (Qutf_8_emacs, "utf-8-emacs");
-#if defined (WINDOWSNT) || defined (CYGWIN)
+#if defined (WINDOWSNT) || defined (CYGWIN) || defined HAVE_ANDROID
/* No, not utf-16-le: that one has a BOM. */
DEFSYM (Qutf_16le, "utf-16le");
#endif