Mercurial > emacs
changeset 88374:fa717c37ad16
Include "character.h" instead of "charset.h".
(Finsert_file_contents): Big change for the new code-conversion
API.
(choose_write_coding_system): Likewise.
(Fwrite_region): Likewise.
(build_annotations_2): Deleted.
(e_write): Big change for the new code-conversion API.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Fri, 01 Mar 2002 01:38:37 +0000 |
parents | 9c612c1faba4 |
children | 38cab5bfa62b |
files | src/fileio.c |
diffstat | 1 files changed, 183 insertions(+), 280 deletions(-) [+] |
line wrap: on
line diff
--- a/src/fileio.c Fri Mar 01 01:38:15 2002 +0000 +++ b/src/fileio.c Fri Mar 01 01:38:37 2002 +0000 @@ -87,7 +87,7 @@ #include "lisp.h" #include "intervals.h" #include "buffer.h" -#include "charset.h" +#include "character.h" #include "coding.h" #include "window.h" @@ -3576,7 +3576,7 @@ unsigned char buffer[1 << 14]; int replace_handled = 0; int set_coding_system = 0; - int coding_system_decided = 0; + Lisp_Object coding_system; int read_quit = 0; if (current_buffer->base_buffer && ! NILP (visit)) @@ -3713,20 +3713,20 @@ } } + /* The value Qnil means that the coding system is not yet + decided. */ + coding_system = Qnil; if (BEG < Z) { /* Decide the coding system to use for reading the file now because we can't use an optimized method for handling `coding:' tag if the current buffer is not empty. */ - Lisp_Object val; - val = Qnil; - if (!NILP (Vcoding_system_for_read)) - val = Vcoding_system_for_read; + coding_system = Vcoding_system_for_read; else if (! NILP (replace)) /* In REPLACE mode, we can use the same coding system that was used to visit the file. */ - val = current_buffer->buffer_file_coding_system; + coding_system = current_buffer->buffer_file_coding_system; else { /* Don't try looking inside a file for a coding system @@ -3773,8 +3773,8 @@ current_buffer->enable_multibyte_characters = Qnil; insert_1_both (read_buf, nread, nread, 0, 0, 0); TEMP_SET_PT_BOTH (BEG, BEG_BYTE); - val = call2 (Vset_auto_coding_function, - filename, make_number (nread)); + coding_system = call2 (Vset_auto_coding_function, + filename, make_number (nread)); set_buffer_internal (prev); /* Remove the binding for standard-output. */ @@ -3791,7 +3791,7 @@ } } - if (NILP (val)) + if (NILP (coding_system)) { /* If we have not yet decided a coding system, check file-coding-system-alist. */ @@ -3805,20 +3805,19 @@ } } - setup_coding_system (Fcheck_coding_system (val), &coding); + if (NILP (coding_system)) + coding_system = Qundecided; + else + CHECK_CODING_SYSTEM (coding_system); + + if (NILP (current_buffer->enable_multibyte_characters)) + /* We must suppress all character code conversion except for + end-of-line conversion. */ + coding_system = raw_text_coding_system (coding_system); + + setup_coding_system (coding_system, &coding); /* Ensure we set Vlast_coding_system_used. */ set_coding_system = 1; - - if (NILP (current_buffer->enable_multibyte_characters) - && ! NILP (val)) - /* We must suppress all character code conversion except for - end-of-line conversion. */ - setup_raw_text_coding_system (&coding); - - coding.src_multibyte = 0; - coding.dst_multibyte - = !NILP (current_buffer->enable_multibyte_characters); - coding_system_decided = 1; } /* If requested, replace the accessible part of the buffer @@ -3837,7 +3836,8 @@ and let the following if-statement handle the replace job. */ if (!NILP (replace) && BEGV < ZV - && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK)) + && (NILP (coding_system) + || ! CODING_REQUIRE_DECODING (&coding))) { /* same_at_start and same_at_end count bytes, because file access counts bytes @@ -3872,21 +3872,14 @@ else if (nread == 0) break; - if (coding.type == coding_type_undecided) - detect_coding (&coding, buffer, nread); - if (coding.common_flags & CODING_REQUIRE_DECODING_MASK) - /* We found that the file should be decoded somehow. - Let's give up here. */ + if (CODING_REQUIRE_DETECTION (&coding)) { - giveup_match_end = 1; - break; + coding_system = detect_coding_system (buffer, nread, 1, 0, + coding_system); + setup_coding_system (coding_system, &coding); } - - if (coding.eol_type == CODING_EOL_UNDECIDED) - detect_eol (&coding, buffer, nread); - if (coding.eol_type != CODING_EOL_UNDECIDED - && coding.eol_type != CODING_EOL_LF) - /* We found that the format of eol should be decoded. + if (CODING_REQUIRE_DECODING (&coding)) + /* We found that the file should be decoded somehow. Let's give up here. */ { giveup_match_end = 1; @@ -4033,17 +4026,20 @@ int same_at_end = ZV_BYTE; int overlap; int bufpos; - /* Make sure that the gap is large enough. */ - int bufsize = 2 * st.st_size; - unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize); + unsigned char *decoded; int temp; + int this_count = BINDING_STACK_SIZE (); + Lisp_Object conversion_buffer + = make_conversion_work_buffer (! NILP (current_buffer + ->enable_multibyte_characters)); + + record_unwind_protect (code_conversion_restore, save_excursion_save ()); /* First read the whole file, performing code conversion into CONVERSION_BUFFER. */ if (lseek (fd, XINT (beg), 0) < 0) { - xfree (conversion_buffer); report_file_error ("Setting file position", Fcons (orig_filename, Qnil)); } @@ -4055,71 +4051,41 @@ while (how_much < total) { + /* We read one bunch by one (READ_BUF_SIZE bytes) to allow + quitting while reading a huge while. */ /* try is reserved in some compilers (Microsoft C) */ int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); - unsigned char *destination = read_buf + unprocessed; int this; /* Allow quitting out of the actual I/O. */ immediate_quit = 1; QUIT; - this = emacs_read (fd, destination, trytry); + this = emacs_read (fd, read_buf + unprocessed, trytry); immediate_quit = 0; - if (this < 0 || this + unprocessed == 0) + if (this <= 0) { - how_much = this; + if (this < 0) + how_much = this; break; } how_much += this; - if (CODING_MAY_REQUIRE_DECODING (&coding)) - { - int require, result; - - this += unprocessed; - - /* If we are using more space than estimated, - make CONVERSION_BUFFER bigger. */ - require = decoding_buffer_size (&coding, this); - if (inserted + require + 2 * (total - how_much) > bufsize) - { - bufsize = inserted + require + 2 * (total - how_much); - conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize); - } - - /* Convert this batch with results in CONVERSION_BUFFER. */ - if (how_much >= total) /* This is the last block. */ - coding.mode |= CODING_MODE_LAST_BLOCK; - if (coding.composing != COMPOSITION_DISABLED) - coding_allocate_composition_data (&coding, BEGV); - result = decode_coding (&coding, read_buf, - conversion_buffer + inserted, - this, bufsize - inserted); - - /* Save for next iteration whatever we didn't convert. */ - unprocessed = this - coding.consumed; - bcopy (read_buf + coding.consumed, read_buf, unprocessed); - if (!NILP (current_buffer->enable_multibyte_characters)) - this = coding.produced; - else - this = str_as_unibyte (conversion_buffer + inserted, - coding.produced); - } - - inserted += this; - } - - /* At this point, INSERTED is how many characters (i.e. bytes) - are present in CONVERSION_BUFFER. - HOW_MUCH should equal TOTAL, - or should be <= 0 if we couldn't read the file. */ + decode_coding_c_string (&coding, read_buf, unprocessed + this, + conversion_buffer); + unprocessed = coding.carryover_bytes; + if (coding.carryover_bytes > 0) + bcopy (coding.carryover, read_buf, unprocessed); + } + + emacs_close (fd); + + /* At this point, HOW_MUCH should equal TOTAL, or should be <= 0 + if we couldn't read the file. */ if (how_much < 0) { - xfree (conversion_buffer); - if (how_much == -1) error ("IO error reading %s: %s", XSTRING (orig_filename)->data, emacs_strerror (errno)); @@ -4127,21 +4093,30 @@ error ("maximum buffer size exceeded"); } - /* Compare the beginning of the converted file - with the buffer text. */ + if (unprocessed > 0) + { + coding.mode |= CODING_MODE_LAST_BLOCK; + decode_coding_c_string (&coding, read_buf, unprocessed, + conversion_buffer); + coding.mode &= ~CODING_MODE_LAST_BLOCK; + } + + decoded = BUF_BEG_ADDR (XBUFFER (conversion_buffer)); + inserted = BUF_Z_BYTE (XBUFFER (conversion_buffer)); + + /* Compare the beginning of the converted string with the buffer + text. */ bufpos = 0; while (bufpos < inserted && same_at_start < same_at_end - && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos]) + && FETCH_BYTE (same_at_start) == decoded[bufpos]) same_at_start++, bufpos++; - /* If the file matches the buffer completely, + /* If the file matches the head of buffer completely, there's no need to replace anything. */ if (bufpos == inserted) { - xfree (conversion_buffer); - emacs_close (fd); specpdl_ptr--; /* Truncate the buffer to the size of the file. */ del_range_byte (same_at_start, same_at_end, 0); @@ -4149,8 +4124,8 @@ goto handled; } - /* Extend the start of non-matching text area to multibyte - character boundary. */ + /* Extend the start of non-matching text area to the previous + multibyte character boundary. */ if (! NILP (current_buffer->enable_multibyte_characters)) while (same_at_start > BEGV_BYTE && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start))) @@ -4163,11 +4138,11 @@ /* Compare with same_at_start to avoid counting some buffer text as matching both at the file's beginning and at the end. */ while (bufpos > 0 && same_at_end > same_at_start - && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1]) + && FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1]) same_at_end--, bufpos--; - /* Extend the end of non-matching text area to multibyte - character boundary. */ + /* Extend the end of non-matching text area to the next + multibyte character boundary. */ if (! NILP (current_buffer->enable_multibyte_characters)) while (same_at_end < ZV_BYTE && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end))) @@ -4185,11 +4160,11 @@ /* Replace the chars that we need to replace, and update INSERTED to equal the number of bytes - we are taking from the file. */ + we are taking from the decoded string. */ inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); if (same_at_end != same_at_start) - { + { del_range_byte (same_at_start, same_at_end, 0); temp = GPT; same_at_start = GPT_BYTE; @@ -4200,18 +4175,16 @@ } /* Insert from the file at the proper position. */ SET_PT_BOTH (temp, same_at_start); - insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted, - 0, 0, 0); - if (coding.cmp_data && coding.cmp_data->used) - coding_restore_composition (&coding, Fcurrent_buffer ()); - coding_free_composition_data (&coding); - + insert_from_buffer (XBUFFER (conversion_buffer), + buf_bytepos_to_charpos (XBUFFER (conversion_buffer), + same_at_start), + buf_bytepos_to_charpos (XBUFFER (conversion_buffer), + same_at_start + inserted), + 0); /* Set `inserted' to the number of inserted characters. */ inserted = PT - temp; - xfree (conversion_buffer); - emacs_close (fd); - specpdl_ptr--; + unbind_to (this_count, Qnil); goto handled; } @@ -4255,7 +4228,7 @@ inserted = 0; /* Here, we don't do code conversion in the loop. It is done by - code_convert_region after all data are read into the buffer. */ + decode_coding_gap after all data are read into the buffer. */ { int gap_size = GAP_SIZE; @@ -4346,18 +4319,16 @@ notfound: - if (! coding_system_decided) + if (NILP (coding_system)) { /* The coding system is not yet decided. Decide it by an optimized method for handling `coding:' tag. Note that we can get here only if the buffer was empty before the insertion. */ - Lisp_Object val; - val = Qnil; if (!NILP (Vcoding_system_for_read)) - val = Vcoding_system_for_read; + coding_system = Vcoding_system_for_read; else { /* Since we are sure that the current buffer was empty @@ -4378,11 +4349,11 @@ if (inserted > 0 && ! NILP (Vset_auto_coding_function)) { - val = call2 (Vset_auto_coding_function, - filename, make_number (inserted)); + coding_system = call2 (Vset_auto_coding_function, + filename, make_number (inserted)); } - if (NILP (val)) + if (NILP (coding_system)) { /* If the coding system is not yet decided, check file-coding-system-alist. */ @@ -4392,66 +4363,70 @@ args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil; coding_systems = Ffind_operation_coding_system (6, args); if (CONSP (coding_systems)) - val = XCAR (coding_systems); + coding_system = XCAR (coding_systems); } unbind_to (count, Qnil); inserted = Z_BYTE - BEG_BYTE; } - /* The following kludgy code is to avoid some compiler bug. - We can't simply do - setup_coding_system (val, &coding); - on some system. */ - { - struct coding_system temp_coding; - setup_coding_system (val, &temp_coding); - bcopy (&temp_coding, &coding, sizeof coding); - } - /* Ensure we set Vlast_coding_system_used. */ - set_coding_system = 1; - - if (NILP (current_buffer->enable_multibyte_characters) - && ! NILP (val)) + if (NILP (coding_system)) + coding_system = Qundecided; + else + CHECK_CODING_SYSTEM (coding_system); + + if (NILP (current_buffer->enable_multibyte_characters)) /* We must suppress all character code conversion except for end-of-line conversion. */ - setup_raw_text_coding_system (&coding); - coding.src_multibyte = 0; - coding.dst_multibyte - = !NILP (current_buffer->enable_multibyte_characters); + coding_system = raw_text_coding_system (coding_system); + + setup_coding_system (coding_system, &coding); + /* Ensure we set Vlast_coding_system_used. */ + set_coding_system = 1; } - if (!NILP (visit) - /* Can't do this if part of the buffer might be preserved. */ - && NILP (replace) - && (coding.type == coding_type_no_conversion - || coding.type == coding_type_raw_text)) + if (!NILP (visit)) { - /* Visiting a file with these coding system makes the buffer - unibyte. */ - current_buffer->enable_multibyte_characters = Qnil; - coding.dst_multibyte = 0; + /* When we visit a file by raw-text, we change the buffer to + unibyte. If we have not yet decided how to decode a text, + decide it at first by detecting the file's encoding. */ + if (CODING_REQUIRE_DETECTION (&coding)) + { + coding_system = detect_coding_system (PT_ADDR, inserted, 1, 0, + coding_system); + setup_coding_system (coding_system, &coding); + } + + if (CODING_FOR_UNIBYTE (&coding) + /* Can't do this if part of the buffer might be preserved. */ + && NILP (replace)) + /* Visiting a file with these coding system makes the buffer + unibyte. */ + current_buffer->enable_multibyte_characters = Qnil; } - if (inserted > 0 || coding.type == coding_type_ccl) + if (CODING_REQUIRE_DETECTION (&coding) + || CODING_REQUIRE_DECODING (&coding)) { - if (CODING_MAY_REQUIRE_DECODING (&coding)) - { - code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, - &coding, 0, 0); - inserted = coding.produced_char; - } - else - adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, - inserted); + move_gap_both (PT, PT_BYTE); + GAP_SIZE += inserted; + ZV_BYTE -= inserted; + Z_BYTE -= inserted; + ZV -= inserted; + Z -= inserted; + decode_coding_gap (&coding, inserted, inserted); + inserted = coding.produced_char; } + else if (inserted > 0) + adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, + inserted); #ifdef DOS_NT /* Use the conversion type to determine buffer-file-type (find-buffer-file-type is now used to help determine the conversion). */ - if ((coding.eol_type == CODING_EOL_UNDECIDED - || coding.eol_type == CODING_EOL_LF) + if ((coding.eol_type == eol_type_undecided + || coding.eol_type == eol_type_lf) && ! CODING_REQUIRE_DECODING (&coding)) current_buffer->buffer_file_type = Qt; else @@ -4515,7 +4490,7 @@ } if (set_coding_system) - Vlast_coding_system_used = coding.symbol; + Vlast_coding_system_used = coding_system; /* Call after-change hooks for the inserted text, aside from the case of normal visiting (not with REPLACE), which is done in a new buffer @@ -4560,8 +4535,6 @@ } static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object)); -static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object, - Lisp_Object, Lisp_Object)); /* If build_annotations switched buffers, switch back to BUF. Kill the temporary buffer that was selected in the meantime. @@ -4643,40 +4616,36 @@ using_default_coding = 1; } + if (! NILP (val) && ! force_raw_text) + { + Lisp_Object spec, attrs; + + CHECK_CODING_SYSTEM_GET_SPEC (val, spec); + attrs = AREF (spec, 0); + if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text)) + force_raw_text = 1; + } + if (!force_raw_text && !NILP (Ffboundp (Vselect_safe_coding_system_function))) /* Confirm that VAL can surely encode the current region. */ val = call3 (Vselect_safe_coding_system_function, start, end, val); - setup_coding_system (Fcheck_coding_system (val), coding); - if (coding->eol_type == CODING_EOL_UNDECIDED - && !using_default_coding) - { - if (! EQ (default_buffer_file_coding.symbol, - buffer_defaults.buffer_file_coding_system)) - setup_coding_system (buffer_defaults.buffer_file_coding_system, - &default_buffer_file_coding); - if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED) - { - Lisp_Object subsidiaries; - - coding->eol_type = default_buffer_file_coding.eol_type; - subsidiaries = Fget (coding->symbol, Qeol_type); - if (VECTORP (subsidiaries) - && XVECTOR (subsidiaries)->size == 3) - coding->symbol - = XVECTOR (subsidiaries)->contents[coding->eol_type]; - } - } - + /* If the decided coding-system doesn't specify end-of-line + format, we use that of + `default-buffer-file-coding-system'. */ + if (! using_default_coding) + val = (coding_inherit_eol_type + (val, buffer_defaults.buffer_file_coding_system)); + + /* If we decide not to encode text, use `raw-text' or one of its + subsidiaries. */ if (force_raw_text) - setup_raw_text_coding_system (coding); - goto done_setup_coding; + val = raw_text_coding_system (val); } setup_coding_system (Fcheck_coding_system (val), coding); - done_setup_coding: if (!STRINGP (start) && !NILP (current_buffer->selective_display)) coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; } @@ -4816,11 +4785,9 @@ unsavable chars (as was the case with X-Symbol). */ choose_write_coding_system (start, end, filename, append, visit, lockname, &coding); - Vlast_coding_system_used = coding.symbol; + Vlast_coding_system_used = CODING_ID_NAME (coding.id); given_buffer = current_buffer; - annotations = build_annotations_2 (start, end, - coding.pre_write_conversion, annotations); if (current_buffer != given_buffer) { XSETFASTINT (start, BEGV); @@ -4963,6 +4930,9 @@ if (GPT > BEG && GPT_ADDR[-1] != '\n') move_gap (find_next_newline (GPT, 1)); #else +#if 0 + /* The new encoding routine doesn't require the following. */ + /* Whether VMS or not, we must move the gap to the next of newline when we must put designation sequences at beginning of line. */ if (INTEGERP (start) @@ -4976,6 +4946,7 @@ SET_PT_BOTH (opoint, opoint_byte); } #endif +#endif failure = 0; immediate_quit = 1; @@ -4988,23 +4959,10 @@ } else if (XINT (start) != XINT (end)) { - tem = CHAR_TO_BYTE (XINT (start)); - - if (XINT (start) < GPT) - { - failure = 0 > a_write (desc, Qnil, XINT (start), - min (GPT, XINT (end)) - XINT (start), - &annotations, &coding); - save_errno = errno; - } - - if (XINT (end) > GPT && !failure) - { - tem = max (XINT (start), GPT); - failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem, - &annotations, &coding); - save_errno = errno; - } + failure = 0 > a_write (desc, Qnil, + XINT (start), XINT (end) - XINT (start), + &annotations, &coding); + save_errno = errno; } else { @@ -5020,7 +4978,7 @@ { /* We have to flush out a data. */ coding.mode |= CODING_MODE_LAST_BLOCK; - failure = 0 > e_write (desc, Qnil, 0, 0, &coding); + failure = 0 > e_write (desc, Qnil, 1, 1, &coding); save_errno = errno; } @@ -5196,30 +5154,6 @@ return annotations; } -static Lisp_Object -build_annotations_2 (start, end, pre_write_conversion, annotations) - Lisp_Object start, end, pre_write_conversion, annotations; -{ - struct gcpro gcpro1; - Lisp_Object res; - - GCPRO1 (annotations); - /* At last, do the same for the function PRE_WRITE_CONVERSION - implied by the current coding-system. */ - if (!NILP (pre_write_conversion)) - { - struct buffer *given_buffer = current_buffer; - Vwrite_region_annotations_so_far = annotations; - res = call2 (pre_write_conversion, start, end); - Flength (res); - annotations = (current_buffer != given_buffer - ? res - : merge (annotations, res, Qcar_less_than_car)); - } - - UNGCPRO; - return annotations; -} /* Write to descriptor DESC the NCHARS chars starting at POS of STRING. If STRING is nil, POS is the character position in the current buffer. @@ -5291,76 +5225,45 @@ int start, end; struct coding_system *coding; { - register char *addr; - register int nbytes; - char buf[WRITE_BUF_SIZE]; int return_val = 0; - if (start >= end) - coding->composing = COMPOSITION_DISABLED; - if (coding->composing != COMPOSITION_DISABLED) - coding_save_composition (coding, start, end, string); - if (STRINGP (string)) { - addr = XSTRING (string)->data; - nbytes = STRING_BYTES (XSTRING (string)); - coding->src_multibyte = STRING_MULTIBYTE (string); + start = 0; + end = XSTRING (string)->size; } - else if (start < end) - { - /* It is assured that the gap is not in the range START and END-1. */ - addr = CHAR_POS_ADDR (start); - nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start); - coding->src_multibyte - = !NILP (current_buffer->enable_multibyte_characters); - } - else - { - addr = ""; - nbytes = 0; - coding->src_multibyte = 1; - } + + coding->mode |= CODING_MODE_FIXED_DESTINATION; + if (! NILP (current_buffer->selective_display)) + coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; /* We used to have a code for handling selective display here. But, now it is handled within encode_coding. */ - while (1) + do { - int result; - - result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE); + if (STRINGP (string)) + encode_coding_object (coding, string, + start, string_char_to_byte (string, start), + end, string_char_to_byte (string, end), Qt); + else + encode_coding_object (coding, Fcurrent_buffer (), + start, CHAR_TO_BYTE (start), + end, CHAR_TO_BYTE (end), Qt); + if (coding->produced > 0) { - coding->produced -= emacs_write (desc, buf, coding->produced); + coding->produced -= emacs_write (desc, + XSTRING (coding->dst_object)->data, + coding->produced); if (coding->produced) { return_val = -1; break; } } - nbytes -= coding->consumed; - addr += coding->consumed; - if (result == CODING_FINISH_INSUFFICIENT_SRC - && nbytes > 0) - { - /* The source text ends by an incomplete multibyte form. - There's no way other than write it out as is. */ - nbytes -= emacs_write (desc, addr, nbytes); - if (nbytes) - { - return_val = -1; - break; - } - } - if (nbytes <= 0) - break; start += coding->consumed_char; - if (coding->cmp_data) - coding_adjust_composition_offset (coding, start); } - - if (coding->cmp_data) - coding_free_composition_data (coding); + while (start < end); return return_val; }