diff options
Diffstat (limited to 'src/coding.c')
-rw-r--r-- | src/coding.c | 97 |
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 |