75 |
#include "lisp.h" |
#include "lisp.h" |
76 |
#include "intervals.h" |
#include "intervals.h" |
77 |
#include "buffer.h" |
#include "buffer.h" |
78 |
#include "charset.h" |
#include "character.h" |
79 |
#include "coding.h" |
#include "coding.h" |
80 |
#include "window.h" |
#include "window.h" |
81 |
|
|
295 |
Fset_marker (location, Qnil, Qnil); |
Fset_marker (location, Qnil, Qnil); |
296 |
return Qnil; |
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); |
307 |
|
return Qnil; |
308 |
|
} |
309 |
|
|
310 |
Lisp_Object Qexpand_file_name; |
Lisp_Object Qexpand_file_name; |
311 |
Lisp_Object Qsubstitute_in_file_name; |
Lisp_Object Qsubstitute_in_file_name; |
3643 |
unsigned char buffer[1 << 14]; |
unsigned char buffer[1 << 14]; |
3644 |
int replace_handled = 0; |
int replace_handled = 0; |
3645 |
int set_coding_system = 0; |
int set_coding_system = 0; |
3646 |
int coding_system_decided = 0; |
Lisp_Object coding_system; |
3647 |
int read_quit = 0; |
int read_quit = 0; |
3648 |
|
|
3649 |
if (current_buffer->base_buffer && ! NILP (visit)) |
if (current_buffer->base_buffer && ! NILP (visit)) |
3661 |
CHECK_STRING (filename); |
CHECK_STRING (filename); |
3662 |
filename = Fexpand_file_name (filename, Qnil); |
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; |
3667 |
|
|
3668 |
/* If the file name has special constructs in it, |
/* If the file name has special constructs in it, |
3669 |
call the corresponding file handler. */ |
call the corresponding file handler. */ |
3670 |
handler = Ffind_file_name_handler (filename, Qinsert_file_contents); |
handler = Ffind_file_name_handler (filename, Qinsert_file_contents); |
3788 |
} |
} |
3789 |
|
|
3790 |
if (EQ (Vcoding_system_for_read, Qauto_save_coding)) |
if (EQ (Vcoding_system_for_read, Qauto_save_coding)) |
3791 |
{ |
coding_system = Qutf_8_emacs; |
|
/* We use emacs-mule for auto saving... */ |
|
|
setup_coding_system (Qemacs_mule, &coding); |
|
|
/* ... but with the special flag to indicate to read in a |
|
|
multibyte sequence for eight-bit-control char as is. */ |
|
|
coding.flags = 1; |
|
|
coding.src_multibyte = 0; |
|
|
coding.dst_multibyte |
|
|
= !NILP (current_buffer->enable_multibyte_characters); |
|
|
coding.eol_type = CODING_EOL_LF; |
|
|
coding_system_decided = 1; |
|
|
} |
|
3792 |
else if (BEG < Z) |
else if (BEG < Z) |
3793 |
{ |
{ |
3794 |
/* Decide the coding system to use for reading the file now |
/* Decide the coding system to use for reading the file now |
3795 |
because we can't use an optimized method for handling |
because we can't use an optimized method for handling |
3796 |
`coding:' tag if the current buffer is not empty. */ |
`coding:' tag if the current buffer is not empty. */ |
|
Lisp_Object val; |
|
|
val = Qnil; |
|
|
|
|
3797 |
if (!NILP (Vcoding_system_for_read)) |
if (!NILP (Vcoding_system_for_read)) |
3798 |
val = Vcoding_system_for_read; |
coding_system = Vcoding_system_for_read; |
3799 |
else if (! NILP (replace)) |
else if (! NILP (replace)) |
3800 |
/* In REPLACE mode, we can use the same coding system |
/* In REPLACE mode, we can use the same coding system |
3801 |
that was used to visit the file. */ |
that was used to visit the file. */ |
3802 |
val = current_buffer->buffer_file_coding_system; |
coding_system = current_buffer->buffer_file_coding_system; |
3803 |
else |
else |
3804 |
{ |
{ |
3805 |
/* Don't try looking inside a file for a coding system |
/* Don't try looking inside a file for a coding system |
3855 |
|
|
3856 |
insert_1_both (read_buf, nread, nread, 0, 0, 0); |
insert_1_both (read_buf, nread, nread, 0, 0, 0); |
3857 |
TEMP_SET_PT_BOTH (BEG, BEG_BYTE); |
TEMP_SET_PT_BOTH (BEG, BEG_BYTE); |
3858 |
val = call2 (Vset_auto_coding_function, |
coding_system = call2 (Vset_auto_coding_function, |
3859 |
filename, make_number (nread)); |
filename, make_number (nread)); |
3860 |
set_buffer_internal (prev); |
set_buffer_internal (prev); |
3861 |
|
|
3862 |
/* Discard the unwind protect for recovering the |
/* Discard the unwind protect for recovering the |
3870 |
} |
} |
3871 |
} |
} |
3872 |
|
|
3873 |
if (NILP (val)) |
if (NILP (coding_system)) |
3874 |
{ |
{ |
3875 |
/* If we have not yet decided a coding system, check |
/* If we have not yet decided a coding system, check |
3876 |
file-coding-system-alist. */ |
file-coding-system-alist. */ |
3877 |
Lisp_Object args[6], coding_systems; |
Lisp_Object args[6]; |
3878 |
|
|
3879 |
args[0] = Qinsert_file_contents, args[1] = orig_filename; |
args[0] = Qinsert_file_contents, args[1] = orig_filename; |
3880 |
args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace; |
args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace; |
3881 |
coding_systems = Ffind_operation_coding_system (6, args); |
coding_system = Ffind_operation_coding_system (6, args); |
3882 |
if (CONSP (coding_systems)) |
if (CONSP (coding_system)) |
3883 |
val = XCAR (coding_systems); |
coding_system = XCAR (coding_system); |
3884 |
} |
} |
3885 |
} |
} |
3886 |
|
|
3887 |
setup_coding_system (Fcheck_coding_system (val), &coding); |
if (NILP (coding_system)) |
3888 |
/* Ensure we set Vlast_coding_system_used. */ |
coding_system = Qundecided; |
3889 |
set_coding_system = 1; |
else |
3890 |
|
CHECK_CODING_SYSTEM (coding_system); |
3891 |
|
|
3892 |
if (NILP (current_buffer->enable_multibyte_characters) |
if (NILP (current_buffer->enable_multibyte_characters)) |
|
&& ! NILP (val)) |
|
3893 |
/* We must suppress all character code conversion except for |
/* We must suppress all character code conversion except for |
3894 |
end-of-line conversion. */ |
end-of-line conversion. */ |
3895 |
setup_raw_text_coding_system (&coding); |
coding_system = raw_text_coding_system (coding_system); |
3896 |
|
|
3897 |
coding.src_multibyte = 0; |
setup_coding_system (coding_system, &coding); |
3898 |
coding.dst_multibyte |
/* Ensure we set Vlast_coding_system_used. */ |
3899 |
= !NILP (current_buffer->enable_multibyte_characters); |
set_coding_system = 1; |
|
coding_system_decided = 1; |
|
3900 |
} |
} |
3901 |
|
|
3902 |
/* If requested, replace the accessible part of the buffer |
/* If requested, replace the accessible part of the buffer |
3915 |
and let the following if-statement handle the replace job. */ |
and let the following if-statement handle the replace job. */ |
3916 |
if (!NILP (replace) |
if (!NILP (replace) |
3917 |
&& BEGV < ZV |
&& BEGV < ZV |
3918 |
&& !(coding.common_flags & CODING_REQUIRE_DECODING_MASK)) |
&& (NILP (coding_system) |
3919 |
|
|| ! CODING_REQUIRE_DECODING (&coding))) |
3920 |
{ |
{ |
3921 |
/* same_at_start and same_at_end count bytes, |
/* same_at_start and same_at_end count bytes, |
3922 |
because file access counts bytes |
because file access counts bytes |
3951 |
else if (nread == 0) |
else if (nread == 0) |
3952 |
break; |
break; |
3953 |
|
|
3954 |
if (coding.type == coding_type_undecided) |
if (CODING_REQUIRE_DETECTION (&coding)) |
|
detect_coding (&coding, buffer, nread); |
|
|
if (coding.common_flags & CODING_REQUIRE_DECODING_MASK) |
|
|
/* We found that the file should be decoded somehow. |
|
|
Let's give up here. */ |
|
3955 |
{ |
{ |
3956 |
giveup_match_end = 1; |
coding_system = detect_coding_system (buffer, nread, 1, 0, |
3957 |
break; |
coding_system); |
3958 |
|
setup_coding_system (coding_system, &coding); |
3959 |
} |
} |
3960 |
|
|
3961 |
if (coding.eol_type == CODING_EOL_UNDECIDED) |
if (CODING_REQUIRE_DECODING (&coding)) |
3962 |
detect_eol (&coding, buffer, nread); |
/* We found that the file should be decoded somehow. |
|
if (coding.eol_type != CODING_EOL_UNDECIDED |
|
|
&& coding.eol_type != CODING_EOL_LF) |
|
|
/* We found that the format of eol should be decoded. |
|
3963 |
Let's give up here. */ |
Let's give up here. */ |
3964 |
{ |
{ |
3965 |
giveup_match_end = 1; |
giveup_match_end = 1; |
4104 |
{ |
{ |
4105 |
int same_at_start = BEGV_BYTE; |
int same_at_start = BEGV_BYTE; |
4106 |
int same_at_end = ZV_BYTE; |
int same_at_end = ZV_BYTE; |
4107 |
|
int same_at_start_charpos; |
4108 |
|
int inserted_chars; |
4109 |
int overlap; |
int overlap; |
4110 |
int bufpos; |
int bufpos; |
4111 |
/* Make sure that the gap is large enough. */ |
unsigned char *decoded; |
|
int bufsize = 2 * st.st_size; |
|
|
unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize); |
|
4112 |
int temp; |
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); |
4120 |
|
|
4121 |
/* First read the whole file, performing code conversion into |
/* First read the whole file, performing code conversion into |
4122 |
CONVERSION_BUFFER. */ |
CONVERSION_BUFFER. */ |
4123 |
|
|
4124 |
if (lseek (fd, XINT (beg), 0) < 0) |
if (lseek (fd, XINT (beg), 0) < 0) |
4125 |
{ |
report_file_error ("Setting file position", |
4126 |
xfree (conversion_buffer); |
Fcons (orig_filename, Qnil)); |
|
report_file_error ("Setting file position", |
|
|
Fcons (orig_filename, Qnil)); |
|
|
} |
|
4127 |
|
|
4128 |
total = st.st_size; /* Total bytes in the file. */ |
total = st.st_size; /* Total bytes in the file. */ |
4129 |
how_much = 0; /* Bytes read from file so far. */ |
how_much = 0; /* Bytes read from file so far. */ |
4130 |
inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ |
inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ |
4131 |
unprocessed = 0; /* Bytes not processed in previous loop. */ |
unprocessed = 0; /* Bytes not processed in previous loop. */ |
4132 |
|
|
4133 |
|
GCPRO1 (conversion_buffer); |
4134 |
while (how_much < total) |
while (how_much < total) |
4135 |
{ |
{ |
4136 |
|
/* We read one bunch by one (READ_BUF_SIZE bytes) to allow |
4137 |
|
quitting while reading a huge while. */ |
4138 |
/* try is reserved in some compilers (Microsoft C) */ |
/* try is reserved in some compilers (Microsoft C) */ |
4139 |
int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); |
int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); |
|
unsigned char *destination = read_buf + unprocessed; |
|
4140 |
int this; |
int this; |
4141 |
|
|
4142 |
/* Allow quitting out of the actual I/O. */ |
/* Allow quitting out of the actual I/O. */ |
4143 |
immediate_quit = 1; |
immediate_quit = 1; |
4144 |
QUIT; |
QUIT; |
4145 |
this = emacs_read (fd, destination, trytry); |
this = emacs_read (fd, read_buf + unprocessed, trytry); |
4146 |
immediate_quit = 0; |
immediate_quit = 0; |
4147 |
|
|
4148 |
if (this < 0 || this + unprocessed == 0) |
if (this <= 0) |
4149 |
{ |
{ |
4150 |
how_much = this; |
if (this < 0) |
4151 |
|
how_much = this; |
4152 |
break; |
break; |
4153 |
} |
} |
4154 |
|
|
4155 |
how_much += this; |
how_much += this; |
4156 |
|
|
4157 |
if (CODING_MAY_REQUIRE_DECODING (&coding)) |
BUF_SET_PT (XBUFFER (conversion_buffer), |
4158 |
{ |
BUF_Z (XBUFFER (conversion_buffer))); |
4159 |
int require, result; |
decode_coding_c_string (&coding, read_buf, unprocessed + this, |
4160 |
|
conversion_buffer); |
4161 |
this += unprocessed; |
unprocessed = coding.carryover_bytes; |
4162 |
|
if (coding.carryover_bytes > 0) |
4163 |
/* If we are using more space than estimated, |
bcopy (coding.carryover, read_buf, unprocessed); |
|
make CONVERSION_BUFFER bigger. */ |
|
|
require = decoding_buffer_size (&coding, this); |
|
|
if (inserted + require + 2 * (total - how_much) > bufsize) |
|
|
{ |
|
|
bufsize = inserted + require + 2 * (total - how_much); |
|
|
conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize); |
|
|
} |
|
|
|
|
|
/* Convert this batch with results in CONVERSION_BUFFER. */ |
|
|
if (how_much >= total) /* This is the last block. */ |
|
|
coding.mode |= CODING_MODE_LAST_BLOCK; |
|
|
if (coding.composing != COMPOSITION_DISABLED) |
|
|
coding_allocate_composition_data (&coding, BEGV); |
|
|
result = decode_coding (&coding, read_buf, |
|
|
conversion_buffer + inserted, |
|
|
this, bufsize - inserted); |
|
|
|
|
|
/* Save for next iteration whatever we didn't convert. */ |
|
|
unprocessed = this - coding.consumed; |
|
|
bcopy (read_buf + coding.consumed, read_buf, unprocessed); |
|
|
if (!NILP (current_buffer->enable_multibyte_characters)) |
|
|
this = coding.produced; |
|
|
else |
|
|
this = str_as_unibyte (conversion_buffer + inserted, |
|
|
coding.produced); |
|
|
} |
|
|
|
|
|
inserted += this; |
|
4164 |
} |
} |
4165 |
|
UNGCPRO; |
4166 |
|
emacs_close (fd); |
4167 |
|
|
4168 |
/* At this point, INSERTED is how many characters (i.e. bytes) |
/* At this point, HOW_MUCH should equal TOTAL, or should be <= 0 |
4169 |
are present in CONVERSION_BUFFER. |
if we couldn't read the file. */ |
|
HOW_MUCH should equal TOTAL, |
|
|
or should be <= 0 if we couldn't read the file. */ |
|
4170 |
|
|
4171 |
if (how_much < 0) |
if (how_much < 0) |
4172 |
{ |
{ |
|
xfree (conversion_buffer); |
|
|
|
|
4173 |
if (how_much == -1) |
if (how_much == -1) |
4174 |
error ("IO error reading %s: %s", |
error ("IO error reading %s: %s", |
4175 |
SDATA (orig_filename), emacs_strerror (errno)); |
SDATA (orig_filename), emacs_strerror (errno)); |
4177 |
error ("maximum buffer size exceeded"); |
error ("maximum buffer size exceeded"); |
4178 |
} |
} |
4179 |
|
|
4180 |
/* Compare the beginning of the converted file |
if (unprocessed > 0) |
4181 |
with the buffer text. */ |
{ |
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. */ |
4194 |
|
|
4195 |
bufpos = 0; |
bufpos = 0; |
4196 |
while (bufpos < inserted && same_at_start < same_at_end |
while (bufpos < inserted && same_at_start < same_at_end |
4197 |
&& FETCH_BYTE (same_at_start) == conversion_buffer[bufpos]) |
&& FETCH_BYTE (same_at_start) == decoded[bufpos]) |
4198 |
same_at_start++, bufpos++; |
same_at_start++, bufpos++; |
4199 |
|
|
4200 |
/* If the file matches the buffer completely, |
/* If the file matches the head of buffer completely, |
4201 |
there's no need to replace anything. */ |
there's no need to replace anything. */ |
4202 |
|
|
4203 |
if (bufpos == inserted) |
if (bufpos == inserted) |
4204 |
{ |
{ |
|
xfree (conversion_buffer); |
|
|
emacs_close (fd); |
|
4205 |
specpdl_ptr--; |
specpdl_ptr--; |
4206 |
/* Truncate the buffer to the size of the file. */ |
/* Truncate the buffer to the size of the file. */ |
4207 |
del_range_byte (same_at_start, same_at_end, 0); |
del_range_byte (same_at_start, same_at_end, 0); |
4209 |
goto handled; |
goto handled; |
4210 |
} |
} |
4211 |
|
|
4212 |
/* Extend the start of non-matching text area to multibyte |
/* Extend the start of non-matching text area to the previous |
4213 |
character boundary. */ |
multibyte character boundary. */ |
4214 |
if (! NILP (current_buffer->enable_multibyte_characters)) |
if (! NILP (current_buffer->enable_multibyte_characters)) |
4215 |
while (same_at_start > BEGV_BYTE |
while (same_at_start > BEGV_BYTE |
4216 |
&& ! CHAR_HEAD_P (FETCH_BYTE (same_at_start))) |
&& ! CHAR_HEAD_P (FETCH_BYTE (same_at_start))) |
4223 |
/* Compare with same_at_start to avoid counting some buffer text |
/* Compare with same_at_start to avoid counting some buffer text |
4224 |
as matching both at the file's beginning and at the end. */ |
as matching both at the file's beginning and at the end. */ |
4225 |
while (bufpos > 0 && same_at_end > same_at_start |
while (bufpos > 0 && same_at_end > same_at_start |
4226 |
&& FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1]) |
&& FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1]) |
4227 |
same_at_end--, bufpos--; |
same_at_end--, bufpos--; |
4228 |
|
|
4229 |
/* Extend the end of non-matching text area to multibyte |
/* Extend the end of non-matching text area to the next |
4230 |
character boundary. */ |
multibyte character boundary. */ |
4231 |
if (! NILP (current_buffer->enable_multibyte_characters)) |
if (! NILP (current_buffer->enable_multibyte_characters)) |
4232 |
while (same_at_end < ZV_BYTE |
while (same_at_end < ZV_BYTE |
4233 |
&& ! CHAR_HEAD_P (FETCH_BYTE (same_at_end))) |
&& ! CHAR_HEAD_P (FETCH_BYTE (same_at_end))) |
4245 |
|
|
4246 |
/* Replace the chars that we need to replace, |
/* Replace the chars that we need to replace, |
4247 |
and update INSERTED to equal the number of bytes |
and update INSERTED to equal the number of bytes |
4248 |
we are taking from the file. */ |
we are taking from the decoded string. */ |
4249 |
inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); |
inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); |
4250 |
|
|
4251 |
if (same_at_end != same_at_start) |
if (same_at_end != same_at_start) |
4260 |
} |
} |
4261 |
/* Insert from the file at the proper position. */ |
/* Insert from the file at the proper position. */ |
4262 |
SET_PT_BOTH (temp, same_at_start); |
SET_PT_BOTH (temp, same_at_start); |
4263 |
insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted, |
same_at_start_charpos |
4264 |
0, 0, 0); |
= buf_bytepos_to_charpos (XBUFFER (conversion_buffer), |
4265 |
if (coding.cmp_data && coding.cmp_data->used) |
same_at_start); |
4266 |
coding_restore_composition (&coding, Fcurrent_buffer ()); |
inserted_chars |
4267 |
coding_free_composition_data (&coding); |
= (buf_bytepos_to_charpos (XBUFFER (conversion_buffer), |
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); |
4272 |
/* Set `inserted' to the number of inserted characters. */ |
/* Set `inserted' to the number of inserted characters. */ |
4273 |
inserted = PT - temp; |
inserted = PT - temp; |
4274 |
|
|
4275 |
xfree (conversion_buffer); |
unbind_to (this_count, Qnil); |
|
emacs_close (fd); |
|
|
specpdl_ptr--; |
|
4276 |
|
|
4277 |
goto handled; |
goto handled; |
4278 |
} |
} |
4316 |
inserted = 0; |
inserted = 0; |
4317 |
|
|
4318 |
/* Here, we don't do code conversion in the loop. It is done by |
/* Here, we don't do code conversion in the loop. It is done by |
4319 |
code_convert_region after all data are read into the buffer. */ |
decode_coding_gap after all data are read into the buffer. */ |
4320 |
{ |
{ |
4321 |
int gap_size = GAP_SIZE; |
int gap_size = GAP_SIZE; |
4322 |
|
|
4407 |
|
|
4408 |
notfound: |
notfound: |
4409 |
|
|
4410 |
if (! coding_system_decided) |
if (NILP (coding_system)) |
4411 |
{ |
{ |
4412 |
/* The coding system is not yet decided. Decide it by an |
/* The coding system is not yet decided. Decide it by an |
4413 |
optimized method for handling `coding:' tag. |
optimized method for handling `coding:' tag. |
4414 |
|
|
4415 |
Note that we can get here only if the buffer was empty |
Note that we can get here only if the buffer was empty |
4416 |
before the insertion. */ |
before the insertion. */ |
|
Lisp_Object val; |
|
|
val = Qnil; |
|
4417 |
|
|
4418 |
if (!NILP (Vcoding_system_for_read)) |
if (!NILP (Vcoding_system_for_read)) |
4419 |
val = Vcoding_system_for_read; |
coding_system = Vcoding_system_for_read; |
4420 |
else |
else |
4421 |
{ |
{ |
4422 |
/* Since we are sure that the current buffer was empty |
/* Since we are sure that the current buffer was empty |
4437 |
|
|
4438 |
if (inserted > 0 && ! NILP (Vset_auto_coding_function)) |
if (inserted > 0 && ! NILP (Vset_auto_coding_function)) |
4439 |
{ |
{ |
4440 |
val = call2 (Vset_auto_coding_function, |
coding_system = call2 (Vset_auto_coding_function, |
4441 |
filename, make_number (inserted)); |
filename, make_number (inserted)); |
4442 |
} |
} |
4443 |
|
|
4444 |
if (NILP (val)) |
if (NILP (coding_system)) |
4445 |
{ |
{ |
4446 |
/* If the coding system is not yet decided, check |
/* If the coding system is not yet decided, check |
4447 |
file-coding-system-alist. */ |
file-coding-system-alist. */ |
4448 |
Lisp_Object args[6], coding_systems; |
Lisp_Object args[6]; |
4449 |
|
|
4450 |
args[0] = Qinsert_file_contents, args[1] = orig_filename; |
args[0] = Qinsert_file_contents, args[1] = orig_filename; |
4451 |
args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil; |
args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil; |
4452 |
coding_systems = Ffind_operation_coding_system (6, args); |
coding_system = Ffind_operation_coding_system (6, args); |
4453 |
if (CONSP (coding_systems)) |
if (CONSP (coding_system)) |
4454 |
val = XCAR (coding_systems); |
coding_system = XCAR (coding_system); |
4455 |
} |
} |
4456 |
|
|
4457 |
unbind_to (count, Qnil); |
unbind_to (count, Qnil); |
4458 |
inserted = Z_BYTE - BEG_BYTE; |
inserted = Z_BYTE - BEG_BYTE; |
4459 |
} |
} |
4460 |
|
|
4461 |
/* The following kludgy code is to avoid some compiler bug. |
if (NILP (coding_system)) |
4462 |
We can't simply do |
coding_system = Qundecided; |
4463 |
setup_coding_system (val, &coding); |
else |
4464 |
on some system. */ |
CHECK_CODING_SYSTEM (coding_system); |
|
{ |
|
|
struct coding_system temp_coding; |
|
|
setup_coding_system (val, &temp_coding); |
|
|
bcopy (&temp_coding, &coding, sizeof coding); |
|
|
} |
|
|
/* Ensure we set Vlast_coding_system_used. */ |
|
|
set_coding_system = 1; |
|
4465 |
|
|
4466 |
if (NILP (current_buffer->enable_multibyte_characters) |
if (NILP (current_buffer->enable_multibyte_characters)) |
|
&& ! NILP (val)) |
|
4467 |
/* We must suppress all character code conversion except for |
/* We must suppress all character code conversion except for |
4468 |
end-of-line conversion. */ |
end-of-line conversion. */ |
4469 |
setup_raw_text_coding_system (&coding); |
coding_system = raw_text_coding_system (coding_system); |
4470 |
coding.src_multibyte = 0; |
setup_coding_system (coding_system, &coding); |
4471 |
coding.dst_multibyte |
/* Ensure we set Vlast_coding_system_used. */ |
4472 |
= !NILP (current_buffer->enable_multibyte_characters); |
set_coding_system = 1; |
4473 |
} |
} |
4474 |
|
|
4475 |
if (!NILP (visit) |
if (!NILP (visit)) |
|
/* Can't do this if part of the buffer might be preserved. */ |
|
|
&& NILP (replace) |
|
|
&& (coding.type == coding_type_no_conversion |
|
|
|| coding.type == coding_type_raw_text)) |
|
4476 |
{ |
{ |
4477 |
/* Visiting a file with these coding system makes the buffer |
/* When we visit a file by raw-text, we change the buffer to |
4478 |
unibyte. */ |
unibyte. If we have not yet decided how to decode a text, |
4479 |
current_buffer->enable_multibyte_characters = Qnil; |
decide it at first by detecting the file's encoding. */ |
4480 |
coding.dst_multibyte = 0; |
if (CODING_REQUIRE_DETECTION (&coding)) |
4481 |
} |
{ |
4482 |
|
coding_system = detect_coding_system (PT_ADDR, inserted, 1, 0, |
4483 |
if (inserted > 0 || coding.type == coding_type_ccl) |
coding_system); |
4484 |
|
setup_coding_system (coding_system, &coding); |
4485 |
|
} |
4486 |
|
|
4487 |
|
if (CODING_FOR_UNIBYTE (&coding) |
4488 |
|
/* Can't do this if part of the buffer might be preserved. */ |
4489 |
|
&& NILP (replace)) |
4490 |
|
/* Visiting a file with these coding system makes the buffer |
4491 |
|
unibyte. */ |
4492 |
|
current_buffer->enable_multibyte_characters = Qnil; |
4493 |
|
} |
4494 |
|
|
4495 |
|
coding.dst_multibyte = ! NILP (current_buffer->enable_multibyte_characters); |
4496 |
|
if ((CODING_REQUIRE_DETECTION (&coding) |
4497 |
|
|| CODING_REQUIRE_DECODING (&coding)) |
4498 |
|
&& (inserted > 0 || CODING_REQUIRE_FLUSHING (&coding))) |
4499 |
{ |
{ |
4500 |
if (CODING_MAY_REQUIRE_DECODING (&coding)) |
move_gap_both (PT, PT_BYTE); |
4501 |
{ |
GAP_SIZE += inserted; |
4502 |
code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, |
ZV_BYTE -= inserted; |
4503 |
&coding, 0, 0); |
Z_BYTE -= inserted; |
4504 |
inserted = coding.produced_char; |
ZV -= inserted; |
4505 |
} |
Z -= inserted; |
4506 |
else |
decode_coding_gap (&coding, inserted, inserted); |
4507 |
adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, |
inserted = coding.produced_char; |
4508 |
inserted); |
} |
4509 |
} |
else if (inserted > 0) |
4510 |
|
adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, |
4511 |
|
inserted); |
4512 |
|
|
4513 |
/* Now INSERTED is measured in characters. */ |
/* Now INSERTED is measured in characters. */ |
4514 |
|
|
4516 |
/* Use the conversion type to determine buffer-file-type |
/* Use the conversion type to determine buffer-file-type |
4517 |
(find-buffer-file-type is now used to help determine the |
(find-buffer-file-type is now used to help determine the |
4518 |
conversion). */ |
conversion). */ |
4519 |
if ((coding.eol_type == CODING_EOL_UNDECIDED |
if ((coding.eol_type == eol_type_undecided |
4520 |
|| coding.eol_type == CODING_EOL_LF) |
|| coding.eol_type == eol_type_lf) |
4521 |
&& ! CODING_REQUIRE_DECODING (&coding)) |
&& ! CODING_REQUIRE_DECODING (&coding)) |
4522 |
current_buffer->buffer_file_type = Qt; |
current_buffer->buffer_file_type = Qt; |
4523 |
else |
else |
4558 |
} |
} |
4559 |
|
|
4560 |
if (set_coding_system) |
if (set_coding_system) |
4561 |
Vlast_coding_system_used = coding.symbol; |
Vlast_coding_system_used = coding_system; |
4562 |
|
|
4563 |
if (! NILP (Ffboundp (Qafter_insert_file_set_coding))) |
if (! NILP (Ffboundp (Qafter_insert_file_set_coding))) |
4564 |
{ |
{ |
4636 |
} |
} |
4637 |
|
|
4638 |
static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object)); |
static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object)); |
|
static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object, |
|
|
Lisp_Object, Lisp_Object)); |
|
4639 |
|
|
4640 |
/* If build_annotations switched buffers, switch back to BUF. |
/* If build_annotations switched buffers, switch back to BUF. |
4641 |
Kill the temporary buffer that was selected in the meantime. |
Kill the temporary buffer that was selected in the meantime. |
4660 |
|
|
4661 |
/* Decide the coding-system to encode the data with. */ |
/* Decide the coding-system to encode the data with. */ |
4662 |
|
|
4663 |
void |
static Lisp_Object |
4664 |
choose_write_coding_system (start, end, filename, |
choose_write_coding_system (start, end, filename, |
4665 |
append, visit, lockname, coding) |
append, visit, lockname, coding) |
4666 |
Lisp_Object start, end, filename, append, visit, lockname; |
Lisp_Object start, end, filename, append, visit, lockname; |
4669 |
Lisp_Object val; |
Lisp_Object val; |
4670 |
|
|
4671 |
if (auto_saving) |
if (auto_saving) |
4672 |
{ |
val = Qutf_8_emacs; |
|
/* We use emacs-mule for auto saving... */ |
|
|
setup_coding_system (Qemacs_mule, coding); |
|
|
/* ... but with the special flag to indicate not to strip off |
|
|
leading code of eight-bit-control chars. */ |
|
|
coding->flags = 1; |
|
|
goto done_setup_coding; |
|
|
} |
|
4673 |
else if (!NILP (Vcoding_system_for_write)) |
else if (!NILP (Vcoding_system_for_write)) |
4674 |
{ |
{ |
4675 |
val = Vcoding_system_for_write; |
val = Vcoding_system_for_write; |
4716 |
val = XCDR (coding_systems); |
val = XCDR (coding_systems); |
4717 |
} |
} |
4718 |
|
|
4719 |
if (NILP (val) |
if (NILP (val)) |
|
&& !NILP (current_buffer->buffer_file_coding_system)) |
|
4720 |
{ |
{ |
4721 |
/* If we still have not decided a coding system, use the |
/* If we still have not decided a coding system, use the |
4722 |
default value of buffer-file-coding-system. */ |
default value of buffer-file-coding-system. */ |
4724 |
using_default_coding = 1; |
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; |
4735 |
|
} |
4736 |
|
|
4737 |
if (!force_raw_text |
if (!force_raw_text |
4738 |
&& !NILP (Ffboundp (Vselect_safe_coding_system_function))) |
&& !NILP (Ffboundp (Vselect_safe_coding_system_function))) |
4739 |
/* Confirm that VAL can surely encode the current region. */ |
/* Confirm that VAL can surely encode the current region. */ |
4740 |
val = call5 (Vselect_safe_coding_system_function, |
val = call5 (Vselect_safe_coding_system_function, |
4741 |
start, end, val, Qnil, filename); |
start, end, val, Qnil, filename); |
4742 |
|
|
4743 |
setup_coding_system (Fcheck_coding_system (val), coding); |
/* If the decided coding-system doesn't specify end-of-line |
4744 |
if (coding->eol_type == CODING_EOL_UNDECIDED |
format, we use that of |
4745 |
&& !using_default_coding) |
`default-buffer-file-coding-system'. */ |
4746 |
{ |
if (! using_default_coding |
4747 |
if (! EQ (default_buffer_file_coding.symbol, |
&& ! NILP (buffer_defaults.buffer_file_coding_system)) |
4748 |
buffer_defaults.buffer_file_coding_system)) |
val = (coding_inherit_eol_type |
4749 |
setup_coding_system (buffer_defaults.buffer_file_coding_system, |
(val, buffer_defaults.buffer_file_coding_system)); |
|
&default_buffer_file_coding); |
|
|
if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED) |
|
|
{ |
|
|
Lisp_Object subsidiaries; |
|
|
|
|
|
coding->eol_type = default_buffer_file_coding.eol_type; |
|
|
subsidiaries = Fget (coding->symbol, Qeol_type); |
|
|
if (VECTORP (subsidiaries) |
|
|
&& XVECTOR (subsidiaries)->size == 3) |
|
|
coding->symbol |
|
|
= XVECTOR (subsidiaries)->contents[coding->eol_type]; |
|
|
} |
|
|
} |
|
4750 |
|
|
4751 |
|
/* If we decide not to encode text, use `raw-text' or one of its |
4752 |
|
subsidiaries. */ |
4753 |
if (force_raw_text) |
if (force_raw_text) |
4754 |
setup_raw_text_coding_system (coding); |
val = raw_text_coding_system (val); |
|
goto done_setup_coding; |
|
4755 |
} |
} |
4756 |
|
|
4757 |
setup_coding_system (Fcheck_coding_system (val), coding); |
setup_coding_system (val, coding); |
4758 |
|
if (! NILP (val) |
4759 |
|
&& VECTORP (CODING_ID_EOL_TYPE (coding->id))) |
4760 |
|
val = AREF (CODING_ID_EOL_TYPE (coding->id), 0); |
4761 |
|
|
|
done_setup_coding: |
|
4762 |
if (!STRINGP (start) && !NILP (current_buffer->selective_display)) |
if (!STRINGP (start) && !NILP (current_buffer->selective_display)) |
4763 |
coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; |
coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; |
4764 |
|
return val; |
4765 |
} |
} |
4766 |
|
|
4767 |
DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7, |
DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7, |
4905 |
We used to make this choice before calling build_annotations, but that |
We used to make this choice before calling build_annotations, but that |
4906 |
leads to problems when a write-annotate-function takes care of |
leads to problems when a write-annotate-function takes care of |
4907 |
unsavable chars (as was the case with X-Symbol). */ |
unsavable chars (as was the case with X-Symbol). */ |
4908 |
choose_write_coding_system (start, end, filename, |
Vlast_coding_system_used |
4909 |
append, visit, lockname, &coding); |
= choose_write_coding_system (start, end, filename, |
4910 |
Vlast_coding_system_used = coding.symbol; |
append, visit, lockname, &coding); |
|
|
|
|
given_buffer = current_buffer; |
|
|
if (! STRINGP (start)) |
|
|
{ |
|
|
annotations = build_annotations_2 (start, end, |
|
|
coding.pre_write_conversion, annotations); |
|
|
if (current_buffer != given_buffer) |
|
|
{ |
|
|
XSETFASTINT (start, BEGV); |
|
|
XSETFASTINT (end, ZV); |
|
|
} |
|
|
} |
|
4911 |
|
|
4912 |
#ifdef CLASH_DETECTION |
#ifdef CLASH_DETECTION |
4913 |
if (!auto_saving) |
if (!auto_saving) |
5045 |
if (GPT > BEG && GPT_ADDR[-1] != '\n') |
if (GPT > BEG && GPT_ADDR[-1] != '\n') |
5046 |
move_gap (find_next_newline (GPT, 1)); |
move_gap (find_next_newline (GPT, 1)); |
5047 |
#else |
#else |
5048 |
|
#if 0 |
5049 |
|
/* The new encoding routine doesn't require the following. */ |
5050 |
|
|
5051 |
/* Whether VMS or not, we must move the gap to the next of newline |
/* Whether VMS or not, we must move the gap to the next of newline |
5052 |
when we must put designation sequences at beginning of line. */ |
when we must put designation sequences at beginning of line. */ |
5053 |
if (INTEGERP (start) |
if (INTEGERP (start) |
5061 |
SET_PT_BOTH (opoint, opoint_byte); |
SET_PT_BOTH (opoint, opoint_byte); |
5062 |
} |
} |
5063 |
#endif |
#endif |
5064 |
|
#endif |
5065 |
|
|
5066 |
failure = 0; |
failure = 0; |
5067 |
immediate_quit = 1; |
immediate_quit = 1; |
5074 |
} |
} |
5075 |
else if (XINT (start) != XINT (end)) |
else if (XINT (start) != XINT (end)) |
5076 |
{ |
{ |
5077 |
tem = CHAR_TO_BYTE (XINT (start)); |
failure = 0 > a_write (desc, Qnil, |
5078 |
|
XINT (start), XINT (end) - XINT (start), |
5079 |
if (XINT (start) < GPT) |
&annotations, &coding); |
5080 |
{ |
save_errno = errno; |
|
failure = 0 > a_write (desc, Qnil, XINT (start), |
|
|
min (GPT, XINT (end)) - XINT (start), |
|
|
&annotations, &coding); |
|
|
save_errno = errno; |
|
|
} |
|
|
|
|
|
if (XINT (end) > GPT && !failure) |
|
|
{ |
|
|
tem = max (XINT (start), GPT); |
|
|
failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem, |
|
|
&annotations, &coding); |
|
|
save_errno = errno; |
|
|
} |
|
5081 |
} |
} |
5082 |
else |
else |
5083 |
{ |
{ |
5093 |
{ |
{ |
5094 |
/* We have to flush out a data. */ |
/* We have to flush out a data. */ |
5095 |
coding.mode |= CODING_MODE_LAST_BLOCK; |
coding.mode |= CODING_MODE_LAST_BLOCK; |
5096 |
failure = 0 > e_write (desc, Qnil, 0, 0, &coding); |
failure = 0 > e_write (desc, Qnil, 1, 1, &coding); |
5097 |
save_errno = errno; |
save_errno = errno; |
5098 |
} |
} |
5099 |
|
|
5283 |
return annotations; |
return annotations; |
5284 |
} |
} |
5285 |
|
|
|
static Lisp_Object |
|
|
build_annotations_2 (start, end, pre_write_conversion, annotations) |
|
|
Lisp_Object start, end, pre_write_conversion, annotations; |
|
|
{ |
|
|
struct gcpro gcpro1; |
|
|
Lisp_Object res; |
|
|
|
|
|
GCPRO1 (annotations); |
|
|
/* At last, do the same for the function PRE_WRITE_CONVERSION |
|
|
implied by the current coding-system. */ |
|
|
if (!NILP (pre_write_conversion)) |
|
|
{ |
|
|
struct buffer *given_buffer = current_buffer; |
|
|
Vwrite_region_annotations_so_far = annotations; |
|
|
res = call2 (pre_write_conversion, start, end); |
|
|
Flength (res); |
|
|
annotations = (current_buffer != given_buffer |
|
|
? res |
|
|
: merge (annotations, res, Qcar_less_than_car)); |
|
|
} |
|
|
|
|
|
UNGCPRO; |
|
|
return annotations; |
|
|
} |
|
5286 |
|
|
5287 |
/* Write to descriptor DESC the NCHARS chars starting at POS of STRING. |
/* Write to descriptor DESC the NCHARS chars starting at POS of STRING. |
5288 |
If STRING is nil, POS is the character position in the current buffer. |
If STRING is nil, POS is the character position in the current buffer. |
5354 |
int start, end; |
int start, end; |
5355 |
struct coding_system *coding; |
struct coding_system *coding; |
5356 |
{ |
{ |
|
register char *addr; |
|
|
register int nbytes; |
|
|
char buf[WRITE_BUF_SIZE]; |
|
5357 |
int return_val = 0; |
int return_val = 0; |
5358 |
|
|
|
if (start >= end) |
|
|
coding->composing = COMPOSITION_DISABLED; |
|
|
if (coding->composing != COMPOSITION_DISABLED) |
|
|
coding_save_composition (coding, start, end, string); |
|
|
|
|
5359 |
if (STRINGP (string)) |
if (STRINGP (string)) |
5360 |
{ |
{ |
5361 |
addr = SDATA (string); |
start = 0; |
5362 |
nbytes = SBYTES (string); |
end = SCHARS (string); |
|
coding->src_multibyte = STRING_MULTIBYTE (string); |
|
|
} |
|
|
else if (start < end) |
|
|
{ |
|
|
/* It is assured that the gap is not in the range START and END-1. */ |
|
|
addr = CHAR_POS_ADDR (start); |
|
|
nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start); |
|
|
coding->src_multibyte |
|
|
= !NILP (current_buffer->enable_multibyte_characters); |
|
|
} |
|
|
else |
|
|
{ |
|
|
addr = ""; |
|
|
nbytes = 0; |
|
|
coding->src_multibyte = 1; |
|
5363 |
} |
} |
5364 |
|
|
5365 |
/* We used to have a code for handling selective display here. But, |
/* We used to have a code for handling selective display here. But, |
5366 |
now it is handled within encode_coding. */ |
now it is handled within encode_coding. */ |
5367 |
while (1) |
do |
5368 |
{ |
{ |
5369 |
int result; |
if (STRINGP (string)) |
5370 |
|
encode_coding_object (coding, string, |
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 |
|
|
|
result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE); |
|
5378 |
if (coding->produced > 0) |
if (coding->produced > 0) |
5379 |
{ |
{ |
5380 |
coding->produced -= emacs_write (desc, buf, coding->produced); |
coding->produced -= emacs_write (desc, SDATA (coding->dst_object), |
5381 |
|
coding->produced); |
5382 |
|
|
5383 |
if (coding->produced) |
if (coding->produced) |
5384 |
{ |
{ |
5385 |
return_val = -1; |
return_val = -1; |
5386 |
break; |
break; |
5387 |
} |
} |
5388 |
} |
} |
|
nbytes -= coding->consumed; |
|
|
addr += coding->consumed; |
|
|
if (result == CODING_FINISH_INSUFFICIENT_SRC |
|
|
&& nbytes > 0) |
|
|
{ |
|
|
/* The source text ends by an incomplete multibyte form. |
|
|
There's no way other than write it out as is. */ |
|
|
nbytes -= emacs_write (desc, addr, nbytes); |
|
|
if (nbytes) |
|
|
{ |
|
|
return_val = -1; |
|
|
break; |
|
|
} |
|
|
} |
|
|
if (nbytes <= 0) |
|
|
break; |
|
5389 |
start += coding->consumed_char; |
start += coding->consumed_char; |
|
if (coding->cmp_data) |
|
|
coding_adjust_composition_offset (coding, start); |
|
5390 |
} |
} |
5391 |
|
while (start < end); |
|
if (coding->cmp_data) |
|
|
coding_free_composition_data (coding); |
|
5392 |
|
|
5393 |
return return_val; |
return return_val; |
5394 |
} |
} |