comparison src/fileio.c @ 89483:2f877ed80fa6

*** empty log message ***
author Kenichi Handa <handa@m17n.org>
date Mon, 08 Sep 2003 12:53:41 +0000
parents 375f2633d815 756c32423971
children e1159b1e5142
comparison
equal deleted inserted replaced
88123:375f2633d815 89483:2f877ed80fa6
73 #endif 73 #endif
74 74
75 #include "lisp.h" 75 #include "lisp.h"
76 #include "intervals.h" 76 #include "intervals.h"
77 #include "buffer.h" 77 #include "buffer.h"
78 #include "charset.h" 78 #include "character.h"
79 #include "coding.h" 79 #include "coding.h"
80 #include "window.h" 80 #include "window.h"
81 81
82 #ifdef WINDOWSNT 82 #ifdef WINDOWSNT
83 #define NOMINMAX 1 83 #define NOMINMAX 1
291 restore_point_unwind (location) 291 restore_point_unwind (location)
292 Lisp_Object location; 292 Lisp_Object location;
293 { 293 {
294 Fgoto_char (location); 294 Fgoto_char (location);
295 Fset_marker (location, Qnil, Qnil); 295 Fset_marker (location, Qnil, Qnil);
296 return Qnil;
297 }
298
299 /* Kill the working buffer for code conversion. */
300
301 static Lisp_Object
302 kill_workbuf_unwind (workbuf)
303 Lisp_Object workbuf;
304 {
305 if (! NILP (workbuf) && ! NILP (Fbuffer_live_p (workbuf)))
306 Fkill_buffer (workbuf);
296 return Qnil; 307 return Qnil;
297 } 308 }
298 309
299 Lisp_Object Qexpand_file_name; 310 Lisp_Object Qexpand_file_name;
300 Lisp_Object Qsubstitute_in_file_name; 311 Lisp_Object Qsubstitute_in_file_name;
3630 unsigned char read_buf[READ_BUF_SIZE]; 3641 unsigned char read_buf[READ_BUF_SIZE];
3631 struct coding_system coding; 3642 struct coding_system coding;
3632 unsigned char buffer[1 << 14]; 3643 unsigned char buffer[1 << 14];
3633 int replace_handled = 0; 3644 int replace_handled = 0;
3634 int set_coding_system = 0; 3645 int set_coding_system = 0;
3635 int coding_system_decided = 0; 3646 Lisp_Object coding_system;
3636 int read_quit = 0; 3647 int read_quit = 0;
3637 3648
3638 if (current_buffer->base_buffer && ! NILP (visit)) 3649 if (current_buffer->base_buffer && ! NILP (visit))
3639 error ("Cannot do file visiting in an indirect buffer"); 3650 error ("Cannot do file visiting in an indirect buffer");
3640 3651
3647 3658
3648 GCPRO4 (filename, val, p, orig_filename); 3659 GCPRO4 (filename, val, p, orig_filename);
3649 3660
3650 CHECK_STRING (filename); 3661 CHECK_STRING (filename);
3651 filename = Fexpand_file_name (filename, Qnil); 3662 filename = Fexpand_file_name (filename, Qnil);
3663
3664 /* The value Qnil means that the coding system is not yet
3665 decided. */
3666 coding_system = Qnil;
3652 3667
3653 /* If the file name has special constructs in it, 3668 /* If the file name has special constructs in it,
3654 call the corresponding file handler. */ 3669 call the corresponding file handler. */
3655 handler = Ffind_file_name_handler (filename, Qinsert_file_contents); 3670 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
3656 if (!NILP (handler)) 3671 if (!NILP (handler))
3771 XSETINT (end, READ_BUF_SIZE); 3786 XSETINT (end, READ_BUF_SIZE);
3772 } 3787 }
3773 } 3788 }
3774 3789
3775 if (EQ (Vcoding_system_for_read, Qauto_save_coding)) 3790 if (EQ (Vcoding_system_for_read, Qauto_save_coding))
3776 { 3791 coding_system = Qutf_8_emacs;
3777 /* We use emacs-mule for auto saving... */
3778 setup_coding_system (Qemacs_mule, &coding);
3779 /* ... but with the special flag to indicate to read in a
3780 multibyte sequence for eight-bit-control char as is. */
3781 coding.flags = 1;
3782 coding.src_multibyte = 0;
3783 coding.dst_multibyte
3784 = !NILP (current_buffer->enable_multibyte_characters);
3785 coding.eol_type = CODING_EOL_LF;
3786 coding_system_decided = 1;
3787 }
3788 else if (BEG < Z) 3792 else if (BEG < Z)
3789 { 3793 {
3790 /* Decide the coding system to use for reading the file now 3794 /* Decide the coding system to use for reading the file now
3791 because we can't use an optimized method for handling 3795 because we can't use an optimized method for handling
3792 `coding:' tag if the current buffer is not empty. */ 3796 `coding:' tag if the current buffer is not empty. */
3793 Lisp_Object val;
3794 val = Qnil;
3795
3796 if (!NILP (Vcoding_system_for_read)) 3797 if (!NILP (Vcoding_system_for_read))
3797 val = Vcoding_system_for_read; 3798 coding_system = Vcoding_system_for_read;
3798 else if (! NILP (replace)) 3799 else if (! NILP (replace))
3799 /* In REPLACE mode, we can use the same coding system 3800 /* In REPLACE mode, we can use the same coding system
3800 that was used to visit the file. */ 3801 that was used to visit the file. */
3801 val = current_buffer->buffer_file_coding_system; 3802 coding_system = current_buffer->buffer_file_coding_system;
3802 else 3803 else
3803 { 3804 {
3804 /* Don't try looking inside a file for a coding system 3805 /* Don't try looking inside a file for a coding system
3805 specification if it is not seekable. */ 3806 specification if it is not seekable. */
3806 if (! not_regular && ! NILP (Vset_auto_coding_function)) 3807 if (! not_regular && ! NILP (Vset_auto_coding_function))
3852 Ferase_buffer (); 3853 Ferase_buffer ();
3853 buf->enable_multibyte_characters = Qnil; 3854 buf->enable_multibyte_characters = Qnil;
3854 3855
3855 insert_1_both (read_buf, nread, nread, 0, 0, 0); 3856 insert_1_both (read_buf, nread, nread, 0, 0, 0);
3856 TEMP_SET_PT_BOTH (BEG, BEG_BYTE); 3857 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3857 val = call2 (Vset_auto_coding_function, 3858 coding_system = call2 (Vset_auto_coding_function,
3858 filename, make_number (nread)); 3859 filename, make_number (nread));
3859 set_buffer_internal (prev); 3860 set_buffer_internal (prev);
3860 3861
3861 /* Discard the unwind protect for recovering the 3862 /* Discard the unwind protect for recovering the
3862 current buffer. */ 3863 current buffer. */
3863 specpdl_ptr--; 3864 specpdl_ptr--;
3867 report_file_error ("Setting file position", 3868 report_file_error ("Setting file position",
3868 Fcons (orig_filename, Qnil)); 3869 Fcons (orig_filename, Qnil));
3869 } 3870 }
3870 } 3871 }
3871 3872
3872 if (NILP (val)) 3873 if (NILP (coding_system))
3873 { 3874 {
3874 /* If we have not yet decided a coding system, check 3875 /* If we have not yet decided a coding system, check
3875 file-coding-system-alist. */ 3876 file-coding-system-alist. */
3876 Lisp_Object args[6], coding_systems; 3877 Lisp_Object args[6];
3877 3878
3878 args[0] = Qinsert_file_contents, args[1] = orig_filename; 3879 args[0] = Qinsert_file_contents, args[1] = orig_filename;
3879 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace; 3880 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3880 coding_systems = Ffind_operation_coding_system (6, args); 3881 coding_system = Ffind_operation_coding_system (6, args);
3881 if (CONSP (coding_systems)) 3882 if (CONSP (coding_system))
3882 val = XCAR (coding_systems); 3883 coding_system = XCAR (coding_system);
3883 } 3884 }
3884 } 3885 }
3885 3886
3886 setup_coding_system (Fcheck_coding_system (val), &coding); 3887 if (NILP (coding_system))
3888 coding_system = Qundecided;
3889 else
3890 CHECK_CODING_SYSTEM (coding_system);
3891
3892 if (NILP (current_buffer->enable_multibyte_characters))
3893 /* We must suppress all character code conversion except for
3894 end-of-line conversion. */
3895 coding_system = raw_text_coding_system (coding_system);
3896
3897 setup_coding_system (coding_system, &coding);
3887 /* Ensure we set Vlast_coding_system_used. */ 3898 /* Ensure we set Vlast_coding_system_used. */
3888 set_coding_system = 1; 3899 set_coding_system = 1;
3889
3890 if (NILP (current_buffer->enable_multibyte_characters)
3891 && ! NILP (val))
3892 /* We must suppress all character code conversion except for
3893 end-of-line conversion. */
3894 setup_raw_text_coding_system (&coding);
3895
3896 coding.src_multibyte = 0;
3897 coding.dst_multibyte
3898 = !NILP (current_buffer->enable_multibyte_characters);
3899 coding_system_decided = 1;
3900 } 3900 }
3901 3901
3902 /* If requested, replace the accessible part of the buffer 3902 /* If requested, replace the accessible part of the buffer
3903 with the file contents. Avoid replacing text at the 3903 with the file contents. Avoid replacing text at the
3904 beginning or end of the buffer that matches the file contents; 3904 beginning or end of the buffer that matches the file contents;
3913 method and hope for the best. 3913 method and hope for the best.
3914 But if we discover the need for conversion, we give up on this method 3914 But if we discover the need for conversion, we give up on this method
3915 and let the following if-statement handle the replace job. */ 3915 and let the following if-statement handle the replace job. */
3916 if (!NILP (replace) 3916 if (!NILP (replace)
3917 && BEGV < ZV 3917 && BEGV < ZV
3918 && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK)) 3918 && (NILP (coding_system)
3919 || ! CODING_REQUIRE_DECODING (&coding)))
3919 { 3920 {
3920 /* same_at_start and same_at_end count bytes, 3921 /* same_at_start and same_at_end count bytes,
3921 because file access counts bytes 3922 because file access counts bytes
3922 and BEG and END count bytes. */ 3923 and BEG and END count bytes. */
3923 int same_at_start = BEGV_BYTE; 3924 int same_at_start = BEGV_BYTE;
3948 error ("IO error reading %s: %s", 3949 error ("IO error reading %s: %s",
3949 SDATA (orig_filename), emacs_strerror (errno)); 3950 SDATA (orig_filename), emacs_strerror (errno));
3950 else if (nread == 0) 3951 else if (nread == 0)
3951 break; 3952 break;
3952 3953
3953 if (coding.type == coding_type_undecided) 3954 if (CODING_REQUIRE_DETECTION (&coding))
3954 detect_coding (&coding, buffer, nread); 3955 {
3955 if (coding.common_flags & CODING_REQUIRE_DECODING_MASK) 3956 coding_system = detect_coding_system (buffer, nread, 1, 0,
3957 coding_system);
3958 setup_coding_system (coding_system, &coding);
3959 }
3960
3961 if (CODING_REQUIRE_DECODING (&coding))
3956 /* We found that the file should be decoded somehow. 3962 /* We found that the file should be decoded somehow.
3957 Let's give up here. */
3958 {
3959 giveup_match_end = 1;
3960 break;
3961 }
3962
3963 if (coding.eol_type == CODING_EOL_UNDECIDED)
3964 detect_eol (&coding, buffer, nread);
3965 if (coding.eol_type != CODING_EOL_UNDECIDED
3966 && coding.eol_type != CODING_EOL_LF)
3967 /* We found that the format of eol should be decoded.
3968 Let's give up here. */ 3963 Let's give up here. */
3969 { 3964 {
3970 giveup_match_end = 1; 3965 giveup_match_end = 1;
3971 break; 3966 break;
3972 } 3967 }
4107 in a more optimized way. */ 4102 in a more optimized way. */
4108 if (!NILP (replace) && ! replace_handled && BEGV < ZV) 4103 if (!NILP (replace) && ! replace_handled && BEGV < ZV)
4109 { 4104 {
4110 int same_at_start = BEGV_BYTE; 4105 int same_at_start = BEGV_BYTE;
4111 int same_at_end = ZV_BYTE; 4106 int same_at_end = ZV_BYTE;
4107 int same_at_start_charpos;
4108 int inserted_chars;
4112 int overlap; 4109 int overlap;
4113 int bufpos; 4110 int bufpos;
4114 /* Make sure that the gap is large enough. */ 4111 unsigned char *decoded;
4115 int bufsize = 2 * st.st_size;
4116 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
4117 int temp; 4112 int temp;
4113 int this_count = SPECPDL_INDEX ();
4114 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
4115 Lisp_Object conversion_buffer
4116 = make_conversion_work_buffer (-1, multibyte);
4117 struct gcpro1;
4118
4119 record_unwind_protect (kill_workbuf_unwind, conversion_buffer);
4118 4120
4119 /* First read the whole file, performing code conversion into 4121 /* First read the whole file, performing code conversion into
4120 CONVERSION_BUFFER. */ 4122 CONVERSION_BUFFER. */
4121 4123
4122 if (lseek (fd, XINT (beg), 0) < 0) 4124 if (lseek (fd, XINT (beg), 0) < 0)
4123 { 4125 report_file_error ("Setting file position",
4124 xfree (conversion_buffer); 4126 Fcons (orig_filename, Qnil));
4125 report_file_error ("Setting file position",
4126 Fcons (orig_filename, Qnil));
4127 }
4128 4127
4129 total = st.st_size; /* Total bytes in the file. */ 4128 total = st.st_size; /* Total bytes in the file. */
4130 how_much = 0; /* Bytes read from file so far. */ 4129 how_much = 0; /* Bytes read from file so far. */
4131 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ 4130 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
4132 unprocessed = 0; /* Bytes not processed in previous loop. */ 4131 unprocessed = 0; /* Bytes not processed in previous loop. */
4133 4132
4133 GCPRO1 (conversion_buffer);
4134 while (how_much < total) 4134 while (how_much < total)
4135 { 4135 {
4136 /* We read one bunch by one (READ_BUF_SIZE bytes) to allow
4137 quitting while reading a huge while. */
4136 /* try is reserved in some compilers (Microsoft C) */ 4138 /* try is reserved in some compilers (Microsoft C) */
4137 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); 4139 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
4138 unsigned char *destination = read_buf + unprocessed;
4139 int this; 4140 int this;
4140 4141
4141 /* Allow quitting out of the actual I/O. */ 4142 /* Allow quitting out of the actual I/O. */
4142 immediate_quit = 1; 4143 immediate_quit = 1;
4143 QUIT; 4144 QUIT;
4144 this = emacs_read (fd, destination, trytry); 4145 this = emacs_read (fd, read_buf + unprocessed, trytry);
4145 immediate_quit = 0; 4146 immediate_quit = 0;
4146 4147
4147 if (this < 0 || this + unprocessed == 0) 4148 if (this <= 0)
4148 { 4149 {
4149 how_much = this; 4150 if (this < 0)
4151 how_much = this;
4150 break; 4152 break;
4151 } 4153 }
4152 4154
4153 how_much += this; 4155 how_much += this;
4154 4156
4155 if (CODING_MAY_REQUIRE_DECODING (&coding)) 4157 BUF_SET_PT (XBUFFER (conversion_buffer),
4156 { 4158 BUF_Z (XBUFFER (conversion_buffer)));
4157 int require, result; 4159 decode_coding_c_string (&coding, read_buf, unprocessed + this,
4158 4160 conversion_buffer);
4159 this += unprocessed; 4161 unprocessed = coding.carryover_bytes;
4160 4162 if (coding.carryover_bytes > 0)
4161 /* If we are using more space than estimated, 4163 bcopy (coding.carryover, read_buf, unprocessed);
4162 make CONVERSION_BUFFER bigger. */ 4164 }
4163 require = decoding_buffer_size (&coding, this); 4165 UNGCPRO;
4164 if (inserted + require + 2 * (total - how_much) > bufsize) 4166 emacs_close (fd);
4165 { 4167
4166 bufsize = inserted + require + 2 * (total - how_much); 4168 /* At this point, HOW_MUCH should equal TOTAL, or should be <= 0
4167 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize); 4169 if we couldn't read the file. */
4168 }
4169
4170 /* Convert this batch with results in CONVERSION_BUFFER. */
4171 if (how_much >= total) /* This is the last block. */
4172 coding.mode |= CODING_MODE_LAST_BLOCK;
4173 if (coding.composing != COMPOSITION_DISABLED)
4174 coding_allocate_composition_data (&coding, BEGV);
4175 result = decode_coding (&coding, read_buf,
4176 conversion_buffer + inserted,
4177 this, bufsize - inserted);
4178
4179 /* Save for next iteration whatever we didn't convert. */
4180 unprocessed = this - coding.consumed;
4181 bcopy (read_buf + coding.consumed, read_buf, unprocessed);
4182 if (!NILP (current_buffer->enable_multibyte_characters))
4183 this = coding.produced;
4184 else
4185 this = str_as_unibyte (conversion_buffer + inserted,
4186 coding.produced);
4187 }
4188
4189 inserted += this;
4190 }
4191
4192 /* At this point, INSERTED is how many characters (i.e. bytes)
4193 are present in CONVERSION_BUFFER.
4194 HOW_MUCH should equal TOTAL,
4195 or should be <= 0 if we couldn't read the file. */
4196 4170
4197 if (how_much < 0) 4171 if (how_much < 0)
4198 { 4172 {
4199 xfree (conversion_buffer);
4200
4201 if (how_much == -1) 4173 if (how_much == -1)
4202 error ("IO error reading %s: %s", 4174 error ("IO error reading %s: %s",
4203 SDATA (orig_filename), emacs_strerror (errno)); 4175 SDATA (orig_filename), emacs_strerror (errno));
4204 else if (how_much == -2) 4176 else if (how_much == -2)
4205 error ("maximum buffer size exceeded"); 4177 error ("maximum buffer size exceeded");
4206 } 4178 }
4207 4179
4208 /* Compare the beginning of the converted file 4180 if (unprocessed > 0)
4209 with the buffer text. */ 4181 {
4182 coding.mode |= CODING_MODE_LAST_BLOCK;
4183 decode_coding_c_string (&coding, read_buf, unprocessed,
4184 conversion_buffer);
4185 coding.mode &= ~CODING_MODE_LAST_BLOCK;
4186 }
4187
4188 decoded = BUF_BEG_ADDR (XBUFFER (conversion_buffer));
4189 inserted = (BUF_Z_BYTE (XBUFFER (conversion_buffer))
4190 - BUF_BEG_BYTE (XBUFFER (conversion_buffer)));
4191
4192 /* Compare the beginning of the converted string with the buffer
4193 text. */
4210 4194
4211 bufpos = 0; 4195 bufpos = 0;
4212 while (bufpos < inserted && same_at_start < same_at_end 4196 while (bufpos < inserted && same_at_start < same_at_end
4213 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos]) 4197 && FETCH_BYTE (same_at_start) == decoded[bufpos])
4214 same_at_start++, bufpos++; 4198 same_at_start++, bufpos++;
4215 4199
4216 /* If the file matches the buffer completely, 4200 /* If the file matches the head of buffer completely,
4217 there's no need to replace anything. */ 4201 there's no need to replace anything. */
4218 4202
4219 if (bufpos == inserted) 4203 if (bufpos == inserted)
4220 { 4204 {
4221 xfree (conversion_buffer);
4222 emacs_close (fd);
4223 specpdl_ptr--; 4205 specpdl_ptr--;
4224 /* Truncate the buffer to the size of the file. */ 4206 /* Truncate the buffer to the size of the file. */
4225 del_range_byte (same_at_start, same_at_end, 0); 4207 del_range_byte (same_at_start, same_at_end, 0);
4226 inserted = 0; 4208 inserted = 0;
4227 goto handled; 4209 goto handled;
4228 } 4210 }
4229 4211
4230 /* Extend the start of non-matching text area to multibyte 4212 /* Extend the start of non-matching text area to the previous
4231 character boundary. */ 4213 multibyte character boundary. */
4232 if (! NILP (current_buffer->enable_multibyte_characters)) 4214 if (! NILP (current_buffer->enable_multibyte_characters))
4233 while (same_at_start > BEGV_BYTE 4215 while (same_at_start > BEGV_BYTE
4234 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start))) 4216 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
4235 same_at_start--; 4217 same_at_start--;
4236 4218
4239 bufpos = inserted; 4221 bufpos = inserted;
4240 4222
4241 /* Compare with same_at_start to avoid counting some buffer text 4223 /* Compare with same_at_start to avoid counting some buffer text
4242 as matching both at the file's beginning and at the end. */ 4224 as matching both at the file's beginning and at the end. */
4243 while (bufpos > 0 && same_at_end > same_at_start 4225 while (bufpos > 0 && same_at_end > same_at_start
4244 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1]) 4226 && FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1])
4245 same_at_end--, bufpos--; 4227 same_at_end--, bufpos--;
4246 4228
4247 /* Extend the end of non-matching text area to multibyte 4229 /* Extend the end of non-matching text area to the next
4248 character boundary. */ 4230 multibyte character boundary. */
4249 if (! NILP (current_buffer->enable_multibyte_characters)) 4231 if (! NILP (current_buffer->enable_multibyte_characters))
4250 while (same_at_end < ZV_BYTE 4232 while (same_at_end < ZV_BYTE
4251 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end))) 4233 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
4252 same_at_end++; 4234 same_at_end++;
4253 4235
4261 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) 4243 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
4262 XWINDOW (selected_window)->start_at_line_beg = Fbolp (); 4244 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
4263 4245
4264 /* Replace the chars that we need to replace, 4246 /* Replace the chars that we need to replace,
4265 and update INSERTED to equal the number of bytes 4247 and update INSERTED to equal the number of bytes
4266 we are taking from the file. */ 4248 we are taking from the decoded string. */
4267 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); 4249 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
4268 4250
4269 if (same_at_end != same_at_start) 4251 if (same_at_end != same_at_start)
4270 { 4252 {
4271 del_range_byte (same_at_start, same_at_end, 0); 4253 del_range_byte (same_at_start, same_at_end, 0);
4276 { 4258 {
4277 temp = BYTE_TO_CHAR (same_at_start); 4259 temp = BYTE_TO_CHAR (same_at_start);
4278 } 4260 }
4279 /* Insert from the file at the proper position. */ 4261 /* Insert from the file at the proper position. */
4280 SET_PT_BOTH (temp, same_at_start); 4262 SET_PT_BOTH (temp, same_at_start);
4281 insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted, 4263 same_at_start_charpos
4282 0, 0, 0); 4264 = buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4283 if (coding.cmp_data && coding.cmp_data->used) 4265 same_at_start);
4284 coding_restore_composition (&coding, Fcurrent_buffer ()); 4266 inserted_chars
4285 coding_free_composition_data (&coding); 4267 = (buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4286 4268 same_at_start + inserted)
4269 - same_at_start_charpos);
4270 insert_from_buffer (XBUFFER (conversion_buffer),
4271 same_at_start_charpos, inserted_chars, 0);
4287 /* Set `inserted' to the number of inserted characters. */ 4272 /* Set `inserted' to the number of inserted characters. */
4288 inserted = PT - temp; 4273 inserted = PT - temp;
4289 4274
4290 xfree (conversion_buffer); 4275 unbind_to (this_count, Qnil);
4291 emacs_close (fd);
4292 specpdl_ptr--;
4293 4276
4294 goto handled; 4277 goto handled;
4295 } 4278 }
4296 4279
4297 if (! not_regular) 4280 if (! not_regular)
4331 4314
4332 /* Total bytes inserted. */ 4315 /* Total bytes inserted. */
4333 inserted = 0; 4316 inserted = 0;
4334 4317
4335 /* Here, we don't do code conversion in the loop. It is done by 4318 /* Here, we don't do code conversion in the loop. It is done by
4336 code_convert_region after all data are read into the buffer. */ 4319 decode_coding_gap after all data are read into the buffer. */
4337 { 4320 {
4338 int gap_size = GAP_SIZE; 4321 int gap_size = GAP_SIZE;
4339 4322
4340 while (how_much < total) 4323 while (how_much < total)
4341 { 4324 {
4422 error ("IO error reading %s: %s", 4405 error ("IO error reading %s: %s",
4423 SDATA (orig_filename), emacs_strerror (errno)); 4406 SDATA (orig_filename), emacs_strerror (errno));
4424 4407
4425 notfound: 4408 notfound:
4426 4409
4427 if (! coding_system_decided) 4410 if (NILP (coding_system))
4428 { 4411 {
4429 /* The coding system is not yet decided. Decide it by an 4412 /* The coding system is not yet decided. Decide it by an
4430 optimized method for handling `coding:' tag. 4413 optimized method for handling `coding:' tag.
4431 4414
4432 Note that we can get here only if the buffer was empty 4415 Note that we can get here only if the buffer was empty
4433 before the insertion. */ 4416 before the insertion. */
4434 Lisp_Object val;
4435 val = Qnil;
4436 4417
4437 if (!NILP (Vcoding_system_for_read)) 4418 if (!NILP (Vcoding_system_for_read))
4438 val = Vcoding_system_for_read; 4419 coding_system = Vcoding_system_for_read;
4439 else 4420 else
4440 { 4421 {
4441 /* Since we are sure that the current buffer was empty 4422 /* Since we are sure that the current buffer was empty
4442 before the insertion, we can toggle 4423 before the insertion, we can toggle
4443 enable-multibyte-characters directly here without taking 4424 enable-multibyte-characters directly here without taking
4454 current_buffer->undo_list = Qt; 4435 current_buffer->undo_list = Qt;
4455 record_unwind_protect (decide_coding_unwind, unwind_data); 4436 record_unwind_protect (decide_coding_unwind, unwind_data);
4456 4437
4457 if (inserted > 0 && ! NILP (Vset_auto_coding_function)) 4438 if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4458 { 4439 {
4459 val = call2 (Vset_auto_coding_function, 4440 coding_system = call2 (Vset_auto_coding_function,
4460 filename, make_number (inserted)); 4441 filename, make_number (inserted));
4461 } 4442 }
4462 4443
4463 if (NILP (val)) 4444 if (NILP (coding_system))
4464 { 4445 {
4465 /* If the coding system is not yet decided, check 4446 /* If the coding system is not yet decided, check
4466 file-coding-system-alist. */ 4447 file-coding-system-alist. */
4467 Lisp_Object args[6], coding_systems; 4448 Lisp_Object args[6];
4468 4449
4469 args[0] = Qinsert_file_contents, args[1] = orig_filename; 4450 args[0] = Qinsert_file_contents, args[1] = orig_filename;
4470 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil; 4451 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4471 coding_systems = Ffind_operation_coding_system (6, args); 4452 coding_system = Ffind_operation_coding_system (6, args);
4472 if (CONSP (coding_systems)) 4453 if (CONSP (coding_system))
4473 val = XCAR (coding_systems); 4454 coding_system = XCAR (coding_system);
4474 } 4455 }
4475 4456
4476 unbind_to (count, Qnil); 4457 unbind_to (count, Qnil);
4477 inserted = Z_BYTE - BEG_BYTE; 4458 inserted = Z_BYTE - BEG_BYTE;
4478 } 4459 }
4479 4460
4480 /* The following kludgy code is to avoid some compiler bug. 4461 if (NILP (coding_system))
4481 We can't simply do 4462 coding_system = Qundecided;
4482 setup_coding_system (val, &coding); 4463 else
4483 on some system. */ 4464 CHECK_CODING_SYSTEM (coding_system);
4484 { 4465
4485 struct coding_system temp_coding; 4466 if (NILP (current_buffer->enable_multibyte_characters))
4486 setup_coding_system (val, &temp_coding); 4467 /* We must suppress all character code conversion except for
4487 bcopy (&temp_coding, &coding, sizeof coding); 4468 end-of-line conversion. */
4488 } 4469 coding_system = raw_text_coding_system (coding_system);
4470 setup_coding_system (coding_system, &coding);
4489 /* Ensure we set Vlast_coding_system_used. */ 4471 /* Ensure we set Vlast_coding_system_used. */
4490 set_coding_system = 1; 4472 set_coding_system = 1;
4491 4473 }
4492 if (NILP (current_buffer->enable_multibyte_characters) 4474
4493 && ! NILP (val)) 4475 if (!NILP (visit))
4494 /* We must suppress all character code conversion except for 4476 {
4495 end-of-line conversion. */ 4477 /* When we visit a file by raw-text, we change the buffer to
4496 setup_raw_text_coding_system (&coding); 4478 unibyte. If we have not yet decided how to decode a text,
4497 coding.src_multibyte = 0; 4479 decide it at first by detecting the file's encoding. */
4498 coding.dst_multibyte 4480 if (CODING_REQUIRE_DETECTION (&coding))
4499 = !NILP (current_buffer->enable_multibyte_characters); 4481 {
4500 } 4482 coding_system = detect_coding_system (PT_ADDR, inserted, 1, 0,
4501 4483 coding_system);
4502 if (!NILP (visit) 4484 setup_coding_system (coding_system, &coding);
4503 /* Can't do this if part of the buffer might be preserved. */ 4485 }
4504 && NILP (replace) 4486
4505 && (coding.type == coding_type_no_conversion 4487 if (CODING_FOR_UNIBYTE (&coding)
4506 || coding.type == coding_type_raw_text)) 4488 /* Can't do this if part of the buffer might be preserved. */
4507 { 4489 && NILP (replace))
4508 /* Visiting a file with these coding system makes the buffer 4490 /* Visiting a file with these coding system makes the buffer
4509 unibyte. */ 4491 unibyte. */
4510 current_buffer->enable_multibyte_characters = Qnil; 4492 current_buffer->enable_multibyte_characters = Qnil;
4511 coding.dst_multibyte = 0; 4493 }
4512 } 4494
4513 4495 coding.dst_multibyte = ! NILP (current_buffer->enable_multibyte_characters);
4514 if (inserted > 0 || coding.type == coding_type_ccl) 4496 if ((CODING_REQUIRE_DETECTION (&coding)
4515 { 4497 || CODING_REQUIRE_DECODING (&coding))
4516 if (CODING_MAY_REQUIRE_DECODING (&coding)) 4498 && (inserted > 0 || CODING_REQUIRE_FLUSHING (&coding)))
4517 { 4499 {
4518 code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, 4500 move_gap_both (PT, PT_BYTE);
4519 &coding, 0, 0); 4501 GAP_SIZE += inserted;
4520 inserted = coding.produced_char; 4502 ZV_BYTE -= inserted;
4521 } 4503 Z_BYTE -= inserted;
4522 else 4504 ZV -= inserted;
4523 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, 4505 Z -= inserted;
4524 inserted); 4506 decode_coding_gap (&coding, inserted, inserted);
4525 } 4507 inserted = coding.produced_char;
4508 }
4509 else if (inserted > 0)
4510 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4511 inserted);
4526 4512
4527 /* Now INSERTED is measured in characters. */ 4513 /* Now INSERTED is measured in characters. */
4528 4514
4529 #ifdef DOS_NT 4515 #ifdef DOS_NT
4530 /* Use the conversion type to determine buffer-file-type 4516 /* Use the conversion type to determine buffer-file-type
4531 (find-buffer-file-type is now used to help determine the 4517 (find-buffer-file-type is now used to help determine the
4532 conversion). */ 4518 conversion). */
4533 if ((coding.eol_type == CODING_EOL_UNDECIDED 4519 if ((coding.eol_type == eol_type_undecided
4534 || coding.eol_type == CODING_EOL_LF) 4520 || coding.eol_type == eol_type_lf)
4535 && ! CODING_REQUIRE_DECODING (&coding)) 4521 && ! CODING_REQUIRE_DECODING (&coding))
4536 current_buffer->buffer_file_type = Qt; 4522 current_buffer->buffer_file_type = Qt;
4537 else 4523 else
4538 current_buffer->buffer_file_type = Qnil; 4524 current_buffer->buffer_file_type = Qnil;
4539 #endif 4525 #endif
4570 Fcons (build_string ("not a regular file"), 4556 Fcons (build_string ("not a regular file"),
4571 Fcons (orig_filename, Qnil))); 4557 Fcons (orig_filename, Qnil)));
4572 } 4558 }
4573 4559
4574 if (set_coding_system) 4560 if (set_coding_system)
4575 Vlast_coding_system_used = coding.symbol; 4561 Vlast_coding_system_used = coding_system;
4576 4562
4577 if (! NILP (Ffboundp (Qafter_insert_file_set_coding))) 4563 if (! NILP (Ffboundp (Qafter_insert_file_set_coding)))
4578 { 4564 {
4579 insval = call1 (Qafter_insert_file_set_coding, make_number (inserted)); 4565 insval = call1 (Qafter_insert_file_set_coding, make_number (inserted));
4580 if (! NILP (insval)) 4566 if (! NILP (insval))
4648 4634
4649 RETURN_UNGCPRO (unbind_to (count, val)); 4635 RETURN_UNGCPRO (unbind_to (count, val));
4650 } 4636 }
4651 4637
4652 static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object)); 4638 static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));
4653 static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object,
4654 Lisp_Object, Lisp_Object));
4655 4639
4656 /* If build_annotations switched buffers, switch back to BUF. 4640 /* If build_annotations switched buffers, switch back to BUF.
4657 Kill the temporary buffer that was selected in the meantime. 4641 Kill the temporary buffer that was selected in the meantime.
4658 4642
4659 Since this kill only the last temporary buffer, some buffers remain 4643 Since this kill only the last temporary buffer, some buffers remain
4674 return Qnil; 4658 return Qnil;
4675 } 4659 }
4676 4660
4677 /* Decide the coding-system to encode the data with. */ 4661 /* Decide the coding-system to encode the data with. */
4678 4662
4679 void 4663 static Lisp_Object
4680 choose_write_coding_system (start, end, filename, 4664 choose_write_coding_system (start, end, filename,
4681 append, visit, lockname, coding) 4665 append, visit, lockname, coding)
4682 Lisp_Object start, end, filename, append, visit, lockname; 4666 Lisp_Object start, end, filename, append, visit, lockname;
4683 struct coding_system *coding; 4667 struct coding_system *coding;
4684 { 4668 {
4685 Lisp_Object val; 4669 Lisp_Object val;
4686 4670
4687 if (auto_saving) 4671 if (auto_saving)
4688 { 4672 val = Qutf_8_emacs;
4689 /* We use emacs-mule for auto saving... */
4690 setup_coding_system (Qemacs_mule, coding);
4691 /* ... but with the special flag to indicate not to strip off
4692 leading code of eight-bit-control chars. */
4693 coding->flags = 1;
4694 goto done_setup_coding;
4695 }
4696 else if (!NILP (Vcoding_system_for_write)) 4673 else if (!NILP (Vcoding_system_for_write))
4697 { 4674 {
4698 val = Vcoding_system_for_write; 4675 val = Vcoding_system_for_write;
4699 if (coding_system_require_warning 4676 if (coding_system_require_warning
4700 && !NILP (Ffboundp (Vselect_safe_coding_system_function))) 4677 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4737 coding_systems = Ffind_operation_coding_system (7, args); 4714 coding_systems = Ffind_operation_coding_system (7, args);
4738 if (CONSP (coding_systems) && !NILP (XCDR (coding_systems))) 4715 if (CONSP (coding_systems) && !NILP (XCDR (coding_systems)))
4739 val = XCDR (coding_systems); 4716 val = XCDR (coding_systems);
4740 } 4717 }
4741 4718
4742 if (NILP (val) 4719 if (NILP (val))
4743 && !NILP (current_buffer->buffer_file_coding_system))
4744 { 4720 {
4745 /* If we still have not decided a coding system, use the 4721 /* If we still have not decided a coding system, use the
4746 default value of buffer-file-coding-system. */ 4722 default value of buffer-file-coding-system. */
4747 val = current_buffer->buffer_file_coding_system; 4723 val = current_buffer->buffer_file_coding_system;
4748 using_default_coding = 1; 4724 using_default_coding = 1;
4725 }
4726
4727 if (! NILP (val) && ! force_raw_text)
4728 {
4729 Lisp_Object spec, attrs;
4730
4731 CHECK_CODING_SYSTEM_GET_SPEC (val, spec);
4732 attrs = AREF (spec, 0);
4733 if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
4734 force_raw_text = 1;
4749 } 4735 }
4750 4736
4751 if (!force_raw_text 4737 if (!force_raw_text
4752 && !NILP (Ffboundp (Vselect_safe_coding_system_function))) 4738 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4753 /* Confirm that VAL can surely encode the current region. */ 4739 /* Confirm that VAL can surely encode the current region. */
4754 val = call5 (Vselect_safe_coding_system_function, 4740 val = call5 (Vselect_safe_coding_system_function,
4755 start, end, val, Qnil, filename); 4741 start, end, val, Qnil, filename);
4756 4742
4757 setup_coding_system (Fcheck_coding_system (val), coding); 4743 /* If the decided coding-system doesn't specify end-of-line
4758 if (coding->eol_type == CODING_EOL_UNDECIDED 4744 format, we use that of
4759 && !using_default_coding) 4745 `default-buffer-file-coding-system'. */
4760 { 4746 if (! using_default_coding
4761 if (! EQ (default_buffer_file_coding.symbol, 4747 && ! NILP (buffer_defaults.buffer_file_coding_system))
4762 buffer_defaults.buffer_file_coding_system)) 4748 val = (coding_inherit_eol_type
4763 setup_coding_system (buffer_defaults.buffer_file_coding_system, 4749 (val, buffer_defaults.buffer_file_coding_system));
4764 &default_buffer_file_coding); 4750
4765 if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED) 4751 /* If we decide not to encode text, use `raw-text' or one of its
4766 { 4752 subsidiaries. */
4767 Lisp_Object subsidiaries;
4768
4769 coding->eol_type = default_buffer_file_coding.eol_type;
4770 subsidiaries = Fget (coding->symbol, Qeol_type);
4771 if (VECTORP (subsidiaries)
4772 && XVECTOR (subsidiaries)->size == 3)
4773 coding->symbol
4774 = XVECTOR (subsidiaries)->contents[coding->eol_type];
4775 }
4776 }
4777
4778 if (force_raw_text) 4753 if (force_raw_text)
4779 setup_raw_text_coding_system (coding); 4754 val = raw_text_coding_system (val);
4780 goto done_setup_coding; 4755 }
4781 } 4756
4782 4757 setup_coding_system (val, coding);
4783 setup_coding_system (Fcheck_coding_system (val), coding); 4758 if (! NILP (val)
4784 4759 && VECTORP (CODING_ID_EOL_TYPE (coding->id)))
4785 done_setup_coding: 4760 val = AREF (CODING_ID_EOL_TYPE (coding->id), 0);
4761
4786 if (!STRINGP (start) && !NILP (current_buffer->selective_display)) 4762 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4787 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; 4763 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
4764 return val;
4788 } 4765 }
4789 4766
4790 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7, 4767 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
4791 "r\nFWrite region to file: \ni\ni\ni\np", 4768 "r\nFWrite region to file: \ni\ni\ni\np",
4792 doc: /* Write current region into specified file. 4769 doc: /* Write current region into specified file.
4926 4903
4927 /* Decide the coding-system to encode the data with. 4904 /* Decide the coding-system to encode the data with.
4928 We used to make this choice before calling build_annotations, but that 4905 We used to make this choice before calling build_annotations, but that
4929 leads to problems when a write-annotate-function takes care of 4906 leads to problems when a write-annotate-function takes care of
4930 unsavable chars (as was the case with X-Symbol). */ 4907 unsavable chars (as was the case with X-Symbol). */
4931 choose_write_coding_system (start, end, filename, 4908 Vlast_coding_system_used
4932 append, visit, lockname, &coding); 4909 = choose_write_coding_system (start, end, filename,
4933 Vlast_coding_system_used = coding.symbol; 4910 append, visit, lockname, &coding);
4934
4935 given_buffer = current_buffer;
4936 if (! STRINGP (start))
4937 {
4938 annotations = build_annotations_2 (start, end,
4939 coding.pre_write_conversion, annotations);
4940 if (current_buffer != given_buffer)
4941 {
4942 XSETFASTINT (start, BEGV);
4943 XSETFASTINT (end, ZV);
4944 }
4945 }
4946 4911
4947 #ifdef CLASH_DETECTION 4912 #ifdef CLASH_DETECTION
4948 if (!auto_saving) 4913 if (!auto_saving)
4949 { 4914 {
4950 #if 0 /* This causes trouble for GNUS. */ 4915 #if 0 /* This causes trouble for GNUS. */
5078 * Yech! 5043 * Yech!
5079 */ 5044 */
5080 if (GPT > BEG && GPT_ADDR[-1] != '\n') 5045 if (GPT > BEG && GPT_ADDR[-1] != '\n')
5081 move_gap (find_next_newline (GPT, 1)); 5046 move_gap (find_next_newline (GPT, 1));
5082 #else 5047 #else
5048 #if 0
5049 /* The new encoding routine doesn't require the following. */
5050
5083 /* Whether VMS or not, we must move the gap to the next of newline 5051 /* Whether VMS or not, we must move the gap to the next of newline
5084 when we must put designation sequences at beginning of line. */ 5052 when we must put designation sequences at beginning of line. */
5085 if (INTEGERP (start) 5053 if (INTEGERP (start)
5086 && coding.type == coding_type_iso2022 5054 && coding.type == coding_type_iso2022
5087 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL 5055 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
5091 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0); 5059 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0);
5092 move_gap_both (PT, PT_BYTE); 5060 move_gap_both (PT, PT_BYTE);
5093 SET_PT_BOTH (opoint, opoint_byte); 5061 SET_PT_BOTH (opoint, opoint_byte);
5094 } 5062 }
5095 #endif 5063 #endif
5064 #endif
5096 5065
5097 failure = 0; 5066 failure = 0;
5098 immediate_quit = 1; 5067 immediate_quit = 1;
5099 5068
5100 if (STRINGP (start)) 5069 if (STRINGP (start))
5103 &annotations, &coding); 5072 &annotations, &coding);
5104 save_errno = errno; 5073 save_errno = errno;
5105 } 5074 }
5106 else if (XINT (start) != XINT (end)) 5075 else if (XINT (start) != XINT (end))
5107 { 5076 {
5108 tem = CHAR_TO_BYTE (XINT (start)); 5077 failure = 0 > a_write (desc, Qnil,
5109 5078 XINT (start), XINT (end) - XINT (start),
5110 if (XINT (start) < GPT) 5079 &annotations, &coding);
5111 { 5080 save_errno = errno;
5112 failure = 0 > a_write (desc, Qnil, XINT (start),
5113 min (GPT, XINT (end)) - XINT (start),
5114 &annotations, &coding);
5115 save_errno = errno;
5116 }
5117
5118 if (XINT (end) > GPT && !failure)
5119 {
5120 tem = max (XINT (start), GPT);
5121 failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem,
5122 &annotations, &coding);
5123 save_errno = errno;
5124 }
5125 } 5081 }
5126 else 5082 else
5127 { 5083 {
5128 /* If file was empty, still need to write the annotations */ 5084 /* If file was empty, still need to write the annotations */
5129 coding.mode |= CODING_MODE_LAST_BLOCK; 5085 coding.mode |= CODING_MODE_LAST_BLOCK;
5135 && !(coding.mode & CODING_MODE_LAST_BLOCK) 5091 && !(coding.mode & CODING_MODE_LAST_BLOCK)
5136 && ! failure) 5092 && ! failure)
5137 { 5093 {
5138 /* We have to flush out a data. */ 5094 /* We have to flush out a data. */
5139 coding.mode |= CODING_MODE_LAST_BLOCK; 5095 coding.mode |= CODING_MODE_LAST_BLOCK;
5140 failure = 0 > e_write (desc, Qnil, 0, 0, &coding); 5096 failure = 0 > e_write (desc, Qnil, 1, 1, &coding);
5141 save_errno = errno; 5097 save_errno = errno;
5142 } 5098 }
5143 5099
5144 immediate_quit = 0; 5100 immediate_quit = 0;
5145 5101
5325 5281
5326 UNGCPRO; 5282 UNGCPRO;
5327 return annotations; 5283 return annotations;
5328 } 5284 }
5329 5285
5330 static Lisp_Object
5331 build_annotations_2 (start, end, pre_write_conversion, annotations)
5332 Lisp_Object start, end, pre_write_conversion, annotations;
5333 {
5334 struct gcpro gcpro1;
5335 Lisp_Object res;
5336
5337 GCPRO1 (annotations);
5338 /* At last, do the same for the function PRE_WRITE_CONVERSION
5339 implied by the current coding-system. */
5340 if (!NILP (pre_write_conversion))
5341 {
5342 struct buffer *given_buffer = current_buffer;
5343 Vwrite_region_annotations_so_far = annotations;
5344 res = call2 (pre_write_conversion, start, end);
5345 Flength (res);
5346 annotations = (current_buffer != given_buffer
5347 ? res
5348 : merge (annotations, res, Qcar_less_than_car));
5349 }
5350
5351 UNGCPRO;
5352 return annotations;
5353 }
5354 5286
5355 /* Write to descriptor DESC the NCHARS chars starting at POS of STRING. 5287 /* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
5356 If STRING is nil, POS is the character position in the current buffer. 5288 If STRING is nil, POS is the character position in the current buffer.
5357 Intersperse with them the annotations from *ANNOT 5289 Intersperse with them the annotations from *ANNOT
5358 which fall within the range of POS to POS + NCHARS, 5290 which fall within the range of POS to POS + NCHARS,
5420 int desc; 5352 int desc;
5421 Lisp_Object string; 5353 Lisp_Object string;
5422 int start, end; 5354 int start, end;
5423 struct coding_system *coding; 5355 struct coding_system *coding;
5424 { 5356 {
5425 register char *addr;
5426 register int nbytes;
5427 char buf[WRITE_BUF_SIZE];
5428 int return_val = 0; 5357 int return_val = 0;
5429 5358
5430 if (start >= end)
5431 coding->composing = COMPOSITION_DISABLED;
5432 if (coding->composing != COMPOSITION_DISABLED)
5433 coding_save_composition (coding, start, end, string);
5434
5435 if (STRINGP (string)) 5359 if (STRINGP (string))
5436 { 5360 {
5437 addr = SDATA (string); 5361 start = 0;
5438 nbytes = SBYTES (string); 5362 end = SCHARS (string);
5439 coding->src_multibyte = STRING_MULTIBYTE (string);
5440 }
5441 else if (start < end)
5442 {
5443 /* It is assured that the gap is not in the range START and END-1. */
5444 addr = CHAR_POS_ADDR (start);
5445 nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start);
5446 coding->src_multibyte
5447 = !NILP (current_buffer->enable_multibyte_characters);
5448 }
5449 else
5450 {
5451 addr = "";
5452 nbytes = 0;
5453 coding->src_multibyte = 1;
5454 } 5363 }
5455 5364
5456 /* We used to have a code for handling selective display here. But, 5365 /* We used to have a code for handling selective display here. But,
5457 now it is handled within encode_coding. */ 5366 now it is handled within encode_coding. */
5458 while (1) 5367 do
5459 { 5368 {
5460 int result; 5369 if (STRINGP (string))
5461 5370 encode_coding_object (coding, string,
5462 result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE); 5371 start, string_char_to_byte (string, start),
5372 end, string_char_to_byte (string, end), Qt);
5373 else
5374 encode_coding_object (coding, Fcurrent_buffer (),
5375 start, CHAR_TO_BYTE (start),
5376 end, CHAR_TO_BYTE (end), Qt);
5377
5463 if (coding->produced > 0) 5378 if (coding->produced > 0)
5464 { 5379 {
5465 coding->produced -= emacs_write (desc, buf, coding->produced); 5380 coding->produced -= emacs_write (desc, SDATA (coding->dst_object),
5381 coding->produced);
5382
5466 if (coding->produced) 5383 if (coding->produced)
5467 { 5384 {
5468 return_val = -1; 5385 return_val = -1;
5469 break; 5386 break;
5470 } 5387 }
5471 } 5388 }
5472 nbytes -= coding->consumed;
5473 addr += coding->consumed;
5474 if (result == CODING_FINISH_INSUFFICIENT_SRC
5475 && nbytes > 0)
5476 {
5477 /* The source text ends by an incomplete multibyte form.
5478 There's no way other than write it out as is. */
5479 nbytes -= emacs_write (desc, addr, nbytes);
5480 if (nbytes)
5481 {
5482 return_val = -1;
5483 break;
5484 }
5485 }
5486 if (nbytes <= 0)
5487 break;
5488 start += coding->consumed_char; 5389 start += coding->consumed_char;
5489 if (coding->cmp_data) 5390 }
5490 coding_adjust_composition_offset (coding, start); 5391 while (start < end);
5491 }
5492
5493 if (coding->cmp_data)
5494 coding_free_composition_data (coding);
5495 5392
5496 return return_val; 5393 return return_val;
5497 } 5394 }
5498 5395
5499 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, 5396 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,