Skip to content

Commit 224e8d1

Browse files
author
Alan Mackenzie
committed
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.
1 parent d02f2a7 commit 224e8d1

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

src/callproc.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
746746
int carryover = 0;
747747
bool display_on_the_fly = display_p;
748748
struct coding_system saved_coding = process_coding;
749+
ptrdiff_t prepared_pos = 0; /* prepare_to_modify_buffer was last
750+
called here. */
749751

750752
while (1)
751753
{
@@ -773,22 +775,50 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
773775
if (display_on_the_fly)
774776
break;
775777
}
778+
/* CHANGE FUNCTIONS
779+
For each iteration of the enclosing while (1) loop which
780+
yields data (i.e. nread > 0), before- and
781+
after-change-functions are each invoked exactly once.
782+
This is done directly from the current function only, by
783+
calling prepare_to_modify_buffer and signal_after_change.
784+
It is not done here by directing another function such as
785+
insert_1_both to call them. The call to
786+
prepare_to_modify_buffer follows this comment, and there
787+
is one call to signal_after_change in each of the
788+
branches of the next `else if'.
789+
790+
Exceptionally, the insertion into the buffer is aborted
791+
at the call to del_range_2 ~45 lines further down, this
792+
function removing the newly inserted data. At this stage
793+
prepare_to_modify_buffer has been called, but
794+
signal_after_change hasn't. A continue statement
795+
restarts the enclosing while (1) loop. A second,
796+
unwanted, call to `prepare_to_modify_buffer' is inhibited
797+
by the test perpared_pos < PT. The data are inserted
798+
again, and this time signal_after_change gets called,
799+
balancing the previous call to prepare_to_modify_buffer. */
800+
if ((prepared_pos < PT) && nread)
801+
{
802+
prepare_to_modify_buffer (PT, PT, NULL);
803+
prepared_pos = PT;
804+
}
776805

777806
/* Now NREAD is the total amount of data in the buffer. */
778807

779808
if (!nread)
780809
;
781810
else if (NILP (BVAR (current_buffer, enable_multibyte_characters))
782811
&& ! CODING_MAY_REQUIRE_DECODING (&process_coding))
783-
insert_1_both (buf, nread, nread, 0, 1, 0);
812+
{
813+
insert_1_both (buf, nread, nread, 0, 0, 0);
814+
signal_after_change (PT, 0, nread);
815+
}
784816
else
785817
{ /* We have to decode the input. */
786818
Lisp_Object curbuf;
787819
ptrdiff_t count1 = SPECPDL_INDEX ();
788820

789821
XSETBUFFER (curbuf, current_buffer);
790-
/* FIXME: Call signal_after_change! */
791-
prepare_to_modify_buffer (PT, PT, NULL);
792822
/* We cannot allow after-change-functions be run
793823
during decoding, because that might modify the
794824
buffer, while we rely on process_coding.produced to
@@ -824,6 +854,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
824854

825855
TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
826856
PT_BYTE + process_coding.produced);
857+
signal_after_change (PT, 0, process_coding.produced_char);
827858
carryover = process_coding.carryover_bytes;
828859
if (carryover > 0)
829860
memcpy (buf, process_coding.carryover,

0 commit comments

Comments
 (0)