The multiple change stuff has an incredible way of complexifying and
buggifying the code in insdel.c in subtle and not-so-subtle ways.
For example, the indirect buffers code iterated signal_after_change()
over all the indirect buffers; however, this caused a corruption of
multiple-change structures followed by a crash which Karl reported.
I hope this patch fixes the problem. I'm not sure I got it 100%
right, but it seems to fix the crash. People who understand insdel.c,
please keep your eyes open (Ben?). Karl, can you confirm that the
crash is now gone?
1998-09-09 Hrvoje Niksic <hniksic(a)srce.hr>
* insdel.c (signal_after_change): Add return value.
(buffer_insert_string_1): Use it.
(buffer_delete_range): Ditto.
(buffer_replace_char): Ditto.
(cancel_multiple_change): Map the indirect buffers.
--- src/insdel.c.orig Wed Sep 9 23:35:34 1998
+++ src/insdel.c Wed Sep 9 23:41:57 1998
@@ -1986,7 +1986,7 @@
buf->changes->newline_was_deleted = 0;
}
-static void
+static int
signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
Bufpos new_end);
@@ -2012,11 +2012,17 @@
if (buf->text->changes->mc_begin != 0 &&
buf->text->changes->mc_begin_signaled)
{
+ struct buffer *mbuf;
+ Lisp_Object bufcons;
Bufpos real_mc_begin = buf->text->changes->mc_begin;
buf->text->changes->mc_begin = 0;
- signal_after_change (buf, real_mc_begin, buf->text->changes->mc_orig_end,
- buf->text->changes->mc_new_end);
+ /* #### Is this correct? */
+ MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+ {
+ signal_after_change (buf, real_mc_begin, buf->text->changes->mc_orig_end,
+ buf->text->changes->mc_new_end);
+ }
}
else
{
@@ -2216,9 +2222,12 @@
START is the bufpos of the start of the changed text.
ORIG_END is the bufpos of the end of the before-changed text.
NEW_END is the bufpos of the end of the after-changed text.
- */
-static void
+ Non-zero return value means that hooks are postponed until end of
+ multiple change.
+*/
+
+static int
signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
Bufpos new_end)
{
@@ -2240,7 +2249,7 @@
assert (orig_end >= buf->text->changes->mc_begin &&
orig_end <= buf->text->changes->mc_new_end);
buf->text->changes->mc_new_end += new_end - orig_end;
- return; /* after-change-functions signalled when all changes done */
+ return 1; /* after-change-functions signalled when all changes done */
}
if (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer))
@@ -2266,6 +2275,7 @@
report_extent_modification (buffer, start, new_end,
&inside_change_hook, 1);
}
+ return 0;
}
/* Call this if you're about to change the region of BUFFER from START
@@ -2533,7 +2543,8 @@
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
- signal_after_change (mbuf, pos, pos, pos + cclen);
+ if (signal_after_change (mbuf, pos, pos, pos + cclen))
+ break;
}
UNGCPRO;
@@ -2845,7 +2856,8 @@
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
- signal_after_change (mbuf, from, to, from);
+ if (signal_after_change (mbuf, from, to, from))
+ break;
}
}
@@ -2918,7 +2930,8 @@
memcpy (BUF_BYTE_ADDRESS (buf, pos), newstr, newlen);
MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
{
- signal_after_change (mbuf, pos, pos + 1, pos + 1);
+ if (signal_after_change (mbuf, pos, pos + 1, pos + 1))
+ break;
}
/* We do not have to adjust the Mule data; we just replaced a
--
Hrvoje Niksic <hniksic(a)srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
Lost in Static 18 / And the storm is closing in now