87 |
#include "lisp.h" |
#include "lisp.h" |
88 |
#include "intervals.h" |
#include "intervals.h" |
89 |
#include "buffer.h" |
#include "buffer.h" |
90 |
#include "charset.h" |
#include "character.h" |
91 |
#include "coding.h" |
#include "coding.h" |
92 |
#include "window.h" |
#include "window.h" |
93 |
|
|
3576 |
unsigned char buffer[1 << 14]; |
unsigned char buffer[1 << 14]; |
3577 |
int replace_handled = 0; |
int replace_handled = 0; |
3578 |
int set_coding_system = 0; |
int set_coding_system = 0; |
3579 |
int coding_system_decided = 0; |
Lisp_Object coding_system; |
3580 |
int read_quit = 0; |
int read_quit = 0; |
3581 |
|
|
3582 |
if (current_buffer->base_buffer && ! NILP (visit)) |
if (current_buffer->base_buffer && ! NILP (visit)) |
3713 |
} |
} |
3714 |
} |
} |
3715 |
|
|
3716 |
|
/* The value Qnil means that the coding system is not yet |
3717 |
|
decided. */ |
3718 |
|
coding_system = Qnil; |
3719 |
if (BEG < Z) |
if (BEG < Z) |
3720 |
{ |
{ |
3721 |
/* Decide the coding system to use for reading the file now |
/* Decide the coding system to use for reading the file now |
3722 |
because we can't use an optimized method for handling |
because we can't use an optimized method for handling |
3723 |
`coding:' tag if the current buffer is not empty. */ |
`coding:' tag if the current buffer is not empty. */ |
|
Lisp_Object val; |
|
|
val = Qnil; |
|
|
|
|
3724 |
if (!NILP (Vcoding_system_for_read)) |
if (!NILP (Vcoding_system_for_read)) |
3725 |
val = Vcoding_system_for_read; |
coding_system = Vcoding_system_for_read; |
3726 |
else if (! NILP (replace)) |
else if (! NILP (replace)) |
3727 |
/* In REPLACE mode, we can use the same coding system |
/* In REPLACE mode, we can use the same coding system |
3728 |
that was used to visit the file. */ |
that was used to visit the file. */ |
3729 |
val = current_buffer->buffer_file_coding_system; |
coding_system = current_buffer->buffer_file_coding_system; |
3730 |
else |
else |
3731 |
{ |
{ |
3732 |
/* Don't try looking inside a file for a coding system |
/* Don't try looking inside a file for a coding system |
3773 |
current_buffer->enable_multibyte_characters = Qnil; |
current_buffer->enable_multibyte_characters = Qnil; |
3774 |
insert_1_both (read_buf, nread, nread, 0, 0, 0); |
insert_1_both (read_buf, nread, nread, 0, 0, 0); |
3775 |
TEMP_SET_PT_BOTH (BEG, BEG_BYTE); |
TEMP_SET_PT_BOTH (BEG, BEG_BYTE); |
3776 |
val = call2 (Vset_auto_coding_function, |
coding_system = call2 (Vset_auto_coding_function, |
3777 |
filename, make_number (nread)); |
filename, make_number (nread)); |
3778 |
set_buffer_internal (prev); |
set_buffer_internal (prev); |
3779 |
|
|
3780 |
/* Remove the binding for standard-output. */ |
/* Remove the binding for standard-output. */ |
3791 |
} |
} |
3792 |
} |
} |
3793 |
|
|
3794 |
if (NILP (val)) |
if (NILP (coding_system)) |
3795 |
{ |
{ |
3796 |
/* If we have not yet decided a coding system, check |
/* If we have not yet decided a coding system, check |
3797 |
file-coding-system-alist. */ |
file-coding-system-alist. */ |
3805 |
} |
} |
3806 |
} |
} |
3807 |
|
|
3808 |
setup_coding_system (Fcheck_coding_system (val), &coding); |
if (NILP (coding_system)) |
3809 |
/* Ensure we set Vlast_coding_system_used. */ |
coding_system = Qundecided; |
3810 |
set_coding_system = 1; |
else |
3811 |
|
CHECK_CODING_SYSTEM (coding_system); |
3812 |
|
|
3813 |
if (NILP (current_buffer->enable_multibyte_characters) |
if (NILP (current_buffer->enable_multibyte_characters)) |
|
&& ! NILP (val)) |
|
3814 |
/* We must suppress all character code conversion except for |
/* We must suppress all character code conversion except for |
3815 |
end-of-line conversion. */ |
end-of-line conversion. */ |
3816 |
setup_raw_text_coding_system (&coding); |
coding_system = raw_text_coding_system (coding_system); |
3817 |
|
|
3818 |
coding.src_multibyte = 0; |
setup_coding_system (coding_system, &coding); |
3819 |
coding.dst_multibyte |
/* Ensure we set Vlast_coding_system_used. */ |
3820 |
= !NILP (current_buffer->enable_multibyte_characters); |
set_coding_system = 1; |
|
coding_system_decided = 1; |
|
3821 |
} |
} |
3822 |
|
|
3823 |
/* If requested, replace the accessible part of the buffer |
/* If requested, replace the accessible part of the buffer |
3836 |
and let the following if-statement handle the replace job. */ |
and let the following if-statement handle the replace job. */ |
3837 |
if (!NILP (replace) |
if (!NILP (replace) |
3838 |
&& BEGV < ZV |
&& BEGV < ZV |
3839 |
&& !(coding.common_flags & CODING_REQUIRE_DECODING_MASK)) |
&& (NILP (coding_system) |
3840 |
|
|| ! CODING_REQUIRE_DECODING (&coding))) |
3841 |
{ |
{ |
3842 |
/* same_at_start and same_at_end count bytes, |
/* same_at_start and same_at_end count bytes, |
3843 |
because file access counts bytes |
because file access counts bytes |
3872 |
else if (nread == 0) |
else if (nread == 0) |
3873 |
break; |
break; |
3874 |
|
|
3875 |
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. */ |
|
3876 |
{ |
{ |
3877 |
giveup_match_end = 1; |
coding_system = detect_coding_system (buffer, nread, 1, 0, |
3878 |
break; |
coding_system); |
3879 |
|
setup_coding_system (coding_system, &coding); |
3880 |
} |
} |
3881 |
|
if (CODING_REQUIRE_DECODING (&coding)) |
3882 |
if (coding.eol_type == CODING_EOL_UNDECIDED) |
/* We found that the file should be decoded somehow. |
|
detect_eol (&coding, buffer, nread); |
|
|
if (coding.eol_type != CODING_EOL_UNDECIDED |
|
|
&& coding.eol_type != CODING_EOL_LF) |
|
|
/* We found that the format of eol should be decoded. |
|
3883 |
Let's give up here. */ |
Let's give up here. */ |
3884 |
{ |
{ |
3885 |
giveup_match_end = 1; |
giveup_match_end = 1; |
4026 |
int same_at_end = ZV_BYTE; |
int same_at_end = ZV_BYTE; |
4027 |
int overlap; |
int overlap; |
4028 |
int bufpos; |
int bufpos; |
4029 |
/* 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); |
|
4030 |
int temp; |
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 ()); |
4037 |
|
|
4038 |
/* First read the whole file, performing code conversion into |
/* First read the whole file, performing code conversion into |
4039 |
CONVERSION_BUFFER. */ |
CONVERSION_BUFFER. */ |
4040 |
|
|
4041 |
if (lseek (fd, XINT (beg), 0) < 0) |
if (lseek (fd, XINT (beg), 0) < 0) |
4042 |
{ |
{ |
|
xfree (conversion_buffer); |
|
4043 |
report_file_error ("Setting file position", |
report_file_error ("Setting file position", |
4044 |
Fcons (orig_filename, Qnil)); |
Fcons (orig_filename, Qnil)); |
4045 |
} |
} |
4051 |
|
|
4052 |
while (how_much < total) |
while (how_much < total) |
4053 |
{ |
{ |
4054 |
|
/* We read one bunch by one (READ_BUF_SIZE bytes) to allow |
4055 |
|
quitting while reading a huge while. */ |
4056 |
/* try is reserved in some compilers (Microsoft C) */ |
/* try is reserved in some compilers (Microsoft C) */ |
4057 |
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; |
|
4058 |
int this; |
int this; |
4059 |
|
|
4060 |
/* Allow quitting out of the actual I/O. */ |
/* Allow quitting out of the actual I/O. */ |
4061 |
immediate_quit = 1; |
immediate_quit = 1; |
4062 |
QUIT; |
QUIT; |
4063 |
this = emacs_read (fd, destination, trytry); |
this = emacs_read (fd, read_buf + unprocessed, trytry); |
4064 |
immediate_quit = 0; |
immediate_quit = 0; |
4065 |
|
|
4066 |
if (this < 0 || this + unprocessed == 0) |
if (this <= 0) |
4067 |
{ |
{ |
4068 |
how_much = this; |
if (this < 0) |
4069 |
|
how_much = this; |
4070 |
break; |
break; |
4071 |
} |
} |
4072 |
|
|
4073 |
how_much += this; |
how_much += this; |
4074 |
|
|
4075 |
if (CODING_MAY_REQUIRE_DECODING (&coding)) |
decode_coding_c_string (&coding, read_buf, unprocessed + this, |
4076 |
{ |
conversion_buffer); |
4077 |
int require, result; |
unprocessed = coding.carryover_bytes; |
4078 |
|
if (coding.carryover_bytes > 0) |
4079 |
this += unprocessed; |
bcopy (coding.carryover, read_buf, unprocessed); |
4080 |
|
} |
4081 |
/* If we are using more space than estimated, |
|
4082 |
make CONVERSION_BUFFER bigger. */ |
emacs_close (fd); |
|
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; |
|
|
} |
|
4083 |
|
|
4084 |
/* At this point, INSERTED is how many characters (i.e. bytes) |
/* At this point, HOW_MUCH should equal TOTAL, or should be <= 0 |
4085 |
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. */ |
|
4086 |
|
|
4087 |
if (how_much < 0) |
if (how_much < 0) |
4088 |
{ |
{ |
|
xfree (conversion_buffer); |
|
|
|
|
4089 |
if (how_much == -1) |
if (how_much == -1) |
4090 |
error ("IO error reading %s: %s", |
error ("IO error reading %s: %s", |
4091 |
XSTRING (orig_filename)->data, emacs_strerror (errno)); |
XSTRING (orig_filename)->data, emacs_strerror (errno)); |
4093 |
error ("maximum buffer size exceeded"); |
error ("maximum buffer size exceeded"); |
4094 |
} |
} |
4095 |
|
|
4096 |
/* Compare the beginning of the converted file |
if (unprocessed > 0) |
4097 |
with the buffer text. */ |
{ |
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. */ |
4109 |
|
|
4110 |
bufpos = 0; |
bufpos = 0; |
4111 |
while (bufpos < inserted && same_at_start < same_at_end |
while (bufpos < inserted && same_at_start < same_at_end |
4112 |
&& FETCH_BYTE (same_at_start) == conversion_buffer[bufpos]) |
&& FETCH_BYTE (same_at_start) == decoded[bufpos]) |
4113 |
same_at_start++, bufpos++; |
same_at_start++, bufpos++; |
4114 |
|
|
4115 |
/* If the file matches the buffer completely, |
/* If the file matches the head of buffer completely, |
4116 |
there's no need to replace anything. */ |
there's no need to replace anything. */ |
4117 |
|
|
4118 |
if (bufpos == inserted) |
if (bufpos == inserted) |
4119 |
{ |
{ |
|
xfree (conversion_buffer); |
|
|
emacs_close (fd); |
|
4120 |
specpdl_ptr--; |
specpdl_ptr--; |
4121 |
/* Truncate the buffer to the size of the file. */ |
/* Truncate the buffer to the size of the file. */ |
4122 |
del_range_byte (same_at_start, same_at_end, 0); |
del_range_byte (same_at_start, same_at_end, 0); |
4124 |
goto handled; |
goto handled; |
4125 |
} |
} |
4126 |
|
|
4127 |
/* Extend the start of non-matching text area to multibyte |
/* Extend the start of non-matching text area to the previous |
4128 |
character boundary. */ |
multibyte character boundary. */ |
4129 |
if (! NILP (current_buffer->enable_multibyte_characters)) |
if (! NILP (current_buffer->enable_multibyte_characters)) |
4130 |
while (same_at_start > BEGV_BYTE |
while (same_at_start > BEGV_BYTE |
4131 |
&& ! CHAR_HEAD_P (FETCH_BYTE (same_at_start))) |
&& ! CHAR_HEAD_P (FETCH_BYTE (same_at_start))) |
4138 |
/* Compare with same_at_start to avoid counting some buffer text |
/* Compare with same_at_start to avoid counting some buffer text |
4139 |
as matching both at the file's beginning and at the end. */ |
as matching both at the file's beginning and at the end. */ |
4140 |
while (bufpos > 0 && same_at_end > same_at_start |
while (bufpos > 0 && same_at_end > same_at_start |
4141 |
&& FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1]) |
&& FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1]) |
4142 |
same_at_end--, bufpos--; |
same_at_end--, bufpos--; |
4143 |
|
|
4144 |
/* Extend the end of non-matching text area to multibyte |
/* Extend the end of non-matching text area to the next |
4145 |
character boundary. */ |
multibyte character boundary. */ |
4146 |
if (! NILP (current_buffer->enable_multibyte_characters)) |
if (! NILP (current_buffer->enable_multibyte_characters)) |
4147 |
while (same_at_end < ZV_BYTE |
while (same_at_end < ZV_BYTE |
4148 |
&& ! CHAR_HEAD_P (FETCH_BYTE (same_at_end))) |
&& ! CHAR_HEAD_P (FETCH_BYTE (same_at_end))) |
4160 |
|
|
4161 |
/* Replace the chars that we need to replace, |
/* Replace the chars that we need to replace, |
4162 |
and update INSERTED to equal the number of bytes |
and update INSERTED to equal the number of bytes |
4163 |
we are taking from the file. */ |
we are taking from the decoded string. */ |
4164 |
inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); |
inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); |
4165 |
|
|
4166 |
if (same_at_end != same_at_start) |
if (same_at_end != same_at_start) |
4167 |
{ |
{ |
4168 |
del_range_byte (same_at_start, same_at_end, 0); |
del_range_byte (same_at_start, same_at_end, 0); |
4169 |
temp = GPT; |
temp = GPT; |
4170 |
same_at_start = GPT_BYTE; |
same_at_start = GPT_BYTE; |
4175 |
} |
} |
4176 |
/* Insert from the file at the proper position. */ |
/* Insert from the file at the proper position. */ |
4177 |
SET_PT_BOTH (temp, same_at_start); |
SET_PT_BOTH (temp, same_at_start); |
4178 |
insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted, |
insert_from_buffer (XBUFFER (conversion_buffer), |
4179 |
0, 0, 0); |
buf_bytepos_to_charpos (XBUFFER (conversion_buffer), |
4180 |
if (coding.cmp_data && coding.cmp_data->used) |
same_at_start), |
4181 |
coding_restore_composition (&coding, Fcurrent_buffer ()); |
buf_bytepos_to_charpos (XBUFFER (conversion_buffer), |
4182 |
coding_free_composition_data (&coding); |
same_at_start + inserted), |
4183 |
|
0); |
4184 |
/* Set `inserted' to the number of inserted characters. */ |
/* Set `inserted' to the number of inserted characters. */ |
4185 |
inserted = PT - temp; |
inserted = PT - temp; |
4186 |
|
|
4187 |
xfree (conversion_buffer); |
unbind_to (this_count, Qnil); |
|
emacs_close (fd); |
|
|
specpdl_ptr--; |
|
4188 |
|
|
4189 |
goto handled; |
goto handled; |
4190 |
} |
} |
4228 |
inserted = 0; |
inserted = 0; |
4229 |
|
|
4230 |
/* 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 |
4231 |
code_convert_region after all data are read into the buffer. */ |
decode_coding_gap after all data are read into the buffer. */ |
4232 |
{ |
{ |
4233 |
int gap_size = GAP_SIZE; |
int gap_size = GAP_SIZE; |
4234 |
|
|
4319 |
|
|
4320 |
notfound: |
notfound: |
4321 |
|
|
4322 |
if (! coding_system_decided) |
if (NILP (coding_system)) |
4323 |
{ |
{ |
4324 |
/* The coding system is not yet decided. Decide it by an |
/* The coding system is not yet decided. Decide it by an |
4325 |
optimized method for handling `coding:' tag. |
optimized method for handling `coding:' tag. |
4326 |
|
|
4327 |
Note that we can get here only if the buffer was empty |
Note that we can get here only if the buffer was empty |
4328 |
before the insertion. */ |
before the insertion. */ |
|
Lisp_Object val; |
|
|
val = Qnil; |
|
4329 |
|
|
4330 |
if (!NILP (Vcoding_system_for_read)) |
if (!NILP (Vcoding_system_for_read)) |
4331 |
val = Vcoding_system_for_read; |
coding_system = Vcoding_system_for_read; |
4332 |
else |
else |
4333 |
{ |
{ |
4334 |
/* Since we are sure that the current buffer was empty |
/* Since we are sure that the current buffer was empty |
4349 |
|
|
4350 |
if (inserted > 0 && ! NILP (Vset_auto_coding_function)) |
if (inserted > 0 && ! NILP (Vset_auto_coding_function)) |
4351 |
{ |
{ |
4352 |
val = call2 (Vset_auto_coding_function, |
coding_system = call2 (Vset_auto_coding_function, |
4353 |
filename, make_number (inserted)); |
filename, make_number (inserted)); |
4354 |
} |
} |
4355 |
|
|
4356 |
if (NILP (val)) |
if (NILP (coding_system)) |
4357 |
{ |
{ |
4358 |
/* If the coding system is not yet decided, check |
/* If the coding system is not yet decided, check |
4359 |
file-coding-system-alist. */ |
file-coding-system-alist. */ |
4363 |
args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil; |
args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil; |
4364 |
coding_systems = Ffind_operation_coding_system (6, args); |
coding_systems = Ffind_operation_coding_system (6, args); |
4365 |
if (CONSP (coding_systems)) |
if (CONSP (coding_systems)) |
4366 |
val = XCAR (coding_systems); |
coding_system = XCAR (coding_systems); |
4367 |
} |
} |
4368 |
|
|
4369 |
unbind_to (count, Qnil); |
unbind_to (count, Qnil); |
4370 |
inserted = Z_BYTE - BEG_BYTE; |
inserted = Z_BYTE - BEG_BYTE; |
4371 |
} |
} |
4372 |
|
|
4373 |
/* The following kludgy code is to avoid some compiler bug. |
if (NILP (coding_system)) |
4374 |
We can't simply do |
coding_system = Qundecided; |
4375 |
setup_coding_system (val, &coding); |
else |
4376 |
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; |
|
4377 |
|
|
4378 |
if (NILP (current_buffer->enable_multibyte_characters) |
if (NILP (current_buffer->enable_multibyte_characters)) |
|
&& ! NILP (val)) |
|
4379 |
/* We must suppress all character code conversion except for |
/* We must suppress all character code conversion except for |
4380 |
end-of-line conversion. */ |
end-of-line conversion. */ |
4381 |
setup_raw_text_coding_system (&coding); |
coding_system = raw_text_coding_system (coding_system); |
4382 |
coding.src_multibyte = 0; |
|
4383 |
coding.dst_multibyte |
setup_coding_system (coding_system, &coding); |
4384 |
= !NILP (current_buffer->enable_multibyte_characters); |
/* Ensure we set Vlast_coding_system_used. */ |
4385 |
|
set_coding_system = 1; |
4386 |
} |
} |
4387 |
|
|
4388 |
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)) |
|
4389 |
{ |
{ |
4390 |
/* Visiting a file with these coding system makes the buffer |
/* When we visit a file by raw-text, we change the buffer to |
4391 |
unibyte. */ |
unibyte. If we have not yet decided how to decode a text, |
4392 |
current_buffer->enable_multibyte_characters = Qnil; |
decide it at first by detecting the file's encoding. */ |
4393 |
coding.dst_multibyte = 0; |
if (CODING_REQUIRE_DETECTION (&coding)) |
4394 |
|
{ |
4395 |
|
coding_system = detect_coding_system (PT_ADDR, inserted, 1, 0, |
4396 |
|
coding_system); |
4397 |
|
setup_coding_system (coding_system, &coding); |
4398 |
|
} |
4399 |
|
|
4400 |
|
if (CODING_FOR_UNIBYTE (&coding) |
4401 |
|
/* Can't do this if part of the buffer might be preserved. */ |
4402 |
|
&& NILP (replace)) |
4403 |
|
/* Visiting a file with these coding system makes the buffer |
4404 |
|
unibyte. */ |
4405 |
|
current_buffer->enable_multibyte_characters = Qnil; |
4406 |
} |
} |
4407 |
|
|
4408 |
if (inserted > 0 || coding.type == coding_type_ccl) |
if (CODING_REQUIRE_DETECTION (&coding) |
4409 |
|
|| CODING_REQUIRE_DECODING (&coding)) |
4410 |
{ |
{ |
4411 |
if (CODING_MAY_REQUIRE_DECODING (&coding)) |
move_gap_both (PT, PT_BYTE); |
4412 |
{ |
GAP_SIZE += inserted; |
4413 |
code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, |
ZV_BYTE -= inserted; |
4414 |
&coding, 0, 0); |
Z_BYTE -= inserted; |
4415 |
inserted = coding.produced_char; |
ZV -= inserted; |
4416 |
} |
Z -= inserted; |
4417 |
else |
decode_coding_gap (&coding, inserted, inserted); |
4418 |
adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, |
inserted = coding.produced_char; |
4419 |
inserted); |
} |
4420 |
} |
else if (inserted > 0) |
4421 |
|
adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, |
4422 |
|
inserted); |
4423 |
|
|
4424 |
#ifdef DOS_NT |
#ifdef DOS_NT |
4425 |
/* Use the conversion type to determine buffer-file-type |
/* Use the conversion type to determine buffer-file-type |
4426 |
(find-buffer-file-type is now used to help determine the |
(find-buffer-file-type is now used to help determine the |
4427 |
conversion). */ |
conversion). */ |
4428 |
if ((coding.eol_type == CODING_EOL_UNDECIDED |
if ((coding.eol_type == eol_type_undecided |
4429 |
|| coding.eol_type == CODING_EOL_LF) |
|| coding.eol_type == eol_type_lf) |
4430 |
&& ! CODING_REQUIRE_DECODING (&coding)) |
&& ! CODING_REQUIRE_DECODING (&coding)) |
4431 |
current_buffer->buffer_file_type = Qt; |
current_buffer->buffer_file_type = Qt; |
4432 |
else |
else |
4490 |
} |
} |
4491 |
|
|
4492 |
if (set_coding_system) |
if (set_coding_system) |
4493 |
Vlast_coding_system_used = coding.symbol; |
Vlast_coding_system_used = coding_system; |
4494 |
|
|
4495 |
/* Call after-change hooks for the inserted text, aside from the case |
/* Call after-change hooks for the inserted text, aside from the case |
4496 |
of normal visiting (not with REPLACE), which is done in a new buffer |
of normal visiting (not with REPLACE), which is done in a new buffer |
4535 |
} |
} |
4536 |
|
|
4537 |
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)); |
|
4538 |
|
|
4539 |
/* If build_annotations switched buffers, switch back to BUF. |
/* If build_annotations switched buffers, switch back to BUF. |
4540 |
Kill the temporary buffer that was selected in the meantime. |
Kill the temporary buffer that was selected in the meantime. |
4616 |
using_default_coding = 1; |
using_default_coding = 1; |
4617 |
} |
} |
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 |
|
|
4629 |
if (!force_raw_text |
if (!force_raw_text |
4630 |
&& !NILP (Ffboundp (Vselect_safe_coding_system_function))) |
&& !NILP (Ffboundp (Vselect_safe_coding_system_function))) |
4631 |
/* Confirm that VAL can surely encode the current region. */ |
/* Confirm that VAL can surely encode the current region. */ |
4632 |
val = call3 (Vselect_safe_coding_system_function, start, end, val); |
val = call3 (Vselect_safe_coding_system_function, start, end, val); |
4633 |
|
|
4634 |
setup_coding_system (Fcheck_coding_system (val), coding); |
/* If the decided coding-system doesn't specify end-of-line |
4635 |
if (coding->eol_type == CODING_EOL_UNDECIDED |
format, we use that of |
4636 |
&& !using_default_coding) |
`default-buffer-file-coding-system'. */ |
4637 |
{ |
if (! using_default_coding) |
4638 |
if (! EQ (default_buffer_file_coding.symbol, |
val = (coding_inherit_eol_type |
4639 |
buffer_defaults.buffer_file_coding_system)) |
(val, buffer_defaults.buffer_file_coding_system)); |
|
setup_coding_system (buffer_defaults.buffer_file_coding_system, |
|
|
&default_buffer_file_coding); |
|
|
if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED) |
|
|
{ |
|
|
Lisp_Object subsidiaries; |
|
|
|
|
|
coding->eol_type = default_buffer_file_coding.eol_type; |
|
|
subsidiaries = Fget (coding->symbol, Qeol_type); |
|
|
if (VECTORP (subsidiaries) |
|
|
&& XVECTOR (subsidiaries)->size == 3) |
|
|
coding->symbol |
|
|
= XVECTOR (subsidiaries)->contents[coding->eol_type]; |
|
|
} |
|
|
} |
|
4640 |
|
|
4641 |
|
/* If we decide not to encode text, use `raw-text' or one of its |
4642 |
|
subsidiaries. */ |
4643 |
if (force_raw_text) |
if (force_raw_text) |
4644 |
setup_raw_text_coding_system (coding); |
val = raw_text_coding_system (val); |
|
goto done_setup_coding; |
|
4645 |
} |
} |
4646 |
|
|
4647 |
setup_coding_system (Fcheck_coding_system (val), coding); |
setup_coding_system (Fcheck_coding_system (val), coding); |
4648 |
|
|
|
done_setup_coding: |
|
4649 |
if (!STRINGP (start) && !NILP (current_buffer->selective_display)) |
if (!STRINGP (start) && !NILP (current_buffer->selective_display)) |
4650 |
coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; |
coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; |
4651 |
} |
} |
4785 |
unsavable chars (as was the case with X-Symbol). */ |
unsavable chars (as was the case with X-Symbol). */ |
4786 |
choose_write_coding_system (start, end, filename, |
choose_write_coding_system (start, end, filename, |
4787 |
append, visit, lockname, &coding); |
append, visit, lockname, &coding); |
4788 |
Vlast_coding_system_used = coding.symbol; |
Vlast_coding_system_used = CODING_ID_NAME (coding.id); |
4789 |
|
|
4790 |
given_buffer = current_buffer; |
given_buffer = current_buffer; |
|
annotations = build_annotations_2 (start, end, |
|
|
coding.pre_write_conversion, annotations); |
|
4791 |
if (current_buffer != given_buffer) |
if (current_buffer != given_buffer) |
4792 |
{ |
{ |
4793 |
XSETFASTINT (start, BEGV); |
XSETFASTINT (start, BEGV); |
4930 |
if (GPT > BEG && GPT_ADDR[-1] != '\n') |
if (GPT > BEG && GPT_ADDR[-1] != '\n') |
4931 |
move_gap (find_next_newline (GPT, 1)); |
move_gap (find_next_newline (GPT, 1)); |
4932 |
#else |
#else |
4933 |
|
#if 0 |
4934 |
|
/* The new encoding routine doesn't require the following. */ |
4935 |
|
|
4936 |
/* 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 |
4937 |
when we must put designation sequences at beginning of line. */ |
when we must put designation sequences at beginning of line. */ |
4938 |
if (INTEGERP (start) |
if (INTEGERP (start) |
4946 |
SET_PT_BOTH (opoint, opoint_byte); |
SET_PT_BOTH (opoint, opoint_byte); |
4947 |
} |
} |
4948 |
#endif |
#endif |
4949 |
|
#endif |
4950 |
|
|
4951 |
failure = 0; |
failure = 0; |
4952 |
immediate_quit = 1; |
immediate_quit = 1; |
4959 |
} |
} |
4960 |
else if (XINT (start) != XINT (end)) |
else if (XINT (start) != XINT (end)) |
4961 |
{ |
{ |
4962 |
tem = CHAR_TO_BYTE (XINT (start)); |
failure = 0 > a_write (desc, Qnil, |
4963 |
|
XINT (start), XINT (end) - XINT (start), |
4964 |
if (XINT (start) < GPT) |
&annotations, &coding); |
4965 |
{ |
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; |
|
|
} |
|
4966 |
} |
} |
4967 |
else |
else |
4968 |
{ |
{ |
4978 |
{ |
{ |
4979 |
/* We have to flush out a data. */ |
/* We have to flush out a data. */ |
4980 |
coding.mode |= CODING_MODE_LAST_BLOCK; |
coding.mode |= CODING_MODE_LAST_BLOCK; |
4981 |
failure = 0 > e_write (desc, Qnil, 0, 0, &coding); |
failure = 0 > e_write (desc, Qnil, 1, 1, &coding); |
4982 |
save_errno = errno; |
save_errno = errno; |
4983 |
} |
} |
4984 |
|
|
5154 |
return annotations; |
return annotations; |
5155 |
} |
} |
5156 |
|
|
|
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; |
|
|
} |
|
5157 |
|
|
5158 |
/* Write to descriptor DESC the NCHARS chars starting at POS of STRING. |
/* Write to descriptor DESC the NCHARS chars starting at POS of STRING. |
5159 |
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. |
5225 |
int start, end; |
int start, end; |
5226 |
struct coding_system *coding; |
struct coding_system *coding; |
5227 |
{ |
{ |
|
register char *addr; |
|
|
register int nbytes; |
|
|
char buf[WRITE_BUF_SIZE]; |
|
5228 |
int return_val = 0; |
int return_val = 0; |
5229 |
|
|
|
if (start >= end) |
|
|
coding->composing = COMPOSITION_DISABLED; |
|
|
if (coding->composing != COMPOSITION_DISABLED) |
|
|
coding_save_composition (coding, start, end, string); |
|
|
|
|
5230 |
if (STRINGP (string)) |
if (STRINGP (string)) |
5231 |
{ |
{ |
5232 |
addr = XSTRING (string)->data; |
start = 0; |
5233 |
nbytes = STRING_BYTES (XSTRING (string)); |
end = XSTRING (string)->size; |
|
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; |
|
5234 |
} |
} |
5235 |
|
|
5236 |
|
coding->mode |= CODING_MODE_FIXED_DESTINATION; |
5237 |
|
if (! NILP (current_buffer->selective_display)) |
5238 |
|
coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; |
5239 |
|
|
5240 |
/* We used to have a code for handling selective display here. But, |
/* We used to have a code for handling selective display here. But, |
5241 |
now it is handled within encode_coding. */ |
now it is handled within encode_coding. */ |
5242 |
while (1) |
do |
5243 |
{ |
{ |
5244 |
int result; |
if (STRINGP (string)) |
5245 |
|
encode_coding_object (coding, string, |
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 |
|
|
|
result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE); |
|
5253 |
if (coding->produced > 0) |
if (coding->produced > 0) |
5254 |
{ |
{ |
5255 |
coding->produced -= emacs_write (desc, buf, coding->produced); |
coding->produced -= emacs_write (desc, |
5256 |
|
XSTRING (coding->dst_object)->data, |
5257 |
|
coding->produced); |
5258 |
if (coding->produced) |
if (coding->produced) |
5259 |
{ |
{ |
5260 |
return_val = -1; |
return_val = -1; |
5261 |
break; |
break; |
5262 |
} |
} |
5263 |
} |
} |
|
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; |
|
5264 |
start += coding->consumed_char; |
start += coding->consumed_char; |
|
if (coding->cmp_data) |
|
|
coding_adjust_composition_offset (coding, start); |
|
5265 |
} |
} |
5266 |
|
while (start < end); |
|
if (coding->cmp_data) |
|
|
coding_free_composition_data (coding); |
|
5267 |
|
|
5268 |
return return_val; |
return return_val; |
5269 |
} |
} |