1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43: #include <config.h>
44: #include "lisp.h"
45: #include "intervals.h"
46: #include "buffer.h"
47: #include "puresize.h"
48: #include "keyboard.h"
49: #include "keymap.h"
50:
51:
52:
53:
54: #define TMEM(sym, set) (CONSP (set) ? ! NILP (Fmemq (sym, set)) : ! NILP (set))
55:
56: Lisp_Object merge_properties_sticky ();
57: static INTERVAL reproduce_tree P_ ((INTERVAL, INTERVAL));
58: static INTERVAL reproduce_tree_obj P_ ((INTERVAL, Lisp_Object));
59: ^L
60:
61:
62:
63:
64:
65: INTERVAL
66: create_root_interval (parent)
67: Lisp_Object parent;
68: {
69: INTERVAL new;
70:
71: CHECK_IMPURE (parent);
72:
73: new = make_interval ();
74:
75: if (BUFFERP (parent))
76: {
77: new->total_length = (BUF_Z (XBUFFER (parent))
78: - BUF_BEG (XBUFFER (parent)));
79: CHECK_TOTAL_LENGTH (new);
80: BUF_INTERVALS (XBUFFER (parent)) = new;
81: new->position = BEG;
82: }
83: else if (STRINGP (parent))
84: {
85: new->total_length = SCHARS (parent);
86: CHECK_TOTAL_LENGTH (new);
87: STRING_SET_INTERVALS (parent, new);
88: new->position = 0;
89: }
90:
91: SET_INTERVAL_OBJECT (new, parent);
92:
93: return new;
94: }
95:
96:
97:
98: void
99: copy_properties (source, target)
100: register INTERVAL source, target;
101: {
102: if (DEFAULT_INTERVAL_P (source) && DEFAULT_INTERVAL_P (target))
103: return;
104:
105: COPY_INTERVAL_CACHE (source, target);
106: target->plist = Fcopy_sequence (source->plist);
107: }
108:
109:
110:
111:
112:
113: static void
114: merge_properties (source, target)
115: register INTERVAL source, target;
116: {
117: register Lisp_Object o, sym, val;
118:
119: if (DEFAULT_INTERVAL_P (source) && DEFAULT_INTERVAL_P (target))
120: return;
121:
122: MERGE_INTERVAL_CACHE (source, target);
123:
124: o = source->plist;
125: while (CONSP (o))
126: {
127: sym = XCAR (o);
128: o = XCDR (o);
129: CHECK_CONS (o);
130:
131: val = target->plist;
132: while (CONSP (val) && !EQ (XCAR (val), sym))
133: {
134: val = XCDR (val);
135: if (!CONSP (val))
136: break;
137: val = XCDR (val);
138: }
139:
140: if (NILP (val))
141: {
142: val = XCAR (o);
143: target->plist = Fcons (sym, Fcons (val, target->plist));
144: }
145: o = XCDR (o);
146: }
147: }
148:
149:
150:
151:
152: int
153: intervals_equal (i0, i1)
154: INTERVAL i0, i1;
155: {
156: register Lisp_Object i0_cdr, i0_sym;
157: register Lisp_Object i1_cdr, i1_val;
158:
159: if (DEFAULT_INTERVAL_P (i0) && DEFAULT_INTERVAL_P (i1))
160: return 1;
161:
162: if (DEFAULT_INTERVAL_P (i0) || DEFAULT_INTERVAL_P (i1))
163: return 0;
164:
165: i0_cdr = i0->plist;
166: i1_cdr = i1->plist;
167: while (CONSP (i0_cdr) && CONSP (i1_cdr))
168: {
169: i0_sym = XCAR (i0_cdr);
170: i0_cdr = XCDR (i0_cdr);
171: if (!CONSP (i0_cdr))
172: return 0;
173: i1_val = i1->plist;
174: while (CONSP (i1_val) && !EQ (XCAR (i1_val), i0_sym))
175: {
176: i1_val = XCDR (i1_val);
177: if (!CONSP (i1_val))
178: return 0;
179: i1_val = XCDR (i1_val);
180: }
181:
182:
183: if (EQ (i1_val, Qnil))
184: return 0;
185:
186:
187: if (!CONSP (i1_val)
188: || (i1_val = XCDR (i1_val), !CONSP (i1_val))
189: || !EQ (XCAR (i1_val), XCAR (i0_cdr)))
190: return 0;
191:
192: i0_cdr = XCDR (i0_cdr);
193:
194: i1_cdr = XCDR (i1_cdr);
195: if (!CONSP (i1_cdr))
196: return 0;
197: i1_cdr = XCDR (i1_cdr);
198: }
199:
200:
201: return (NILP (i0_cdr) && NILP (i1_cdr));
202: }
203: ^L
204:
205:
206:
207:
208:
209: void
210: traverse_intervals_noorder (tree, function, arg)
211: INTERVAL tree;
212: void (* function) P_ ((INTERVAL, Lisp_Object));
213: Lisp_Object arg;
214: {
215:
216: while (!NULL_INTERVAL_P (tree))
217: {
218: (*function) (tree, arg);
219: if (NULL_INTERVAL_P (tree->right))
220: tree = tree->left;
221: else
222: {
223: traverse_intervals_noorder (tree->left, function, arg);
224: tree = tree->right;
225: }
226: }
227: }
228:
229:
230:
231:
232: void
233: traverse_intervals (tree, position, function, arg)
234: INTERVAL tree;
235: int position;
236: void (* function) P_ ((INTERVAL, Lisp_Object));
237: Lisp_Object arg;
238: {
239: while (!NULL_INTERVAL_P (tree))
240: {
241: traverse_intervals (tree->left, position, function, arg);
242: position += LEFT_TOTAL_LENGTH (tree);
243: tree->position = position;
244: (*function) (tree, arg);
245: position += LENGTH (tree); tree = tree->right;
246: }
247: }
248: ^L
249: #if 0
250:
251: static int icount;
252: static int idepth;
253: static int zero_length;
254:
255:
256:
257: INTERVAL search_interval, found_interval;
258:
259: void
260: check_for_interval (i)
261: register INTERVAL i;
262: {
263: if (i == search_interval)
264: {
265: found_interval = i;
266: icount++;
267: }
268: }
269:
270: INTERVAL
271: search_for_interval (i, tree)
272: register INTERVAL i, tree;
273: {
274: icount = 0;
275: search_interval = i;
276: found_interval = NULL_INTERVAL;
277: traverse_intervals_noorder (tree, &check_for_interval, Qnil);
278: return found_interval;
279: }
280:
281: static void
282: inc_interval_count (i)
283: INTERVAL i;
284: {
285: icount++;
286: if (LENGTH (i) == 0)
287: zero_length++;
288: if (depth > idepth)
289: idepth = depth;
290: }
291:
292: int
293: count_intervals (i)
294: register INTERVAL i;
295: {
296: icount = 0;
297: idepth = 0;
298: zero_length = 0;
299: traverse_intervals_noorder (i, &inc_interval_count, Qnil);
300:
301: return icount;
302: }
303:
304: static INTERVAL
305: root_interval (interval)
306: INTERVAL interval;
307: {
308: register INTERVAL i = interval;
309:
310: while (! ROOT_INTERVAL_P (i))
311: i = INTERVAL_PARENT (i);
312:
313: return i;
314: }
315: #endif
316: ^L
317:
318:
319:
320:
321:
322:
323:
324:
325:
326: static INLINE INTERVAL
327: rotate_right (interval)
328: INTERVAL interval;
329: {
330: INTERVAL i;
331: INTERVAL B = interval->left;
332: int old_total = interval->total_length;
333:
334:
335: if (! ROOT_INTERVAL_P (interval))
336: {
337: if (AM_LEFT_CHILD (interval))
338: INTERVAL_PARENT (interval)->left = B;
339: else
340: INTERVAL_PARENT (interval)->right = B;
341: }
342: COPY_INTERVAL_PARENT (B, interval);
343:
344:
345: i = B->right;
346: B->right = interval;
347: SET_INTERVAL_PARENT (interval, B);
348:
349:
350: interval->left = i;
351: if (! NULL_INTERVAL_P (i))
352: SET_INTERVAL_PARENT (i, interval);
353:
354:
355: interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval);
356: CHECK_TOTAL_LENGTH (interval);
357:
358:
359: B->total_length = old_total;
360: CHECK_TOTAL_LENGTH (B);
361:
362: return B;
363: }
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374: static INLINE INTERVAL
375: rotate_left (interval)
376: INTERVAL interval;
377: {
378: INTERVAL i;
379: INTERVAL B = interval->right;
380: int old_total = interval->total_length;
381:
382:
383: if (! ROOT_INTERVAL_P (interval))
384: {
385: if (AM_LEFT_CHILD (interval))
386: INTERVAL_PARENT (interval)->left = B;
387: else
388: INTERVAL_PARENT (interval)->right = B;
389: }
390: COPY_INTERVAL_PARENT (B, interval);
391:
392:
393: i = B->left;
394: B->left = interval;
395: SET_INTERVAL_PARENT (interval, B);
396:
397:
398: interval->right = i;
399: if (! NULL_INTERVAL_P (i))
400: SET_INTERVAL_PARENT (i, interval);
401:
402:
403: interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval);
404: CHECK_TOTAL_LENGTH (interval);
405:
406:
407: B->total_length = old_total;
408: CHECK_TOTAL_LENGTH (B);
409:
410: return B;
411: }
412: ^L
413:
414:
415:
416: static INTERVAL
417: balance_an_interval (i)
418: INTERVAL i;
419: {
420: register int old_diff, new_diff;
421:
422: while (1)
423: {
424: old_diff = LEFT_TOTAL_LENGTH (i) - RIGHT_TOTAL_LENGTH (i);
425: if (old_diff > 0)
426: {
427:
428: new_diff = i->total_length - i->left->total_length
429: + RIGHT_TOTAL_LENGTH (i->left) - LEFT_TOTAL_LENGTH (i->left);
430: if (abs (new_diff) >= old_diff)
431: break;
432: i = rotate_right (i);
433: balance_an_interval (i->right);
434: }
435: else if (old_diff < 0)
436: {
437:
438: new_diff = i->total_length - i->right->total_length
439: + LEFT_TOTAL_LENGTH (i->right) - RIGHT_TOTAL_LENGTH (i->right);
440: if (abs (new_diff) >= -old_diff)
441: break;
442: i = rotate_left (i);
443: balance_an_interval (i->left);
444: }
445: else
446: break;
447: }
448: return i;
449: }
450:
451:
452:
453:
454: static INLINE INTERVAL
455: balance_possible_root_interval (interval)
456: register INTERVAL interval;
457: {
458: Lisp_Object parent;
459: int have_parent = 0;
460:
461: if (!INTERVAL_HAS_OBJECT (interval) && !INTERVAL_HAS_PARENT (interval))
462: return interval;
463:
464: if (INTERVAL_HAS_OBJECT (interval))
465: {
466: have_parent = 1;
467: GET_INTERVAL_OBJECT (parent, interval);
468: }
469: interval = balance_an_interval (interval);
470:
471: if (have_parent)
472: {
473: if (BUFFERP (parent))
474: BUF_INTERVALS (XBUFFER (parent)) = interval;
475: else if (STRINGP (parent))
476: STRING_SET_INTERVALS (parent, interval);
477: }
478:
479: return interval;
480: }
481:
482:
483:
484:
485: static INTERVAL
486: balance_intervals_internal (tree)
487: register INTERVAL tree;
488: {
489:
490: if (tree->left)
491: balance_intervals_internal (tree->left);
492: if (tree->right)
493: balance_intervals_internal (tree->right);
494: return balance_an_interval (tree);
495: }
496:
497:
498:
499: INTERVAL
500: balance_intervals (tree)
501: INTERVAL tree;
502: {
503: if (tree == NULL_INTERVAL)
504: return NULL_INTERVAL;
505:
506: return balance_intervals_internal (tree);
507: }
508: ^L
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522: INTERVAL
523: split_interval_right (interval, offset)
524: INTERVAL interval;
525: int offset;
526: {
527: INTERVAL new = make_interval ();
528: int position = interval->position;
529: int new_length = LENGTH (interval) - offset;
530:
531: new->position = position + offset;
532: SET_INTERVAL_PARENT (new, interval);
533:
534: if (NULL_RIGHT_CHILD (interval))
535: {
536: interval->right = new;
537: new->total_length = new_length;
538: CHECK_TOTAL_LENGTH (new);
539: }
540: else
541: {
542:
543: new->right = interval->right;
544: SET_INTERVAL_PARENT (interval->right, new);
545: interval->right = new;
546: new->total_length = new_length + new->right->total_length;
547: CHECK_TOTAL_LENGTH (new);
548: balance_an_interval (new);
549: }
550:
551: balance_possible_root_interval (interval);
552:
553: return new;
554: }
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569: INTERVAL
570: split_interval_left (interval, offset)
571: INTERVAL interval;
572: int offset;
573: {
574: INTERVAL new = make_interval ();
575: int new_length = offset;
576:
577: new->position = interval->position;
578: interval->position = interval->position + offset;
579: SET_INTERVAL_PARENT (new, interval);
580:
581: if (NULL_LEFT_CHILD (interval))
582: {
583: interval->left = new;
584: new->total_length = new_length;
585: CHECK_TOTAL_LENGTH (new);
586: }
587: else
588: {
589:
590: new->left = interval->left;
591: SET_INTERVAL_PARENT (new->left, new);
592: interval->left = new;
593: new->total_length = new_length + new->left->total_length;
594: CHECK_TOTAL_LENGTH (new);
595: balance_an_interval (new);
596: }
597:
598: balance_possible_root_interval (interval);
599:
600: return new;
601: }
602: ^L
603:
604:
605:
606:
607:
608:
609:
610:
611: int
612: interval_start_pos (source)
613: INTERVAL source;
614: {
615: Lisp_Object parent;
616:
617: if (NULL_INTERVAL_P (source))
618: return 0;
619:
620: if (! INTERVAL_HAS_OBJECT (source))
621: return 0;
622: GET_INTERVAL_OBJECT (parent, source);
623: if (BUFFERP (parent))
624: return BUF_BEG (XBUFFER (parent));
625: return 0;
626: }
627:
628:
629:
630:
631:
632: