From 1b9781296a6c10ecc4e208ec14f1da742321aa65 Mon Sep 17 00:00:00 2001 From: Gerd Moellmann Date: Mon, 16 Jul 2001 15:59:43 +0000 Subject: [PATCH] (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. --- src/fileio.c | 193 +++++++++++++++++++++++++++------------------------ 1 file 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) } -/* 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 - current_buffer. +static int non_regular_fd; +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 - +-----------------------------------------------------+ - | | inserted bytes | GAP_SIZE | | - +-----------------------------------------------------+ - \ / - +--------- the gap ---------+ */ +/* Read from a non-regular file. + Read non_regular_trytry bytes max from non_regular_fd. + Non_regular_inserted specifies where to put the read bytes. + Value is the number of bytes read. */ static Lisp_Object -unwind_read (inserted_bytes) - Lisp_Object inserted_bytes; +read_non_regular () { - if (!NILP (current_buffer->enable_multibyte_characters)) - { - int nbytes = XINT (inserted_bytes); - Lisp_Object args[3]; - char *action; + int nbytes; + + immediate_quit = 1; + QUIT; + 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"; - } - - args[0] = build_string ("Quit while inserting text in buffer `%s': %s"); - args[1] = current_buffer->name; - args[2] = build_string (action); - Fmessage (3, args); - } - +/* Condition-case handler used when reading from non-regular files + in insert-file-contents. */ + +static Lisp_Object +read_non_regular_quit () +{ return Qnil; } @@ -3523,6 +3502,8 @@ actually used.") int replace_handled = 0; int set_coding_system = 0; int coding_system_decided = 0; + int gap_size; + int read_quit = 0; if (current_buffer->base_buffer && ! NILP (visit)) error ("Cannot do file visiting in an indirect buffer"); @@ -4182,55 +4163,86 @@ actually used.") before exiting the loop, it is set to a negative value if I/O error occurs. */ how_much = 0; + /* Total bytes inserted. */ inserted = 0; + /* 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. */ - while (how_much < total) - { + { + int gap_size = GAP_SIZE; + + while (how_much < total) + { /* try is reserved in some compilers (Microsoft C) */ - int trytry = min (total - how_much, READ_BUF_SIZE); - 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; + int trytry = min (total - how_much, READ_BUF_SIZE); + int this; - if (this <= 0) - { - how_much = this; - break; - } + if (not_regular) + { + Lisp_Object val; - GAP_SIZE -= this; - GPT_BYTE += this; - ZV_BYTE += this; - Z_BYTE += this; - GPT += this; - ZV += this; - Z += 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; - } + /* Maybe make more room. */ + if (gap_size < trytry) + { + make_gap (total - gap_size); + gap_size = GAP_SIZE; + } + + /* Read from the file, capturing `quit'. When an + error occurs, end the loop, and arrange for a quit + to be signaled after decoding the text we read. */ + non_regular_fd = fd; + non_regular_inserted = inserted; + non_regular_nbytes = trytry; + val = internal_condition_case_1 (read_non_regular, Qnil, Qerror, + read_non_regular_quit); + 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) /* Put an anchor to ensure multi-byte form ends at gap. */ @@ -4446,6 +4458,9 @@ actually used.") 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. */ if (NILP (val)) val = Fcons (orig_filename, -- 2.39.5