Commit 1b978129 authored by Gerd Moellmann's avatar Gerd Moellmann
Browse files

(unwind_read): Function removed.

(read_non_regular, read_non_regular_quit): New functions.
(Finsert_file_contents): When reading from non-regular files,
arrange to catch a `quit' and terminate the loop.  Rearrange
code so that a `quit' when reading from a regular file doesn't
insert text in the buffer.
parent 9d5ceccb
...@@ -3419,61 +3419,40 @@ decide_coding_unwind (unwind_data) ...@@ -3419,61 +3419,40 @@ decide_coding_unwind (unwind_data)
} }
/* Unwind-function for reading from a file in insert-file-contents. /* Used to pass values from insert-file-contents to read_non_regular. */
INSERTED_BYTES is the number of bytes successfully inserted into static int non_regular_fd;
current_buffer. static int non_regular_inserted;
static int non_regular_nbytes;
When reading is interrupted by C-g, this leaves the newly read part
of the current buffer undecoded. If this happens in a multibyte
buffer, prevent invalid characters by either discarding what has
been read or switching the buffer to unibyte.
PT GPT /* Read from a non-regular file.
+-----------------------------------------------------+ Read non_regular_trytry bytes max from non_regular_fd.
| | inserted bytes | GAP_SIZE | | Non_regular_inserted specifies where to put the read bytes.
+-----------------------------------------------------+ Value is the number of bytes read. */
\ /
+--------- the gap ---------+ */
static Lisp_Object static Lisp_Object
unwind_read (inserted_bytes) read_non_regular ()
Lisp_Object inserted_bytes;
{ {
if (!NILP (current_buffer->enable_multibyte_characters)) int nbytes;
{
int nbytes = XINT (inserted_bytes); immediate_quit = 1;
Lisp_Object args[3]; QUIT;
char *action; nbytes = emacs_read (non_regular_fd,
BEG_ADDR + PT_BYTE - 1 + non_regular_inserted,
non_regular_nbytes);
Fsignal (Qquit, Qnil);
immediate_quit = 0;
return make_number (nbytes);
}
if (Z == nbytes)
{
/* Buffer was previously empty. Switch it to unibyte
because newly inserted text is not decoded. */
current_buffer->enable_multibyte_characters = Qnil;
action = "buffer made unibyte";
}
else
{
ZV -= nbytes;
ZV_BYTE -= nbytes;
Z -= nbytes;
Z_BYTE -= nbytes;
GPT = PT;
GPT_BYTE = PT_BYTE;
GAP_SIZE = nbytes + GAP_SIZE;
action = "no text inserted";
}
/* Condition-case handler used when reading from non-regular files
args[0] = build_string ("Quit while inserting text in buffer `%s': %s"); in insert-file-contents. */
args[1] = current_buffer->name;
args[2] = build_string (action); static Lisp_Object
Fmessage (3, args); read_non_regular_quit ()
} {
return Qnil; return Qnil;
} }
...@@ -3523,6 +3502,8 @@ actually used.") ...@@ -3523,6 +3502,8 @@ actually used.")
int replace_handled = 0; int replace_handled = 0;
int set_coding_system = 0; int set_coding_system = 0;
int coding_system_decided = 0; int coding_system_decided = 0;
int gap_size;
int read_quit = 0;
if (current_buffer->base_buffer && ! NILP (visit)) if (current_buffer->base_buffer && ! NILP (visit))
error ("Cannot do file visiting in an indirect buffer"); error ("Cannot do file visiting in an indirect buffer");
...@@ -4182,55 +4163,86 @@ actually used.") ...@@ -4182,55 +4163,86 @@ actually used.")
before exiting the loop, it is set to a negative value if I/O before exiting the loop, it is set to a negative value if I/O
error occurs. */ error occurs. */
how_much = 0; how_much = 0;
/* Total bytes inserted. */ /* Total bytes inserted. */
inserted = 0; inserted = 0;
/* 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
code_convert_region after all data are read into the buffer. */ code_convert_region after all data are read into the buffer. */
while (how_much < total) {
{ int gap_size = GAP_SIZE;
while (how_much < total)
{
/* try is reserved in some compilers (Microsoft C) */ /* try is reserved in some compilers (Microsoft C) */
int trytry = min (total - how_much, READ_BUF_SIZE); int trytry = min (total - how_much, READ_BUF_SIZE);
int this; int this;
int count = BINDING_STACK_SIZE ();
/* For a special file, GAP_SIZE should be checked every time. */
if (not_regular && GAP_SIZE < trytry)
make_gap (total - GAP_SIZE);
/* Allow quitting out of the actual I/O. If a C-g interrupts
this, make sure that no invalid characters remain
in the undecoded part read. */
record_unwind_protect (unwind_read, make_number (inserted));
immediate_quit = 1;
QUIT;
this = emacs_read (fd, BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1,
trytry);
immediate_quit = 0;
--specpdl_ptr;
if (this <= 0) if (not_regular)
{ {
how_much = this; Lisp_Object val;
break;
}
GAP_SIZE -= this; /* Maybe make more room. */
GPT_BYTE += this; if (gap_size < trytry)
ZV_BYTE += this; {
Z_BYTE += this; make_gap (total - gap_size);
GPT += this; gap_size = GAP_SIZE;
ZV += this; }
Z += this;
/* Read from the file, capturing `quit'. When an
/* For a regular file, where TOTAL is the real size, error occurs, end the loop, and arrange for a quit
count HOW_MUCH to compare with it. to be signaled after decoding the text we read. */
For a special file, where TOTAL is just a buffer size, non_regular_fd = fd;
so don't bother counting in HOW_MUCH. non_regular_inserted = inserted;
(INSERTED is where we count the number of characters inserted.) */ non_regular_nbytes = trytry;
if (! not_regular) val = internal_condition_case_1 (read_non_regular, Qnil, Qerror,
how_much += this; read_non_regular_quit);
inserted += this; if (NILP (val))
} {
read_quit = 1;
break;
}
this = XINT (val);
}
else
{
/* Allow quitting out of the actual I/O. We don't make text
part of the buffer until all the reading is done, so a C-g
here doesn't do any harm. */
immediate_quit = 1;
QUIT;
this = emacs_read (fd, BEG_ADDR + PT_BYTE - 1 + inserted, trytry);
immediate_quit = 0;
}
if (this <= 0)
{
how_much = this;
break;
}
gap_size -= this;
/* For a regular file, where TOTAL is the real size,
count HOW_MUCH to compare with it.
For a special file, where TOTAL is just a buffer size,
so don't bother counting in HOW_MUCH.
(INSERTED is where we count the number of characters inserted.) */
if (! not_regular)
how_much += this;
inserted += this;
}
}
/* Make the text read part of the buffer. */
GAP_SIZE -= inserted;
GPT += inserted;
GPT_BYTE += inserted;
ZV += inserted;
ZV_BYTE += inserted;
Z += inserted;
Z_BYTE += inserted;
if (GAP_SIZE > 0) if (GAP_SIZE > 0)
/* Put an anchor to ensure multi-byte form ends at gap. */ /* Put an anchor to ensure multi-byte form ends at gap. */
...@@ -4446,6 +4458,9 @@ actually used.") ...@@ -4446,6 +4458,9 @@ actually used.")
report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
} }
if (read_quit)
Fsignal (Qquit, Qnil);
/* ??? Retval needs to be dealt with in all cases consistently. */ /* ??? Retval needs to be dealt with in all cases consistently. */
if (NILP (val)) if (NILP (val))
val = Fcons (orig_filename, val = Fcons (orig_filename,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment