Mercurial > emacs
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, |