From: Andreas Politz Date: Tue, 7 Feb 2017 16:56:50 +0000 (+0100) Subject: Provide a new tree data-structure for overlays. X-Git-Tag: emacs-29.0.90~1616^2~406^2~70 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=8d7bdfa3fca076b34aaf86548d3243bee11872ad;p=emacs.git Provide a new tree data-structure for overlays. * src/itree.c (interval_generator_narrow, interval_generator_next) (interval_node_init, interval_node_begin) (interval_node_end, interval_node_set_region) (interval_tree_create, interval_tree_clear) (interval_tree_init, interval_tree_destroy) (interval_tree_size, interval_tree_insert) (interval_tree_contains, interval_tree_remove) (interval_tree_validate, interval_tree_iter_start) (interval_tree_iter_finish, interval_tree_iter_next) (interval_tree_iter_ensure_space, interval_tree_max_height) (interval_tree_insert_gap, interval_tree_delete_gap) (interval_generator_create, interval_generator_reset) (interval_generator_ensure_space, interval_node_intersects) (interval_generator_next, interval_generator_narrow) (interval_generator_destroy, interval_stack_create) (interval_stack_destroy, interval_stack_clear) (interval_stack_ensure_space, interval_stack_push) (interval_stack_push_flagged, interval_stack_pop) (interval_tree_update_limit, interval_tree_inherit_offset) (interval_tree_propagate_limit, interval_tree_rotate_left) (interval_tree_rotate_right, interval_tree_insert_fix) (interval_tree_remove_fix, interval_tree_transplant) (interval_tree_subtree_min): New file and new functions. * src/itree.h: New file. * configure.ac: Create Makefile for manual overlay tests. * src/Makefile.in: Add itree.o target. * src/alloc.c (build_overlay, mark_overlay, mark_buffer) (sweep_misc, sweep_buffers): Adapt to new tree data-structure. * src/buffer.c (overlays_in, overlays_at): Remove unused arguments prev_ptr and change_req, adapt to new data-structure and reuse code. (copy_overlays, drop_overlays, delete_all_overlays) (reset_buffer, kill-buffer, buffer-swap-text, next_overlay_change) (previous_overlay_change, mouse_face_overlay_overlaps) (disable_line_numbers_overlay_at_eob, overlay_touches_p) (overlay_strings, adjust_overlays_for_insert) (adjust_overlays_for_delete, overlayp, make-overlay, move-overlay) (delete-overlay, overlay-start, overlay-end, overlay-buffer) (overlay-properties, overlays-at, overlays-in) (next-overlay-change, previous-overlay-change, overlay-put) (overlay-get, report_overlay_modification, evaporate_overlays) (init_buffer_once): Adapt to changes and tree data-structure. (overlay-lists, overlay-recenter): Funtions are now obsolete, but kept anyway. (set_buffer_overlays_before, set_buffer_overlays_after) (recenter_overlay_lists,fix_start_end_in_overlays,fix_overlays_before) (unchain_overlay,): Removed functions of the old list data-structure. (swap_buffer_overlays, make_sortvec_item): New functions. (sort_overlays): Adapt to changes and tree data-structure. (sortvec): Moved to buffer.h . (make_lispy_interval_node, overlay_tree, overlay-tree) [ITREE_DEBUG]: New debugging functions. * src/buffer.h (overlays_before, overlays_after): Removed struct member of the list data-structure. (overlays): Added tree struct member. (sortvec): Moved here from buffer.c . (GET_OVERLAYS_AT): Adapt to changes. (set_buffer_intervals, OVERLAY_START, OVERLAY_END, OVERLAY_PLIST): Adapt to tree data-structure. (OVERLAY_POSITION): Removed macro of the list data-structure. (OVERLAY_REAR_ADVANCE_P, OVERLAY_FRONT_ADVANCE_P): New macros. (overlay_start, overlay_end) (set_overlay_region, maybe_alloc_buffer_overlays) (free_buffer_overlays, add_buffer_overlay) (remove_buffer_overlay, buffer_overlay_iter_start) (buffer_overlay_iter_next, buffer_overlay_iter_finish) (buffer_overlay_iter_narrow): New functions. (compare_overlays, make_sortvec_item): Export functions. * src/editfns.c (overlays_around): Reuse overlays_in. (get-pos-property): Adapt to tree data-structure. (transpose-regions): Remove call to deleted function. * src/fileio.c: (insert-file-contents): Remove references to deleted struct member. * src/fns.c (internal_equal): Adapt to tree data-structure. * src/indent.c (check_display_width): Adapt to tree data-structure. (skip_invisible): Remove call to deleted function. * src/insdel.c (adjust_markers_for_insert): Remove calls to deleted functions. * src/intervals.c (adjust_for_invis_intang): Adapt to tree data-structure. * src/keyboard.c (adjust_point_for_property): Adapt to tree data-structure. * src/lisp.h (Lisp_Overlay): Modified struct layout. * src/print.c (temp_output_buffer_setup, print_object): Adapt to tree data-structure. * src/textprop.c (get_char_property_and_overlay): Adapt to tree data-structure. Take advantage of the new data-structure. * src/window.h (overlay_matches_window): New function. * src/xdisp.h (next_overlay_change): Removed function. Use next-overlay-change, which does not use xmalloc anymore. (handle_single_display_spec, load_overlay_strings) (back_to_previous_visible_line_start, note_mouse_highlight): Adapt to tree data-structure. (move_it_to, display_line): Remove calls to deleted functions. * src/xfaces.c (face_at_buffer_position): Adapt to changes and tree data-structure. * test/src/buffer-tests.el: Many tests regarding overlays added. * test/manual/noverlay/itree-tests.c: New file with tests of the tree data-structure on the C level. * test/manual/noverlay/Makefile.in: New file. * test/manual/noverlay/check-sanitize.sh: New file. * test/manual/noverlay/emacs-compat.h: New file. * test/manual/noverlay/.gitignore: New file. * test/manual/noverlay/overlay-perf.el: New file providing performance tests. * test/manual/noverlay/many-errors.h: New file. --- diff --git a/configure.ac b/configure.ac index eba95e2fb84..76cf5570b52 100644 --- a/configure.ac +++ b/configure.ac @@ -5495,6 +5495,7 @@ if test -f "$srcdir/$opt_makefile.in"; then dnl Again, it's best not to use a variable. Though you can add dnl ", [], [opt_makefile='$opt_makefile']" and it should work. AC_CONFIG_FILES([test/Makefile]) + AC_CONFIG_FILES([test/manual/noverlay/Makefile]) fi diff --git a/src/Makefile.in b/src/Makefile.in index 9a8c9c85f04..8a8df03e49f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -395,6 +395,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ $(XWIDGETS_OBJ) \ profiler.o decompress.o \ thread.o systhread.o \ + itree.o \ $(if $(HYBRID_MALLOC),sheap.o) \ $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) diff --git a/src/alloc.c b/src/alloc.c index 2e6399e7f8d..15a6fc43b72 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -43,6 +43,7 @@ along with GNU Emacs. If not, see . */ #include "frame.h" #include "blockinput.h" #include "termhooks.h" /* For struct terminal. */ +#include "itree.h" #ifdef HAVE_WINDOW_SYSTEM #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ @@ -3835,16 +3836,19 @@ free_save_value (Lisp_Object save) /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ Lisp_Object -build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist) +build_overlay (ptrdiff_t begin, ptrdiff_t end, + bool front_advance, bool rear_advance, + Lisp_Object plist) { - register Lisp_Object overlay; + Lisp_Object ov = allocate_misc (Lisp_Misc_Overlay); + struct interval_node *node = xmalloc (sizeof (*node)); - overlay = allocate_misc (Lisp_Misc_Overlay); - OVERLAY_START (overlay) = start; - OVERLAY_END (overlay) = end; - set_overlay_plist (overlay, plist); - XOVERLAY (overlay)->next = NULL; - return overlay; + interval_node_init (node, begin, end, front_advance, + rear_advance, ov); + XOVERLAY (ov)->interval = node; + XOVERLAY (ov)->buffer = NULL; + set_overlay_plist (ov, plist); + return ov; } DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, @@ -6280,16 +6284,10 @@ mark_compiled (struct Lisp_Vector *ptr) /* Mark the chain of overlays starting at PTR. */ static void -mark_overlay (struct Lisp_Overlay *ptr) +mark_overlay (struct Lisp_Overlay *ov) { - for (; ptr && !ptr->gcmarkbit; ptr = ptr->next) - { - ptr->gcmarkbit = 1; - /* These two are always markers and can be marked fast. */ - XMARKER (ptr->start)->gcmarkbit = 1; - XMARKER (ptr->end)->gcmarkbit = 1; - mark_object (ptr->plist); - } + ov->gcmarkbit = 1; + mark_object (ov->plist); } /* Mark Lisp_Objects and special pointers in BUFFER. */ @@ -6308,8 +6306,15 @@ mark_buffer (struct buffer *buffer) a special way just before the sweep phase, and after stripping some of its elements that are not needed any more. */ - mark_overlay (buffer->overlays_before); - mark_overlay (buffer->overlays_after); + if (buffer->overlays) + { + struct interval_node *node; + buffer_overlay_iter_start (buffer, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING); + + while ((node = buffer_overlay_iter_next (buffer))) + mark_overlay (XOVERLAY (node->data)); + buffer_overlay_iter_finish (buffer); + } /* If this is an indirect buffer, mark its base buffer. */ if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer)) @@ -7090,6 +7095,11 @@ sweep_misc (void) unchain_marker (&mblk->markers[i].m.u_marker); else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Finalizer) unchain_finalizer (&mblk->markers[i].m.u_finalizer); + else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Overlay) + { + xfree (mblk->markers[i].m.u_overlay.interval); + mblk->markers[i].m.u_overlay.interval = NULL; + } #ifdef HAVE_MODULES else if (mblk->markers[i].m.u_any.type == Lisp_Misc_User_Ptr) { @@ -7145,6 +7155,7 @@ sweep_buffers (void) if (!VECTOR_MARKED_P (buffer)) { *bprev = buffer->next; + free_buffer_overlays (buffer); lisp_free (buffer); } else diff --git a/src/buffer.c b/src/buffer.c index 76670b89545..21c040ad0e1 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -44,6 +44,7 @@ along with GNU Emacs. If not, see . */ #include "keymap.h" #include "frame.h" #include "xwidget.h" +#include "itree.h" #ifdef WINDOWSNT #include "w32heap.h" /* for mmap_* */ @@ -120,7 +121,7 @@ static Lisp_Object QSFundamental; /* A string "Fundamental". */ static void alloc_buffer_text (struct buffer *, ptrdiff_t); static void free_buffer_text (struct buffer *b); -static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *); +static void copy_overlays (struct buffer *, struct buffer *); static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t); static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool); @@ -600,51 +601,30 @@ even if it is dead. The return value is never nil. */) } -/* Return a list of overlays which is a copy of the overlay list - LIST, but for buffer B. */ +/* Copy overlays of buffer FROM to buffer TO. */ -static struct Lisp_Overlay * -copy_overlays (struct buffer *b, struct Lisp_Overlay *list) +static void +copy_overlays (struct buffer *from, struct buffer *to) { - struct Lisp_Overlay *result = NULL, *tail = NULL; + eassert (to && ! to->overlays); - for (; list; list = list->next) - { - Lisp_Object overlay, start, end; - struct Lisp_Marker *m; - - eassert (MARKERP (list->start)); - m = XMARKER (list->start); - start = build_marker (b, m->charpos, m->bytepos); - XMARKER (start)->insertion_type = m->insertion_type; - - eassert (MARKERP (list->end)); - m = XMARKER (list->end); - end = build_marker (b, m->charpos, m->bytepos); - XMARKER (end)->insertion_type = m->insertion_type; - - overlay = build_overlay (start, end, Fcopy_sequence (list->plist)); - if (tail) - tail = tail->next = XOVERLAY (overlay); - else - result = tail = XOVERLAY (overlay); - } - - return result; -} + struct interval_node *node; -/* Set an appropriate overlay of B. */ + if (! from->overlays) + return; -static void -set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o) -{ - b->overlays_before = o; -} + buffer_overlay_iter_start (from, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING); -static void -set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o) -{ - b->overlays_after = o; + while ((node = buffer_overlay_iter_next (from))) + { + Lisp_Object ov = node->data; + Lisp_Object copy = build_overlay (node->begin, node->end, + node->front_advance, + node->rear_advance, + Fcopy_sequence (OVERLAY_PLIST (ov))); + add_buffer_overlay (to, XOVERLAY (copy)); + } + buffer_overlay_iter_finish (from); } /* Clone per-buffer values of buffer FROM. @@ -681,8 +661,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to) memcpy (to->local_flags, from->local_flags, sizeof to->local_flags); - set_buffer_overlays_before (to, copy_overlays (to, from->overlays_before)); - set_buffer_overlays_after (to, copy_overlays (to, from->overlays_after)); + copy_overlays (from, to); /* Get (a copy of) the alist of Lisp-level local variables of FROM and install that in TO. */ @@ -867,17 +846,16 @@ CLONE nil means the indirect buffer's state is reset to default values. */) return buf; } -/* Mark OV as no longer associated with B. */ +/* Mark OV as no longer associated with its buffer. */ static void -drop_overlay (struct buffer *b, struct Lisp_Overlay *ov) +drop_overlay (struct Lisp_Overlay *ov) { - eassert (b == XBUFFER (Fmarker_buffer (ov->start))); - modify_overlay (b, marker_position (ov->start), - marker_position (ov->end)); - unchain_marker (XMARKER (ov->start)); - unchain_marker (XMARKER (ov->end)); + if (! ov->buffer) + return; + modify_overlay (ov->buffer, overlay_start (ov), overlay_end (ov)); + remove_buffer_overlay (ov->buffer, ov); } /* Delete all overlays of B and reset its overlay lists. */ @@ -885,26 +863,20 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov) void delete_all_overlays (struct buffer *b) { - struct Lisp_Overlay *ov, *next; + struct interval_node *node; - /* FIXME: Since each drop_overlay will scan BUF_MARKERS to unlink its - markers, we have an unneeded O(N^2) behavior here. */ - for (ov = b->overlays_before; ov; ov = next) - { - drop_overlay (b, ov); - next = ov->next; - ov->next = NULL; - } + if (! b->overlays) + return; - for (ov = b->overlays_after; ov; ov = next) + buffer_overlay_iter_start (b, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING); + while ((node = buffer_overlay_iter_next (b))) { - drop_overlay (b, ov); - next = ov->next; - ov->next = NULL; + modify_overlay (b, node->begin, node->end); + /* Where are the nodes freed ? --ap */ + XOVERLAY (node->data)->buffer = NULL; } - - set_buffer_overlays_before (b, NULL); - set_buffer_overlays_after (b, NULL); + buffer_overlay_iter_finish (b); + interval_tree_clear (b->overlays); } /* Reinitialize everything about a buffer except its name and contents @@ -932,9 +904,7 @@ reset_buffer (register struct buffer *b) b->auto_save_failure_time = 0; bset_auto_save_file_name (b, Qnil); bset_read_only (b, Qnil); - set_buffer_overlays_before (b, NULL); - set_buffer_overlays_after (b, NULL); - b->overlay_center = BEG; + b->overlays = NULL; bset_mark_active (b, Qnil); bset_point_before_scroll (b, Qnil); bset_file_format (b, Qnil); @@ -1843,10 +1813,8 @@ cleaning up all windows currently displaying the buffer to be killed. */) /* Perhaps we should explicitly free the interval tree here... */ } - /* Since we've unlinked the markers, the overlays can't be here any more - either. */ - b->overlays_before = NULL; - b->overlays_after = NULL; + delete_all_overlays (b); + free_buffer_overlays (b); /* Reset the local variables, so that this buffer's local values won't be protected from GC. They would be protected @@ -2254,6 +2222,31 @@ advance_to_char_boundary (ptrdiff_t byte_pos) return byte_pos; } +static void +swap_buffer_overlays (struct buffer *buffer, struct buffer *other) +{ + struct interval_node *node; + + if (buffer->overlays) + { + buffer_overlay_iter_start (buffer, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING); + while ((node = buffer_overlay_iter_next (buffer))) + XOVERLAY (node->data)->buffer = other; + buffer_overlay_iter_finish (buffer); + } + if (other->overlays) + { + buffer_overlay_iter_start (other, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING); + while ((node = buffer_overlay_iter_next (other))) + XOVERLAY (node->data)->buffer = buffer; + buffer_overlay_iter_finish (other); + } + /* Swap the interval trees. */ + void *tmp = buffer->overlays; + buffer->overlays = other->overlays; + other->overlays = tmp; +} + DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, 1, 1, 0, doc: /* Swap the text between current buffer and BUFFER. @@ -2324,9 +2317,6 @@ results, see Info node `(elisp)Swapping Text'. */) swapfield (bidi_paragraph_cache, struct region_cache *); current_buffer->prevent_redisplay_optimizations_p = 1; other_buffer->prevent_redisplay_optimizations_p = 1; - swapfield (overlays_before, struct Lisp_Overlay *); - swapfield (overlays_after, struct Lisp_Overlay *); - swapfield (overlay_center, ptrdiff_t); swapfield_ (undo_list, Lisp_Object); swapfield_ (mark, Lisp_Object); swapfield_ (enable_multibyte_characters, Lisp_Object); @@ -2349,6 +2339,7 @@ results, see Info node `(elisp)Swapping Text'. */) current_buffer->text->end_unchanged = current_buffer->text->gpt; other_buffer->text->beg_unchanged = other_buffer->text->gpt; other_buffer->text->end_unchanged = other_buffer->text->gpt; + swap_buffer_overlays (current_buffer, other_buffer); { struct Lisp_Marker *m; for (m = BUF_MARKERS (current_buffer); m; m = m->next) @@ -2763,285 +2754,160 @@ swap_out_buffer_local_variables (struct buffer *b) } } } + -/* Find all the overlays in the current buffer that contain position POS. +/* Find all the overlays in the current buffer that overlap the range + [BEG, END). + + If EMPTY is true, include empty overlays in that range and also at + END, provided END denotes the position at the end of the buffer. + Return the number found, and store them in a vector in *VEC_PTR. Store in *LEN_PTR the size allocated for the vector. Store in *NEXT_PTR the next position after POS where an overlay starts, - or ZV if there are no more overlays between POS and ZV. - Store in *PREV_PTR the previous position before POS where an overlay ends, - or where an overlay starts which ends at or after POS; - or BEGV if there are no such overlays from BEGV to POS. - NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info. + or ZV if there are no more overlays. + NEXT_PTR may be 0, meaning don't store that info. *VEC_PTR and *LEN_PTR should contain a valid vector and size when this function is called. - If EXTEND, make the vector bigger if necessary. - If not, never extend the vector, - and store only as many overlays as will fit. + If EXTEND, make the vector bigger if necessary. If not, never + extend the vector, and store only as many overlays as will fit. But still return the total number of overlays. - - If CHANGE_REQ, any position written into *PREV_PTR or - *NEXT_PTR is guaranteed to be not equal to POS, unless it is the - default (BEGV or ZV). */ +*/ ptrdiff_t -overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr, - ptrdiff_t *len_ptr, - ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req) +overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend, + Lisp_Object **vec_ptr, ptrdiff_t *len_ptr, bool empty, + ptrdiff_t *next_ptr) { - Lisp_Object overlay, start, end; - struct Lisp_Overlay *tail; ptrdiff_t idx = 0; ptrdiff_t len = *len_ptr; - Lisp_Object *vec = *vec_ptr; ptrdiff_t next = ZV; - ptrdiff_t prev = BEGV; - bool inhibit_storing = 0; - - for (tail = current_buffer->overlays_before; tail; tail = tail->next) - { - ptrdiff_t startpos, endpos; + Lisp_Object *vec = *vec_ptr; - XSETMISC (overlay, tail); + struct interval_node *node; - start = OVERLAY_START (overlay); - end = OVERLAY_END (overlay); - endpos = OVERLAY_POSITION (end); - if (endpos < pos) - { - if (prev < endpos) - prev = endpos; - break; - } - startpos = OVERLAY_POSITION (start); - /* This one ends at or after POS - so its start counts for PREV_PTR if it's before POS. */ - if (prev < startpos && startpos < pos) - prev = startpos; - if (endpos == pos) - continue; - if (startpos <= pos) - { - if (idx == len) - { - /* The supplied vector is full. - Either make it bigger, or don't store any more in it. */ - if (extend) - { - vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, - sizeof *vec); - *vec_ptr = vec; - len = *len_ptr; - } - else - inhibit_storing = 1; - } + if (! current_buffer->overlays) + return idx; - if (!inhibit_storing) - vec[idx] = overlay; - /* Keep counting overlays even if we can't return them all. */ - idx++; - } - else if (startpos < next) - next = startpos; - } + buffer_overlay_iter_start (current_buffer, beg, + /* Find empty OV at Z ? */ + (end >= Z && empty) ? Z + 1 : ZV, + ITREE_ASCENDING); - for (tail = current_buffer->overlays_after; tail; tail = tail->next) + while ((node = buffer_overlay_iter_next (current_buffer))) { - ptrdiff_t startpos, endpos; - - XSETMISC (overlay, tail); - - start = OVERLAY_START (overlay); - end = OVERLAY_END (overlay); - startpos = OVERLAY_POSITION (start); - if (pos < startpos) - { - if (startpos < next) - next = startpos; - break; - } - endpos = OVERLAY_POSITION (end); - if (pos < endpos) - { - if (idx == len) - { - if (extend) - { - vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, - sizeof *vec); - *vec_ptr = vec; - len = *len_ptr; - } - else - inhibit_storing = 1; - } + if (node->begin > end) + { + next = min (next, node->begin); + break; + } + else if (node->begin == end) + { + next = node->begin; + if ((! empty || end < Z) && beg < end) + break; + } - if (!inhibit_storing) - vec[idx] = overlay; - idx++; + if (! empty && node->begin == node->end) + continue; - if (startpos < pos && startpos > prev) - prev = startpos; - } - else if (endpos < pos && endpos > prev) - prev = endpos; - else if (endpos == pos && startpos > prev - && (!change_req || startpos < pos)) - prev = startpos; + if (extend && idx == len) + { + vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, + sizeof *vec); + *vec_ptr = vec; + len = *len_ptr; + } + if (idx < len) + vec[idx] = node->data; + /* Keep counting overlays even if we can't return them all. */ + idx++; } - + buffer_overlay_iter_finish (current_buffer); if (next_ptr) - *next_ptr = next; - if (prev_ptr) - *prev_ptr = prev; + *next_ptr = next ? next : ZV; + return idx; } - -/* Find all the overlays in the current buffer that overlap the range - BEG-END, or are empty at BEG, or are empty at END provided END - denotes the position at the end of the current buffer. - Return the number found, and store them in a vector in *VEC_PTR. - Store in *LEN_PTR the size allocated for the vector. - Store in *NEXT_PTR the next position after POS where an overlay starts, - or ZV if there are no more overlays. - Store in *PREV_PTR the previous position before POS where an overlay ends, - or BEGV if there are no previous overlays. - NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info. +/* Find all non-empty overlays in the current buffer that contain + position POS. - *VEC_PTR and *LEN_PTR should contain a valid vector and size - when this function is called. + See overlays_in for the meaning of the arguments. + */ - If EXTEND, make the vector bigger if necessary. - If not, never extend the vector, - and store only as many overlays as will fit. - But still return the total number of overlays. */ +ptrdiff_t +overlays_at (ptrdiff_t pos, bool extend, + Lisp_Object **vec_ptr, ptrdiff_t *len_ptr, + ptrdiff_t *next_ptr) +{ + return overlays_in (pos, pos + 1, extend, vec_ptr, len_ptr, false, next_ptr); +} -static ptrdiff_t -overlays_in (EMACS_INT beg, EMACS_INT end, bool extend, - Lisp_Object **vec_ptr, ptrdiff_t *len_ptr, - ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr) +ptrdiff_t +next_overlay_change (ptrdiff_t pos) { - Lisp_Object overlay, ostart, oend; - struct Lisp_Overlay *tail; - ptrdiff_t idx = 0; - ptrdiff_t len = *len_ptr; - Lisp_Object *vec = *vec_ptr; ptrdiff_t next = ZV; - ptrdiff_t prev = BEGV; - bool inhibit_storing = 0; - bool end_is_Z = end == Z; + struct interval_node *node; - for (tail = current_buffer->overlays_before; tail; tail = tail->next) - { - ptrdiff_t startpos, endpos; + if (! current_buffer->overlays) + return next; - XSETMISC (overlay, tail); - - ostart = OVERLAY_START (overlay); - oend = OVERLAY_END (overlay); - endpos = OVERLAY_POSITION (oend); - if (endpos < beg) - { - if (prev < endpos) - prev = endpos; - break; - } - startpos = OVERLAY_POSITION (ostart); - /* Count an interval if it overlaps the range, is empty at the - start of the range, or is empty at END provided END denotes the - end of the buffer. */ - if ((beg < endpos && startpos < end) - || (startpos == endpos - && (beg == endpos || (end_is_Z && endpos == end)))) - { - if (idx == len) - { - /* The supplied vector is full. - Either make it bigger, or don't store any more in it. */ - if (extend) - { - vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, - sizeof *vec); - *vec_ptr = vec; - len = *len_ptr; - } - else - inhibit_storing = 1; - } - - if (!inhibit_storing) - vec[idx] = overlay; - /* Keep counting overlays even if we can't return them all. */ - idx++; - } - else if (startpos < next) - next = startpos; + buffer_overlay_iter_start (current_buffer, pos, ZV, ITREE_ASCENDING); + while ((node = buffer_overlay_iter_next (current_buffer))) + { + if (node->begin > pos) + { + /* If we reach this branch, node->begin must be the least upper bound + of pos, because the search is limited to [pos,next) . */ + eassert (node->begin < next); + next = node->begin; + break; + } + else if (node->begin < node->end && node->end < next) + { + next = node->end; + buffer_overlay_iter_narrow (current_buffer, pos, next); + } } + buffer_overlay_iter_finish (current_buffer); - for (tail = current_buffer->overlays_after; tail; tail = tail->next) - { - ptrdiff_t startpos, endpos; + return next; +} - XSETMISC (overlay, tail); +ptrdiff_t +previous_overlay_change (ptrdiff_t pos) +{ + struct interval_node *node; + ptrdiff_t prev = BEGV; - ostart = OVERLAY_START (overlay); - oend = OVERLAY_END (overlay); - startpos = OVERLAY_POSITION (ostart); - if (end < startpos) - { - if (startpos < next) - next = startpos; - break; - } - endpos = OVERLAY_POSITION (oend); - /* Count an interval if it overlaps the range, is empty at the - start of the range, or is empty at END provided END denotes the - end of the buffer. */ - if ((beg < endpos && startpos < end) - || (startpos == endpos - && (beg == endpos || (end_is_Z && endpos == end)))) - { - if (idx == len) - { - if (extend) - { - vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, - sizeof *vec); - *vec_ptr = vec; - len = *len_ptr; - } - else - inhibit_storing = 1; - } + if (! current_buffer->overlays) + return prev; - if (!inhibit_storing) - vec[idx] = overlay; - idx++; - } - else if (endpos < beg && endpos > prev) - prev = endpos; + buffer_overlay_iter_start (current_buffer, BEGV, pos, ITREE_DESCENDING); + while ((node = buffer_overlay_iter_next (current_buffer))) + { + if (node->end < pos) + prev = node->end; + else + prev = max (prev, node->begin); + buffer_overlay_iter_narrow (current_buffer, prev, pos); } + buffer_overlay_iter_finish (current_buffer); - if (next_ptr) - *next_ptr = next; - if (prev_ptr) - *prev_ptr = prev; - return idx; + return prev; } - /* Return true if there exists an overlay with a non-nil `mouse-face' property overlapping OVERLAY. */ bool mouse_face_overlay_overlaps (Lisp_Object overlay) { - ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay)); - ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay)); + ptrdiff_t start = OVERLAY_START (overlay); + ptrdiff_t end = OVERLAY_END (overlay); ptrdiff_t n, i, size; Lisp_Object *v, tem; Lisp_Object vbuf[10]; @@ -3049,11 +2915,11 @@ mouse_face_overlay_overlaps (Lisp_Object overlay) size = ARRAYELTS (vbuf); v = vbuf; - n = overlays_in (start, end, 0, &v, &size, NULL, NULL); + n = overlays_in (start, end, 0, &v, &size, true, NULL); if (n > size) { SAFE_NALLOCA (v, 1, n); - overlays_in (start, end, 0, &v, &n, NULL, NULL); + overlays_in (start, end, 0, &v, &n, true, NULL); } for (i = 0; i < n; ++i) @@ -3095,52 +2961,34 @@ disable_line_numbers_overlay_at_eob (void) } -/* Fast function to just test if we're at an overlay boundary. */ +/* Fast function to just test if we're at an overlay boundary. + + Returns true if some overlay starts or ends (or both) at POS, +*/ bool overlay_touches_p (ptrdiff_t pos) { - Lisp_Object overlay; - struct Lisp_Overlay *tail; - - for (tail = current_buffer->overlays_before; tail; tail = tail->next) - { - ptrdiff_t endpos; + struct interval_node *node; + bool result = false; - XSETMISC (overlay ,tail); - eassert (OVERLAYP (overlay)); + if (! current_buffer->overlays) + return false; - endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); - if (endpos < pos) - break; - if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos) - return 1; - } + /* We need to find overlays ending in pos, as well as empty ones at + pos. */ + buffer_overlay_iter_start (current_buffer, + pos - 1, pos + 1, ITREE_DESCENDING); - for (tail = current_buffer->overlays_after; tail; tail = tail->next) - { - ptrdiff_t startpos; + while (! result && (node = buffer_overlay_iter_next (current_buffer))) + result = (node->begin == pos || node->end == pos); - XSETMISC (overlay, tail); - eassert (OVERLAYP (overlay)); + buffer_overlay_iter_finish (current_buffer); - startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); - if (pos < startpos) - break; - if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos) - return 1; - } - return 0; + return result; } - -struct sortvec -{ - Lisp_Object overlay; - ptrdiff_t beg, end; - EMACS_INT priority; - EMACS_INT spriority; /* Secondary priority. */ -}; -static int + +int compare_overlays (const void *v1, const void *v2) { const struct sortvec *s1 = v1; @@ -3169,6 +3017,33 @@ compare_overlays (const void *v1, const void *v2) return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1; } +void +make_sortvec_item (struct sortvec *item, Lisp_Object overlay) +{ + Lisp_Object tem; + /* This overlay is good and counts: put it into sortvec. */ + item->overlay = overlay; + item->beg = OVERLAY_START (overlay); + item->end = OVERLAY_END (overlay); + tem = Foverlay_get (overlay, Qpriority); + if (NILP (tem)) + { + item->priority = 0; + item->spriority = 0; + } + else if (INTEGERP (tem)) + { + item->priority = XINT (tem); + item->spriority = 0; + } + else if (CONSP (tem)) + { + Lisp_Object car = XCAR (tem); + Lisp_Object cdr = XCDR (tem); + item->priority = INTEGERP (car) ? XINT (car) : 0; + item->spriority = INTEGERP (cdr) ? XINT (cdr) : 0; + } +} /* Sort an array of overlays by priority. The array is modified in place. The return value is the new size; this may be smaller than the original size if some of the overlays were invalid or were window-specific. */ @@ -3185,47 +3060,18 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w) for (i = 0, j = 0; i < noverlays; i++) { - Lisp_Object tem; Lisp_Object overlay; overlay = overlay_vec[i]; if (OVERLAYP (overlay) - && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 - && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) + && OVERLAY_START (overlay) > 0 + && OVERLAY_END (overlay) > 0) { - /* If we're interested in a specific window, then ignore - overlays that are limited to some other window. */ - if (w) - { - Lisp_Object window; - - window = Foverlay_get (overlay, Qwindow); - if (WINDOWP (window) && XWINDOW (window) != w) - continue; - } - - /* This overlay is good and counts: put it into sortvec. */ - sortvec[j].overlay = overlay; - sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay)); - sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay)); - tem = Foverlay_get (overlay, Qpriority); - if (NILP (tem)) - { - sortvec[j].priority = 0; - sortvec[j].spriority = 0; - } - else if (INTEGERP (tem)) - { - sortvec[j].priority = XINT (tem); - sortvec[j].spriority = 0; - } - else if (CONSP (tem)) - { - Lisp_Object car = XCAR (tem); - Lisp_Object cdr = XCDR (tem); - sortvec[j].priority = INTEGERP (car) ? XINT (car) : 0; - sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0; - } + /* If we're interested in a specific window, then ignore + overlays that are limited to some other window. */ + if (w && ! overlay_matches_window (w, overlay)) + continue; + make_sortvec_item (sortvec + j, overlay); j++; } } @@ -3340,68 +3186,44 @@ ptrdiff_t overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) { Lisp_Object overlay, window, str; - struct Lisp_Overlay *ov; - ptrdiff_t startpos, endpos; + ptrdiff_t obegin, oend; bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); + struct interval_node *node; overlay_heads.used = overlay_heads.bytes = 0; overlay_tails.used = overlay_tails.bytes = 0; - for (ov = current_buffer->overlays_before; ov; ov = ov->next) + + buffer_overlay_iter_start (current_buffer, + pos - 1, pos + 1, ITREE_DESCENDING); + while ((node = buffer_overlay_iter_next (current_buffer))) { - XSETMISC (overlay, ov); + overlay = node->data; eassert (OVERLAYP (overlay)); - startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); - endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); - if (endpos < pos) - break; - if (endpos != pos && startpos != pos) + obegin = node->begin; + oend = node->end; + + if (oend != pos && obegin != pos) continue; window = Foverlay_get (overlay, Qwindow); if (WINDOWP (window) && XWINDOW (window) != w) continue; - if (startpos == pos + if (obegin == pos && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) record_overlay_string (&overlay_heads, str, - (startpos == endpos + (obegin == oend ? Foverlay_get (overlay, Qafter_string) : Qnil), Foverlay_get (overlay, Qpriority), - endpos - startpos); - else if (endpos == pos + oend - obegin); + else if (oend == pos && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))) record_overlay_string (&overlay_tails, str, Qnil, Foverlay_get (overlay, Qpriority), - endpos - startpos); + oend - obegin); } - for (ov = current_buffer->overlays_after; ov; ov = ov->next) - { - XSETMISC (overlay, ov); - eassert (OVERLAYP (overlay)); + buffer_overlay_iter_finish (current_buffer); - startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); - endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); - if (startpos > pos) - break; - if (endpos != pos && startpos != pos) - continue; - window = Foverlay_get (overlay, Qwindow); - if (WINDOWP (window) && XWINDOW (window) != w) - continue; - if (startpos == pos - && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) - record_overlay_string (&overlay_heads, str, - (startpos == endpos - ? Foverlay_get (overlay, Qafter_string) - : Qnil), - Foverlay_get (overlay, Qpriority), - endpos - startpos); - else if (endpos == pos - && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))) - record_overlay_string (&overlay_tails, str, Qnil, - Foverlay_get (overlay, Qpriority), - endpos - startpos); - } if (overlay_tails.used > 1) qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr), cmp_for_strings); @@ -3456,385 +3278,26 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) } return 0; } - -/* Shift overlays in BUF's overlay lists, to center the lists at POS. */ - -void -recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) -{ - Lisp_Object overlay, beg, end; - struct Lisp_Overlay *prev, *tail, *next; - - /* See if anything in overlays_before should move to overlays_after. */ - - /* We don't strictly need prev in this loop; it should always be nil. - But we use it for symmetry and in case that should cease to be true - with some future change. */ - prev = NULL; - for (tail = buf->overlays_before; tail; prev = tail, tail = next) - { - next = tail->next; - XSETMISC (overlay, tail); - eassert (OVERLAYP (overlay)); - - beg = OVERLAY_START (overlay); - end = OVERLAY_END (overlay); - - if (OVERLAY_POSITION (end) > pos) - { - /* OVERLAY needs to be moved. */ - ptrdiff_t where = OVERLAY_POSITION (beg); - struct Lisp_Overlay *other, *other_prev; - - /* Splice the cons cell TAIL out of overlays_before. */ - if (prev) - prev->next = next; - else - set_buffer_overlays_before (buf, next); - - /* Search thru overlays_after for where to put it. */ - other_prev = NULL; - for (other = buf->overlays_after; other; - other_prev = other, other = other->next) - { - Lisp_Object otherbeg, otheroverlay; - - XSETMISC (otheroverlay, other); - eassert (OVERLAYP (otheroverlay)); - - otherbeg = OVERLAY_START (otheroverlay); - if (OVERLAY_POSITION (otherbeg) >= where) - break; - } - - /* Add TAIL to overlays_after before OTHER. */ - tail->next = other; - if (other_prev) - other_prev->next = tail; - else - set_buffer_overlays_after (buf, tail); - tail = prev; - } - else - /* We've reached the things that should stay in overlays_before. - All the rest of overlays_before must end even earlier, - so stop now. */ - break; - } - - /* See if anything in overlays_after should be in overlays_before. */ - prev = NULL; - for (tail = buf->overlays_after; tail; prev = tail, tail = next) - { - next = tail->next; - XSETMISC (overlay, tail); - eassert (OVERLAYP (overlay)); - - beg = OVERLAY_START (overlay); - end = OVERLAY_END (overlay); - - /* Stop looking, when we know that nothing further - can possibly end before POS. */ - if (OVERLAY_POSITION (beg) > pos) - break; - - if (OVERLAY_POSITION (end) <= pos) - { - /* OVERLAY needs to be moved. */ - ptrdiff_t where = OVERLAY_POSITION (end); - struct Lisp_Overlay *other, *other_prev; - - /* Splice the cons cell TAIL out of overlays_after. */ - if (prev) - prev->next = next; - else - set_buffer_overlays_after (buf, next); - - /* Search thru overlays_before for where to put it. */ - other_prev = NULL; - for (other = buf->overlays_before; other; - other_prev = other, other = other->next) - { - Lisp_Object otherend, otheroverlay; - - XSETMISC (otheroverlay, other); - eassert (OVERLAYP (otheroverlay)); - - otherend = OVERLAY_END (otheroverlay); - if (OVERLAY_POSITION (otherend) <= where) - break; - } - - /* Add TAIL to overlays_before before OTHER. */ - tail->next = other; - if (other_prev) - other_prev->next = tail; - else - set_buffer_overlays_before (buf, tail); - tail = prev; - } - } - - buf->overlay_center = pos; -} + void adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length) { /* After an insertion, the lists are still sorted properly, but we may need to update the value of the overlay center. */ - if (current_buffer->overlay_center >= pos) - current_buffer->overlay_center += length; + if (! current_buffer->overlays) + return; + interval_tree_insert_gap (current_buffer->overlays, pos, length); } void adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length) { - if (current_buffer->overlay_center < pos) - /* The deletion was to our right. No change needed; the before- and - after-lists are still consistent. */ - ; - else if (current_buffer->overlay_center - pos > length) - /* The deletion was to our left. We need to adjust the center value - to account for the change in position, but the lists are consistent - given the new value. */ - current_buffer->overlay_center -= length; - else - /* We're right in the middle. There might be things on the after-list - that now belong on the before-list. Recentering will move them, - and also update the center point. */ - recenter_overlay_lists (current_buffer, pos); -} - -/* Fix up overlays that were garbled as a result of permuting markers - in the range START through END. Any overlay with at least one - endpoint in this range will need to be unlinked from the overlay - list and reinserted in its proper place. - Such an overlay might even have negative size at this point. - If so, we'll make the overlay empty. */ -void -fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) -{ - Lisp_Object overlay; - struct Lisp_Overlay *before_list; - struct Lisp_Overlay *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. */ - struct Lisp_Overlay *beforep = NULL, *afterp = NULL; - /* 'Parent', likewise, indicates a cons cell or - current_buffer->overlays_before or overlays_after, depending - which loop we're in. */ - struct Lisp_Overlay *tail, *parent; - ptrdiff_t 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 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 = NULL, tail = current_buffer->overlays_before; tail;) - { - XSETMISC (overlay, tail); - - endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); - startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); - - /* If the overlay is backwards, make it empty. */ - if (endpos < startpos) - { - startpos = endpos; - Fset_marker (OVERLAY_START (overlay), make_number (startpos), - Qnil); - } - - if (endpos < start) - break; - - if (endpos < end - || (startpos >= start && startpos < end)) - { - /* Add it to the end of the wrong list. Later on, - recenter_overlay_lists will move it to the right place. */ - if (endpos < current_buffer->overlay_center) - { - if (!afterp) - after_list = tail; - else - afterp->next = tail; - afterp = tail; - } - else - { - if (!beforep) - before_list = tail; - else - beforep->next = tail; - beforep = tail; - } - if (!parent) - set_buffer_overlays_before (current_buffer, tail->next); - else - parent->next = tail->next; - tail = tail->next; - } - else - parent = tail, tail = parent->next; - } - for (parent = NULL, tail = current_buffer->overlays_after; tail;) - { - XSETMISC (overlay, tail); - - startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); - endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); - - /* If the overlay is backwards, make it empty. */ - if (endpos < startpos) - { - startpos = endpos; - Fset_marker (OVERLAY_START (overlay), make_number (startpos), - Qnil); - } - - if (startpos >= end) - break; - - if (startpos >= start - || (endpos >= start && endpos < end)) - { - if (endpos < current_buffer->overlay_center) - { - if (!afterp) - after_list = tail; - else - afterp->next = tail; - afterp = tail; - } - else - { - if (!beforep) - before_list = tail; - else - beforep->next = tail; - beforep = tail; - } - if (!parent) - set_buffer_overlays_after (current_buffer, tail->next); - else - parent->next = tail->next; - tail = tail->next; - } - else - parent = tail, tail = parent->next; - } - - /* Splice the constructed (wrong) lists into the buffer's lists, - and let the recenter function make it sane again. */ - if (beforep) - { - beforep->next = current_buffer->overlays_before; - set_buffer_overlays_before (current_buffer, before_list); - } - - if (afterp) - { - afterp->next = current_buffer->overlays_after; - set_buffer_overlays_after (current_buffer, after_list); - } - recenter_overlay_lists (current_buffer, current_buffer->overlay_center); -} - -/* We have two types of overlay: the one whose ending marker is - after-insertion-marker (this is the usual case) and the one whose - ending marker is before-insertion-marker. When `overlays_before' - contains overlays of the latter type and the former type in this - order and both overlays end at inserting position, inserting a text - increases only the ending marker of the latter type, which results - in incorrect ordering of `overlays_before'. - - This function fixes ordering of overlays in the slot - `overlays_before' of the buffer *BP. Before the insertion, `point' - was at PREV, and now is at POS. */ - -void -fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos) -{ - /* If parent is nil, replace overlays_before; otherwise, parent->next. */ - struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair; - Lisp_Object tem; - ptrdiff_t end UNINIT; - - /* After the insertion, the several overlays may be in incorrect - order. The possibility is that, in the list `overlays_before', - an overlay which ends at POS appears after an overlay which ends - at PREV. Since POS is greater than PREV, we must fix the - ordering of these overlays, by moving overlays ends at POS before - the overlays ends at PREV. */ - - /* At first, find a place where disordered overlays should be linked - 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 (tail - && (XSETMISC (tem, tail), - (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos)) - { - parent = tail; - tail = tail->next; - } - - /* 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 (!tail || end < prev || !tail->next) + if (! current_buffer->overlays) return; - - right_pair = parent; - parent = tail; - tail = tail->next; - - /* 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 indicated by the CDR of RIGHT_PAIR. If - we found an overlay which ends before PREV, the remaining - overlays are in correct order. */ - while (tail) - { - XSETMISC (tem, tail); - end = OVERLAY_POSITION (OVERLAY_END (tem)); - - if (end == pos) - { /* This overlay is disordered. */ - struct Lisp_Overlay *found = tail; - - /* Unlink the found overlay. */ - tail = found->next; - parent->next = tail; - /* Move an overlay at RIGHT_PLACE to the next of the found one, - and link it into the right place. */ - if (!right_pair) - { - found->next = bp->overlays_before; - set_buffer_overlays_before (bp, found); - } - else - { - found->next = right_pair->next; - right_pair->next = found; - } - } - else if (end == prev) - { - parent = tail; - tail = tail->next; - } - else /* No more disordered overlay. */ - break; - } + interval_tree_delete_gap (current_buffer->overlays, pos, length); } + DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0, doc: /* Return t if OBJECT is an overlay. */) @@ -3853,10 +3316,11 @@ for the front of the overlay advance when text is inserted there The fifth arg REAR-ADVANCE, if non-nil, makes the marker for the rear of the overlay advance when text is inserted there \(which means the text *is* included in the overlay). */) - (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, + (Lisp_Object begin, Lisp_Object end, Lisp_Object buffer, Lisp_Object front_advance, Lisp_Object rear_advance) { - Lisp_Object overlay; + Lisp_Object ov; + ptrdiff_t obegin, oend; struct buffer *b; if (NILP (buffer)) @@ -3864,53 +3328,35 @@ for the rear of the overlay advance when text is inserted there else CHECK_BUFFER (buffer); - if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer)) - signal_error ("Marker points into wrong buffer", beg); + b = XBUFFER (buffer); + if (! BUFFER_LIVE_P (b)) + error ("Attempt to create overlay in a dead buffer"); + + if (MARKERP (begin) && !EQ (Fmarker_buffer (begin), buffer)) + signal_error ("Marker points into wrong buffer", begin); if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer)) signal_error ("Marker points into wrong buffer", end); - CHECK_NUMBER_COERCE_MARKER (beg); + CHECK_NUMBER_COERCE_MARKER (begin); CHECK_NUMBER_COERCE_MARKER (end); - if (XINT (beg) > XINT (end)) + if (XINT (begin) > XINT (end)) { Lisp_Object temp; - temp = beg; beg = end; end = temp; + temp = begin; begin = end; end = temp; } - b = XBUFFER (buffer); - - beg = Fset_marker (Fmake_marker (), beg, buffer); - end = Fset_marker (Fmake_marker (), end, buffer); - - if (!NILP (front_advance)) - XMARKER (beg)->insertion_type = 1; - if (!NILP (rear_advance)) - XMARKER (end)->insertion_type = 1; - - overlay = build_overlay (beg, end, Qnil); - - /* Put the new overlay on the wrong list. */ - end = OVERLAY_END (overlay); - if (OVERLAY_POSITION (end) < b->overlay_center) - { - eassert (b->overlays_after || (XOVERLAY (overlay)->next == NULL)); - XOVERLAY (overlay)->next = b->overlays_after; - set_buffer_overlays_after (b, XOVERLAY (overlay)); - } - else - { - eassert (b->overlays_before || (XOVERLAY (overlay)->next == NULL)); - XOVERLAY (overlay)->next = b->overlays_before; - set_buffer_overlays_before (b, XOVERLAY (overlay)); - } - /* This puts it in the right list, and in the right order. */ - recenter_overlay_lists (b, b->overlay_center); + obegin = clip_to_bounds (BEG, XINT (begin), b->text->z); + oend = clip_to_bounds (obegin, XINT (end), b->text->z); + ov = build_overlay (obegin, oend, + ! NILP (front_advance), + ! NILP (rear_advance), Qnil); + add_buffer_overlay (b, XOVERLAY (ov)); /* We don't need to redisplay the region covered by the overlay, because the overlay has no properties at the moment. */ - return overlay; + return ov; } /* Mark a section of BUF as needing redisplay because of overlays changes. */ @@ -3932,35 +3378,6 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) ++BUF_OVERLAY_MODIFF (buf); } -/* Remove OVERLAY from LIST. */ - -static struct Lisp_Overlay * -unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay) -{ - register struct Lisp_Overlay *tail, **prev = &list; - - for (tail = list; tail; prev = &tail->next, tail = *prev) - if (tail == overlay) - { - *prev = overlay->next; - overlay->next = NULL; - break; - } - return list; -} - -/* Remove OVERLAY from both overlay lists of B. */ - -static void -unchain_both (struct buffer *b, Lisp_Object overlay) -{ - struct Lisp_Overlay *ov = XOVERLAY (overlay); - - set_buffer_overlays_before (b, unchain_overlay (b->overlays_before, ov)); - set_buffer_overlays_after (b, unchain_overlay (b->overlays_after, ov)); - eassert (XOVERLAY (overlay)->next == NULL); -} - DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0, doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER. If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now. @@ -3976,7 +3393,7 @@ buffer. */) CHECK_OVERLAY (overlay); if (NILP (buffer)) - buffer = Fmarker_buffer (OVERLAY_START (overlay)); + buffer = Foverlay_buffer (overlay); if (NILP (buffer)) XSETBUFFER (buffer, current_buffer); CHECK_BUFFER (buffer); @@ -4000,25 +3417,28 @@ buffer. */) specbind (Qinhibit_quit, Qt); - obuffer = Fmarker_buffer (OVERLAY_START (overlay)); + obuffer = Foverlay_buffer (overlay); b = XBUFFER (buffer); if (!NILP (obuffer)) { ob = XBUFFER (obuffer); - o_beg = OVERLAY_POSITION (OVERLAY_START (overlay)); - o_end = OVERLAY_POSITION (OVERLAY_END (overlay)); - - unchain_both (ob, overlay); + o_beg = OVERLAY_START (overlay); + o_end = OVERLAY_END (overlay); } + if (! EQ (buffer, obuffer)) + { + if (! NILP (obuffer)) + remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay)); + add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay)); + } /* Set the overlay boundaries, which may clip them. */ - Fset_marker (OVERLAY_START (overlay), beg, buffer); - Fset_marker (OVERLAY_END (overlay), end, buffer); + set_overlay_region (XOVERLAY (overlay), XINT (beg), XINT (end)); - n_beg = marker_position (OVERLAY_START (overlay)); - n_end = marker_position (OVERLAY_END (overlay)); + n_beg = OVERLAY_START (overlay); + n_end = OVERLAY_END (overlay); /* If the overlay has changed buffers, do a thorough redisplay. */ if (!EQ (buffer, obuffer)) @@ -4046,22 +3466,6 @@ buffer. */) if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate))) return unbind_to (count, Fdelete_overlay (overlay)); - /* Put the overlay into the new buffer's overlay lists, first on the - wrong list. */ - if (n_end < b->overlay_center) - { - XOVERLAY (overlay)->next = b->overlays_after; - set_buffer_overlays_after (b, XOVERLAY (overlay)); - } - else - { - XOVERLAY (overlay)->next = b->overlays_before; - set_buffer_overlays_before (b, XOVERLAY (overlay)); - } - - /* This puts it in the right list, and in the right order. */ - recenter_overlay_lists (b, b->overlay_center); - return unbind_to (count, overlay); } @@ -4069,21 +3473,18 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0, doc: /* Delete the overlay OVERLAY from its buffer. */) (Lisp_Object overlay) { - Lisp_Object buffer; struct buffer *b; ptrdiff_t count = SPECPDL_INDEX (); CHECK_OVERLAY (overlay); - buffer = Fmarker_buffer (OVERLAY_START (overlay)); - if (NILP (buffer)) + b = OVERLAY_BUFFER (overlay); + if (! b) return Qnil; - b = XBUFFER (buffer); specbind (Qinhibit_quit, Qt); - unchain_both (b, overlay); - drop_overlay (b, XOVERLAY (overlay)); + drop_overlay (XOVERLAY (overlay)); /* When deleting an overlay with before or after strings, turn off display optimizations for the affected buffer, on the basis that @@ -4114,8 +3515,10 @@ DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0, (Lisp_Object overlay) { CHECK_OVERLAY (overlay); + if (! OVERLAY_BUFFER (overlay)) + return Qnil; - return (Fmarker_position (OVERLAY_START (overlay))); + return make_number (OVERLAY_START (overlay)); } DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0, @@ -4123,8 +3526,10 @@ DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0, (Lisp_Object overlay) { CHECK_OVERLAY (overlay); + if (! OVERLAY_BUFFER (overlay)) + return Qnil; - return (Fmarker_position (OVERLAY_END (overlay))); + return make_number (OVERLAY_END (overlay)); } DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0, @@ -4132,9 +3537,16 @@ DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0, Return nil if OVERLAY has been deleted. */) (Lisp_Object overlay) { + Lisp_Object buffer; + CHECK_OVERLAY (overlay); - return Fmarker_buffer (OVERLAY_START (overlay)); + if (! OVERLAY_BUFFER (overlay)) + return Qnil; + + XSETBUFFER (buffer, OVERLAY_BUFFER (overlay)); + + return buffer; } DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0, @@ -4145,7 +3557,7 @@ OVERLAY. */) { CHECK_OVERLAY (overlay); - return Fcopy_sequence (XOVERLAY (overlay)->plist); + return Fcopy_sequence (OVERLAY_PLIST (overlay)); } @@ -4169,8 +3581,7 @@ If SORTED is non-nil, then sort them by decreasing priority. */) /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. */ - noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, - NULL, NULL, 0); + noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, NULL); if (!NILP (sorted)) noverlays = sort_overlays (overlay_vec, noverlays, @@ -4213,8 +3624,7 @@ end of the buffer. */) /* Put all the overlays we want in a vector in overlay_vec. Store the length in len. */ - noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len, - NULL, NULL); + noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len, true, NULL); /* Make a list of them all. */ result = Flist (noverlays, overlay_vec); @@ -4230,39 +3640,12 @@ If there are no overlay boundaries from POS to (point-max), the value is (point-max). */) (Lisp_Object pos) { - ptrdiff_t i, len, noverlays; - ptrdiff_t endpos; - Lisp_Object *overlay_vec; - CHECK_NUMBER_COERCE_MARKER (pos); if (!buffer_has_overlays ()) return make_number (ZV); - len = 10; - overlay_vec = xmalloc (len * sizeof *overlay_vec); - - /* Put all the overlays we want in a vector in overlay_vec. - Store the length in len. - endpos gets the position where the next overlay starts. */ - noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, - &endpos, 0, 1); - - /* If any of these overlays ends before endpos, - use its ending point instead. */ - for (i = 0; i < noverlays; i++) - { - Lisp_Object oend; - ptrdiff_t oendpos; - - oend = OVERLAY_END (overlay_vec[i]); - oendpos = OVERLAY_POSITION (oend); - if (oendpos < endpos) - endpos = oendpos; - } - - xfree (overlay_vec); - return make_number (endpos); + return make_number (next_overlay_change (XINT (pos))); } DEFUN ("previous-overlay-change", Fprevious_overlay_change, @@ -4272,32 +3655,15 @@ If there are no overlay boundaries from (point-min) to POS, the value is (point-min). */) (Lisp_Object pos) { - ptrdiff_t prevpos; - Lisp_Object *overlay_vec; - ptrdiff_t len; CHECK_NUMBER_COERCE_MARKER (pos); if (!buffer_has_overlays ()) return make_number (BEGV); - /* At beginning of buffer, we know the answer; - avoid bug subtracting 1 below. */ - if (XINT (pos) == BEGV) - return pos; - - len = 10; - overlay_vec = xmalloc (len * sizeof *overlay_vec); - - /* Put all the overlays we want in a vector in overlay_vec. - Store the length in len. - prevpos gets the position of the previous change. */ - overlays_at (XINT (pos), 1, &overlay_vec, &len, - 0, &prevpos, 1); - - xfree (overlay_vec); - return make_number (prevpos); + return make_number (previous_overlay_change (XINT (pos))); } + /* These functions are for debugging overlays. */ @@ -4307,24 +3673,21 @@ The car has all the overlays before the overlay center; the cdr has all the overlays after the overlay center. Recentering overlays moves overlays between these lists. The lists you get are copies, so that changing them has no effect. -However, the overlays you get are the real objects that the buffer uses. */) +However, the overlays you get are the real objects that the buffer uses. */) (void) { - struct Lisp_Overlay *ol; - Lisp_Object before = Qnil, after = Qnil, tmp; + Lisp_Object overlays = Qnil; - for (ol = current_buffer->overlays_before; ol; ol = ol->next) - { - XSETMISC (tmp, ol); - before = Fcons (tmp, before); - } - for (ol = current_buffer->overlays_after; ol; ol = ol->next) + if (current_buffer->overlays) { - XSETMISC (tmp, ol); - after = Fcons (tmp, after); - } + struct interval_node *node; - return Fcons (Fnreverse (before), Fnreverse (after)); + buffer_overlay_iter_start (current_buffer, BEG, Z, ITREE_DESCENDING); + while ((node = buffer_overlay_iter_next (current_buffer))) + overlays = Fcons (node->data, overlays); + buffer_overlay_iter_finish (current_buffer); + } + return Fcons (overlays, Qnil); } DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0, @@ -4333,11 +3696,8 @@ That makes overlay lookup faster for positions near POS (but perhaps slower for positions far away from POS). */) (Lisp_Object pos) { - ptrdiff_t p; CHECK_NUMBER_COERCE_MARKER (pos); - - p = clip_to_bounds (PTRDIFF_MIN, XINT (pos), PTRDIFF_MAX); - recenter_overlay_lists (current_buffer, p); + /* Noop */ return Qnil; } @@ -4354,12 +3714,13 @@ DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0, VALUE will be returned.*/) (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value) { - Lisp_Object tail, buffer; + Lisp_Object tail; + struct buffer *b; bool changed; CHECK_OVERLAY (overlay); - buffer = Fmarker_buffer (OVERLAY_START (overlay)); + b = OVERLAY_BUFFER (overlay); for (tail = XOVERLAY (overlay)->plist; CONSP (tail) && CONSP (XCDR (tail)); @@ -4375,15 +3736,14 @@ VALUE will be returned.*/) set_overlay_plist (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist))); found: - if (! NILP (buffer)) + if (b) { if (changed) - modify_overlay (XBUFFER (buffer), - marker_position (OVERLAY_START (overlay)), - marker_position (OVERLAY_END (overlay))); + modify_overlay (b, OVERLAY_START (overlay), + OVERLAY_END (overlay)); if (EQ (prop, Qevaporate) && ! NILP (value) - && (OVERLAY_POSITION (OVERLAY_START (overlay)) - == OVERLAY_POSITION (OVERLAY_END (overlay)))) + && (OVERLAY_START (overlay) + == OVERLAY_END (overlay))) Fdelete_overlay (overlay); } @@ -4441,14 +3801,9 @@ void report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) { - Lisp_Object prop, overlay; - struct Lisp_Overlay *tail; /* True if this change is an insertion. */ bool insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end)); - overlay = Qnil; - tail = NULL; - /* We used to run the functions as soon as we found them and only register them in last_overlay_modification_hooks for the purpose of the `after' case. But running elisp code as we traverse the list of overlays is @@ -4459,68 +3814,35 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, if (!after) { + struct interval_node *node; + EMACS_INT begin_arg = XFASTINT (start); + EMACS_INT end_arg = XFASTINT (end); /* We are being called before a change. Scan the overlays to find the functions to call. */ last_overlay_modification_hooks_used = 0; - for (tail = current_buffer->overlays_before; tail; tail = tail->next) - { - ptrdiff_t startpos, endpos; - Lisp_Object ostart, oend; - - XSETMISC (overlay, 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)) - { - prop = Foverlay_get (overlay, Qinsert_in_front_hooks); - if (!NILP (prop)) - add_overlay_mod_hooklist (prop, overlay); - } - if (insertion && (XFASTINT (start) == endpos - || XFASTINT (end) == endpos)) - { - prop = Foverlay_get (overlay, Qinsert_behind_hooks); - if (!NILP (prop)) - add_overlay_mod_hooklist (prop, overlay); - } - /* Test for intersecting intervals. This does the right thing - for both insertion and deletion. */ - if (XFASTINT (end) > startpos && XFASTINT (start) < endpos) - { - prop = Foverlay_get (overlay, Qmodification_hooks); - if (!NILP (prop)) - add_overlay_mod_hooklist (prop, overlay); - } - } - for (tail = current_buffer->overlays_after; tail; tail = tail->next) + if (! current_buffer->overlays) + return; + buffer_overlay_iter_start (current_buffer, + begin_arg - (insertion ? 1 : 0), + end_arg + (insertion ? 1 : 0), + ITREE_ASCENDING); + while ((node = buffer_overlay_iter_next (current_buffer))) { - ptrdiff_t startpos, endpos; - Lisp_Object ostart, oend; - - XSETMISC (overlay, 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)) + Lisp_Object overlay = node->data; + ptrdiff_t obegin = OVERLAY_START (overlay); + ptrdiff_t oend = OVERLAY_END (overlay); + Lisp_Object prop; + + if (insertion && (begin_arg == obegin + || end_arg == obegin)) { prop = Foverlay_get (overlay, Qinsert_in_front_hooks); if (!NILP (prop)) add_overlay_mod_hooklist (prop, overlay); } - if (insertion && (XFASTINT (start) == endpos - || XFASTINT (end) == endpos)) + if (insertion && (begin_arg == oend + || end_arg == oend)) { prop = Foverlay_get (overlay, Qinsert_behind_hooks); if (!NILP (prop)) @@ -4528,15 +3850,15 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, } /* Test for intersecting intervals. This does the right thing for both insertion and deletion. */ - if (XFASTINT (end) > startpos && XFASTINT (start) < endpos) + if (! insertion || (end_arg > obegin && begin_arg < oend)) { prop = Foverlay_get (overlay, Qmodification_hooks); if (!NILP (prop)) add_overlay_mod_hooklist (prop, overlay); } } + buffer_overlay_iter_finish (current_buffer); } - { /* Call the functions recorded in last_overlay_modification_hooks. First copy the vector contents, in case some of these hooks @@ -4558,7 +3880,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, function is never called to record the overlay modification hook functions in the last_overlay_modification_hooks array, so anything we find there is not ours. */ - if (XMARKER (OVERLAY_START (ovl))->buffer != current_buffer) + if (OVERLAY_BUFFER (ovl) != current_buffer) return; } @@ -4598,34 +3920,22 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after, void evaporate_overlays (ptrdiff_t pos) { - Lisp_Object overlay, hit_list; - struct Lisp_Overlay *tail; + Lisp_Object hit_list; + struct interval_node *node; + + if (! current_buffer->overlays) + return; hit_list = Qnil; - if (pos <= current_buffer->overlay_center) - for (tail = current_buffer->overlays_before; tail; tail = tail->next) - { - ptrdiff_t endpos; - XSETMISC (overlay, tail); - endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); - if (endpos < pos) - break; - if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos - && ! NILP (Foverlay_get (overlay, Qevaporate))) - hit_list = Fcons (overlay, hit_list); - } - else - for (tail = current_buffer->overlays_after; tail; tail = tail->next) - { - ptrdiff_t startpos; - XSETMISC (overlay, tail); - startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); - if (startpos > pos) - break; - if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos - && ! NILP (Foverlay_get (overlay, Qevaporate))) - hit_list = Fcons (overlay, hit_list); - } + buffer_overlay_iter_start (current_buffer, pos, pos, ITREE_ASCENDING); + + while ((node = buffer_overlay_iter_next (current_buffer))) + { + if (node->end == pos + && ! NILP (Foverlay_get (node->data, Qevaporate))) + hit_list = Fcons (node->data, hit_list); + } + buffer_overlay_iter_finish (current_buffer); for (; CONSP (hit_list); hit_list = XCDR (hit_list)) Fdelete_overlay (XCAR (hit_list)); } @@ -5212,9 +4522,7 @@ init_buffer_once (void) bset_mark_active (&buffer_defaults, Qnil); bset_file_format (&buffer_defaults, Qnil); bset_auto_save_file_format (&buffer_defaults, Qt); - set_buffer_overlays_before (&buffer_defaults, NULL); - set_buffer_overlays_after (&buffer_defaults, NULL); - buffer_defaults.overlay_center = BEG; + buffer_defaults.overlays = NULL; XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8); bset_truncate_lines (&buffer_defaults, Qnil); @@ -5434,6 +4742,48 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, emacs_abort (); } +#ifdef ITREE_DEBUG +static Lisp_Object +make_lispy_interval_node (const struct interval_node *node) +{ + return listn (CONSTYPE_HEAP, 12, + intern (":begin"), + make_number (node->begin), + intern (":end"), + make_number (node->end), + intern (":limit"), + make_number (node->limit), + intern (":offset"), + make_number (node->offset), + intern (":rear-advance"), + node->rear_advance ? Qt : Qnil, + intern (":front-advance"), + node->front_advance ? Qt : Qnil); +} + +static Lisp_Object +overlay_tree (const struct interval_tree *tree, + const struct interval_node *node) +{ + if (node == &tree->nil) + return Qnil; + return list3 (make_lispy_interval_node (node), + overlay_tree (tree, node->left), + overlay_tree (tree, node->right)); +} + +DEFUN ("overlay-tree", Foverlay_tree, Soverlay_tree, 0, 1, 0, + doc: /* Get the overlay tree for BUFFER. */) + (Lisp_Object buffer) +{ + struct buffer *b = decode_buffer (buffer); + if (! b->overlays) + return Qnil; + return overlay_tree (b->overlays, b->overlays->root); +} +#endif + + /* Initialize the buffer routines. */ void @@ -6303,6 +5653,10 @@ Functions running this hook are, `get-buffer-create', defsubr (&Srestore_buffer_modified_p); Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt); + +#ifdef ITREE_DEBUG + defsubr (&Soverlay_tree); +#endif } void diff --git a/src/buffer.h b/src/buffer.h index ac7c5a54679..ef31ad1ed9d 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -26,6 +26,7 @@ along with GNU Emacs. If not, see . */ #include "character.h" #include "lisp.h" +#include "itree.h" INLINE_HEADER_BEGIN @@ -877,16 +878,8 @@ struct buffer /* Non-zero whenever the narrowing is changed in this buffer. */ bool_bf clip_changed : 1; - /* List of overlays that end at or before the current center, - in order of end-position. */ - struct Lisp_Overlay *overlays_before; - - /* List of overlays that end after the current center, - in order of start-position. */ - struct Lisp_Overlay *overlays_after; - - /* Position where the overlay lists are centered. */ - ptrdiff_t overlay_center; + /* The inveral tree containing this buffer's overlays. */ + struct interval_tree *overlays; /* Changes in the buffer are recorded here for undo, and t means don't record anything. This information belongs to the base @@ -896,6 +889,14 @@ struct buffer Lisp_Object undo_list_; }; +struct sortvec +{ + Lisp_Object overlay; + ptrdiff_t beg, end; + EMACS_INT priority; + EMACS_INT spriority; /* Secondary priority. */ +}; + INLINE bool BUFFERP (Lisp_Object a) { @@ -1109,8 +1110,11 @@ extern void delete_all_overlays (struct buffer *); extern void reset_buffer (struct buffer *); extern void compact_buffer (struct buffer *); extern void evaporate_overlays (ptrdiff_t); -extern ptrdiff_t overlays_at (EMACS_INT, bool, Lisp_Object **, - ptrdiff_t *, ptrdiff_t *, ptrdiff_t *, bool); +extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, ptrdiff_t *); +extern ptrdiff_t overlays_in (ptrdiff_t, ptrdiff_t, bool, Lisp_Object **, + ptrdiff_t *, bool, ptrdiff_t *); +extern ptrdiff_t previous_overlay_change (ptrdiff_t); +extern ptrdiff_t next_overlay_change (ptrdiff_t); extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *); extern void recenter_overlay_lists (struct buffer *, ptrdiff_t); extern ptrdiff_t overlay_strings (ptrdiff_t, struct window *, unsigned char **); @@ -1162,18 +1166,16 @@ record_unwind_current_buffer (void) If NEXTP is non-NULL, return next overlay there. See overlay_at arg CHANGE_REQ for meaning of CHRQ arg. */ -#define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq) \ +#define GET_OVERLAYS_AT(posn, overlays, noverlays, next) \ do { \ ptrdiff_t maxlen = 40; \ SAFE_NALLOCA (overlays, 1, maxlen); \ - (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, \ - nextp, NULL, chrq); \ + (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, next); \ if ((noverlays) > maxlen) \ { \ maxlen = noverlays; \ SAFE_NALLOCA (overlays, 1, maxlen); \ - (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, \ - nextp, NULL, chrq); \ + (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, next); \ } \ } while (false) @@ -1208,7 +1210,8 @@ set_buffer_intervals (struct buffer *b, INTERVAL i) INLINE bool buffer_has_overlays (void) { - return current_buffer->overlays_before || current_buffer->overlays_after; + return current_buffer->overlays + && (interval_tree_size (current_buffer->overlays) > 0); } /* Return character code of multi-byte form at byte position POS. If POS @@ -1248,23 +1251,124 @@ buffer_window_count (struct buffer *b) /* Overlays */ -/* Return the marker that stands for where OV starts in the buffer. */ +INLINE ptrdiff_t +overlay_start (struct Lisp_Overlay *ov) +{ + if (! ov->buffer) + return -1; + return interval_node_begin (ov->buffer->overlays, ov->interval); +} + +INLINE ptrdiff_t +overlay_end (struct Lisp_Overlay *ov) +{ + if (! ov->buffer) + return -1; + return interval_node_end (ov->buffer->overlays, ov->interval); +} + +INLINE void +set_overlay_region (struct Lisp_Overlay *ov, ptrdiff_t begin, ptrdiff_t end) +{ + eassert (ov->buffer); + begin = clip_to_bounds (BEG, begin, ov->buffer->text->z); + end = clip_to_bounds (begin, end, ov->buffer->text->z); + interval_node_set_region (ov->buffer->overlays, ov->interval, begin, end); +} + +INLINE void +maybe_alloc_buffer_overlays (struct buffer *b) +{ + if (! b->overlays) + b->overlays = interval_tree_create (); +} + +/* FIXME: Actually this does not free any overlay, but the tree + only. --ap */ + +INLINE void +free_buffer_overlays (struct buffer *b) +{ + eassert (! b->overlays || 0 == interval_tree_size (b->overlays)); + if (b->overlays) + { + interval_tree_destroy (b->overlays); + b->overlays = NULL; + } +} + +INLINE void +add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov) +{ + eassert (! ov->buffer); + maybe_alloc_buffer_overlays (b); + ov->buffer = b; + interval_tree_insert (b->overlays, ov->interval); +} + +INLINE void +remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov) +{ + eassert (b->overlays); + eassert (ov->buffer == b); + interval_tree_remove (ov->buffer->overlays, ov->interval); + ov->buffer = NULL; +} + +INLINE void +buffer_overlay_iter_start (struct buffer *b, ptrdiff_t begin, ptrdiff_t end, + enum interval_tree_order order) +{ + if (b->overlays) + interval_tree_iter_start (b->overlays, begin, end, order); +} + +INLINE struct interval_node* +buffer_overlay_iter_next (struct buffer *b) +{ + if (! b->overlays) + return NULL; + return interval_tree_iter_next (b->overlays); +} + +INLINE void +buffer_overlay_iter_finish (struct buffer *b) +{ + if (b->overlays) + interval_tree_iter_finish (b->overlays); +} + +INLINE void +buffer_overlay_iter_narrow (struct buffer *b, ptrdiff_t begin, ptrdiff_t end) +{ + if (b->overlays) + interval_tree_iter_narrow (b->overlays, begin, end); +} -#define OVERLAY_START(OV) XOVERLAY (OV)->start +/* Return the start of OV in its buffer, or -1 if OV is not associated + with any buffer. */ -/* Return the marker that stands for where OV ends in the buffer. */ +#define OVERLAY_START(OV) (overlay_start (XOVERLAY (OV))) -#define OVERLAY_END(OV) XOVERLAY (OV)->end +/* Return the end of OV in its buffer, or -1. */ + +#define OVERLAY_END(OV) (overlay_end (XOVERLAY (OV))) /* Return the plist of overlay OV. */ -#define OVERLAY_PLIST(OV) XOVERLAY (OV)->plist +#define OVERLAY_PLIST(OV) (XOVERLAY (OV)->plist) + +/* Return the buffer of overlay OV. */ + +#define OVERLAY_BUFFER(OV) (XOVERLAY (OV)->buffer) -/* Return the actual buffer position for the marker P. - We assume you know which buffer it's pointing into. */ +/* Return true, if OV's rear-advance is set. */ -#define OVERLAY_POSITION(P) \ - (MARKERP (P) ? marker_position (P) : (emacs_abort (), 0)) +#define OVERLAY_REAR_ADVANCE_P(OV) (XOVERLAY (OV)->interval->rear_advance) + +/* Return true, if OV's front-advance is set. */ + +#define OVERLAY_FRONT_ADVANCE_P(OV) (XOVERLAY (OV)->interval->front_advance) /*********************************************************************** @@ -1405,4 +1509,7 @@ lowercasep (int c) INLINE_HEADER_END +int compare_overlays (const void *v1, const void *v2); +void make_sortvec_item (struct sortvec *item, Lisp_Object overlay); + #endif /* EMACS_BUFFER_H */ diff --git a/src/editfns.c b/src/editfns.c index 4dcf7cbe6ef..8628b1b2d49 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -457,51 +457,9 @@ If you set the marker not to point anywhere, the buffer will have no mark. */) of length LEN. */ static ptrdiff_t -overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len) +overlays_around (ptrdiff_t pos, Lisp_Object *vec, ptrdiff_t len) { - Lisp_Object overlay, start, end; - struct Lisp_Overlay *tail; - ptrdiff_t startpos, endpos; - ptrdiff_t idx = 0; - - for (tail = current_buffer->overlays_before; tail; tail = tail->next) - { - XSETMISC (overlay, tail); - - end = OVERLAY_END (overlay); - endpos = OVERLAY_POSITION (end); - if (endpos < pos) - break; - start = OVERLAY_START (overlay); - startpos = OVERLAY_POSITION (start); - if (startpos <= pos) - { - if (idx < len) - vec[idx] = overlay; - /* Keep counting overlays even if we can't return them all. */ - idx++; - } - } - - for (tail = current_buffer->overlays_after; tail; tail = tail->next) - { - XSETMISC (overlay, tail); - - start = OVERLAY_START (overlay); - startpos = OVERLAY_POSITION (start); - if (pos < startpos) - break; - end = OVERLAY_END (overlay); - endpos = OVERLAY_POSITION (end); - if (pos <= endpos) - { - if (idx < len) - vec[idx] = overlay; - idx++; - } - } - - return idx; + return overlays_in (pos - 1, pos, false, &vec, &len, false, NULL); } DEFUN ("get-pos-property", Fget_pos_property, Sget_pos_property, 2, 3, 0, @@ -561,11 +519,10 @@ at POSITION. */) if (!NILP (tem)) { /* Check the overlay is indeed active at point. */ - Lisp_Object start = OVERLAY_START (ol), finish = OVERLAY_END (ol); - if ((OVERLAY_POSITION (start) == posn - && XMARKER (start)->insertion_type == 1) - || (OVERLAY_POSITION (finish) == posn - && XMARKER (finish)->insertion_type == 0)) + if ((OVERLAY_START (ol) == posn + && OVERLAY_FRONT_ADVANCE_P (ol)) + || (OVERLAY_END (ol) == posn + && ! OVERLAY_REAR_ADVANCE_P (ol))) ; /* The overlay will not cover a char inserted at point. */ else { @@ -5385,7 +5342,6 @@ Transposing beyond buffer boundaries is an error. */) transpose_markers (start1, end1, start2, end2, start1_byte, start1_byte + len1_byte, start2_byte, start2_byte + len2_byte); - fix_start_end_in_overlays (start1, end2); } else { diff --git a/src/fileio.c b/src/fileio.c index 11370279d1b..6b22b29aa70 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3656,8 +3656,7 @@ by calling `format-decode', which see. */) bset_read_only (buf, Qnil); bset_filename (buf, Qnil); bset_undo_list (buf, Qt); - eassert (buf->overlays_before == NULL); - eassert (buf->overlays_after == NULL); + eassert (buf->overlays == NULL); set_buffer_internal (buf); Ferase_buffer (); diff --git a/src/fns.c b/src/fns.c index 2311a6e041b..9f411036825 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2240,10 +2240,9 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, return false; if (OVERLAYP (o1)) { - if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2), - equal_kind, depth + 1, ht) - || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2), - equal_kind, depth + 1, ht)) + if (OVERLAY_START (o1) != OVERLAY_START (o2) + || OVERLAY_END (o1) != OVERLAY_END (o2) + || OVERLAY_BUFFER (o1) != OVERLAY_BUFFER (o2)) return false; o1 = XOVERLAY (o1)->plist; o2 = XOVERLAY (o2)->plist; diff --git a/src/indent.c b/src/indent.c index 26507b5eb5b..8ac7c6ef109 100644 --- a/src/indent.c +++ b/src/indent.c @@ -225,9 +225,6 @@ skip_invisible (ptrdiff_t pos, ptrdiff_t *next_boundary_p, ptrdiff_t to, Lisp_Ob XSETFASTINT (position, pos); XSETBUFFER (buffer, current_buffer); - /* Give faster response for overlay lookup near POS. */ - recenter_overlay_lists (current_buffer, pos); - /* We must not advance farther than the next overlay change. The overlay change might change the invisible property; or there might be overlay strings to be displayed there. */ @@ -501,7 +498,7 @@ check_display_width (ptrdiff_t pos, ptrdiff_t col, ptrdiff_t *endpos) { ptrdiff_t start; if (OVERLAYP (overlay)) - *endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); + *endpos = OVERLAY_END (overlay); else get_property_and_range (pos, Qdisplay, &val, &start, endpos, Qnil); diff --git a/src/insdel.c b/src/insdel.c index 5dfc62843a7..3e9f0c90e34 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -276,7 +276,6 @@ adjust_markers_for_insert (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t to, ptrdiff_t to_byte, bool before_markers) { struct Lisp_Marker *m; - bool adjusted = 0; ptrdiff_t nchars = to - from; ptrdiff_t nbytes = to_byte - from_byte; @@ -292,8 +291,6 @@ adjust_markers_for_insert (ptrdiff_t from, ptrdiff_t from_byte, { m->bytepos = to_byte; m->charpos = to; - if (m->insertion_type) - adjusted = 1; } } else if (m->bytepos > from_byte) @@ -302,15 +299,6 @@ adjust_markers_for_insert (ptrdiff_t from, ptrdiff_t from_byte, m->charpos += nchars; } } - - /* Adjusting only markers whose insertion-type is t may result in - - disordered start and end in overlays, and - - disordered overlays in the slot `overlays_before' of current_buffer. */ - if (adjusted) - { - fix_start_end_in_overlays (from, to); - fix_overlays_before (current_buffer, from, to); - } } /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters. diff --git a/src/intervals.c b/src/intervals.c index e711212d744..3db80ebed4a 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -1810,8 +1810,8 @@ adjust_for_invis_intang (ptrdiff_t pos, ptrdiff_t test_offs, ptrdiff_t adj, == (test_offs == 0 ? 1 : -1)) /* Invisible property is from an overlay. */ : (test_offs == 0 - ? XMARKER (OVERLAY_START (invis_overlay))->insertion_type == 0 - : XMARKER (OVERLAY_END (invis_overlay))->insertion_type == 1))) + ? ! OVERLAY_FRONT_ADVANCE_P (invis_overlay) + : OVERLAY_REAR_ADVANCE_P (invis_overlay)))) pos += adj; return pos; diff --git a/src/itree.c b/src/itree.c new file mode 100644 index 00000000000..0c10100eef7 --- /dev/null +++ b/src/itree.c @@ -0,0 +1,1138 @@ +/* This file implements an efficient interval data-structure. + +Copyright (C) 2017 Andreas Politz (politza@hochschule-trier.de) + +This file is not part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see . */ + +#include +#include +#include "lisp.h" +#include "itree.h" + +/* + Intervals of the form [BEGIN, END), are stored as nodes inside a RB + tree, sorted by BEGIN . The core operation of this tree (besides + insert, remove, etc.) is finding all intervals intersecting with + some given interval. In order to perform this operation + efficiently, every node stores a third value called LIMIT. (See + https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree and its + source Introduction to Algorithms (Section 14.3), Cormen et al. .) + + ==== Finding intervals ==== + + If we search for all intervals intersecting with (X, Y], we look at + some node and test whether + + NODE.BEGIN > Y + + Due to the invariant of the search tree, we know, that we may + safely prune NODE's right subtree if this test succeeds, since all + intervals begin strictly after Y. + + But we can not make such an assumptions about the left tree, since + all we know is that the intervals in this subtree must start before + or at NODE.BEGIN. So we can't tell, whether they end before X or + not. To solve this problem we add another attribute to each node, + called LIMIT. + + The LIMIT of a node is the largest END value occurring in the nodes + subtree (including the node itself). Thus, we may look at the left + child of some NODE and test whether + + NODE.left.LIMIT < X + + and this tells us, if all intervals in the left subtree of NODE end + before X and if they can be pruned. + + Conversely, if this inequality is false, the left subtree must + contain at least one intersecting interval, giving a resulting time + complexity of O(K*log(N)) for this operation, where K is the size + of the result set and N the size of the tree. + + ==== Adjusting intervals ==== + + Since this data-structure will be used for overlays in an Emacs + buffer, a second core operation implements the ability to insert or + delete gaps in resp. from the tree. This models the insertion + resp. deletion of text in a buffer and the effects it may have on + the positions of overlays. + + Consider this: Something gets inserted at position P into a buffer + and assume that all overlays occur strictly after P. Ordinarily, + we would have to iterate all overlays and increment their BEGIN and + END values accordingly (the insertion of text pushes them back). + In order to avoid this, we introduce yet another node attribute, + called OFFSET. + + The OFFSET of some some subtree, represented by its root, is the + amount of shift that needs to be applied to its BEGIN, END and + LIMIT values, in order to get to the real values. Coming back to + the example, all we would need to do in this case, is to increment + the OFFSET of the tree's root, without any traversal of the tree + itself. + + As a consequence, the real values of BEGIN, END and LIMIT of some + NODE need to be computed by incrementing them by the sum of NODE's + OFFSET and all of its ancestors offsets. Therefore, we store a + counter (otick) inside every node and also the tree, by which we + remember the fact, that a node's path to the root has no offsets + applied (i.e. its values are up to date). This is the case if some + node's value differs from the tree's one, the later of which is + incremented whenever some node's offset has changed. +*/ + +static struct interval_node *interval_tree_validate(struct interval_tree *, struct interval_node *); +static void interval_generator_ensure_space(struct interval_generator *); +static bool interval_node_intersects(const struct interval_node *, ptrdiff_t, ptrdiff_t); +static int interval_tree_max_height(const struct interval_tree *); +static struct interval_stack *interval_stack_create(intmax_t); +static void interval_stack_destroy(struct interval_stack *); +static void interval_stack_clear(struct interval_stack *); +static void interval_stack_ensure_space(struct interval_stack *, intmax_t); +static void interval_stack_push(struct interval_stack *, struct interval_node *); +static void interval_stack_push_flagged(struct interval_stack *, struct interval_node *, bool); +static struct interval_node *interval_stack_pop(struct interval_stack *); +static void interval_tree_update_limit(const struct interval_tree *, struct interval_node *); +static void interval_tree_inherit_offset(const struct interval_tree *, struct interval_node *); +static void interval_tree_propagate_limit(const struct interval_tree *, struct interval_node *); +static void interval_tree_rotate_left(struct interval_tree *, struct interval_node *); +static void interval_tree_rotate_right(struct interval_tree *, struct interval_node *); +static void interval_tree_insert_fix(struct interval_tree *, struct interval_node *); +static void interval_tree_remove_fix(struct interval_tree *, struct interval_node *); +static void interval_tree_transplant(struct interval_tree *, struct interval_node *, struct interval_node *); +static struct interval_node *interval_tree_subtree_min(const struct interval_tree *, struct interval_node *); +static struct interval_generator* interval_generator_create (struct interval_tree *); +static void interval_generator_destroy (struct interval_generator *); +static void interval_generator_reset (struct interval_generator *, + ptrdiff_t, ptrdiff_t, + enum interval_tree_order); +static void +interval_generator_narrow (struct interval_generator *g, + ptrdiff_t begin, ptrdiff_t end); +static inline struct interval_node* +interval_generator_next (struct interval_generator *g); +static inline void interval_tree_iter_ensure_space(struct interval_tree *); + + + +/* +------------------------------------------------------------------------------------+ */ + +/* Simple dynamic array. */ +struct interval_stack +{ + struct interval_node **nodes; + size_t size; + size_t length; +}; + +/* State used when iterating interval. */ +struct interval_generator +{ + struct interval_tree *tree; + struct interval_stack *stack; + ptrdiff_t begin; + ptrdiff_t end; + enum interval_tree_order order; +}; + + + +/* +===================================================================================+ + * | Tree operations + * +===================================================================================+ */ + +/* Initialize an allocated node. */ + +void +interval_node_init (struct interval_node *node, + ptrdiff_t begin, ptrdiff_t end, + bool front_advance, bool rear_advance, + Lisp_Object data) +{ + node->begin = begin; + node->end = max (begin, end); + node->front_advance = front_advance; + node->rear_advance = rear_advance; + node->data = data; +} + +/* Return NODE's begin value, computing it if necessary. */ + +ptrdiff_t +interval_node_begin (struct interval_tree *tree, + struct interval_node *node) +{ + interval_tree_validate (tree, node); + return node->begin; +} + +/* Return NODE's end value, computing it if necessary. */ + +ptrdiff_t +interval_node_end (struct interval_tree *tree, + struct interval_node *node) +{ + interval_tree_validate (tree, node); + return node->end; +} + +/* Safely modify a node's interval. */ + +void +interval_node_set_region (struct interval_tree *tree, + struct interval_node *node, + ptrdiff_t begin, ptrdiff_t end) +{ + interval_tree_validate (tree, node); + if (begin != node->begin) + { + interval_tree_remove (tree, node); + node->begin = min (begin, PTRDIFF_MAX - 1); + node->end = max (node->begin, end); + interval_tree_insert (tree, node); + } + else if (end != node->end) + { + node->end = max (node->begin, end); + interval_tree_propagate_limit (tree, node); + } +} + +/* Allocate an interval_tree. Free with interval_tree_destroy. */ + +struct interval_tree* +interval_tree_create (void) +{ + struct interval_tree *tree = xmalloc (sizeof (*tree)); + interval_tree_clear (tree); + tree->iter = interval_generator_create (tree); + return tree; +} + +/* Reset the tree TREE to its empty state. */ + +void +interval_tree_clear (struct interval_tree *tree) +{ + struct interval_node *nil = &tree->nil; + nil->left = nil->right = nil->parent = nil; + nil->offset = nil->otick = 0; + nil->begin = PTRDIFF_MIN; + nil->end = PTRDIFF_MIN; + nil->limit = PTRDIFF_MIN; /* => max(x, nil.limit) = x */ + nil->color = ITREE_BLACK; + tree->root = nil; + tree->otick = 1; + tree->size = 0; + tree->iter_running = 0; +} + +#ifdef ITREE_TESTING +/* Initialize a pre-allocated tree (presumably on the stack). */ + +static void +interval_tree_init (struct interval_tree *tree) +{ + interval_tree_clear (tree); + tree->iter = interval_generator_create (tree); +} +#endif + +/* Release a tree, freeing its allocated memory. */ +void +interval_tree_destroy (struct interval_tree *tree) +{ + if (! tree) + return; + if (tree->iter) + interval_generator_destroy (tree->iter); + xfree (tree); +} + +/* Return the number of nodes in TREE. */ + +intmax_t +interval_tree_size (struct interval_tree *tree) +{ + return tree->size; +} + +/* Insert a NODE into the TREE. + + Note, that inserting a node twice results in undefined behaviour. +*/ + +void +interval_tree_insert (struct interval_tree *tree, struct interval_node *node) +{ + eassert (node && node->begin <= node->end && node != &tree->nil); + + struct interval_node *parent = &tree->nil; + struct interval_node *child = tree->root; + ptrdiff_t offset = 0; + + /* Find the insertion point, accumulate node's offset and update + ancestors limit values. */ + while (child != &tree->nil) + { + parent = child; + offset += child->offset; + child->limit = max (child->limit, node->end - offset); + /* This suggests that nodes in the right subtree are strictly + greater. But this is not true due to later rotations. */ + child = node->begin <= child->begin ? child->left : child->right; + } + + /* Insert the node */ + if (parent == &tree->nil) + tree->root = node; + else if (node->begin <= parent->begin) + parent->left = node; + else + parent->right = node; + + /* Init the node */ + node->parent = parent; + node->left = &tree->nil; + node->right = &tree->nil; + node->color = ITREE_RED; + node->offset = offset; + node->limit = node->end; + node->otick = tree->otick - 1; + + /* Fix/update the tree */ + ++tree->size; + interval_tree_insert_fix (tree, node); + interval_tree_iter_ensure_space (tree); +} + +/* Return true, if NODE is a member of TREE. */ + +bool +interval_tree_contains (struct interval_tree *tree, struct interval_node *node) +{ + struct interval_node *other; + + interval_tree_iter_start (tree, node->begin, PTRDIFF_MAX, ITREE_ASCENDING); + while ((other = interval_tree_iter_next (tree))) + if (other == node) + break; + + interval_tree_iter_finish (tree); + return other == node; +} + +/* Remove NODE from TREE and return it. NODE must exist in TREE.*/ + +struct interval_node* +interval_tree_remove (struct interval_tree *tree, struct interval_node *node) +{ + eassert (interval_tree_contains (tree, node)); + + struct interval_node *broken = NULL; + + interval_tree_inherit_offset (tree, node); + if (node->left == &tree->nil || node->right == &tree->nil) + { + struct interval_node *subst = + (node->right == &tree->nil) ? node->left : node->right; + if (node->color == ITREE_BLACK) + broken = subst; + interval_tree_transplant (tree, subst, node); + interval_tree_propagate_limit (tree, subst); + } + else + { + struct interval_node *min = interval_tree_subtree_min (tree, node->right); + struct interval_node *min_right = min->right; + + if (min->color == ITREE_BLACK) + broken = min->right; + if (min->parent == node) + min_right->parent = min; /* set parent, if min_right = nil */ + else + { + interval_tree_transplant (tree, min->right, min); + min->right = node->right; + min->right->parent = min; + } + interval_tree_inherit_offset (tree, min); + interval_tree_transplant (tree, min, node); + min->left = node->left; + min->left->parent = min; + min->color = node->color; + interval_tree_propagate_limit (tree, min_right); + interval_tree_propagate_limit (tree, min); + } + + if (broken) + interval_tree_remove_fix (tree, broken); + + node->right = node->left = node->parent = NULL; + --tree->size; + + eassert (tree->size == 0 || (tree->size > 0 && tree->root != &tree->nil)); + + return node; +} + +static struct interval_node* +interval_tree_validate (struct interval_tree *tree, struct interval_node *node) +{ + + if (tree->otick == node->otick || node == &tree->nil) + return node; + if (node != tree->root) + interval_tree_validate (tree, node->parent); + + interval_tree_inherit_offset (tree, node); + return node; +} + +/* Start a generator iterating all intervals in [BEGIN,END) in the + given ORDER. Only one iterator per tree can be running at any + time. +*/ + +void +interval_tree_iter_start (struct interval_tree *tree, + ptrdiff_t begin, ptrdiff_t end, + enum interval_tree_order order) +{ + if (tree->iter_running) + emacs_abort (); + interval_generator_reset (tree->iter, begin, end, order); + tree->iter_running = 1; +} + +/* Limit the search interval of the iterator to the given values. The + interval can only shrink, but never grow.*/ + +inline void +interval_tree_iter_narrow(struct interval_tree *tree, + ptrdiff_t begin, ptrdiff_t end) +{ + if (! tree->iter_running) + emacs_abort (); + interval_generator_narrow (tree->iter, begin, end); +} + +/* Stop using the iterator. */ + +void +interval_tree_iter_finish (struct interval_tree *tree) +{ + if (! tree->iter_running) + emacs_abort (); + tree->iter_running = 0; +} + +/* Return the next node of the iterator in the order given when it was + started; or NULL if there are no more nodes. */ + +inline struct interval_node* +interval_tree_iter_next (struct interval_tree *tree) +{ + if (! tree->iter_running) + emacs_abort (); + return interval_generator_next (tree->iter); +} + +/* Ensure that the tree's iterator does not need to allocate space + until the tree grows in size. */ + +static inline void +interval_tree_iter_ensure_space (struct interval_tree *tree) +{ + interval_generator_ensure_space (tree->iter); +} + +static int +interval_tree_max_height (const struct interval_tree *tree) +{ + return 2 * log (tree->size + 1) / log (2) + 0.5; +} + + +/* +===================================================================================+ + * | Insert/Delete Gaps + * +===================================================================================+ */ + +/* Insert a gap at POS of length LENGTH expanding all intervals + intersecting it, while respecting their rear_advance and + front_advance setting. */ + +void +interval_tree_insert_gap (struct interval_tree *tree, ptrdiff_t pos, ptrdiff_t length) +{ + if (length <= 0 || tree->size == 0) + return; + + /* FIXME: Don't allocate generator/stack anew every time. */ + + /* Nodes with front_advance starting at pos may mess up the tree + order, so we need to remove them first. */ + struct interval_stack *saved = interval_stack_create (0); + struct interval_node *node = NULL; + interval_tree_iter_start (tree, pos, pos + 1, ITREE_PRE_ORDER); + while ((node = interval_tree_iter_next (tree))) + { + if (node->begin == pos && node->front_advance + && (node->begin != node->end || node->rear_advance)) + interval_stack_push (saved, node); + } + interval_tree_iter_finish (tree); + for (int i = 0; i < saved->length; ++i) + interval_tree_remove (tree, saved->nodes[i]); + + + /* We can't use a generator here, because we can't effectively + narrow AND shift some subtree at the same time. */ + const int size = interval_tree_max_height (tree) + 1; + struct interval_stack *stack = interval_stack_create (size); + interval_stack_push (stack, tree->root); + while ((node = interval_stack_pop (stack))) + { + /* Process in pre-order. */ + interval_tree_inherit_offset (tree, node); + if (node->right != &tree->nil) + { + if (node->begin > pos) + { + /* All nodes in this subtree are shifted by length. */ + node->right->offset += length; + ++tree->otick; + } + else + interval_stack_push (stack, node->right); + } + if (node->left != &tree->nil && pos <= node->left->limit) + interval_stack_push (stack, node->left); + + /* node->begin == pos implies no front-advance. */ + if (node->begin > pos) + node->begin += length; + if (node->end > pos || (node->end == pos && node->rear_advance)) + { + node->end += length; + interval_tree_propagate_limit (tree, node); + } + } + interval_stack_destroy (stack); + + /* Reinsert nodes starting at POS having front-advance. */ + while ((node = interval_stack_pop (saved))) + { + node->begin += length; + if (node->end != pos || node->rear_advance) + node->end += length; + interval_tree_insert (tree, node); + } + + interval_stack_destroy (saved); +} + +/* Delete a gap at POS of length LENGTH, contracting all intervals + intersecting it. */ + +void +interval_tree_delete_gap (struct interval_tree *tree, ptrdiff_t pos, ptrdiff_t length) +{ + if (length <= 0 || tree->size == 0) + return; + + /* FIXME: Don't allocate stack anew every time. */ + + /* Can't use the generator here, because by decrementing begin, we + might unintentionally bring shifted nodes back into our search + space. */ + const int size = interval_tree_max_height (tree) + 1; + struct interval_stack *stack = interval_stack_create (size); + struct interval_node *node; + + interval_stack_push (stack, tree->root); + while ((node = interval_stack_pop (stack))) + { + interval_tree_inherit_offset (tree, node); + if (node->right != &tree->nil) + { + if (node->begin > pos + length) + { + /* Shift right subtree to the left. */ + node->right->offset -= length; + ++tree->otick; + } + else + interval_stack_push (stack, node->right); + } + if (node->left != &tree->nil && pos <= node->left->limit) + interval_stack_push (stack, node->left); + + if (pos < node->begin) + node->begin = max (pos, node->begin - length); + if (node->end > pos) + { + node->end = max (pos , node->end - length); + interval_tree_propagate_limit (tree, node); + } + } + interval_stack_destroy (stack); +} + + + +/* +===================================================================================+ + * | Generator + * +===================================================================================+ */ + +/* Allocate a new generator for TREE. */ + +static struct interval_generator* +interval_generator_create (struct interval_tree *tree) +{ + struct interval_generator *g = xmalloc (sizeof *g); + const int size = interval_tree_max_height (tree) + 1; + + g->stack = interval_stack_create (size); + g->tree = tree; + interval_generator_reset (g, 1, 0, 0); + return g; +} + +/* Reset generator G such that it iterates over intervals intersecting + with [BEGIN, END) in the given ORDER. */ + +void +interval_generator_reset (struct interval_generator *g, + ptrdiff_t begin, ptrdiff_t end, + enum interval_tree_order order) +{ + if (! g) return; + + g->begin = begin; + g->end = end; + g->order = order; + interval_stack_clear (g->stack); + if (begin <= end && g->tree->size > 0) + interval_stack_push_flagged (g->stack, g->tree->root, false); +} + +/* Allocate enough space for the tree of G in its current shape. */ + +static inline void +interval_generator_ensure_space (struct interval_generator *g) +{ + interval_stack_ensure_space (g->stack, interval_tree_max_height (g->tree) + 1); +} + +/* Return true, if NODE's interval intersects with [BEGIN, END). */ + +static inline bool +interval_node_intersects (const struct interval_node *node, + ptrdiff_t begin, ptrdiff_t end) +{ + return (begin < node->end && node->begin < end) + || (node->begin == node->end && begin == node->begin); +} + +/* Return the next node of G, or NULL if there is none. */ + +inline struct interval_node* +interval_generator_next (struct interval_generator *g) +{ + if (! g) return NULL; + + struct interval_node * const nil = &g->tree->nil; + struct interval_node *node; + + do { + node = interval_stack_pop (g->stack); + + while (node && ! node->visited) + { + struct interval_node * const left = node->left; + struct interval_node * const right = node->right; + + interval_tree_inherit_offset (g->tree, node); + switch (g->order) + { + case ITREE_ASCENDING: + if (right != nil && node->begin <= g->end) + interval_stack_push_flagged (g->stack, right, false); + if (interval_node_intersects (node, g->begin, g->end)) + interval_stack_push_flagged (g->stack, node, true); + /* Node's children may still be off-set and we need to add it. */ + if (left != nil && g->begin <= left->limit + left->offset) + interval_stack_push_flagged (g->stack, left, false); + break; + case ITREE_DESCENDING: + if (left != nil && g->begin <= left->limit + left->offset) + interval_stack_push_flagged (g->stack, left, false); + if (interval_node_intersects (node, g->begin, g->end)) + interval_stack_push_flagged (g->stack, node, true); + if (right != nil && node->begin <= g->end) + interval_stack_push_flagged (g->stack, right, false); + break; + case ITREE_PRE_ORDER: + if (right != nil && node->begin <= g->end) + interval_stack_push_flagged (g->stack, right, false); + if (left != nil && g->begin <= left->limit + left->offset) + interval_stack_push_flagged (g->stack, left, false); + if (interval_node_intersects (node, g->begin, g->end)) + interval_stack_push_flagged (g->stack, node, true); + break; + } + node = interval_stack_pop (g->stack); + } + /* Node may have been invalidated by interval_generator_narrow + after it was pushed: Check if it still intersects. */ + } while (node && ! interval_node_intersects (node, g->begin, g->end)); + + return node; +} + +/* Limit G to the new interval [BEGIN, END), which must be a subset of + the current one. I.E. it can't grow on either side. */ + +static inline void +interval_generator_narrow (struct interval_generator *g, + ptrdiff_t begin, ptrdiff_t end) +{ + g->begin = max (begin, g->begin); + g->end = min (end, g->end); +} + +/* Free the memory allocated for G. */ + +void +interval_generator_destroy (struct interval_generator *g) +{ + if (! g) return; + if (g->stack) + interval_stack_destroy (g->stack); + xfree (g); +} + + +/* +===================================================================================+ + * | Stack + * +===================================================================================+ */ + +/* This is just a simple dynamic array with stack semantics. */ + +static struct interval_stack* +interval_stack_create (intmax_t initial_size) +{ + struct interval_stack *stack = xmalloc (sizeof (struct interval_stack)); + stack->size = max (0, initial_size); + stack->nodes = xmalloc (stack->size * sizeof (struct interval_node*)); + stack->length = 0; + return stack; +} + +static void +interval_stack_destroy (struct interval_stack *stack) +{ + if (! stack) + return; + if (stack->nodes) + xfree (stack->nodes); + xfree (stack); +} + +static void +interval_stack_clear (struct interval_stack *stack) +{ + stack->length = 0; +} + +static inline void +interval_stack_ensure_space (struct interval_stack *stack, intmax_t nelements) +{ + if (nelements > stack->size) + { + stack->size = (nelements + 1) * 2; + stack->nodes = xrealloc (stack->nodes, stack->size * sizeof (*stack->nodes)); + } +} + +static inline void +interval_stack_push (struct interval_stack *stack, struct interval_node *node) +{ + interval_stack_ensure_space (stack, stack->length + 1); + stack->nodes[stack->length] = node; + stack->length++; +} + +/* Push NODE on the STACK, while settings its visited flag to FLAG. */ + +static inline void +interval_stack_push_flagged (struct interval_stack *stack, + struct interval_node *node, bool flag) +{ + interval_stack_push (stack, node); + node->visited = flag; +} + +static inline struct interval_node* +interval_stack_pop (struct interval_stack *stack) +{ + if (stack->length == 0) + return NULL; + return stack->nodes[--stack->length]; +} + + +/* +===================================================================================+ + * | Internal Functions + * +===================================================================================+ */ + +/* Update NODE's limit attribute according to its children. */ + +static void +interval_tree_update_limit (const struct interval_tree *tree, + struct interval_node *node) +{ + if (node == &tree->nil) + return; + + node->limit = max (node->end, max (node->left->limit + node->left->offset, + node->right->limit + node->right->offset)); +} + +/* Apply NODE's offset to its begin, end and limit values and + propagate it to its children. + + Does nothing, if NODE is clean, i.e. NODE.otick = tree.otick . +*/ + +static void +interval_tree_inherit_offset (const struct interval_tree *tree, + struct interval_node *node) +{ + + if (node->otick == tree->otick) + return; + + node->begin += node->offset; + node->end += node->offset; + node->limit += node->offset; + if (node->left != &tree->nil) + node->left->offset += node->offset; + if (node->right != &tree->nil) + node->right->offset += node->offset; + node->offset = 0; + if (node == tree->root || node->parent->otick == tree->otick) + node->otick = tree->otick; +} + +/* Update limit of NODE and its ancestors. Stop when it becomes + stable, i.e. new_limit = old_limit. + + NODE may also be the nil node, in which case its parent is + used. (This feature is due to the RB algorithm.) +*/ + +static void +interval_tree_propagate_limit (const struct interval_tree *tree, + struct interval_node *node) +{ + if (node == &tree->nil) + node = node->parent; + if (node == &tree->nil) + return; + + while (1) { + ptrdiff_t newlimit = max (node->end, max (node->left->limit + node->left->offset, + node->right->limit + node->right->offset)); + if (newlimit == node->limit) + break; + node->limit = newlimit; + if (node == tree->root) + break; + node = node->parent; + } +} + +/* Perform the familiar left-rotation on node NODE. */ + +static void +interval_tree_rotate_left (struct interval_tree *tree, struct interval_node *node) +{ + eassert (node->right != &tree->nil); + + struct interval_node *right = node->right; + + interval_tree_inherit_offset (tree, node); + interval_tree_inherit_offset (tree, right); + + /* Turn right's left subtree into node's right subtree. */ + node->right = right->left; + if (right->left != &tree->nil) + right->left->parent = node; + + /* right's parent was node's parent. */ + if (right != &tree->nil) + right->parent = node->parent; + + /* Get the parent to point to right instead of node. */ + if (node != tree->root) + { + if (node == node->parent->left) + node->parent->left = right; + else + node->parent->right = right; + } + else + tree->root = right; + + /* Put node on right's left. */ + right->left = node; + if (node != &tree->nil) + node->parent = right; + + /* Order matters here. */ + interval_tree_update_limit (tree, node); + interval_tree_update_limit (tree, right); +} + +/* Perform the familiar right-rotation on node NODE. */ + +static void +interval_tree_rotate_right (struct interval_tree *tree, struct interval_node *node) +{ + eassert (tree && node && node->left != &tree->nil); + + struct interval_node *left = node->left; + + interval_tree_inherit_offset (tree, node); + interval_tree_inherit_offset (tree, left); + + node->left = left->right; + if (left->right != &tree->nil) + left->right->parent = node; + + if (left != &tree->nil) + left->parent = node->parent; + if (node != tree->root) + { + if (node == node->parent->right) + node->parent->right = left; + else + node->parent->left = left; + } + else + tree->root = left; + + left->right = node; + if (node != &tree->nil) + node->parent = left; + + interval_tree_update_limit (tree, left); + interval_tree_update_limit (tree, node); +} + +/* Repair the tree after an insertion. Part of the RB-Tree + algorithm. */ + +static void +interval_tree_insert_fix (struct interval_tree *tree, struct interval_node *node) +{ + while (node->parent->color == ITREE_RED) + { + /* NODE is red and its parent is red. This is a violation of + red-black tree property #3. */ + + if (node->parent == node->parent->parent->left) + { + /* We're on the left side of our grandparent, and OTHER is + our "uncle". */ + struct interval_node *uncle = node->parent->parent->right; + + if (uncle->color == ITREE_RED) /* case 1.a */ + { + /* Uncle and parent are red but should be black because + NODE is red. Change the colors accordingly and + proceed with the grandparent. */ + node->parent->color = ITREE_BLACK; + uncle->color = ITREE_BLACK; + node->parent->parent->color = ITREE_RED; + node = node->parent->parent; + } + else + { + /* Parent and uncle have different colors; parent is + red, uncle is black. */ + if (node == node->parent->right) /* case 2.a */ + { + node = node->parent; + interval_tree_rotate_left (tree, node); + } + /* case 3.a */ + node->parent->color = ITREE_BLACK; + node->parent->parent->color = ITREE_RED; + interval_tree_rotate_right (tree, node->parent->parent); + } + } + else + { + /* This is the symmetrical case of above. */ + struct interval_node *uncle = node->parent->parent->left; + + if (uncle->color == ITREE_RED) /* case 1.b */ + { + node->parent->color = ITREE_BLACK; + uncle->color = ITREE_BLACK; + node->parent->parent->color = ITREE_RED; + node = node->parent->parent; + } + else + { + if (node == node->parent->left) /* case 2.b */ + { + node = node->parent; + interval_tree_rotate_right (tree, node); + } + /* case 3.b */ + node->parent->color = ITREE_BLACK; + node->parent->parent->color = ITREE_RED; + interval_tree_rotate_left (tree, node->parent->parent); + } + } + } + + /* The root may have been changed to red due to the algorithm. Set + it to black so that property #5 is satisfied. */ + tree->root->color = ITREE_BLACK; +} + +/* Repair the tree after a deletion. Part of the RB-Tree + algorithm. */ + +static void +interval_tree_remove_fix (struct interval_tree *tree, struct interval_node *node) +{ + while (node != tree->root && node->color == ITREE_BLACK) + { + if (node == node->parent->left) + { + struct interval_node *other = node->parent->right; + + if (other->color == ITREE_RED) /* case 1.a */ + { + other->color = ITREE_BLACK; + node->parent->color = ITREE_RED; + interval_tree_rotate_left (tree, node->parent); + other = node->parent->right; + } + + if (other->left->color == ITREE_BLACK /* 2.a */ + && other->right->color == ITREE_BLACK) + { + other->color = ITREE_RED; + node = node->parent; + } + else + { + if (other->right->color == ITREE_BLACK) /* 3.a */ + { + other->left->color = ITREE_BLACK; + other->color = ITREE_RED; + interval_tree_rotate_right (tree, other); + other = node->parent->right; + } + other->color = node->parent->color; /* 4.a */ + node->parent->color = ITREE_BLACK; + other->right->color = ITREE_BLACK; + interval_tree_rotate_left (tree, node->parent); + node = tree->root; + } + } + else + { + struct interval_node *other = node->parent->left; + + if (other->color == ITREE_RED) /* 1.b */ + { + other->color = ITREE_BLACK; + node->parent->color = ITREE_RED; + interval_tree_rotate_right (tree, node->parent); + other = node->parent->left; + } + + if (other->right->color == ITREE_BLACK /* 2.b */ + && other->left->color == ITREE_BLACK) + { + other->color = ITREE_RED; + node = node->parent; + } + else + { + if (other->left->color == ITREE_BLACK) /* 3.b */ + { + other->right->color = ITREE_BLACK; + other->color = ITREE_RED; + interval_tree_rotate_left (tree, other); + other = node->parent->left; + } + + other->color = node->parent->color; /* 4.b */ + node->parent->color = ITREE_BLACK; + other->left->color = ITREE_BLACK; + interval_tree_rotate_right (tree, node->parent); + node = tree->root; + } + } + } + + node->color = ITREE_BLACK; +} + +/* Link node SOURCE in DEST's place. */ + +static void +interval_tree_transplant (struct interval_tree *tree, struct interval_node *source, + struct interval_node *dest) +{ + eassert (tree && source && dest && dest != &tree->nil); + + if (dest == tree->root) + tree->root = source; + else if (dest == dest->parent->left) + dest->parent->left = source; + else + dest->parent->right = source; + + source->parent = dest->parent; +} + + +static struct interval_node* +interval_tree_subtree_min (const struct interval_tree *tree, struct interval_node *node) +{ + if (node == &tree->nil) + return node; + while (node->left != &tree->nil) + node = node->left; + return node; +} + + +/* +===================================================================================+ + * | Debugging + * +===================================================================================+ */ + +/* See Foverlay_tree in buffer.c */ diff --git a/src/itree.h b/src/itree.h new file mode 100644 index 00000000000..d35c5afc24c --- /dev/null +++ b/src/itree.h @@ -0,0 +1,88 @@ +/* This file implements an efficient interval data-structure. + +Copyright (C) 2017 Andreas Politz (politza@hochschule-trier.de) + +This file is not part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see . */ + +#ifndef ITREE_H +#define ITREE_H +#include +#include +#include + +/* The tree and node structs are mainly here, so they can be allocated. + + NOTE: The only time where it is safe to modify node.begin and + node.end directly, is while the node is not part of any tree. + + NOTE: It is safe to read node.begin and node.end directly, if the + node came from a generator, because it validates the nodes it + returns as a side-effect. +*/ + +struct interval_node; +struct interval_node +{ + enum { ITREE_RED, ITREE_BLACK } color; + struct interval_node *parent; + struct interval_node *left; + struct interval_node *right; + ptrdiff_t begin; /* The beginning of this interval. */ + ptrdiff_t end; /* The end of the interval. */ + ptrdiff_t limit; /* The maximum end in this subtree. */ + ptrdiff_t offset; /* The amount of shift to apply to this subtree. */ + uintmax_t otick; /* offset modified tick */ + Lisp_Object data; /* Exclusively used by the client. */ + bool_bf visited; /* For traversal via generator. */ + bool_bf rear_advance : 1; /* Same as for marker and overlays. */ + bool_bf front_advance : 1; /* Same as for marker and overlays. */ +}; + +struct interval_tree +{ + struct interval_node *root; + struct interval_node nil; /* The tree's version of NULL. */ + uintmax_t otick; /* offset tick, compared with node's otick. */ + intmax_t size; /* Number of nodes in the tree. */ + struct interval_generator *iter; + bool_bf iter_running; +}; + +enum interval_tree_order { + ITREE_ASCENDING = 0, + ITREE_DEFLT_ORDER = 0, + ITREE_DESCENDING, + ITREE_PRE_ORDER, +}; + +void interval_node_init(struct interval_node *, ptrdiff_t, ptrdiff_t, bool, bool, Lisp_Object); +ptrdiff_t interval_node_begin(struct interval_tree *, struct interval_node *); +ptrdiff_t interval_node_end(struct interval_tree *, struct interval_node *); +void interval_node_set_region(struct interval_tree *, struct interval_node *, ptrdiff_t, ptrdiff_t); +struct interval_tree *interval_tree_create(void); +void interval_tree_destroy(struct interval_tree *); +intmax_t interval_tree_size(struct interval_tree *); +void interval_tree_clear(struct interval_tree *); +void interval_tree_insert(struct interval_tree *, struct interval_node *); +bool interval_tree_contains(struct interval_tree *, struct interval_node *); +struct interval_node *interval_tree_remove(struct interval_tree *, struct interval_node *); +void interval_tree_iter_start(struct interval_tree *, ptrdiff_t, ptrdiff_t, enum interval_tree_order); +void interval_tree_iter_narrow(struct interval_tree *, ptrdiff_t, ptrdiff_t); +void interval_tree_iter_finish(struct interval_tree *); +struct interval_node *interval_tree_iter_next(struct interval_tree *); +void interval_tree_insert_gap(struct interval_tree *, ptrdiff_t, ptrdiff_t); +void interval_tree_delete_gap(struct interval_tree *, ptrdiff_t, ptrdiff_t); +#endif diff --git a/src/keyboard.c b/src/keyboard.c index e8701b88708..60cdaba9f0b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1668,8 +1668,8 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) && display_prop_intangible_p (val, overlay, PT, PT_BYTE) && (!OVERLAYP (overlay) ? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil) - : (beg = OVERLAY_POSITION (OVERLAY_START (overlay)), - end = OVERLAY_POSITION (OVERLAY_END (overlay)))) + : (beg = OVERLAY_START (overlay), + end = OVERLAY_END (overlay))) && (beg < PT /* && end > PT <- It's always the case. */ || (beg <= PT && STRINGP (val) && SCHARS (val) == 0))) { diff --git a/src/lisp.h b/src/lisp.h index 680c25d4c49..222a99950a8 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2217,15 +2217,14 @@ struct Lisp_Overlay - next fields of start and end markers (singly linked list of markers). I.e. 9words plus 2 bits, 3words of which are for external linked lists. */ - { - ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Overlay */ - bool_bf gcmarkbit : 1; - unsigned spacer : 15; - struct Lisp_Overlay *next; - Lisp_Object start; - Lisp_Object end; - Lisp_Object plist; - }; +{ + ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Overlay */ + bool_bf gcmarkbit : 1; + unsigned spacer : 15; + Lisp_Object plist; + struct buffer *buffer; /* eassert (live buffer || NULL). */ + struct interval_node *interval; +}; /* Number of bits needed to store one of the values SAVE_UNUSED..SAVE_OBJECT. */ @@ -3704,7 +3703,7 @@ extern Lisp_Object make_save_funcptr_ptr_obj (void (*) (void), void *, Lisp_Object); extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t); extern void free_save_value (Lisp_Object); -extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); +extern Lisp_Object build_overlay (ptrdiff_t, ptrdiff_t, bool, bool, Lisp_Object); extern void free_marker (Lisp_Object); extern void free_cons (struct Lisp_Cons *); extern void init_alloc_once (void); diff --git a/src/print.c b/src/print.c index f280616af8a..a07baa3067a 100644 --- a/src/print.c +++ b/src/print.c @@ -548,8 +548,7 @@ temp_output_buffer_setup (const char *bufname) bset_read_only (current_buffer, Qnil); bset_filename (current_buffer, Qnil); bset_undo_list (current_buffer, Qt); - eassert (current_buffer->overlays_before == NULL); - eassert (current_buffer->overlays_after == NULL); + eassert (current_buffer->overlays == NULL); bset_enable_multibyte_characters (current_buffer, BVAR (&buffer_defaults, enable_multibyte_characters)); specbind (Qinhibit_read_only, Qt); @@ -2074,7 +2073,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) obj = XCDR (obj); if (!(i & 1)) halftail = XCDR (halftail); - } + } /* OBJ non-nil here means it's the end of a dotted list. */ if (!NILP (obj)) @@ -2114,15 +2113,14 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) case Lisp_Misc_Overlay: print_c_string ("#buffer) + if (! OVERLAY_BUFFER (obj)) print_c_string ("in no buffer", printcharfun); else { int len = sprintf (buf, "from %"pD"d to %"pD"d in ", - marker_position (OVERLAY_START (obj)), - marker_position (OVERLAY_END (obj))); + OVERLAY_START (obj), OVERLAY_END (obj)); strout (buf, len, len, printcharfun); - print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name), + print_string (BVAR (OVERLAY_BUFFER (obj), name), printcharfun); } printchar ('>', printcharfun); diff --git a/src/textprop.c b/src/textprop.c index 513780c3009..aebb6524e68 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -617,36 +617,42 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop, } if (BUFFERP (object)) { - ptrdiff_t noverlays; - Lisp_Object *overlay_vec; - struct buffer *obuf = current_buffer; + struct buffer *b = XBUFFER (object); + struct interval_node *node; + struct sortvec items[2]; + struct sortvec *result = NULL; + Lisp_Object result_tem = Qnil; - if (XINT (position) < BUF_BEGV (XBUFFER (object)) - || XINT (position) > BUF_ZV (XBUFFER (object))) + if (XINT (position) < BUF_BEGV (b) || XINT (position) > BUF_ZV (b)) xsignal1 (Qargs_out_of_range, position); - set_buffer_temp (XBUFFER (object)); - - USE_SAFE_ALLOCA; - GET_OVERLAYS_AT (XINT (position), overlay_vec, noverlays, NULL, false); - noverlays = sort_overlays (overlay_vec, noverlays, w); - - set_buffer_temp (obuf); + buffer_overlay_iter_start(b, XINT (position), XINT (position) + 1, + ITREE_ASCENDING); /* Now check the overlays in order of decreasing priority. */ - while (--noverlays >= 0) + while ((node = buffer_overlay_iter_next (b))) { - Lisp_Object tem = Foverlay_get (overlay_vec[noverlays], prop); - if (!NILP (tem)) - { - if (overlay) - /* Return the overlay we got the property from. */ - *overlay = overlay_vec[noverlays]; - SAFE_FREE (); - return tem; - } + Lisp_Object tem = Foverlay_get (node->data, prop); + struct sortvec *this; + + if (NILP (tem) || (w && ! overlay_matches_window (w, node->data))) + continue; + + this = (result == items ? items + 1 : items); + make_sortvec_item (this, node->data); + if (! result || (compare_overlays (result, this) < 0)) + { + result = this; + result_tem = tem; + } } - SAFE_FREE (); + buffer_overlay_iter_finish (b); + if (result) + { + if (overlay) + *overlay = result->overlay; + return result_tem; + } } if (overlay) diff --git a/src/window.h b/src/window.h index df7c23f824b..324d30b57f9 100644 --- a/src/window.h +++ b/src/window.h @@ -1128,6 +1128,16 @@ output_cursor_to (struct window *w, int vpos, int hpos, int y, int x) w->output_cursor.y = y; } +/* Return true, if overlay OV's properties should have an effect in + window W. */ +INLINE bool +overlay_matches_window (const struct window *w, Lisp_Object ov) +{ + eassert (OVERLAYP (ov)); + Lisp_Object window = Foverlay_get (ov, Qwindow); + return (! WINDOWP (window) || XWINDOW (window) == w); +} + INLINE_HEADER_END #endif /* not WINDOW_H_INCLUDED */ diff --git a/src/xdisp.c b/src/xdisp.c index 86164eb9f6f..b3b9ecae377 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -873,7 +873,6 @@ static enum move_it_result static void get_visually_first_element (struct it *); static void compute_stop_pos (struct it *); static int face_before_or_after_it_pos (struct it *, bool); -static ptrdiff_t next_overlay_change (ptrdiff_t); static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object, Lisp_Object, struct text_pos *, ptrdiff_t, bool); static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object, @@ -3606,39 +3605,6 @@ compute_stop_pos (struct it *it) && it->stop_charpos >= IT_CHARPOS (*it))); } - -/* Return the position of the next overlay change after POS in - current_buffer. Value is point-max if no overlay change - follows. This is like `next-overlay-change' but doesn't use - xmalloc. */ - -static ptrdiff_t -next_overlay_change (ptrdiff_t pos) -{ - ptrdiff_t i, noverlays; - ptrdiff_t endpos; - Lisp_Object *overlays; - USE_SAFE_ALLOCA; - - /* Get all overlays at the given position. */ - GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, true); - - /* If any of these overlays ends before endpos, - use its ending point instead. */ - for (i = 0; i < noverlays; ++i) - { - Lisp_Object oend; - ptrdiff_t oendpos; - - oend = OVERLAY_END (overlays[i]); - oendpos = OVERLAY_POSITION (oend); - endpos = min (endpos, oendpos); - } - - SAFE_FREE (); - return endpos; -} - /* How many characters forward to search for a display property or display string. Searching too far forward makes the bidi display sluggish, especially in small windows. */ @@ -5071,7 +5037,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, overlay's display string/image twice. */ if (!NILP (overlay)) { - ptrdiff_t ovendpos = OVERLAY_POSITION (OVERLAY_END (overlay)); + ptrdiff_t ovendpos = OVERLAY_END (overlay); /* Some borderline-sane Lisp might call us with the current buffer narrowed so that overlay-end is outside the @@ -5785,13 +5751,14 @@ static void load_overlay_strings (struct it *it, ptrdiff_t charpos) { Lisp_Object overlay, window, str, invisible; - struct Lisp_Overlay *ov; ptrdiff_t start, end; ptrdiff_t n = 0, i, j; int invis; struct overlay_entry entriesbuf[20]; ptrdiff_t size = ARRAYELTS (entriesbuf); struct overlay_entry *entries = entriesbuf; + struct interval_node *node; + USE_SAFE_ALLOCA; if (charpos <= 0) @@ -5823,83 +5790,47 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos) } \ while (false) - /* Process overlay before the overlay center. */ - for (ov = current_buffer->overlays_before; ov; ov = ov->next) + if (current_buffer->overlays) { - XSETMISC (overlay, ov); - eassert (OVERLAYP (overlay)); - start = OVERLAY_POSITION (OVERLAY_START (overlay)); - end = OVERLAY_POSITION (OVERLAY_END (overlay)); - - if (end < charpos) - break; - - /* Skip this overlay if it doesn't start or end at IT's current - position. */ - if (end != charpos && start != charpos) - continue; - - /* Skip this overlay if it doesn't apply to IT->w. */ - window = Foverlay_get (overlay, Qwindow); - if (WINDOWP (window) && XWINDOW (window) != it->w) - continue; - - /* If the text ``under'' the overlay is invisible, both before- - and after-strings from this overlay are visible; start and - end position are indistinguishable. */ - invisible = Foverlay_get (overlay, Qinvisible); - invis = TEXT_PROP_MEANS_INVISIBLE (invisible); - - /* If overlay has a non-empty before-string, record it. */ - if ((start == charpos || (end == charpos && invis != 0)) - && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) - && SCHARS (str)) - RECORD_OVERLAY_STRING (overlay, str, false); - - /* If overlay has a non-empty after-string, record it. */ - if ((end == charpos || (start == charpos && invis != 0)) - && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)) - && SCHARS (str)) - RECORD_OVERLAY_STRING (overlay, str, true); - } - - /* Process overlays after the overlay center. */ - for (ov = current_buffer->overlays_after; ov; ov = ov->next) - { - XSETMISC (overlay, ov); - eassert (OVERLAYP (overlay)); - start = OVERLAY_POSITION (OVERLAY_START (overlay)); - end = OVERLAY_POSITION (OVERLAY_END (overlay)); - - if (start > charpos) - break; - - /* Skip this overlay if it doesn't start or end at IT's current - position. */ - if (end != charpos && start != charpos) - continue; - - /* Skip this overlay if it doesn't apply to IT->w. */ - window = Foverlay_get (overlay, Qwindow); - if (WINDOWP (window) && XWINDOW (window) != it->w) - continue; - - /* If the text ``under'' the overlay is invisible, it has a zero - dimension, and both before- and after-strings apply. */ - invisible = Foverlay_get (overlay, Qinvisible); - invis = TEXT_PROP_MEANS_INVISIBLE (invisible); - - /* If overlay has a non-empty before-string, record it. */ - if ((start == charpos || (end == charpos && invis != 0)) - && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) - && SCHARS (str)) - RECORD_OVERLAY_STRING (overlay, str, false); - - /* If overlay has a non-empty after-string, record it. */ - if ((end == charpos || (start == charpos && invis != 0)) - && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)) - && SCHARS (str)) - RECORD_OVERLAY_STRING (overlay, str, true); + buffer_overlay_iter_start (current_buffer, + charpos - 1, charpos + 1, ITREE_DESCENDING); + /* Process overlays. */ + while ((node = buffer_overlay_iter_next (current_buffer))) + { + overlay = node->data; + eassert (OVERLAYP (overlay)); + start = node->begin; + end = node->end; + + /* Skip this overlay if it doesn't start or end at IT's current + position. */ + if (end != charpos && start != charpos) + continue; + + /* Skip this overlay if it doesn't apply to IT->w. */ + window = Foverlay_get (overlay, Qwindow); + if (WINDOWP (window) && XWINDOW (window) != it->w) + continue; + + /* If the text ``under'' the overlay is invisible, both before- + and after-strings from this overlay are visible; start and + end position are indistinguishable. */ + invisible = Foverlay_get (overlay, Qinvisible); + invis = TEXT_PROP_MEANS_INVISIBLE (invisible); + + /* If overlay has a non-empty before-string, record it. */ + if ((start == charpos || (end == charpos && invis != 0)) + && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) + && SCHARS (str)) + RECORD_OVERLAY_STRING (overlay, str, false); + + /* If overlay has a non-empty after-string, record it. */ + if ((end == charpos || (start == charpos && invis != 0)) + && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)) + && SCHARS (str)) + RECORD_OVERLAY_STRING (overlay, str, true); + } + buffer_overlay_iter_finish (current_buffer); } #undef RECORD_OVERLAY_STRING @@ -6463,7 +6394,7 @@ back_to_previous_visible_line_start (struct it *it) && !NILP (val = get_char_property_and_overlay (make_number (pos), Qdisplay, Qnil, &overlay)) && (OVERLAYP (overlay) - ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) + ? (beg = OVERLAY_START (overlay)) : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) { RESTORE_IT (it, it, it2data); @@ -9568,7 +9499,6 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos } /* Reset/increment for the next run. */ - recenter_overlay_lists (current_buffer, IT_CHARPOS (*it)); it->current_x = line_start_x; line_start_x = 0; it->hpos = 0; @@ -21212,13 +21142,6 @@ display_line (struct it *it, int cursor_vpos) row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; it->starts_in_middle_of_char_p = false; - /* Arrange the overlays nicely for our purposes. Usually, we call - display_line on only one line at a time, in which case this - can't really hurt too much, or we call it on lines which appear - one after another in the buffer, in which case all calls to - recenter_overlay_lists but the first will be pretty cheap. */ - recenter_overlay_lists (current_buffer, IT_CHARPOS (*it)); - /* If we are going to display the cursor's line, account for the hscroll of that line. We subtract the window's min_hscroll, because that was already accounted for in init_iterator. */ @@ -31212,7 +31135,7 @@ note_mouse_highlight (struct frame *f, int x, int y) if (BUFFERP (object)) { /* Put all the overlays we want in a vector in overlay_vec. */ - GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false); + GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL); /* Sort overlays into increasing priority order. */ noverlays = sort_overlays (overlay_vec, noverlays, w); } diff --git a/src/xfaces.c b/src/xfaces.c index b309c161278..b1788725eb7 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -5931,8 +5931,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, USE_SAFE_ALLOCA; { ptrdiff_t next_overlay; - - GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, false); + GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay); if (next_overlay < endpos) endpos = next_overlay; } @@ -5975,7 +5974,6 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, { for (prop = Qnil, i = noverlays - 1; i >= 0 && NILP (prop); --i) { - Lisp_Object oend; ptrdiff_t oendpos; prop = Foverlay_get (overlay_vec[i], propname); @@ -5988,8 +5986,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, merge_face_ref (f, prop, attrs, true, 0); } - oend = OVERLAY_END (overlay_vec[i]); - oendpos = OVERLAY_POSITION (oend); + oendpos = OVERLAY_END (overlay_vec[i]); if (oendpos < endpos) endpos = oendpos; } @@ -5998,18 +5995,16 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, { for (i = 0; i < noverlays; i++) { - Lisp_Object oend; ptrdiff_t oendpos; prop = Foverlay_get (overlay_vec[i], propname); if (!NILP (prop)) merge_face_ref (f, prop, attrs, true, 0); - oend = OVERLAY_END (overlay_vec[i]); - oendpos = OVERLAY_POSITION (oend); - if (oendpos < endpos) - endpos = oendpos; - } + oendpos = OVERLAY_END (overlay_vec[i]); + if (oendpos < endpos) + endpos = oendpos; + } } *endptr = endpos; diff --git a/test/manual/noverlay/.gitignore b/test/manual/noverlay/.gitignore new file mode 100644 index 00000000000..ca7fc452b84 --- /dev/null +++ b/test/manual/noverlay/.gitignore @@ -0,0 +1 @@ +itree-tests diff --git a/test/manual/noverlay/Makefile.in b/test/manual/noverlay/Makefile.in new file mode 100644 index 00000000000..beef1dbc097 --- /dev/null +++ b/test/manual/noverlay/Makefile.in @@ -0,0 +1,32 @@ +PROGRAM = itree-tests +LIBS = check +top_srcdir = @top_srcdir@ +CFLAGS += -O0 -g3 $(shell pkg-config --cflags $(LIBS)) -I $(top_srcdir)/src +LDFLAGS += $(shell pkg-config --libs $(LIBS)) -lm +OBJECTS = itree-tests.o +CC = gcc +EMACS ?= ../../../src/emacs + +.PHONY: all check have-libcheck + +all: check + +have-libcheck: + pkg-config --cflags $(LIBS) + +check: have-libcheck $(PROGRAM) + ./check-sanitize.sh ./$(PROGRAM) + +itree-tests.o: emacs-compat.h itree-tests.c $(top_srcdir)/src/itree.c $(top_srcdir)/src/itree.h + +$(PROGRAM): $(OBJECTS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) -o $(PROGRAM) + +perf: + -$(EMACS) -Q -l ./overlay-perf.el -f perf-run-batch + +clean: + rm -f -- $(OBJECTS) $(PROGRAM) + +distclean: clean + rm -f -- Makefile diff --git a/test/manual/noverlay/check-sanitize.sh b/test/manual/noverlay/check-sanitize.sh new file mode 100755 index 00000000000..03eedce8a67 --- /dev/null +++ b/test/manual/noverlay/check-sanitize.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +prog=$1 +shift + +[ -z "$prog" ] && { + echo "usage:$(basename $0) CHECK_PRGOGRAM"; + exit 1; +} + +"$prog" "$@" | sed -e 's/^\([^:]\+\):\([0-9]\+\):[PFE]:[^:]*:\([^:]*\):[^:]*: *\(.*\)/\1:\2:\3:\4/' diff --git a/test/manual/noverlay/emacs-compat.h b/test/manual/noverlay/emacs-compat.h new file mode 100644 index 00000000000..812f8e48a36 --- /dev/null +++ b/test/manual/noverlay/emacs-compat.h @@ -0,0 +1,52 @@ +#ifndef TEST_COMPAT_H +#define TEST_COMPAT_H + +#include +#include + +typedef int Lisp_Object; + +void * +xmalloc (size_t size) +{ + return malloc (size); +} + +void +xfree (void *ptr) +{ + free (ptr); +} + +void * +xrealloc (void *block, size_t size) +{ + return realloc (block, size); +} + +void +emacs_abort () +{ + fprintf (stderr, "Aborting...\n"); + exit (1); +} + +#ifndef eassert +#define eassert(cond) \ + do { \ + if (! (cond)) { \ + fprintf (stderr, "\n%s:%d:eassert condition failed: %s\n", \ + __FILE__, __LINE__ ,#cond); \ + exit (1); \ + } \ + } while (0) +#endif + +#ifndef max +#define max(x,y) ((x) >= (y) ? (x) : (y)) +#endif +#ifndef min +#define min(x,y) ((x) <= (y) ? (x) : (y)) +#endif + +#endif diff --git a/test/manual/noverlay/itree-tests.c b/test/manual/noverlay/itree-tests.c new file mode 100644 index 00000000000..a3183892132 --- /dev/null +++ b/test/manual/noverlay/itree-tests.c @@ -0,0 +1,1381 @@ +#include +#include +#include +#include +#include "emacs-compat.h" + +#define EMACS_LISP_H /* lisp.h inclusion guard */ +#define ITREE_DEBUG 1 +#define ITREE_TESTING +#include "itree.c" + +/* Basic tests of the interval_tree data-structure. */ + +/* +===================================================================================+ + * | Insert + * +===================================================================================+ */ + +/* The graphs below display the trees after each insertion (as they + should be). See the source code for the different cases + applied. */ + +#define N_50 (n[0]) +#define N_30 (n[1]) +#define N_20 (n[2]) +#define N_10 (n[3]) +#define N_15 (n[4]) +#define N_05 (n[5]) + +#define DEF_TEST_SETUP() \ + struct interval_tree tree; \ + struct interval_node n[6]; \ + interval_tree_init (&tree); \ + const int values[] = {50, 30, 20, 10, 15, 5}; \ + for (int i = 0; i < 6; ++i) \ + { \ + n[i].begin = values[i]; \ + n[i].end = values[i]; \ + } + +START_TEST (test_insert_1) +{ + /* + * [50] + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (&N_50 == tree.root); +} +END_TEST + +START_TEST (test_insert_2) +{ + /* + * [50] + * / + * (30) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_30); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (N_30.color == ITREE_RED); + ck_assert (&N_50 == tree.root); + ck_assert (N_30.parent == &N_50); + ck_assert (N_50.left == &N_30); + ck_assert (N_50.right == &tree.nil); + ck_assert (N_30.left == &tree.nil); + ck_assert (N_30.right == &tree.nil); +} +END_TEST + +START_TEST (test_insert_3) +{ + /* case 3.a + * [30] + * / \ + * (20) (50) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_30); + interval_tree_insert (&tree, &N_20); + ck_assert (N_50.color == ITREE_RED); + ck_assert (N_30.color == ITREE_BLACK); + ck_assert (N_20.color == ITREE_RED); + ck_assert (&N_30 == tree.root); + ck_assert (N_50.parent == &N_30); + ck_assert (N_30.right == &N_50); + ck_assert (N_30.left == &N_20); + ck_assert (N_20.left == &tree.nil); + ck_assert (N_20.right == &tree.nil); + ck_assert (N_20.parent == &N_30); +} +END_TEST + +START_TEST (test_insert_4) +{ + /* 1.a + * [30] + * / \ + * [20] [50] + * / + * (10) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_30); + interval_tree_insert (&tree, &N_20); + interval_tree_insert (&tree, &N_10); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (N_30.color == ITREE_BLACK); + ck_assert (N_20.color == ITREE_BLACK); + ck_assert (N_10.color == ITREE_RED); + ck_assert (&N_30 == tree.root); + ck_assert (N_50.parent == &N_30); + ck_assert (N_30.right == &N_50); + ck_assert (N_30.left == &N_20); + ck_assert (N_20.left == &N_10); + ck_assert (N_20.right == &tree.nil); + ck_assert (N_20.parent == &N_30); + ck_assert (N_10.parent == &N_20); + ck_assert (N_20.left == &N_10); + ck_assert (N_10.right == &tree.nil); +} +END_TEST + +START_TEST (test_insert_5) +{ + /* 2.a + * [30] + * / \ + * [15] [50] + * / \ + * (10) (20) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_30); + interval_tree_insert (&tree, &N_20); + interval_tree_insert (&tree, &N_10); + interval_tree_insert (&tree, &N_15); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (N_30.color == ITREE_BLACK); + ck_assert (N_20.color == ITREE_RED); + ck_assert (N_10.color == ITREE_RED); + ck_assert (N_15.color == ITREE_BLACK); + ck_assert (&N_30 == tree.root); + ck_assert (N_50.parent == &N_30); + ck_assert (N_30.right == &N_50); + ck_assert (N_30.left == &N_15); + ck_assert (N_20.left == &tree.nil); + ck_assert (N_20.right == &tree.nil); + ck_assert (N_20.parent == &N_15); + ck_assert (N_10.parent == &N_15); + ck_assert (N_20.left == &tree.nil); + ck_assert (N_10.right == &tree.nil); + ck_assert (N_15.right == &N_20); + ck_assert (N_15.left == &N_10); + ck_assert (N_15.parent == &N_30); + +} +END_TEST + +START_TEST (test_insert_6) +{ + /* 1.a + * [30] + * / \ + * (15) [50] + * / \ + * [10] [20] + * / + * (5) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_30); + interval_tree_insert (&tree, &N_20); + interval_tree_insert (&tree, &N_10); + interval_tree_insert (&tree, &N_15); + interval_tree_insert (&tree, &N_05); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (N_30.color == ITREE_BLACK); + ck_assert (N_20.color == ITREE_BLACK); + ck_assert (N_10.color == ITREE_BLACK); + ck_assert (N_15.color == ITREE_RED); + ck_assert (N_05.color == ITREE_RED); + ck_assert (&N_30 == tree.root); + ck_assert (N_50.parent == &N_30); + ck_assert (N_30.right == &N_50); + ck_assert (N_30.left == &N_15); + ck_assert (N_20.left == &tree.nil); + ck_assert (N_20.right == &tree.nil); + ck_assert (N_20.parent == &N_15); + ck_assert (N_10.parent == &N_15); + ck_assert (N_20.left == &tree.nil); + ck_assert (N_10.right == &tree.nil); + ck_assert (N_15.right == &N_20); + ck_assert (N_15.left == &N_10); + ck_assert (N_15.parent == &N_30); + ck_assert (N_05.parent == &N_10); + ck_assert (N_10.left == &N_05); + ck_assert (N_05.right == &tree.nil); +} +END_TEST + +#undef N_50 +#undef N_30 +#undef N_20 +#undef N_10 +#undef N_15 +#undef N_05 +#undef DEF_TEST_SETUP + + + +/* These are the mirror cases to the above ones. */ + +#define N_50 (n[0]) +#define N_70 (n[1]) +#define N_80 (n[2]) +#define N_90 (n[3]) +#define N_85 (n[4]) +#define N_95 (n[5]) + +#define DEF_TEST_SETUP() \ + struct interval_tree tree; \ + struct interval_node n[6]; \ + interval_tree_init (&tree); \ + const int values[] = {50, 70, 80, 90, 85, 95}; \ + for (int i = 0; i < 6; ++i) \ + { \ + n[i].begin = values[i]; \ + n[i].end = values[i]; \ + } + +START_TEST (test_insert_7) +{ + /* + * [50] + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (&N_50 == tree.root); +} +END_TEST + +START_TEST (test_insert_8) +{ + /* + * [50] + * \ + * (70) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_70); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (N_70.color == ITREE_RED); + ck_assert (&N_50 == tree.root); + ck_assert (N_70.parent == &N_50); + ck_assert (N_50.right == &N_70); + ck_assert (N_50.left == &tree.nil); + ck_assert (N_70.right == &tree.nil); + ck_assert (N_70.left == &tree.nil); +} +END_TEST + +START_TEST (test_insert_9) +{ + /* 3.a + * [70] + * / \ + * (50) (80) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_70); + interval_tree_insert (&tree, &N_80); + ck_assert (N_50.color == ITREE_RED); + ck_assert (N_70.color == ITREE_BLACK); + ck_assert (N_80.color == ITREE_RED); + ck_assert (&N_70 == tree.root); + ck_assert (N_50.parent == &N_70); + ck_assert (N_70.right == &N_80); + ck_assert (N_70.left == &N_50); + ck_assert (N_80.right == &tree.nil); + ck_assert (N_80.left == &tree.nil); + ck_assert (N_80.parent == &N_70); +} +END_TEST + +START_TEST (test_insert_10) +{ + /* 1.b + * [70] + * / \ + * [50] [80] + * \ + * (90) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_70); + interval_tree_insert (&tree, &N_80); + interval_tree_insert (&tree, &N_90); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (N_70.color == ITREE_BLACK); + ck_assert (N_80.color == ITREE_BLACK); + ck_assert (N_90.color == ITREE_RED); + ck_assert (&N_70 == tree.root); + ck_assert (N_50.parent == &N_70); + ck_assert (N_70.right == &N_80); + ck_assert (N_70.left == &N_50); + ck_assert (N_80.right == &N_90); + ck_assert (N_80.left == &tree.nil); + ck_assert (N_80.parent == &N_70); + ck_assert (N_90.parent == &N_80); + ck_assert (N_80.right == &N_90); + ck_assert (N_90.left == &tree.nil); +} +END_TEST + +START_TEST (test_insert_11) +{ + /* 2.b + * [70] + * / \ + * [50] [85] + * / \ + * (80) (90) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_70); + interval_tree_insert (&tree, &N_80); + interval_tree_insert (&tree, &N_90); + interval_tree_insert (&tree, &N_85); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (N_70.color == ITREE_BLACK); + ck_assert (N_80.color == ITREE_RED); + ck_assert (N_90.color == ITREE_RED); + ck_assert (N_85.color == ITREE_BLACK); + ck_assert (&N_70 == tree.root); + ck_assert (N_50.parent == &N_70); + ck_assert (N_70.right == &N_85); + ck_assert (N_70.left == &N_50); + ck_assert (N_80.right == &tree.nil); + ck_assert (N_80.left == &tree.nil); + ck_assert (N_80.parent == &N_85); + ck_assert (N_90.parent == &N_85); + ck_assert (N_80.right == &tree.nil); + ck_assert (N_90.left == &tree.nil); + ck_assert (N_85.right == &N_90); + ck_assert (N_85.left == &N_80); + ck_assert (N_85.parent == &N_70); + +} +END_TEST + +START_TEST (test_insert_12) +{ + /* 1.b + * [70] + * / \ + * [50] (85) + * / \ + * [80] [90] + * \ + * (95) + */ + + DEF_TEST_SETUP (); + interval_tree_insert (&tree, &N_50); + interval_tree_insert (&tree, &N_70); + interval_tree_insert (&tree, &N_80); + interval_tree_insert (&tree, &N_90); + interval_tree_insert (&tree, &N_85); + interval_tree_insert (&tree, &N_95); + ck_assert (N_50.color == ITREE_BLACK); + ck_assert (N_70.color == ITREE_BLACK); + ck_assert (N_80.color == ITREE_BLACK); + ck_assert (N_90.color == ITREE_BLACK); + ck_assert (N_85.color == ITREE_RED); + ck_assert (N_95.color == ITREE_RED); + ck_assert (&N_70 == tree.root); + ck_assert (N_50.parent == &N_70); + ck_assert (N_70.right == &N_85); + ck_assert (N_70.left == &N_50); + ck_assert (N_80.right == &tree.nil); + ck_assert (N_80.left == &tree.nil); + ck_assert (N_80.parent == &N_85); + ck_assert (N_90.parent == &N_85); + ck_assert (N_80.right == &tree.nil); + ck_assert (N_90.left == &tree.nil); + ck_assert (N_85.right == &N_90); + ck_assert (N_85.left == &N_80); + ck_assert (N_85.parent == &N_70); + ck_assert (N_95.parent == &N_90); + ck_assert (N_90.right == &N_95); + ck_assert (N_95.left == &tree.nil); +} +END_TEST + +#undef N_50 +#undef N_70 +#undef N_80 +#undef N_90 +#undef N_85 +#undef N_95 +#undef DEF_TEST_SETUP + +struct interval_tree* +test_get_tree4 (struct interval_node **n) +{ + static struct interval_tree tree; + static struct interval_node nodes[4]; + memset (&tree, 0, sizeof (struct interval_tree)); + memset (&nodes, 0, 4 * sizeof (struct interval_node)); + interval_tree_init (&tree); + for (int i = 0; i < 4; ++i) + { + nodes[i].begin = 10 * (i + 1); + nodes[i].end = nodes[i].begin; + interval_tree_insert (&tree, &nodes[i]); + } + *n = nodes; + return &tree; +} + +static void +shuffle (int *index, int n) +{ + for (int i = n - 1; i >= 0; --i) + { + int j = random () % (i + 1); + int h = index[j]; + index[j] = index[i]; + index[i] = h; + } +} + +#define N_10 (nodes[0]) +#define N_20 (nodes[1]) +#define N_30 (nodes[2]) +#define N_40 (nodes[3]) + +START_TEST (test_insert_13) +{ + struct interval_node *nodes = NULL; + struct interval_tree *tree = test_get_tree4 (&nodes); + + + ck_assert (tree->root == &N_20); + ck_assert (N_20.left == &N_10); + ck_assert (N_20.right == &N_30); + ck_assert (N_30.right == &N_40); + ck_assert (N_10.color == ITREE_BLACK); + ck_assert (N_20.color == ITREE_BLACK); + ck_assert (N_30.color == ITREE_BLACK); + ck_assert (N_40.color == ITREE_RED); +} +END_TEST + +START_TEST (test_insert_14) +{ + struct interval_tree tree; + struct interval_node nodes[3]; + + nodes[0].begin = nodes[1].begin = nodes[2].begin = 10; + nodes[0].end = nodes[1].end = nodes[2].end = 10; + + for (int i = 0; i < 3; ++i) + interval_tree_insert (&tree, &nodes[i]); + for (int i = 0; i < 3; ++i) + ck_assert (interval_tree_contains (&tree, &nodes[i])); +} +END_TEST + + + + +/* +===================================================================================+ + * | Remove + * +===================================================================================+ */ + +#define A (nodes[0]) +#define B (nodes[1]) +#define C (nodes[2]) +#define D (nodes[3]) +#define E (nodes[4]) + +/* Creating proper test trees for the formal tests via insertions is + way to tedious, so we just fake it and only test the + fix-routine. */ +#define DEF_TEST_SETUP() \ + struct interval_tree tree; \ + struct interval_node nodes[5]; \ + interval_tree_init (&tree); \ + tree.root = &B; \ + A.parent = &B; B.parent = &tree.nil; C.parent = &D; \ + D.parent = &B; E.parent = &D; \ + A.left = A.right = C.left = C.right = &tree.nil; \ + E.left = E.right = &tree.nil; \ + B.left = &A; B.right = &D; D.left = &C; D.right = &E \ + +/* 1.a -> 2.a + * [B] + * / \ + * [A] (D) + * / \ + * [C] [E] + */ + + +START_TEST (test_remove_1) +{ + DEF_TEST_SETUP (); + B.color = A.color = C.color = E.color = ITREE_BLACK; + D.color = ITREE_RED; + interval_tree_remove_fix (&tree, &A); + + ck_assert (A.color == ITREE_BLACK); + ck_assert (B.color == ITREE_BLACK); + ck_assert (C.color == ITREE_RED); + ck_assert (D.color == ITREE_BLACK); + ck_assert (E.color == ITREE_BLACK); + ck_assert (A.parent == &B); + ck_assert (B.left == &A); + ck_assert (B.right == &C); + ck_assert (C.parent == &B); + ck_assert (E.parent == &D); + ck_assert (D.right == &E); + ck_assert (D.left == &B); + ck_assert (tree.root == &D); +} +END_TEST + +/* 2.a */ +START_TEST (test_remove_2) +{ + DEF_TEST_SETUP (); + B.color = D.color = A.color = C.color = E.color = ITREE_BLACK; + interval_tree_remove_fix (&tree, &A); + + ck_assert (A.color == ITREE_BLACK); + ck_assert (B.color == ITREE_BLACK); + ck_assert (C.color == ITREE_BLACK); + ck_assert (D.color == ITREE_RED); + ck_assert (E.color == ITREE_BLACK); + ck_assert (A.parent == &B); + ck_assert (B.left == &A); + ck_assert (B.right == &D); + ck_assert (C.parent == &D); + ck_assert (E.parent == &D); + ck_assert (tree.root == &B); +} +END_TEST + +/* 3.a -> 4.a*/ +START_TEST (test_remove_3) +{ + DEF_TEST_SETUP (); + D.color = A.color = E.color = ITREE_BLACK; + B.color = C.color = ITREE_RED; + interval_tree_remove_fix (&tree, &A); + + ck_assert (A.color == ITREE_BLACK); + ck_assert (B.color == ITREE_BLACK); + ck_assert (C.color == ITREE_BLACK); + ck_assert (D.color == ITREE_BLACK); + ck_assert (E.color == ITREE_BLACK); + ck_assert (A.parent == &B); + ck_assert (B.left == &A); + ck_assert (B.right == &tree.nil); + ck_assert (&C == tree.root); + ck_assert (C.left == &B); + ck_assert (C.right == &D); + ck_assert (E.parent == &D); + ck_assert (D.left == &tree.nil); + +} +END_TEST + +/* 4.a */ +START_TEST (test_remove_4) +{ + DEF_TEST_SETUP (); + B.color = C.color = E.color = ITREE_RED; + A.color = D.color = ITREE_BLACK; + interval_tree_remove_fix (&tree, &A); + + ck_assert (A.color == ITREE_BLACK); + ck_assert (B.color == ITREE_BLACK); + ck_assert (C.color == ITREE_RED); + ck_assert (D.color == ITREE_BLACK); + ck_assert (E.color == ITREE_BLACK); + ck_assert (A.parent == &B); + ck_assert (B.left == &A); + ck_assert (B.right == &C); + ck_assert (C.parent == &B); + ck_assert (E.parent == &D); + ck_assert (tree.root == &D); +} +END_TEST + + +#undef A +#undef B +#undef C +#undef D +#undef E +#undef DEF_TEST_SETUP + + + +/* These are the mirrored cases. */ + +#define A (nodes[0]) +#define B (nodes[1]) +#define C (nodes[2]) +#define D (nodes[3]) +#define E (nodes[4]) + +#define DEF_TEST_SETUP() \ + struct interval_tree tree; \ + struct interval_node nodes[5]; \ + interval_tree_init (&tree); \ + tree.root = &B; \ + A.parent = &B; B.parent = &tree.nil; C.parent = &D; \ + D.parent = &B; E.parent = &D; \ + A.right = A.left = C.right = C.left = &tree.nil; \ + E.right = E.left = &tree.nil; \ + B.right = &A; B.left = &D; D.right = &C; D.left = &E \ + +/* 1.b -> 2.b + * [B] + * / \ + * [A] (D) + * / \ + * [C] [E] + */ + + +START_TEST (test_remove_5) +{ + DEF_TEST_SETUP (); + B.color = A.color = C.color = E.color = ITREE_BLACK; + D.color = ITREE_RED; + interval_tree_remove_fix (&tree, &A); + + ck_assert (A.color == ITREE_BLACK); + ck_assert (B.color == ITREE_BLACK); + ck_assert (C.color == ITREE_RED); + ck_assert (D.color == ITREE_BLACK); + ck_assert (E.color == ITREE_BLACK); + ck_assert (A.parent == &B); + ck_assert (B.right == &A); + ck_assert (B.left == &C); + ck_assert (C.parent == &B); + ck_assert (E.parent == &D); + ck_assert (D.left == &E); + ck_assert (D.right == &B); + ck_assert (tree.root == &D); +} +END_TEST + +/* 2.b */ +START_TEST (test_remove_6) +{ + DEF_TEST_SETUP (); + B.color = D.color = A.color = C.color = E.color = ITREE_BLACK; + interval_tree_remove_fix (&tree, &A); + + ck_assert (A.color == ITREE_BLACK); + ck_assert (B.color == ITREE_BLACK); + ck_assert (C.color == ITREE_BLACK); + ck_assert (D.color == ITREE_RED); + ck_assert (E.color == ITREE_BLACK); + ck_assert (A.parent == &B); + ck_assert (B.right == &A); + ck_assert (B.left == &D); + ck_assert (C.parent == &D); + ck_assert (E.parent == &D); + ck_assert (tree.root == &B); +} +END_TEST + +/* 3.b -> 4.b*/ +START_TEST (test_remove_7) +{ + DEF_TEST_SETUP (); + D.color = A.color = E.color = ITREE_BLACK; + B.color = C.color = ITREE_RED; + interval_tree_remove_fix (&tree, &A); + + ck_assert (A.color == ITREE_BLACK); + ck_assert (B.color == ITREE_BLACK); + ck_assert (C.color == ITREE_BLACK); + ck_assert (D.color == ITREE_BLACK); + ck_assert (E.color == ITREE_BLACK); + ck_assert (A.parent == &B); + ck_assert (B.right == &A); + ck_assert (B.left == &tree.nil); + ck_assert (&C == tree.root); + ck_assert (C.right == &B); + ck_assert (C.left == &D); + ck_assert (E.parent == &D); + ck_assert (D.right == &tree.nil); + +} +END_TEST + +/* 4.b */ +START_TEST (test_remove_8) +{ + DEF_TEST_SETUP (); + B.color = C.color = E.color = ITREE_RED; + A.color = D.color = ITREE_BLACK; + interval_tree_remove_fix (&tree, &A); + + ck_assert (A.color == ITREE_BLACK); + ck_assert (B.color == ITREE_BLACK); + ck_assert (C.color == ITREE_RED); + ck_assert (D.color == ITREE_BLACK); + ck_assert (E.color == ITREE_BLACK); + ck_assert (A.parent == &B); + ck_assert (B.right == &A); + ck_assert (B.left == &C); + ck_assert (C.parent == &B); + ck_assert (E.parent == &D); + ck_assert (tree.root == &D); +} +END_TEST + + +#undef A +#undef B +#undef C +#undef D +#undef E +#undef DEF_TEST_SETUP + + +START_TEST (test_remove_9) +{ + struct interval_node *nodes = NULL; + struct interval_tree *tree = test_get_tree4 (&nodes); + + ck_assert (tree->root == &N_20); + ck_assert (N_20.left == &N_10); + ck_assert (N_20.right == &N_30); + ck_assert (N_30.right == &N_40); + ck_assert (N_20.color == ITREE_BLACK); + ck_assert (N_10.color == ITREE_BLACK); + ck_assert (N_30.color == ITREE_BLACK); + ck_assert (N_40.color == ITREE_RED); + + interval_tree_remove (tree, &N_10); + + ck_assert (tree->root == &N_30); + ck_assert (N_30.parent == &tree->nil); + ck_assert (N_30.left == &N_20); + ck_assert (N_30.right == &N_40); + ck_assert (N_20.color == ITREE_BLACK); + ck_assert (N_30.color == ITREE_BLACK); + ck_assert (N_40.color == ITREE_BLACK); +} +END_TEST + +#define N 3 + +START_TEST (test_remove_10) +{ + struct interval_tree tree; + struct interval_node nodes[N]; + int index[N]; + + srand (42); + interval_tree_init (&tree); + for (int i = 0; i < N; ++i) + { + nodes[i].begin = (i + 1) * 10; + nodes[i].end = nodes[i].begin + 1; + index[i] = i; + } + shuffle (index, N); + for (int i = 0; i < N; ++i) + interval_tree_insert (&tree, &nodes[index[i]]); + + shuffle (index, N); + for (int i = 0; i < N; ++i) + { + ck_assert (interval_tree_contains (&tree, &nodes[index[i]])); + interval_tree_remove (&tree, &nodes[index[i]]); + } + ck_assert (tree.root == &tree.nil); + ck_assert (tree.size == 0); +} +END_TEST + + +/* +===================================================================================+ + * | Generator + * +===================================================================================+ */ + +START_TEST (test_generator_1) +{ + struct interval_tree tree; + struct interval_node node, *n; + struct interval_generator *g; + interval_tree_init (&tree); + node.begin = 10; + node.end = 20; + interval_tree_insert (&tree, &node); + g = interval_generator_create (&tree); + interval_generator_reset (g, 0, 30, ITREE_ASCENDING); + n = interval_generator_next (g); + ck_assert (n == &node); + ck_assert (n->begin == 10 && n->end == 20); + ck_assert (interval_generator_next (g) == NULL); + ck_assert (interval_generator_next (g) == NULL); + ck_assert (interval_generator_next (g) == NULL); + interval_generator_destroy (g); + + g = interval_generator_create (&tree); + interval_generator_reset (g, 30, 50, ITREE_ASCENDING); + ck_assert (interval_generator_next (g) == NULL); + ck_assert (interval_generator_next (g) == NULL); + ck_assert (interval_generator_next (g) == NULL); + interval_generator_destroy (g); +} +END_TEST + +void +test_check_generator (struct interval_tree *tree, + ptrdiff_t begin, ptrdiff_t end, + int n, ...) +{ + va_list ap; + struct interval_generator *g = interval_generator_create (tree); + interval_generator_reset (g, begin, end, ITREE_ASCENDING); + + va_start (ap, n); + for (int i = 0; i < n; ++i) + { + ptrdiff_t begin = va_arg (ap, ptrdiff_t); + struct interval_node *node = interval_generator_next (g); + ck_assert (node); + ck_assert_int_eq (node->begin, begin); + } + va_end (ap); + ck_assert (! interval_generator_next (g)); + ck_assert (! interval_generator_next (g)); + interval_generator_destroy (g); +} + +#define DEF_TEST_SETUP() \ + + +START_TEST (test_generator_2) +{ + struct interval_tree tree; + struct interval_node nodes[3]; + + interval_tree_init (&tree); + + for (int i = 0; i < 3; ++i) { + nodes[i].begin = 10 * (i + 1); + nodes[i].end = 10 * (i + 2); + interval_tree_insert (&tree, &nodes[i]); + } + + test_check_generator (&tree, 0, 50, 3, + 10, 20, 30); + test_check_generator (&tree, 0, 10, 0); + test_check_generator (&tree, 40, 50, 0); + test_check_generator (&tree, 15, 35, 3, + 10, 20, 30); + test_check_generator (&tree, -100, -50, 0); + test_check_generator (&tree, -100, -50, 0); + test_check_generator (&tree, 100, 50, 0); + test_check_generator (&tree, 100, 150, 0); + test_check_generator (&tree, 0, 0, 0); + test_check_generator (&tree, 40, 40, 0); + test_check_generator (&tree, 30, 30, 0); + test_check_generator (&tree, 35, 35, 1, + 30); +} +END_TEST + + +struct interval_node* +test_create_tree (struct interval_tree *tree, int n, + bool doshuffle, ...) +{ + va_list ap; + struct interval_node *nodes = calloc (n, sizeof (struct interval_node)); + int *index = calloc (n, sizeof (int)); + + interval_tree_init (tree); + va_start (ap, doshuffle); + for (int i = 0; i < n; ++i) + { + ptrdiff_t begin = va_arg (ap, ptrdiff_t); + ptrdiff_t end = va_arg (ap, ptrdiff_t); + nodes[i].begin = begin; + nodes[i].end = end; + index[i] = i; + } + va_end (ap); + srand (42); + if (doshuffle) + shuffle (index, n); + for (int i = 0; i < n; ++i) + interval_tree_insert (tree, &nodes[index[i]]); + free (index); + + return nodes; +} + +START_TEST (test_generator_3) +{ + struct interval_tree tree; + struct interval_node *nodes = NULL; + + nodes = test_create_tree (&tree, 3, true, + 10, 10, + 10, 10, + 10, 10); + test_check_generator (&tree, 0, 10, 0); + test_check_generator (&tree, 10, 10, 3, 10, 10, 10); + test_check_generator (&tree, 10, 20, 3, 10, 10, 10); + free (nodes); +} +END_TEST + +#define FOREACH(n, g) \ + for ((n) = interval_generator_next (g); (n) != NULL; \ + (n) = interval_generator_next (g)) + +START_TEST (test_generator_5) +{ + struct interval_tree tree; + struct interval_node *nodes; + struct interval_generator *g; + nodes = test_create_tree (&tree, 4, false, + 10, 30, + 20, 40, + 30, 50, + 40, 60); + g = interval_generator_create (&tree); + interval_generator_reset (g, 0, 100, ITREE_PRE_ORDER); + for (int i = 0; i < 4; ++i) + { + struct interval_node *n = interval_generator_next (g); + ck_assert (n); + switch (i) + { + case 0: ck_assert_int_eq (20, n->begin); break; + case 1: ck_assert_int_eq (10, n->begin); break; + case 2: ck_assert_int_eq (30, n->begin); break; + case 3: ck_assert_int_eq (40, n->begin); break; + } + } + interval_generator_destroy (g); + free (nodes); + +} +END_TEST + +START_TEST (test_generator_6) +{ + struct interval_tree tree; + struct interval_node *nodes; + struct interval_generator *g; + nodes = test_create_tree (&tree, 4, true, + 10, 30, + 20, 40, + 30, 50, + 40, 60); + g = interval_generator_create (&tree); + interval_generator_reset (g, 0, 100, ITREE_ASCENDING); + for (int i = 0; i < 4; ++i) + { + struct interval_node *n = interval_generator_next (g); + ck_assert (n); + switch (i) + { + case 0: ck_assert_int_eq (10, n->begin); break; + case 1: ck_assert_int_eq (20, n->begin); break; + case 2: ck_assert_int_eq (30, n->begin); break; + case 3: ck_assert_int_eq (40, n->begin); break; + } + } + interval_generator_destroy (g); + free (nodes); + +} +END_TEST + +START_TEST (test_generator_7) +{ + struct interval_tree tree; + struct interval_node *nodes; + struct interval_generator *g; + nodes = test_create_tree (&tree, 4, true, + 10, 30, + 20, 40, + 30, 50, + 40, 60); + g = interval_generator_create (&tree); + interval_generator_reset (g, 0, 100, ITREE_DESCENDING); + for (int i = 0; i < 4; ++i) + { + struct interval_node *n = interval_generator_next (g); + ck_assert (n); + switch (i) + { + case 0: ck_assert_int_eq (40, n->begin); break; + case 1: ck_assert_int_eq (30, n->begin); break; + case 2: ck_assert_int_eq (20, n->begin); break; + case 3: ck_assert_int_eq (10, n->begin); break; + } + } + interval_generator_destroy (g); + free (nodes); + +} +END_TEST + +START_TEST (test_generator_8) +{ + struct interval_tree tree; + struct interval_node *nodes, *n; + struct interval_generator *g; + nodes = test_create_tree (&tree, 2, false, + 20, 30, + 40, 50); + g = interval_generator_create (&tree); + interval_generator_reset (g, 1, 60, ITREE_DESCENDING); + n = interval_generator_next (g); + ck_assert_int_eq (n->begin, 40); + interval_generator_narrow (g, 50, 60); + n = interval_generator_next (g); + ck_assert (n == NULL); + free (nodes); +} +END_TEST + + +START_TEST (test_generator_9) +{ + struct interval_tree tree; + struct interval_node *nodes, *n; + struct interval_generator *g; + nodes = test_create_tree (&tree, 2, false, + 25, 25, + 20, 30); + g = interval_generator_create (&tree); + interval_generator_reset (g, 1, 30, ITREE_DESCENDING); + n = interval_generator_next (g); + ck_assert_int_eq (n->begin, 25); + interval_generator_narrow (g, 25, 35); + n = interval_generator_next (g); + ck_assert_int_eq (n->begin, 20); + free (nodes); +} +END_TEST + + +/* +===================================================================================+ + * | Insert Gap + * +===================================================================================+ */ + +static struct interval_tree gap_tree; +static struct interval_node gap_node; + +#define N_BEG (interval_tree_validate (&gap_tree, &gap_node)->begin) +#define N_END (interval_tree_validate (&gap_tree, &gap_node)->end) + +static void +test_setup_gap_node (ptrdiff_t begin, ptrdiff_t end, + bool front_advance, bool rear_advance) +{ + interval_tree_init (&gap_tree); + gap_node.begin = begin; + gap_node.end = end; + gap_node.front_advance = front_advance; + gap_node.rear_advance = rear_advance; + interval_tree_insert (&gap_tree, &gap_node); +} + +static void +test_setup_gap_node_noadvance (ptrdiff_t begin, ptrdiff_t end) +{ + test_setup_gap_node (begin, end, false, false); +} + +START_TEST (test_gap_insert_1) +{ + test_setup_gap_node (100, 200, false, false); + interval_tree_insert_gap (&gap_tree, 100 + 10, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 200 + 20); +} +END_TEST + +START_TEST (test_gap_insert_2) +{ + test_setup_gap_node (100, 200, false, false); + interval_tree_insert_gap (&gap_tree, 300, 10); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 200); +} +END_TEST + +START_TEST (test_gap_insert_3) +{ + test_setup_gap_node (100, 200, false, false); + interval_tree_insert_gap (&gap_tree, 0, 15); + ck_assert_int_eq (N_BEG, 100 + 15); + ck_assert_int_eq (N_END, 200 + 15); +} +END_TEST + +START_TEST (test_gap_insert_4) +{ + test_setup_gap_node (100, 200, true, false); + interval_tree_insert_gap (&gap_tree, 100, 20); + ck_assert_int_eq (N_BEG, 100 + 20); + ck_assert_int_eq (N_END, 200 + 20); + +} +END_TEST + +START_TEST (test_gap_insert_5) +{ + test_setup_gap_node (100, 200, false, false); + interval_tree_insert_gap (&gap_tree, 100, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 200 + 20); + +} +END_TEST + +START_TEST (test_gap_insert_6) +{ + test_setup_gap_node (100, 200, false, true); + interval_tree_insert_gap (&gap_tree, 200, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 200 + 20); + +} +END_TEST + +START_TEST (test_gap_insert_7) +{ + test_setup_gap_node (100, 200, false, false); + interval_tree_insert_gap (&gap_tree, 200, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 200); + +} +END_TEST + +START_TEST (test_gap_insert_8) +{ + test_setup_gap_node (100, 100, true, true); + interval_tree_insert_gap (&gap_tree, 100, 20); + ck_assert_int_eq (N_BEG, 100 + 20); + ck_assert_int_eq (N_END, 100 + 20); + +} +END_TEST + +START_TEST (test_gap_insert_9) +{ + test_setup_gap_node (100, 100, false, true); + interval_tree_insert_gap (&gap_tree, 100, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 100 + 20); + +} +END_TEST + +START_TEST (test_gap_insert_10) +{ + test_setup_gap_node (100, 100, true, false); + interval_tree_insert_gap (&gap_tree, 100, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 100); + +} +END_TEST + +START_TEST (test_gap_insert_11) +{ + test_setup_gap_node (100, 100, false, false); + interval_tree_insert_gap (&gap_tree, 100, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 100); + +} +END_TEST + + +/* +===================================================================================+ + * | Delete Gap + * +===================================================================================+ */ + +START_TEST (test_gap_delete_1) +{ + test_setup_gap_node_noadvance (100, 200); + interval_tree_delete_gap (&gap_tree, 100 + 10, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 200 - 20); + +} +END_TEST + +START_TEST (test_gap_delete_2) +{ + test_setup_gap_node_noadvance (100, 200); + interval_tree_delete_gap (&gap_tree, 200 + 10, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 200); + +} +END_TEST + +START_TEST (test_gap_delete_3) +{ + test_setup_gap_node_noadvance (100, 200); + interval_tree_delete_gap (&gap_tree, 200, 20); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 200); + +} +END_TEST + +START_TEST (test_gap_delete_4) +{ + test_setup_gap_node_noadvance (100, 200); + interval_tree_delete_gap (&gap_tree, 100 - 20, 20); + ck_assert_int_eq (N_BEG, 100 - 20); + ck_assert_int_eq (N_END, 200 - 20); + +} +END_TEST + +START_TEST (test_gap_delete_5) +{ + test_setup_gap_node_noadvance (100, 200); + interval_tree_delete_gap (&gap_tree, 70, 20); + ck_assert_int_eq (N_BEG, 100 - 20); + ck_assert_int_eq (N_END, 200 - 20); + +} +END_TEST + +START_TEST (test_gap_delete_6) +{ + test_setup_gap_node_noadvance (100, 200); + interval_tree_delete_gap (&gap_tree, 80, 100); + ck_assert_int_eq (N_BEG, 80); + ck_assert_int_eq (N_END, 100); +} +END_TEST + +START_TEST (test_gap_delete_7) +{ + test_setup_gap_node_noadvance (100, 200); + interval_tree_delete_gap (&gap_tree, 120, 100); + ck_assert_int_eq (N_BEG, 100); + ck_assert_int_eq (N_END, 120); +} +END_TEST + +START_TEST (test_gap_delete_8) +{ + test_setup_gap_node_noadvance (100, 200); + interval_tree_delete_gap (&gap_tree, 100 - 20, 200 + 20); + ck_assert_int_eq (N_BEG, 100 - 20); + ck_assert_int_eq (N_END, 100 - 20); + +} +END_TEST + + + +Suite * basic_suite () +{ + Suite *s = suite_create ("basic_suite"); + TCase *tc = tcase_create ("basic_test"); + + tcase_add_test (tc, test_insert_1); + tcase_add_test (tc, test_insert_2); + tcase_add_test (tc, test_insert_3); + tcase_add_test (tc, test_insert_4); + tcase_add_test (tc, test_insert_5); + tcase_add_test (tc, test_insert_6); + tcase_add_test (tc, test_insert_7); + tcase_add_test (tc, test_insert_8); + tcase_add_test (tc, test_insert_9); + tcase_add_test (tc, test_insert_10); + tcase_add_test (tc, test_insert_11); + tcase_add_test (tc, test_insert_12); + tcase_add_test (tc, test_insert_13); + + tcase_add_test (tc, test_remove_1); + tcase_add_test (tc, test_remove_2); + tcase_add_test (tc, test_remove_3); + tcase_add_test (tc, test_remove_4); + tcase_add_test (tc, test_remove_5); + tcase_add_test (tc, test_remove_6); + tcase_add_test (tc, test_remove_7); + tcase_add_test (tc, test_remove_8); + tcase_add_test (tc, test_remove_9); + tcase_add_test (tc, test_remove_10); + + tcase_add_test (tc, test_generator_1); + tcase_add_test (tc, test_generator_2); + tcase_add_test (tc, test_generator_3); + tcase_add_test (tc, test_generator_5); + tcase_add_test (tc, test_generator_6); + tcase_add_test (tc, test_generator_7); + tcase_add_test (tc, test_generator_8); + tcase_add_test (tc, test_generator_9); + + tcase_add_test (tc, test_gap_insert_1); + tcase_add_test (tc, test_gap_insert_2); + tcase_add_test (tc, test_gap_insert_3); + tcase_add_test (tc, test_gap_insert_4); + tcase_add_test (tc, test_gap_insert_5); + tcase_add_test (tc, test_gap_insert_6); + tcase_add_test (tc, test_gap_insert_7); + tcase_add_test (tc, test_gap_insert_8); + tcase_add_test (tc, test_gap_insert_9); + tcase_add_test (tc, test_gap_insert_10); + tcase_add_test (tc, test_gap_insert_11); + + tcase_add_test (tc, test_gap_delete_1); + tcase_add_test (tc, test_gap_delete_2); + tcase_add_test (tc, test_gap_delete_3); + tcase_add_test (tc, test_gap_delete_4); + tcase_add_test (tc, test_gap_delete_5); + tcase_add_test (tc, test_gap_delete_6); + tcase_add_test (tc, test_gap_delete_7); + tcase_add_test (tc, test_gap_delete_8); + + /* tcase_set_timeout (tc, 120); */ + suite_add_tcase (s, tc); + return s; +} + +int +main (void) +{ + int nfailed; + Suite *s = basic_suite (); + SRunner *sr = srunner_create (s); + + srunner_run_all (sr, CK_NORMAL); + nfailed = srunner_ntests_failed (sr); + srunner_free (sr); + return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/test/manual/noverlay/many-errors.py b/test/manual/noverlay/many-errors.py new file mode 100644 index 00000000000..fa4ef5f98d1 --- /dev/null +++ b/test/manual/noverlay/many-errors.py @@ -0,0 +1,2480 @@ +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass +def a(x, y, y): + return t; pass diff --git a/test/manual/noverlay/overlay-perf.el b/test/manual/noverlay/overlay-perf.el new file mode 100644 index 00000000000..e84941c08f9 --- /dev/null +++ b/test/manual/noverlay/overlay-perf.el @@ -0,0 +1,764 @@ +;; -*- lexical-binding:t -*- +(require 'cl-lib) +(require 'subr-x) +(require 'seq) +(require 'hi-lock) + + +;; +===================================================================================+ +;; | Framework +;; +===================================================================================+ + +(defmacro perf-define-constant-test (name &optional doc &rest body) + (declare (indent 1) (debug (symbol &optional string &rest form))) + `(progn + (put ',name 'perf-constant-test t) + (defun ,name nil ,doc ,@body))) + +(defmacro perf-define-variable-test (name args &optional doc &rest body) + (declare (indent 2) (debug defun)) + (unless (and (consp args) + (= (length args) 1)) + (error "Function %s should accept exactly one argument." name)) + `(progn + (put ',name 'perf-variable-test t) + (defun ,name ,args ,doc ,@body))) + +(defmacro perf-define-test-suite (name &rest tests) + (declare (indent 1)) + `(put ',name 'perf-test-suite + ,(cons 'list tests))) + +(defun perf-constant-test-p (test) + (get test 'perf-constant-test)) + +(defun perf-variable-test-p (test) + (get test 'perf-variable-test)) + +(defun perf-test-suite-p (suite) + (not (null (perf-test-suite-elements suite)))) + +(defun perf-test-suite-elements (suite) + (get suite 'perf-test-suite)) + +(defun perf-expand-suites (test-and-suites) + (apply #' append (mapcar (lambda (elt) + (if (perf-test-suite-p elt) + (perf-test-suite-elements elt) + (list elt))) + test-and-suites))) +(defun perf-test-p (symbol) + (or (perf-variable-test-p symbol) + (perf-constant-test-p symbol))) + +(defun perf-all-tests () + (let (result) + (mapatoms (lambda (symbol) + (when (and (fboundp symbol) + (perf-test-p symbol)) + (push symbol result)))) + (sort result #'string-lessp))) + +(defvar perf-default-test-argument 4096) + +(defun perf-run-1 (&optional k n &rest tests) + "Run TESTS K times using N as argument for non-constant ones. + +Return test-total elapsed time." + (random "") + (when (and n (not (numberp n))) + (push k tests) + (push n tests) + (setq n nil k nil)) + (when (and k (not (numberp k))) + (push k tests) + (setq k nil)) + (let* ((k (or k 1)) + (n (or n perf-default-test-argument)) + (tests (perf-expand-suites (or tests + (perf-all-tests)))) + (variable-tests (seq-filter #'perf-variable-test-p tests)) + (constant-tests (seq-filter #'perf-constant-test-p tests)) + (max-test-string-width (perf-max-symbol-length tests))) + (unless (seq-every-p #'perf-test-p tests) + (error "Some of these are not tests: %s" tests)) + (cl-labels ((format-result (result) + (cond + ((numberp result) (format "%.2f" result)) + ((stringp result) result) + ((null result) "N/A"))) + (format-test (fn) + (concat (symbol-name fn) + (make-string + (+ (- max-test-string-width + (length (symbol-name fn))) + 1) + ?\s))) + (format-summary (results _total) + (let ((min (apply #'min results)) + (max (apply #'max results)) + (avg (/ (apply #'+ results) (float (length results))))) + (format "n=%d min=%.2f avg=%.2f max=%.2f" (length results) min avg max))) + (run-test (fn) + (let ((total 0) results) + (dotimes (_ (max 0 k)) + (garbage-collect) + (princ (concat " " (format-test fn))) + (let ((result (condition-case-unless-debug err + (cond + ((perf-variable-test-p fn) + (random "") (car (funcall fn n))) + ((perf-constant-test-p fn) + (random "") (car (funcall fn))) + (t "skip")) + (error (error-message-string err))))) + (when (numberp result) + (cl-incf total result) + (push result results)) + (princ (format-result result)) + (terpri))) + (when (> (length results) 1) + (princ (concat "#" (format-test fn) + (format-summary results total))) + (terpri))))) + (when variable-tests + (terpri) + (dolist (fn variable-tests) + (run-test fn) + (terpri))) + (when constant-tests + (dolist (fn constant-tests) + (run-test fn) + (terpri)))))) + +(defun perf-run (&optional k n &rest tests) + (interactive + (let* ((n (if current-prefix-arg + (prefix-numeric-value current-prefix-arg) + perf-default-test-argument)) + (tests (mapcar #'intern + (completing-read-multiple + (format "Run tests (n=%d): " n) + (perf-all-tests) nil t nil 'perf-test-history)))) + (cons 1 (cons n tests)))) + (with-current-buffer (get-buffer-create "*perf-results*") + (let ((inhibit-read-only t) + (standard-output (current-buffer))) + (erase-buffer) + (apply #'perf-run-1 k n tests) + (display-buffer (current-buffer))))) + + +(defun perf-batch-parse-command-line (args) + (let ((k 1) + (n perf-default-test-argument) + tests) + (while args + (cond ((string-match-p "\\`-[cn]\\'" (car args)) + (unless (and (cdr args) + (string-match-p "\\`[0-9]+\\'" (cadr args))) + (error "%s expectes a natnum argument" (car args))) + (if (equal (car args) "-c") + (setq k (string-to-number (cadr args))) + (setq n (string-to-number (cadr args)))) + (setq args (cddr args))) + (t (push (intern (pop args)) tests)))) + (list k n tests))) + + +(defun perf-run-batch () + "Runs tests from `command-line-args-left' and kill emacs." + (let ((standard-output #'external-debugging-output)) + (condition-case err + (cl-destructuring-bind (k n tests) + (perf-batch-parse-command-line command-line-args-left) + (apply #'perf-run-1 k n tests) + (save-buffers-kill-emacs)) + (error + (princ (error-message-string err)) + (save-buffers-kill-emacs))))) + +(defconst perf-number-of-columns 70) + +(defun perf-insert-lines (n) + "Insert N lines into the current buffer." + (dotimes (i n) + (insert (make-string 70 (if (= (% i 2) 0) + ?. + ?O)) + ?\n))) + +(defun perf-switch-to-buffer-scroll-random (n &optional buffer) + (interactive) + (set-window-buffer nil (or buffer (current-buffer))) + (goto-char (point-min)) + (redisplay t) + (dotimes (_ n) + (goto-char (random (point-max))) + (recenter) + (redisplay t))) + +(defun perf-insert-overlays (n &optional create-callback random-p) + (if random-p + (perf-insert-overlays-random n create-callback) + (perf-insert-overlays-sequential n create-callback))) + +(defun perf-insert-overlays-sequential (n &optional create-callback) + "Insert an overlay every Nth line." + (declare (indent 1)) + (let ((i 0) + (create-callback (or create-callback #'ignore))) + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (when (= 0 (% i n)) + (let ((ov (make-overlay (point-at-bol) (point-at-eol)))) + (funcall create-callback ov) + (overlay-put ov 'priority (random (buffer-size))))) + (cl-incf i) + (forward-line))))) + +(defun perf-insert-overlays-random (n &optional create-callback) + "Insert an overlay every Nth line." + (declare (indent 1)) + (let ((create-callback (or create-callback #'ignore))) + (save-excursion + (while (>= (cl-decf n) 0) + (let* ((beg (1+ (random (point-max)))) + (ov (make-overlay beg (+ beg (random 70))))) + (funcall create-callback ov) + (overlay-put ov 'priority (random (buffer-size)))))))) + +(defun perf-insert-overlays-hierarchical (n &optional create-callback) + (let ((create-callback (or create-callback #'ignore))) + (save-excursion + (goto-char (point-min)) + (let ((spacing (floor (/ (/ (count-lines (point-min) (point-max)) + (float 3)) + n)))) + (when (< spacing 1) + (error "Hierarchical overlay overflow !!")) + (dotimes (i n) + (funcall create-callback + (make-overlay (point) + (save-excursion + (goto-char (point-max)) + (forward-line (- (* spacing i))) + (point)))) + + (when (eobp) + (error "End of buffer in hierarchical overlays")) + (forward-line spacing)))))) + +(defun perf-overlay-ascii-chart (&optional buffer width) + (interactive) + (save-current-buffer + (when buffer (set-buffer buffer)) + (unless width (setq width 100)) + (let* ((ovl (sort (overlays-in (point-min) (point-max)) + (lambda (ov1 ov2) + (or (<= (overlay-start ov1) + (overlay-start ov2)) + (and + (= (overlay-start ov1) + (overlay-start ov2)) + (< (overlay-end ov1) + (overlay-end ov2))))))) + (ov-width (apply #'max (mapcar (lambda (ov) + (- (overlay-end ov) + (overlay-start ov))) + ovl))) + (ov-min (apply #'min (mapcar #'overlay-start ovl))) + (ov-max (apply #'max (mapcar #'overlay-end ovl))) + (scale (/ (float width) (+ ov-min ov-width)))) + (with-current-buffer (get-buffer-create "*overlay-ascii-chart*") + (let ((inhibit-read-only t)) + (erase-buffer) + (buffer-disable-undo) + (insert (format "%06d%s%06d\n" ov-min (make-string (- width 12) ?\s) ov-max)) + (dolist (ov ovl) + (let ((length (round (* scale (- (overlay-end ov) + (overlay-start ov)))))) + (insert (make-string (round (* scale (overlay-start ov))) ?\s)) + (cl-case length + (0 (insert "O")) + (1 (insert "|")) + (t (insert (format "|%s|" (make-string (- length 2) ?-))))) + (insert "\n"))) + (goto-char (point-min))) + (read-only-mode 1) + (pop-to-buffer (current-buffer)))))) + +(defconst perf-overlay-faces (mapcar #'intern (seq-take hi-lock-face-defaults 3))) + +(defun perf-overlay-face-callback (ov) + (overlay-put ov 'face (nth (random (length perf-overlay-faces)) + perf-overlay-faces))) + +(defun perf-overlay-invisible-callback (ov) + (overlay-put ov 'invisble (= 1 (random 2)))) + +(defun perf-overlay-display-callback (ov) + (overlay-put ov 'display (make-string 70 ?*))) + +(defmacro perf-define-display-test (overlay-type property-type scroll-type) + (let ((name (intern (format "perf-display-%s/%s/%s" + overlay-type property-type scroll-type))) + (arg (make-symbol "n"))) + + `(perf-define-variable-test ,name (,arg) + (with-temp-buffer + (perf-insert-lines ,arg) + (overlay-recenter (point-max)) + ,@(perf-define-display-test-1 arg overlay-type property-type scroll-type))))) + +(defun perf-define-display-test-1 (arg overlay-type property-type scroll-type) + (list (append (cl-case overlay-type + (sequential + (list 'perf-insert-overlays-sequential 2)) + (hierarchical + `(perf-insert-overlays-hierarchical (/ ,arg 10))) + (random + `(perf-insert-overlays-random (/ ,arg 2))) + (t (error "Invalid insert type: %s" overlay-type))) + (list + (cl-case property-type + (display '#'perf-overlay-display-callback) + (face '#'perf-overlay-face-callback) + (invisible '#'perf-overlay-invisible-callback) + (t (error "Invalid overlay type: %s" overlay-type))))) + (list 'benchmark-run 1 + (cl-case scroll-type + (scroll '(perf-switch-to-buffer-scroll-up-and-down)) + (random `(perf-switch-to-buffer-scroll-random (/ ,arg 50))) + (t (error "Invalid scroll type: %s" overlay-type)))))) + +(defun perf-max-symbol-length (symbols) + "Return the longest symbol in SYMBOLS, or -1 if symbols is nil." + (if (null symbols) + -1 + (apply #'max (mapcar + (lambda (elt) + (length (symbol-name elt))) + symbols)))) + +(defun perf-insert-text (n) + "Insert N character into the current buffer." + (let ((ncols 68) + (char ?.)) + (dotimes (_ (/ n ncols)) + (insert (make-string (1- ncols) char) ?\n)) + (when (> (% n ncols) 0) + (insert (make-string (1- (% n ncols)) char) ?\n)))) + +(defconst perf-insert-overlays-default-length 24) + +(defun perf-insert-overlays-scattered (n &optional length) + "Insert N overlays of max length 24 randomly." + (dotimes (_ n) + (let ((begin (random (1+ (point-max))))) + (make-overlay + begin (+ begin (random (1+ (or length perf-insert-overlays-default-length 0)))))))) + +(defvar perf-marker-gc-protection nil) + +(defun perf-insert-marker-scattered (n) + "Insert N marker randomly." + (setq perf-marker-gc-protection nil) + (dotimes (_ n) + (push (copy-marker (random (1+ (point-max)))) + perf-marker-gc-protection))) + +(defun perf-switch-to-buffer-scroll-up-and-down (&optional buffer) + (interactive) + (set-window-buffer nil (or buffer (current-buffer))) + (goto-char (point-min)) + (redisplay t) + (while (condition-case nil + (progn (scroll-up) t) + (end-of-buffer nil)) + (redisplay t)) + (while (condition-case nil + (progn (scroll-down) t) + (beginning-of-buffer nil)) + (redisplay t))) + +(defun perf-emacs-lisp-setup () + (add-to-list 'imenu-generic-expression + '(nil "^\\s-*(perf-define\\(?:\\w\\|\\s_\\)*\\s-*\\(\\(?:\\w\\|\\s_\\)+\\)" 1))) + +(add-hook 'emacs-lisp-mode 'perf-emacs-lisp-setup) + + +;; +===================================================================================+ +;; | Basic performance tests +;; +===================================================================================+ + +(perf-define-variable-test perf-make-overlay (n) + (with-temp-buffer + (overlay-recenter (point-min)) + (benchmark-run 1 + (dotimes (_ n) + (make-overlay 1 1))))) + +(perf-define-variable-test perf-make-overlay-continuous (n) + (with-temp-buffer + (perf-insert-text n) + (overlay-recenter (point-max)) + (benchmark-run 1 + (dotimes (i n) + (make-overlay i (1+ i)))))) + +(perf-define-variable-test perf-make-overlay-scatter (n) + (with-temp-buffer + (perf-insert-text n) + (benchmark-run 1 + (perf-insert-overlays-scattered n)))) + +(perf-define-variable-test perf-delete-overlay (n) + (with-temp-buffer + (let ((ovls (cl-loop for i from 1 to n + collect (make-overlay 1 1)))) + (overlay-recenter (point-min)) + (benchmark-run 1 + (mapc #'delete-overlay ovls))))) + +(perf-define-variable-test perf-delete-overlay-continuous (n) + (with-temp-buffer + (perf-insert-text n) + (let ((ovls (cl-loop for i from 1 to n + collect (make-overlay i (1+ i))))) + (overlay-recenter (point-min)) + (benchmark-run 1 + (mapc #'delete-overlay ovls))))) + +(perf-define-variable-test perf-delete-overlay-scatter (n) + (with-temp-buffer + (perf-insert-text n) + (let ((ovls (progn (perf-insert-overlays-scattered n) + (overlays-in (point-min) (point-max))))) + (benchmark-run 1 + (mapc #'delete-overlay ovls))))) + +(perf-define-variable-test perf-overlays-at (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-overlays-scattered n) + (benchmark-run 1 + (dotimes (i (point-max)) + (overlays-at i))))) + +(perf-define-variable-test perf-overlays-in (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-overlays-scattered n) + (let ((len perf-insert-overlays-default-length)) + (benchmark-run 1 + (dotimes (i (- (point-max) len)) + (overlays-in i (+ i len))))))) + +(perf-define-variable-test perf-insert-before (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-overlays-scattered n) + (goto-char 1) + (overlay-recenter (point-min)) + (benchmark-run 1 + (dotimes (_ (/ n 2)) + (insert ?X))))) + +(perf-define-variable-test perf-insert-before-empty (n) + (let ((perf-insert-overlays-default-length 0)) + (perf-insert-before n))) +(perf-define-variable-test perf-insert-after-empty (n) + (let ((perf-insert-overlays-default-length 0)) + (perf-insert-after n))) +(perf-define-variable-test perf-insert-scatter-empty (n) + (let ((perf-insert-overlays-default-length 0)) + (perf-insert-scatter n))) +(perf-define-variable-test perf-delete-before-empty (n) + (let ((perf-insert-overlays-default-length 0)) + (perf-delete-before n))) +(perf-define-variable-test perf-delete-after-empty (n) + (let ((perf-insert-overlays-default-length 0)) + (perf-delete-after n))) +(perf-define-variable-test perf-delete-scatter-empty (n) + (let ((perf-insert-overlays-default-length 0)) + (perf-delete-scatter n))) + +(defmacro perf-define-marker-test (type where) + (let ((name (intern (format "perf-%s-%s-marker" type where)))) + `(perf-define-variable-test ,name (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-marker-scattered n) + (goto-char ,(cl-case where + (after (list 'point-max)) + (t (list 'point-min)))) + (benchmark-run 1 + (dotimes (_ (/ n 2)) + ,@(when (eq where 'scatter) + (list '(goto-char (max 1 (random (point-max)))))) + ,(cl-case type + (insert (list 'insert ?X)) + (delete (list 'delete-char (if (eq where 'after) -1 1)))))))))) + +(perf-define-test-suite perf-marker-suite + (perf-define-marker-test insert before) + (perf-define-marker-test insert after) + (perf-define-marker-test insert scatter) + (perf-define-marker-test delete before) + (perf-define-marker-test delete after) + (perf-define-marker-test delete scatter)) + +(perf-define-variable-test perf-insert-after (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-overlays-scattered n) + (goto-char (point-max)) + (overlay-recenter (point-max)) + (benchmark-run 1 + (dotimes (_ (/ n 2)) + (insert ?X))))) + +(perf-define-variable-test perf-insert-scatter (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-overlays-scattered n) + (goto-char (point-max)) + (benchmark-run 1 + (dotimes (_ (/ n 2)) + (goto-char (1+ (random (point-max)))) + (insert ?X))))) + +(perf-define-variable-test perf-delete-before (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-overlays-scattered n) + (goto-char 1) + (overlay-recenter (point-min)) + (benchmark-run 1 + (dotimes (_ (/ n 2)) + (delete-char 1))))) + +(perf-define-variable-test perf-delete-after (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-overlays-scattered n) + (goto-char (point-max)) + (overlay-recenter (point-max)) + (benchmark-run 1 + (dotimes (_ (/ n 2)) + (delete-char -1))))) + +(perf-define-variable-test perf-delete-scatter (n) + (with-temp-buffer + (perf-insert-text n) + (perf-insert-overlays-scattered n) + (goto-char (point-max)) + (benchmark-run 1 + (dotimes (_ (/ n 2)) + (goto-char (max 1 (random (point-max)))) + (delete-char 1))))) + +(perf-define-test-suite perf-insert-delete-suite + 'perf-insert-before + 'perf-insert-after + 'perf-insert-scatter + 'perf-delete-before + 'perf-delete-after + 'perf-delete-scatter + ) + + +;; +===================================================================================+ +;; | Redisplay (new) +;; +===================================================================================+ + +;; 5000 +;; 25000 +;; 75000 + +;; Number of Overlays = N / 2 +;; +;; (except for the hierarchical case, where it is divided by 10.) + + ;; . scrolling through a buffer with lots of overlays that affect faces + ;; of characters in the buffer text + ;; . scrolling through a buffer with lots of overlays that define + ;; 'display' properties which are strings + ;; . scrolling through a buffer with lots of overlays that define + ;; 'invisible' properties + +(perf-define-test-suite perf-display-suite + (perf-define-display-test sequential display scroll) + (perf-define-display-test sequential display random) + (perf-define-display-test sequential face scroll) + (perf-define-display-test sequential face random) + (perf-define-display-test sequential invisible scroll) + (perf-define-display-test sequential invisible random) + (perf-define-display-test random display scroll) + (perf-define-display-test random display random) + (perf-define-display-test random face scroll) + (perf-define-display-test random face random) + (perf-define-display-test random invisible scroll) + (perf-define-display-test random invisible random)) + +;; |------------| +;; |--------| +;; |----| +(perf-define-display-test hierarchical face scroll) + + + + +;; +===================================================================================+ +;; | Real World +;; +===================================================================================+ + +(require 'python) + +(defconst perf-many-errors-file + (expand-file-name "many-errors.py" + (and load-file-name (file-name-directory load-file-name)))) + +(perf-define-constant-test perf-realworld-flycheck + (interactive) + (package-initialize) + (when (and (require 'flycheck nil t) + (file-exists-p perf-many-errors-file) + (or (executable-find "pylint") + (executable-find "flake8"))) + (setq flycheck-python-pylint-executable + (executable-find "pylint")) + (setq flycheck-python-flake8-executable + (executable-find "flake8")) + (setq python-indent-guess-indent-offset-verbose nil) + (setq flycheck-check-syntax-automatically nil) + (setq flycheck-checker-error-threshold nil) + (setq flycheck-display-errors-function nil) + (with-current-buffer (find-file-noselect perf-many-errors-file) + (let* ((done) + (flycheck-after-syntax-check-hook + (list (lambda () (setq done t))))) + (flycheck-mode 1) + (flycheck-buffer) + (benchmark-run 1 + (while (not done) + (accept-process-output)) + (perf-switch-to-buffer-scroll-up-and-down) + (flycheck-mode -1)))))) + +;; https://lists.gnu.org/archive/html/emacs-devel/2009-04/msg00242.html +(defun make-lines-invisible (regexp &optional arg) + "Make all lines matching a regexp invisible and intangible. +With a prefix arg, make it visible again. It is not necessary +that REGEXP matches the whole line; if a hit is found, the +affected line gets automatically selected. + +This command affects the whole buffer." + (interactive "MRegexp: \nP") + (let (ov + ovs + count) + (cond + ((equal arg '(4)) + (setq ovs (overlays-in (point-min) (point-max))) + (mapc (lambda (o) + (if (overlay-get o 'make-lines-invisible) + (delete-overlay o))) + ovs)) + (t + (save-excursion + (goto-char (point-min)) + (setq count 0) + (while (re-search-forward regexp nil t) + (setq count (1+ count)) + (if (= (% count 100) 0) + (message "%d" count)) + (setq ov (make-overlay (line-beginning-position) + (1+ (line-end-position)))) + (overlay-put ov 'make-lines-invisible t) + (overlay-put ov 'invisible t) + (overlay-put ov 'intangible t) + (goto-char (line-end-position)))))))) + +(perf-define-constant-test perf-realworld-make-lines-invisible + (with-temp-buffer + (insert-file-contents "/usr/share/dict/words") + (set-window-buffer nil (current-buffer)) + (redisplay t) + (overlay-recenter (point-max)) + (benchmark-run 1 + (make-lines-invisible "a")))) + +(perf-define-constant-test perf-realworld-line-numbering + (interactive) + (with-temp-buffer + (insert-file-contents "/usr/share/dict/words") + (overlay-recenter (point-max)) + (goto-char (point-min)) + (let* ((nlines (count-lines (point-min) (point-max))) + (line 1) + (width 0)) + (dotimes (i nlines) ;;-with-progress-reporter "Creating overlays" + (let ((ov (make-overlay (point) (point))) + (str (propertize (format "%04d" line) 'face 'shadow))) + (overlay-put ov 'before-string + (propertize " " 'display `((margin left-margin) ,str))) + (setq width (max width (length str))) + (cl-incf line) + (forward-line))) + (benchmark-run 1 + (let ((left-margin-width width)) + (perf-switch-to-buffer-scroll-up-and-down)))))) + +(perf-define-test-suite perf-realworld-suite + 'perf-realworld-flycheck + 'perf-realworld-make-lines-invisible + 'perf-realworld-line-numbering) + + +;; +===================================================================================+ +;; | next-overlay-change +;; +===================================================================================+ + +(perf-define-variable-test perf-noc-hierarchical/forward/linear (n) + "Search linear for the next change on every line." + (with-temp-buffer + (perf-insert-lines (* 3 n)) + (perf-insert-overlays-hierarchical n) + (goto-char (point-min)) + (benchmark-run 1 + (while (not (eobp)) + (next-overlay-change (point)) + (forward-line))))) + +(perf-define-variable-test perf-noc-sequential/forward/linear (n) + "Search linear for the next change on every line." + (with-temp-buffer + (perf-insert-lines (* 3 n)) + (perf-insert-overlays-sequential n) + (goto-char (point-min)) + (benchmark-run 1 + (while (not (eobp)) + (next-overlay-change (point)) + (forward-line))))) + +(perf-define-variable-test perf-noc-hierarchical/forward/backnforth (n) + "Search back and forth for the next change from `point-min' to `point-max'." + (with-temp-buffer + (perf-insert-lines (* 3 n)) + (overlay-recenter (point-max)) + (perf-insert-overlays-hierarchical n) + (goto-char (point-min)) + (benchmark-run 1 + (while (not (eobp)) + (next-overlay-change (point)) + (next-overlay-change (+ (point) 2)) + (forward-char))))) + +(perf-define-test-suite perf-noc-suite + 'perf-noc-hierarchical/forward/linear + 'perf-noc-hierarchical/forward/backnforth + 'perf-noc-hierarchical/forward/backnforth) diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index 834acaf66f5..71f8705c6fd 100644 --- a/test/src/buffer-tests.el +++ b/test/src/buffer-tests.el @@ -20,6 +20,7 @@ ;;; Code: (require 'ert) +(require 'seq) (ert-deftest overlay-modification-hooks-message-other-buf () "Test for bug#21824. @@ -50,4 +51,7522 @@ with parameters from the *Messages* buffer modification." (progn (get-buffer-create "nil") (generate-new-buffer-name "nil"))))) + +;; +===================================================================================+ +;; | Overlay test setup +;; +===================================================================================+ + +(eval-when-compile + (defun make-overlay-test-name (fn x y) + (intern (format "test-%s-%s-%s" fn x y)))) + +(defun unmake-ov-test-name (symbol) + (let ((name (if (stringp symbol) symbol (symbol-name symbol)))) + (when (string-match "\\`test-\\(.*\\)-\\(.*\\)-\\(.*\\)\\'" name) + (list (match-string 1 name) (match-string 2 name) (match-string 3 name))))) + +(defmacro deftest-make-overlay-1 (id args) + (declare (indent 1)) + `(ert-deftest ,(make-overlay-test-name 'make-overlay 1 id) () + (with-temp-buffer + (should ,(cons 'make-overlay args))))) + +(defmacro deftest-make-overlay-2 (id args condition) + (declare (indent 1)) + `(ert-deftest ,(make-overlay-test-name 'make-overlay 2 id) () + (with-temp-buffer + (should-error + ,(cons 'make-overlay args) + :type ',condition + :exclude-subtypes t)))) + +(defmacro deftest-overlay-start/end-1 (id start-end-args start-end-should) + (declare (indent 1)) + (cl-destructuring-bind (start end sstart send) + (append start-end-args start-end-should) + `(ert-deftest ,(make-overlay-test-name 'overlay-start/end 1 id) () + (with-temp-buffer + (insert (make-string 9 ?\n)) + (let ((ov (make-overlay ,start ,end))) + (should (equal ,sstart (overlay-start ov))) + (should (equal ,send (overlay-end ov)))))))) + +(defmacro deftest-overlay-buffer-1 (id arg-expr should-expr) + (declare (indent 1)) + `(ert-deftest ,(make-overlay-test-name 'overlay-buffer 1 id) () + (with-temp-buffer + (should (equal (overlay-buffer (make-overlay 1 1 ,arg-expr)) + ,should-expr))))) + +(defmacro deftest-overlayp-1 (id arg-expr should-expr) + (declare (indent 1)) + `(ert-deftest ,(make-overlay-test-name 'overlay-buffer 1 id) () + (with-temp-buffer + (should (equal ,should-expr (overlayp ,arg-expr)))))) + +(defmacro deftest-next-overlay-change-1 (id pos result &rest ov-tuple) + `(ert-deftest ,(make-overlay-test-name 'next-overlay-change 1 id) () + (let ((tuple (copy-sequence ',ov-tuple))) + (with-temp-buffer + (insert (make-string (max 100 (if tuple + (apply #'max + (mapcar + (lambda (m) (apply #'max m)) tuple)) + 0)) + ?\n)) + (dolist (tup tuple) + (make-overlay (car tup) (cadr tup))) + (should (equal (next-overlay-change ,pos) + ,result)))))) + +(defmacro deftest-previous-overlay-change-1 (id pos result &rest ov-tuple) + `(ert-deftest ,(make-overlay-test-name 'previous-overlay-change 1 id) () + (let ((tuple ',ov-tuple)) + (with-temp-buffer + (insert (make-string (max 100 (if tuple + (apply #'max + (mapcar + (lambda (m) (apply #'max m)) tuple)) + 0)) + ?\n)) + (dolist (tup tuple) + (make-overlay (car tup) (cadr tup))) + (should (equal (previous-overlay-change ,pos) + ,result)))))) + +(defmacro deftest-overlays-at-1 (id pos result &rest ov-triple) + `(ert-deftest ,(make-overlay-test-name 'overlays-at 1 id) () + (let ((pos* ,pos)) + (with-temp-buffer + (insert (make-string 100 ?\s)) + (should-not (memq nil ',result)) + (dolist (v ',ov-triple) + (cl-destructuring-bind (tag start end) + v + (overlay-put (make-overlay start end) 'tag tag))) + (let ((ovl (overlays-at pos*))) + (should (equal (length ovl) (length ',result))) + (dolist (ov ovl) + (should (memq (overlay-get ov 'tag) ',result)))))))) + +(defmacro deftest-overlays-in-1 (id beg end result &rest ov-triple) + `(ert-deftest ,(make-overlay-test-name 'overlays-in 1 id) () + (let ((beg* ,beg) + (end* ,end)) + (with-temp-buffer + (insert (make-string 100 ?\s)) + (should-not (memq nil ',result)) + (dolist (v ',ov-triple) + (cl-destructuring-bind (tag start end) + v + (overlay-put (make-overlay start end) 'tag tag))) + (let ((ovl (overlays-in beg* end*))) + (should (equal (length ovl) (length ',result))) + (dolist (ov ovl) + (should (memq (overlay-get ov 'tag) ',result)))))))) + +(defmacro test-with-overlay-in-buffer (symbol-beg-end-fa-ra &rest body) + (declare (indent 1)) + (cl-destructuring-bind (symbol beg end &optional fa ra) + symbol-beg-end-fa-ra + `(with-temp-buffer + (insert (make-string (max 1000 (1- ,end)) ?\s)) + (goto-char 1) + (let ((,symbol (make-overlay ,beg ,end nil ,fa ,ra))) + ,@body)))) + +(defmacro deftest-overlays-equal-1 (id result ov1-args ov2-args) + `(ert-deftest ,(make-overlay-test-name 'overlays-equal 1 id) () + (cl-labels ((create-overlay (args) + (cl-destructuring-bind (start end &optional fa ra &rest properties) + args + (let ((ov (make-overlay start end nil fa ra))) + (while properties + (overlay-put ov (pop properties) (pop properties))) + ov)))) + (with-temp-buffer + (insert (make-string 1024 ?\s)) + (should (,(if result 'identity 'not) + (equal (create-overlay ',ov1-args) + (create-overlay ',ov2-args)))))))) + + +(defun find-ert-overlay-test (name) + (let ((test (unmake-ov-test-name name))) + (or (and test + (cl-destructuring-bind (fn x y) + test + (let ((regexp (format "deftest-%s-%s +%s" fn x y))) + (re-search-forward regexp nil t)))) + (let ((find-function-regexp-alist + (cl-remove 'find-ert-overlay-test find-function-regexp-alist :key #'cdr))) + (find-function-do-it name 'ert-deftest 'switch-to-buffer-other-window))))) + +(add-to-list 'find-function-regexp-alist + '(ert-deftest . find-ert-overlay-test)) + + +;; +===================================================================================+ +;; | make-overlay +;; +===================================================================================+ + +;; Test if making an overlay succeeds. +(deftest-make-overlay-1 A (1 1)) +(deftest-make-overlay-1 B (7 26)) +(deftest-make-overlay-1 C (29 7)) +(deftest-make-overlay-1 D (most-positive-fixnum 1)) +(deftest-make-overlay-1 E (most-negative-fixnum 1)) +(deftest-make-overlay-1 F (1 most-positive-fixnum)) +(deftest-make-overlay-1 G (1 most-negative-fixnum)) +(deftest-make-overlay-1 H (1 1 nil t)) +(deftest-make-overlay-1 I (1 1 nil nil)) +(deftest-make-overlay-1 J (1 1 nil nil nil)) +(deftest-make-overlay-1 K (1 1 nil nil t)) +(deftest-make-overlay-1 L (1 1 nil t t)) +(deftest-make-overlay-1 M (1 1 nil "yes" "yes")) + +;; Test if trying to make an overlay signals conditions. +(deftest-make-overlay-2 A () wrong-number-of-arguments) +(deftest-make-overlay-2 B (1) wrong-number-of-arguments) +(deftest-make-overlay-2 C (1 2 3 4 5 6) wrong-number-of-arguments) +(deftest-make-overlay-2 D ("1") wrong-number-of-arguments) +(deftest-make-overlay-2 E ("1" "2") wrong-type-argument) +(deftest-make-overlay-2 F (1 2 "b") wrong-type-argument) +(deftest-make-overlay-2 G (1 2 3.14) wrong-type-argument) +(deftest-make-overlay-2 H (3.14 3) wrong-type-argument) +(deftest-make-overlay-2 I (1 [1]) wrong-type-argument) +(deftest-make-overlay-2 J (1 1 (with-temp-buffer + (current-buffer))) + error) + + +;; +===================================================================================+ +;; | overlay-start/end +;; +===================================================================================+ + +;; Test if the overlays return proper positions. point-max of the +;; buffer will equal 10. ARG RESULT +(deftest-overlay-start/end-1 A (1 1) (1 1)) +(deftest-overlay-start/end-1 B (2 7) (2 7)) +(deftest-overlay-start/end-1 C (7 2) (2 7)) +(deftest-overlay-start/end-1 D (1 10) (1 10)) +(deftest-overlay-start/end-1 E (1 11) (1 10)) +(deftest-overlay-start/end-1 F (1 most-positive-fixnum) (1 10)) +(deftest-overlay-start/end-1 G (most-positive-fixnum 1) (1 10)) +(deftest-overlay-start/end-1 H (most-positive-fixnum most-positive-fixnum) (10 10)) +(deftest-overlay-start/end-1 I (100 11) (10 10)) +(deftest-overlay-start/end-1 J (11 100) (10 10)) +(deftest-overlay-start/end-1 K (0 1) (1 1)) +(deftest-overlay-start/end-1 L (1 0) (1 1)) +(deftest-overlay-start/end-1 M (0 0) (1 1)) + +(ert-deftest test-overlay-start/end-2 () + (should-not (overlay-start (with-temp-buffer (make-overlay 1 1)))) + (should-not (overlay-end (with-temp-buffer (make-overlay 1 1))))) + + +;; +===================================================================================+ +;; | overlay-buffer +;; +===================================================================================+ + +;; Test if overlay-buffer returns appropriate values. +(deftest-overlay-buffer-1 A (current-buffer) (current-buffer)) +(deftest-overlay-buffer-1 B nil (current-buffer)) +(ert-deftest test-overlay-buffer-1-C () + (should-error (make-overlay + 1 1 (with-temp-buffer (current-buffer))))) + + +;; +===================================================================================+ +;; | overlayp +;; +===================================================================================+ + +;; Check the overlay predicate. +(deftest-overlayp-1 A (make-overlay 1 1) t) +(deftest-overlayp-1 B (with-temp-buffer (make-overlay 1 1)) t) +(deftest-overlayp-1 C nil nil) +(deftest-overlayp-1 D 'symbol nil) +(deftest-overlayp-1 E "string" nil) +(deftest-overlayp-1 F 42 nil) +(deftest-overlayp-1 G [1 2] nil) +(deftest-overlayp-1 H (symbol-function 'car) nil) +(deftest-overlayp-1 I float-pi nil) +(deftest-overlayp-1 J (cons 1 2) nil) +(deftest-overlayp-1 K (make-hash-table) nil) +(deftest-overlayp-1 L (symbol-function 'ert-deftest) nil) +(deftest-overlayp-1 M (current-buffer) nil) +(deftest-overlayp-1 N (selected-window) nil) +(deftest-overlayp-1 O (selected-frame) nil) + + +;; +===================================================================================+ +;; | overlay equality +;; +===================================================================================+ + +(deftest-overlays-equal-1 A t (1 1) (1 1)) +(deftest-overlays-equal-1 B t (5 10) (5 10)) +(deftest-overlays-equal-1 C nil (5 11) (5 10)) +(deftest-overlays-equal-1 D t (10 20 t) (10 20)) +(deftest-overlays-equal-1 E t (10 20 nil t) (10 20)) +(deftest-overlays-equal-1 F t (10 20 t t) (10 20 nil t)) +(deftest-overlays-equal-1 G t (10 20 t t) (10 20 t nil)) +(deftest-overlays-equal-1 H t (10 20 nil nil foo 42) (10 20 nil nil foo 42)) +(deftest-overlays-equal-1 I nil (10 20 nil nil foo 42) (10 20 nil nil foo 43)) + + +;; +===================================================================================+ +;; | overlay-lists +;; +===================================================================================+ + +;; Check whether overlay-lists returns something sensible. +(ert-deftest test-overlay-lists-1 () + (with-temp-buffer + (should (equal (cons nil nil) (overlay-lists))) + (dotimes (i 10) (make-overlay 1 i)) + (should (listp (car (overlay-lists)))) + (should (listp (cdr (overlay-lists)))) + (let ((list (append (car (overlay-lists)) + (cdr (overlay-lists))))) + (should (= 10 (length list))) + (should (seq-every-p #'overlayp list))))) + + +;; +===================================================================================+ +;; | overlay-put/get/properties +;; +===================================================================================+ + +;; Test if overlay-put properties can be retrieved by overlay-get and +;; overlay-properties. +(ert-deftest test-overlay-props-1 () + (with-temp-buffer + (let* ((keys '(:k1 :k2 :k3)) + (values '(1 "v2" v3)) + (ov (make-overlay 1 1)) + (n (length keys))) + (should (equal (length keys) (length values))) + (should (null (overlay-properties ov))) + ;; Insert keys and values. + (dotimes (i n) + (should (equal (overlay-put ov (nth i keys) (nth i values)) + (nth i values)))) + ;; Compare with what overlay-get says. + (dotimes (i n) + (should (equal (overlay-get ov (nth i keys)) + (nth i values)))) + ;; Test if overlay-properties is a superset. + (dotimes (i n) + (should (equal (plist-get (overlay-properties ov) + (nth i keys)) + (nth i values)))) + ;; Check if overlay-properties is a subset. + (should (= (length (overlay-properties ov)) (* n 2)))))) + + +;; +===================================================================================+ +;; | next-overlay-change +;; +===================================================================================+ + +;; Test if next-overlay-change returns RESULT if called with POS in a +;; buffer with overlays corresponding to OVS and point-max >= 100. +;; (POS RESULT &rest OVS) +;; 0 overlays +(deftest-next-overlay-change-1 A (point-min) (point-max)) +(deftest-next-overlay-change-1 B (point-max) (point-max)) +;; 1 non-empty overlay +(deftest-next-overlay-change-1 C 1 10 (10 20)) +(deftest-next-overlay-change-1 D 10 20 (10 20)) +(deftest-next-overlay-change-1 E 15 20 (10 20)) +(deftest-next-overlay-change-1 F 20 (point-max) (10 20)) +(deftest-next-overlay-change-1 G 30 (point-max) (10 20)) +;; 1 empty overlay +(deftest-next-overlay-change-1 H 1 10 (10 10)) +(deftest-next-overlay-change-1 I 10 (point-max) (10 10)) +(deftest-next-overlay-change-1 J 20 (point-max) (10 10)) +;; 2 non-empty, non-intersecting +(deftest-next-overlay-change-1 D 10 20 (20 30) (40 50)) +(deftest-next-overlay-change-1 E 35 40 (20 30) (40 50)) +(deftest-next-overlay-change-1 F 60 (point-max) (20 30) (40 50)) +(deftest-next-overlay-change-1 G 30 40 (20 30) (40 50)) +(deftest-next-overlay-change-1 H 50 (point-max) (20 30) (40 50)) +;; 2 non-empty, intersecting +(deftest-next-overlay-change-1 I 10 20 (20 30) (25 35)) +(deftest-next-overlay-change-1 J 20 25 (20 30) (25 35)) +(deftest-next-overlay-change-1 K 23 25 (20 30) (25 35)) +(deftest-next-overlay-change-1 L 25 30 (20 30) (25 35)) +(deftest-next-overlay-change-1 M 28 30 (20 30) (25 35)) +(deftest-next-overlay-change-1 N 30 35 (20 30) (25 35)) +(deftest-next-overlay-change-1 O 35 (point-max) (20 30) (25 35)) +(deftest-next-overlay-change-1 P 50 (point-max) (20 30) (25 35)) +;; 2 non-empty, continuous +(deftest-next-overlay-change-1 Q 10 20 (20 30) (30 40)) +(deftest-next-overlay-change-1 R 20 30 (20 30) (30 40)) +(deftest-next-overlay-change-1 S 25 30 (20 30) (30 40)) +(deftest-next-overlay-change-1 T 30 40 (20 30) (30 40)) +(deftest-next-overlay-change-1 U 35 40 (20 30) (30 40)) +(deftest-next-overlay-change-1 V 40 (point-max) (20 30) (30 40)) +(deftest-next-overlay-change-1 W 50 (point-max) (20 30) (30 40)) +;; 1 empty, 1 non-empty, non-in +(deftest-next-overlay-change-1 a 10 20 (20 20) (30 40)) +(deftest-next-overlay-change-1 b 20 30 (20 30) (30 40)) +(deftest-next-overlay-change-1 c 25 30 (20 30) (30 40)) +(deftest-next-overlay-change-1 d 30 40 (20 30) (30 40)) +(deftest-next-overlay-change-1 e 35 40 (20 30) (30 40)) +(deftest-next-overlay-change-1 f 40 (point-max) (20 30) (30 40)) +(deftest-next-overlay-change-1 g 50 (point-max) (20 30) (30 40)) +;; 1 empty, 1 non-empty, intersecting at begin +(deftest-next-overlay-change-1 h 10 20 (20 20) (20 30)) +(deftest-next-overlay-change-1 i 20 30 (20 20) (20 30)) +(deftest-next-overlay-change-1 j 25 30 (20 20) (20 30)) +(deftest-next-overlay-change-1 k 30 (point-max) (20 20) (20 30)) +(deftest-next-overlay-change-1 l 40 (point-max) (20 20) (20 30)) +;; 1 empty, 1 non-empty, intersecting at end +(deftest-next-overlay-change-1 h 10 20 (30 30) (20 30)) +(deftest-next-overlay-change-1 i 20 30 (30 30) (20 30)) +(deftest-next-overlay-change-1 j 25 30 (30 30) (20 30)) +(deftest-next-overlay-change-1 k 30 (point-max) (20 20) (20 30)) +(deftest-next-overlay-change-1 l 40 (point-max) (20 20) (20 30)) +;; 1 empty, 1 non-empty, intersecting in the middle +(deftest-next-overlay-change-1 m 10 20 (25 25) (20 30)) +(deftest-next-overlay-change-1 n 20 25 (25 25) (20 30)) +(deftest-next-overlay-change-1 o 25 30 (25 25) (20 30)) +(deftest-next-overlay-change-1 p 30 (point-max) (25 25) (20 30)) +(deftest-next-overlay-change-1 q 40 (point-max) (25 25) (20 30)) +;; 2 empty, intersecting +(deftest-next-overlay-change-1 r 10 20 (20 20) (20 20)) +(deftest-next-overlay-change-1 s 20 (point-max) (20 20) (20 20)) +(deftest-next-overlay-change-1 t 30 (point-max) (20 20) (20 20)) +;; 2 empty, non-intersecting +(deftest-next-overlay-change-1 u 10 20 (20 20) (30 30)) +(deftest-next-overlay-change-1 v 20 30 (20 20) (30 30)) +(deftest-next-overlay-change-1 w 25 30 (20 20) (30 30)) +(deftest-next-overlay-change-1 x 30 (point-max) (20 20) (30 30)) +(deftest-next-overlay-change-1 y 50 (point-max) (20 20) (30 30)) +;; 10 random +(deftest-next-overlay-change-1 aa 1 5 + (58 66) (41 10) (9 67) (28 88) (27 43) + (24 27) (48 36) (5 90) (61 9)) +(deftest-next-overlay-change-1 ab (point-max) (point-max) + (58 66) (41 10) (9 67) (28 88) (27 43) + (24 27) (48 36) (5 90) (61 9)) +(deftest-next-overlay-change-1 ac 67 88 + (58 66) (41 10) (9 67) (28 88) (27 43) + (24 27) (48 36) (5 90) (61 9)) + + +;; +===================================================================================+ +;; | previous-overlay-change. +;; +===================================================================================+ + +;; Same for previous-overlay-change. +;; 1 non-empty overlay +(deftest-previous-overlay-change-1 A (point-max) 1) +(deftest-previous-overlay-change-1 B 1 1) +(deftest-previous-overlay-change-1 C 1 1 (10 20)) +(deftest-previous-overlay-change-1 D 10 1 (10 20)) +(deftest-previous-overlay-change-1 E 15 10 (10 20)) +(deftest-previous-overlay-change-1 F 20 10 (10 20)) +(deftest-previous-overlay-change-1 G 30 20 (10 20)) +;; 1 empty overlay +(deftest-previous-overlay-change-1 H 1 1 (10 10)) +(deftest-previous-overlay-change-1 I 10 1 (10 10)) +(deftest-previous-overlay-change-1 J 20 10 (10 10)) +;; 2 non-empty, non-intersecting +(deftest-previous-overlay-change-1 D 10 1 (20 30) (40 50)) +(deftest-previous-overlay-change-1 E 35 30 (20 30) (40 50)) +(deftest-previous-overlay-change-1 F 60 50 (20 30) (40 50)) +(deftest-previous-overlay-change-1 G 30 20 (20 30) (40 50)) +(deftest-previous-overlay-change-1 H 50 40 (20 30) (40 50)) +;; 2 non-empty, intersecting +(deftest-previous-overlay-change-1 I 10 1 (20 30) (25 35)) +(deftest-previous-overlay-change-1 J 20 1 (20 30) (25 35)) +(deftest-previous-overlay-change-1 K 23 20 (20 30) (25 35)) +(deftest-previous-overlay-change-1 L 25 20 (20 30) (25 35)) +(deftest-previous-overlay-change-1 M 28 25 (20 30) (25 35)) +(deftest-previous-overlay-change-1 N 30 25 (20 30) (25 35)) +(deftest-previous-overlay-change-1 O 35 30 (20 30) (25 35)) +(deftest-previous-overlay-change-1 P 50 35 (20 30) (25 35)) +;; 2 non-empty, continuous +(deftest-previous-overlay-change-1 Q 10 1 (20 30) (30 40)) +(deftest-previous-overlay-change-1 R 20 1 (20 30) (30 40)) +(deftest-previous-overlay-change-1 S 25 20 (20 30) (30 40)) +(deftest-previous-overlay-change-1 T 30 20 (20 30) (30 40)) +(deftest-previous-overlay-change-1 U 35 30 (20 30) (30 40)) +(deftest-previous-overlay-change-1 V 40 30 (20 30) (30 40)) +(deftest-previous-overlay-change-1 W 50 40 (20 30) (30 40)) +;; 1 empty, 1 non-empty, non-intersecting +(deftest-previous-overlay-change-1 a 10 1 (20 20) (30 40)) +(deftest-previous-overlay-change-1 b 20 1 (20 30) (30 40)) +(deftest-previous-overlay-change-1 c 25 20 (20 30) (30 40)) +(deftest-previous-overlay-change-1 d 30 20 (20 30) (30 40)) +(deftest-previous-overlay-change-1 e 35 30 (20 30) (30 40)) +(deftest-previous-overlay-change-1 f 40 30 (20 30) (30 40)) +(deftest-previous-overlay-change-1 g 50 40 (20 30) (30 40)) +;; 1 empty, 1 non-empty, intersecting at begin +(deftest-previous-overlay-change-1 h 10 1 (20 20) (20 30)) +(deftest-previous-overlay-change-1 i 20 1 (20 20) (20 30)) +(deftest-previous-overlay-change-1 j 25 20 (20 20) (20 30)) +(deftest-previous-overlay-change-1 k 30 20 (20 20) (20 30)) +(deftest-previous-overlay-change-1 l 40 30 (20 20) (20 30)) +;; 1 empty, 1 non-empty, intersecting at end +(deftest-previous-overlay-change-1 m 10 1 (30 30) (20 30)) +(deftest-previous-overlay-change-1 n 20 1 (30 30) (20 30)) +(deftest-previous-overlay-change-1 o 25 20 (30 30) (20 30)) +(deftest-previous-overlay-change-1 p 30 20 (20 20) (20 30)) +(deftest-previous-overlay-change-1 q 40 30 (20 20) (20 30)) +;; 1 empty, 1 non-empty, intersectig in the middle +(deftest-previous-overlay-change-1 r 10 1 (25 25) (20 30)) +(deftest-previous-overlay-change-1 s 20 1 (25 25) (20 30)) +(deftest-previous-overlay-change-1 t 25 20 (25 25) (20 30)) +(deftest-previous-overlay-change-1 u 30 25 (25 25) (20 30)) +(deftest-previous-overlay-change-1 v 40 30 (25 25) (20 30)) +;; 2 empty, intersecting +(deftest-previous-overlay-change-1 w 10 1 (20 20) (20 20)) +(deftest-previous-overlay-change-1 x 20 1 (20 20) (20 20)) +(deftest-previous-overlay-change-1 y 30 20 (20 20) (20 20)) +;; 2 empty, non-intersecting +(deftest-previous-overlay-change-1 z 10 1 (20 20) (30 30)) +(deftest-previous-overlay-change-1 aa 20 1 (20 20) (30 30)) +(deftest-previous-overlay-change-1 ab 25 20 (20 20) (30 30)) +(deftest-previous-overlay-change-1 ac 30 20 (20 20) (30 30)) +(deftest-previous-overlay-change-1 ad 50 30 (20 20) (30 30)) +;; 10 random +(deftest-previous-overlay-change-1 ae 100 90 + (58 66) (41 10) (9 67) (28 88) (27 43) + (24 27) (48 36) (5 90) (61 9)) +(deftest-previous-overlay-change-1 af (point-min) (point-min) + (58 66) (41 10) (9 67) (28 88) (27 43) + (24 27) (48 36) (5 90) (61 9)) +(deftest-previous-overlay-change-1 ag 29 28 + (58 66) (41 10) (9 67) (28 88) (27 43) + (24 27) (48 36) (5 90) (61 9)) + + +;; +===================================================================================+ +;; | overlays-at +;; +===================================================================================+ + + +;; Test whether overlay-at returns RESULT at POS after overlays OVL were +;; created in a buffer. POS RES OVL +(deftest-overlays-at-1 A 1 ()) +;; 1 overlay +(deftest-overlays-at-1 B 10 (a) (a 10 20)) +(deftest-overlays-at-1 C 15 (a) (a 10 20)) +(deftest-overlays-at-1 D 19 (a) (a 10 20)) +(deftest-overlays-at-1 E 20 () (a 10 20)) +(deftest-overlays-at-1 F 1 () (a 10 20)) + +;; 2 non-empty overlays non-intersecting +(deftest-overlays-at-1 G 1 () (a 10 20) (b 30 40)) +(deftest-overlays-at-1 H 10 (a) (a 10 20) (b 30 40)) +(deftest-overlays-at-1 I 15 (a) (a 10 20) (b 30 40)) +(deftest-overlays-at-1 K 20 () (a 10 20) (b 30 40)) +(deftest-overlays-at-1 L 25 () (a 10 20) (b 30 40)) +(deftest-overlays-at-1 M 30 (b) (a 10 20) (b 30 40)) +(deftest-overlays-at-1 N 35 (b) (a 10 20) (b 30 40)) +(deftest-overlays-at-1 O 40 () (a 10 20) (b 30 40)) +(deftest-overlays-at-1 P 50 () (a 10 20) (b 30 40)) + +;; 2 non-empty overlays intersecting +(deftest-overlays-at-1 G 1 () (a 10 30) (b 20 40)) +(deftest-overlays-at-1 H 10 (a) (a 10 30) (b 20 40)) +(deftest-overlays-at-1 I 15 (a) (a 10 30) (b 20 40)) +(deftest-overlays-at-1 K 20 (a b) (a 10 30) (b 20 40)) +(deftest-overlays-at-1 L 25 (a b) (a 10 30) (b 20 40)) +(deftest-overlays-at-1 M 30 (b) (a 10 30) (b 20 40)) +(deftest-overlays-at-1 N 35 (b) (a 10 30) (b 20 40)) +(deftest-overlays-at-1 O 40 () (a 10 30) (b 20 40)) +(deftest-overlays-at-1 P 50 () (a 10 30) (b 20 40)) + +;; 2 non-empty overlays continuous +(deftest-overlays-at-1 G 1 () (a 10 20) (b 20 30)) +(deftest-overlays-at-1 H 10 (a) (a 10 20) (b 20 30)) +(deftest-overlays-at-1 I 15 (a) (a 10 20) (b 20 30)) +(deftest-overlays-at-1 K 20 (b) (a 10 20) (b 20 30)) +(deftest-overlays-at-1 L 25 (b) (a 10 20) (b 20 30)) +(deftest-overlays-at-1 M 30 () (a 10 20) (b 20 30)) + +;; overlays-at never returns empty overlays. +(deftest-overlays-at-1 N 1 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50)) +(deftest-overlays-at-1 O 20 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50)) +(deftest-overlays-at-1 P 30 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50)) +(deftest-overlays-at-1 Q 40 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50)) +(deftest-overlays-at-1 R 50 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50)) +(deftest-overlays-at-1 S 60 () (a 1 60) (c 1 1) (b 30 30) (d 50 50)) + +;; behaviour at point-min and point-max +(ert-deftest test-overlays-at-2 () + (cl-macrolet ((should-length (n list) + `(should (= ,n (length ,list))))) + (with-temp-buffer + (insert (make-string 100 ?\s)) + (make-overlay 1 (point-max)) + (make-overlay 10 10) + (make-overlay 20 20) + (make-overlay (point-max) (point-max)) + (should-length 1 (overlays-at 1)) + (should-length 1 (overlays-at 10)) + (should-length 1 (overlays-at 20)) + (should-length 0 (overlays-at (point-max))) + (narrow-to-region 10 20) + (should-length 1 (overlays-at (point-min))) + (should-length 1 (overlays-at 15)) + (should-length 1 (overlays-at (point-max)))))) + + +;; +===================================================================================+ +;; | overlay-in +;; +===================================================================================+ + + +;; Test whether overlays-in returns RES in BEG,END after overlays OVL were +;; created in a buffer. + +(deftest-overlays-in-1 A 1 (point-max) ());;POS RES OVL +;; 1 overlay +(deftest-overlays-in-1 B 1 10 () (a 10 20)) +(deftest-overlays-in-1 C 5 10 () (a 10 20)) +(deftest-overlays-in-1 D 5 15 (a) (a 10 20)) +(deftest-overlays-in-1 E 10 15 (a) (a 10 20)) +(deftest-overlays-in-1 F 10 20 (a) (a 10 20)) +(deftest-overlays-in-1 G 15 20 (a) (a 10 20)) +(deftest-overlays-in-1 H 15 25 (a) (a 10 20)) +(deftest-overlays-in-1 I 20 25 () (a 10 20)) +(deftest-overlays-in-1 J 30 50 () (a 10 20)) + +;; 2 non-empty overlays non-intersecting +(deftest-overlays-in-1 K 1 5 () (a 10 20) (b 30 40)) +(deftest-overlays-in-1 L 5 10 () (a 10 20) (b 30 40)) +(deftest-overlays-in-1 M 5 15 (a) (a 10 20) (b 30 40)) +(deftest-overlays-in-1 N 10 15 (a) (a 10 20) (b 30 40)) +(deftest-overlays-in-1 O 15 20 (a) (a 10 20) (b 30 40)) +(deftest-overlays-in-1 P 15 25 (a) (a 10 20) (b 30 40)) +(deftest-overlays-in-1 Q 20 25 () (a 10 20) (b 30 40)) +(deftest-overlays-in-1 R 20 30 () (a 10 20) (b 30 40)) +(deftest-overlays-in-1 S 25 30 () (a 10 20) (b 30 40)) +(deftest-overlays-in-1 T 25 35 (b) (a 10 20) (b 30 40)) +(deftest-overlays-in-1 U 30 35 (b) (a 10 20) (b 30 40)) +(deftest-overlays-in-1 V 40 50 () (a 10 20) (b 30 40)) +(deftest-overlays-in-1 W 50 60 () (a 10 20) (b 30 40)) +(deftest-overlays-in-1 X 1 50 (a b) (a 10 20) (b 30 40)) +(deftest-overlays-in-1 Y 10 40 (a b) (a 10 20) (b 30 40)) +(deftest-overlays-in-1 Z 10 41 (a b) (a 10 20) (b 30 40)) + +;; 2 non-empty overlays intersecting +(deftest-overlays-in-1 a 1 5 () (a 10 30) (b 20 40)) +(deftest-overlays-in-1 b 5 10 () (a 10 30) (b 20 40)) +(deftest-overlays-in-1 c 5 15 (a) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 d 10 15 (a) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 e 10 20 (a) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 f 15 20 (a) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 g 20 30 (a b) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 h 20 40 (a b) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 i 25 30 (a b) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 j 30 30 (b) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 k 30 35 (b) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 l 35 40 (b) (a 10 30) (b 20 40)) +(deftest-overlays-in-1 m 40 45 () (a 10 30) (b 20 40)) +(deftest-overlays-in-1 n 41 45 () (a 10 30) (b 20 40)) +(deftest-overlays-in-1 o 50 60 () (a 10 30) (b 20 40)) + +;; 2 non-empty overlays continuous +(deftest-overlays-in-1 p 1 5 () (a 10 20) (b 20 30)) +(deftest-overlays-in-1 q 5 10 () (a 10 20) (b 20 30)) +(deftest-overlays-in-1 r 15 20 (a) (a 10 20) (b 20 30)) +(deftest-overlays-in-1 s 15 25 (a b) (a 10 20) (b 20 30)) +(deftest-overlays-in-1 t 20 25 (b) (a 10 20) (b 20 30)) +(deftest-overlays-in-1 u 25 30 (b) (a 10 20) (b 20 30)) +(deftest-overlays-in-1 v 29 35 (b) (a 10 20) (b 20 30)) +(deftest-overlays-in-1 w 30 35 () (a 10 20) (b 20 30)) +(deftest-overlays-in-1 x 35 50 () (a 10 20) (b 20 30)) +(deftest-overlays-in-1 y 1 50 (a b) (a 10 20) (b 20 30)) +(deftest-overlays-in-1 z 15 50 (a b) (a 10 20) (b 20 30)) +(deftest-overlays-in-1 aa 1 25 (a b) (a 10 20) (b 20 30)) + +;; 1 empty overlay +(deftest-overlays-in-1 ab 1 10 () (a 10 10)) +(deftest-overlays-in-1 ac 10 10 (a) (a 10 10)) +(deftest-overlays-in-1 ad 9 10 () (a 10 10)) +(deftest-overlays-in-1 ae 9 11 (a) (a 10 10)) +(deftest-overlays-in-1 af 10 11 (a) (a 10 10)) + + +;; behaviour at point-max +(ert-deftest test-overlays-in-2 () + (cl-macrolet ((should-length (n list) + `(should (= ,n (length ,list))))) + (with-temp-buffer + (insert (make-string 100 ?\s)) + (make-overlay (point-max) (point-max)) + (make-overlay 50 50) + (should-length 1 (overlays-in 50 50)) + (should-length 2 (overlays-in 1 (point-max))) + (should-length 1 (overlays-in (point-max) (point-max))) + (narrow-to-region 1 50) + (should-length 0 (overlays-in 1 (point-max))) + (should-length 1 (overlays-in (point-max) (point-max)))))) + + +;; +===================================================================================+ +;; | overlay-recenter +;; +===================================================================================+ + +;; This function is a noop in the overlay tree branch. +(ert-deftest test-overlay-recenter () + (with-temp-buffer + (should-not (overlay-recenter 1)) + (insert (make-string 100 ?\s)) + (dotimes (i 10) + (make-overlay i (1+ i)) + (should-not (overlay-recenter i))))) + + +;; +===================================================================================+ +;; | move-overlay +;; +===================================================================================+ + +;; buffer nil with live overlay +(ert-deftest test-move-overlay-1 () + (test-with-overlay-in-buffer (ov 1 100) + (move-overlay ov 50 60) + (should (= 50 (overlay-start ov))) + (should (= 60 (overlay-end ov))) + (should (eq (current-buffer) (overlay-buffer ov))))) + +;; buffer nil, dead overlay +(ert-deftest test-move-overlay-2 () + (with-temp-buffer + (let ((ov (test-with-overlay-in-buffer (ov 1 100) ov))) + (insert (make-string 100 ?\s)) + (move-overlay ov 50 60) + (should (= 50 (overlay-start ov))) + (should (= 60 (overlay-end ov))) + (should (eq (current-buffer) (overlay-buffer ov)))))) + +;; buffer non-nil, live overlay +(ert-deftest test-move-overlay-3 () + (test-with-overlay-in-buffer (ov 10 100) + (with-temp-buffer + (move-overlay ov 1 1 (current-buffer)) + (should (= 1 (overlay-start ov))) + (should (= 1 (overlay-end ov))) + (should (eq (current-buffer) (overlay-buffer ov)))) + (should-not (overlay-start ov)) + (should-not (overlay-end ov)) + (should-not (overlay-buffer ov)))) + +;; buffer non-nil, dead overlay +(ert-deftest test-move-overlay-4 () + (let ((ov (test-with-overlay-in-buffer (ov 1 1) ov))) + (with-temp-buffer + (move-overlay ov 1 1 (current-buffer)) + (should (= 1 (overlay-start ov))) + (should (= 1 (overlay-end ov))) + (should (eq (current-buffer) (overlay-buffer ov)))) + (should-not (overlay-start ov)) + (should-not (overlay-end ov)) + (should-not (overlay-buffer ov)))) + +;; This used to fail. +(ert-deftest test-move-overlay-5 () + (skip-unless (fboundp 'overlay-tree)) + (with-temp-buffer + (insert (make-string 1 ?.)) + (let ((other (make-overlay 1 1))) + (make-overlay 1 1) + (insert "()") + (move-overlay other (point-max) (1+ (point-max)) (current-buffer)) + (delete-overlay other)) + (should (= (plist-get (car (with-no-warnings (overlay-tree))) :limit) + 1)))) + + +;; +===================================================================================+ +;; | delete-(all-)overlay +;; +===================================================================================+ + +;; delete live overlay +(ert-deftest test-delete-overlay-1 () + (test-with-overlay-in-buffer (ov 10 100) + (should (buffer-live-p (overlay-buffer ov))) + (delete-overlay ov) + (should-not (overlay-start ov)) + (should-not (overlay-end ov)) + (should-not (overlay-buffer ov)))) + +;; delete dead overlay +(ert-deftest test-delete-overlay-2 () + (let ((ov (test-with-overlay-in-buffer (ov 10 100) ov))) + (should-not (overlay-start ov)) + (should-not (overlay-end ov)) + (should-not (overlay-buffer ov)) + (should-not (delete-overlay ov)) + (should-not (overlay-start ov)) + (should-not (overlay-end ov)) + (should-not (overlay-buffer ov)))) + +(ert-deftest test-delete-all-overlay-1 () + (with-temp-buffer + (should-not (delete-all-overlays)) + (should-not (delete-all-overlays (current-buffer))) + (insert (make-string 100 ?\s)) + (dotimes (i 10) (make-overlay i (1+ i))) + (should-not (delete-all-overlays (current-buffer))) + (should-not (delete-all-overlays)))) + + +;; +===================================================================================+ +;; | get-char-property(-and-overlay) +;; +===================================================================================+ + +;; FIXME: TBD + + +;; +===================================================================================+ +;; | Moving by insertions +;; +===================================================================================+ + +(defmacro deftest-moving-insert-1 (id beg-end insert sbeg-send fa ra) + (cl-destructuring-bind (beg end ipos ilen sbeg send fa ra) + (append beg-end insert sbeg-send (list fa ra) nil) + `(ert-deftest ,(make-overlay-test-name 'moving-insert 1 id) () + (test-with-overlay-in-buffer (ov ,beg ,end ,fa ,ra) + (should (= ,beg (overlay-start ov))) + (should (= ,end (overlay-end ov))) + (goto-char ,ipos) + (insert (make-string ,ilen ?x)) + (should (= ,sbeg (overlay-start ov))) + (should (= ,send (overlay-end ov))))))) + +;; non-empty, no fa, no ra +;; -------------------- OV INS RESULT +(deftest-moving-insert-1 A (10 20) (15 3) (10 23) nil nil) +(deftest-moving-insert-1 B (10 20) (20 4) (10 20) nil nil) +(deftest-moving-insert-1 C (10 20) (5 5) (15 25) nil nil) +(deftest-moving-insert-1 D (10 20) (10 3) (10 23) nil nil) +(deftest-moving-insert-1 E (10 20) (20 4) (10 20) nil nil) + +;; non-empty no fa, ra +(deftest-moving-insert-1 F (10 20) (15 3) (10 23) nil t) +(deftest-moving-insert-1 G (10 20) (20 4) (10 24) nil t) +(deftest-moving-insert-1 H (10 20) (5 5) (15 25) nil t) +(deftest-moving-insert-1 I (10 20) (10 3) (10 23) nil t) +(deftest-moving-insert-1 J (10 20) (20 4) (10 24) nil t) + +;; non-empty, fa, no r +(deftest-moving-insert-1 K (10 20) (15 3) (10 23) t nil) +(deftest-moving-insert-1 L (10 20) (20 4) (10 20) t nil) +(deftest-moving-insert-1 M (10 20) (5 5) (15 25) t nil) +(deftest-moving-insert-1 N (10 20) (10 3) (13 23) t nil) +(deftest-moving-insert-1 O (10 20) (20 4) (10 20) t nil) + +;; This used to fail. +(ert-deftest test-moving-insert-2-a () + (with-temp-buffer + (insert (make-string 1 ?.)) + (let ((ov (make-overlay 1 1 nil t nil))) + (insert "()") + (should (= 1 (overlay-end ov)))))) + +;; non-empty, fa, ra +(deftest-moving-insert-1 P (10 20) (15 3) (10 23) t t) +(deftest-moving-insert-1 Q (10 20) (20 4) (10 24) t t) +(deftest-moving-insert-1 R (10 20) (5 5) (15 25) t t) +(deftest-moving-insert-1 S (10 20) (10 3) (13 23) t t) +(deftest-moving-insert-1 T (10 20) (20 4) (10 24) t t) + +;; empty, no fa, no ra +(deftest-moving-insert-1 U (15 15) (20 4) (15 15) nil nil) +(deftest-moving-insert-1 V (15 15) (5 5) (20 20) nil nil) +(deftest-moving-insert-1 W (15 15) (15 3) (15 15) nil nil) + +;; empty no fa, ra +(deftest-moving-insert-1 X (15 15) (20 4) (15 15) nil t) +(deftest-moving-insert-1 Y (15 15) (5 5) (20 20) nil t) +(deftest-moving-insert-1 Z (15 15) (15 3) (15 18) nil t) + +;; empty, fa, no ra +(deftest-moving-insert-1 a (15 15) (20 4) (15 15) t nil) +(deftest-moving-insert-1 b (15 15) (5 5) (20 20) t nil) +(deftest-moving-insert-1 c (15 15) (15 3) (15 15) t nil) + +;; empty, fa, ra +(deftest-moving-insert-1 d (15 15) (20 4) (15 15) t t) +(deftest-moving-insert-1 e (15 15) (5 5) (20 20) t t) +(deftest-moving-insert-1 f (15 15) (15 3) (18 18) t t) + +;; Try to trigger a pathological case where the tree could become +;; unordered due to an insert operation. + +(ert-deftest test-moving-insert-2 () + (with-temp-buffer + (insert (make-string 1000 ?x)) + (let ((root (make-overlay 50 75 nil nil 'rear-advance)) + (left (make-overlay 25 50 nil 'front-advance 'rear-advance)) + (right (make-overlay 75 100 nil nil nil))) + ;; [50] <--- start + ;; / \ + ;; (25) (75) + (delete-region 25 75) + ;; [25] + ;; / \ + ;; (25) (25) + (should (= 25 (overlay-start root))) + (should (= 25 (overlay-end root))) + (should (= 25 (overlay-start left))) + (should (= 25 (overlay-end left))) + (should (= 25 (overlay-start right))) + (should (= 50 (overlay-end right))) + ;; Inserting at start should make left advance while right and + ;; root stay, thus we would have left > right . + (goto-char 25) + (insert (make-string 25 ?x)) + ;; [25] + ;; / \ + ;; (50) (25) + (should (= 25 (overlay-start root))) + (should (= 50 (overlay-end root))) + (should (= 50 (overlay-start left))) + (should (= 50 (overlay-end left))) + (should (= 25 (overlay-start right))) + (should (= 75 (overlay-end right))) + ;; Try to detect the error, by removing left. The should fail + ;; an eassert, since it won't be found by a reular tree + ;; traversal - in theory. + (delete-overlay left) + (should (= 2 (length (overlays-in 1 (point-max)))))))) + + + +;; +===================================================================================+ +;; | Moving by deletions +;; +===================================================================================+ + +(defmacro deftest-moving-delete-1 (id beg-end delete sbeg-send fa ra) + (cl-destructuring-bind (beg end dpos dlen sbeg send fa ra) + (append beg-end delete sbeg-send (list fa ra) nil) + `(ert-deftest ,(make-overlay-test-name 'moving-delete 1 id) () + (test-with-overlay-in-buffer (ov ,beg ,end ,fa ,ra) + (should (= ,beg (overlay-start ov))) + (should (= ,end (overlay-end ov))) + (delete-region ,dpos (+ ,dpos ,dlen)) + (should (= ,sbeg (overlay-start ov))) + (should (= ,send (overlay-end ov))))))) + +;; non-empty, no fa, no ra +;; -------------------- OV DEL RESULT +(deftest-moving-delete-1 A (10 20) (15 3) (10 17) nil nil) +(deftest-moving-delete-1 B (10 20) (20 4) (10 20) nil nil) +(deftest-moving-delete-1 C (10 20) (5 5) (5 15) nil nil) +(deftest-moving-delete-1 D (10 20) (10 3) (10 17) nil nil) +(deftest-moving-delete-1 E (10 20) (20 4) (10 20) nil nil) + +;; non-empty no fa, ra +(deftest-moving-delete-1 F (10 20) (15 3) (10 17) nil t) +(deftest-moving-delete-1 G (10 20) (20 4) (10 20) nil t) +(deftest-moving-delete-1 H (10 20) (5 5) (5 15) nil t) +(deftest-moving-delete-1 I (10 20) (10 3) (10 17) nil t) +(deftest-moving-delete-1 J (10 20) (20 4) (10 20) nil t) + +;; non-empty, fa, no ra +(deftest-moving-delete-1 K (10 20) (15 3) (10 17) t nil) +(deftest-moving-delete-1 L (10 20) (20 4) (10 20) t nil) +(deftest-moving-delete-1 M (10 20) (5 5) (5 15) t nil) +(deftest-moving-delete-1 N (10 20) (10 3) (10 17) t nil) +(deftest-moving-delete-1 O (10 20) (20 4) (10 20) t nil) + +;; non-empty, fa, ra +(deftest-moving-delete-1 P (10 20) (15 3) (10 17) t t) +(deftest-moving-delete-1 Q (10 20) (20 4) (10 20) t t) +(deftest-moving-delete-1 R (10 20) (5 5) (5 15) t t) +(deftest-moving-delete-1 S (10 20) (10 3) (10 17) t t) +(deftest-moving-delete-1 T (10 20) (20 4) (10 20) t t) + +;; empty, no fa, no ra +(deftest-moving-delete-1 U (15 15) (20 4) (15 15) nil nil) +(deftest-moving-delete-1 V (15 15) (5 5) (10 10) nil nil) +(deftest-moving-delete-1 W (15 15) (15 3) (15 15) nil nil) + +;; empty no fa, ra +(deftest-moving-delete-1 X (15 15) (20 4) (15 15) nil t) +(deftest-moving-delete-1 Y (15 15) (5 5) (10 10) nil t) +(deftest-moving-delete-1 Z (15 15) (15 3) (15 15) nil t) + +;; empty, fa, no ra +(deftest-moving-delete-1 a (15 15) (20 4) (15 15) t nil) +(deftest-moving-delete-1 b (15 15) (5 5) (10 10) t nil) +(deftest-moving-delete-1 c (15 15) (15 3) (15 15) t nil) + +;; empty, fa, ra +(deftest-moving-delete-1 d (15 15) (20 4) (15 15) t t) +(deftest-moving-delete-1 e (15 15) (5 5) (10 10) t t) +(deftest-moving-delete-1 f (15 15) (15 3) (15 15) t t) + + +;; +===================================================================================+ +;; | make-indirect-buffer +;; +===================================================================================+ + +;; Check if overlays are cloned/seperate from indirect buffer. +(ert-deftest test-make-indirect-buffer-1 () + (with-temp-buffer + (dotimes (_ 10) (make-overlay 1 1)) + (let (indirect clone) + (unwind-protect + (progn + (setq indirect (make-indirect-buffer + (current-buffer) "indirect")) + (with-current-buffer indirect + (should-not (overlays-in (point-min) (point-max))) + (dotimes (_ 20) (make-overlay 1 1)) + (should (= 20 (length (overlays-in (point-min) (point-max))))) + (delete-all-overlays) + (should-not (overlays-in (point-min) (point-max)))) + (should (= 10 (length (overlays-in (point-min) (point-max))))) + (setq clone (make-indirect-buffer + (current-buffer) "clone" 'clone)) + (with-current-buffer clone + (should (= 10 (length (overlays-in (point-min) (point-max))))) + (dotimes (_ 30) (make-overlay 1 1)) + (should (= 40 (length (overlays-in (point-min) (point-max)))))) + ;; back in temp buffer + (should (= 10 (length (overlays-in (point-min) (point-max))))) + (with-current-buffer clone + (mapc #'delete-overlay + (seq-take (overlays-in (point-min) (point-max)) 10)) + (should (= 30 (length (overlays-in (point-min) (point-max)))))) + (should (= 10 (length (overlays-in (point-min) (point-max))))) + (delete-all-overlays) + (with-current-buffer clone + (should (= 30 (length (overlays-in (point-min) (point-max))))))) + (when (buffer-live-p clone) + (kill-buffer clone)) + (when (buffer-live-p indirect) + (kill-buffer indirect)))))) + + + +;; +===================================================================================+ +;; | buffer-swap-text +;; +===================================================================================+ + +(defmacro test-with-temp-buffers (vars &rest body) + (declare (indent 1) (debug (sexp &rest form))) + (if (null vars) + `(progn ,@body) + `(with-temp-buffer + (let ((,(car vars) (current-buffer))) + (test-with-temp-buffers ,(cdr vars) ,@body))))) + +;; basic +(ert-deftest test-buffer-swap-text-1 () + (test-with-temp-buffers (buffer other) + (with-current-buffer buffer + (let ((ov (make-overlay 1 1))) + (buffer-swap-text other) + (should-not (overlays-in 1 1)) + (with-current-buffer other + (should (overlays-in 1 1)) + (should (eq ov (car (overlays-in 1 1))))))))) + +;; properties +(ert-deftest test-buffer-swap-text-1 () + (test-with-temp-buffers (buffer other) + (with-current-buffer other + (overlay-put (make-overlay 1 1) 'buffer 'other)) + (with-current-buffer buffer + (overlay-put (make-overlay 1 1) 'buffer 'buffer) + (buffer-swap-text other) + (should (= 1 (length (overlays-in 1 1)))) + (should (eq (overlay-get (car (overlays-in 1 1)) 'buffer) 'other))) + (with-current-buffer other + (should (= 1 (length (overlays-in 1 1)))) + (should (eq (overlay-get (car (overlays-in 1 1)) 'buffer) 'buffer))))) + + +;; +===================================================================================+ +;; | priorities +;; +===================================================================================+ + +(ert-deftest test-overlay-priorities-1 () + (with-temp-buffer + (insert " ") + (dotimes (i 10) + (let ((ov (make-overlay 1 2))) + (overlay-put ov 'priority i) + (overlay-put ov 'value i))) + (should (eq 9 (get-char-property 1 'value))))) + +(ert-deftest test-overlay-priorities-2 () + (with-temp-buffer + (insert " ") + (dotimes (j 10) + (let* ((i (- 9 j)) + (ov (make-overlay 1 2))) + (overlay-put ov 'priority i) + (overlay-put ov 'value i))) + (should (eq 9 (get-char-property 1 'value))))) + + +;; +===================================================================================+ +;; | Other +;; +===================================================================================+ + +(defun test-overlay-regions () + (sort (mapcar (lambda (ov) + (cons (overlay-start ov) + (overlay-end ov))) + (overlays-in (point-min) + (point-max))) + (lambda (o1 o2) + (or (< (car o1) (car o2)) + (and (= (car o1) (car o2)) + (< (cdr o1) (cdr o2))))))) + +;; This test used to fail. +(ert-deftest overlay-complex-delete-with-offset () + (with-temp-buffer + (let (todelete) + (insert (make-string 1000 ?\s)) + (make-overlay 1 2 nil t nil) + (make-overlay 2 3 nil t nil) + (make-overlay 3 4 nil t nil) + (make-overlay 4 5 nil t nil) + (setq todelete (make-overlay 280 287 nil t nil)) + (make-overlay 265 275 nil t nil) + (make-overlay 329 386 nil t nil) + (make-overlay 386 390 nil t nil) + (goto-char 50) + (delete-char 50) + (goto-char 1) + (delete-char 2) + (delete-overlay todelete) + (should (equal (test-overlay-regions) + '((1 . 1) (1 . 1) (1 . 2) (2 . 3) (213 . 223) (277 . 334) (334 . 338))))))) + +;; This test used to fail. +(ert-deftest overlay-complex-insert-1 () + (with-temp-buffer + (insert " ") + (make-overlay 8 11 nil nil t) + (make-overlay 2 7 nil nil nil) + (make-overlay 2 4 nil t nil) + (goto-char 1) + (insert " ") + (should (equal (test-overlay-regions) + '((7 . 9) + (7 . 12) + (13 . 16)))))) + +;; This test used to fail. +(ert-deftest overlay-complex-insert-2 () + (with-temp-buffer + (insert (make-string 100 ?\s)) + (make-overlay 77 7 nil nil t) + (make-overlay 21 53 nil t t) + (make-overlay 84 14 nil nil nil) + (make-overlay 38 69 nil t nil) + (make-overlay 93 15 nil nil t) + (make-overlay 73 48 nil t t) + (make-overlay 96 51 nil t t) + (make-overlay 6 43 nil t t) + (make-overlay 15 100 nil t t) + (make-overlay 22 17 nil nil nil) + (make-overlay 72 45 nil t nil) + (make-overlay 2 74 nil nil t) + (make-overlay 15 29 nil t t) + (make-overlay 17 34 nil t t) + (make-overlay 101 66 nil t nil) + (make-overlay 94 24 nil nil nil) + (goto-char 78) + (insert " ") + (narrow-to-region 47 19) + (goto-char 46) + (widen) + (narrow-to-region 13 3) + (goto-char 9) + (delete-char 0) + (goto-char 11) + (insert " ") + (goto-char 3) + (insert " ") + (goto-char 8) + (insert " ") + (goto-char 26) + (insert " ") + (goto-char 14) + (widen) + (narrow-to-region 71 35) + (should + (equal (test-overlay-regions) + '((2 . 104) + (23 . 73) + (24 . 107) + (44 . 125) + (45 . 59) + (45 . 134) + (45 . 141) + (47 . 52) + (47 . 64) + (51 . 83) + (54 . 135) + (68 . 99)))))) + + +;; +===================================================================================+ +;; | Autogenerated insert/delete/narrow tests +;; +===================================================================================+ + + +;; (defun test-overlay-generate-test (name) +;; (interactive) +;; (with-temp-buffer +;; (let ((forms nil) +;; (buffer-size 64) +;; (noverlays 16) +;; (nforms 32) +;; (dist '(0.5 0.4 0.1))) +;; (cl-labels ((brand () +;; (+ (point-min) +;; (random (1+ (- (point-max) (point-min))))))) +;; (cl-macrolet ((push-eval (form) +;; `(cl-destructuring-bind (&rest args) +;; (list ,@(cdr form)) +;; (push (cons ',(car form) args) forms) +;; (apply #',(car form) args)))) +;; (push-eval (insert (make-string buffer-size ?.))) +;; (dotimes (_ noverlays) +;; (push-eval (make-overlay (brand) (brand) +;; nil +;; (= 0 (random 2)) +;; (= 0 (random 2))))) +;; (dotimes (_ nforms) +;; (push-eval (goto-char (brand))) +;; (pcase (/ (random 100) 100.0) +;; ((and x (guard (< x (nth 0 dist)))) +;; (push-eval (insert (make-string (random 16) ?.)))) +;; ((and x (guard (< x (+ (nth 0 dist) (nth 1 dist))))) +;; (push-eval (delete-char (random (1+ (- (point-max) (point))))))) +;; (_ +;; (push-eval (widen)) +;; (push-eval (narrow-to-region (brand) (brand)))))) +;; `(ert-deftest ,name () +;; (with-temp-buffer +;; ,@(nreverse forms) +;; (should (equal (test-overlay-regions) +;; ',(test-overlay-regions)))))))))) + +;; (defun test-overlay-generate-tests (n) +;; (let ((namefmt "overlay-autogenerated-test-%d") +;; (standard-output (current-buffer)) +;; (print-length nil) +;; (print-level nil) +;; (print-quoted t)) +;; (dotimes (i n) +;; (pp (test-overlay-generate-test (intern (format namefmt i)))) +;; (terpri)))) + +;; (progn (random "4711") (test-overlay-generate-tests 64)) + +(ert-deftest overlay-autogenerated-test-0 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 63 7 nil t t) + (make-overlay 47 9 nil nil nil) + (make-overlay 50 43 nil nil nil) + (make-overlay 20 53 nil nil t) + (make-overlay 62 4 nil nil t) + (make-overlay 40 27 nil t t) + (make-overlay 58 44 nil t t) + (make-overlay 46 38 nil nil nil) + (make-overlay 51 28 nil t nil) + (make-overlay 12 53 nil t t) + (make-overlay 52 60 nil nil nil) + (make-overlay 13 47 nil nil nil) + (make-overlay 16 31 nil nil nil) + (make-overlay 9 48 nil t t) + (make-overlay 43 29 nil nil t) + (make-overlay 48 13 nil t nil) + (goto-char 44) + (delete-char 15) + (goto-char 19) + (widen) + (narrow-to-region 20 8) + (goto-char 9) + (delete-char 3) + (goto-char 16) + (insert "..............") + (goto-char 12) + (delete-char 15) + (goto-char 12) + (delete-char 4) + (goto-char 12) + (delete-char 0) + (goto-char 12) + (insert "......") + (goto-char 13) + (delete-char 5) + (goto-char 8) + (insert "...") + (goto-char 10) + (insert ".............") + (goto-char 14) + (insert ".......") + (goto-char 25) + (delete-char 4) + (goto-char 26) + (insert "...............") + (goto-char 27) + (insert "...") + (goto-char 29) + (delete-char 7) + (goto-char 24) + (insert "...") + (goto-char 30) + (insert "..........") + (goto-char 29) + (widen) + (narrow-to-region 34 41) + (goto-char 40) + (delete-char 0) + (goto-char 35) + (delete-char 4) + (goto-char 36) + (widen) + (narrow-to-region 80 66) + (goto-char 74) + (delete-char 5) + (goto-char 69) + (delete-char 5) + (goto-char 70) + (widen) + (narrow-to-region 50 71) + (goto-char 66) + (insert "...............") + (goto-char 54) + (insert "...............") + (goto-char 84) + (insert "....") + (goto-char 72) + (insert "...........") + (goto-char 84) + (insert "..........") + (goto-char 102) + (insert "") + (goto-char 80) + (delete-char 25) + (should + (equal + (test-overlay-regions) + '((4 . 99) + (7 . 100) + (48 . 99) + (48 . 99) + (48 . 99) + (49 . 99) + (49 . 99) + (51 . 80) + (51 . 99) + (80 . 99) + (80 . 99) + (80 . 99) + (99 . 99) + (99 . 99) + (99 . 99) + (99 . 99)))))) + +(ert-deftest overlay-autogenerated-test-1 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 17 27 nil nil nil) + (make-overlay 13 28 nil nil t) + (make-overlay 8 56 nil nil nil) + (make-overlay 34 64 nil nil nil) + (make-overlay 51 4 nil t t) + (make-overlay 1 19 nil nil nil) + (make-overlay 53 59 nil nil t) + (make-overlay 25 13 nil nil nil) + (make-overlay 19 28 nil t nil) + (make-overlay 33 23 nil t nil) + (make-overlay 10 46 nil t t) + (make-overlay 18 39 nil nil nil) + (make-overlay 1 49 nil t nil) + (make-overlay 57 21 nil t t) + (make-overlay 10 58 nil t t) + (make-overlay 39 49 nil nil t) + (goto-char 37) + (delete-char 9) + (goto-char 3) + (insert "......") + (goto-char 38) + (delete-char 14) + (goto-char 18) + (insert "..........") + (goto-char 53) + (insert "....") + (goto-char 49) + (delete-char 10) + (goto-char 11) + (delete-char 12) + (goto-char 17) + (delete-char 22) + (goto-char 8) + (insert ".") + (goto-char 16) + (insert "........") + (goto-char 16) + (delete-char 5) + (goto-char 11) + (delete-char 0) + (goto-char 22) + (insert ".......") + (goto-char 18) + (delete-char 11) + (goto-char 16) + (delete-char 0) + (goto-char 9) + (insert "...........") + (goto-char 7) + (insert "...............") + (goto-char 2) + (insert ".......") + (goto-char 21) + (delete-char 11) + (goto-char 13) + (insert "..............") + (goto-char 17) + (delete-char 3) + (goto-char 21) + (insert "......") + (goto-char 15) + (delete-char 32) + (goto-char 10) + (insert "........") + (goto-char 25) + (widen) + (narrow-to-region 15 20) + (goto-char 17) + (insert ".............") + (goto-char 22) + (insert "............") + (goto-char 21) + (delete-char 8) + (goto-char 36) + (delete-char 1) + (goto-char 32) + (delete-char 2) + (goto-char 21) + (insert ".....") + (goto-char 31) + (insert "......") + (should + (equal + (test-overlay-regions) + '((1 . 58) + (1 . 58)))))) + +(ert-deftest overlay-autogenerated-test-2 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 15 59 nil t t) + (make-overlay 56 16 nil nil nil) + (make-overlay 65 51 nil t nil) + (make-overlay 14 24 nil t nil) + (make-overlay 28 9 nil t nil) + (make-overlay 58 50 nil t t) + (make-overlay 13 32 nil t t) + (make-overlay 12 21 nil t nil) + (make-overlay 60 23 nil t nil) + (make-overlay 39 38 nil nil t) + (make-overlay 15 64 nil t nil) + (make-overlay 17 21 nil nil t) + (make-overlay 46 23 nil t t) + (make-overlay 19 40 nil t nil) + (make-overlay 13 48 nil nil t) + (make-overlay 35 11 nil t nil) + (goto-char 41) + (delete-char 19) + (goto-char 45) + (insert "......") + (goto-char 3) + (delete-char 32) + (goto-char 19) + (insert "") + (goto-char 16) + (insert "...............") + (goto-char 2) + (insert "") + (goto-char 30) + (delete-char 0) + (goto-char 18) + (delete-char 17) + (goto-char 2) + (insert "...............") + (goto-char 12) + (insert "...") + (goto-char 2) + (insert ".............") + (goto-char 16) + (insert ".......") + (goto-char 15) + (insert ".......") + (goto-char 43) + (insert "......") + (goto-char 22) + (insert ".........") + (goto-char 25) + (delete-char 1) + (goto-char 38) + (insert "...............") + (goto-char 76) + (delete-char 3) + (goto-char 12) + (delete-char 5) + (goto-char 70) + (delete-char 9) + (goto-char 36) + (delete-char 4) + (goto-char 18) + (insert "...............") + (goto-char 52) + (delete-char 14) + (goto-char 23) + (insert "..........") + (goto-char 64) + (insert "...........") + (goto-char 68) + (delete-char 21) + (goto-char 71) + (insert "........") + (goto-char 28) + (delete-char 43) + (goto-char 25) + (insert "....") + (goto-char 2) + (insert "...............") + (goto-char 40) + (insert "....") + (goto-char 56) + (delete-char 2) + (should + (equal + (test-overlay-regions) + '((51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 51) + (51 . 58)))))) + +(ert-deftest overlay-autogenerated-test-3 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 53 38 nil t nil) + (make-overlay 17 40 nil t t) + (make-overlay 64 26 nil t t) + (make-overlay 48 24 nil t nil) + (make-overlay 21 18 nil nil nil) + (make-overlay 2 20 nil nil t) + (make-overlay 43 26 nil t t) + (make-overlay 56 28 nil t nil) + (make-overlay 19 51 nil nil nil) + (make-overlay 39 61 nil t nil) + (make-overlay 59 12 nil t nil) + (make-overlay 65 7 nil t nil) + (make-overlay 41 7 nil t nil) + (make-overlay 62 50 nil t nil) + (make-overlay 7 10 nil t t) + (make-overlay 45 28 nil t nil) + (goto-char 13) + (insert "...") + (goto-char 37) + (widen) + (narrow-to-region 2 10) + (goto-char 8) + (delete-char 1) + (goto-char 3) + (delete-char 6) + (goto-char 2) + (insert "...........") + (goto-char 5) + (widen) + (narrow-to-region 55 70) + (goto-char 55) + (insert "......") + (goto-char 64) + (delete-char 12) + (goto-char 61) + (insert ".....") + (goto-char 64) + (insert "..............") + (goto-char 72) + (delete-char 6) + (goto-char 63) + (delete-char 12) + (goto-char 63) + (delete-char 2) + (goto-char 57) + (insert "..............") + (goto-char 68) + (insert "........") + (goto-char 77) + (delete-char 6) + (goto-char 77) + (insert ".............") + (goto-char 67) + (delete-char 0) + (goto-char 84) + (insert "........") + (goto-char 74) + (delete-char 12) + (goto-char 78) + (insert "...") + (goto-char 80) + (insert "............") + (goto-char 69) + (insert "......") + (goto-char 89) + (insert ".") + (goto-char 56) + (insert "....") + (goto-char 100) + (insert ".............") + (goto-char 114) + (delete-char 0) + (goto-char 61) + (widen) + (narrow-to-region 94 50) + (goto-char 55) + (insert "............") + (goto-char 53) + (insert ".............") + (goto-char 116) + (delete-char 3) + (goto-char 81) + (insert "...............") + (should + (equal + (test-overlay-regions) + '((14 . 166) + (16 . 164) + (26 . 164) + (31 . 68) + (33 . 165) + (35 . 52) + (35 . 164) + (45 . 164) + (46 . 164)))))) + +(ert-deftest overlay-autogenerated-test-4 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 25 15 nil nil t) + (make-overlay 8 13 nil nil nil) + (make-overlay 45 49 nil t t) + (make-overlay 22 13 nil t t) + (make-overlay 34 17 nil nil t) + (make-overlay 42 15 nil nil t) + (make-overlay 43 28 nil t t) + (make-overlay 3 28 nil t nil) + (make-overlay 32 61 nil nil t) + (make-overlay 30 64 nil t t) + (make-overlay 21 39 nil nil t) + (make-overlay 32 62 nil t nil) + (make-overlay 25 29 nil t nil) + (make-overlay 34 43 nil t nil) + (make-overlay 9 11 nil t nil) + (make-overlay 21 65 nil nil t) + (goto-char 21) + (delete-char 4) + (goto-char 25) + (insert "..") + (goto-char 53) + (insert "..") + (goto-char 2) + (insert "...............") + (goto-char 42) + (delete-char 36) + (goto-char 23) + (delete-char 12) + (goto-char 22) + (widen) + (narrow-to-region 30 32) + (goto-char 30) + (delete-char 0) + (goto-char 31) + (delete-char 1) + (goto-char 31) + (widen) + (narrow-to-region 28 27) + (goto-char 27) + (delete-char 1) + (goto-char 27) + (delete-char 0) + (goto-char 27) + (delete-char 0) + (goto-char 27) + (insert ".") + (goto-char 28) + (insert "......") + (goto-char 34) + (delete-char 0) + (goto-char 27) + (delete-char 5) + (goto-char 27) + (delete-char 1) + (goto-char 27) + (insert ".............") + (goto-char 30) + (insert "..............") + (goto-char 37) + (delete-char 15) + (goto-char 32) + (delete-char 2) + (goto-char 36) + (delete-char 1) + (goto-char 34) + (delete-char 0) + (goto-char 34) + (delete-char 1) + (goto-char 32) + (widen) + (narrow-to-region 24 19) + (goto-char 21) + (delete-char 1) + (goto-char 21) + (widen) + (narrow-to-region 11 38) + (goto-char 27) + (widen) + (narrow-to-region 20 22) + (goto-char 20) + (delete-char 1) + (goto-char 20) + (widen) + (narrow-to-region 36 4) + (goto-char 26) + (delete-char 9) + (should + (equal + (test-overlay-regions) + '((18 . 25) + (21 . 21) + (21 . 21) + (21 . 22) + (21 . 22) + (21 . 27) + (21 . 27) + (22 . 25) + (22 . 27) + (22 . 28) + (26 . 27)))))) + +(ert-deftest overlay-autogenerated-test-5 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 64 1 nil nil nil) + (make-overlay 38 43 nil nil nil) + (make-overlay 42 19 nil t nil) + (make-overlay 22 12 nil nil nil) + (make-overlay 12 30 nil t t) + (make-overlay 38 46 nil nil nil) + (make-overlay 18 23 nil nil nil) + (make-overlay 58 65 nil nil t) + (make-overlay 52 41 nil nil nil) + (make-overlay 12 26 nil nil nil) + (make-overlay 39 4 nil nil nil) + (make-overlay 20 1 nil nil t) + (make-overlay 36 60 nil nil nil) + (make-overlay 24 18 nil t nil) + (make-overlay 9 50 nil nil nil) + (make-overlay 19 17 nil t nil) + (goto-char 40) + (insert "") + (goto-char 64) + (insert ".............") + (goto-char 32) + (delete-char 40) + (goto-char 25) + (insert "...") + (goto-char 31) + (delete-char 1) + (goto-char 8) + (delete-char 14) + (goto-char 20) + (delete-char 5) + (goto-char 20) + (insert "...........") + (goto-char 20) + (insert ".........") + (goto-char 17) + (widen) + (narrow-to-region 11 21) + (goto-char 14) + (widen) + (narrow-to-region 9 24) + (goto-char 24) + (insert ".............") + (goto-char 30) + (widen) + (narrow-to-region 47 45) + (goto-char 47) + (insert ".") + (goto-char 46) + (widen) + (narrow-to-region 30 42) + (goto-char 32) + (delete-char 0) + (goto-char 34) + (insert ".......") + (goto-char 42) + (delete-char 4) + (goto-char 39) + (delete-char 6) + (goto-char 31) + (delete-char 6) + (goto-char 31) + (insert "............") + (goto-char 30) + (insert "......") + (goto-char 50) + (delete-char 0) + (goto-char 30) + (insert "....") + (goto-char 53) + (insert "............") + (goto-char 41) + (delete-char 12) + (goto-char 52) + (insert ".......") + (goto-char 56) + (insert "...........") + (goto-char 68) + (insert ".......") + (goto-char 52) + (insert "......") + (goto-char 71) + (delete-char 10) + (goto-char 47) + (insert "") + (should + (equal + (test-overlay-regions) + '((20 . 89)))))) + +(ert-deftest overlay-autogenerated-test-6 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 28 59 nil nil nil) + (make-overlay 36 21 nil t t) + (make-overlay 60 19 nil t nil) + (make-overlay 26 30 nil t nil) + (make-overlay 47 27 nil nil t) + (make-overlay 8 25 nil t t) + (make-overlay 57 43 nil t t) + (make-overlay 28 61 nil nil t) + (make-overlay 42 31 nil nil t) + (make-overlay 15 44 nil t nil) + (make-overlay 56 38 nil nil nil) + (make-overlay 39 44 nil nil t) + (make-overlay 50 6 nil t nil) + (make-overlay 6 19 nil t nil) + (make-overlay 50 44 nil t t) + (make-overlay 34 60 nil nil t) + (goto-char 27) + (insert "...............") + (goto-char 23) + (insert "..............") + (goto-char 50) + (widen) + (narrow-to-region 53 67) + (goto-char 60) + (delete-char 0) + (goto-char 54) + (insert "......") + (goto-char 64) + (delete-char 1) + (goto-char 66) + (delete-char 3) + (goto-char 58) + (insert ".............") + (goto-char 58) + (insert ".........") + (goto-char 76) + (insert "...........") + (goto-char 57) + (insert "....") + (goto-char 106) + (widen) + (narrow-to-region 5 45) + (goto-char 31) + (delete-char 8) + (goto-char 36) + (insert "...") + (goto-char 6) + (insert "........") + (goto-char 33) + (insert ".............") + (goto-char 38) + (delete-char 3) + (goto-char 28) + (delete-char 6) + (goto-char 42) + (widen) + (narrow-to-region 17 25) + (goto-char 19) + (insert "..............") + (goto-char 37) + (delete-char 1) + (goto-char 22) + (delete-char 9) + (goto-char 28) + (insert "..............") + (goto-char 37) + (delete-char 3) + (goto-char 18) + (insert "...............") + (goto-char 30) + (widen) + (narrow-to-region 68 25) + (goto-char 38) + (delete-char 22) + (goto-char 43) + (widen) + (narrow-to-region 47 96) + (goto-char 86) + (insert ".") + (goto-char 63) + (insert "......") + (goto-char 78) + (widen) + (narrow-to-region 61 27) + (goto-char 43) + (delete-char 8) + (should + (equal + (test-overlay-regions) + '((14 . 38) + (14 . 132) + (16 . 43) + (38 . 118) + (38 . 126) + (38 . 142) + (44 . 115) + (45 . 129)))))) + +(ert-deftest overlay-autogenerated-test-7 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 13 50 nil t nil) + (make-overlay 28 44 nil nil t) + (make-overlay 56 27 nil t nil) + (make-overlay 8 34 nil nil nil) + (make-overlay 22 8 nil nil t) + (make-overlay 8 28 nil t nil) + (make-overlay 65 31 nil nil t) + (make-overlay 44 8 nil nil nil) + (make-overlay 52 64 nil nil t) + (make-overlay 52 27 nil t t) + (make-overlay 47 32 nil nil nil) + (make-overlay 18 62 nil nil nil) + (make-overlay 18 24 nil t t) + (make-overlay 33 46 nil nil t) + (make-overlay 20 8 nil t nil) + (make-overlay 51 51 nil t nil) + (goto-char 2) + (delete-char 46) + (goto-char 12) + (delete-char 5) + (goto-char 2) + (delete-char 12) + (goto-char 2) + (insert "..") + (goto-char 2) + (widen) + (narrow-to-region 2 4) + (goto-char 4) + (insert "......") + (goto-char 4) + (widen) + (narrow-to-region 4 6) + (goto-char 5) + (insert "") + (goto-char 6) + (insert "...............") + (goto-char 9) + (insert "...") + (goto-char 7) + (delete-char 13) + (goto-char 8) + (delete-char 1) + (goto-char 9) + (insert "...............") + (goto-char 24) + (delete-char 1) + (goto-char 15) + (insert "...............") + (goto-char 16) + (insert "............") + (goto-char 17) + (delete-char 8) + (goto-char 36) + (widen) + (narrow-to-region 47 38) + (goto-char 43) + (delete-char 0) + (goto-char 46) + (delete-char 0) + (goto-char 40) + (delete-char 4) + (goto-char 39) + (insert ".......") + (goto-char 50) + (delete-char 0) + (goto-char 47) + (insert "...........") + (goto-char 45) + (insert ".....") + (goto-char 38) + (delete-char 3) + (goto-char 59) + (delete-char 1) + (goto-char 42) + (insert "...............") + (goto-char 65) + (insert "...........") + (goto-char 73) + (delete-char 13) + (goto-char 72) + (insert "....") + (goto-char 47) + (insert "..") + (should + (equal + (test-overlay-regions) + '((2 . 81) + (2 . 81) + (2 . 81) + (2 . 81) + (2 . 81) + (81 . 81) + (81 . 81)))))) + +(ert-deftest overlay-autogenerated-test-8 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 20 6 nil t nil) + (make-overlay 48 13 nil t nil) + (make-overlay 58 65 nil nil t) + (make-overlay 63 65 nil nil nil) + (make-overlay 42 40 nil t t) + (make-overlay 40 6 nil nil t) + (make-overlay 37 46 nil t nil) + (make-overlay 4 14 nil nil nil) + (make-overlay 58 44 nil t t) + (make-overlay 14 16 nil nil t) + (make-overlay 31 61 nil t nil) + (make-overlay 34 3 nil nil nil) + (make-overlay 11 16 nil t nil) + (make-overlay 19 42 nil nil t) + (make-overlay 30 9 nil nil t) + (make-overlay 63 52 nil t t) + (goto-char 57) + (delete-char 2) + (goto-char 8) + (insert "........") + (goto-char 30) + (insert "...........") + (goto-char 35) + (insert "...........") + (goto-char 66) + (insert "...............") + (goto-char 53) + (delete-char 15) + (goto-char 75) + (delete-char 10) + (goto-char 62) + (delete-char 21) + (goto-char 52) + (delete-char 10) + (goto-char 10) + (insert "............") + (goto-char 42) + (insert "...........") + (goto-char 68) + (insert ".............") + (goto-char 12) + (insert "........") + (goto-char 1) + (insert "...............") + (goto-char 89) + (insert "") + (goto-char 94) + (insert ".............") + (goto-char 57) + (insert "...........") + (goto-char 130) + (insert "...") + (goto-char 69) + (insert "..") + (goto-char 101) + (insert "......") + (goto-char 128) + (delete-char 13) + (goto-char 19) + (delete-char 100) + (goto-char 22) + (insert "..") + (goto-char 13) + (widen) + (narrow-to-region 30 16) + (goto-char 19) + (insert "..........") + (goto-char 22) + (delete-char 3) + (goto-char 19) + (insert ".........") + (goto-char 17) + (insert "..") + (goto-char 16) + (insert "............") + (goto-char 47) + (insert ".") + (goto-char 50) + (insert "..........") + (goto-char 70) + (delete-char 1) + (should + (equal + (test-overlay-regions) + '((32 . 75) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 60) + (33 . 75) + (33 . 75) + (33 . 75) + (60 . 75)))))) + +(ert-deftest overlay-autogenerated-test-9 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 58 13 nil nil nil) + (make-overlay 29 4 nil nil t) + (make-overlay 3 53 nil nil nil) + (make-overlay 31 9 nil t t) + (make-overlay 48 30 nil nil nil) + (make-overlay 43 50 nil nil nil) + (make-overlay 7 27 nil nil t) + (make-overlay 30 59 nil nil nil) + (make-overlay 42 25 nil nil t) + (make-overlay 15 13 nil t t) + (make-overlay 39 11 nil t t) + (make-overlay 21 62 nil t t) + (make-overlay 35 2 nil t nil) + (make-overlay 60 53 nil nil t) + (make-overlay 64 8 nil nil t) + (make-overlay 58 59 nil t t) + (goto-char 28) + (insert ".............") + (goto-char 28) + (insert "...............") + (goto-char 71) + (insert ".......") + (goto-char 65) + (insert "......") + (goto-char 3) + (delete-char 12) + (goto-char 79) + (delete-char 11) + (goto-char 65) + (widen) + (narrow-to-region 12 53) + (goto-char 38) + (insert ".......") + (goto-char 20) + (insert ".........") + (goto-char 27) + (insert "...........") + (goto-char 75) + (insert "........") + (goto-char 85) + (insert "............") + (goto-char 52) + (insert "..........") + (goto-char 16) + (delete-char 8) + (goto-char 15) + (insert "...............") + (goto-char 112) + (insert "") + (goto-char 61) + (insert "..") + (goto-char 29) + (delete-char 34) + (goto-char 52) + (delete-char 32) + (goto-char 43) + (insert "........") + (goto-char 45) + (insert "..") + (goto-char 35) + (insert "...........") + (goto-char 29) + (insert ".......") + (goto-char 75) + (widen) + (narrow-to-region 69 55) + (goto-char 67) + (delete-char 2) + (goto-char 66) + (delete-char 0) + (goto-char 62) + (delete-char 1) + (goto-char 61) + (delete-char 3) + (goto-char 63) + (insert ".") + (goto-char 56) + (insert ".....") + (goto-char 67) + (insert ".............") + (goto-char 76) + (delete-char 3) + (should + (equal + (test-overlay-regions) + '((2 . 90) + (3 . 90) + (3 . 90) + (3 . 99) + (3 . 117) + (3 . 117) + (3 . 120) + (9 . 118) + (13 . 102)))))) + +(ert-deftest overlay-autogenerated-test-10 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 16 60 nil nil nil) + (make-overlay 36 53 nil nil nil) + (make-overlay 44 39 nil t t) + (make-overlay 61 47 nil t t) + (make-overlay 58 39 nil nil t) + (make-overlay 23 54 nil nil t) + (make-overlay 65 59 nil t t) + (make-overlay 13 57 nil nil t) + (make-overlay 22 64 nil nil t) + (make-overlay 16 19 nil nil nil) + (make-overlay 16 1 nil nil t) + (make-overlay 28 21 nil t t) + (make-overlay 10 62 nil nil nil) + (make-overlay 12 18 nil nil t) + (make-overlay 15 5 nil nil t) + (make-overlay 36 31 nil nil t) + (goto-char 42) + (insert "...") + (goto-char 25) + (delete-char 28) + (goto-char 30) + (delete-char 10) + (goto-char 8) + (delete-char 9) + (goto-char 5) + (insert "........") + (goto-char 6) + (delete-char 2) + (goto-char 4) + (insert "") + (goto-char 21) + (insert ".............") + (goto-char 6) + (delete-char 33) + (goto-char 1) + (delete-char 1) + (goto-char 6) + (insert "..........") + (goto-char 8) + (insert "...........") + (goto-char 21) + (insert "........") + (goto-char 16) + (delete-char 18) + (goto-char 5) + (insert "...") + (goto-char 5) + (delete-char 8) + (goto-char 11) + (insert ".") + (goto-char 1) + (insert ".......") + (goto-char 9) + (delete-char 9) + (goto-char 5) + (insert "") + (goto-char 8) + (delete-char 0) + (goto-char 11) + (insert "..............") + (goto-char 12) + (insert "") + (goto-char 11) + (delete-char 8) + (goto-char 7) + (delete-char 3) + (goto-char 5) + (delete-char 3) + (goto-char 1) + (delete-char 8) + (goto-char 1) + (insert "....") + (goto-char 1) + (insert "..") + (goto-char 7) + (insert "...") + (goto-char 8) + (widen) + (narrow-to-region 9 11) + (goto-char 11) + (delete-char 0) + (should + (equal + (test-overlay-regions) + '((1 . 10) + (1 . 10) + (1 . 10) + (1 . 10) + (1 . 10) + (1 . 12) + (1 . 12) + (1 . 12) + (10 . 10) + (10 . 10) + (10 . 12)))))) + +(ert-deftest overlay-autogenerated-test-11 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 33 18 nil nil nil) + (make-overlay 56 38 nil t nil) + (make-overlay 2 45 nil nil t) + (make-overlay 19 55 nil nil t) + (make-overlay 28 42 nil t t) + (make-overlay 50 29 nil t nil) + (make-overlay 40 63 nil nil nil) + (make-overlay 13 2 nil nil t) + (make-overlay 26 7 nil t t) + (make-overlay 22 25 nil nil nil) + (make-overlay 14 14 nil t nil) + (make-overlay 15 39 nil t t) + (make-overlay 51 22 nil t t) + (make-overlay 58 5 nil t nil) + (make-overlay 16 10 nil nil nil) + (make-overlay 32 33 nil t nil) + (goto-char 40) + (delete-char 20) + (goto-char 45) + (delete-char 0) + (goto-char 6) + (insert "..") + (goto-char 45) + (insert "...") + (goto-char 26) + (insert "...............") + (goto-char 27) + (insert "...........") + (goto-char 38) + (insert "......") + (goto-char 62) + (insert "...............") + (goto-char 18) + (insert "...........") + (goto-char 99) + (widen) + (narrow-to-region 37 17) + (goto-char 29) + (delete-char 2) + (goto-char 28) + (delete-char 2) + (goto-char 17) + (insert ".....") + (goto-char 21) + (widen) + (narrow-to-region 34 96) + (goto-char 44) + (delete-char 22) + (goto-char 39) + (insert "..") + (goto-char 53) + (insert "...............") + (goto-char 58) + (insert ".............") + (goto-char 93) + (insert ".........") + (goto-char 78) + (widen) + (narrow-to-region 27 104) + (goto-char 93) + (delete-char 11) + (goto-char 59) + (insert "....") + (goto-char 59) + (insert "..............") + (goto-char 74) + (delete-char 5) + (goto-char 70) + (insert ".") + (goto-char 37) + (insert "...........") + (goto-char 34) + (delete-char 46) + (goto-char 49) + (insert "......") + (goto-char 55) + (insert "...") + (goto-char 42) + (insert "...") + (goto-char 70) + (delete-char 8) + (goto-char 48) + (delete-char 28) + (should + (equal + (test-overlay-regions) + '((2 . 62) + (5 . 62) + (9 . 34) + (22 . 61) + (33 . 55) + (33 . 62) + (34 . 34) + (34 . 62)))))) + +(ert-deftest overlay-autogenerated-test-12 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 18 50 nil nil nil) + (make-overlay 63 3 nil nil t) + (make-overlay 44 20 nil t t) + (make-overlay 58 38 nil nil t) + (make-overlay 3 17 nil t nil) + (make-overlay 31 62 nil t nil) + (make-overlay 12 17 nil t nil) + (make-overlay 17 52 nil nil nil) + (make-overlay 9 35 nil nil nil) + (make-overlay 17 38 nil nil nil) + (make-overlay 53 54 nil nil t) + (make-overlay 65 34 nil t nil) + (make-overlay 12 33 nil t nil) + (make-overlay 54 58 nil nil nil) + (make-overlay 42 26 nil t nil) + (make-overlay 2 4 nil t nil) + (goto-char 4) + (delete-char 26) + (goto-char 39) + (insert ".") + (goto-char 2) + (delete-char 14) + (goto-char 16) + (widen) + (narrow-to-region 19 1) + (goto-char 7) + (delete-char 9) + (goto-char 6) + (insert ".........") + (goto-char 6) + (insert "..........") + (goto-char 16) + (insert ".............") + (goto-char 36) + (delete-char 1) + (goto-char 4) + (insert "..........") + (goto-char 49) + (delete-char 2) + (goto-char 16) + (insert "............") + (goto-char 52) + (widen) + (narrow-to-region 36 38) + (goto-char 37) + (delete-char 1) + (goto-char 37) + (insert ".............") + (goto-char 46) + (insert ".") + (goto-char 40) + (delete-char 5) + (goto-char 45) + (delete-char 0) + (goto-char 46) + (delete-char 0) + (goto-char 40) + (insert "..........") + (goto-char 39) + (delete-char 4) + (goto-char 39) + (delete-char 3) + (goto-char 40) + (widen) + (narrow-to-region 8 9) + (goto-char 8) + (delete-char 1) + (goto-char 8) + (delete-char 0) + (goto-char 8) + (widen) + (narrow-to-region 45 15) + (goto-char 40) + (insert "...............") + (goto-char 29) + (delete-char 7) + (goto-char 30) + (delete-char 6) + (goto-char 21) + (delete-char 9) + (goto-char 22) + (insert "...............") + (goto-char 51) + (insert "..............") + (should + (equal + (test-overlay-regions) + '((2 . 92) + (2 . 92) + (2 . 93) + (2 . 96) + (2 . 97) + (2 . 99)))))) + +(ert-deftest overlay-autogenerated-test-13 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 18 30 nil t t) + (make-overlay 54 37 nil nil t) + (make-overlay 16 61 nil nil t) + (make-overlay 58 7 nil nil t) + (make-overlay 27 39 nil nil t) + (make-overlay 39 31 nil nil t) + (make-overlay 11 47 nil nil nil) + (make-overlay 47 40 nil t t) + (make-overlay 27 18 nil nil nil) + (make-overlay 33 26 nil nil t) + (make-overlay 55 4 nil t t) + (make-overlay 62 50 nil t t) + (make-overlay 47 65 nil t t) + (make-overlay 17 23 nil nil t) + (make-overlay 30 31 nil t nil) + (make-overlay 10 37 nil t nil) + (goto-char 8) + (delete-char 6) + (goto-char 56) + (delete-char 0) + (goto-char 28) + (insert ".........") + (goto-char 19) + (insert "..............") + (goto-char 4) + (delete-char 28) + (goto-char 49) + (delete-char 4) + (goto-char 2) + (insert "............") + (goto-char 10) + (delete-char 37) + (goto-char 19) + (delete-char 2) + (goto-char 20) + (delete-char 0) + (goto-char 16) + (insert "..") + (goto-char 8) + (widen) + (narrow-to-region 12 3) + (goto-char 10) + (delete-char 2) + (goto-char 9) + (insert "..") + (goto-char 12) + (insert "...............") + (goto-char 25) + (insert ".....") + (goto-char 10) + (widen) + (narrow-to-region 42 18) + (goto-char 20) + (insert ".......") + (goto-char 18) + (insert ".........") + (goto-char 55) + (delete-char 3) + (goto-char 48) + (insert ".......") + (goto-char 52) + (delete-char 6) + (goto-char 45) + (delete-char 11) + (goto-char 27) + (delete-char 13) + (goto-char 22) + (insert "...........") + (goto-char 19) + (delete-char 15) + (goto-char 20) + (delete-char 0) + (goto-char 23) + (widen) + (narrow-to-region 12 25) + (goto-char 16) + (insert "..........") + (goto-char 25) + (widen) + (narrow-to-region 2 38) + (goto-char 34) + (delete-char 0) + (goto-char 31) + (insert "...............") + (should + (equal + (test-overlay-regions) + '((12 . 12) + (12 . 12) + (12 . 12) + (12 . 12) + (12 . 53) + (12 . 53) + (12 . 53) + (12 . 53) + (12 . 53) + (12 . 53) + (12 . 55)))))) + +(ert-deftest overlay-autogenerated-test-14 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 29 37 nil t nil) + (make-overlay 15 44 nil nil nil) + (make-overlay 31 34 nil nil t) + (make-overlay 35 33 nil t t) + (make-overlay 4 27 nil t t) + (make-overlay 37 5 nil nil t) + (make-overlay 58 19 nil nil t) + (make-overlay 57 47 nil nil t) + (make-overlay 49 5 nil t t) + (make-overlay 21 59 nil t t) + (make-overlay 42 33 nil t nil) + (make-overlay 22 16 nil t t) + (make-overlay 9 51 nil t nil) + (make-overlay 20 24 nil nil t) + (make-overlay 21 7 nil t t) + (make-overlay 58 52 nil t t) + (goto-char 39) + (widen) + (narrow-to-region 55 54) + (goto-char 54) + (insert ".............") + (goto-char 55) + (insert "............") + (goto-char 66) + (delete-char 10) + (goto-char 62) + (insert "...............") + (goto-char 82) + (delete-char 2) + (goto-char 82) + (delete-char 0) + (goto-char 76) + (insert "..............") + (goto-char 60) + (insert ".............") + (goto-char 71) + (insert "...............") + (goto-char 122) + (delete-char 0) + (goto-char 93) + (delete-char 3) + (goto-char 108) + (delete-char 1) + (goto-char 121) + (insert "........") + (goto-char 92) + (insert "") + (goto-char 103) + (insert "..........") + (goto-char 85) + (delete-char 13) + (goto-char 116) + (delete-char 7) + (goto-char 103) + (widen) + (narrow-to-region 60 27) + (goto-char 28) + (delete-char 16) + (goto-char 35) + (insert ".......") + (goto-char 47) + (insert "........") + (goto-char 38) + (delete-char 1) + (goto-char 43) + (insert "..........") + (goto-char 59) + (insert "........") + (goto-char 57) + (insert "........") + (goto-char 36) + (insert "...........") + (goto-char 82) + (delete-char 11) + (goto-char 67) + (insert "..........") + (goto-char 46) + (delete-char 1) + (goto-char 47) + (insert "......") + (goto-char 69) + (delete-char 7) + (should + (equal + (test-overlay-regions) + '((5 . 28) + (5 . 33) + (9 . 35) + (15 . 28) + (19 . 154) + (21 . 155) + (28 . 28) + (28 . 28) + (28 . 28) + (28 . 28) + (31 . 153) + (58 . 154)))))) + +(ert-deftest overlay-autogenerated-test-15 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 3 19 nil t t) + (make-overlay 11 18 nil t nil) + (make-overlay 28 51 nil nil t) + (make-overlay 29 15 nil t t) + (make-overlay 46 57 nil t t) + (make-overlay 26 24 nil nil nil) + (make-overlay 29 43 nil nil nil) + (make-overlay 54 29 nil nil nil) + (make-overlay 34 52 nil t nil) + (make-overlay 10 32 nil nil nil) + (make-overlay 28 34 nil nil t) + (make-overlay 11 43 nil nil nil) + (make-overlay 18 50 nil t t) + (make-overlay 28 39 nil nil nil) + (make-overlay 62 62 nil t t) + (make-overlay 30 62 nil t nil) + (goto-char 30) + (widen) + (narrow-to-region 6 22) + (goto-char 9) + (insert "..") + (goto-char 12) + (insert ".............") + (goto-char 29) + (insert "..............") + (goto-char 47) + (insert "........") + (goto-char 46) + (insert ".............") + (goto-char 55) + (insert "..........") + (goto-char 62) + (insert "...............") + (goto-char 47) + (delete-char 49) + (goto-char 11) + (insert "...........") + (goto-char 40) + (delete-char 1) + (goto-char 27) + (insert "..............") + (goto-char 51) + (insert "......") + (goto-char 60) + (delete-char 10) + (goto-char 37) + (insert ".........") + (goto-char 69) + (insert ".") + (goto-char 36) + (insert "............") + (goto-char 75) + (insert ".............") + (goto-char 21) + (widen) + (narrow-to-region 44 21) + (goto-char 37) + (insert ".............") + (goto-char 55) + (widen) + (narrow-to-region 84 28) + (goto-char 58) + (widen) + (narrow-to-region 96 49) + (goto-char 62) + (delete-char 0) + (goto-char 72) + (delete-char 24) + (goto-char 61) + (widen) + (narrow-to-region 105 83) + (goto-char 96) + (widen) + (narrow-to-region 109 46) + (goto-char 95) + (delete-char 4) + (goto-char 81) + (insert ".") + (goto-char 51) + (delete-char 8) + (goto-char 52) + (insert ".") + (goto-char 60) + (delete-char 10) + (goto-char 50) + (insert "......") + (should + (equal + (test-overlay-regions) + '((3 . 81) + (23 . 88) + (66 . 99) + (69 . 81) + (78 . 85) + (81 . 106) + (84 . 85) + (85 . 90) + (85 . 95) + (85 . 99) + (85 . 107) + (85 . 110) + (86 . 118) + (90 . 108)))))) + +(ert-deftest overlay-autogenerated-test-16 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 3 55 nil t nil) + (make-overlay 45 47 nil nil nil) + (make-overlay 23 57 nil t t) + (make-overlay 64 55 nil nil nil) + (make-overlay 37 26 nil t t) + (make-overlay 29 38 nil nil t) + (make-overlay 33 3 nil t t) + (make-overlay 49 16 nil t nil) + (make-overlay 35 56 nil t t) + (make-overlay 9 39 nil nil nil) + (make-overlay 2 61 nil nil nil) + (make-overlay 59 26 nil nil t) + (make-overlay 5 50 nil t t) + (make-overlay 19 19 nil nil t) + (make-overlay 64 21 nil t nil) + (make-overlay 21 8 nil nil t) + (goto-char 17) + (insert ".....") + (goto-char 29) + (insert "............") + (goto-char 42) + (delete-char 38) + (goto-char 24) + (insert "") + (goto-char 9) + (delete-char 2) + (goto-char 20) + (insert "..") + (goto-char 27) + (delete-char 8) + (goto-char 25) + (delete-char 6) + (goto-char 8) + (delete-char 21) + (goto-char 9) + (insert "..............") + (goto-char 3) + (insert "....") + (goto-char 8) + (delete-char 18) + (goto-char 6) + (widen) + (narrow-to-region 5 8) + (goto-char 5) + (delete-char 3) + (goto-char 5) + (insert "...") + (goto-char 8) + (insert "..........") + (goto-char 5) + (insert "") + (goto-char 7) + (delete-char 8) + (goto-char 8) + (widen) + (narrow-to-region 2 2) + (goto-char 2) + (delete-char 0) + (goto-char 2) + (delete-char 0) + (goto-char 2) + (delete-char 0) + (goto-char 2) + (delete-char 0) + (goto-char 2) + (widen) + (narrow-to-region 10 3) + (goto-char 8) + (delete-char 2) + (goto-char 7) + (insert ".......") + (goto-char 8) + (delete-char 3) + (goto-char 12) + (insert "..") + (goto-char 9) + (delete-char 2) + (goto-char 7) + (insert "......") + (goto-char 15) + (insert "..........") + (goto-char 4) + (insert "........") + (should + (equal + (test-overlay-regions) + '((2 . 13) + (13 . 13) + (13 . 13) + (13 . 13) + (13 . 13) + (13 . 13) + (13 . 13) + (13 . 36) + (13 . 36) + (13 . 36) + (13 . 36)))))) + +(ert-deftest overlay-autogenerated-test-17 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 15 37 nil t nil) + (make-overlay 40 3 nil t t) + (make-overlay 61 19 nil t t) + (make-overlay 46 9 nil nil t) + (make-overlay 64 39 nil nil t) + (make-overlay 50 58 nil nil t) + (make-overlay 21 30 nil t nil) + (make-overlay 44 54 nil t nil) + (make-overlay 32 2 nil t nil) + (make-overlay 14 9 nil t t) + (make-overlay 41 40 nil t nil) + (make-overlay 17 26 nil t nil) + (make-overlay 57 50 nil t t) + (make-overlay 16 65 nil nil t) + (make-overlay 13 61 nil t t) + (make-overlay 39 64 nil nil t) + (goto-char 37) + (widen) + (narrow-to-region 12 1) + (goto-char 12) + (insert "......") + (goto-char 8) + (delete-char 4) + (goto-char 11) + (delete-char 3) + (goto-char 6) + (insert ".....") + (goto-char 6) + (widen) + (narrow-to-region 53 48) + (goto-char 48) + (delete-char 5) + (goto-char 48) + (widen) + (narrow-to-region 59 58) + (goto-char 59) + (delete-char 0) + (goto-char 58) + (insert "...") + (goto-char 60) + (insert "...............") + (goto-char 58) + (insert ".............") + (goto-char 67) + (insert ".....") + (goto-char 73) + (insert "") + (goto-char 68) + (insert ".....") + (goto-char 64) + (insert "....") + (goto-char 62) + (insert "..") + (goto-char 91) + (insert "..........") + (goto-char 80) + (insert "............") + (goto-char 100) + (delete-char 21) + (goto-char 74) + (insert "...") + (goto-char 60) + (delete-char 30) + (goto-char 64) + (widen) + (narrow-to-region 71 23) + (goto-char 53) + (delete-char 11) + (goto-char 23) + (delete-char 21) + (goto-char 39) + (delete-char 0) + (goto-char 35) + (insert "") + (goto-char 35) + (insert ".........") + (goto-char 30) + (insert "...........") + (goto-char 35) + (insert "..") + (goto-char 37) + (delete-char 1) + (goto-char 28) + (delete-char 3) + (should + (equal + (test-overlay-regions) + '((13 . 27) + (17 . 67) + (20 . 71) + (23 . 23) + (23 . 24) + (23 . 67) + (23 . 70) + (23 . 70) + (27 . 41) + (28 . 41) + (28 . 41)))))) + +(ert-deftest overlay-autogenerated-test-18 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 43 52 nil nil t) + (make-overlay 27 29 nil nil t) + (make-overlay 24 18 nil nil nil) + (make-overlay 39 52 nil nil nil) + (make-overlay 33 62 nil t t) + (make-overlay 16 7 nil t nil) + (make-overlay 47 39 nil nil t) + (make-overlay 59 41 nil nil nil) + (make-overlay 22 55 nil nil t) + (make-overlay 60 16 nil t t) + (make-overlay 55 20 nil nil t) + (make-overlay 25 12 nil nil t) + (make-overlay 26 2 nil nil t) + (make-overlay 17 35 nil nil t) + (make-overlay 46 41 nil t nil) + (make-overlay 57 53 nil t t) + (goto-char 52) + (insert "") + (goto-char 4) + (delete-char 21) + (goto-char 17) + (insert "") + (goto-char 35) + (insert "...............") + (goto-char 8) + (insert "...............") + (goto-char 9) + (insert "........") + (goto-char 73) + (delete-char 9) + (goto-char 62) + (insert "...............") + (goto-char 27) + (widen) + (narrow-to-region 34 84) + (goto-char 81) + (insert "...........") + (goto-char 48) + (insert "...") + (goto-char 74) + (insert ".......") + (goto-char 41) + (widen) + (narrow-to-region 37 105) + (goto-char 75) + (insert "...............") + (goto-char 47) + (insert "..........") + (goto-char 99) + (delete-char 13) + (goto-char 105) + (delete-char 4) + (goto-char 94) + (delete-char 5) + (goto-char 96) + (insert "..............") + (goto-char 74) + (insert "") + (goto-char 121) + (insert "...") + (goto-char 102) + (insert "...") + (goto-char 64) + (insert "......") + (goto-char 67) + (insert "...") + (goto-char 95) + (delete-char 19) + (goto-char 37) + (insert "..........") + (goto-char 50) + (widen) + (narrow-to-region 67 96) + (goto-char 88) + (insert "..........") + (goto-char 91) + (insert ".............") + (goto-char 70) + (delete-char 8) + (goto-char 111) + (widen) + (narrow-to-region 72 103) + (goto-char 101) + (insert "...............") + (should + (equal + (test-overlay-regions) + '((4 . 119) + (4 . 119) + (4 . 162) + (35 . 162) + (51 . 78) + (53 . 162) + (55 . 78) + (79 . 162)))))) + +(ert-deftest overlay-autogenerated-test-19 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 19 31 nil t t) + (make-overlay 40 5 nil nil nil) + (make-overlay 13 41 nil t t) + (make-overlay 41 43 nil nil t) + (make-overlay 7 60 nil t nil) + (make-overlay 40 23 nil t nil) + (make-overlay 32 15 nil t t) + (make-overlay 12 45 nil nil nil) + (make-overlay 18 1 nil nil nil) + (make-overlay 58 32 nil t t) + (make-overlay 30 3 nil t t) + (make-overlay 43 61 nil t nil) + (make-overlay 54 57 nil nil t) + (make-overlay 34 14 nil t t) + (make-overlay 26 49 nil nil t) + (make-overlay 54 49 nil nil t) + (goto-char 28) + (insert "........") + (goto-char 32) + (insert "...........") + (goto-char 78) + (delete-char 6) + (goto-char 37) + (delete-char 0) + (goto-char 49) + (insert ".........") + (goto-char 40) + (widen) + (narrow-to-region 8 30) + (goto-char 20) + (delete-char 4) + (goto-char 23) + (delete-char 1) + (goto-char 10) + (insert ".") + (goto-char 22) + (delete-char 2) + (goto-char 22) + (insert "......") + (goto-char 17) + (insert "..........") + (goto-char 34) + (delete-char 0) + (goto-char 21) + (insert "............") + (goto-char 45) + (delete-char 7) + (goto-char 39) + (insert "...............") + (goto-char 29) + (insert "........") + (goto-char 9) + (delete-char 3) + (goto-char 63) + (delete-char 1) + (goto-char 33) + (insert "........") + (goto-char 16) + (delete-char 36) + (goto-char 20) + (delete-char 2) + (goto-char 28) + (delete-char 0) + (goto-char 24) + (insert "...........") + (goto-char 43) + (insert "..........") + (goto-char 30) + (delete-char 1) + (goto-char 40) + (delete-char 13) + (goto-char 22) + (delete-char 19) + (goto-char 10) + (delete-char 8) + (goto-char 14) + (delete-char 0) + (goto-char 12) + (delete-char 2) + (goto-char 11) + (delete-char 0) + (should + (equal + (test-overlay-regions) + '((1 . 12) + (3 . 40) + (5 . 50) + (7 . 69) + (10 . 42) + (10 . 44) + (10 . 51) + (10 . 55)))))) + +(ert-deftest overlay-autogenerated-test-20 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 44 42 nil t t) + (make-overlay 47 1 nil nil nil) + (make-overlay 24 48 nil nil nil) + (make-overlay 62 50 nil nil t) + (make-overlay 54 38 nil nil nil) + (make-overlay 3 9 nil nil nil) + (make-overlay 61 28 nil t nil) + (make-overlay 33 33 nil nil t) + (make-overlay 37 37 nil t nil) + (make-overlay 20 13 nil nil t) + (make-overlay 54 36 nil t nil) + (make-overlay 18 58 nil nil t) + (make-overlay 55 3 nil nil t) + (make-overlay 23 21 nil t t) + (make-overlay 47 55 nil t t) + (make-overlay 50 12 nil nil nil) + (goto-char 11) + (delete-char 46) + (goto-char 7) + (delete-char 3) + (goto-char 14) + (delete-char 1) + (goto-char 14) + (insert "......") + (goto-char 14) + (delete-char 4) + (goto-char 12) + (widen) + (narrow-to-region 11 12) + (goto-char 11) + (insert "...") + (goto-char 13) + (delete-char 1) + (goto-char 14) + (insert ".") + (goto-char 13) + (delete-char 2) + (goto-char 11) + (delete-char 2) + (goto-char 11) + (insert "") + (goto-char 11) + (delete-char 0) + (goto-char 11) + (delete-char 0) + (goto-char 11) + (delete-char 0) + (goto-char 11) + (insert ".") + (goto-char 11) + (insert ".") + (goto-char 12) + (insert "......") + (goto-char 14) + (delete-char 2) + (goto-char 11) + (delete-char 2) + (goto-char 14) + (insert "............") + (goto-char 19) + (insert "..............") + (goto-char 29) + (insert ".....") + (goto-char 42) + (delete-char 1) + (goto-char 22) + (insert ".....") + (goto-char 19) + (insert "..............") + (goto-char 42) + (insert ".....") + (goto-char 63) + (widen) + (narrow-to-region 26 42) + (goto-char 36) + (insert "..........") + (goto-char 40) + (delete-char 11) + (goto-char 26) + (delete-char 13) + (goto-char 28) + (delete-char 0) + (should + (equal + (test-overlay-regions) + '((8 . 56)))))) + +(ert-deftest overlay-autogenerated-test-21 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 65 15 nil nil nil) + (make-overlay 52 31 nil nil nil) + (make-overlay 12 51 nil t t) + (make-overlay 42 20 nil nil t) + (make-overlay 51 48 nil nil nil) + (make-overlay 59 28 nil t t) + (make-overlay 51 53 nil t nil) + (make-overlay 50 59 nil nil t) + (make-overlay 24 40 nil t nil) + (make-overlay 51 61 nil nil nil) + (make-overlay 12 58 nil nil t) + (make-overlay 64 17 nil t t) + (make-overlay 26 38 nil t t) + (make-overlay 23 36 nil nil nil) + (make-overlay 57 50 nil nil nil) + (make-overlay 42 15 nil nil t) + (goto-char 14) + (insert "............") + (goto-char 37) + (insert ".") + (goto-char 73) + (insert "..........") + (goto-char 17) + (delete-char 31) + (goto-char 21) + (delete-char 35) + (goto-char 9) + (delete-char 0) + (goto-char 7) + (delete-char 2) + (goto-char 1) + (insert "") + (goto-char 5) + (insert ".......") + (goto-char 8) + (insert "....") + (goto-char 27) + (delete-char 0) + (goto-char 10) + (insert ".............") + (goto-char 24) + (delete-char 16) + (goto-char 14) + (insert ".............") + (goto-char 25) + (delete-char 11) + (goto-char 3) + (insert "........") + (goto-char 38) + (insert "............") + (goto-char 41) + (insert "..............") + (goto-char 56) + (delete-char 3) + (goto-char 15) + (widen) + (narrow-to-region 16 53) + (goto-char 19) + (widen) + (narrow-to-region 18 33) + (goto-char 32) + (insert "......") + (goto-char 38) + (delete-char 1) + (goto-char 19) + (widen) + (narrow-to-region 11 11) + (goto-char 11) + (insert ".........") + (goto-char 11) + (insert ".........") + (goto-char 20) + (widen) + (narrow-to-region 22 69) + (goto-char 49) + (insert ".........") + (goto-char 54) + (delete-char 22) + (goto-char 44) + (insert "........") + (goto-char 40) + (delete-char 7) + (goto-char 29) + (delete-char 22) + (should + (equal + (test-overlay-regions) + '((33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33) + (33 . 33)))))) + +(ert-deftest overlay-autogenerated-test-22 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 12 14 nil nil t) + (make-overlay 54 7 nil nil t) + (make-overlay 8 3 nil nil nil) + (make-overlay 42 32 nil nil nil) + (make-overlay 10 27 nil t t) + (make-overlay 50 28 nil t t) + (make-overlay 39 35 nil nil nil) + (make-overlay 12 4 nil t t) + (make-overlay 29 54 nil nil nil) + (make-overlay 14 52 nil t t) + (make-overlay 9 15 nil t nil) + (make-overlay 44 11 nil nil nil) + (make-overlay 46 29 nil t t) + (make-overlay 40 58 nil t t) + (make-overlay 40 61 nil t nil) + (make-overlay 13 59 nil nil t) + (goto-char 32) + (insert ".............") + (goto-char 25) + (delete-char 10) + (goto-char 3) + (insert ".............") + (goto-char 33) + (delete-char 32) + (goto-char 39) + (widen) + (narrow-to-region 41 46) + (goto-char 43) + (delete-char 2) + (goto-char 42) + (delete-char 2) + (goto-char 42) + (insert "...") + (goto-char 43) + (delete-char 1) + (goto-char 42) + (widen) + (narrow-to-region 8 46) + (goto-char 25) + (delete-char 7) + (goto-char 12) + (delete-char 10) + (goto-char 23) + (insert "...............") + (goto-char 41) + (delete-char 3) + (goto-char 17) + (insert ".........") + (goto-char 37) + (insert "...............") + (goto-char 53) + (delete-char 7) + (goto-char 53) + (delete-char 0) + (goto-char 42) + (widen) + (narrow-to-region 20 54) + (goto-char 20) + (delete-char 28) + (goto-char 23) + (insert "..........") + (goto-char 30) + (insert "......") + (goto-char 26) + (delete-char 1) + (goto-char 27) + (widen) + (narrow-to-region 40 37) + (goto-char 37) + (insert ".....") + (goto-char 41) + (widen) + (narrow-to-region 13 37) + (goto-char 29) + (insert "...........") + (goto-char 33) + (delete-char 7) + (goto-char 33) + (delete-char 8) + (goto-char 20) + (insert "") + (goto-char 23) + (delete-char 7) + (goto-char 14) + (widen) + (narrow-to-region 33 33) + (should + (equal + (test-overlay-regions) + '((15 . 39) + (16 . 38) + (16 . 39)))))) + +(ert-deftest overlay-autogenerated-test-23 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 51 32 nil t t) + (make-overlay 13 61 nil t nil) + (make-overlay 47 19 nil nil t) + (make-overlay 11 30 nil nil nil) + (make-overlay 50 26 nil t t) + (make-overlay 64 13 nil t t) + (make-overlay 29 8 nil t t) + (make-overlay 25 42 nil t t) + (make-overlay 33 28 nil t t) + (make-overlay 54 7 nil nil nil) + (make-overlay 30 59 nil nil nil) + (make-overlay 65 50 nil t t) + (make-overlay 64 15 nil t nil) + (make-overlay 16 35 nil nil nil) + (make-overlay 40 36 nil nil t) + (make-overlay 31 35 nil t nil) + (goto-char 61) + (insert "......") + (goto-char 55) + (delete-char 2) + (goto-char 20) + (insert "..............") + (goto-char 56) + (insert "............") + (goto-char 48) + (delete-char 6) + (goto-char 9) + (delete-char 54) + (goto-char 20) + (delete-char 2) + (goto-char 16) + (delete-char 12) + (goto-char 18) + (insert ".............") + (goto-char 24) + (delete-char 7) + (goto-char 5) + (delete-char 2) + (goto-char 1) + (insert ".......") + (goto-char 1) + (insert ".......") + (goto-char 33) + (insert "") + (goto-char 4) + (insert "..") + (goto-char 5) + (widen) + (narrow-to-region 17 4) + (goto-char 13) + (insert ".") + (goto-char 8) + (insert "............") + (goto-char 9) + (delete-char 3) + (goto-char 4) + (widen) + (narrow-to-region 32 32) + (goto-char 32) + (delete-char 0) + (goto-char 32) + (delete-char 0) + (goto-char 32) + (delete-char 0) + (goto-char 32) + (insert "...............") + (goto-char 43) + (delete-char 4) + (goto-char 32) + (delete-char 1) + (goto-char 40) + (widen) + (narrow-to-region 33 19) + (goto-char 27) + (insert "........") + (goto-char 38) + (delete-char 2) + (goto-char 26) + (insert "") + (goto-char 33) + (delete-char 1) + (goto-char 27) + (insert ".") + (should + (equal + (test-overlay-regions) + '((38 . 56)))))) + +(ert-deftest overlay-autogenerated-test-24 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 63 8 nil t t) + (make-overlay 10 13 nil nil t) + (make-overlay 40 38 nil nil nil) + (make-overlay 21 34 nil t t) + (make-overlay 55 29 nil nil nil) + (make-overlay 36 65 nil t t) + (make-overlay 29 12 nil t nil) + (make-overlay 41 3 nil nil t) + (make-overlay 20 9 nil t t) + (make-overlay 52 42 nil t t) + (make-overlay 21 56 nil nil t) + (make-overlay 25 65 nil nil nil) + (make-overlay 38 4 nil t t) + (make-overlay 48 23 nil t t) + (make-overlay 52 9 nil nil t) + (make-overlay 48 19 nil nil nil) + (goto-char 43) + (delete-char 8) + (goto-char 30) + (delete-char 16) + (goto-char 7) + (insert "...") + (goto-char 14) + (delete-char 5) + (goto-char 36) + (delete-char 0) + (goto-char 9) + (insert "...............") + (goto-char 13) + (delete-char 17) + (goto-char 16) + (delete-char 2) + (goto-char 9) + (insert "") + (goto-char 11) + (delete-char 5) + (goto-char 18) + (insert "........") + (goto-char 15) + (insert "....") + (goto-char 16) + (delete-char 14) + (goto-char 20) + (insert ".") + (goto-char 25) + (delete-char 1) + (goto-char 14) + (delete-char 14) + (goto-char 3) + (delete-char 7) + (goto-char 3) + (delete-char 4) + (goto-char 1) + (insert "...........") + (goto-char 9) + (insert ".......") + (goto-char 5) + (delete-char 7) + (goto-char 12) + (insert ".........") + (goto-char 2) + (delete-char 4) + (goto-char 3) + (widen) + (narrow-to-region 14 6) + (goto-char 9) + (insert "..........") + (goto-char 13) + (delete-char 8) + (goto-char 7) + (delete-char 7) + (goto-char 7) + (insert "..") + (goto-char 9) + (insert ".............") + (goto-char 9) + (insert "..........") + (goto-char 21) + (insert "...............") + (goto-char 42) + (insert ".........") + (should + (equal + (test-overlay-regions) + 'nil)))) + +(ert-deftest overlay-autogenerated-test-25 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 24 8 nil nil t) + (make-overlay 41 16 nil t nil) + (make-overlay 3 16 nil nil nil) + (make-overlay 26 42 nil nil nil) + (make-overlay 32 45 nil nil t) + (make-overlay 34 19 nil nil nil) + (make-overlay 37 54 nil nil t) + (make-overlay 44 34 nil t nil) + (make-overlay 49 40 nil t t) + (make-overlay 29 34 nil t nil) + (make-overlay 54 16 nil t t) + (make-overlay 29 4 nil t nil) + (make-overlay 44 57 nil nil nil) + (make-overlay 5 32 nil nil nil) + (make-overlay 12 33 nil nil t) + (make-overlay 38 29 nil t nil) + (goto-char 12) + (delete-char 53) + (goto-char 1) + (delete-char 6) + (goto-char 5) + (widen) + (narrow-to-region 6 1) + (goto-char 6) + (insert "......") + (goto-char 10) + (insert "...............") + (goto-char 17) + (delete-char 5) + (goto-char 7) + (insert ".....") + (goto-char 8) + (insert "...............") + (goto-char 4) + (insert ".....") + (goto-char 44) + (widen) + (narrow-to-region 18 11) + (goto-char 15) + (delete-char 1) + (goto-char 17) + (delete-char 0) + (goto-char 13) + (delete-char 3) + (goto-char 14) + (insert "..") + (goto-char 16) + (insert "..") + (goto-char 15) + (delete-char 3) + (goto-char 13) + (delete-char 0) + (goto-char 14) + (insert "..........") + (goto-char 19) + (insert ".") + (goto-char 23) + (delete-char 1) + (goto-char 12) + (widen) + (narrow-to-region 23 40) + (goto-char 35) + (insert "....") + (goto-char 33) + (insert "..........") + (goto-char 37) + (delete-char 16) + (goto-char 37) + (delete-char 0) + (goto-char 23) + (widen) + (narrow-to-region 30 8) + (goto-char 29) + (delete-char 0) + (goto-char 15) + (delete-char 15) + (goto-char 9) + (insert "...........") + (goto-char 9) + (delete-char 1) + (goto-char 22) + (delete-char 3) + (goto-char 10) + (insert ".........") + (should + (equal + (test-overlay-regions) + '((1 . 30) + (1 . 30) + (1 . 30) + (2 . 53) + (30 . 30) + (30 . 30) + (30 . 30) + (30 . 30) + (30 . 30) + (30 . 30) + (30 . 30) + (30 . 53) + (30 . 53) + (30 . 53)))))) + +(ert-deftest overlay-autogenerated-test-26 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 60 59 nil t nil) + (make-overlay 18 11 nil nil t) + (make-overlay 4 44 nil nil nil) + (make-overlay 7 22 nil nil nil) + (make-overlay 54 50 nil t nil) + (make-overlay 59 28 nil nil nil) + (make-overlay 49 23 nil nil t) + (make-overlay 21 5 nil t nil) + (make-overlay 17 39 nil t nil) + (make-overlay 16 14 nil nil nil) + (make-overlay 50 26 nil nil nil) + (make-overlay 37 14 nil nil nil) + (make-overlay 6 59 nil nil t) + (make-overlay 30 17 nil nil t) + (make-overlay 17 34 nil nil t) + (make-overlay 7 22 nil t nil) + (goto-char 35) + (delete-char 25) + (goto-char 30) + (delete-char 7) + (goto-char 25) + (widen) + (narrow-to-region 3 19) + (goto-char 6) + (insert ".........") + (goto-char 21) + (insert "...............") + (goto-char 12) + (insert ".............") + (goto-char 34) + (widen) + (narrow-to-region 64 37) + (goto-char 62) + (insert ".............") + (goto-char 50) + (widen) + (narrow-to-region 72 38) + (goto-char 66) + (insert "") + (goto-char 54) + (insert "...") + (goto-char 70) + (delete-char 4) + (goto-char 49) + (delete-char 13) + (goto-char 38) + (insert "....") + (goto-char 46) + (insert ".") + (goto-char 43) + (widen) + (narrow-to-region 74 53) + (goto-char 60) + (delete-char 10) + (goto-char 53) + (insert "..............") + (goto-char 72) + (insert "............") + (goto-char 87) + (delete-char 2) + (goto-char 73) + (insert "............") + (goto-char 81) + (insert "........") + (goto-char 106) + (insert "...") + (goto-char 95) + (widen) + (narrow-to-region 77 39) + (goto-char 43) + (insert "..........") + (goto-char 40) + (insert "...............") + (goto-char 101) + (insert "") + (goto-char 53) + (insert "....") + (goto-char 79) + (delete-char 21) + (goto-char 85) + (insert "........") + (goto-char 52) + (delete-char 41) + (goto-char 43) + (insert ".....") + (should + (equal + (test-overlay-regions) + '((4 . 90) + (5 . 57) + (6 . 90) + (29 . 57) + (29 . 57) + (33 . 57)))))) + +(ert-deftest overlay-autogenerated-test-27 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 20 12 nil t nil) + (make-overlay 3 10 nil t t) + (make-overlay 11 53 nil t nil) + (make-overlay 59 3 nil t nil) + (make-overlay 28 19 nil t t) + (make-overlay 16 30 nil t t) + (make-overlay 39 19 nil t t) + (make-overlay 33 50 nil t nil) + (make-overlay 36 54 nil nil nil) + (make-overlay 42 59 nil nil nil) + (make-overlay 30 48 nil t nil) + (make-overlay 20 13 nil nil t) + (make-overlay 63 48 nil t nil) + (make-overlay 48 12 nil t t) + (make-overlay 64 50 nil nil nil) + (make-overlay 7 7 nil nil nil) + (goto-char 20) + (widen) + (narrow-to-region 21 54) + (goto-char 40) + (insert "..........") + (goto-char 21) + (delete-char 2) + (goto-char 35) + (widen) + (narrow-to-region 70 11) + (goto-char 45) + (insert "...............") + (goto-char 74) + (insert ".") + (goto-char 28) + (widen) + (narrow-to-region 77 67) + (goto-char 72) + (insert "..........") + (goto-char 85) + (delete-char 1) + (goto-char 82) + (widen) + (narrow-to-region 83 86) + (goto-char 83) + (delete-char 0) + (goto-char 86) + (delete-char 0) + (goto-char 86) + (insert "...........") + (goto-char 97) + (insert ".......") + (goto-char 103) + (widen) + (narrow-to-region 44 68) + (goto-char 49) + (insert "..") + (goto-char 65) + (insert ".............") + (goto-char 59) + (delete-char 0) + (goto-char 57) + (insert "........") + (goto-char 55) + (delete-char 30) + (goto-char 45) + (insert "...............") + (goto-char 44) + (insert "") + (goto-char 62) + (insert "............") + (goto-char 63) + (widen) + (narrow-to-region 12 5) + (goto-char 8) + (delete-char 4) + (goto-char 6) + (delete-char 0) + (goto-char 7) + (insert "..........") + (goto-char 15) + (delete-char 0) + (goto-char 16) + (insert "............") + (goto-char 20) + (insert ".........") + (goto-char 13) + (insert "..") + (goto-char 32) + (insert "..............") + (should + (equal + (test-overlay-regions) + '((3 . 55) + (3 . 173) + (7 . 7)))))) + +(ert-deftest overlay-autogenerated-test-28 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 59 48 nil t nil) + (make-overlay 59 4 nil nil t) + (make-overlay 45 35 nil t nil) + (make-overlay 13 18 nil t t) + (make-overlay 10 7 nil t t) + (make-overlay 9 8 nil nil nil) + (make-overlay 33 47 nil nil t) + (make-overlay 1 57 nil t nil) + (make-overlay 16 59 nil nil t) + (make-overlay 43 58 nil nil t) + (make-overlay 6 11 nil nil nil) + (make-overlay 59 7 nil t nil) + (make-overlay 3 57 nil t t) + (make-overlay 61 35 nil nil nil) + (make-overlay 57 8 nil nil nil) + (make-overlay 5 32 nil t nil) + (goto-char 18) + (insert "............") + (goto-char 43) + (delete-char 2) + (goto-char 38) + (delete-char 26) + (goto-char 42) + (insert ".....") + (goto-char 52) + (insert "..........") + (goto-char 45) + (delete-char 11) + (goto-char 33) + (insert "....") + (goto-char 23) + (delete-char 14) + (goto-char 33) + (widen) + (narrow-to-region 30 33) + (goto-char 30) + (delete-char 0) + (goto-char 30) + (insert "...........") + (goto-char 30) + (delete-char 7) + (goto-char 30) + (insert ".") + (goto-char 32) + (delete-char 4) + (goto-char 34) + (delete-char 0) + (goto-char 34) + (delete-char 0) + (goto-char 32) + (insert "...............") + (goto-char 46) + (insert ".........") + (goto-char 45) + (delete-char 3) + (goto-char 49) + (delete-char 2) + (goto-char 42) + (delete-char 2) + (goto-char 32) + (insert "..........") + (goto-char 47) + (insert "....") + (goto-char 59) + (insert ".......") + (goto-char 35) + (insert ".") + (goto-char 45) + (insert "..............") + (goto-char 37) + (insert "..") + (goto-char 80) + (insert ".....") + (goto-char 30) + (insert ".............") + (goto-char 102) + (insert "............") + (goto-char 113) + (insert "") + (goto-char 66) + (widen) + (narrow-to-region 47 38) + (should + (equal + (test-overlay-regions) + '((1 . 45) + (3 . 117) + (4 . 121) + (7 . 121) + (8 . 45) + (16 . 121) + (28 . 121) + (28 . 121) + (28 . 121)))))) + +(ert-deftest overlay-autogenerated-test-29 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 5 63 nil nil t) + (make-overlay 20 28 nil t t) + (make-overlay 58 53 nil t nil) + (make-overlay 4 57 nil t t) + (make-overlay 4 16 nil nil nil) + (make-overlay 33 26 nil t nil) + (make-overlay 9 32 nil t t) + (make-overlay 11 8 nil nil nil) + (make-overlay 59 35 nil nil t) + (make-overlay 15 25 nil t t) + (make-overlay 36 16 nil nil nil) + (make-overlay 8 37 nil nil nil) + (make-overlay 65 63 nil nil t) + (make-overlay 3 20 nil nil t) + (make-overlay 44 55 nil t t) + (make-overlay 45 25 nil t nil) + (goto-char 39) + (insert "...") + (goto-char 22) + (insert "........") + (goto-char 60) + (insert ".........") + (goto-char 17) + (insert "............") + (goto-char 13) + (widen) + (narrow-to-region 79 16) + (goto-char 19) + (delete-char 11) + (goto-char 25) + (insert "........") + (goto-char 61) + (insert "....") + (goto-char 45) + (widen) + (narrow-to-region 73 66) + (goto-char 71) + (insert "............") + (goto-char 81) + (delete-char 2) + (goto-char 73) + (insert "..........") + (goto-char 74) + (insert "............") + (goto-char 82) + (delete-char 7) + (goto-char 78) + (delete-char 18) + (goto-char 75) + (insert ".........") + (goto-char 66) + (insert ".........") + (goto-char 86) + (delete-char 12) + (goto-char 77) + (widen) + (narrow-to-region 23 55) + (goto-char 43) + (insert ".") + (goto-char 50) + (insert "..") + (goto-char 25) + (delete-char 18) + (goto-char 33) + (delete-char 7) + (goto-char 26) + (insert "........") + (goto-char 29) + (insert "...........") + (goto-char 33) + (insert "...") + (goto-char 40) + (insert "..........") + (goto-char 26) + (insert "") + (goto-char 35) + (insert ".") + (goto-char 59) + (insert ".") + (goto-char 51) + (insert "..") + (goto-char 59) + (insert ".............") + (should + (equal + (test-overlay-regions) + '((4 . 130) + (5 . 136) + (8 . 82) + (9 . 82) + (15 . 25) + (16 . 82) + (21 . 77) + (25 . 105) + (75 . 82)))))) + +(ert-deftest overlay-autogenerated-test-30 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 27 65 nil t t) + (make-overlay 39 51 nil t t) + (make-overlay 53 2 nil nil nil) + (make-overlay 3 17 nil nil t) + (make-overlay 35 4 nil nil t) + (make-overlay 65 53 nil t nil) + (make-overlay 8 21 nil t t) + (make-overlay 18 62 nil t t) + (make-overlay 42 59 nil nil t) + (make-overlay 12 37 nil t t) + (make-overlay 64 31 nil t nil) + (make-overlay 39 54 nil nil t) + (make-overlay 41 24 nil t nil) + (make-overlay 10 21 nil nil t) + (make-overlay 49 15 nil t nil) + (make-overlay 49 63 nil nil t) + (goto-char 43) + (insert "..........") + (goto-char 44) + (delete-char 29) + (goto-char 32) + (insert "..") + (goto-char 13) + (insert ".") + (goto-char 42) + (insert ".........") + (goto-char 39) + (insert "..........") + (goto-char 15) + (insert "............") + (goto-char 58) + (delete-char 9) + (goto-char 63) + (insert ".........") + (goto-char 49) + (insert ".") + (goto-char 28) + (delete-char 51) + (goto-char 12) + (delete-char 6) + (goto-char 20) + (delete-char 2) + (goto-char 7) + (widen) + (narrow-to-region 2 9) + (goto-char 5) + (insert "...............") + (goto-char 18) + (delete-char 1) + (goto-char 4) + (insert ".............") + (goto-char 13) + (delete-char 22) + (goto-char 12) + (insert "") + (goto-char 3) + (insert ".............") + (goto-char 22) + (insert "...............") + (goto-char 9) + (insert "....") + (goto-char 8) + (insert "...........") + (goto-char 6) + (delete-char 34) + (goto-char 21) + (insert "....") + (goto-char 14) + (insert ".....") + (goto-char 20) + (insert ".......") + (goto-char 34) + (widen) + (narrow-to-region 3 2) + (goto-char 3) + (delete-char 0) + (goto-char 2) + (insert "..............") + (goto-char 15) + (delete-char 2) + (goto-char 11) + (insert "......") + (should + (equal + (test-overlay-regions) + '((2 . 68)))))) + +(ert-deftest overlay-autogenerated-test-31 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 54 64 nil nil nil) + (make-overlay 49 12 nil nil t) + (make-overlay 40 12 nil t nil) + (make-overlay 17 38 nil nil nil) + (make-overlay 21 36 nil t t) + (make-overlay 8 38 nil t nil) + (make-overlay 50 22 nil t nil) + (make-overlay 65 15 nil nil t) + (make-overlay 57 60 nil t t) + (make-overlay 35 11 nil nil t) + (make-overlay 49 44 nil nil t) + (make-overlay 45 31 nil nil t) + (make-overlay 51 24 nil t t) + (make-overlay 20 14 nil nil nil) + (make-overlay 6 18 nil t t) + (make-overlay 25 3 nil nil nil) + (goto-char 18) + (delete-char 10) + (goto-char 36) + (delete-char 13) + (goto-char 8) + (delete-char 4) + (goto-char 2) + (delete-char 8) + (goto-char 12) + (delete-char 10) + (goto-char 15) + (delete-char 4) + (goto-char 16) + (insert ".........") + (goto-char 17) + (insert "...............") + (goto-char 33) + (delete-char 0) + (goto-char 38) + (delete-char 0) + (goto-char 11) + (insert "...........") + (goto-char 8) + (delete-char 14) + (goto-char 32) + (insert "........") + (goto-char 40) + (widen) + (narrow-to-region 14 6) + (goto-char 10) + (delete-char 1) + (goto-char 7) + (widen) + (narrow-to-region 18 39) + (goto-char 36) + (delete-char 1) + (goto-char 34) + (widen) + (narrow-to-region 39 14) + (goto-char 22) + (widen) + (narrow-to-region 25 21) + (goto-char 23) + (delete-char 2) + (goto-char 23) + (delete-char 0) + (goto-char 23) + (insert ".........") + (goto-char 32) + (delete-char 0) + (goto-char 31) + (insert ".........") + (goto-char 32) + (insert "...") + (goto-char 30) + (widen) + (narrow-to-region 10 56) + (goto-char 10) + (insert ".........") + (goto-char 38) + (insert ".........") + (goto-char 19) + (insert "..") + (goto-char 11) + (insert "..............") + (goto-char 66) + (insert "...............") + (goto-char 13) + (insert "......") + (should + (equal + (test-overlay-regions) + '((2 . 41) + (3 . 117) + (6 . 41) + (8 . 41) + (9 . 41) + (10 . 42) + (41 . 42)))))) + +(ert-deftest overlay-autogenerated-test-32 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 35 60 nil nil t) + (make-overlay 45 46 nil nil nil) + (make-overlay 47 11 nil nil t) + (make-overlay 12 51 nil t nil) + (make-overlay 61 17 nil t nil) + (make-overlay 7 24 nil t nil) + (make-overlay 36 37 nil nil t) + (make-overlay 5 39 nil t t) + (make-overlay 5 40 nil nil t) + (make-overlay 38 40 nil t t) + (make-overlay 47 45 nil t nil) + (make-overlay 61 48 nil nil nil) + (make-overlay 23 39 nil t t) + (make-overlay 11 52 nil nil nil) + (make-overlay 37 35 nil nil nil) + (make-overlay 19 20 nil t nil) + (goto-char 43) + (insert "........") + (goto-char 7) + (insert "") + (goto-char 28) + (delete-char 41) + (goto-char 3) + (delete-char 17) + (goto-char 2) + (insert ".") + (goto-char 7) + (insert ".........") + (goto-char 21) + (delete-char 4) + (goto-char 13) + (delete-char 1) + (goto-char 2) + (insert "...............") + (goto-char 7) + (insert "") + (goto-char 14) + (insert ".....") + (goto-char 16) + (insert ".") + (goto-char 10) + (insert "..............") + (goto-char 16) + (delete-char 18) + (goto-char 1) + (delete-char 36) + (goto-char 1) + (delete-char 0) + (goto-char 1) + (delete-char 0) + (goto-char 1) + (insert ".............") + (goto-char 9) + (insert ".") + (goto-char 14) + (insert ".....") + (goto-char 9) + (delete-char 0) + (goto-char 15) + (delete-char 0) + (goto-char 6) + (delete-char 4) + (goto-char 11) + (delete-char 5) + (goto-char 5) + (insert "....") + (goto-char 5) + (insert ".....") + (goto-char 12) + (insert "") + (goto-char 13) + (insert ".......") + (goto-char 14) + (insert "......") + (goto-char 9) + (delete-char 3) + (goto-char 17) + (delete-char 0) + (goto-char 7) + (delete-char 12) + (should + (equal + (test-overlay-regions) + '((1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 18) + (1 . 18) + (1 . 18) + (1 . 18) + (18 . 18) + (18 . 18) + (18 . 18)))))) + +(ert-deftest overlay-autogenerated-test-33 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 65 33 nil t nil) + (make-overlay 45 54 nil t t) + (make-overlay 17 38 nil t nil) + (make-overlay 58 46 nil nil t) + (make-overlay 21 36 nil t t) + (make-overlay 31 63 nil nil t) + (make-overlay 37 64 nil t t) + (make-overlay 42 19 nil nil nil) + (make-overlay 51 60 nil t nil) + (make-overlay 47 15 nil t t) + (make-overlay 57 47 nil nil nil) + (make-overlay 40 45 nil nil nil) + (make-overlay 44 47 nil t nil) + (make-overlay 42 35 nil t nil) + (make-overlay 1 65 nil nil t) + (make-overlay 29 63 nil t nil) + (goto-char 33) + (insert "...........") + (goto-char 56) + (insert ".........") + (goto-char 67) + (insert "....") + (goto-char 28) + (delete-char 35) + (goto-char 9) + (insert "......") + (goto-char 43) + (delete-char 17) + (goto-char 29) + (insert ".......") + (goto-char 20) + (insert "....") + (goto-char 53) + (insert ".......") + (goto-char 14) + (widen) + (narrow-to-region 38 57) + (goto-char 51) + (insert "") + (goto-char 57) + (insert ".......") + (goto-char 64) + (insert ".....") + (goto-char 59) + (delete-char 3) + (goto-char 45) + (delete-char 12) + (goto-char 43) + (insert "......") + (goto-char 48) + (insert "......") + (goto-char 52) + (insert "........") + (goto-char 57) + (delete-char 16) + (goto-char 43) + (delete-char 9) + (goto-char 40) + (insert "") + (goto-char 39) + (insert "..........") + (goto-char 50) + (widen) + (narrow-to-region 31 27) + (goto-char 27) + (insert "..........") + (goto-char 33) + (delete-char 0) + (goto-char 37) + (insert "..") + (goto-char 38) + (delete-char 4) + (goto-char 38) + (insert "..........") + (goto-char 45) + (insert ".....") + (goto-char 53) + (insert "...") + (goto-char 51) + (insert ".") + (goto-char 28) + (insert "...") + (should + (equal + (test-overlay-regions) + '((1 . 93) + (25 . 92) + (41 . 88) + (60 . 88)))))) + +(ert-deftest overlay-autogenerated-test-34 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 2 63 nil nil t) + (make-overlay 54 30 nil t nil) + (make-overlay 21 57 nil t nil) + (make-overlay 61 19 nil nil nil) + (make-overlay 55 8 nil nil t) + (make-overlay 14 51 nil nil nil) + (make-overlay 33 13 nil t t) + (make-overlay 36 25 nil t t) + (make-overlay 22 21 nil nil t) + (make-overlay 21 48 nil nil t) + (make-overlay 36 7 nil nil t) + (make-overlay 2 40 nil nil nil) + (make-overlay 21 27 nil nil t) + (make-overlay 26 2 nil nil nil) + (make-overlay 60 43 nil nil nil) + (make-overlay 12 50 nil t t) + (goto-char 44) + (delete-char 6) + (goto-char 5) + (insert "..") + (goto-char 17) + (insert "........") + (goto-char 48) + (insert "..") + (goto-char 27) + (delete-char 29) + (goto-char 10) + (delete-char 2) + (goto-char 35) + (insert ".............") + (goto-char 20) + (delete-char 0) + (goto-char 6) + (insert ".") + (goto-char 9) + (delete-char 6) + (goto-char 38) + (insert ".........") + (goto-char 5) + (insert ".........") + (goto-char 10) + (delete-char 20) + (goto-char 6) + (delete-char 6) + (goto-char 14) + (insert ".............") + (goto-char 31) + (delete-char 10) + (goto-char 20) + (widen) + (narrow-to-region 27 39) + (goto-char 34) + (delete-char 5) + (goto-char 32) + (delete-char 1) + (goto-char 27) + (insert "..") + (goto-char 28) + (insert "........") + (goto-char 39) + (insert "........") + (goto-char 38) + (delete-char 7) + (goto-char 44) + (delete-char 0) + (goto-char 30) + (insert "...............") + (goto-char 43) + (insert "............") + (goto-char 56) + (delete-char 1) + (goto-char 65) + (delete-char 3) + (goto-char 36) + (insert ".........") + (goto-char 74) + (insert ".....") + (goto-char 67) + (delete-char 5) + (goto-char 38) + (insert "..") + (should + (equal + (test-overlay-regions) + '((2 . 80) + (6 . 78)))))) + +(ert-deftest overlay-autogenerated-test-35 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 38 16 nil nil nil) + (make-overlay 19 22 nil t nil) + (make-overlay 16 43 nil nil t) + (make-overlay 27 5 nil nil nil) + (make-overlay 43 34 nil t nil) + (make-overlay 47 4 nil nil t) + (make-overlay 1 47 nil nil t) + (make-overlay 27 35 nil t nil) + (make-overlay 41 41 nil nil t) + (make-overlay 21 19 nil nil nil) + (make-overlay 16 38 nil nil t) + (make-overlay 33 39 nil t nil) + (make-overlay 34 51 nil nil t) + (make-overlay 45 36 nil t nil) + (make-overlay 42 18 nil t t) + (make-overlay 12 30 nil nil nil) + (goto-char 18) + (insert "") + (goto-char 58) + (delete-char 3) + (goto-char 58) + (delete-char 0) + (goto-char 1) + (insert ".......") + (goto-char 48) + (delete-char 17) + (goto-char 39) + (delete-char 6) + (goto-char 33) + (widen) + (narrow-to-region 45 46) + (goto-char 46) + (insert "") + (goto-char 46) + (delete-char 0) + (goto-char 46) + (insert ".....") + (goto-char 51) + (widen) + (narrow-to-region 17 26) + (goto-char 25) + (widen) + (narrow-to-region 50 41) + (goto-char 45) + (insert "..............") + (goto-char 59) + (insert "...........") + (goto-char 47) + (delete-char 9) + (goto-char 59) + (insert "") + (goto-char 46) + (insert "") + (goto-char 54) + (delete-char 5) + (goto-char 57) + (widen) + (narrow-to-region 57 31) + (goto-char 42) + (delete-char 2) + (goto-char 52) + (insert "....") + (goto-char 44) + (insert "..") + (goto-char 44) + (insert "...............") + (goto-char 72) + (delete-char 1) + (goto-char 66) + (delete-char 6) + (goto-char 64) + (delete-char 5) + (goto-char 49) + (delete-char 12) + (goto-char 32) + (insert "......") + (goto-char 44) + (delete-char 2) + (goto-char 39) + (delete-char 12) + (goto-char 42) + (insert "......") + (goto-char 36) + (widen) + (narrow-to-region 14 47) + (should + (equal + (test-overlay-regions) + '((1 . 39) + (11 . 39) + (12 . 39) + (19 . 39) + (23 . 39) + (23 . 39) + (23 . 39) + (25 . 39) + (26 . 28) + (26 . 29) + (39 . 39) + (39 . 39) + (39 . 39) + (39 . 39) + (39 . 39) + (39 . 39)))))) + +(ert-deftest overlay-autogenerated-test-36 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 1 38 nil t t) + (make-overlay 58 34 nil t nil) + (make-overlay 6 33 nil nil t) + (make-overlay 63 54 nil nil t) + (make-overlay 54 54 nil t t) + (make-overlay 21 61 nil nil nil) + (make-overlay 64 55 nil nil t) + (make-overlay 28 65 nil nil t) + (make-overlay 32 51 nil t nil) + (make-overlay 36 38 nil nil nil) + (make-overlay 35 21 nil nil nil) + (make-overlay 65 48 nil nil nil) + (make-overlay 32 27 nil nil t) + (make-overlay 27 55 nil t t) + (make-overlay 30 22 nil t nil) + (make-overlay 14 58 nil t nil) + (goto-char 40) + (delete-char 7) + (goto-char 42) + (insert "......") + (goto-char 11) + (widen) + (narrow-to-region 64 9) + (goto-char 21) + (delete-char 23) + (goto-char 24) + (insert "...") + (goto-char 13) + (insert "..........") + (goto-char 12) + (delete-char 5) + (goto-char 10) + (delete-char 0) + (goto-char 21) + (widen) + (narrow-to-region 9 5) + (goto-char 6) + (delete-char 0) + (goto-char 9) + (delete-char 0) + (goto-char 9) + (delete-char 0) + (goto-char 7) + (insert "............") + (goto-char 9) + (insert "...") + (goto-char 18) + (insert ".") + (goto-char 23) + (delete-char 1) + (goto-char 9) + (insert "....") + (goto-char 6) + (insert ".....") + (goto-char 23) + (widen) + (narrow-to-region 28 1) + (goto-char 6) + (insert "...........") + (goto-char 30) + (delete-char 8) + (goto-char 2) + (insert ".") + (goto-char 18) + (insert "......") + (goto-char 5) + (delete-char 9) + (goto-char 5) + (delete-char 20) + (goto-char 4) + (delete-char 3) + (goto-char 3) + (delete-char 2) + (goto-char 3) + (delete-char 0) + (goto-char 1) + (insert "......") + (goto-char 8) + (widen) + (narrow-to-region 39 2) + (goto-char 13) + (delete-char 12) + (goto-char 24) + (delete-char 0) + (should + (equal + (test-overlay-regions) + '((7 . 20) + (9 . 20) + (13 . 36) + (20 . 20) + (20 . 20) + (20 . 20) + (20 . 20) + (20 . 29) + (20 . 33) + (20 . 36) + (20 . 39) + (20 . 43) + (20 . 43)))))) + +(ert-deftest overlay-autogenerated-test-37 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 26 30 nil nil nil) + (make-overlay 55 50 nil nil t) + (make-overlay 43 54 nil nil t) + (make-overlay 53 48 nil nil nil) + (make-overlay 37 51 nil nil t) + (make-overlay 15 30 nil nil nil) + (make-overlay 2 24 nil t t) + (make-overlay 56 61 nil t nil) + (make-overlay 65 46 nil t nil) + (make-overlay 28 47 nil t nil) + (make-overlay 21 24 nil t t) + (make-overlay 17 13 nil t t) + (make-overlay 7 44 nil t nil) + (make-overlay 28 63 nil nil nil) + (make-overlay 22 16 nil t t) + (make-overlay 26 44 nil t t) + (goto-char 57) + (delete-char 6) + (goto-char 42) + (insert ".....") + (goto-char 63) + (insert ".............") + (goto-char 17) + (insert "") + (goto-char 57) + (insert "...........") + (goto-char 3) + (delete-char 47) + (goto-char 15) + (insert ".............") + (goto-char 28) + (insert "") + (goto-char 17) + (delete-char 31) + (goto-char 7) + (delete-char 16) + (goto-char 2) + (insert "...........") + (goto-char 2) + (insert "..") + (goto-char 18) + (widen) + (narrow-to-region 20 8) + (goto-char 13) + (widen) + (narrow-to-region 12 10) + (goto-char 10) + (delete-char 1) + (goto-char 11) + (delete-char 0) + (goto-char 10) + (insert "...") + (goto-char 11) + (delete-char 0) + (goto-char 13) + (insert "..") + (goto-char 16) + (delete-char 0) + (goto-char 10) + (delete-char 2) + (goto-char 11) + (insert ".....") + (goto-char 16) + (widen) + (narrow-to-region 6 13) + (goto-char 10) + (insert "..") + (goto-char 6) + (delete-char 6) + (goto-char 8) + (insert "...............") + (goto-char 21) + (delete-char 0) + (goto-char 21) + (widen) + (narrow-to-region 36 11) + (goto-char 12) + (insert "...............") + (goto-char 19) + (insert ".......") + (goto-char 56) + (delete-char 2) + (goto-char 42) + (delete-char 11) + (should + (equal + (test-overlay-regions) + '((44 . 45)))))) + +(ert-deftest overlay-autogenerated-test-38 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 29 13 nil t t) + (make-overlay 19 28 nil nil t) + (make-overlay 47 33 nil nil nil) + (make-overlay 8 44 nil t nil) + (make-overlay 48 4 nil t nil) + (make-overlay 8 20 nil t t) + (make-overlay 38 31 nil nil t) + (make-overlay 17 65 nil nil t) + (make-overlay 49 31 nil nil nil) + (make-overlay 39 19 nil nil t) + (make-overlay 40 49 nil t t) + (make-overlay 24 16 nil t t) + (make-overlay 4 41 nil t nil) + (make-overlay 61 42 nil t nil) + (make-overlay 46 11 nil nil nil) + (make-overlay 1 43 nil nil t) + (goto-char 62) + (delete-char 2) + (goto-char 25) + (widen) + (narrow-to-region 30 38) + (goto-char 37) + (delete-char 1) + (goto-char 37) + (insert "...........") + (goto-char 41) + (delete-char 3) + (goto-char 39) + (delete-char 5) + (goto-char 39) + (widen) + (narrow-to-region 31 9) + (goto-char 11) + (insert "..............") + (goto-char 9) + (widen) + (narrow-to-region 62 30) + (goto-char 32) + (widen) + (narrow-to-region 17 48) + (goto-char 39) + (delete-char 7) + (goto-char 24) + (delete-char 8) + (goto-char 19) + (insert "") + (goto-char 25) + (delete-char 5) + (goto-char 28) + (delete-char 0) + (goto-char 22) + (widen) + (narrow-to-region 52 35) + (goto-char 49) + (delete-char 0) + (goto-char 49) + (delete-char 3) + (goto-char 48) + (insert "...........") + (goto-char 37) + (delete-char 23) + (goto-char 36) + (delete-char 0) + (goto-char 35) + (insert "....") + (goto-char 35) + (insert "..") + (goto-char 39) + (delete-char 4) + (goto-char 39) + (delete-char 0) + (goto-char 36) + (delete-char 3) + (goto-char 36) + (delete-char 0) + (goto-char 36) + (delete-char 0) + (goto-char 36) + (delete-char 0) + (goto-char 36) + (insert ".....") + (goto-char 38) + (delete-char 1) + (goto-char 35) + (delete-char 3) + (should + (equal + (test-overlay-regions) + '((1 . 37) + (24 . 44) + (25 . 37)))))) + +(ert-deftest overlay-autogenerated-test-39 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 15 49 nil t t) + (make-overlay 27 20 nil t nil) + (make-overlay 55 50 nil t nil) + (make-overlay 17 5 nil t t) + (make-overlay 26 56 nil nil t) + (make-overlay 42 11 nil t t) + (make-overlay 24 35 nil nil t) + (make-overlay 47 45 nil t t) + (make-overlay 37 12 nil nil t) + (make-overlay 17 25 nil t nil) + (make-overlay 32 53 nil nil nil) + (make-overlay 20 34 nil nil t) + (make-overlay 56 58 nil nil t) + (make-overlay 42 31 nil nil t) + (make-overlay 22 55 nil t t) + (make-overlay 55 11 nil t nil) + (goto-char 16) + (insert ".............") + (goto-char 30) + (insert ".") + (goto-char 12) + (delete-char 56) + (goto-char 9) + (insert ".............") + (goto-char 6) + (insert "....") + (goto-char 19) + (delete-char 19) + (goto-char 19) + (insert "...............") + (goto-char 13) + (delete-char 21) + (goto-char 7) + (delete-char 0) + (goto-char 14) + (widen) + (narrow-to-region 5 6) + (goto-char 5) + (delete-char 0) + (goto-char 6) + (insert "......") + (goto-char 10) + (delete-char 0) + (goto-char 7) + (widen) + (narrow-to-region 2 6) + (goto-char 2) + (insert "..........") + (goto-char 2) + (delete-char 9) + (goto-char 7) + (insert "...") + (goto-char 9) + (insert "...") + (goto-char 10) + (insert "......") + (goto-char 4) + (delete-char 14) + (goto-char 4) + (insert ".") + (goto-char 5) + (insert "..............") + (goto-char 13) + (insert "......") + (goto-char 10) + (insert "......") + (goto-char 20) + (insert "............") + (goto-char 16) + (widen) + (narrow-to-region 3 32) + (goto-char 18) + (insert "..") + (goto-char 6) + (insert "......") + (goto-char 38) + (delete-char 0) + (goto-char 31) + (insert "............") + (goto-char 28) + (insert "") + (goto-char 9) + (delete-char 23) + (should + (equal + (test-overlay-regions) + 'nil)))) + +(ert-deftest overlay-autogenerated-test-40 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 52 3 nil t nil) + (make-overlay 35 41 nil t t) + (make-overlay 4 2 nil t nil) + (make-overlay 51 48 nil nil t) + (make-overlay 44 57 nil t t) + (make-overlay 13 32 nil nil nil) + (make-overlay 46 29 nil t nil) + (make-overlay 28 13 nil t nil) + (make-overlay 10 65 nil t t) + (make-overlay 41 48 nil nil t) + (make-overlay 36 44 nil nil t) + (make-overlay 29 61 nil t nil) + (make-overlay 25 24 nil nil t) + (make-overlay 22 45 nil nil t) + (make-overlay 37 55 nil nil t) + (make-overlay 36 39 nil nil nil) + (goto-char 16) + (delete-char 48) + (goto-char 17) + (delete-char 0) + (goto-char 7) + (insert "..............") + (goto-char 30) + (insert "........") + (goto-char 11) + (insert "..........") + (goto-char 5) + (delete-char 14) + (goto-char 19) + (insert ".") + (goto-char 27) + (insert "..") + (goto-char 35) + (delete-char 1) + (goto-char 29) + (delete-char 0) + (goto-char 33) + (delete-char 2) + (goto-char 33) + (insert "..") + (goto-char 28) + (insert ".........") + (goto-char 30) + (delete-char 4) + (goto-char 40) + (delete-char 1) + (goto-char 15) + (widen) + (narrow-to-region 40 8) + (goto-char 10) + (delete-char 13) + (goto-char 11) + (delete-char 5) + (goto-char 15) + (insert "........") + (goto-char 26) + (delete-char 4) + (goto-char 11) + (delete-char 1) + (goto-char 14) + (insert "............") + (goto-char 33) + (insert ".") + (goto-char 10) + (insert "...") + (goto-char 30) + (widen) + (narrow-to-region 28 9) + (goto-char 27) + (delete-char 0) + (goto-char 27) + (delete-char 1) + (goto-char 26) + (insert "..") + (goto-char 27) + (insert "..") + (goto-char 20) + (delete-char 5) + (goto-char 12) + (widen) + (narrow-to-region 40 30) + (goto-char 37) + (delete-char 3) + (should + (equal + (test-overlay-regions) + '((13 . 37) + (14 . 37) + (14 . 37) + (14 . 37) + (14 . 37) + (14 . 37) + (14 . 37) + (37 . 37) + (37 . 37)))))) + +(ert-deftest overlay-autogenerated-test-41 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 28 48 nil nil t) + (make-overlay 30 11 nil nil t) + (make-overlay 7 12 nil t nil) + (make-overlay 65 35 nil t nil) + (make-overlay 22 61 nil t nil) + (make-overlay 37 42 nil nil nil) + (make-overlay 33 38 nil nil t) + (make-overlay 48 45 nil t t) + (make-overlay 45 62 nil t nil) + (make-overlay 63 7 nil nil t) + (make-overlay 23 42 nil t nil) + (make-overlay 21 4 nil t nil) + (make-overlay 64 41 nil t nil) + (make-overlay 20 33 nil t t) + (make-overlay 41 26 nil t nil) + (make-overlay 43 31 nil t t) + (goto-char 55) + (delete-char 3) + (goto-char 12) + (insert "..") + (goto-char 62) + (insert "") + (goto-char 24) + (delete-char 2) + (goto-char 41) + (insert "............") + (goto-char 2) + (insert ".") + (goto-char 55) + (insert "........") + (goto-char 67) + (delete-char 6) + (goto-char 58) + (delete-char 10) + (goto-char 29) + (insert "") + (goto-char 6) + (widen) + (narrow-to-region 44 45) + (goto-char 44) + (delete-char 1) + (goto-char 44) + (widen) + (narrow-to-region 24 37) + (goto-char 30) + (delete-char 7) + (goto-char 27) + (insert "......") + (goto-char 35) + (delete-char 0) + (goto-char 32) + (insert "...............") + (goto-char 37) + (delete-char 9) + (goto-char 40) + (insert "..........") + (goto-char 35) + (insert "......") + (goto-char 25) + (delete-char 7) + (goto-char 40) + (delete-char 4) + (goto-char 25) + (delete-char 14) + (goto-char 28) + (insert "") + (goto-char 28) + (widen) + (narrow-to-region 17 43) + (goto-char 20) + (insert "..........") + (goto-char 22) + (delete-char 2) + (goto-char 48) + (insert "............") + (goto-char 47) + (insert ".........") + (goto-char 69) + (widen) + (narrow-to-region 52 25) + (goto-char 26) + (insert "......") + (goto-char 53) + (insert "..") + (should + (equal + (test-overlay-regions) + '((5 . 38) + (8 . 97) + (12 . 47) + (37 . 47) + (39 . 52) + (39 . 87) + (39 . 95) + (46 . 90) + (47 . 49) + (47 . 90) + (47 . 99) + (48 . 87)))))) + +(ert-deftest overlay-autogenerated-test-42 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 20 23 nil nil nil) + (make-overlay 45 51 nil t nil) + (make-overlay 34 58 nil t nil) + (make-overlay 27 11 nil nil nil) + (make-overlay 14 8 nil t t) + (make-overlay 64 43 nil t nil) + (make-overlay 61 56 nil nil t) + (make-overlay 28 14 nil t nil) + (make-overlay 21 46 nil t t) + (make-overlay 30 34 nil t t) + (make-overlay 47 40 nil nil nil) + (make-overlay 5 44 nil t t) + (make-overlay 11 45 nil nil nil) + (make-overlay 65 8 nil nil t) + (make-overlay 47 54 nil t t) + (make-overlay 37 57 nil t nil) + (goto-char 11) + (insert "....") + (goto-char 65) + (delete-char 0) + (goto-char 56) + (delete-char 4) + (goto-char 11) + (delete-char 2) + (goto-char 23) + (insert ".............") + (goto-char 2) + (insert "............") + (goto-char 84) + (delete-char 1) + (goto-char 10) + (insert "..............") + (goto-char 19) + (insert "............") + (goto-char 69) + (delete-char 6) + (goto-char 15) + (insert "........") + (goto-char 104) + (insert "") + (goto-char 94) + (delete-char 11) + (goto-char 66) + (insert ".....") + (goto-char 67) + (insert "") + (goto-char 53) + (delete-char 22) + (goto-char 42) + (insert ".") + (goto-char 38) + (delete-char 13) + (goto-char 27) + (insert "......") + (goto-char 16) + (insert "............") + (goto-char 71) + (widen) + (narrow-to-region 59 15) + (goto-char 46) + (insert "..") + (goto-char 20) + (widen) + (narrow-to-region 95 93) + (goto-char 94) + (insert ".............") + (goto-char 103) + (widen) + (narrow-to-region 97 7) + (goto-char 93) + (insert "....") + (goto-char 85) + (insert "...........") + (goto-char 69) + (delete-char 24) + (goto-char 87) + (insert ".............") + (goto-char 7) + (delete-char 28) + (goto-char 65) + (delete-char 8) + (goto-char 48) + (insert "......") + (should + (equal + (test-overlay-regions) + '((31 . 44) + (33 . 33) + (33 . 41) + (33 . 41) + (33 . 41) + (33 . 41) + (33 . 82) + (40 . 44) + (41 . 41) + (41 . 41) + (41 . 47) + (41 . 48) + (44 . 45) + (44 . 46) + (44 . 63) + (46 . 57)))))) + +(ert-deftest overlay-autogenerated-test-43 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 8 53 nil t nil) + (make-overlay 11 50 nil t nil) + (make-overlay 1 30 nil nil nil) + (make-overlay 54 15 nil t t) + (make-overlay 22 30 nil nil nil) + (make-overlay 1 33 nil nil nil) + (make-overlay 18 15 nil t nil) + (make-overlay 43 39 nil nil t) + (make-overlay 43 17 nil t nil) + (make-overlay 2 29 nil t nil) + (make-overlay 57 42 nil t nil) + (make-overlay 40 1 nil nil nil) + (make-overlay 8 64 nil nil nil) + (make-overlay 64 15 nil nil nil) + (make-overlay 9 11 nil nil t) + (make-overlay 40 21 nil t nil) + (goto-char 5) + (delete-char 37) + (goto-char 25) + (delete-char 2) + (goto-char 17) + (insert "...........") + (goto-char 19) + (widen) + (narrow-to-region 20 20) + (goto-char 20) + (delete-char 0) + (goto-char 20) + (insert "..........") + (goto-char 24) + (delete-char 5) + (goto-char 24) + (insert "...") + (goto-char 28) + (widen) + (narrow-to-region 20 36) + (goto-char 26) + (delete-char 2) + (goto-char 31) + (insert ".............") + (goto-char 22) + (insert ".....") + (goto-char 38) + (delete-char 0) + (goto-char 31) + (delete-char 4) + (goto-char 27) + (insert "...") + (goto-char 23) + (widen) + (narrow-to-region 37 20) + (goto-char 22) + (insert ".............") + (goto-char 33) + (insert "......") + (goto-char 43) + (insert "............") + (goto-char 59) + (insert ".......") + (goto-char 25) + (delete-char 26) + (goto-char 49) + (insert ".........") + (goto-char 50) + (insert ".......") + (goto-char 39) + (widen) + (narrow-to-region 54 86) + (goto-char 64) + (insert "...............") + (goto-char 83) + (insert "............") + (goto-char 70) + (insert "........") + (goto-char 58) + (insert "..............") + (goto-char 83) + (insert "............") + (goto-char 83) + (insert "..........") + (goto-char 69) + (delete-char 75) + (goto-char 75) + (delete-char 3) + (should + (equal + (test-overlay-regions) + '((5 . 75) + (5 . 75) + (5 . 80) + (5 . 80)))))) + +(ert-deftest overlay-autogenerated-test-44 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 8 48 nil nil t) + (make-overlay 52 38 nil nil nil) + (make-overlay 3 63 nil nil nil) + (make-overlay 44 15 nil nil t) + (make-overlay 27 44 nil nil t) + (make-overlay 43 9 nil nil t) + (make-overlay 11 27 nil t nil) + (make-overlay 36 41 nil nil t) + (make-overlay 23 25 nil t t) + (make-overlay 19 60 nil t t) + (make-overlay 11 55 nil t nil) + (make-overlay 59 2 nil t nil) + (make-overlay 32 64 nil t nil) + (make-overlay 15 8 nil nil nil) + (make-overlay 61 15 nil nil nil) + (make-overlay 64 30 nil t t) + (goto-char 42) + (delete-char 20) + (goto-char 44) + (delete-char 1) + (goto-char 43) + (insert "...........") + (goto-char 43) + (delete-char 1) + (goto-char 28) + (delete-char 8) + (goto-char 37) + (delete-char 9) + (goto-char 4) + (delete-char 30) + (goto-char 6) + (delete-char 0) + (goto-char 7) + (delete-char 0) + (goto-char 2) + (delete-char 2) + (goto-char 5) + (delete-char 0) + (goto-char 5) + (delete-char 0) + (goto-char 2) + (insert ".....") + (goto-char 10) + (insert "...........") + (goto-char 21) + (insert "...") + (goto-char 10) + (delete-char 13) + (goto-char 9) + (insert "..........") + (goto-char 16) + (delete-char 1) + (goto-char 16) + (delete-char 4) + (goto-char 16) + (delete-char 0) + (goto-char 14) + (delete-char 1) + (goto-char 3) + (widen) + (narrow-to-region 2 9) + (goto-char 2) + (insert "") + (goto-char 2) + (insert ".............") + (goto-char 17) + (insert "....") + (goto-char 12) + (insert "........") + (goto-char 8) + (widen) + (narrow-to-region 32 23) + (goto-char 29) + (insert ".....") + (goto-char 35) + (delete-char 2) + (goto-char 27) + (delete-char 7) + (goto-char 23) + (widen) + (narrow-to-region 4 14) + (goto-char 8) + (insert "...............") + (should + (equal + (test-overlay-regions) + '((2 . 43) + (2 . 43) + (2 . 43) + (2 . 43) + (2 . 43) + (2 . 44)))))) + +(ert-deftest overlay-autogenerated-test-45 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 15 48 nil nil nil) + (make-overlay 1 47 nil t nil) + (make-overlay 43 4 nil t t) + (make-overlay 9 45 nil t t) + (make-overlay 1 25 nil t t) + (make-overlay 5 46 nil t t) + (make-overlay 7 14 nil t nil) + (make-overlay 1 53 nil nil t) + (make-overlay 13 41 nil t nil) + (make-overlay 5 31 nil t t) + (make-overlay 26 10 nil nil nil) + (make-overlay 56 37 nil nil nil) + (make-overlay 23 15 nil t nil) + (make-overlay 62 30 nil t t) + (make-overlay 2 35 nil t t) + (make-overlay 46 41 nil nil nil) + (goto-char 65) + (delete-char 0) + (goto-char 55) + (insert "...........") + (goto-char 22) + (insert "") + (goto-char 73) + (delete-char 3) + (goto-char 43) + (widen) + (narrow-to-region 54 63) + (goto-char 56) + (insert "......") + (goto-char 61) + (delete-char 3) + (goto-char 65) + (insert "......") + (goto-char 66) + (insert ".....") + (goto-char 62) + (insert ".") + (goto-char 74) + (insert ".........") + (goto-char 76) + (delete-char 4) + (goto-char 56) + (widen) + (narrow-to-region 2 46) + (goto-char 43) + (insert "...........") + (goto-char 20) + (delete-char 4) + (goto-char 38) + (delete-char 7) + (goto-char 25) + (delete-char 21) + (goto-char 12) + (insert ".........") + (goto-char 19) + (widen) + (narrow-to-region 72 61) + (goto-char 63) + (insert "") + (goto-char 65) + (delete-char 4) + (goto-char 61) + (delete-char 5) + (goto-char 63) + (delete-char 0) + (goto-char 63) + (delete-char 0) + (goto-char 62) + (delete-char 0) + (goto-char 61) + (insert "............") + (goto-char 72) + (insert "..............") + (goto-char 62) + (delete-char 7) + (goto-char 71) + (delete-char 5) + (goto-char 75) + (widen) + (narrow-to-region 29 8) + (goto-char 17) + (delete-char 2) + (goto-char 27) + (insert "........") + (should + (equal + (test-overlay-regions) + '((1 . 36) + (1 . 41) + (1 . 47) + (2 . 40) + (4 . 40) + (5 . 40) + (5 . 40) + (7 . 21) + (9 . 40) + (10 . 37) + (20 . 40) + (22 . 27) + (22 . 42)))))) + +(ert-deftest overlay-autogenerated-test-46 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 2 43 nil nil t) + (make-overlay 44 40 nil nil t) + (make-overlay 49 14 nil nil t) + (make-overlay 6 55 nil nil nil) + (make-overlay 13 52 nil t t) + (make-overlay 40 54 nil t nil) + (make-overlay 51 41 nil nil t) + (make-overlay 7 28 nil nil t) + (make-overlay 10 47 nil nil t) + (make-overlay 63 21 nil t nil) + (make-overlay 4 55 nil nil nil) + (make-overlay 52 58 nil t nil) + (make-overlay 62 11 nil t t) + (make-overlay 22 49 nil t nil) + (make-overlay 23 65 nil nil nil) + (make-overlay 50 33 nil nil t) + (goto-char 22) + (insert "..............") + (goto-char 12) + (insert "....") + (goto-char 25) + (delete-char 16) + (goto-char 14) + (delete-char 53) + (goto-char 2) + (insert "............") + (goto-char 20) + (delete-char 5) + (goto-char 11) + (delete-char 7) + (goto-char 9) + (widen) + (narrow-to-region 11 7) + (goto-char 8) + (insert "...............") + (goto-char 12) + (delete-char 4) + (goto-char 21) + (insert "...") + (goto-char 20) + (delete-char 5) + (goto-char 7) + (delete-char 3) + (goto-char 16) + (delete-char 0) + (goto-char 12) + (delete-char 1) + (goto-char 15) + (delete-char 0) + (goto-char 7) + (insert "..............") + (goto-char 17) + (insert "...........") + (goto-char 15) + (insert "............") + (goto-char 20) + (delete-char 5) + (goto-char 7) + (insert "....") + (goto-char 37) + (delete-char 7) + (goto-char 8) + (insert "..........") + (goto-char 47) + (insert ".............") + (goto-char 65) + (insert ".......") + (goto-char 39) + (delete-char 26) + (goto-char 14) + (delete-char 2) + (goto-char 27) + (insert ".............") + (goto-char 17) + (widen) + (narrow-to-region 54 32) + (goto-char 40) + (widen) + (narrow-to-region 10 3) + (goto-char 7) + (insert "........") + (goto-char 13) + (insert "..............") + (should + (equal + (test-overlay-regions) + '((2 . 85)))))) + +(ert-deftest overlay-autogenerated-test-47 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 58 62 nil t nil) + (make-overlay 14 38 nil nil nil) + (make-overlay 63 44 nil t t) + (make-overlay 41 41 nil nil t) + (make-overlay 19 39 nil nil nil) + (make-overlay 10 49 nil t t) + (make-overlay 56 38 nil t t) + (make-overlay 23 38 nil nil t) + (make-overlay 1 64 nil nil t) + (make-overlay 21 3 nil t nil) + (make-overlay 1 1 nil nil t) + (make-overlay 27 61 nil nil nil) + (make-overlay 29 59 nil nil nil) + (make-overlay 37 30 nil t nil) + (make-overlay 47 21 nil nil t) + (make-overlay 34 26 nil t nil) + (goto-char 6) + (delete-char 44) + (goto-char 8) + (delete-char 0) + (goto-char 8) + (insert "....") + (goto-char 17) + (delete-char 2) + (goto-char 12) + (insert "...") + (goto-char 20) + (insert "") + (goto-char 2) + (delete-char 20) + (goto-char 1) + (insert ".........") + (goto-char 7) + (insert ".............") + (goto-char 27) + (delete-char 0) + (goto-char 15) + (insert "..........") + (goto-char 36) + (insert "..............") + (goto-char 26) + (insert "..............") + (goto-char 63) + (insert "...........") + (goto-char 9) + (insert "............") + (goto-char 71) + (delete-char 17) + (goto-char 36) + (insert "....") + (goto-char 45) + (delete-char 31) + (goto-char 28) + (delete-char 8) + (goto-char 10) + (delete-char 16) + (goto-char 14) + (delete-char 4) + (goto-char 16) + (delete-char 0) + (goto-char 15) + (insert "") + (goto-char 14) + (delete-char 1) + (goto-char 10) + (delete-char 2) + (goto-char 6) + (delete-char 0) + (goto-char 1) + (insert ".........") + (goto-char 23) + (insert "......") + (goto-char 25) + (insert "..........") + (goto-char 25) + (widen) + (narrow-to-region 10 30) + (goto-char 21) + (delete-char 1) + (goto-char 17) + (insert "..........") + (should + (equal + (test-overlay-regions) + '((1 . 48) + (1 . 48) + (32 . 32) + (32 . 32) + (32 . 32) + (32 . 32) + (32 . 32) + (32 . 32) + (32 . 32) + (32 . 32) + (32 . 48) + (32 . 48) + (32 . 48)))))) + +(ert-deftest overlay-autogenerated-test-48 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 1 11 nil nil nil) + (make-overlay 35 29 nil t t) + (make-overlay 24 46 nil nil t) + (make-overlay 15 43 nil nil t) + (make-overlay 51 49 nil t t) + (make-overlay 25 43 nil t nil) + (make-overlay 23 59 nil nil nil) + (make-overlay 10 4 nil t nil) + (make-overlay 40 45 nil nil nil) + (make-overlay 42 43 nil nil t) + (make-overlay 20 38 nil t nil) + (make-overlay 17 49 nil nil nil) + (make-overlay 9 25 nil nil t) + (make-overlay 13 19 nil nil nil) + (make-overlay 44 31 nil t nil) + (make-overlay 12 65 nil nil t) + (goto-char 59) + (widen) + (narrow-to-region 28 14) + (goto-char 26) + (insert "...") + (goto-char 30) + (delete-char 1) + (goto-char 23) + (insert "...") + (goto-char 27) + (widen) + (narrow-to-region 45 67) + (goto-char 50) + (insert "...............") + (goto-char 59) + (insert "..............") + (goto-char 55) + (insert ".............") + (goto-char 106) + (delete-char 0) + (goto-char 97) + (delete-char 10) + (goto-char 67) + (delete-char 16) + (goto-char 76) + (insert "..............") + (goto-char 71) + (insert ".............") + (goto-char 110) + (delete-char 0) + (goto-char 56) + (delete-char 38) + (goto-char 61) + (delete-char 10) + (goto-char 56) + (delete-char 5) + (goto-char 49) + (insert ".......") + (goto-char 62) + (insert "...") + (goto-char 54) + (insert "..........") + (goto-char 47) + (delete-char 10) + (goto-char 47) + (delete-char 20) + (goto-char 46) + (insert ".............") + (goto-char 56) + (insert "...........") + (goto-char 70) + (delete-char 1) + (goto-char 62) + (widen) + (narrow-to-region 50 64) + (goto-char 60) + (insert "..") + (goto-char 55) + (delete-char 6) + (goto-char 60) + (insert ".............") + (goto-char 61) + (delete-char 9) + (goto-char 64) + (delete-char 0) + (goto-char 53) + (widen) + (narrow-to-region 15 62) + (should + (equal + (test-overlay-regions) + '((9 . 28) + (12 . 73) + (13 . 19) + (15 . 70) + (17 . 70) + (20 . 43) + (23 . 70) + (27 . 70) + (28 . 70) + (34 . 40) + (36 . 70) + (45 . 70)))))) + +(ert-deftest overlay-autogenerated-test-49 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 24 10 nil nil t) + (make-overlay 53 23 nil t nil) + (make-overlay 53 9 nil nil t) + (make-overlay 65 64 nil t t) + (make-overlay 48 2 nil nil t) + (make-overlay 12 58 nil nil t) + (make-overlay 64 64 nil nil nil) + (make-overlay 26 13 nil t t) + (make-overlay 46 26 nil nil t) + (make-overlay 28 59 nil t t) + (make-overlay 33 52 nil nil nil) + (make-overlay 39 8 nil t t) + (make-overlay 9 59 nil t t) + (make-overlay 50 45 nil nil t) + (make-overlay 41 53 nil nil t) + (make-overlay 51 51 nil t nil) + (goto-char 61) + (insert "..............") + (goto-char 19) + (widen) + (narrow-to-region 10 65) + (goto-char 65) + (delete-char 0) + (goto-char 11) + (insert "...............") + (goto-char 77) + (delete-char 0) + (goto-char 51) + (insert "...") + (goto-char 75) + (insert ".....") + (goto-char 77) + (delete-char 11) + (goto-char 45) + (delete-char 0) + (goto-char 24) + (widen) + (narrow-to-region 33 52) + (goto-char 46) + (insert "..............") + (goto-char 46) + (insert "..........") + (goto-char 39) + (widen) + (narrow-to-region 46 77) + (goto-char 77) + (insert "..............") + (goto-char 54) + (insert ".......") + (goto-char 87) + (insert ".") + (goto-char 70) + (delete-char 16) + (goto-char 79) + (delete-char 0) + (goto-char 73) + (widen) + (narrow-to-region 74 100) + (goto-char 91) + (insert ".............") + (goto-char 80) + (delete-char 11) + (goto-char 82) + (insert "......") + (goto-char 108) + (delete-char 0) + (goto-char 104) + (insert ".....") + (goto-char 100) + (delete-char 1) + (goto-char 90) + (insert ".............") + (goto-char 99) + (insert ".............") + (goto-char 124) + (insert "..............") + (goto-char 114) + (insert "....") + (goto-char 134) + (delete-char 0) + (goto-char 89) + (delete-char 65) + (goto-char 75) + (delete-char 16) + (should + (equal + (test-overlay-regions) + '((2 . 75) + (8 . 75) + (9 . 76) + (9 . 82) + (27 . 82) + (38 . 76) + (41 . 75) + (43 . 82) + (70 . 75)))))) + +(ert-deftest overlay-autogenerated-test-50 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 29 53 nil t t) + (make-overlay 65 64 nil nil nil) + (make-overlay 3 31 nil nil t) + (make-overlay 45 59 nil t nil) + (make-overlay 60 37 nil t t) + (make-overlay 7 5 nil t t) + (make-overlay 37 24 nil nil nil) + (make-overlay 45 20 nil nil nil) + (make-overlay 33 42 nil nil t) + (make-overlay 47 57 nil t nil) + (make-overlay 14 49 nil t t) + (make-overlay 14 30 nil t nil) + (make-overlay 21 40 nil t t) + (make-overlay 5 45 nil t t) + (make-overlay 59 40 nil t t) + (make-overlay 37 52 nil nil nil) + (goto-char 48) + (insert "") + (goto-char 7) + (insert ".........") + (goto-char 31) + (insert "...........") + (goto-char 41) + (delete-char 7) + (goto-char 21) + (delete-char 11) + (goto-char 41) + (widen) + (narrow-to-region 51 53) + (goto-char 52) + (insert ".....") + (goto-char 55) + (widen) + (narrow-to-region 18 24) + (goto-char 23) + (widen) + (narrow-to-region 39 38) + (goto-char 38) + (insert ".............") + (goto-char 41) + (insert "......") + (goto-char 38) + (insert "..............") + (goto-char 52) + (insert "...............") + (goto-char 78) + (delete-char 5) + (goto-char 50) + (insert "..........") + (goto-char 50) + (delete-char 3) + (goto-char 85) + (widen) + (narrow-to-region 86 1) + (goto-char 5) + (insert "....") + (goto-char 69) + (insert "...........") + (goto-char 94) + (insert "......") + (goto-char 98) + (delete-char 7) + (goto-char 46) + (insert "...............") + (goto-char 79) + (insert "............") + (goto-char 89) + (insert "") + (goto-char 14) + (delete-char 63) + (goto-char 20) + (insert ".........") + (goto-char 34) + (insert "...") + (goto-char 53) + (delete-char 14) + (goto-char 6) + (widen) + (narrow-to-region 6 52) + (goto-char 42) + (insert "...........") + (goto-char 40) + (insert ".......") + (goto-char 46) + (widen) + (narrow-to-region 1 68) + (should + (equal + (test-overlay-regions) + '((3 . 14) + (9 . 14) + (9 . 91) + (14 . 14) + (14 . 83) + (14 . 86) + (14 . 88) + (14 . 91) + (14 . 95) + (14 . 104)))))) + +(ert-deftest overlay-autogenerated-test-51 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 14 5 nil t nil) + (make-overlay 62 34 nil nil t) + (make-overlay 7 62 nil nil t) + (make-overlay 23 12 nil t t) + (make-overlay 16 4 nil nil nil) + (make-overlay 24 15 nil nil nil) + (make-overlay 6 6 nil t t) + (make-overlay 25 64 nil t t) + (make-overlay 23 6 nil t t) + (make-overlay 55 64 nil nil nil) + (make-overlay 8 62 nil nil t) + (make-overlay 65 65 nil nil nil) + (make-overlay 57 51 nil t t) + (make-overlay 35 8 nil t nil) + (make-overlay 55 13 nil nil t) + (make-overlay 60 62 nil nil t) + (goto-char 12) + (insert "..") + (goto-char 66) + (insert "............") + (goto-char 32) + (insert "..") + (goto-char 27) + (insert ".........") + (goto-char 8) + (insert ".............") + (goto-char 79) + (insert ".") + (goto-char 47) + (insert "....") + (goto-char 49) + (insert "...") + (goto-char 81) + (insert "....") + (goto-char 112) + (delete-char 0) + (goto-char 97) + (insert ".....") + (goto-char 109) + (delete-char 5) + (goto-char 20) + (insert ".....") + (goto-char 59) + (delete-char 33) + (goto-char 87) + (insert ".............") + (goto-char 98) + (insert "....") + (goto-char 22) + (delete-char 36) + (goto-char 45) + (insert "..............") + (goto-char 42) + (delete-char 29) + (goto-char 51) + (widen) + (narrow-to-region 39 41) + (goto-char 39) + (delete-char 2) + (goto-char 39) + (insert ".............") + (goto-char 51) + (insert "......") + (goto-char 52) + (insert "...............") + (goto-char 56) + (widen) + (narrow-to-region 59 20) + (goto-char 56) + (insert "............") + (goto-char 57) + (insert ".") + (goto-char 37) + (delete-char 12) + (goto-char 39) + (delete-char 11) + (goto-char 38) + (delete-char 8) + (goto-char 36) + (widen) + (narrow-to-region 65 26) + (goto-char 40) + (widen) + (narrow-to-region 27 55) + (should + (equal + (test-overlay-regions) + '((7 . 55) + (8 . 55) + (22 . 29) + (23 . 55) + (23 . 56) + (24 . 31) + (29 . 56) + (37 . 55)))))) + +(ert-deftest overlay-autogenerated-test-52 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 58 32 nil nil nil) + (make-overlay 44 54 nil nil t) + (make-overlay 27 50 nil nil nil) + (make-overlay 55 35 nil nil t) + (make-overlay 40 46 nil nil t) + (make-overlay 56 63 nil t nil) + (make-overlay 29 48 nil nil nil) + (make-overlay 45 24 nil t nil) + (make-overlay 60 25 nil t nil) + (make-overlay 55 41 nil t nil) + (make-overlay 55 1 nil nil t) + (make-overlay 30 45 nil t t) + (make-overlay 26 19 nil nil t) + (make-overlay 61 5 nil nil nil) + (make-overlay 33 5 nil nil nil) + (make-overlay 42 18 nil t nil) + (goto-char 55) + (insert ".") + (goto-char 49) + (delete-char 12) + (goto-char 41) + (insert "..........") + (goto-char 27) + (insert ".....") + (goto-char 58) + (insert "...........") + (goto-char 24) + (delete-char 23) + (goto-char 47) + (delete-char 9) + (goto-char 4) + (insert "...") + (goto-char 10) + (delete-char 32) + (goto-char 4) + (insert "..............") + (goto-char 29) + (insert "....") + (goto-char 28) + (delete-char 2) + (goto-char 34) + (insert "...........") + (goto-char 9) + (insert "......") + (goto-char 5) + (insert "") + (goto-char 45) + (delete-char 1) + (goto-char 18) + (insert ".........") + (goto-char 36) + (delete-char 5) + (goto-char 15) + (delete-char 27) + (goto-char 15) + (delete-char 10) + (goto-char 16) + (delete-char 2) + (goto-char 16) + (widen) + (narrow-to-region 10 2) + (goto-char 9) + (delete-char 1) + (goto-char 3) + (delete-char 2) + (goto-char 2) + (widen) + (narrow-to-region 9 10) + (goto-char 9) + (insert "...........") + (goto-char 19) + (delete-char 0) + (goto-char 14) + (delete-char 3) + (goto-char 11) + (delete-char 2) + (goto-char 9) + (delete-char 6) + (goto-char 9) + (delete-char 0) + (goto-char 10) + (insert "....") + (should + (equal + (test-overlay-regions) + '((1 . 17)))))) + +(ert-deftest overlay-autogenerated-test-53 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 10 30 nil nil nil) + (make-overlay 11 57 nil t nil) + (make-overlay 59 56 nil nil t) + (make-overlay 20 37 nil nil t) + (make-overlay 41 29 nil nil nil) + (make-overlay 31 10 nil nil t) + (make-overlay 6 36 nil nil nil) + (make-overlay 12 54 nil nil nil) + (make-overlay 25 26 nil t t) + (make-overlay 21 19 nil nil t) + (make-overlay 1 21 nil nil t) + (make-overlay 48 51 nil nil nil) + (make-overlay 54 55 nil t nil) + (make-overlay 64 48 nil t t) + (make-overlay 56 25 nil nil t) + (make-overlay 12 60 nil t nil) + (goto-char 41) + (delete-char 1) + (goto-char 63) + (insert "") + (goto-char 14) + (delete-char 5) + (goto-char 11) + (insert "..............") + (goto-char 41) + (widen) + (narrow-to-region 12 1) + (goto-char 1) + (delete-char 3) + (goto-char 9) + (delete-char 0) + (goto-char 5) + (insert "..............") + (goto-char 1) + (insert "..........") + (goto-char 29) + (insert "...............") + (goto-char 4) + (insert "..") + (goto-char 31) + (delete-char 15) + (goto-char 31) + (insert "") + (goto-char 27) + (insert "......") + (goto-char 6) + (insert "...") + (goto-char 23) + (widen) + (narrow-to-region 23 47) + (goto-char 37) + (delete-char 2) + (goto-char 35) + (delete-char 5) + (goto-char 38) + (delete-char 2) + (goto-char 30) + (insert ".......") + (goto-char 45) + (widen) + (narrow-to-region 13 2) + (goto-char 9) + (delete-char 1) + (goto-char 3) + (insert ".....") + (goto-char 2) + (insert "...............") + (goto-char 16) + (delete-char 5) + (goto-char 20) + (insert ".....") + (goto-char 26) + (delete-char 0) + (goto-char 26) + (widen) + (narrow-to-region 76 98) + (goto-char 88) + (insert ".........") + (goto-char 92) + (insert ".") + (goto-char 108) + (delete-char 0) + (goto-char 103) + (delete-char 3) + (should + (equal + (test-overlay-regions) + '((1 . 79) + (37 . 103) + (61 . 88) + (61 . 99) + (74 . 121) + (75 . 118) + (75 . 124) + (77 . 79) + (78 . 103) + (83 . 84) + (83 . 120) + (87 . 106)))))) + +(ert-deftest overlay-autogenerated-test-54 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 58 36 nil t t) + (make-overlay 55 49 nil nil t) + (make-overlay 12 25 nil nil t) + (make-overlay 16 37 nil t t) + (make-overlay 42 25 nil t t) + (make-overlay 8 41 nil t t) + (make-overlay 13 27 nil nil t) + (make-overlay 52 22 nil t nil) + (make-overlay 36 17 nil t nil) + (make-overlay 1 52 nil t nil) + (make-overlay 55 5 nil nil t) + (make-overlay 50 50 nil t nil) + (make-overlay 32 15 nil t nil) + (make-overlay 39 26 nil t nil) + (make-overlay 26 4 nil nil nil) + (make-overlay 38 47 nil t t) + (goto-char 23) + (insert ".") + (goto-char 57) + (delete-char 6) + (goto-char 54) + (insert "..............") + (goto-char 46) + (insert "...............") + (goto-char 29) + (insert ".......") + (goto-char 58) + (delete-char 21) + (goto-char 45) + (delete-char 4) + (goto-char 50) + (delete-char 4) + (goto-char 20) + (insert ".........") + (goto-char 16) + (insert "......") + (goto-char 17) + (insert ".....") + (goto-char 63) + (insert "........") + (goto-char 83) + (insert "....") + (goto-char 73) + (delete-char 8) + (goto-char 69) + (insert "...........") + (goto-char 48) + (widen) + (narrow-to-region 19 31) + (goto-char 22) + (delete-char 3) + (goto-char 23) + (delete-char 5) + (goto-char 20) + (insert "............") + (goto-char 23) + (delete-char 11) + (goto-char 19) + (insert "..........") + (goto-char 23) + (insert "........") + (goto-char 38) + (delete-char 1) + (goto-char 33) + (delete-char 5) + (goto-char 27) + (insert "..........") + (goto-char 35) + (delete-char 8) + (goto-char 35) + (insert ".") + (goto-char 20) + (insert "......") + (goto-char 22) + (delete-char 22) + (goto-char 23) + (delete-char 0) + (goto-char 22) + (widen) + (narrow-to-region 1 41) + (goto-char 13) + (insert ".......") + (should + (equal + (test-overlay-regions) + '((1 . 83) + (4 . 46) + (5 . 97) + (8 . 83) + (12 . 45) + (13 . 47) + (22 . 59) + (30 . 82) + (30 . 83) + (41 . 83) + (45 . 83) + (46 . 83)))))) + +(ert-deftest overlay-autogenerated-test-55 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 58 20 nil nil nil) + (make-overlay 60 33 nil t nil) + (make-overlay 6 27 nil nil nil) + (make-overlay 53 31 nil nil t) + (make-overlay 30 55 nil t t) + (make-overlay 4 64 nil t t) + (make-overlay 51 31 nil nil t) + (make-overlay 4 65 nil t t) + (make-overlay 57 62 nil t t) + (make-overlay 28 7 nil nil t) + (make-overlay 61 48 nil t nil) + (make-overlay 23 54 nil nil t) + (make-overlay 47 49 nil nil nil) + (make-overlay 12 52 nil t nil) + (make-overlay 39 57 nil t t) + (make-overlay 28 61 nil nil t) + (goto-char 8) + (insert "..............") + (goto-char 63) + (delete-char 3) + (goto-char 67) + (delete-char 6) + (goto-char 3) + (widen) + (narrow-to-region 10 67) + (goto-char 43) + (insert ".............") + (goto-char 20) + (insert "...............") + (goto-char 18) + (insert "..") + (goto-char 37) + (delete-char 47) + (goto-char 34) + (insert "..............") + (goto-char 31) + (delete-char 2) + (goto-char 16) + (widen) + (narrow-to-region 29 36) + (goto-char 31) + (delete-char 2) + (goto-char 31) + (insert ".......") + (goto-char 40) + (delete-char 0) + (goto-char 32) + (widen) + (narrow-to-region 40 19) + (goto-char 40) + (insert "..") + (goto-char 37) + (delete-char 0) + (goto-char 40) + (delete-char 1) + (goto-char 34) + (delete-char 4) + (goto-char 33) + (insert "..............") + (goto-char 19) + (widen) + (narrow-to-region 78 70) + (goto-char 77) + (insert ".........") + (goto-char 80) + (delete-char 1) + (goto-char 73) + (delete-char 3) + (goto-char 70) + (insert ".........") + (goto-char 75) + (delete-char 10) + (goto-char 74) + (delete-char 3) + (goto-char 73) + (insert "...............") + (goto-char 90) + (insert "......") + (goto-char 94) + (insert "..............") + (goto-char 101) + (insert "........") + (goto-char 111) + (insert "........") + (should + (equal + (test-overlay-regions) + '((4 . 132) + (4 . 133) + (65 . 89) + (65 . 89) + (65 . 89) + (65 . 89) + (65 . 129) + (65 . 130) + (65 . 130) + (65 . 130) + (65 . 130) + (89 . 89) + (89 . 130)))))) + +(ert-deftest overlay-autogenerated-test-56 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 7 14 nil nil t) + (make-overlay 10 10 nil nil t) + (make-overlay 21 23 nil nil t) + (make-overlay 4 44 nil t nil) + (make-overlay 42 16 nil t t) + (make-overlay 1 57 nil t nil) + (make-overlay 15 27 nil nil nil) + (make-overlay 31 1 nil t nil) + (make-overlay 56 45 nil t t) + (make-overlay 46 19 nil t nil) + (make-overlay 15 6 nil nil nil) + (make-overlay 31 26 nil nil t) + (make-overlay 39 41 nil t t) + (make-overlay 52 48 nil nil t) + (make-overlay 44 2 nil t nil) + (make-overlay 60 7 nil nil t) + (goto-char 49) + (delete-char 11) + (goto-char 43) + (delete-char 9) + (goto-char 42) + (delete-char 2) + (goto-char 12) + (insert "...........") + (goto-char 36) + (insert ".........") + (goto-char 1) + (insert "......") + (goto-char 67) + (delete-char 0) + (goto-char 47) + (insert ".............") + (goto-char 57) + (insert "........") + (goto-char 22) + (widen) + (narrow-to-region 75 33) + (goto-char 41) + (delete-char 28) + (goto-char 43) + (delete-char 0) + (goto-char 33) + (delete-char 5) + (goto-char 38) + (insert "..") + (goto-char 42) + (delete-char 0) + (goto-char 38) + (delete-char 0) + (goto-char 38) + (insert "............") + (goto-char 51) + (insert ".......") + (goto-char 48) + (insert "..") + (goto-char 55) + (insert ".") + (goto-char 33) + (delete-char 8) + (goto-char 42) + (insert "..") + (goto-char 45) + (insert "..") + (goto-char 59) + (insert ".............") + (goto-char 53) + (insert ".......") + (goto-char 81) + (delete-char 0) + (goto-char 44) + (delete-char 36) + (goto-char 38) + (delete-char 8) + (goto-char 33) + (insert ".............") + (goto-char 41) + (insert "..............") + (goto-char 65) + (insert "...............") + (goto-char 61) + (insert "...") + (should + (equal + (test-overlay-regions) + '((7 . 86) + (7 . 97) + (8 . 97) + (10 . 97) + (13 . 97) + (32 . 68) + (33 . 60) + (60 . 97) + (60 . 97) + (68 . 86)))))) + +(ert-deftest overlay-autogenerated-test-57 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 52 31 nil t nil) + (make-overlay 39 17 nil t nil) + (make-overlay 19 20 nil t t) + (make-overlay 18 3 nil nil t) + (make-overlay 19 47 nil nil t) + (make-overlay 38 54 nil nil nil) + (make-overlay 30 51 nil nil t) + (make-overlay 29 60 nil t t) + (make-overlay 57 38 nil nil nil) + (make-overlay 13 41 nil t nil) + (make-overlay 9 44 nil t nil) + (make-overlay 30 55 nil t nil) + (make-overlay 33 10 nil nil nil) + (make-overlay 14 35 nil nil t) + (make-overlay 53 50 nil t nil) + (make-overlay 25 28 nil nil t) + (goto-char 40) + (insert "..") + (goto-char 64) + (insert "........") + (goto-char 47) + (insert "............") + (goto-char 65) + (delete-char 0) + (goto-char 86) + (delete-char 1) + (goto-char 59) + (delete-char 11) + (goto-char 64) + (delete-char 8) + (goto-char 53) + (delete-char 0) + (goto-char 28) + (delete-char 8) + (goto-char 6) + (delete-char 33) + (goto-char 14) + (delete-char 2) + (goto-char 2) + (delete-char 10) + (goto-char 3) + (insert "..") + (goto-char 5) + (insert ".........") + (goto-char 1) + (insert "........") + (goto-char 10) + (delete-char 4) + (goto-char 26) + (insert "........") + (goto-char 23) + (insert "....") + (goto-char 1) + (widen) + (narrow-to-region 15 23) + (goto-char 19) + (insert "...") + (goto-char 24) + (delete-char 0) + (goto-char 19) + (insert ".......") + (goto-char 18) + (insert "..") + (goto-char 33) + (insert "...") + (goto-char 32) + (insert "...............") + (goto-char 29) + (delete-char 10) + (goto-char 29) + (insert "..........") + (goto-char 50) + (insert "") + (goto-char 16) + (insert ".........") + (goto-char 52) + (widen) + (narrow-to-region 59 15) + (goto-char 35) + (delete-char 4) + (goto-char 18) + (insert "....") + (should + (equal + (test-overlay-regions) + '((10 . 57) + (10 . 57) + (10 . 57) + (10 . 60) + (10 . 60) + (10 . 61) + (10 . 68) + (57 . 57)))))) + +(ert-deftest overlay-autogenerated-test-58 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 8 16 nil t nil) + (make-overlay 57 27 nil nil nil) + (make-overlay 15 62 nil nil nil) + (make-overlay 32 33 nil nil t) + (make-overlay 47 27 nil nil t) + (make-overlay 41 4 nil nil t) + (make-overlay 57 61 nil t nil) + (make-overlay 18 43 nil nil t) + (make-overlay 64 51 nil t t) + (make-overlay 44 26 nil nil nil) + (make-overlay 9 13 nil nil t) + (make-overlay 41 65 nil nil t) + (make-overlay 23 13 nil t t) + (make-overlay 26 59 nil t t) + (make-overlay 65 65 nil t t) + (make-overlay 15 7 nil nil nil) + (goto-char 41) + (insert "........") + (goto-char 35) + (delete-char 14) + (goto-char 32) + (widen) + (narrow-to-region 23 46) + (goto-char 41) + (delete-char 5) + (goto-char 29) + (delete-char 10) + (goto-char 31) + (insert ".") + (goto-char 29) + (insert "........") + (goto-char 27) + (delete-char 7) + (goto-char 29) + (insert "") + (goto-char 24) + (insert "............") + (goto-char 43) + (delete-char 1) + (goto-char 31) + (delete-char 9) + (goto-char 34) + (widen) + (narrow-to-region 20 14) + (goto-char 20) + (delete-char 0) + (goto-char 17) + (insert "...........") + (goto-char 31) + (delete-char 0) + (goto-char 16) + (insert "...........") + (goto-char 17) + (delete-char 8) + (goto-char 23) + (delete-char 5) + (goto-char 20) + (insert "..........") + (goto-char 33) + (widen) + (narrow-to-region 16 29) + (goto-char 24) + (insert "...............") + (goto-char 44) + (delete-char 0) + (goto-char 30) + (insert "....") + (goto-char 27) + (widen) + (narrow-to-region 4 22) + (goto-char 10) + (insert "..............") + (goto-char 36) + (insert "..") + (goto-char 10) + (delete-char 21) + (goto-char 14) + (delete-char 1) + (goto-char 14) + (insert "...........") + (goto-char 12) + (insert "........") + (goto-char 32) + (insert "........") + (should + (equal + (test-overlay-regions) + '((4 . 92) + (7 . 10) + (8 . 10) + (9 . 10) + (10 . 82) + (10 . 104)))))) + +(ert-deftest overlay-autogenerated-test-59 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 46 30 nil t t) + (make-overlay 3 26 nil nil nil) + (make-overlay 36 28 nil t t) + (make-overlay 49 49 nil t t) + (make-overlay 27 61 nil t nil) + (make-overlay 14 16 nil nil nil) + (make-overlay 50 61 nil t nil) + (make-overlay 59 63 nil nil nil) + (make-overlay 36 34 nil t nil) + (make-overlay 35 29 nil nil nil) + (make-overlay 5 65 nil nil nil) + (make-overlay 20 61 nil nil t) + (make-overlay 10 42 nil nil nil) + (make-overlay 47 49 nil nil t) + (make-overlay 12 4 nil nil nil) + (make-overlay 32 24 nil t t) + (goto-char 11) + (insert ".") + (goto-char 32) + (delete-char 2) + (goto-char 61) + (insert ".........") + (goto-char 36) + (insert "........") + (goto-char 55) + (widen) + (narrow-to-region 8 55) + (goto-char 21) + (insert "....") + (goto-char 32) + (delete-char 15) + (goto-char 30) + (delete-char 5) + (goto-char 31) + (insert "......") + (goto-char 18) + (insert "..") + (goto-char 14) + (insert ".............") + (goto-char 34) + (insert "............") + (goto-char 51) + (widen) + (narrow-to-region 58 31) + (goto-char 50) + (delete-char 5) + (goto-char 53) + (insert ".........") + (goto-char 56) + (insert "...............") + (goto-char 45) + (delete-char 1) + (goto-char 67) + (insert "............") + (goto-char 84) + (insert "") + (goto-char 39) + (delete-char 27) + (goto-char 39) + (delete-char 21) + (goto-char 32) + (insert "............") + (goto-char 36) + (widen) + (narrow-to-region 7 37) + (goto-char 11) + (insert ".......") + (goto-char 21) + (delete-char 13) + (goto-char 15) + (insert "....") + (goto-char 9) + (insert ".............") + (goto-char 13) + (delete-char 21) + (goto-char 21) + (delete-char 6) + (goto-char 16) + (insert ".......") + (goto-char 22) + (insert "") + (goto-char 27) + (delete-char 0) + (should + (equal + (test-overlay-regions) + '((3 . 42) + (4 . 16) + (5 . 83) + (13 . 51) + (25 . 27)))))) + +(ert-deftest overlay-autogenerated-test-60 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 38 32 nil t nil) + (make-overlay 32 42 nil t nil) + (make-overlay 29 11 nil nil t) + (make-overlay 52 22 nil t t) + (make-overlay 39 59 nil t nil) + (make-overlay 41 30 nil t t) + (make-overlay 29 61 nil nil t) + (make-overlay 11 45 nil nil nil) + (make-overlay 46 17 nil nil t) + (make-overlay 35 51 nil t t) + (make-overlay 22 13 nil nil t) + (make-overlay 52 34 nil nil t) + (make-overlay 59 4 nil nil t) + (make-overlay 8 22 nil nil nil) + (make-overlay 4 49 nil nil nil) + (make-overlay 52 45 nil t t) + (goto-char 48) + (delete-char 16) + (goto-char 37) + (delete-char 8) + (goto-char 14) + (insert "...............") + (goto-char 40) + (delete-char 16) + (goto-char 19) + (insert ".........") + (goto-char 16) + (insert "......") + (goto-char 10) + (insert "........") + (goto-char 11) + (insert "...............") + (goto-char 22) + (insert ".") + (goto-char 62) + (delete-char 16) + (goto-char 14) + (delete-char 11) + (goto-char 47) + (insert "....") + (goto-char 33) + (insert ".............") + (goto-char 49) + (delete-char 13) + (goto-char 28) + (insert "..") + (goto-char 35) + (delete-char 13) + (goto-char 44) + (insert "....") + (goto-char 34) + (delete-char 14) + (goto-char 23) + (insert ".....") + (goto-char 25) + (delete-char 4) + (goto-char 33) + (insert ".....") + (goto-char 27) + (delete-char 3) + (goto-char 16) + (widen) + (narrow-to-region 36 37) + (goto-char 36) + (delete-char 1) + (goto-char 36) + (insert ".......") + (goto-char 37) + (widen) + (narrow-to-region 35 31) + (goto-char 34) + (delete-char 0) + (goto-char 31) + (delete-char 2) + (goto-char 31) + (widen) + (narrow-to-region 24 3) + (goto-char 22) + (delete-char 2) + (goto-char 22) + (insert ".............") + (goto-char 4) + (insert ".") + (should + (equal + (test-overlay-regions) + '((4 . 54) + (4 . 54) + (9 . 46)))))) + +(ert-deftest overlay-autogenerated-test-61 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 45 56 nil t nil) + (make-overlay 60 45 nil nil nil) + (make-overlay 26 8 nil t t) + (make-overlay 63 39 nil nil nil) + (make-overlay 18 11 nil t nil) + (make-overlay 22 64 nil nil t) + (make-overlay 8 41 nil nil t) + (make-overlay 6 51 nil t t) + (make-overlay 38 26 nil t t) + (make-overlay 7 46 nil t nil) + (make-overlay 2 42 nil nil t) + (make-overlay 44 64 nil nil nil) + (make-overlay 7 62 nil t nil) + (make-overlay 8 40 nil nil t) + (make-overlay 62 36 nil t t) + (make-overlay 61 27 nil nil nil) + (goto-char 21) + (delete-char 0) + (goto-char 8) + (insert "") + (goto-char 55) + (insert "......") + (goto-char 38) + (delete-char 25) + (goto-char 37) + (delete-char 4) + (goto-char 12) + (delete-char 4) + (goto-char 3) + (delete-char 26) + (goto-char 10) + (insert ".......") + (goto-char 18) + (delete-char 0) + (goto-char 16) + (insert ".............") + (goto-char 18) + (delete-char 3) + (goto-char 7) + (insert "...") + (goto-char 20) + (insert "........") + (goto-char 38) + (delete-char 0) + (goto-char 1) + (delete-char 36) + (goto-char 3) + (delete-char 1) + (goto-char 2) + (insert "......") + (goto-char 4) + (insert ".......") + (goto-char 2) + (insert "...........") + (goto-char 27) + (insert ".....") + (goto-char 15) + (insert "...............") + (goto-char 2) + (insert "......") + (goto-char 17) + (delete-char 8) + (goto-char 15) + (delete-char 7) + (goto-char 33) + (delete-char 5) + (goto-char 13) + (insert "...........") + (goto-char 34) + (insert "...............") + (goto-char 33) + (insert "") + (goto-char 51) + (insert "....") + (goto-char 14) + (delete-char 36) + (goto-char 16) + (delete-char 1) + (goto-char 14) + (delete-char 8) + (should + (equal + (test-overlay-regions) + '((1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 1) + (1 . 18) + (1 . 18)))))) + +(ert-deftest overlay-autogenerated-test-62 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 25 36 nil t nil) + (make-overlay 38 6 nil t nil) + (make-overlay 40 63 nil nil t) + (make-overlay 34 23 nil nil nil) + (make-overlay 48 46 nil nil nil) + (make-overlay 43 57 nil t t) + (make-overlay 6 53 nil t t) + (make-overlay 37 27 nil t t) + (make-overlay 8 39 nil t nil) + (make-overlay 62 6 nil nil nil) + (make-overlay 51 6 nil t t) + (make-overlay 58 11 nil nil t) + (make-overlay 19 25 nil t nil) + (make-overlay 13 8 nil nil nil) + (make-overlay 19 8 nil nil t) + (make-overlay 39 5 nil t t) + (goto-char 51) + (delete-char 5) + (goto-char 16) + (delete-char 9) + (goto-char 18) + (insert "") + (goto-char 47) + (delete-char 4) + (goto-char 24) + (insert ".........") + (goto-char 24) + (insert ".....") + (goto-char 18) + (insert "...........") + (goto-char 5) + (delete-char 6) + (goto-char 30) + (insert "...........") + (goto-char 8) + (insert ".............") + (goto-char 78) + (insert "............") + (goto-char 67) + (insert "") + (goto-char 58) + (insert "") + (goto-char 5) + (insert ".") + (goto-char 79) + (widen) + (narrow-to-region 51 55) + (goto-char 51) + (insert "....") + (goto-char 58) + (widen) + (narrow-to-region 36 37) + (goto-char 37) + (insert "....") + (goto-char 40) + (insert ".......") + (goto-char 47) + (delete-char 1) + (goto-char 43) + (delete-char 4) + (goto-char 37) + (insert "........") + (goto-char 49) + (insert "............") + (goto-char 42) + (widen) + (narrow-to-region 75 111) + (goto-char 104) + (widen) + (narrow-to-region 21 95) + (goto-char 22) + (widen) + (narrow-to-region 64 79) + (goto-char 64) + (delete-char 0) + (goto-char 68) + (insert "........") + (goto-char 82) + (insert "") + (goto-char 81) + (insert "........") + (goto-char 92) + (delete-char 2) + (goto-char 87) + (insert ".") + (should + (equal + (test-overlay-regions) + '((5 . 145) + (5 . 148) + (6 . 118) + (6 . 119) + (6 . 119) + (6 . 143) + (6 . 143) + (24 . 114) + (24 . 116) + (63 . 117)))))) + +(ert-deftest overlay-autogenerated-test-63 nil + (with-temp-buffer + (insert "................................................................") + (make-overlay 9 49 nil t nil) + (make-overlay 9 16 nil nil nil) + (make-overlay 64 2 nil t t) + (make-overlay 17 31 nil nil t) + (make-overlay 24 51 nil nil nil) + (make-overlay 27 56 nil t t) + (make-overlay 21 4 nil nil nil) + (make-overlay 24 29 nil t t) + (make-overlay 4 63 nil nil t) + (make-overlay 34 49 nil t nil) + (make-overlay 19 47 nil nil t) + (make-overlay 8 50 nil t nil) + (make-overlay 49 61 nil t nil) + (make-overlay 52 10 nil t t) + (make-overlay 64 30 nil t nil) + (make-overlay 5 13 nil t nil) + (goto-char 27) + (insert "........") + (goto-char 42) + (insert "......") + (goto-char 48) + (insert "....") + (goto-char 55) + (widen) + (narrow-to-region 10 5) + (goto-char 8) + (insert ".............") + (goto-char 19) + (insert "......") + (goto-char 19) + (delete-char 3) + (goto-char 8) + (delete-char 3) + (goto-char 9) + (insert ".......") + (goto-char 29) + (insert "...............") + (goto-char 38) + (insert ".......") + (goto-char 34) + (insert "......") + (goto-char 28) + (delete-char 20) + (goto-char 22) + (insert "............") + (goto-char 21) + (delete-char 23) + (goto-char 25) + (delete-char 2) + (goto-char 19) + (delete-char 2) + (goto-char 12) + (delete-char 6) + (goto-char 12) + (delete-char 0) + (goto-char 13) + (delete-char 0) + (goto-char 12) + (insert "........") + (goto-char 23) + (delete-char 2) + (goto-char 5) + (insert "...............") + (goto-char 28) + (delete-char 0) + (goto-char 16) + (insert "..........") + (goto-char 8) + (delete-char 17) + (goto-char 27) + (delete-char 0) + (goto-char 12) + (insert ".") + (goto-char 14) + (delete-char 12) + (goto-char 11) + (insert "..............") + (goto-char 34) + (insert "") + (goto-char 25) + (delete-char 8) + (should + (equal + (test-overlay-regions) + '((2 . 98) + (4 . 37) + (4 . 97) + (25 . 29) + (25 . 32) + (25 . 84)))))) + ;;; buffer-tests.el ends here