emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-27 224e8d1: Make call_process call signal_after_change. This fixes


From: Alan Mackenzie
Subject: emacs-27 224e8d1: Make call_process call signal_after_change. This fixes bug #38691.
Date: Wed, 22 Jan 2020 14:53:26 -0500 (EST)

branch: emacs-27
commit 224e8d146485ce178086549d41fa8359dcc0e03e
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>

    Make call_process call signal_after_change.  This fixes bug #38691.
    
    Now, functions such as call-proess-region invoke after-change-functions
    correctly.
    
    * src/callproc.c (call_process): Call prepare_to_modify_buffer in a single
    place, no longer delegating the task to insert_1_both, etc.  Call
    signal_after_change in each of two code branches, such that
    before-change-functions and after-change-functions are always called in
    balanced pairs.
---
 src/callproc.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/callproc.c b/src/callproc.c
index 52b8950..6bd4ae2 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -746,6 +746,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
       int carryover = 0;
       bool display_on_the_fly = display_p;
       struct coding_system saved_coding = process_coding;
+      ptrdiff_t prepared_pos = 0; /* prepare_to_modify_buffer was last
+                                     called here.  */
 
       while (1)
        {
@@ -773,6 +775,33 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
              if (display_on_the_fly)
                break;
            }
+          /* CHANGE FUNCTIONS
+             For each iteration of the enclosing while (1) loop which
+             yields data (i.e. nread > 0), before- and
+             after-change-functions are each invoked exactly once.
+             This is done directly from the current function only, by
+             calling prepare_to_modify_buffer and signal_after_change.
+             It is not done here by directing another function such as
+             insert_1_both to call them.  The call to
+             prepare_to_modify_buffer follows this comment, and there
+             is one call to signal_after_change in each of the
+             branches of the next `else if'.
+
+             Exceptionally, the insertion into the buffer is aborted
+             at the call to del_range_2 ~45 lines further down, this
+             function removing the newly inserted data.  At this stage
+             prepare_to_modify_buffer has been called, but
+             signal_after_change hasn't.  A continue statement
+             restarts the enclosing while (1) loop.  A second,
+             unwanted, call to `prepare_to_modify_buffer' is inhibited
+             by the test perpared_pos < PT.  The data are inserted
+             again, and this time signal_after_change gets called,
+             balancing the previous call to prepare_to_modify_buffer.  */
+          if ((prepared_pos < PT) && nread)
+            {
+              prepare_to_modify_buffer (PT, PT, NULL);
+              prepared_pos = PT;
+            }
 
          /* Now NREAD is the total amount of data in the buffer.  */
 
@@ -780,15 +809,16 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
            ;
          else if (NILP (BVAR (current_buffer, enable_multibyte_characters))
                   && ! CODING_MAY_REQUIRE_DECODING (&process_coding))
-           insert_1_both (buf, nread, nread, 0, 1, 0);
+            {
+              insert_1_both (buf, nread, nread, 0, 0, 0);
+              signal_after_change (PT, 0, nread);
+            }
          else
            {                   /* We have to decode the input.  */
              Lisp_Object curbuf;
              ptrdiff_t count1 = SPECPDL_INDEX ();
 
              XSETBUFFER (curbuf, current_buffer);
-             /* FIXME: Call signal_after_change!  */
-             prepare_to_modify_buffer (PT, PT, NULL);
              /* We cannot allow after-change-functions be run
                 during decoding, because that might modify the
                 buffer, while we rely on process_coding.produced to
@@ -824,6 +854,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
 
              TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
                                PT_BYTE + process_coding.produced);
+              signal_after_change (PT, 0, process_coding.produced_char);
              carryover = process_coding.carryover_bytes;
              if (carryover > 0)
                memcpy (buf, process_coding.carryover,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]