diff options
| author | Dmitry Antipov | 2013-01-21 21:01:09 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2013-01-21 21:01:09 +0400 |
| commit | 2ef88fd45c8653fa3f175a3eb9c8e61088587a5e (patch) | |
| tree | 6d7d1918f1c6eb2e0080e35deaa648f15500007b /src | |
| parent | 7fd5a8435ff717b5b49832a96bc2575e46976ddf (diff) | |
| download | emacs-2ef88fd45c8653fa3f175a3eb9c8e61088587a5e.tar.gz emacs-2ef88fd45c8653fa3f175a3eb9c8e61088587a5e.zip | |
* 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/fileio.c | 176 |
2 files changed, 110 insertions, 73 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 1383b12ed68..658febcd21c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2013-01-21 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | * fileio.c (Finsert_file_contents): Revert code introduced at | ||
| 4 | 2013-01-18 in favor of the simpler and generally better fix. | ||
| 5 | Save stack space by removing 'buffer' and reusing 'read_buf' | ||
| 6 | where appropriate. | ||
| 7 | |||
| 1 | 2013-01-19 Paul Eggert <eggert@cs.ucla.edu> | 8 | 2013-01-19 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 9 | ||
| 3 | * lisp.h (eabs): Define unconditionally (Bug#13419). | 10 | * lisp.h (eabs): Define unconditionally (Bug#13419). |
diff --git a/src/fileio.c b/src/fileio.c index 51f966787b9..175f363ec92 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -3413,13 +3413,13 @@ decide_coding_unwind (Lisp_Object unwind_data) | |||
| 3413 | return Qnil; | 3413 | return Qnil; |
| 3414 | } | 3414 | } |
| 3415 | 3415 | ||
| 3416 | /* Check quit and read from the file. STATE is a Lisp_Save_Value | 3416 | /* Read from a non-regular file. STATE is a Lisp_Save_Value |
| 3417 | object where slot 0 is the file descriptor, slot 1 specifies | 3417 | object where slot 0 is the file descriptor, slot 1 specifies |
| 3418 | an offset to put the read bytes, and slot 2 is the maximum | 3418 | an offset to put the read bytes, and slot 2 is the maximum |
| 3419 | amount of bytes to read. Value is the number of bytes read. */ | 3419 | amount of bytes to read. Value is the number of bytes read. */ |
| 3420 | 3420 | ||
| 3421 | static Lisp_Object | 3421 | static Lisp_Object |
| 3422 | read_contents (Lisp_Object state) | 3422 | read_non_regular (Lisp_Object state) |
| 3423 | { | 3423 | { |
| 3424 | int nbytes; | 3424 | int nbytes; |
| 3425 | 3425 | ||
| @@ -3435,10 +3435,12 @@ read_contents (Lisp_Object state) | |||
| 3435 | return make_number (nbytes); | 3435 | return make_number (nbytes); |
| 3436 | } | 3436 | } |
| 3437 | 3437 | ||
| 3438 | /* Condition-case handler used when reading files in insert-file-contents. */ | 3438 | |
| 3439 | /* Condition-case handler used when reading from non-regular files | ||
| 3440 | in insert-file-contents. */ | ||
| 3439 | 3441 | ||
| 3440 | static Lisp_Object | 3442 | static Lisp_Object |
| 3441 | read_contents_quit (Lisp_Object ignore) | 3443 | read_non_regular_quit (Lisp_Object ignore) |
| 3442 | { | 3444 | { |
| 3443 | return Qnil; | 3445 | return Qnil; |
| 3444 | } | 3446 | } |
| @@ -3516,10 +3518,9 @@ by calling `format-decode', which see. */) | |||
| 3516 | Lisp_Object p; | 3518 | Lisp_Object p; |
| 3517 | ptrdiff_t total = 0; | 3519 | ptrdiff_t total = 0; |
| 3518 | bool not_regular = 0; | 3520 | bool not_regular = 0; |
| 3519 | int save_errno = 0, read_errno = 0; | 3521 | int save_errno = 0; |
| 3520 | char read_buf[READ_BUF_SIZE]; | 3522 | char read_buf[READ_BUF_SIZE]; |
| 3521 | struct coding_system coding; | 3523 | struct coding_system coding; |
| 3522 | char buffer[1 << 14]; | ||
| 3523 | bool replace_handled = 0; | 3524 | bool replace_handled = 0; |
| 3524 | bool set_coding_system = 0; | 3525 | bool set_coding_system = 0; |
| 3525 | Lisp_Object coding_system; | 3526 | Lisp_Object coding_system; |
| @@ -3822,7 +3823,7 @@ by calling `format-decode', which see. */) | |||
| 3822 | { | 3823 | { |
| 3823 | int nread, bufpos; | 3824 | int nread, bufpos; |
| 3824 | 3825 | ||
| 3825 | nread = emacs_read (fd, buffer, sizeof buffer); | 3826 | nread = emacs_read (fd, read_buf, sizeof read_buf); |
| 3826 | if (nread < 0) | 3827 | if (nread < 0) |
| 3827 | error ("IO error reading %s: %s", | 3828 | error ("IO error reading %s: %s", |
| 3828 | SSDATA (orig_filename), emacs_strerror (errno)); | 3829 | SSDATA (orig_filename), emacs_strerror (errno)); |
| @@ -3831,7 +3832,7 @@ by calling `format-decode', which see. */) | |||
| 3831 | 3832 | ||
| 3832 | if (CODING_REQUIRE_DETECTION (&coding)) | 3833 | if (CODING_REQUIRE_DETECTION (&coding)) |
| 3833 | { | 3834 | { |
| 3834 | coding_system = detect_coding_system ((unsigned char *) buffer, | 3835 | coding_system = detect_coding_system ((unsigned char *) read_buf, |
| 3835 | nread, nread, 1, 0, | 3836 | nread, nread, 1, 0, |
| 3836 | coding_system); | 3837 | coding_system); |
| 3837 | setup_coding_system (coding_system, &coding); | 3838 | setup_coding_system (coding_system, &coding); |
| @@ -3847,7 +3848,7 @@ by calling `format-decode', which see. */) | |||
| 3847 | 3848 | ||
| 3848 | bufpos = 0; | 3849 | bufpos = 0; |
| 3849 | while (bufpos < nread && same_at_start < ZV_BYTE | 3850 | while (bufpos < nread && same_at_start < ZV_BYTE |
| 3850 | && FETCH_BYTE (same_at_start) == buffer[bufpos]) | 3851 | && FETCH_BYTE (same_at_start) == read_buf[bufpos]) |
| 3851 | same_at_start++, bufpos++; | 3852 | same_at_start++, bufpos++; |
| 3852 | /* If we found a discrepancy, stop the scan. | 3853 | /* If we found a discrepancy, stop the scan. |
| 3853 | Otherwise loop around and scan the next bufferful. */ | 3854 | Otherwise loop around and scan the next bufferful. */ |
| @@ -3881,7 +3882,7 @@ by calling `format-decode', which see. */) | |||
| 3881 | if (curpos == 0) | 3882 | if (curpos == 0) |
| 3882 | break; | 3883 | break; |
| 3883 | /* How much can we scan in the next step? */ | 3884 | /* How much can we scan in the next step? */ |
| 3884 | trial = min (curpos, sizeof buffer); | 3885 | trial = min (curpos, sizeof read_buf); |
| 3885 | if (lseek (fd, curpos - trial, SEEK_SET) < 0) | 3886 | if (lseek (fd, curpos - trial, SEEK_SET) < 0) |
| 3886 | report_file_error ("Setting file position", | 3887 | report_file_error ("Setting file position", |
| 3887 | Fcons (orig_filename, Qnil)); | 3888 | Fcons (orig_filename, Qnil)); |
| @@ -3889,7 +3890,7 @@ by calling `format-decode', which see. */) | |||
| 3889 | total_read = nread = 0; | 3890 | total_read = nread = 0; |
| 3890 | while (total_read < trial) | 3891 | while (total_read < trial) |
| 3891 | { | 3892 | { |
| 3892 | nread = emacs_read (fd, buffer + total_read, trial - total_read); | 3893 | nread = emacs_read (fd, read_buf + total_read, trial - total_read); |
| 3893 | if (nread < 0) | 3894 | if (nread < 0) |
| 3894 | error ("IO error reading %s: %s", | 3895 | error ("IO error reading %s: %s", |
| 3895 | SDATA (orig_filename), emacs_strerror (errno)); | 3896 | SDATA (orig_filename), emacs_strerror (errno)); |
| @@ -3905,7 +3906,7 @@ by calling `format-decode', which see. */) | |||
| 3905 | /* Compare with same_at_start to avoid counting some buffer text | 3906 | /* Compare with same_at_start to avoid counting some buffer text |
| 3906 | as matching both at the file's beginning and at the end. */ | 3907 | as matching both at the file's beginning and at the end. */ |
| 3907 | while (bufpos > 0 && same_at_end > same_at_start | 3908 | while (bufpos > 0 && same_at_end > same_at_start |
| 3908 | && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1]) | 3909 | && FETCH_BYTE (same_at_end - 1) == read_buf[bufpos - 1]) |
| 3909 | same_at_end--, bufpos--; | 3910 | same_at_end--, bufpos--; |
| 3910 | 3911 | ||
| 3911 | /* If we found a discrepancy, stop the scan. | 3912 | /* If we found a discrepancy, stop the scan. |
| @@ -4197,68 +4198,85 @@ by calling `format-decode', which see. */) | |||
| 4197 | Fcons (orig_filename, Qnil)); | 4198 | Fcons (orig_filename, Qnil)); |
| 4198 | } | 4199 | } |
| 4199 | 4200 | ||
| 4200 | /* In the following loop, HOW_MUCH contains the total bytes read | 4201 | /* In the following loop, HOW_MUCH contains the total bytes read so |
| 4201 | so far for a regular file, and not changed for a special file. */ | 4202 | far for a regular file, and not changed for a special file. But, |
| 4203 | before exiting the loop, it is set to a negative value if I/O | ||
| 4204 | error occurs. */ | ||
| 4202 | how_much = 0; | 4205 | how_much = 0; |
| 4203 | 4206 | ||
| 4204 | /* Total bytes inserted. */ | 4207 | /* Total bytes inserted. */ |
| 4205 | inserted = 0; | 4208 | inserted = 0; |
| 4206 | 4209 | ||
| 4207 | /* Here we don't do code conversion in the loop. It is done by | 4210 | /* Here, we don't do code conversion in the loop. It is done by |
| 4208 | decode_coding_gap after all data are read into the buffer, or | 4211 | decode_coding_gap after all data are read into the buffer. */ |
| 4209 | reading loop is interrupted with quit or due to I/O error. */ | 4212 | { |
| 4213 | ptrdiff_t gap_size = GAP_SIZE; | ||
| 4210 | 4214 | ||
| 4211 | while (how_much < total) | 4215 | while (how_much < total) |
| 4212 | { | 4216 | { |
| 4213 | ptrdiff_t nread, maxread = min (total - how_much, READ_BUF_SIZE); | 4217 | /* try is reserved in some compilers (Microsoft C) */ |
| 4214 | Lisp_Object result; | 4218 | ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE); |
| 4215 | 4219 | ptrdiff_t this; | |
| 4216 | /* For a special file, gap is enlarged as we read, | ||
| 4217 | so GAP_SIZE should be checked every time. */ | ||
| 4218 | if (not_regular && (GAP_SIZE < maxread)) | ||
| 4219 | make_gap (maxread - GAP_SIZE); | ||
| 4220 | |||
| 4221 | /* Read from the file, capturing `quit'. */ | ||
| 4222 | result = internal_condition_case_1 | ||
| 4223 | (read_contents, | ||
| 4224 | make_save_value ("iii", (ptrdiff_t) fd, inserted, maxread), | ||
| 4225 | Qerror, read_contents_quit); | ||
| 4226 | if (NILP (result)) | ||
| 4227 | { | ||
| 4228 | /* Quit is signaled. End the loop and arrange | ||
| 4229 | real quit after decoding the text we read. */ | ||
| 4230 | read_quit = 1; | ||
| 4231 | break; | ||
| 4232 | } | ||
| 4233 | nread = XINT (result); | ||
| 4234 | if (nread <= 0) | ||
| 4235 | { | ||
| 4236 | /* End of file or I/O error. End the loop and | ||
| 4237 | save error code in case of I/O error. */ | ||
| 4238 | if (nread < 0) | ||
| 4239 | read_errno = errno; | ||
| 4240 | break; | ||
| 4241 | } | ||
| 4242 | 4220 | ||
| 4243 | /* Adjust gap and end positions. */ | 4221 | if (not_regular) |
| 4244 | GAP_SIZE -= nread; | 4222 | { |
| 4245 | GPT += nread; | 4223 | Lisp_Object nbytes; |
| 4246 | ZV += nread; | 4224 | |
| 4247 | Z += nread; | 4225 | /* Maybe make more room. */ |
| 4248 | GPT_BYTE += nread; | 4226 | if (gap_size < trytry) |
| 4249 | ZV_BYTE += nread; | 4227 | { |
| 4250 | Z_BYTE += nread; | 4228 | make_gap (trytry - gap_size); |
| 4251 | if (GAP_SIZE > 0) | 4229 | gap_size = GAP_SIZE - inserted; |
| 4252 | *(GPT_ADDR) = 0; | 4230 | } |
| 4253 | 4231 | ||
| 4254 | /* For a regular file, where TOTAL is the real size, count HOW_MUCH to | 4232 | /* Read from the file, capturing `quit'. When an |
| 4255 | compare with it. For a special file, where TOTAL is just a buffer | 4233 | error occurs, end the loop, and arrange for a quit |
| 4256 | size, don't bother counting in HOW_MUCH, but always accumulate the | 4234 | to be signaled after decoding the text we read. */ |
| 4257 | number of bytes read in INSERTED. */ | 4235 | nbytes = internal_condition_case_1 |
| 4258 | if (!not_regular) | 4236 | (read_non_regular, |
| 4259 | how_much += nread; | 4237 | make_save_value ("iii", (ptrdiff_t) fd, inserted, trytry), |
| 4260 | inserted += nread; | 4238 | Qerror, read_non_regular_quit); |
| 4261 | } | 4239 | |
| 4240 | if (NILP (nbytes)) | ||
| 4241 | { | ||
| 4242 | read_quit = 1; | ||
| 4243 | break; | ||
| 4244 | } | ||
| 4245 | |||
| 4246 | this = XINT (nbytes); | ||
| 4247 | } | ||
| 4248 | else | ||
| 4249 | { | ||
| 4250 | /* Allow quitting out of the actual I/O. We don't make text | ||
| 4251 | part of the buffer until all the reading is done, so a C-g | ||
| 4252 | here doesn't do any harm. */ | ||
| 4253 | immediate_quit = 1; | ||
| 4254 | QUIT; | ||
| 4255 | this = emacs_read (fd, | ||
| 4256 | ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE | ||
| 4257 | + inserted), | ||
| 4258 | trytry); | ||
| 4259 | immediate_quit = 0; | ||
| 4260 | } | ||
| 4261 | |||
| 4262 | if (this <= 0) | ||
| 4263 | { | ||
| 4264 | how_much = this; | ||
| 4265 | break; | ||
| 4266 | } | ||
| 4267 | |||
| 4268 | gap_size -= this; | ||
| 4269 | |||
| 4270 | /* For a regular file, where TOTAL is the real size, | ||
| 4271 | count HOW_MUCH to compare with it. | ||
| 4272 | For a special file, where TOTAL is just a buffer size, | ||
| 4273 | so don't bother counting in HOW_MUCH. | ||
| 4274 | (INSERTED is where we count the number of characters inserted.) */ | ||
| 4275 | if (! not_regular) | ||
| 4276 | how_much += this; | ||
| 4277 | inserted += this; | ||
| 4278 | } | ||
| 4279 | } | ||
| 4262 | 4280 | ||
| 4263 | /* Now we have either read all the file data into the gap, | 4281 | /* Now we have either read all the file data into the gap, |
| 4264 | or stop reading on I/O error or quit. If nothing was | 4282 | or stop reading on I/O error or quit. If nothing was |
| @@ -4280,6 +4298,23 @@ by calling `format-decode', which see. */) | |||
| 4280 | /* Discard the unwind protect for closing the file. */ | 4298 | /* Discard the unwind protect for closing the file. */ |
| 4281 | specpdl_ptr--; | 4299 | specpdl_ptr--; |
| 4282 | 4300 | ||
| 4301 | if (how_much < 0) | ||
| 4302 | error ("IO error reading %s: %s", | ||
| 4303 | SDATA (orig_filename), emacs_strerror (errno)); | ||
| 4304 | |||
| 4305 | /* Make the text read part of the buffer. */ | ||
| 4306 | GAP_SIZE -= inserted; | ||
| 4307 | GPT += inserted; | ||
| 4308 | GPT_BYTE += inserted; | ||
| 4309 | ZV += inserted; | ||
| 4310 | ZV_BYTE += inserted; | ||
| 4311 | Z += inserted; | ||
| 4312 | Z_BYTE += inserted; | ||
| 4313 | |||
| 4314 | if (GAP_SIZE > 0) | ||
| 4315 | /* Put an anchor to ensure multi-byte form ends at gap. */ | ||
| 4316 | *GPT_ADDR = 0; | ||
| 4317 | |||
| 4283 | notfound: | 4318 | notfound: |
| 4284 | 4319 | ||
| 4285 | if (NILP (coding_system)) | 4320 | if (NILP (coding_system)) |
| @@ -4568,15 +4603,10 @@ by calling `format-decode', which see. */) | |||
| 4568 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); | 4603 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); |
| 4569 | } | 4604 | } |
| 4570 | 4605 | ||
| 4571 | /* There was an error reading file. */ | ||
| 4572 | if (read_errno) | ||
| 4573 | error ("IO error reading %s: %s", | ||
| 4574 | SDATA (orig_filename), emacs_strerror (read_errno)); | ||
| 4575 | |||
| 4576 | /* Quit was signaled. */ | ||
| 4577 | if (read_quit) | 4606 | if (read_quit) |
| 4578 | Fsignal (Qquit, Qnil); | 4607 | Fsignal (Qquit, Qnil); |
| 4579 | 4608 | ||
| 4609 | /* Retval needs to be dealt with in all cases consistently. */ | ||
| 4580 | if (NILP (val)) | 4610 | if (NILP (val)) |
| 4581 | val = list2 (orig_filename, make_number (inserted)); | 4611 | val = list2 (orig_filename, make_number (inserted)); |
| 4582 | 4612 | ||