diff options
author | Gerd Moellmann <gerd@gnu.org> | 2001-07-11 12:04:09 +0000 |
---|---|---|
committer | Gerd Moellmann <gerd@gnu.org> | 2001-07-11 12:04:09 +0000 |
commit | 55587f8a5c6a4588946e13fc70db006d2bdaf51a (patch) | |
tree | 7da9cbfedc97ad5e2fe4da37721adb7510e0a44e | |
parent | 0b725d8cbd58f8b27dc808c9310c441a7fa6bcfd (diff) | |
download | emacs-55587f8a5c6a4588946e13fc70db006d2bdaf51a.tar.gz |
(unwind_read): New function.
(Finsert_file_contents): Record it as unwind-function for
the case that reading is interrupted by C-g.
-rw-r--r-- | src/fileio.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/src/fileio.c b/src/fileio.c index 9987cbfd343..becdc9ce008 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3418,6 +3418,53 @@ decide_coding_unwind (unwind_data) return Qnil; } + +/* Unwind-function for reading from a file in insert-file-contents. + + INFO is a pair (INSERTED-BYTES . VISIT). INSERTED-BYTES is the + number of bytes successfully inserted into current_buffer. VISIT + is the same as the parameter VISIT Of insert-file-contents. + + 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 ---------+ */ + +static Lisp_Object +unwind_read (info) + Lisp_Object info; +{ + if (!NILP (current_buffer->enable_multibyte_characters)) + { + int nbytes = XINT (XCAR (info)); + int visit = !NILP (XCDR (info)); + + if (visit || Z == nbytes) + current_buffer->enable_multibyte_characters = Qnil; + else + { + ZV -= nbytes; + ZV_BYTE -= nbytes; + Z -= nbytes; + Z_BYTE -= nbytes; + + GPT = PT; + GPT_BYTE = PT_BYTE; + GAP_SIZE = nbytes + GAP_SIZE; + } + } + + return Qnil; +} + + DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, 1, 5, 0, "Insert contents of file FILENAME after point.\n\ @@ -4131,17 +4178,22 @@ actually used.") /* 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. */ + /* Allow quitting out of the actual I/O. If we do, + remove 's */ + record_unwind_protect (unwind_read, + Fcons (make_number (inserted), visit)); 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) { |