Commit 2ef88fd4 authored by Dmitry Antipov's avatar Dmitry Antipov
Browse files

* fileio.c (Finsert_file_contents): Revert code introduced at

2013-01-18 in favor of the simpler and generally better fix.
Save stack space by removing 'buffer' and reusing 'read_buf'
where appropriate.
parent 7fd5a843
2013-01-21 Dmitry Antipov <dmantipov@yandex.ru>
* fileio.c (Finsert_file_contents): Revert code introduced at
2013-01-18 in favor of the simpler and generally better fix.
Save stack space by removing 'buffer' and reusing 'read_buf'
where appropriate.
2013-01-19 Paul Eggert <eggert@cs.ucla.edu> 2013-01-19 Paul Eggert <eggert@cs.ucla.edu>
   
* lisp.h (eabs): Define unconditionally (Bug#13419). * lisp.h (eabs): Define unconditionally (Bug#13419).
......
...@@ -3413,13 +3413,13 @@ decide_coding_unwind (Lisp_Object unwind_data) ...@@ -3413,13 +3413,13 @@ decide_coding_unwind (Lisp_Object unwind_data)
return Qnil; return Qnil;
} }
/* Check quit and read from the file. STATE is a Lisp_Save_Value /* Read from a non-regular file. STATE is a Lisp_Save_Value
object where slot 0 is the file descriptor, slot 1 specifies object where slot 0 is the file descriptor, slot 1 specifies
an offset to put the read bytes, and slot 2 is the maximum an offset to put the read bytes, and slot 2 is the maximum
amount of bytes to read. Value is the number of bytes read. */ amount of bytes to read. Value is the number of bytes read. */
static Lisp_Object static Lisp_Object
read_contents (Lisp_Object state) read_non_regular (Lisp_Object state)
{ {
int nbytes; int nbytes;
...@@ -3435,10 +3435,12 @@ read_contents (Lisp_Object state) ...@@ -3435,10 +3435,12 @@ read_contents (Lisp_Object state)
return make_number (nbytes); return make_number (nbytes);
} }
/* Condition-case handler used when reading files in insert-file-contents. */
/* Condition-case handler used when reading from non-regular files
in insert-file-contents. */
static Lisp_Object static Lisp_Object
read_contents_quit (Lisp_Object ignore) read_non_regular_quit (Lisp_Object ignore)
{ {
return Qnil; return Qnil;
} }
...@@ -3516,10 +3518,9 @@ by calling `format-decode', which see. */) ...@@ -3516,10 +3518,9 @@ by calling `format-decode', which see. */)
Lisp_Object p; Lisp_Object p;
ptrdiff_t total = 0; ptrdiff_t total = 0;
bool not_regular = 0; bool not_regular = 0;
int save_errno = 0, read_errno = 0; int save_errno = 0;
char read_buf[READ_BUF_SIZE]; char read_buf[READ_BUF_SIZE];
struct coding_system coding; struct coding_system coding;
char buffer[1 << 14];
bool replace_handled = 0; bool replace_handled = 0;
bool set_coding_system = 0; bool set_coding_system = 0;
Lisp_Object coding_system; Lisp_Object coding_system;
...@@ -3822,7 +3823,7 @@ by calling `format-decode', which see. */) ...@@ -3822,7 +3823,7 @@ by calling `format-decode', which see. */)
{ {
int nread, bufpos; int nread, bufpos;
nread = emacs_read (fd, buffer, sizeof buffer); nread = emacs_read (fd, read_buf, sizeof read_buf);
if (nread < 0) if (nread < 0)
error ("IO error reading %s: %s", error ("IO error reading %s: %s",
SSDATA (orig_filename), emacs_strerror (errno)); SSDATA (orig_filename), emacs_strerror (errno));
...@@ -3831,7 +3832,7 @@ by calling `format-decode', which see. */) ...@@ -3831,7 +3832,7 @@ by calling `format-decode', which see. */)
if (CODING_REQUIRE_DETECTION (&coding)) if (CODING_REQUIRE_DETECTION (&coding))
{ {
coding_system = detect_coding_system ((unsigned char *) buffer, coding_system = detect_coding_system ((unsigned char *) read_buf,
nread, nread, 1, 0, nread, nread, 1, 0,
coding_system); coding_system);
setup_coding_system (coding_system, &coding); setup_coding_system (coding_system, &coding);
...@@ -3847,7 +3848,7 @@ by calling `format-decode', which see. */) ...@@ -3847,7 +3848,7 @@ by calling `format-decode', which see. */)
bufpos = 0; bufpos = 0;
while (bufpos < nread && same_at_start < ZV_BYTE while (bufpos < nread && same_at_start < ZV_BYTE
&& FETCH_BYTE (same_at_start) == buffer[bufpos]) && FETCH_BYTE (same_at_start) == read_buf[bufpos])
same_at_start++, bufpos++; same_at_start++, bufpos++;
/* If we found a discrepancy, stop the scan. /* If we found a discrepancy, stop the scan.
Otherwise loop around and scan the next bufferful. */ Otherwise loop around and scan the next bufferful. */
...@@ -3881,7 +3882,7 @@ by calling `format-decode', which see. */) ...@@ -3881,7 +3882,7 @@ by calling `format-decode', which see. */)
if (curpos == 0) if (curpos == 0)
break; break;
/* How much can we scan in the next step? */ /* How much can we scan in the next step? */
trial = min (curpos, sizeof buffer); trial = min (curpos, sizeof read_buf);
if (lseek (fd, curpos - trial, SEEK_SET) < 0) if (lseek (fd, curpos - trial, SEEK_SET) < 0)
report_file_error ("Setting file position", report_file_error ("Setting file position",
Fcons (orig_filename, Qnil)); Fcons (orig_filename, Qnil));
...@@ -3889,7 +3890,7 @@ by calling `format-decode', which see. */) ...@@ -3889,7 +3890,7 @@ by calling `format-decode', which see. */)
total_read = nread = 0; total_read = nread = 0;
while (total_read < trial) while (total_read < trial)
{ {
nread = emacs_read (fd, buffer + total_read, trial - total_read); nread = emacs_read (fd, read_buf + total_read, trial - total_read);
if (nread < 0) if (nread < 0)
error ("IO error reading %s: %s", error ("IO error reading %s: %s",
SDATA (orig_filename), emacs_strerror (errno)); SDATA (orig_filename), emacs_strerror (errno));
...@@ -3905,7 +3906,7 @@ by calling `format-decode', which see. */) ...@@ -3905,7 +3906,7 @@ by calling `format-decode', which see. */)
/* Compare with same_at_start to avoid counting some buffer text /* Compare with same_at_start to avoid counting some buffer text
as matching both at the file's beginning and at the end. */ as matching both at the file's beginning and at the end. */
while (bufpos > 0 && same_at_end > same_at_start while (bufpos > 0 && same_at_end > same_at_start
&& FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1]) && FETCH_BYTE (same_at_end - 1) == read_buf[bufpos - 1])
same_at_end--, bufpos--; same_at_end--, bufpos--;
/* If we found a discrepancy, stop the scan. /* If we found a discrepancy, stop the scan.
...@@ -4197,68 +4198,85 @@ by calling `format-decode', which see. */) ...@@ -4197,68 +4198,85 @@ by calling `format-decode', which see. */)
Fcons (orig_filename, Qnil)); Fcons (orig_filename, Qnil));
} }
/* In the following loop, HOW_MUCH contains the total bytes read /* In the following loop, HOW_MUCH contains the total bytes read so
so far for a regular file, and not changed for a special file. */ far for a regular file, and not changed for a special file. But,
before exiting the loop, it is set to a negative value if I/O
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
decode_coding_gap after all data are read into the buffer, or decode_coding_gap after all data are read into the buffer. */
reading loop is interrupted with quit or due to I/O error. */ {
ptrdiff_t gap_size = GAP_SIZE;
while (how_much < total) while (how_much < total)
{ {
ptrdiff_t nread, maxread = min (total - how_much, READ_BUF_SIZE); /* try is reserved in some compilers (Microsoft C) */
Lisp_Object result; ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE);
ptrdiff_t this;
/* For a special file, gap is enlarged as we read,
so GAP_SIZE should be checked every time. */
if (not_regular && (GAP_SIZE < maxread))
make_gap (maxread - GAP_SIZE);
/* Read from the file, capturing `quit'. */
result = internal_condition_case_1
(read_contents,
make_save_value ("iii", (ptrdiff_t) fd, inserted, maxread),
Qerror, read_contents_quit);
if (NILP (result))
{
/* Quit is signaled. End the loop and arrange
real quit after decoding the text we read. */
read_quit = 1;
break;
}
nread = XINT (result);
if (nread <= 0)
{
/* End of file or I/O error. End the loop and
save error code in case of I/O error. */
if (nread < 0)
read_errno = errno;
break;
}
/* Adjust gap and end positions. */ if (not_regular)
GAP_SIZE -= nread; {
GPT += nread; Lisp_Object nbytes;
ZV += nread;
Z += nread; /* Maybe make more room. */
GPT_BYTE += nread; if (gap_size < trytry)
ZV_BYTE += nread; {
Z_BYTE += nread; make_gap (trytry - gap_size);
if (GAP_SIZE > 0) gap_size = GAP_SIZE - inserted;
*(GPT_ADDR) = 0; }
/* For a regular file, where TOTAL is the real size, count HOW_MUCH to /* Read from the file, capturing `quit'. When an
compare with it. For a special file, where TOTAL is just a buffer error occurs, end the loop, and arrange for a quit
size, don't bother counting in HOW_MUCH, but always accumulate the to be signaled after decoding the text we read. */
number of bytes read in INSERTED. */ nbytes = internal_condition_case_1
if (!not_regular) (read_non_regular,
how_much += nread; make_save_value ("iii", (ptrdiff_t) fd, inserted, trytry),
inserted += nread; Qerror, read_non_regular_quit);
}
if (NILP (nbytes))
{
read_quit = 1;
break;
}
this = XINT (nbytes);
}
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,
((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
+ 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;
}
}
/* Now we have either read all the file data into the gap, /* Now we have either read all the file data into the gap,
or stop reading on I/O error or quit. If nothing was or stop reading on I/O error or quit. If nothing was
...@@ -4280,6 +4298,23 @@ by calling `format-decode', which see. */) ...@@ -4280,6 +4298,23 @@ by calling `format-decode', which see. */)
/* Discard the unwind protect for closing the file. */ /* Discard the unwind protect for closing the file. */
specpdl_ptr--; specpdl_ptr--;
if (how_much < 0)
error ("IO error reading %s: %s",
SDATA (orig_filename), emacs_strerror (errno));
/* 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)
/* Put an anchor to ensure multi-byte form ends at gap. */
*GPT_ADDR = 0;
notfound: notfound:
if (NILP (coding_system)) if (NILP (coding_system))
...@@ -4568,15 +4603,10 @@ by calling `format-decode', which see. */) ...@@ -4568,15 +4603,10 @@ by calling `format-decode', which see. */)
report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
} }
/* There was an error reading file. */
if (read_errno)
error ("IO error reading %s: %s",
SDATA (orig_filename), emacs_strerror (read_errno));
/* Quit was signaled. */
if (read_quit) if (read_quit)
Fsignal (Qquit, Qnil); Fsignal (Qquit, Qnil);
/* Retval needs to be dealt with in all cases consistently. */
if (NILP (val)) if (NILP (val))
val = list2 (orig_filename, make_number (inserted)); val = list2 (orig_filename, make_number (inserted));
......
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