]> git.eshelyaron.com Git - emacs.git/commitdiff
(unwind_read): Function removed.
authorGerd Moellmann <gerd@gnu.org>
Mon, 16 Jul 2001 15:59:43 +0000 (15:59 +0000)
committerGerd Moellmann <gerd@gnu.org>
Mon, 16 Jul 2001 15:59:43 +0000 (15:59 +0000)
(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

index 0f05a465ab7835cead12339cdeb9a8628b648ba6..e09fac7e79bb2ede6a5f0b49559e7614a902ddc5 100644 (file)
@@ -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,