diff options
| author | Gerd Moellmann | 2001-07-16 15:59:43 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2001-07-16 15:59:43 +0000 |
| commit | 1b9781296a6c10ecc4e208ec14f1da742321aa65 (patch) | |
| tree | 6557a005c50ee99a8a3681932a0497f3056b9f63 /src | |
| parent | 9d5ceccb356da638fee6bc9ccdfa688ce61164b9 (diff) | |
| download | emacs-1b9781296a6c10ecc4e208ec14f1da742321aa65.tar.gz emacs-1b9781296a6c10ecc4e208ec14f1da742321aa65.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 193 |
1 files changed, 104 insertions, 89 deletions
diff --git a/src/fileio.c b/src/fileio.c index 0f05a465ab7..e09fac7e79b 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -3419,61 +3419,40 @@ decide_coding_unwind (unwind_data) | |||
| 3419 | } | 3419 | } |
| 3420 | 3420 | ||
| 3421 | 3421 | ||
| 3422 | /* Unwind-function for reading from a file in insert-file-contents. | 3422 | /* Used to pass values from insert-file-contents to read_non_regular. */ |
| 3423 | 3423 | ||
| 3424 | INSERTED_BYTES is the number of bytes successfully inserted into | 3424 | static int non_regular_fd; |
| 3425 | current_buffer. | 3425 | static int non_regular_inserted; |
| 3426 | static int non_regular_nbytes; | ||
| 3426 | 3427 | ||
| 3427 | When reading is interrupted by C-g, this leaves the newly read part | ||
| 3428 | of the current buffer undecoded. If this happens in a multibyte | ||
| 3429 | buffer, prevent invalid characters by either discarding what has | ||
| 3430 | been read or switching the buffer to unibyte. | ||
| 3431 | 3428 | ||
| 3432 | PT GPT | 3429 | /* Read from a non-regular file. |
| 3433 | +-----------------------------------------------------+ | 3430 | Read non_regular_trytry bytes max from non_regular_fd. |
| 3434 | | | inserted bytes | GAP_SIZE | | | 3431 | Non_regular_inserted specifies where to put the read bytes. |
| 3435 | +-----------------------------------------------------+ | 3432 | Value is the number of bytes read. */ |
| 3436 | \ / | ||
| 3437 | +--------- the gap ---------+ */ | ||
| 3438 | 3433 | ||
| 3439 | static Lisp_Object | 3434 | static Lisp_Object |
| 3440 | unwind_read (inserted_bytes) | 3435 | read_non_regular () |
| 3441 | Lisp_Object inserted_bytes; | ||
| 3442 | { | 3436 | { |
| 3443 | if (!NILP (current_buffer->enable_multibyte_characters)) | 3437 | int nbytes; |
| 3444 | { | 3438 | |
| 3445 | int nbytes = XINT (inserted_bytes); | 3439 | immediate_quit = 1; |
| 3446 | Lisp_Object args[3]; | 3440 | QUIT; |
| 3447 | char *action; | 3441 | nbytes = emacs_read (non_regular_fd, |
| 3442 | BEG_ADDR + PT_BYTE - 1 + non_regular_inserted, | ||
| 3443 | non_regular_nbytes); | ||
| 3444 | Fsignal (Qquit, Qnil); | ||
| 3445 | immediate_quit = 0; | ||
| 3446 | return make_number (nbytes); | ||
| 3447 | } | ||
| 3448 | 3448 | ||
| 3449 | if (Z == nbytes) | ||
| 3450 | { | ||
| 3451 | /* Buffer was previously empty. Switch it to unibyte | ||
| 3452 | because newly inserted text is not decoded. */ | ||
| 3453 | current_buffer->enable_multibyte_characters = Qnil; | ||
| 3454 | action = "buffer made unibyte"; | ||
| 3455 | } | ||
| 3456 | else | ||
| 3457 | { | ||
| 3458 | ZV -= nbytes; | ||
| 3459 | ZV_BYTE -= nbytes; | ||
| 3460 | Z -= nbytes; | ||
| 3461 | Z_BYTE -= nbytes; | ||
| 3462 | |||
| 3463 | GPT = PT; | ||
| 3464 | GPT_BYTE = PT_BYTE; | ||
| 3465 | GAP_SIZE = nbytes + GAP_SIZE; | ||
| 3466 | |||
| 3467 | action = "no text inserted"; | ||
| 3468 | } | ||
| 3469 | 3449 | ||
| 3470 | 3450 | /* Condition-case handler used when reading from non-regular files | |
| 3471 | args[0] = build_string ("Quit while inserting text in buffer `%s': %s"); | 3451 | in insert-file-contents. */ |
| 3472 | args[1] = current_buffer->name; | 3452 | |
| 3473 | args[2] = build_string (action); | 3453 | static Lisp_Object |
| 3474 | Fmessage (3, args); | 3454 | read_non_regular_quit () |
| 3475 | } | 3455 | { |
| 3476 | |||
| 3477 | return Qnil; | 3456 | return Qnil; |
| 3478 | } | 3457 | } |
| 3479 | 3458 | ||
| @@ -3523,6 +3502,8 @@ actually used.") | |||
| 3523 | int replace_handled = 0; | 3502 | int replace_handled = 0; |
| 3524 | int set_coding_system = 0; | 3503 | int set_coding_system = 0; |
| 3525 | int coding_system_decided = 0; | 3504 | int coding_system_decided = 0; |
| 3505 | int gap_size; | ||
| 3506 | int read_quit = 0; | ||
| 3526 | 3507 | ||
| 3527 | if (current_buffer->base_buffer && ! NILP (visit)) | 3508 | if (current_buffer->base_buffer && ! NILP (visit)) |
| 3528 | error ("Cannot do file visiting in an indirect buffer"); | 3509 | error ("Cannot do file visiting in an indirect buffer"); |
| @@ -4182,55 +4163,86 @@ actually used.") | |||
| 4182 | before exiting the loop, it is set to a negative value if I/O | 4163 | before exiting the loop, it is set to a negative value if I/O |
| 4183 | error occurs. */ | 4164 | error occurs. */ |
| 4184 | how_much = 0; | 4165 | how_much = 0; |
| 4166 | |||
| 4185 | /* Total bytes inserted. */ | 4167 | /* Total bytes inserted. */ |
| 4186 | inserted = 0; | 4168 | inserted = 0; |
| 4169 | |||
| 4187 | /* Here, we don't do code conversion in the loop. It is done by | 4170 | /* Here, we don't do code conversion in the loop. It is done by |
| 4188 | code_convert_region after all data are read into the buffer. */ | 4171 | code_convert_region after all data are read into the buffer. */ |
| 4189 | while (how_much < total) | 4172 | { |
| 4190 | { | 4173 | int gap_size = GAP_SIZE; |
| 4174 | |||
| 4175 | while (how_much < total) | ||
| 4176 | { | ||
| 4191 | /* try is reserved in some compilers (Microsoft C) */ | 4177 | /* try is reserved in some compilers (Microsoft C) */ |
| 4192 | int trytry = min (total - how_much, READ_BUF_SIZE); | 4178 | int trytry = min (total - how_much, READ_BUF_SIZE); |
| 4193 | int this; | 4179 | int this; |
| 4194 | int count = BINDING_STACK_SIZE (); | ||
| 4195 | |||
| 4196 | /* For a special file, GAP_SIZE should be checked every time. */ | ||
| 4197 | if (not_regular && GAP_SIZE < trytry) | ||
| 4198 | make_gap (total - GAP_SIZE); | ||
| 4199 | |||
| 4200 | /* Allow quitting out of the actual I/O. If a C-g interrupts | ||
| 4201 | this, make sure that no invalid characters remain | ||
| 4202 | in the undecoded part read. */ | ||
| 4203 | record_unwind_protect (unwind_read, make_number (inserted)); | ||
| 4204 | immediate_quit = 1; | ||
| 4205 | QUIT; | ||
| 4206 | this = emacs_read (fd, BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1, | ||
| 4207 | trytry); | ||
| 4208 | immediate_quit = 0; | ||
| 4209 | --specpdl_ptr; | ||
| 4210 | 4180 | ||
| 4211 | if (this <= 0) | 4181 | if (not_regular) |
| 4212 | { | 4182 | { |
| 4213 | how_much = this; | 4183 | Lisp_Object val; |
| 4214 | break; | ||
| 4215 | } | ||
| 4216 | 4184 | ||
| 4217 | GAP_SIZE -= this; | 4185 | /* Maybe make more room. */ |
| 4218 | GPT_BYTE += this; | 4186 | if (gap_size < trytry) |
| 4219 | ZV_BYTE += this; | 4187 | { |
| 4220 | Z_BYTE += this; | 4188 | make_gap (total - gap_size); |
| 4221 | GPT += this; | 4189 | gap_size = GAP_SIZE; |
| 4222 | ZV += this; | 4190 | } |
| 4223 | Z += this; | 4191 | |
| 4224 | 4192 | /* Read from the file, capturing `quit'. When an | |
| 4225 | /* For a regular file, where TOTAL is the real size, | 4193 | error occurs, end the loop, and arrange for a quit |
| 4226 | count HOW_MUCH to compare with it. | 4194 | to be signaled after decoding the text we read. */ |
| 4227 | For a special file, where TOTAL is just a buffer size, | 4195 | non_regular_fd = fd; |
| 4228 | so don't bother counting in HOW_MUCH. | 4196 | non_regular_inserted = inserted; |
| 4229 | (INSERTED is where we count the number of characters inserted.) */ | 4197 | non_regular_nbytes = trytry; |
| 4230 | if (! not_regular) | 4198 | val = internal_condition_case_1 (read_non_regular, Qnil, Qerror, |
| 4231 | how_much += this; | 4199 | read_non_regular_quit); |
| 4232 | inserted += this; | 4200 | if (NILP (val)) |
| 4233 | } | 4201 | { |
| 4202 | read_quit = 1; | ||
| 4203 | break; | ||
| 4204 | } | ||
| 4205 | |||
| 4206 | this = XINT (val); | ||
| 4207 | } | ||
| 4208 | else | ||
| 4209 | { | ||
| 4210 | /* Allow quitting out of the actual I/O. We don't make text | ||
| 4211 | part of the buffer until all the reading is done, so a C-g | ||
| 4212 | here doesn't do any harm. */ | ||
| 4213 | immediate_quit = 1; | ||
| 4214 | QUIT; | ||
| 4215 | this = emacs_read (fd, BEG_ADDR + PT_BYTE - 1 + inserted, trytry); | ||
| 4216 | immediate_quit = 0; | ||
| 4217 | } | ||
| 4218 | |||
| 4219 | if (this <= 0) | ||
| 4220 | { | ||
| 4221 | how_much = this; | ||
| 4222 | break; | ||
| 4223 | } | ||
| 4224 | |||
| 4225 | gap_size -= this; | ||
| 4226 | |||
| 4227 | /* For a regular file, where TOTAL is the real size, | ||
| 4228 | count HOW_MUCH to compare with it. | ||
| 4229 | For a special file, where TOTAL is just a buffer size, | ||
| 4230 | so don't bother counting in HOW_MUCH. | ||
| 4231 | (INSERTED is where we count the number of characters inserted.) */ | ||
| 4232 | if (! not_regular) | ||
| 4233 | how_much += this; | ||
| 4234 | inserted += this; | ||
| 4235 | } | ||
| 4236 | } | ||
| 4237 | |||
| 4238 | /* Make the text read part of the buffer. */ | ||
| 4239 | GAP_SIZE -= inserted; | ||
| 4240 | GPT += inserted; | ||
| 4241 | GPT_BYTE += inserted; | ||
| 4242 | ZV += inserted; | ||
| 4243 | ZV_BYTE += inserted; | ||
| 4244 | Z += inserted; | ||
| 4245 | Z_BYTE += inserted; | ||
| 4234 | 4246 | ||
| 4235 | if (GAP_SIZE > 0) | 4247 | if (GAP_SIZE > 0) |
| 4236 | /* Put an anchor to ensure multi-byte form ends at gap. */ | 4248 | /* Put an anchor to ensure multi-byte form ends at gap. */ |
| @@ -4446,6 +4458,9 @@ actually used.") | |||
| 4446 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); | 4458 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); |
| 4447 | } | 4459 | } |
| 4448 | 4460 | ||
| 4461 | if (read_quit) | ||
| 4462 | Fsignal (Qquit, Qnil); | ||
| 4463 | |||
| 4449 | /* ??? Retval needs to be dealt with in all cases consistently. */ | 4464 | /* ??? Retval needs to be dealt with in all cases consistently. */ |
| 4450 | if (NILP (val)) | 4465 | if (NILP (val)) |
| 4451 | val = Fcons (orig_filename, | 4466 | val = Fcons (orig_filename, |