comparison src/buffer.c @ 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 56ce64222cbe
children a8851a32a1c7
comparison
equal deleted inserted replaced
45373:0ca1f86bf6fc 45374:030fb28e7ec2
3226 fix_overlays_in_range (start, end) 3226 fix_overlays_in_range (start, end)
3227 register int start, end; 3227 register int start, end;
3228 { 3228 {
3229 Lisp_Object overlay; 3229 Lisp_Object overlay;
3230 Lisp_Object before_list, after_list; 3230 Lisp_Object before_list, after_list;
3231 Lisp_Object *ptail, *pbefore = &before_list, *pafter = &after_list; 3231 /* These are either nil, indicating that before_list or after_list
3232 should be assigned, or the cons cell the cdr of which should be
3233 assigned. */
3234 Lisp_Object beforep = Qnil, afterp = Qnil;
3235 /* 'Parent', likewise, indicates a cons cell or
3236 current_buffer->overlays_before or overlays_after, depending
3237 which loop we're in. */
3238 Lisp_Object tail, parent;
3232 int startpos, endpos; 3239 int startpos, endpos;
3233 3240
3234 /* This algorithm shifts links around instead of consing and GCing. 3241 /* This algorithm shifts links around instead of consing and GCing.
3235 The loop invariant is that before_list (resp. after_list) is a 3242 The loop invariant is that before_list (resp. after_list) is a
3236 well-formed list except that its last element, the one that 3243 well-formed list except that its last element, the CDR of beforep
3237 *pbefore (resp. *pafter) points to, is still uninitialized. 3244 (resp. afterp) if beforep (afterp) isn't nil or before_list
3238 So it's not a bug that before_list isn't initialized, although 3245 (after_list) if it is, is still uninitialized. So it's not a bug
3239 it may look strange. */ 3246 that before_list isn't initialized, although it may look
3240 for (ptail = &current_buffer->overlays_before; CONSP (*ptail);) 3247 strange. */
3241 { 3248 for (parent = Qnil, tail = current_buffer->overlays_before; CONSP (tail);)
3242 overlay = XCAR (*ptail); 3249 {
3250 overlay = XCAR (tail);
3243 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3251 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3244 if (endpos < start) 3252 if (endpos < start)
3245 break; 3253 break;
3246 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3254 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3247 if (endpos < end 3255 if (endpos < end
3259 } 3267 }
3260 /* Add it to the end of the wrong list. Later on, 3268 /* Add it to the end of the wrong list. Later on,
3261 recenter_overlay_lists will move it to the right place. */ 3269 recenter_overlay_lists will move it to the right place. */
3262 if (endpos < XINT (current_buffer->overlay_center)) 3270 if (endpos < XINT (current_buffer->overlay_center))
3263 { 3271 {
3264 *pafter = *ptail; 3272 if (NILP (afterp))
3265 pafter = &XCDR (*ptail); 3273 after_list = tail;
3274 else
3275 XSETCDR (afterp, tail);
3276 afterp = tail;
3266 } 3277 }
3267 else 3278 else
3268 { 3279 {
3269 *pbefore = *ptail; 3280 if (NILP (beforep))
3270 pbefore = &XCDR (*ptail); 3281 before_list = tail;
3282 else
3283 XSETCDR (beforep, tail);
3284 beforep = tail;
3271 } 3285 }
3272 *ptail = XCDR (*ptail); 3286 if (NILP (parent))
3287 current_buffer->overlays_before = XCDR (tail);
3288 else
3289 XSETCDR (parent, XCDR (tail));
3290 tail = XCDR (tail);
3273 } 3291 }
3274 else 3292 else
3275 ptail = &XCDR (*ptail); 3293 parent = tail, tail = XCDR (parent);
3276 } 3294 }
3277 for (ptail = &current_buffer->overlays_after; CONSP (*ptail);) 3295 for (parent = Qnil, tail = current_buffer->overlays_after; CONSP (tail);)
3278 { 3296 {
3279 overlay = XCAR (*ptail); 3297 overlay = XCAR (tail);
3280 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3298 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3281 if (startpos >= end) 3299 if (startpos >= end)
3282 break; 3300 break;
3283 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3301 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3284 if (startpos >= start 3302 if (startpos >= start
3293 Qnil); 3311 Qnil);
3294 tem = startpos; startpos = endpos; endpos = tem; 3312 tem = startpos; startpos = endpos; endpos = tem;
3295 } 3313 }
3296 if (endpos < XINT (current_buffer->overlay_center)) 3314 if (endpos < XINT (current_buffer->overlay_center))
3297 { 3315 {
3298 *pafter = *ptail; 3316 if (NILP (afterp))
3299 pafter = &XCDR (*ptail); 3317 after_list = tail;
3318 else
3319 XSETCDR (afterp, tail);
3320 afterp = tail;
3300 } 3321 }
3301 else 3322 else
3302 { 3323 {
3303 *pbefore = *ptail; 3324 if (NILP (beforep))
3304 pbefore = &XCDR (*ptail); 3325 before_list = tail;
3326 else
3327 XSETCDR (beforep, tail);
3328 beforep = tail;
3305 } 3329 }
3306 *ptail = XCDR (*ptail); 3330 if (NILP (parent))
3331 current_buffer->overlays_after = XCDR (tail);
3332 else
3333 XSETCDR (parent, XCDR (tail));
3334 tail = XCDR (tail);
3307 } 3335 }
3308 else 3336 else
3309 ptail = &XCDR (*ptail); 3337 parent = tail, tail = XCDR (parent);
3310 } 3338 }
3311 3339
3312 /* Splice the constructed (wrong) lists into the buffer's lists, 3340 /* Splice the constructed (wrong) lists into the buffer's lists,
3313 and let the recenter function make it sane again. */ 3341 and let the recenter function make it sane again. */
3314 *pbefore = current_buffer->overlays_before; 3342 if (!NILP (beforep))
3315 current_buffer->overlays_before = before_list; 3343 {
3344 XSETCDR (beforep, current_buffer->overlays_before);
3345 current_buffer->overlays_before = before_list;
3346 }
3316 recenter_overlay_lists (current_buffer, 3347 recenter_overlay_lists (current_buffer,
3317 XINT (current_buffer->overlay_center)); 3348 XINT (current_buffer->overlay_center));
3318 3349
3319 *pafter = current_buffer->overlays_after; 3350 if (!NILP (afterp))
3320 current_buffer->overlays_after = after_list; 3351 {
3352 XSETCDR (afterp, current_buffer->overlays_after);
3353 current_buffer->overlays_after = after_list;
3354 }
3321 recenter_overlay_lists (current_buffer, 3355 recenter_overlay_lists (current_buffer,
3322 XINT (current_buffer->overlay_center)); 3356 XINT (current_buffer->overlay_center));
3323 } 3357 }
3324 3358
3325 /* We have two types of overlay: the one whose ending marker is 3359 /* We have two types of overlay: the one whose ending marker is
3337 void 3371 void
3338 fix_overlays_before (bp, prev, pos) 3372 fix_overlays_before (bp, prev, pos)
3339 struct buffer *bp; 3373 struct buffer *bp;
3340 int prev, pos; 3374 int prev, pos;
3341 { 3375 {
3342 Lisp_Object *tailp = &bp->overlays_before; 3376 /* If parent is nil, replace overlays_before; otherwise, XCDR(parent). */
3343 Lisp_Object *right_place; 3377 Lisp_Object tail = bp->overlays_before, parent = Qnil;
3378 Lisp_Object right_pair;
3344 int end; 3379 int end;
3345 3380
3346 /* After the insertion, the several overlays may be in incorrect 3381 /* After the insertion, the several overlays may be in incorrect
3347 order. The possibility is that, in the list `overlays_before', 3382 order. The possibility is that, in the list `overlays_before',
3348 an overlay which ends at POS appears after an overlay which ends 3383 an overlay which ends at POS appears after an overlay which ends
3352 3387
3353 /* At first, find a place where disordered overlays should be linked 3388 /* At first, find a place where disordered overlays should be linked
3354 in. It is where an overlay which end before POS exists. (i.e. an 3389 in. It is where an overlay which end before POS exists. (i.e. an
3355 overlay whose ending marker is after-insertion-marker if disorder 3390 overlay whose ending marker is after-insertion-marker if disorder
3356 exists). */ 3391 exists). */
3357 while (!NILP (*tailp) 3392 while (!NILP (tail)
3358 && ((end = OVERLAY_POSITION (OVERLAY_END (XCAR (*tailp)))) 3393 && ((end = OVERLAY_POSITION (OVERLAY_END (XCAR (tail))))
3359 >= pos)) 3394 >= pos))
3360 tailp = &XCDR (*tailp); 3395 {
3396 parent = tail;
3397 tail = XCDR (tail);
3398 }
3361 3399
3362 /* If we don't find such an overlay, 3400 /* If we don't find such an overlay,
3363 or the found one ends before PREV, 3401 or the found one ends before PREV,
3364 or the found one is the last one in the list, 3402 or the found one is the last one in the list,
3365 we don't have to fix anything. */ 3403 we don't have to fix anything. */
3366 if (NILP (*tailp) 3404 if (NILP (tail)
3367 || end < prev 3405 || end < prev
3368 || NILP (XCDR (*tailp))) 3406 || NILP (XCDR (tail)))
3369 return; 3407 return;
3370 3408
3371 right_place = tailp; 3409 right_pair = parent;
3372 tailp = &XCDR (*tailp); 3410 parent = tail;
3373 3411 tail = XCDR (tail);
3374 /* Now, end position of overlays in the list *TAILP should be before 3412
3413 /* Now, end position of overlays in the list TAIL should be before
3375 or equal to PREV. In the loop, an overlay which ends at POS is 3414 or equal to PREV. In the loop, an overlay which ends at POS is
3376 moved ahead to the place pointed by RIGHT_PLACE. If we found an 3415 moved ahead to the place indicated by the CDR of RIGHT_PAIR. If
3377 overlay which ends before PREV, the remaining overlays are in 3416 we found an overlay which ends before PREV, the remaining
3378 correct order. */ 3417 overlays are in correct order. */
3379 while (!NILP (*tailp)) 3418 while (!NILP (tail))
3380 { 3419 {
3381 end = OVERLAY_POSITION (OVERLAY_END (XCAR (*tailp))); 3420 end = OVERLAY_POSITION (OVERLAY_END (XCAR (tail)));
3382 3421
3383 if (end == pos) 3422 if (end == pos)
3384 { /* This overlay is disordered. */ 3423 { /* This overlay is disordered. */
3385 Lisp_Object found = *tailp; 3424 Lisp_Object found = tail;
3386 3425
3387 /* Unlink the found overlay. */ 3426 /* Unlink the found overlay. */
3388 *tailp = XCDR (found); 3427 XSETCDR (parent, XCDR (found));
3389 /* Move an overlay at RIGHT_PLACE to the next of the found one. */ 3428 /* Move an overlay at RIGHT_PLACE to the next of the found one,
3390 XCDR (found) = *right_place; 3429 and link it into the right place. */
3391 /* Link it into the right place. */ 3430 if (NILP (right_pair))
3392 *right_place = found; 3431 {
3432 XSETCDR (found, bp->overlays_before);
3433 bp->overlays_before = found;
3434 }
3435 else
3436 {
3437 XSETCDR (found, XCDR (right_pair));
3438 XSETCDR (right_pair, found);
3439 }
3393 } 3440 }
3394 else if (end == prev) 3441 else if (end == prev)
3395 tailp = &XCDR (*tailp); 3442 {
3443 parent = tail;
3444 tail = XCDR (tail);
3445 }
3396 else /* No more disordered overlay. */ 3446 else /* No more disordered overlay. */
3397 break; 3447 break;
3398 } 3448 }
3399 } 3449 }
3400 3450