Commit a615c6dc authored by Stefan Monnier's avatar Stefan Monnier
Browse files

(report_overlay_modification): Don't run hooks while

traversing the list of overlays.
parent 49f601d9
...@@ -4056,153 +4056,117 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3) ...@@ -4056,153 +4056,117 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3)
Lisp_Object prop, overlay, tail; Lisp_Object prop, overlay, tail;
/* 1 if this change is an insertion. */ /* 1 if this change is an insertion. */
int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end)); int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
int tail_copied; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
overlay = Qnil; overlay = Qnil;
tail = Qnil; tail = Qnil;
GCPRO5 (overlay, tail, arg1, arg2, arg3);
if (after)
{
/* Call the functions recorded in last_overlay_modification_hooks
rather than scanning the overlays again.
First copy the vector contents, in case some of these hooks
do subsequent modification of the buffer. */
int size = last_overlay_modification_hooks_used;
Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
int i;
bcopy (XVECTOR (last_overlay_modification_hooks)->contents,
copy, size * sizeof (Lisp_Object));
gcpro1.var = copy;
gcpro1.nvars = size;
for (i = 0; i < size;)
{
Lisp_Object prop, overlay;
prop = copy[i++];
overlay = copy[i++];
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
}
UNGCPRO;
return;
}
/* We are being called before a change. if (!after)
Scan the overlays to find the functions to call. */
last_overlay_modification_hooks_used = 0;
tail_copied = 0;
for (tail = current_buffer->overlays_before;
CONSP (tail);
tail = XCDR (tail))
{ {
int startpos, endpos; /* We are being called before a change.
Lisp_Object ostart, oend; Scan the overlays to find the functions to call. */
last_overlay_modification_hooks_used = 0;
overlay = XCAR (tail); for (tail = current_buffer->overlays_before;
CONSP (tail);
ostart = OVERLAY_START (overlay); tail = XCDR (tail))
oend = OVERLAY_END (overlay);
endpos = OVERLAY_POSITION (oend);
if (XFASTINT (start) > endpos)
break;
startpos = OVERLAY_POSITION (ostart);
if (insertion && (XFASTINT (start) == startpos
|| XFASTINT (end) == startpos))
{ {
prop = Foverlay_get (overlay, Qinsert_in_front_hooks); int startpos, endpos;
if (!NILP (prop)) Lisp_Object ostart, oend;
overlay = XCAR (tail);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
endpos = OVERLAY_POSITION (oend);
if (XFASTINT (start) > endpos)
break;
startpos = OVERLAY_POSITION (ostart);
if (insertion && (XFASTINT (start) == startpos
|| XFASTINT (end) == startpos))
{ {
/* Copy TAIL in case the hook recenters the overlay lists. */ prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
if (!tail_copied) if (!NILP (prop))
tail = Fcopy_sequence (tail); add_overlay_mod_hooklist (prop, overlay);
tail_copied = 1;
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
} }
} if (insertion && (XFASTINT (start) == endpos
if (insertion && (XFASTINT (start) == endpos || XFASTINT (end) == endpos))
|| XFASTINT (end) == endpos))
{
prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
{ {
if (!tail_copied) prop = Foverlay_get (overlay, Qinsert_behind_hooks);
tail = Fcopy_sequence (tail); if (!NILP (prop))
tail_copied = 1; add_overlay_mod_hooklist (prop, overlay);
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
} }
} /* Test for intersecting intervals. This does the right thing
/* Test for intersecting intervals. This does the right thing for both insertion and deletion. */
for both insertion and deletion. */ if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
{
prop = Foverlay_get (overlay, Qmodification_hooks);
if (!NILP (prop))
{ {
if (!tail_copied) prop = Foverlay_get (overlay, Qmodification_hooks);
tail = Fcopy_sequence (tail); if (!NILP (prop))
tail_copied = 1; add_overlay_mod_hooklist (prop, overlay);
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
} }
} }
}
tail_copied = 0;
for (tail = current_buffer->overlays_after;
CONSP (tail);
tail = XCDR (tail))
{
int startpos, endpos;
Lisp_Object ostart, oend;
overlay = XCAR (tail); for (tail = current_buffer->overlays_after;
CONSP (tail);
ostart = OVERLAY_START (overlay); tail = XCDR (tail))
oend = OVERLAY_END (overlay);
startpos = OVERLAY_POSITION (ostart);
endpos = OVERLAY_POSITION (oend);
if (XFASTINT (end) < startpos)
break;
if (insertion && (XFASTINT (start) == startpos
|| XFASTINT (end) == startpos))
{ {
prop = Foverlay_get (overlay, Qinsert_in_front_hooks); int startpos, endpos;
if (!NILP (prop)) Lisp_Object ostart, oend;
overlay = XCAR (tail);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
startpos = OVERLAY_POSITION (ostart);
endpos = OVERLAY_POSITION (oend);
if (XFASTINT (end) < startpos)
break;
if (insertion && (XFASTINT (start) == startpos
|| XFASTINT (end) == startpos))
{ {
if (!tail_copied) prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
tail = Fcopy_sequence (tail); if (!NILP (prop))
tail_copied = 1; add_overlay_mod_hooklist (prop, overlay);
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
} }
} if (insertion && (XFASTINT (start) == endpos
if (insertion && (XFASTINT (start) == endpos || XFASTINT (end) == endpos))
|| XFASTINT (end) == endpos))
{
prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
{ {
if (!tail_copied) prop = Foverlay_get (overlay, Qinsert_behind_hooks);
tail = Fcopy_sequence (tail); if (!NILP (prop))
tail_copied = 1; add_overlay_mod_hooklist (prop, overlay);
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
} }
} /* Test for intersecting intervals. This does the right thing
/* Test for intersecting intervals. This does the right thing for both insertion and deletion. */
for both insertion and deletion. */ if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
{
prop = Foverlay_get (overlay, Qmodification_hooks);
if (!NILP (prop))
{ {
if (!tail_copied) prop = Foverlay_get (overlay, Qmodification_hooks);
tail = Fcopy_sequence (tail); if (!NILP (prop))
tail_copied = 1; add_overlay_mod_hooklist (prop, overlay);
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
} }
} }
} }
GCPRO4 (overlay, arg1, arg2, arg3);
{
/* Call the functions recorded in last_overlay_modification_hooks.
First copy the vector contents, in case some of these hooks
do subsequent modification of the buffer. */
int size = last_overlay_modification_hooks_used;
Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
int i;
bcopy (XVECTOR (last_overlay_modification_hooks)->contents,
copy, size * sizeof (Lisp_Object));
gcpro1.var = copy;
gcpro1.nvars = size;
for (i = 0; i < size;)
{
Lisp_Object prop, overlay;
prop = copy[i++];
overlay = copy[i++];
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
}
}
UNGCPRO; UNGCPRO;
} }
...@@ -4215,8 +4179,6 @@ call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3) ...@@ -4215,8 +4179,6 @@ call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3)
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
GCPRO4 (list, arg1, arg2, arg3); GCPRO4 (list, arg1, arg2, arg3);
if (! after)
add_overlay_mod_hooklist (list, overlay);
while (CONSP (list)) while (CONSP (list))
{ {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment