Mercurial > emacs
changeset 45374:030fb28e7ec2
* buffer.c (fix_overlays_in_range, fix_overlays_before): Don't take the address
of the cdr part of a cons cell; instead, track the parent cell and call
XSETCDR, or set the variable for the head of the list if we haven't started
down the list yet.
author | Ken Raeburn <raeburn@raeburn.org> |
---|---|
date | Sun, 19 May 2002 23:12:30 +0000 |
parents | 0ca1f86bf6fc |
children | 7f3255507201 |
files | src/buffer.c |
diffstat | 1 files changed, 98 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/src/buffer.c Sun May 19 22:28:15 2002 +0000 +++ b/src/buffer.c Sun May 19 23:12:30 2002 +0000 @@ -3228,18 +3228,26 @@ { Lisp_Object overlay; Lisp_Object before_list, after_list; - Lisp_Object *ptail, *pbefore = &before_list, *pafter = &after_list; + /* These are either nil, indicating that before_list or after_list + should be assigned, or the cons cell the cdr of which should be + assigned. */ + Lisp_Object beforep = Qnil, afterp = Qnil; + /* 'Parent', likewise, indicates a cons cell or + current_buffer->overlays_before or overlays_after, depending + which loop we're in. */ + Lisp_Object tail, parent; int startpos, endpos; /* This algorithm shifts links around instead of consing and GCing. The loop invariant is that before_list (resp. after_list) is a - well-formed list except that its last element, the one that - *pbefore (resp. *pafter) points to, is still uninitialized. - So it's not a bug that before_list isn't initialized, although - it may look strange. */ - for (ptail = ¤t_buffer->overlays_before; CONSP (*ptail);) + well-formed list except that its last element, the CDR of beforep + (resp. afterp) if beforep (afterp) isn't nil or before_list + (after_list) if it is, is still uninitialized. So it's not a bug + that before_list isn't initialized, although it may look + strange. */ + for (parent = Qnil, tail = current_buffer->overlays_before; CONSP (tail);) { - overlay = XCAR (*ptail); + overlay = XCAR (tail); endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); if (endpos < start) break; @@ -3261,22 +3269,32 @@ recenter_overlay_lists will move it to the right place. */ if (endpos < XINT (current_buffer->overlay_center)) { - *pafter = *ptail; - pafter = &XCDR (*ptail); + if (NILP (afterp)) + after_list = tail; + else + XSETCDR (afterp, tail); + afterp = tail; } else { - *pbefore = *ptail; - pbefore = &XCDR (*ptail); + if (NILP (beforep)) + before_list = tail; + else + XSETCDR (beforep, tail); + beforep = tail; } - *ptail = XCDR (*ptail); + if (NILP (parent)) + current_buffer->overlays_before = XCDR (tail); + else + XSETCDR (parent, XCDR (tail)); + tail = XCDR (tail); } else - ptail = &XCDR (*ptail); + parent = tail, tail = XCDR (parent); } - for (ptail = ¤t_buffer->overlays_after; CONSP (*ptail);) + for (parent = Qnil, tail = current_buffer->overlays_after; CONSP (tail);) { - overlay = XCAR (*ptail); + overlay = XCAR (tail); startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); if (startpos >= end) break; @@ -3295,29 +3313,45 @@ } if (endpos < XINT (current_buffer->overlay_center)) { - *pafter = *ptail; - pafter = &XCDR (*ptail); + if (NILP (afterp)) + after_list = tail; + else + XSETCDR (afterp, tail); + afterp = tail; } else { - *pbefore = *ptail; - pbefore = &XCDR (*ptail); + if (NILP (beforep)) + before_list = tail; + else + XSETCDR (beforep, tail); + beforep = tail; } - *ptail = XCDR (*ptail); + if (NILP (parent)) + current_buffer->overlays_after = XCDR (tail); + else + XSETCDR (parent, XCDR (tail)); + tail = XCDR (tail); } else - ptail = &XCDR (*ptail); + parent = tail, tail = XCDR (parent); } /* Splice the constructed (wrong) lists into the buffer's lists, and let the recenter function make it sane again. */ - *pbefore = current_buffer->overlays_before; - current_buffer->overlays_before = before_list; + if (!NILP (beforep)) + { + XSETCDR (beforep, current_buffer->overlays_before); + current_buffer->overlays_before = before_list; + } recenter_overlay_lists (current_buffer, XINT (current_buffer->overlay_center)); - *pafter = current_buffer->overlays_after; - current_buffer->overlays_after = after_list; + if (!NILP (afterp)) + { + XSETCDR (afterp, current_buffer->overlays_after); + current_buffer->overlays_after = after_list; + } recenter_overlay_lists (current_buffer, XINT (current_buffer->overlay_center)); } @@ -3339,8 +3373,9 @@ struct buffer *bp; int prev, pos; { - Lisp_Object *tailp = &bp->overlays_before; - Lisp_Object *right_place; + /* If parent is nil, replace overlays_before; otherwise, XCDR(parent). */ + Lisp_Object tail = bp->overlays_before, parent = Qnil; + Lisp_Object right_pair; int end; /* After the insertion, the several overlays may be in incorrect @@ -3354,45 +3389,60 @@ in. It is where an overlay which end before POS exists. (i.e. an overlay whose ending marker is after-insertion-marker if disorder exists). */ - while (!NILP (*tailp) - && ((end = OVERLAY_POSITION (OVERLAY_END (XCAR (*tailp)))) + while (!NILP (tail) + && ((end = OVERLAY_POSITION (OVERLAY_END (XCAR (tail)))) >= pos)) - tailp = &XCDR (*tailp); + { + parent = tail; + tail = XCDR (tail); + } /* If we don't find such an overlay, or the found one ends before PREV, or the found one is the last one in the list, we don't have to fix anything. */ - if (NILP (*tailp) + if (NILP (tail) || end < prev - || NILP (XCDR (*tailp))) + || NILP (XCDR (tail))) return; - right_place = tailp; - tailp = &XCDR (*tailp); - - /* Now, end position of overlays in the list *TAILP should be before + right_pair = parent; + parent = tail; + tail = XCDR (tail); + + /* Now, end position of overlays in the list TAIL should be before or equal to PREV. In the loop, an overlay which ends at POS is - moved ahead to the place pointed by RIGHT_PLACE. If we found an - overlay which ends before PREV, the remaining overlays are in - correct order. */ - while (!NILP (*tailp)) + moved ahead to the place indicated by the CDR of RIGHT_PAIR. If + we found an overlay which ends before PREV, the remaining + overlays are in correct order. */ + while (!NILP (tail)) { - end = OVERLAY_POSITION (OVERLAY_END (XCAR (*tailp))); + end = OVERLAY_POSITION (OVERLAY_END (XCAR (tail))); if (end == pos) { /* This overlay is disordered. */ - Lisp_Object found = *tailp; + Lisp_Object found = tail; /* Unlink the found overlay. */ - *tailp = XCDR (found); - /* Move an overlay at RIGHT_PLACE to the next of the found one. */ - XCDR (found) = *right_place; - /* Link it into the right place. */ - *right_place = found; + XSETCDR (parent, XCDR (found)); + /* Move an overlay at RIGHT_PLACE to the next of the found one, + and link it into the right place. */ + if (NILP (right_pair)) + { + XSETCDR (found, bp->overlays_before); + bp->overlays_before = found; + } + else + { + XSETCDR (found, XCDR (right_pair)); + XSETCDR (right_pair, found); + } } else if (end == prev) - tailp = &XCDR (*tailp); + { + parent = tail; + tail = XCDR (tail); + } else /* No more disordered overlay. */ break; }