comparison src/fileio.c @ 88374:fa717c37ad16

Include "character.h" instead of "charset.h". (Finsert_file_contents): Big change for the new code-conversion API. (choose_write_coding_system): Likewise. (Fwrite_region): Likewise. (build_annotations_2): Deleted. (e_write): Big change for the new code-conversion API.
author Kenichi Handa <handa@m17n.org>
date Fri, 01 Mar 2002 01:38:37 +0000
parents 1874239cb5be
children d5ba4152bd1b
comparison
equal deleted inserted replaced
88373:9c612c1faba4 88374:fa717c37ad16
85 #endif 85 #endif
86 86
87 #include "lisp.h" 87 #include "lisp.h"
88 #include "intervals.h" 88 #include "intervals.h"
89 #include "buffer.h" 89 #include "buffer.h"
90 #include "charset.h" 90 #include "character.h"
91 #include "coding.h" 91 #include "coding.h"
92 #include "window.h" 92 #include "window.h"
93 93
94 #ifdef WINDOWSNT 94 #ifdef WINDOWSNT
95 #define NOMINMAX 1 95 #define NOMINMAX 1
3574 unsigned char read_buf[READ_BUF_SIZE]; 3574 unsigned char read_buf[READ_BUF_SIZE];
3575 struct coding_system coding; 3575 struct coding_system coding;
3576 unsigned char buffer[1 << 14]; 3576 unsigned char buffer[1 << 14];
3577 int replace_handled = 0; 3577 int replace_handled = 0;
3578 int set_coding_system = 0; 3578 int set_coding_system = 0;
3579 int coding_system_decided = 0; 3579 Lisp_Object coding_system;
3580 int read_quit = 0; 3580 int read_quit = 0;
3581 3581
3582 if (current_buffer->base_buffer && ! NILP (visit)) 3582 if (current_buffer->base_buffer && ! NILP (visit))
3583 error ("Cannot do file visiting in an indirect buffer"); 3583 error ("Cannot do file visiting in an indirect buffer");
3584 3584
3711 if (st.st_size == 0) 3711 if (st.st_size == 0)
3712 XSETINT (end, READ_BUF_SIZE); 3712 XSETINT (end, READ_BUF_SIZE);
3713 } 3713 }
3714 } 3714 }
3715 3715
3716 /* The value Qnil means that the coding system is not yet
3717 decided. */
3718 coding_system = Qnil;
3716 if (BEG < Z) 3719 if (BEG < Z)
3717 { 3720 {
3718 /* Decide the coding system to use for reading the file now 3721 /* Decide the coding system to use for reading the file now
3719 because we can't use an optimized method for handling 3722 because we can't use an optimized method for handling
3720 `coding:' tag if the current buffer is not empty. */ 3723 `coding:' tag if the current buffer is not empty. */
3721 Lisp_Object val;
3722 val = Qnil;
3723
3724 if (!NILP (Vcoding_system_for_read)) 3724 if (!NILP (Vcoding_system_for_read))
3725 val = Vcoding_system_for_read; 3725 coding_system = Vcoding_system_for_read;
3726 else if (! NILP (replace)) 3726 else if (! NILP (replace))
3727 /* In REPLACE mode, we can use the same coding system 3727 /* In REPLACE mode, we can use the same coding system
3728 that was used to visit the file. */ 3728 that was used to visit the file. */
3729 val = current_buffer->buffer_file_coding_system; 3729 coding_system = current_buffer->buffer_file_coding_system;
3730 else 3730 else
3731 { 3731 {
3732 /* Don't try looking inside a file for a coding system 3732 /* Don't try looking inside a file for a coding system
3733 specification if it is not seekable. */ 3733 specification if it is not seekable. */
3734 if (! not_regular && ! NILP (Vset_auto_coding_function)) 3734 if (! not_regular && ! NILP (Vset_auto_coding_function))
3771 3771
3772 set_buffer_internal (XBUFFER (Vstandard_output)); 3772 set_buffer_internal (XBUFFER (Vstandard_output));
3773 current_buffer->enable_multibyte_characters = Qnil; 3773 current_buffer->enable_multibyte_characters = Qnil;
3774 insert_1_both (read_buf, nread, nread, 0, 0, 0); 3774 insert_1_both (read_buf, nread, nread, 0, 0, 0);
3775 TEMP_SET_PT_BOTH (BEG, BEG_BYTE); 3775 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3776 val = call2 (Vset_auto_coding_function, 3776 coding_system = call2 (Vset_auto_coding_function,
3777 filename, make_number (nread)); 3777 filename, make_number (nread));
3778 set_buffer_internal (prev); 3778 set_buffer_internal (prev);
3779 3779
3780 /* Remove the binding for standard-output. */ 3780 /* Remove the binding for standard-output. */
3781 unbind_to (count1, Qnil); 3781 unbind_to (count1, Qnil);
3782 3782
3789 report_file_error ("Setting file position", 3789 report_file_error ("Setting file position",
3790 Fcons (orig_filename, Qnil)); 3790 Fcons (orig_filename, Qnil));
3791 } 3791 }
3792 } 3792 }
3793 3793
3794 if (NILP (val)) 3794 if (NILP (coding_system))
3795 { 3795 {
3796 /* If we have not yet decided a coding system, check 3796 /* If we have not yet decided a coding system, check
3797 file-coding-system-alist. */ 3797 file-coding-system-alist. */
3798 Lisp_Object args[6], coding_systems; 3798 Lisp_Object args[6], coding_systems;
3799 3799
3803 if (CONSP (coding_systems)) 3803 if (CONSP (coding_systems))
3804 val = XCAR (coding_systems); 3804 val = XCAR (coding_systems);
3805 } 3805 }
3806 } 3806 }
3807 3807
3808 setup_coding_system (Fcheck_coding_system (val), &coding); 3808 if (NILP (coding_system))
3809 coding_system = Qundecided;
3810 else
3811 CHECK_CODING_SYSTEM (coding_system);
3812
3813 if (NILP (current_buffer->enable_multibyte_characters))
3814 /* We must suppress all character code conversion except for
3815 end-of-line conversion. */
3816 coding_system = raw_text_coding_system (coding_system);
3817
3818 setup_coding_system (coding_system, &coding);
3809 /* Ensure we set Vlast_coding_system_used. */ 3819 /* Ensure we set Vlast_coding_system_used. */
3810 set_coding_system = 1; 3820 set_coding_system = 1;
3811
3812 if (NILP (current_buffer->enable_multibyte_characters)
3813 && ! NILP (val))
3814 /* We must suppress all character code conversion except for
3815 end-of-line conversion. */
3816 setup_raw_text_coding_system (&coding);
3817
3818 coding.src_multibyte = 0;
3819 coding.dst_multibyte
3820 = !NILP (current_buffer->enable_multibyte_characters);
3821 coding_system_decided = 1;
3822 } 3821 }
3823 3822
3824 /* If requested, replace the accessible part of the buffer 3823 /* If requested, replace the accessible part of the buffer
3825 with the file contents. Avoid replacing text at the 3824 with the file contents. Avoid replacing text at the
3826 beginning or end of the buffer that matches the file contents; 3825 beginning or end of the buffer that matches the file contents;
3835 method and hope for the best. 3834 method and hope for the best.
3836 But if we discover the need for conversion, we give up on this method 3835 But if we discover the need for conversion, we give up on this method
3837 and let the following if-statement handle the replace job. */ 3836 and let the following if-statement handle the replace job. */
3838 if (!NILP (replace) 3837 if (!NILP (replace)
3839 && BEGV < ZV 3838 && BEGV < ZV
3840 && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK)) 3839 && (NILP (coding_system)
3840 || ! CODING_REQUIRE_DECODING (&coding)))
3841 { 3841 {
3842 /* same_at_start and same_at_end count bytes, 3842 /* same_at_start and same_at_end count bytes,
3843 because file access counts bytes 3843 because file access counts bytes
3844 and BEG and END count bytes. */ 3844 and BEG and END count bytes. */
3845 int same_at_start = BEGV_BYTE; 3845 int same_at_start = BEGV_BYTE;
3870 error ("IO error reading %s: %s", 3870 error ("IO error reading %s: %s",
3871 XSTRING (orig_filename)->data, emacs_strerror (errno)); 3871 XSTRING (orig_filename)->data, emacs_strerror (errno));
3872 else if (nread == 0) 3872 else if (nread == 0)
3873 break; 3873 break;
3874 3874
3875 if (coding.type == coding_type_undecided) 3875 if (CODING_REQUIRE_DETECTION (&coding))
3876 detect_coding (&coding, buffer, nread); 3876 {
3877 if (coding.common_flags & CODING_REQUIRE_DECODING_MASK) 3877 coding_system = detect_coding_system (buffer, nread, 1, 0,
3878 coding_system);
3879 setup_coding_system (coding_system, &coding);
3880 }
3881 if (CODING_REQUIRE_DECODING (&coding))
3878 /* We found that the file should be decoded somehow. 3882 /* We found that the file should be decoded somehow.
3879 Let's give up here. */
3880 {
3881 giveup_match_end = 1;
3882 break;
3883 }
3884
3885 if (coding.eol_type == CODING_EOL_UNDECIDED)
3886 detect_eol (&coding, buffer, nread);
3887 if (coding.eol_type != CODING_EOL_UNDECIDED
3888 && coding.eol_type != CODING_EOL_LF)
3889 /* We found that the format of eol should be decoded.
3890 Let's give up here. */ 3883 Let's give up here. */
3891 { 3884 {
3892 giveup_match_end = 1; 3885 giveup_match_end = 1;
3893 break; 3886 break;
3894 } 3887 }
4031 { 4024 {
4032 int same_at_start = BEGV_BYTE; 4025 int same_at_start = BEGV_BYTE;
4033 int same_at_end = ZV_BYTE; 4026 int same_at_end = ZV_BYTE;
4034 int overlap; 4027 int overlap;
4035 int bufpos; 4028 int bufpos;
4036 /* Make sure that the gap is large enough. */ 4029 unsigned char *decoded;
4037 int bufsize = 2 * st.st_size;
4038 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
4039 int temp; 4030 int temp;
4031 int this_count = BINDING_STACK_SIZE ();
4032 Lisp_Object conversion_buffer
4033 = make_conversion_work_buffer (! NILP (current_buffer
4034 ->enable_multibyte_characters));
4035
4036 record_unwind_protect (code_conversion_restore, save_excursion_save ());
4040 4037
4041 /* First read the whole file, performing code conversion into 4038 /* First read the whole file, performing code conversion into
4042 CONVERSION_BUFFER. */ 4039 CONVERSION_BUFFER. */
4043 4040
4044 if (lseek (fd, XINT (beg), 0) < 0) 4041 if (lseek (fd, XINT (beg), 0) < 0)
4045 { 4042 {
4046 xfree (conversion_buffer);
4047 report_file_error ("Setting file position", 4043 report_file_error ("Setting file position",
4048 Fcons (orig_filename, Qnil)); 4044 Fcons (orig_filename, Qnil));
4049 } 4045 }
4050 4046
4051 total = st.st_size; /* Total bytes in the file. */ 4047 total = st.st_size; /* Total bytes in the file. */
4053 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ 4049 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
4054 unprocessed = 0; /* Bytes not processed in previous loop. */ 4050 unprocessed = 0; /* Bytes not processed in previous loop. */
4055 4051
4056 while (how_much < total) 4052 while (how_much < total)
4057 { 4053 {
4054 /* We read one bunch by one (READ_BUF_SIZE bytes) to allow
4055 quitting while reading a huge while. */
4058 /* try is reserved in some compilers (Microsoft C) */ 4056 /* try is reserved in some compilers (Microsoft C) */
4059 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); 4057 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
4060 unsigned char *destination = read_buf + unprocessed;
4061 int this; 4058 int this;
4062 4059
4063 /* Allow quitting out of the actual I/O. */ 4060 /* Allow quitting out of the actual I/O. */
4064 immediate_quit = 1; 4061 immediate_quit = 1;
4065 QUIT; 4062 QUIT;
4066 this = emacs_read (fd, destination, trytry); 4063 this = emacs_read (fd, read_buf + unprocessed, trytry);
4067 immediate_quit = 0; 4064 immediate_quit = 0;
4068 4065
4069 if (this < 0 || this + unprocessed == 0) 4066 if (this <= 0)
4070 { 4067 {
4071 how_much = this; 4068 if (this < 0)
4069 how_much = this;
4072 break; 4070 break;
4073 } 4071 }
4074 4072
4075 how_much += this; 4073 how_much += this;
4076 4074
4077 if (CODING_MAY_REQUIRE_DECODING (&coding)) 4075 decode_coding_c_string (&coding, read_buf, unprocessed + this,
4078 { 4076 conversion_buffer);
4079 int require, result; 4077 unprocessed = coding.carryover_bytes;
4080 4078 if (coding.carryover_bytes > 0)
4081 this += unprocessed; 4079 bcopy (coding.carryover, read_buf, unprocessed);
4082 4080 }
4083 /* If we are using more space than estimated, 4081
4084 make CONVERSION_BUFFER bigger. */ 4082 emacs_close (fd);
4085 require = decoding_buffer_size (&coding, this); 4083
4086 if (inserted + require + 2 * (total - how_much) > bufsize) 4084 /* At this point, HOW_MUCH should equal TOTAL, or should be <= 0
4087 { 4085 if we couldn't read the file. */
4088 bufsize = inserted + require + 2 * (total - how_much);
4089 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
4090 }
4091
4092 /* Convert this batch with results in CONVERSION_BUFFER. */
4093 if (how_much >= total) /* This is the last block. */
4094 coding.mode |= CODING_MODE_LAST_BLOCK;
4095 if (coding.composing != COMPOSITION_DISABLED)
4096 coding_allocate_composition_data (&coding, BEGV);
4097 result = decode_coding (&coding, read_buf,
4098 conversion_buffer + inserted,
4099 this, bufsize - inserted);
4100
4101 /* Save for next iteration whatever we didn't convert. */
4102 unprocessed = this - coding.consumed;
4103 bcopy (read_buf + coding.consumed, read_buf, unprocessed);
4104 if (!NILP (current_buffer->enable_multibyte_characters))
4105 this = coding.produced;
4106 else
4107 this = str_as_unibyte (conversion_buffer + inserted,
4108 coding.produced);
4109 }
4110
4111 inserted += this;
4112 }
4113
4114 /* At this point, INSERTED is how many characters (i.e. bytes)
4115 are present in CONVERSION_BUFFER.
4116 HOW_MUCH should equal TOTAL,
4117 or should be <= 0 if we couldn't read the file. */
4118 4086
4119 if (how_much < 0) 4087 if (how_much < 0)
4120 { 4088 {
4121 xfree (conversion_buffer);
4122
4123 if (how_much == -1) 4089 if (how_much == -1)
4124 error ("IO error reading %s: %s", 4090 error ("IO error reading %s: %s",
4125 XSTRING (orig_filename)->data, emacs_strerror (errno)); 4091 XSTRING (orig_filename)->data, emacs_strerror (errno));
4126 else if (how_much == -2) 4092 else if (how_much == -2)
4127 error ("maximum buffer size exceeded"); 4093 error ("maximum buffer size exceeded");
4128 } 4094 }
4129 4095
4130 /* Compare the beginning of the converted file 4096 if (unprocessed > 0)
4131 with the buffer text. */ 4097 {
4098 coding.mode |= CODING_MODE_LAST_BLOCK;
4099 decode_coding_c_string (&coding, read_buf, unprocessed,
4100 conversion_buffer);
4101 coding.mode &= ~CODING_MODE_LAST_BLOCK;
4102 }
4103
4104 decoded = BUF_BEG_ADDR (XBUFFER (conversion_buffer));
4105 inserted = BUF_Z_BYTE (XBUFFER (conversion_buffer));
4106
4107 /* Compare the beginning of the converted string with the buffer
4108 text. */
4132 4109
4133 bufpos = 0; 4110 bufpos = 0;
4134 while (bufpos < inserted && same_at_start < same_at_end 4111 while (bufpos < inserted && same_at_start < same_at_end
4135 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos]) 4112 && FETCH_BYTE (same_at_start) == decoded[bufpos])
4136 same_at_start++, bufpos++; 4113 same_at_start++, bufpos++;
4137 4114
4138 /* If the file matches the buffer completely, 4115 /* If the file matches the head of buffer completely,
4139 there's no need to replace anything. */ 4116 there's no need to replace anything. */
4140 4117
4141 if (bufpos == inserted) 4118 if (bufpos == inserted)
4142 { 4119 {
4143 xfree (conversion_buffer);
4144 emacs_close (fd);
4145 specpdl_ptr--; 4120 specpdl_ptr--;
4146 /* Truncate the buffer to the size of the file. */ 4121 /* Truncate the buffer to the size of the file. */
4147 del_range_byte (same_at_start, same_at_end, 0); 4122 del_range_byte (same_at_start, same_at_end, 0);
4148 inserted = 0; 4123 inserted = 0;
4149 goto handled; 4124 goto handled;
4150 } 4125 }
4151 4126
4152 /* Extend the start of non-matching text area to multibyte 4127 /* Extend the start of non-matching text area to the previous
4153 character boundary. */ 4128 multibyte character boundary. */
4154 if (! NILP (current_buffer->enable_multibyte_characters)) 4129 if (! NILP (current_buffer->enable_multibyte_characters))
4155 while (same_at_start > BEGV_BYTE 4130 while (same_at_start > BEGV_BYTE
4156 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start))) 4131 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
4157 same_at_start--; 4132 same_at_start--;
4158 4133
4161 bufpos = inserted; 4136 bufpos = inserted;
4162 4137
4163 /* Compare with same_at_start to avoid counting some buffer text 4138 /* Compare with same_at_start to avoid counting some buffer text
4164 as matching both at the file's beginning and at the end. */ 4139 as matching both at the file's beginning and at the end. */
4165 while (bufpos > 0 && same_at_end > same_at_start 4140 while (bufpos > 0 && same_at_end > same_at_start
4166 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1]) 4141 && FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1])
4167 same_at_end--, bufpos--; 4142 same_at_end--, bufpos--;
4168 4143
4169 /* Extend the end of non-matching text area to multibyte 4144 /* Extend the end of non-matching text area to the next
4170 character boundary. */ 4145 multibyte character boundary. */
4171 if (! NILP (current_buffer->enable_multibyte_characters)) 4146 if (! NILP (current_buffer->enable_multibyte_characters))
4172 while (same_at_end < ZV_BYTE 4147 while (same_at_end < ZV_BYTE
4173 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end))) 4148 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
4174 same_at_end++; 4149 same_at_end++;
4175 4150
4183 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) 4158 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
4184 XWINDOW (selected_window)->start_at_line_beg = Fbolp (); 4159 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
4185 4160
4186 /* Replace the chars that we need to replace, 4161 /* Replace the chars that we need to replace,
4187 and update INSERTED to equal the number of bytes 4162 and update INSERTED to equal the number of bytes
4188 we are taking from the file. */ 4163 we are taking from the decoded string. */
4189 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); 4164 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
4190 4165
4191 if (same_at_end != same_at_start) 4166 if (same_at_end != same_at_start)
4192 { 4167 {
4193 del_range_byte (same_at_start, same_at_end, 0); 4168 del_range_byte (same_at_start, same_at_end, 0);
4194 temp = GPT; 4169 temp = GPT;
4195 same_at_start = GPT_BYTE; 4170 same_at_start = GPT_BYTE;
4196 } 4171 }
4197 else 4172 else
4198 { 4173 {
4199 temp = BYTE_TO_CHAR (same_at_start); 4174 temp = BYTE_TO_CHAR (same_at_start);
4200 } 4175 }
4201 /* Insert from the file at the proper position. */ 4176 /* Insert from the file at the proper position. */
4202 SET_PT_BOTH (temp, same_at_start); 4177 SET_PT_BOTH (temp, same_at_start);
4203 insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted, 4178 insert_from_buffer (XBUFFER (conversion_buffer),
4204 0, 0, 0); 4179 buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4205 if (coding.cmp_data && coding.cmp_data->used) 4180 same_at_start),
4206 coding_restore_composition (&coding, Fcurrent_buffer ()); 4181 buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4207 coding_free_composition_data (&coding); 4182 same_at_start + inserted),
4208 4183 0);
4209 /* Set `inserted' to the number of inserted characters. */ 4184 /* Set `inserted' to the number of inserted characters. */
4210 inserted = PT - temp; 4185 inserted = PT - temp;
4211 4186
4212 xfree (conversion_buffer); 4187 unbind_to (this_count, Qnil);
4213 emacs_close (fd);
4214 specpdl_ptr--;
4215 4188
4216 goto handled; 4189 goto handled;
4217 } 4190 }
4218 4191
4219 if (! not_regular) 4192 if (! not_regular)
4253 4226
4254 /* Total bytes inserted. */ 4227 /* Total bytes inserted. */
4255 inserted = 0; 4228 inserted = 0;
4256 4229
4257 /* Here, we don't do code conversion in the loop. It is done by 4230 /* Here, we don't do code conversion in the loop. It is done by
4258 code_convert_region after all data are read into the buffer. */ 4231 decode_coding_gap after all data are read into the buffer. */
4259 { 4232 {
4260 int gap_size = GAP_SIZE; 4233 int gap_size = GAP_SIZE;
4261 4234
4262 while (how_much < total) 4235 while (how_much < total)
4263 { 4236 {
4344 error ("IO error reading %s: %s", 4317 error ("IO error reading %s: %s",
4345 XSTRING (orig_filename)->data, emacs_strerror (errno)); 4318 XSTRING (orig_filename)->data, emacs_strerror (errno));
4346 4319
4347 notfound: 4320 notfound:
4348 4321
4349 if (! coding_system_decided) 4322 if (NILP (coding_system))
4350 { 4323 {
4351 /* The coding system is not yet decided. Decide it by an 4324 /* The coding system is not yet decided. Decide it by an
4352 optimized method for handling `coding:' tag. 4325 optimized method for handling `coding:' tag.
4353 4326
4354 Note that we can get here only if the buffer was empty 4327 Note that we can get here only if the buffer was empty
4355 before the insertion. */ 4328 before the insertion. */
4356 Lisp_Object val;
4357 val = Qnil;
4358 4329
4359 if (!NILP (Vcoding_system_for_read)) 4330 if (!NILP (Vcoding_system_for_read))
4360 val = Vcoding_system_for_read; 4331 coding_system = Vcoding_system_for_read;
4361 else 4332 else
4362 { 4333 {
4363 /* Since we are sure that the current buffer was empty 4334 /* Since we are sure that the current buffer was empty
4364 before the insertion, we can toggle 4335 before the insertion, we can toggle
4365 enable-multibyte-characters directly here without taking 4336 enable-multibyte-characters directly here without taking
4376 current_buffer->undo_list = Qt; 4347 current_buffer->undo_list = Qt;
4377 record_unwind_protect (decide_coding_unwind, unwind_data); 4348 record_unwind_protect (decide_coding_unwind, unwind_data);
4378 4349
4379 if (inserted > 0 && ! NILP (Vset_auto_coding_function)) 4350 if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4380 { 4351 {
4381 val = call2 (Vset_auto_coding_function, 4352 coding_system = call2 (Vset_auto_coding_function,
4382 filename, make_number (inserted)); 4353 filename, make_number (inserted));
4383 } 4354 }
4384 4355
4385 if (NILP (val)) 4356 if (NILP (coding_system))
4386 { 4357 {
4387 /* If the coding system is not yet decided, check 4358 /* If the coding system is not yet decided, check
4388 file-coding-system-alist. */ 4359 file-coding-system-alist. */
4389 Lisp_Object args[6], coding_systems; 4360 Lisp_Object args[6], coding_systems;
4390 4361
4391 args[0] = Qinsert_file_contents, args[1] = orig_filename; 4362 args[0] = Qinsert_file_contents, args[1] = orig_filename;
4392 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil; 4363 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4393 coding_systems = Ffind_operation_coding_system (6, args); 4364 coding_systems = Ffind_operation_coding_system (6, args);
4394 if (CONSP (coding_systems)) 4365 if (CONSP (coding_systems))
4395 val = XCAR (coding_systems); 4366 coding_system = XCAR (coding_systems);
4396 } 4367 }
4397 4368
4398 unbind_to (count, Qnil); 4369 unbind_to (count, Qnil);
4399 inserted = Z_BYTE - BEG_BYTE; 4370 inserted = Z_BYTE - BEG_BYTE;
4400 } 4371 }
4401 4372
4402 /* The following kludgy code is to avoid some compiler bug. 4373 if (NILP (coding_system))
4403 We can't simply do 4374 coding_system = Qundecided;
4404 setup_coding_system (val, &coding); 4375 else
4405 on some system. */ 4376 CHECK_CODING_SYSTEM (coding_system);
4406 { 4377
4407 struct coding_system temp_coding; 4378 if (NILP (current_buffer->enable_multibyte_characters))
4408 setup_coding_system (val, &temp_coding); 4379 /* We must suppress all character code conversion except for
4409 bcopy (&temp_coding, &coding, sizeof coding); 4380 end-of-line conversion. */
4410 } 4381 coding_system = raw_text_coding_system (coding_system);
4382
4383 setup_coding_system (coding_system, &coding);
4411 /* Ensure we set Vlast_coding_system_used. */ 4384 /* Ensure we set Vlast_coding_system_used. */
4412 set_coding_system = 1; 4385 set_coding_system = 1;
4413 4386 }
4414 if (NILP (current_buffer->enable_multibyte_characters) 4387
4415 && ! NILP (val)) 4388 if (!NILP (visit))
4416 /* We must suppress all character code conversion except for 4389 {
4417 end-of-line conversion. */ 4390 /* When we visit a file by raw-text, we change the buffer to
4418 setup_raw_text_coding_system (&coding); 4391 unibyte. If we have not yet decided how to decode a text,
4419 coding.src_multibyte = 0; 4392 decide it at first by detecting the file's encoding. */
4420 coding.dst_multibyte 4393 if (CODING_REQUIRE_DETECTION (&coding))
4421 = !NILP (current_buffer->enable_multibyte_characters); 4394 {
4422 } 4395 coding_system = detect_coding_system (PT_ADDR, inserted, 1, 0,
4423 4396 coding_system);
4424 if (!NILP (visit) 4397 setup_coding_system (coding_system, &coding);
4425 /* Can't do this if part of the buffer might be preserved. */ 4398 }
4426 && NILP (replace) 4399
4427 && (coding.type == coding_type_no_conversion 4400 if (CODING_FOR_UNIBYTE (&coding)
4428 || coding.type == coding_type_raw_text)) 4401 /* Can't do this if part of the buffer might be preserved. */
4429 { 4402 && NILP (replace))
4430 /* Visiting a file with these coding system makes the buffer 4403 /* Visiting a file with these coding system makes the buffer
4431 unibyte. */ 4404 unibyte. */
4432 current_buffer->enable_multibyte_characters = Qnil; 4405 current_buffer->enable_multibyte_characters = Qnil;
4433 coding.dst_multibyte = 0; 4406 }
4434 } 4407
4435 4408 if (CODING_REQUIRE_DETECTION (&coding)
4436 if (inserted > 0 || coding.type == coding_type_ccl) 4409 || CODING_REQUIRE_DECODING (&coding))
4437 { 4410 {
4438 if (CODING_MAY_REQUIRE_DECODING (&coding)) 4411 move_gap_both (PT, PT_BYTE);
4439 { 4412 GAP_SIZE += inserted;
4440 code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, 4413 ZV_BYTE -= inserted;
4441 &coding, 0, 0); 4414 Z_BYTE -= inserted;
4442 inserted = coding.produced_char; 4415 ZV -= inserted;
4443 } 4416 Z -= inserted;
4444 else 4417 decode_coding_gap (&coding, inserted, inserted);
4445 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, 4418 inserted = coding.produced_char;
4446 inserted); 4419 }
4447 } 4420 else if (inserted > 0)
4421 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4422 inserted);
4448 4423
4449 #ifdef DOS_NT 4424 #ifdef DOS_NT
4450 /* Use the conversion type to determine buffer-file-type 4425 /* Use the conversion type to determine buffer-file-type
4451 (find-buffer-file-type is now used to help determine the 4426 (find-buffer-file-type is now used to help determine the
4452 conversion). */ 4427 conversion). */
4453 if ((coding.eol_type == CODING_EOL_UNDECIDED 4428 if ((coding.eol_type == eol_type_undecided
4454 || coding.eol_type == CODING_EOL_LF) 4429 || coding.eol_type == eol_type_lf)
4455 && ! CODING_REQUIRE_DECODING (&coding)) 4430 && ! CODING_REQUIRE_DECODING (&coding))
4456 current_buffer->buffer_file_type = Qt; 4431 current_buffer->buffer_file_type = Qt;
4457 else 4432 else
4458 current_buffer->buffer_file_type = Qnil; 4433 current_buffer->buffer_file_type = Qnil;
4459 #endif 4434 #endif
4513 if (!NILP (visit)) 4488 if (!NILP (visit))
4514 current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt; 4489 current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt;
4515 } 4490 }
4516 4491
4517 if (set_coding_system) 4492 if (set_coding_system)
4518 Vlast_coding_system_used = coding.symbol; 4493 Vlast_coding_system_used = coding_system;
4519 4494
4520 /* Call after-change hooks for the inserted text, aside from the case 4495 /* Call after-change hooks for the inserted text, aside from the case
4521 of normal visiting (not with REPLACE), which is done in a new buffer 4496 of normal visiting (not with REPLACE), which is done in a new buffer
4522 "before" the buffer is changed. */ 4497 "before" the buffer is changed. */
4523 if (inserted > 0 && total > 0 4498 if (inserted > 0 && total > 0
4558 4533
4559 RETURN_UNGCPRO (unbind_to (count, val)); 4534 RETURN_UNGCPRO (unbind_to (count, val));
4560 } 4535 }
4561 4536
4562 static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object)); 4537 static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));
4563 static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object,
4564 Lisp_Object, Lisp_Object));
4565 4538
4566 /* If build_annotations switched buffers, switch back to BUF. 4539 /* If build_annotations switched buffers, switch back to BUF.
4567 Kill the temporary buffer that was selected in the meantime. 4540 Kill the temporary buffer that was selected in the meantime.
4568 4541
4569 Since this kill only the last temporary buffer, some buffers remain 4542 Since this kill only the last temporary buffer, some buffers remain
4641 default value of buffer-file-coding-system. */ 4614 default value of buffer-file-coding-system. */
4642 val = current_buffer->buffer_file_coding_system; 4615 val = current_buffer->buffer_file_coding_system;
4643 using_default_coding = 1; 4616 using_default_coding = 1;
4644 } 4617 }
4645 4618
4619 if (! NILP (val) && ! force_raw_text)
4620 {
4621 Lisp_Object spec, attrs;
4622
4623 CHECK_CODING_SYSTEM_GET_SPEC (val, spec);
4624 attrs = AREF (spec, 0);
4625 if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
4626 force_raw_text = 1;
4627 }
4628
4646 if (!force_raw_text 4629 if (!force_raw_text
4647 && !NILP (Ffboundp (Vselect_safe_coding_system_function))) 4630 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4648 /* Confirm that VAL can surely encode the current region. */ 4631 /* Confirm that VAL can surely encode the current region. */
4649 val = call3 (Vselect_safe_coding_system_function, start, end, val); 4632 val = call3 (Vselect_safe_coding_system_function, start, end, val);
4650 4633
4651 setup_coding_system (Fcheck_coding_system (val), coding); 4634 /* If the decided coding-system doesn't specify end-of-line
4652 if (coding->eol_type == CODING_EOL_UNDECIDED 4635 format, we use that of
4653 && !using_default_coding) 4636 `default-buffer-file-coding-system'. */
4654 { 4637 if (! using_default_coding)
4655 if (! EQ (default_buffer_file_coding.symbol, 4638 val = (coding_inherit_eol_type
4656 buffer_defaults.buffer_file_coding_system)) 4639 (val, buffer_defaults.buffer_file_coding_system));
4657 setup_coding_system (buffer_defaults.buffer_file_coding_system, 4640
4658 &default_buffer_file_coding); 4641 /* If we decide not to encode text, use `raw-text' or one of its
4659 if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED) 4642 subsidiaries. */
4660 {
4661 Lisp_Object subsidiaries;
4662
4663 coding->eol_type = default_buffer_file_coding.eol_type;
4664 subsidiaries = Fget (coding->symbol, Qeol_type);
4665 if (VECTORP (subsidiaries)
4666 && XVECTOR (subsidiaries)->size == 3)
4667 coding->symbol
4668 = XVECTOR (subsidiaries)->contents[coding->eol_type];
4669 }
4670 }
4671
4672 if (force_raw_text) 4643 if (force_raw_text)
4673 setup_raw_text_coding_system (coding); 4644 val = raw_text_coding_system (val);
4674 goto done_setup_coding;
4675 } 4645 }
4676 4646
4677 setup_coding_system (Fcheck_coding_system (val), coding); 4647 setup_coding_system (Fcheck_coding_system (val), coding);
4678 4648
4679 done_setup_coding:
4680 if (!STRINGP (start) && !NILP (current_buffer->selective_display)) 4649 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4681 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; 4650 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
4682 } 4651 }
4683 4652
4684 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7, 4653 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
4814 We used to make this choice before calling build_annotations, but that 4783 We used to make this choice before calling build_annotations, but that
4815 leads to problems when a write-annotate-function takes care of 4784 leads to problems when a write-annotate-function takes care of
4816 unsavable chars (as was the case with X-Symbol). */ 4785 unsavable chars (as was the case with X-Symbol). */
4817 choose_write_coding_system (start, end, filename, 4786 choose_write_coding_system (start, end, filename,
4818 append, visit, lockname, &coding); 4787 append, visit, lockname, &coding);
4819 Vlast_coding_system_used = coding.symbol; 4788 Vlast_coding_system_used = CODING_ID_NAME (coding.id);
4820 4789
4821 given_buffer = current_buffer; 4790 given_buffer = current_buffer;
4822 annotations = build_annotations_2 (start, end,
4823 coding.pre_write_conversion, annotations);
4824 if (current_buffer != given_buffer) 4791 if (current_buffer != given_buffer)
4825 { 4792 {
4826 XSETFASTINT (start, BEGV); 4793 XSETFASTINT (start, BEGV);
4827 XSETFASTINT (end, ZV); 4794 XSETFASTINT (end, ZV);
4828 } 4795 }
4961 * Yech! 4928 * Yech!
4962 */ 4929 */
4963 if (GPT > BEG && GPT_ADDR[-1] != '\n') 4930 if (GPT > BEG && GPT_ADDR[-1] != '\n')
4964 move_gap (find_next_newline (GPT, 1)); 4931 move_gap (find_next_newline (GPT, 1));
4965 #else 4932 #else
4933 #if 0
4934 /* The new encoding routine doesn't require the following. */
4935
4966 /* Whether VMS or not, we must move the gap to the next of newline 4936 /* Whether VMS or not, we must move the gap to the next of newline
4967 when we must put designation sequences at beginning of line. */ 4937 when we must put designation sequences at beginning of line. */
4968 if (INTEGERP (start) 4938 if (INTEGERP (start)
4969 && coding.type == coding_type_iso2022 4939 && coding.type == coding_type_iso2022
4970 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL 4940 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
4974 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0); 4944 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0);
4975 move_gap_both (PT, PT_BYTE); 4945 move_gap_both (PT, PT_BYTE);
4976 SET_PT_BOTH (opoint, opoint_byte); 4946 SET_PT_BOTH (opoint, opoint_byte);
4977 } 4947 }
4978 #endif 4948 #endif
4949 #endif
4979 4950
4980 failure = 0; 4951 failure = 0;
4981 immediate_quit = 1; 4952 immediate_quit = 1;
4982 4953
4983 if (STRINGP (start)) 4954 if (STRINGP (start))
4986 &annotations, &coding); 4957 &annotations, &coding);
4987 save_errno = errno; 4958 save_errno = errno;
4988 } 4959 }
4989 else if (XINT (start) != XINT (end)) 4960 else if (XINT (start) != XINT (end))
4990 { 4961 {
4991 tem = CHAR_TO_BYTE (XINT (start)); 4962 failure = 0 > a_write (desc, Qnil,
4992 4963 XINT (start), XINT (end) - XINT (start),
4993 if (XINT (start) < GPT) 4964 &annotations, &coding);
4994 { 4965 save_errno = errno;
4995 failure = 0 > a_write (desc, Qnil, XINT (start),
4996 min (GPT, XINT (end)) - XINT (start),
4997 &annotations, &coding);
4998 save_errno = errno;
4999 }
5000
5001 if (XINT (end) > GPT && !failure)
5002 {
5003 tem = max (XINT (start), GPT);
5004 failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem,
5005 &annotations, &coding);
5006 save_errno = errno;
5007 }
5008 } 4966 }
5009 else 4967 else
5010 { 4968 {
5011 /* If file was empty, still need to write the annotations */ 4969 /* If file was empty, still need to write the annotations */
5012 coding.mode |= CODING_MODE_LAST_BLOCK; 4970 coding.mode |= CODING_MODE_LAST_BLOCK;
5018 && !(coding.mode & CODING_MODE_LAST_BLOCK) 4976 && !(coding.mode & CODING_MODE_LAST_BLOCK)
5019 && ! failure) 4977 && ! failure)
5020 { 4978 {
5021 /* We have to flush out a data. */ 4979 /* We have to flush out a data. */
5022 coding.mode |= CODING_MODE_LAST_BLOCK; 4980 coding.mode |= CODING_MODE_LAST_BLOCK;
5023 failure = 0 > e_write (desc, Qnil, 0, 0, &coding); 4981 failure = 0 > e_write (desc, Qnil, 1, 1, &coding);
5024 save_errno = errno; 4982 save_errno = errno;
5025 } 4983 }
5026 4984
5027 immediate_quit = 0; 4985 immediate_quit = 0;
5028 4986
5194 5152
5195 UNGCPRO; 5153 UNGCPRO;
5196 return annotations; 5154 return annotations;
5197 } 5155 }
5198 5156
5199 static Lisp_Object
5200 build_annotations_2 (start, end, pre_write_conversion, annotations)
5201 Lisp_Object start, end, pre_write_conversion, annotations;
5202 {
5203 struct gcpro gcpro1;
5204 Lisp_Object res;
5205
5206 GCPRO1 (annotations);
5207 /* At last, do the same for the function PRE_WRITE_CONVERSION
5208 implied by the current coding-system. */
5209 if (!NILP (pre_write_conversion))
5210 {
5211 struct buffer *given_buffer = current_buffer;
5212 Vwrite_region_annotations_so_far = annotations;
5213 res = call2 (pre_write_conversion, start, end);
5214 Flength (res);
5215 annotations = (current_buffer != given_buffer
5216 ? res
5217 : merge (annotations, res, Qcar_less_than_car));
5218 }
5219
5220 UNGCPRO;
5221 return annotations;
5222 }
5223 5157
5224 /* Write to descriptor DESC the NCHARS chars starting at POS of STRING. 5158 /* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
5225 If STRING is nil, POS is the character position in the current buffer. 5159 If STRING is nil, POS is the character position in the current buffer.
5226 Intersperse with them the annotations from *ANNOT 5160 Intersperse with them the annotations from *ANNOT
5227 which fall within the range of POS to POS + NCHARS, 5161 which fall within the range of POS to POS + NCHARS,
5289 int desc; 5223 int desc;
5290 Lisp_Object string; 5224 Lisp_Object string;
5291 int start, end; 5225 int start, end;
5292 struct coding_system *coding; 5226 struct coding_system *coding;
5293 { 5227 {
5294 register char *addr;
5295 register int nbytes;
5296 char buf[WRITE_BUF_SIZE];
5297 int return_val = 0; 5228 int return_val = 0;
5298 5229
5299 if (start >= end)
5300 coding->composing = COMPOSITION_DISABLED;
5301 if (coding->composing != COMPOSITION_DISABLED)
5302 coding_save_composition (coding, start, end, string);
5303
5304 if (STRINGP (string)) 5230 if (STRINGP (string))
5305 { 5231 {
5306 addr = XSTRING (string)->data; 5232 start = 0;
5307 nbytes = STRING_BYTES (XSTRING (string)); 5233 end = XSTRING (string)->size;
5308 coding->src_multibyte = STRING_MULTIBYTE (string); 5234 }
5309 } 5235
5310 else if (start < end) 5236 coding->mode |= CODING_MODE_FIXED_DESTINATION;
5311 { 5237 if (! NILP (current_buffer->selective_display))
5312 /* It is assured that the gap is not in the range START and END-1. */ 5238 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
5313 addr = CHAR_POS_ADDR (start);
5314 nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start);
5315 coding->src_multibyte
5316 = !NILP (current_buffer->enable_multibyte_characters);
5317 }
5318 else
5319 {
5320 addr = "";
5321 nbytes = 0;
5322 coding->src_multibyte = 1;
5323 }
5324 5239
5325 /* We used to have a code for handling selective display here. But, 5240 /* We used to have a code for handling selective display here. But,
5326 now it is handled within encode_coding. */ 5241 now it is handled within encode_coding. */
5327 while (1) 5242 do
5328 { 5243 {
5329 int result; 5244 if (STRINGP (string))
5330 5245 encode_coding_object (coding, string,
5331 result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE); 5246 start, string_char_to_byte (string, start),
5247 end, string_char_to_byte (string, end), Qt);
5248 else
5249 encode_coding_object (coding, Fcurrent_buffer (),
5250 start, CHAR_TO_BYTE (start),
5251 end, CHAR_TO_BYTE (end), Qt);
5252
5332 if (coding->produced > 0) 5253 if (coding->produced > 0)
5333 { 5254 {
5334 coding->produced -= emacs_write (desc, buf, coding->produced); 5255 coding->produced -= emacs_write (desc,
5256 XSTRING (coding->dst_object)->data,
5257 coding->produced);
5335 if (coding->produced) 5258 if (coding->produced)
5336 { 5259 {
5337 return_val = -1; 5260 return_val = -1;
5338 break; 5261 break;
5339 } 5262 }
5340 } 5263 }
5341 nbytes -= coding->consumed;
5342 addr += coding->consumed;
5343 if (result == CODING_FINISH_INSUFFICIENT_SRC
5344 && nbytes > 0)
5345 {
5346 /* The source text ends by an incomplete multibyte form.
5347 There's no way other than write it out as is. */
5348 nbytes -= emacs_write (desc, addr, nbytes);
5349 if (nbytes)
5350 {
5351 return_val = -1;
5352 break;
5353 }
5354 }
5355 if (nbytes <= 0)
5356 break;
5357 start += coding->consumed_char; 5264 start += coding->consumed_char;
5358 if (coding->cmp_data) 5265 }
5359 coding_adjust_composition_offset (coding, start); 5266 while (start < end);
5360 }
5361
5362 if (coding->cmp_data)
5363 coding_free_composition_data (coding);
5364 5267
5365 return return_val; 5268 return return_val;
5366 } 5269 }
5367 5270
5368 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, 5271 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,