[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 71589b101c: Merge remote-tracking branch 'origin/feature/noverlay
From: |
Stefan Monnier |
Subject: |
master 71589b101c: Merge remote-tracking branch 'origin/feature/noverlay' |
Date: |
Fri, 28 Oct 2022 17:44:58 -0400 (EDT) |
branch: master
commit 71589b101ccbec67fa2741856ee0add5752dea72
Merge: 69121c33e4 9d7ba2b199
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>
Merge remote-tracking branch 'origin/feature/noverlay'
---
.clang-format | 2 +-
configure.ac | 1 +
src/Makefile.in | 39 +-
src/alloc.c | 60 +-
src/buffer.c | 1505 +++-----
src/buffer.h | 110 +-
src/editfns.c | 67 +-
src/eval.c | 1 +
src/fileio.c | 3 +-
src/fns.c | 15 +-
src/indent.c | 5 +-
src/insdel.c | 12 -
src/intervals.c | 4 +-
src/itree.c | 1421 +++++++
src/itree.h | 181 +
src/keyboard.c | 4 +-
src/lisp.h | 9 +-
src/pdumper.c | 68 +-
src/print.c | 14 +-
src/textprop.c | 57 +-
src/window.h | 10 +
src/xdisp.c | 195 +-
src/xfaces.c | 17 +-
test/manual/noverlay/.gitignore | 1 +
test/manual/noverlay/Makefile.in | 32 +
test/manual/noverlay/check-sanitize.sh | 11 +
test/manual/noverlay/emacs-compat.h | 52 +
test/manual/noverlay/itree-tests.c | 1381 +++++++
test/manual/noverlay/many-errors.py | 2480 ++++++++++++
test/manual/noverlay/overlay-perf.el | 764 ++++
test/src/buffer-tests.el | 6665 ++++++++++++++++++++++++++++++++
31 files changed, 13775 insertions(+), 1411 deletions(-)
diff --git a/.clang-format b/.clang-format
index 44200a3995..ac9f95c88a 100644
--- a/.clang-format
+++ b/.clang-format
@@ -6,7 +6,7 @@ BreakBeforeBinaryOperators: All
BreakBeforeBraces: GNU
ColumnLimit: 70
ContinuationIndentWidth: 2
-ForEachMacros: [FOR_EACH_TAIL, FOR_EACH_TAIL_SAFE]
+ForEachMacros: [FOR_EACH_TAIL, FOR_EACH_TAIL_SAFE, ITREE_FOREACH]
IncludeCategories:
- Regex: '^<config\.h>$'
Priority: -1
diff --git a/configure.ac b/configure.ac
index 2d84344050..63cb9c412e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6708,6 +6708,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
opt_makefile=test/infra/Makefile
if test -f "$srcdir/$opt_makefile.in"; then
diff --git a/src/Makefile.in b/src/Makefile.in
index 1f941874ea..059e6c717b 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -426,25 +426,26 @@ ALL_CXX_CFLAGS = $(EMACS_CFLAGS) \
## lastfile must follow all files whose initialized data areas should
## be dumped as pure by dump-emacs.
-base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
- charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
- $(CM_OBJ) term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
- emacs.o keyboard.o macros.o keymap.o sysdep.o \
- bignum.o buffer.o filelock.o insdel.o marker.o \
- minibuf.o fileio.o dired.o \
- cmds.o casetab.o casefiddle.o indent.o search.o regex-emacs.o undo.o \
- alloc.o pdumper.o data.o doc.o editfns.o callint.o \
- eval.o floatfns.o fns.o sort.o font.o print.o lread.o $(MODULES_OBJ) \
- syntax.o $(UNEXEC_OBJ) bytecode.o comp.o $(DYNLIB_OBJ) \
- process.o gnutls.o callproc.o \
- region-cache.o sound.o timefns.o atimer.o \
+base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o
\
+ charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
+ $(CM_OBJ) term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
+ emacs.o keyboard.o macros.o keymap.o sysdep.o \
+ bignum.o buffer.o filelock.o insdel.o marker.o \
+ minibuf.o fileio.o dired.o \
+ cmds.o casetab.o casefiddle.o indent.o search.o regex-emacs.o undo.o \
+ alloc.o pdumper.o data.o doc.o editfns.o callint.o \
+ eval.o floatfns.o fns.o sort.o font.o print.o lread.o $(MODULES_OBJ) \
+ syntax.o $(UNEXEC_OBJ) bytecode.o comp.o $(DYNLIB_OBJ) \
+ process.o gnutls.o callproc.o \
+ region-cache.o sound.o timefns.o atimer.o \
doprnt.o intervals.o textprop.o composite.o xml.o lcms.o $(NOTIFY_OBJ) \
- $(XWIDGETS_OBJ) \
- profiler.o decompress.o \
- thread.o systhread.o sqlite.o \
- $(if $(HYBRID_MALLOC),sheap.o) \
- $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
- $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) \
+ $(XWIDGETS_OBJ) \
+ profiler.o decompress.o \
+ thread.o systhread.o sqlite.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) $(JSON_OBJ) \
$(HAIKU_OBJ) $(PGTK_OBJ)
doc_obj = $(base_obj) $(NS_OBJC_OBJ)
obj = $(doc_obj) $(HAIKU_CXX_OBJ)
@@ -498,7 +499,7 @@ all: ../native-lisp
endif
.PHONY: all
-dmpstruct_headers=$(srcdir)/lisp.h $(srcdir)/buffer.h \
+dmpstruct_headers=$(srcdir)/lisp.h $(srcdir)/buffer.h $(srcdir)/itree.h \
$(srcdir)/intervals.h $(srcdir)/charset.h $(srcdir)/bignum.h
ifeq ($(CHECK_STRUCTS),true)
pdumper.o: dmpstruct.h
diff --git a/src/alloc.c b/src/alloc.c
index 419c5e558b..f69c65dedc 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1,7 +1,6 @@
/* Storage allocation and gc for GNU Emacs Lisp interpreter.
-Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2022 Free Software
-Foundation, Inc.
+Copyright (C) 1985-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -46,6 +45,7 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include "blockinput.h"
#include "pdumper.h"
#include "termhooks.h" /* For struct terminal. */
+#include "itree.h"
#ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
@@ -3129,6 +3129,11 @@ cleanup_vector (struct Lisp_Vector *vector)
if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BIGNUM))
mpz_clear (PSEUDOVEC_STRUCT (vector, Lisp_Bignum)->value);
+ else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_OVERLAY))
+ {
+ struct Lisp_Overlay *ol = PSEUDOVEC_STRUCT (vector, Lisp_Overlay);
+ xfree (ol->interval);
+ }
else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FINALIZER))
unchain_finalizer (PSEUDOVEC_STRUCT (vector, Lisp_Finalizer));
else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT))
@@ -3697,18 +3702,20 @@ build_symbol_with_pos (Lisp_Object symbol, Lisp_Object
position)
return val;
}
-/* Return a new overlay with specified START, END and PLIST. */
+/* Return a new (deleted) overlay with PLIST. */
Lisp_Object
-build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist)
+build_overlay (bool front_advance, bool rear_advance,
+ Lisp_Object plist)
{
struct Lisp_Overlay *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Overlay, plist,
PVEC_OVERLAY);
Lisp_Object overlay = make_lisp_ptr (p, Lisp_Vectorlike);
- OVERLAY_START (overlay) = start;
- OVERLAY_END (overlay) = end;
+ struct itree_node *node = xmalloc (sizeof (*node));
+ itree_node_init (node, front_advance, rear_advance, overlay);
+ p->interval = node;
+ p->buffer = NULL;
set_overlay_plist (overlay, plist);
- p->next = NULL;
return overlay;
}
@@ -5938,8 +5945,7 @@ visit_buffer_root (struct gc_root_visitor visitor,
/* Buffers that are roots don't have intervals, an undo list, or
other constructs that real buffers have. */
eassert (buffer->base_buffer == NULL);
- eassert (buffer->overlays_before == NULL);
- eassert (buffer->overlays_after == NULL);
+ eassert (buffer->overlays == NULL);
/* Visit the buffer-locals. */
visit_vectorlike_root (visitor, (struct Lisp_Vector *) buffer, type);
@@ -6273,6 +6279,11 @@ garbage_collect (void)
image_prune_animation_caches (false);
#endif
+ /* ELisp code run by `gc-post-hook' could result in itree iteration,
+ which must not happen while the itree is already busy. See
+ bug#58639. */
+ eassert (!itree_iterator_busy_p ());
+
if (!NILP (Vpost_gc_hook))
{
specpdl_ref gc_count = inhibit_garbage_collection ();
@@ -6495,16 +6506,25 @@ mark_char_table (struct Lisp_Vector *ptr, enum
pvec_type pvectype)
/* Mark the chain of overlays starting at PTR. */
static void
-mark_overlay (struct Lisp_Overlay *ptr)
+mark_overlay (struct Lisp_Overlay *ov)
{
- for (; ptr && !vectorlike_marked_p (&ptr->header); ptr = ptr->next)
- {
- set_vectorlike_marked (&ptr->header);
- /* These two are always markers and can be marked fast. */
- set_vectorlike_marked (&XMARKER (ptr->start)->header);
- set_vectorlike_marked (&XMARKER (ptr->end)->header);
- mark_object (ptr->plist);
- }
+ /* We don't mark the `interval_node` object, because it is managed manually
+ rather than by the GC. */
+ eassert (BASE_EQ (ov->interval->data, make_lisp_ptr (ov, Lisp_Vectorlike)));
+ set_vectorlike_marked (&ov->header);
+ mark_object (ov->plist);
+}
+
+/* Mark the overlay subtree rooted at NODE. */
+
+static void
+mark_overlays (struct itree_node *node)
+{
+ if (node == NULL)
+ return;
+ mark_object (node->data);
+ mark_overlays (node->left);
+ mark_overlays (node->right);
}
/* Mark Lisp_Objects and special pointers in BUFFER. */
@@ -6528,8 +6548,8 @@ mark_buffer (struct buffer *buffer)
if (!BUFFER_LIVE_P (buffer))
mark_object (BVAR (buffer, undo_list));
- mark_overlay (buffer->overlays_before);
- mark_overlay (buffer->overlays_after);
+ if (buffer->overlays)
+ mark_overlays (buffer->overlays->root);
/* If this is an indirect buffer, mark its base buffer. */
if (buffer->base_buffer &&
diff --git a/src/buffer.c b/src/buffer.c
index d4a0c37bed..b67b989326 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1,7 +1,6 @@
/* Buffer manipulation primitives for GNU Emacs.
-Copyright (C) 1985-1989, 1993-1995, 1997-2022 Free Software Foundation,
-Inc.
+Copyright (C) 1985-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -44,6 +43,7 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include "keymap.h"
#include "frame.h"
#include "xwidget.h"
+#include "itree.h"
#include "pdumper.h"
#ifdef WINDOWSNT
@@ -116,7 +116,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);
static Lisp_Object buffer_local_variables_1 (struct buffer *buf, int offset,
Lisp_Object sym);
@@ -638,52 +638,33 @@ even if it is dead. The return value is never nil. */)
return buffer;
}
-
-/* Return a list of overlays which is a copy of the overlay list
- LIST, but for buffer B. */
-
-static struct Lisp_Overlay *
-copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
+static void
+add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov,
+ ptrdiff_t begin, ptrdiff_t end)
{
- struct Lisp_Overlay *result = NULL, *tail = NULL;
-
- 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;
+ eassert (! ov->buffer);
+ if (! b->overlays)
+ b->overlays = itree_create ();
+ ov->buffer = b;
+ itree_insert (b->overlays, ov->interval, begin, end);
}
-/* Set an appropriate overlay of B. */
+/* Copy overlays of buffer FROM to buffer TO. */
static void
-set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o)
+copy_overlays (struct buffer *from, struct buffer *to)
{
- b->overlays_before = o;
-}
+ eassert (to && ! to->overlays);
+ struct itree_node *node;
-static void
-set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o)
-{
- b->overlays_after = o;
+ ITREE_FOREACH (node, from->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
+ {
+ Lisp_Object ov = node->data;
+ Lisp_Object copy = build_overlay (node->front_advance,
+ node->rear_advance,
+ Fcopy_sequence (OVERLAY_PLIST (ov)));
+ add_buffer_overlay (to, XOVERLAY (copy), node->begin, node->end);
+ }
}
bool
@@ -726,8 +707,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. */
@@ -926,17 +906,25 @@ does not run the hooks `kill-buffer-hook',
return buf;
}
-/* Mark OV as no longer associated with B. */
+static void
+remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov)
+{
+ eassert (b->overlays);
+ eassert (ov->buffer == b);
+ itree_remove (ov->buffer->overlays, ov->interval);
+ ov->buffer = NULL;
+}
+
+/* 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. */
@@ -944,26 +932,94 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
void
delete_all_overlays (struct buffer *b)
{
- struct Lisp_Overlay *ov, *next;
+ struct itree_node *node;
+
+ if (! b->overlays)
+ return;
- /* 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)
+ /* FIXME: This loop sets the overlays' `buffer` field to NULL but
+ doesn't set the itree_nodes' `parent`, `left` and `right`
+ fields accordingly. I believe it's harmless, but a bit untidy since
+ other parts of the code are careful to set those fields to NULL when
+ the overlay is deleted.
+ Of course, we can't set them to NULL from within the iteration
+ because the iterator may need them (tho we could if we added
+ an ITREE_POST_ORDER iteration order). */
+ ITREE_FOREACH (node, b->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
{
- 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;
}
+ itree_clear (b->overlays);
+}
- for (ov = b->overlays_after; ov; ov = next)
+static void
+free_buffer_overlays (struct buffer *b)
+{
+ /* Actually this does not free any overlay, but the tree only. --ap */
+ if (b->overlays)
{
- drop_overlay (b, ov);
- next = ov->next;
- ov->next = NULL;
+ itree_destroy (b->overlays);
+ b->overlays = NULL;
}
+}
- set_buffer_overlays_before (b, NULL);
- set_buffer_overlays_after (b, NULL);
+/* Adjust the position of overlays in the current buffer according to
+ MULTIBYTE.
+
+ Assume that positions currently correspond to byte positions, if
+ MULTIBYTE is true and to character positions if not.
+*/
+
+static void
+set_overlays_multibyte (bool multibyte)
+{
+ if (! current_buffer->overlays || Z == Z_BYTE)
+ return;
+
+ struct itree_node **nodes = NULL;
+ struct itree_tree *tree = current_buffer->overlays;
+ const intmax_t size = itree_size (tree);
+
+ /* We can't use `interval_node_set_region` at the same time
+ as we iterate over the itree, so we need an auxiliary storage
+ to keep the list of nodes. */
+ USE_SAFE_ALLOCA;
+ SAFE_NALLOCA (nodes, 1, size);
+ {
+ struct itree_node *node, **cursor = nodes;
+ ITREE_FOREACH (node, tree, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
+ *(cursor++) = node;
+ }
+
+ for (int i = 0; i < size; ++i, ++nodes)
+ {
+ struct itree_node * const node = *nodes;
+
+ if (multibyte)
+ {
+ ptrdiff_t begin = itree_node_begin (tree, node);
+ ptrdiff_t end = itree_node_end (tree, node);
+
+ /* This models the behavior of markers. (The behavior of
+ text-intervals differs slightly.) */
+ while (begin < Z_BYTE
+ && !CHAR_HEAD_P (FETCH_BYTE (begin)))
+ begin++;
+ while (end < Z_BYTE
+ && !CHAR_HEAD_P (FETCH_BYTE (end)))
+ end++;
+ itree_node_set_region (tree, node, BYTE_TO_CHAR (begin),
+ BYTE_TO_CHAR (end));
+ }
+ else
+ {
+ itree_node_set_region (tree, node, CHAR_TO_BYTE (node->begin),
+ CHAR_TO_BYTE (node->end));
+ }
+ }
+ SAFE_FREE ();
}
/* Reinitialize everything about a buffer except its name and contents
@@ -993,9 +1049,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);
@@ -1978,10 +2032,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. */
- set_buffer_overlays_before (b, NULL);
- set_buffer_overlays_after (b, 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
@@ -2381,6 +2433,23 @@ advance_to_char_boundary (ptrdiff_t byte_pos)
return byte_pos;
}
+static void
+swap_buffer_overlays (struct buffer *buffer, struct buffer *other)
+{
+ struct itree_node *node;
+
+ ITREE_FOREACH (node, buffer->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
+ XOVERLAY (node->data)->buffer = other;
+
+ ITREE_FOREACH (node, other->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
+ XOVERLAY (node->data)->buffer = buffer;
+
+ /* 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.
@@ -2452,9 +2521,6 @@ results, see Info node `(elisp)Swapping Text'. */)
current_buffer->prevent_redisplay_optimizations_p = 1;
other_buffer->prevent_redisplay_optimizations_p = 1;
swapfield (long_line_optimizations_p, bool_bf);
- 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_ (mark_active, Lisp_Object); /* Belongs with the `mark'. */
@@ -2481,6 +2547,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)
@@ -2597,7 +2664,8 @@ current buffer is cleared. */)
/* Do this first, so it can use CHAR_TO_BYTE
to calculate the old correspondences. */
- set_intervals_multibyte (0);
+ set_intervals_multibyte (false);
+ set_overlays_multibyte (false);
bset_enable_multibyte_characters (current_buffer, Qnil);
@@ -2784,7 +2852,8 @@ current buffer is cleared. */)
/* FIXME: Is it worth the trouble, really? Couldn't we just throw
away all the text-properties instead of trying to guess how
to adjust them? AFAICT the result is not reliable anyway. */
- set_intervals_multibyte (1);
+ set_intervals_multibyte (true);
+ set_overlays_multibyte (true);
}
if (!EQ (old_undo, Qt))
@@ -2867,272 +2936,159 @@ the normal hook `change-major-mode-hook'. */)
}
-/* 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 accessible
+ part of the buffer.
+
+ If TRAILING is true, include overlays that begin at END, provided
+ END denotes the position at the end of the accessible part 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, bool trailing,
+ ptrdiff_t *next_ptr)
{
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 (struct Lisp_Overlay *tail = current_buffer->overlays_before;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- Lisp_Object start = OVERLAY_START (overlay);
- Lisp_Object end = OVERLAY_END (overlay);
- ptrdiff_t endpos = OVERLAY_POSITION (end);
- if (endpos < pos)
- {
- if (prev < endpos)
- prev = endpos;
- break;
- }
- ptrdiff_t 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;
- }
+ Lisp_Object *vec = *vec_ptr;
+ struct itree_node *node;
- if (!inhibit_storing)
- vec[idx] = overlay;
- /* Keep counting overlays even if we can't return them all. */
- idx++;
- }
- else if (startpos < next)
- next = startpos;
- }
+ /* Extend the search range if overlays beginning at ZV are
+ wanted. */
+ ptrdiff_t search_end = ZV;
+ if (end >= ZV && (empty || trailing))
+ ++search_end;
- for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
- tail; tail = tail->next)
+ ITREE_FOREACH (node, current_buffer->overlays, beg, search_end,
+ ASCENDING)
{
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- Lisp_Object start = OVERLAY_START (overlay);
- Lisp_Object end = OVERLAY_END (overlay);
- ptrdiff_t startpos = OVERLAY_POSITION (start);
- if (pos < startpos)
- {
- if (startpos < next)
- next = startpos;
- break;
- }
- ptrdiff_t 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);
+ ITREE_FOREACH_ABORT ();
+ break;
+ }
+ else if (node->begin == end)
+ {
+ next = node->begin;
+ if ((! empty || end < ZV) && beg < end)
+ {
+ ITREE_FOREACH_ABORT ();
+ break;
+ }
+ if (empty && node->begin != node->end)
+ continue;
+ }
- 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++;
}
-
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, true, 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)
{
- 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 == ZV;
+ struct itree_node *node;
- for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
- tail; tail = tail->next)
+ ITREE_FOREACH (node, current_buffer->overlays, pos, next, ASCENDING)
{
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- Lisp_Object ostart = OVERLAY_START (overlay);
- Lisp_Object oend = OVERLAY_END (overlay);
- ptrdiff_t endpos = OVERLAY_POSITION (oend);
- if (endpos < beg)
- {
- if (prev < endpos)
- prev = endpos;
- break;
- }
- ptrdiff_t 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;
+ 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;
+ ITREE_FOREACH_ABORT ();
+ break;
+ }
+ else if (node->begin < node->end && node->end < next)
+ {
+ next = node->end;
+ ITREE_FOREACH_NARROW (pos, next);
+ }
}
- for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- Lisp_Object ostart = OVERLAY_START (overlay);
- Lisp_Object oend = OVERLAY_END (overlay);
- ptrdiff_t startpos = OVERLAY_POSITION (ostart);
- if (end < startpos)
- {
- if (startpos < next)
- next = startpos;
- break;
- }
- ptrdiff_t 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;
- }
+ return next;
+}
- if (!inhibit_storing)
- vec[idx] = overlay;
- idx++;
- }
- else if (endpos < beg && endpos > prev)
- prev = endpos;
+ptrdiff_t
+previous_overlay_change (ptrdiff_t pos)
+{
+ struct itree_node *node;
+ ptrdiff_t prev = BEGV;
+
+ ITREE_FOREACH (node, current_buffer->overlays, prev, pos, DESCENDING)
+ {
+ if (node->end < pos)
+ prev = node->end;
+ else
+ prev = max (prev, node->begin);
+ ITREE_FOREACH_NARROW (prev, pos);
}
- 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];
@@ -3140,11 +3096,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, false, 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, false, NULL);
}
for (i = 0; i < n; ++i)
@@ -3169,11 +3125,11 @@ disable_line_numbers_overlay_at_eob (void)
size = ARRAYELTS (vbuf);
v = vbuf;
- n = overlays_in (ZV, ZV, 0, &v, &size, NULL, NULL);
+ n = overlays_in (ZV, ZV, 0, &v, &size, false, false, NULL);
if (n > size)
{
SAFE_NALLOCA (v, 1, n);
- overlays_in (ZV, ZV, 0, &v, &n, NULL, NULL);
+ overlays_in (ZV, ZV, 0, &v, &n, false, false, NULL);
}
for (i = 0; i < n; ++i)
@@ -3186,47 +3142,28 @@ 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)
{
- for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- eassert (OVERLAYP (overlay));
+ struct itree_node *node;
- ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
- if (endpos < pos)
- break;
- if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
- return 1;
- }
-
- for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- eassert (OVERLAYP (overlay));
-
- ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- if (pos < startpos)
- break;
- if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
- return 1;
- }
- return 0;
+ /* We need to find overlays ending in pos, as well as empty ones at
+ pos. */
+ ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
+ if (node->begin == pos || node->end == pos)
+ {
+ ITREE_FOREACH_ABORT ();
+ return true;
+ }
+ return false;
}
-
-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;
@@ -3255,6 +3192,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 (FIXNUMP (tem))
+ {
+ item->priority = XFIXNUM (tem);
+ item->spriority = 0;
+ }
+ else if (CONSP (tem))
+ {
+ Lisp_Object car = XCAR (tem);
+ Lisp_Object cdr = XCDR (tem);
+ item->priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
+ item->spriority = FIXNUMP (cdr) ? XFIXNUM (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. */
@@ -3271,47 +3235,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 (FIXNUMP (tem))
- {
- sortvec[j].priority = XFIXNUM (tem);
- sortvec[j].spriority = 0;
- }
- else if (CONSP (tem))
- {
- Lisp_Object car = XCAR (tem);
- Lisp_Object cdr = XCDR (tem);
- sortvec[j].priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
- sortvec[j].spriority = FIXNUMP (cdr) ? XFIXNUM (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++;
}
}
@@ -3426,25 +3361,27 @@ ptrdiff_t
overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
{
bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
+ struct itree_node *node;
overlay_heads.used = overlay_heads.bytes = 0;
overlay_tails.used = overlay_tails.bytes = 0;
- for (struct Lisp_Overlay *ov = current_buffer->overlays_before;
- ov; ov = ov->next)
+
+ ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
{
- Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
+ Lisp_Object overlay = node->data;
eassert (OVERLAYP (overlay));
- ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
- if (endpos < pos)
- break;
+ ptrdiff_t startpos = node->begin;
+ ptrdiff_t endpos = node->end;
+
if (endpos != pos && startpos != pos)
continue;
Lisp_Object window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
Lisp_Object str;
+ /* FIXME: Are we really sure that `record_overlay_string` can
+ never cause a non-local exit? */
if (startpos == pos
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
record_overlay_string (&overlay_heads, str,
@@ -3459,36 +3396,7 @@ overlay_strings (ptrdiff_t pos, struct window *w,
unsigned char **pstr)
Foverlay_get (overlay, Qpriority),
endpos - startpos);
}
- for (struct Lisp_Overlay *ov = current_buffer->overlays_after;
- ov; ov = ov->next)
- {
- Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
- eassert (OVERLAYP (overlay));
- ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
- if (startpos > pos)
- break;
- if (endpos != pos && startpos != pos)
- continue;
- Lisp_Object window = Foverlay_get (overlay, Qwindow);
- if (WINDOWP (window) && XWINDOW (window) != w)
- continue;
- Lisp_Object str;
- 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);
@@ -3543,384 +3451,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)
-{
- struct Lisp_Overlay *prev, *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 (struct Lisp_Overlay *tail = buf->overlays_before;
- tail; prev = tail, tail = next)
- {
- next = tail->next;
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- eassert (OVERLAYP (overlay));
-
- Lisp_Object beg = OVERLAY_START (overlay);
- Lisp_Object 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 otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
- eassert (OVERLAYP (otheroverlay));
-
- Lisp_Object 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 (struct Lisp_Overlay *tail = buf->overlays_after;
- tail; prev = tail, tail = next)
- {
- next = tail->next;
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- eassert (OVERLAYP (overlay));
-
- Lisp_Object beg = OVERLAY_START (overlay);
- Lisp_Object 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 otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
- eassert (OVERLAYP (otheroverlay));
-
- Lisp_Object 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;
+ itree_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)
-{
- struct Lisp_Overlay *before_list UNINIT;
- struct Lisp_Overlay *after_list UNINIT;
- /* 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 *parent;
-
- /* 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. */
- parent = NULL;
- for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
-
- ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
- ptrdiff_t 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_fixnum (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;
- }
- else
- parent = tail;
- }
- parent = NULL;
- for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
-
- ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- ptrdiff_t 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_fixnum (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;
- }
- else
- parent = tail;
- }
-
- /* 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
- && (tem = make_lisp_ptr (tail, Lisp_Vectorlike),
- (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)
- return;
- if (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)
- {
- tem = make_lisp_ptr (tail, Lisp_Vectorlike);
- 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;
- }
+ itree_delete_gap (current_buffer->overlays, pos, length);
}
+
DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
doc: /* Return t if OBJECT is an overlay. */)
@@ -3942,7 +3492,7 @@ for the rear of the overlay advance when text is inserted
there
(Lisp_Object beg, Lisp_Object end, Lisp_Object buffer,
Lisp_Object front_advance, Lisp_Object rear_advance)
{
- Lisp_Object overlay;
+ Lisp_Object ov;
struct buffer *b;
if (NILP (buffer))
@@ -3950,6 +3500,10 @@ for the rear of the overlay advance when text is
inserted there
else
CHECK_BUFFER (buffer);
+ b = XBUFFER (buffer);
+ if (! BUFFER_LIVE_P (b))
+ error ("Attempt to create overlay in a dead buffer");
+
if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
signal_error ("Marker points into wrong buffer", beg);
if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
@@ -3964,39 +3518,16 @@ for the rear of the overlay advance when text is
inserted there
temp = beg; beg = 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);
+ ptrdiff_t obeg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
+ ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), BUF_Z (b));
+ ov = build_overlay (! NILP (front_advance),
+ ! NILP (rear_advance), Qnil);
+ add_buffer_overlay (b, XOVERLAY (ov), obeg, oend);
/* 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. */
@@ -4018,35 +3549,6 @@ modify_overlay (struct buffer *buf, ptrdiff_t start,
ptrdiff_t end)
modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1);
}
-/* 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.
@@ -4057,12 +3559,11 @@ buffer. */)
struct buffer *b, *ob = 0;
Lisp_Object obuffer;
specpdl_ref count = SPECPDL_INDEX ();
- ptrdiff_t n_beg, n_end;
ptrdiff_t o_beg UNINIT, o_end UNINIT;
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);
@@ -4084,37 +3585,31 @@ buffer. */)
temp = beg; beg = end; end = temp;
}
- specbind (Qinhibit_quit, Qt);
+ specbind (Qinhibit_quit, Qt); /* FIXME: Why? */
- obuffer = Fmarker_buffer (OVERLAY_START (overlay));
+ obuffer = Foverlay_buffer (overlay);
b = XBUFFER (buffer);
+ ptrdiff_t n_beg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
+ ptrdiff_t n_end = clip_to_bounds (n_beg, XFIXNUM (end), BUF_Z (b));
+
if (!NILP (obuffer))
{
ob = XBUFFER (obuffer);
- o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
- o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
+ o_beg = OVERLAY_START (overlay);
+ o_end = OVERLAY_END (overlay);
+ }
- unchain_both (ob, overlay);
+ if (! EQ (buffer, obuffer))
+ {
+ if (! NILP (obuffer))
+ remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay));
+ add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay), n_beg, n_end);
}
else
- /* An overlay not associated with any buffer will normally have its
- `next' field set to NULL, but not always: when killing a buffer,
- we just set its overlays_after and overlays_before to NULL without
- manually setting each overlay's `next' field to NULL.
- Let's correct it here, to simplify subsequent assertions.
- FIXME: Maybe the better fix is to change `kill-buffer'!? */
- XOVERLAY (overlay)->next = NULL;
-
- eassert (XOVERLAY (overlay)->next == NULL);
-
- /* Set the overlay boundaries, which may clip them. */
- Fset_marker (OVERLAY_START (overlay), beg, buffer);
- Fset_marker (OVERLAY_END (overlay), end, buffer);
-
- n_beg = marker_position (OVERLAY_START (overlay));
- n_end = marker_position (OVERLAY_END (overlay));
+ itree_node_set_region (b->overlays, XOVERLAY (overlay)->interval,
+ n_beg, n_end);
/* If the overlay has changed buffers, do a thorough redisplay. */
if (!BASE_EQ (buffer, obuffer))
@@ -4137,8 +3632,6 @@ buffer. */)
modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end));
}
- eassert (XOVERLAY (overlay)->next == NULL);
-
/* Delete the overlay if it is empty after clipping and has the
evaporate property. */
if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
@@ -4148,26 +3641,10 @@ buffer. */)
contrary to `Fdelete_overlay's assumptions.
- Most of the work done by Fdelete_overlay has already been done
here for other reasons. */
- drop_overlay (XBUFFER (buffer), XOVERLAY (overlay));
+ drop_overlay (XOVERLAY (overlay));
return unbind_to (count, 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);
}
@@ -4175,21 +3652,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;
specpdl_ref 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
@@ -4220,8 +3694,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_fixnum (OVERLAY_START (overlay));
}
DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
@@ -4229,8 +3705,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_fixnum (OVERLAY_END (overlay));
}
DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
@@ -4238,9 +3716,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,
@@ -4251,7 +3736,7 @@ OVERLAY. */)
{
CHECK_OVERLAY (overlay);
- return Fcopy_sequence (XOVERLAY (overlay)->plist);
+ return Fcopy_sequence (OVERLAY_PLIST (overlay));
}
@@ -4279,8 +3764,7 @@ interest. */)
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len. */
- noverlays = overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len,
- NULL, NULL, 0);
+ noverlays = overlays_at (XFIXNUM (pos), true, &overlay_vec, &len, NULL);
if (!NILP (sorted))
noverlays = sort_overlays (overlay_vec, noverlays,
@@ -4325,7 +3809,7 @@ end of the accessible part of the buffer. */)
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len. */
noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len,
- NULL, NULL);
+ true, false, NULL);
/* Make a list of them all. */
result = Flist (noverlays, overlay_vec);
@@ -4341,39 +3825,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_FIXNUM_COERCE_MARKER (pos);
if (!buffer_has_overlays ())
return make_fixnum (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 (XFIXNUM (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_fixnum (endpos);
+ return make_fixnum (next_overlay_change (XFIXNUM (pos)));
}
DEFUN ("previous-overlay-change", Fprevious_overlay_change,
@@ -4383,32 +3840,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_FIXNUM_COERCE_MARKER (pos);
if (!buffer_has_overlays ())
return make_fixnum (BEGV);
- /* At beginning of buffer, we know the answer;
- avoid bug subtracting 1 below. */
- if (XFIXNUM (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 (XFIXNUM (pos), 1, &overlay_vec, &len,
- 0, &prevpos, 1);
-
- xfree (overlay_vec);
- return make_fixnum (prevpos);
+ return make_fixnum (previous_overlay_change (XFIXNUM (pos)));
}
+
/* These functions are for debugging overlays. */
@@ -4418,19 +3858,16 @@ 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)
{
- Lisp_Object before = Qnil, after = Qnil;
+ Lisp_Object overlays = Qnil;
+ struct itree_node *node;
- for (struct Lisp_Overlay *ol = current_buffer->overlays_before;
- ol; ol = ol->next)
- before = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), before);
- for (struct Lisp_Overlay *ol = current_buffer->overlays_after;
- ol; ol = ol->next)
- after = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), after);
+ ITREE_FOREACH (node, current_buffer->overlays, BEG, Z, DESCENDING)
+ overlays = Fcons (node->data, overlays);
- return Fcons (Fnreverse (before), Fnreverse (after));
+ return Fcons (overlays, Qnil);
}
DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
@@ -4439,11 +3876,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_FIXNUM_COERCE_MARKER (pos);
-
- p = clip_to_bounds (PTRDIFF_MIN, XFIXNUM (pos), PTRDIFF_MAX);
- recenter_overlay_lists (current_buffer, p);
+ /* Noop */
return Qnil;
}
@@ -4460,12 +3894,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));
@@ -4481,15 +3916,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);
}
@@ -4560,70 +3994,33 @@ report_overlay_modification (Lisp_Object start,
Lisp_Object end, bool after,
if (!after)
{
+ struct itree_node *node;
+ EMACS_INT begin_arg = XFIXNUM (start);
+ EMACS_INT end_arg = XFIXNUM (end);
/* We are being called before a change.
Scan the overlays to find the functions to call. */
last_overlay_modification_hooks_used = 0;
- for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
- tail; tail = tail->next)
- {
- ptrdiff_t startpos, endpos;
- Lisp_Object ostart, oend;
-
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
-
- ostart = OVERLAY_START (overlay);
- oend = OVERLAY_END (overlay);
- endpos = OVERLAY_POSITION (oend);
- if (XFIXNAT (start) > endpos)
- break;
- startpos = OVERLAY_POSITION (ostart);
- if (insertion && (XFIXNAT (start) == startpos
- || XFIXNAT (end) == startpos))
- {
- Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
- if (!NILP (prop))
- add_overlay_mod_hooklist (prop, overlay);
- }
- if (insertion && (XFIXNAT (start) == endpos
- || XFIXNAT (end) == endpos))
- {
- Lisp_Object 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 (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
- {
- Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
- if (!NILP (prop))
- add_overlay_mod_hooklist (prop, overlay);
- }
- }
- for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
- tail; tail = tail->next)
+ if (! current_buffer->overlays)
+ return;
+ ITREE_FOREACH (node, current_buffer->overlays,
+ begin_arg - (insertion ? 1 : 0),
+ end_arg + (insertion ? 1 : 0),
+ ASCENDING)
{
- ptrdiff_t startpos, endpos;
- Lisp_Object ostart, oend;
-
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
-
- ostart = OVERLAY_START (overlay);
- oend = OVERLAY_END (overlay);
- startpos = OVERLAY_POSITION (ostart);
- endpos = OVERLAY_POSITION (oend);
- if (XFIXNAT (end) < startpos)
- break;
- if (insertion && (XFIXNAT (start) == startpos
- || XFIXNAT (end) == startpos))
+ Lisp_Object overlay = node->data;
+ ptrdiff_t obegin = OVERLAY_START (overlay);
+ ptrdiff_t oend = OVERLAY_END (overlay);
+
+ if (insertion && (begin_arg == obegin
+ || end_arg == obegin))
{
Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
- if (insertion && (XFIXNAT (start) == endpos
- || XFIXNAT (end) == endpos))
+ if (insertion && (begin_arg == oend
+ || end_arg == oend))
{
Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
@@ -4631,7 +4028,7 @@ 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 (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
+ if (! insertion || (end_arg > obegin && begin_arg < oend))
{
Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
if (!NILP (prop))
@@ -4639,7 +4036,6 @@ report_overlay_modification (Lisp_Object start,
Lisp_Object end, bool after,
}
}
}
-
{
/* Call the functions recorded in last_overlay_modification_hooks.
First copy the vector contents, in case some of these hooks
@@ -4662,7 +4058,7 @@ report_overlay_modification (Lisp_Object start,
Lisp_Object end, bool after,
(which makes its markers' buffers be nil), or that (due to
some bug) it belongs to a different buffer. Only run this
hook if the overlay belongs to the current buffer. */
- if (XMARKER (OVERLAY_START (overlay_i))->buffer == current_buffer)
+ if (OVERLAY_BUFFER (overlay_i) == current_buffer)
call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
}
@@ -4690,30 +4086,15 @@ void
evaporate_overlays (ptrdiff_t pos)
{
Lisp_Object hit_list = Qnil;
- if (pos <= current_buffer->overlay_center)
- for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- ptrdiff_t 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 (struct Lisp_Overlay *tail = current_buffer->overlays_after;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- ptrdiff_t 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);
- }
+ struct itree_node *node;
+
+ ITREE_FOREACH (node, current_buffer->overlays, pos, pos, ASCENDING)
+ {
+ if (node->end == pos
+ && ! NILP (Foverlay_get (node->data, Qevaporate)))
+ hit_list = Fcons (node->data, hit_list);
+ }
+
for (; CONSP (hit_list); hit_list = XCDR (hit_list))
Fdelete_overlay (XCAR (hit_list));
}
@@ -5339,9 +4720,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);
@@ -5546,6 +4925,48 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd,
const char *namestring,
emacs_abort ();
}
+#ifdef ITREE_DEBUG
+static Lisp_Object
+make_lispy_itree_node (const struct itree_node *node)
+{
+ return listn (12,
+ intern (":begin"),
+ make_fixnum (node->begin),
+ intern (":end"),
+ make_fixnum (node->end),
+ intern (":limit"),
+ make_fixnum (node->limit),
+ intern (":offset"),
+ make_fixnum (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 itree_tree *tree,
+ const struct itree_node *node)
+{
+ if (node == ITREE_NULL)
+ return Qnil;
+ return list3 (make_lispy_itree_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
@@ -6517,6 +5938,10 @@ There is no reason to change that value except for
debugging purposes. */);
DEFSYM (Qautosaved, "autosaved");
+#ifdef ITREE_DEBUG
+ defsubr (&Soverlay_tree);
+#endif
+
DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save");
DEFSYM (Qbuffer_stale_function, "buffer-stale-function");
diff --git a/src/buffer.h b/src/buffer.h
index cbdbae798b..3ea4125645 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1,7 +1,6 @@
/* Header file for the buffer manipulation primitives.
-Copyright (C) 1985-1986, 1993-1995, 1997-2022 Free Software Foundation,
-Inc.
+Copyright (C) 1985-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -26,6 +25,7 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include "character.h"
#include "lisp.h"
+#include "itree.h"
INLINE_HEADER_BEGIN
@@ -697,16 +697,8 @@ struct buffer
display optimizations must be used. */
bool_bf long_line_optimizations_p : 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 itree_tree *overlays;
/* Changes in the buffer are recorded here for undo, and t means
don't record anything. This information belongs to the base
@@ -716,6 +708,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)
{
@@ -1171,8 +1171,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, 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
**);
@@ -1186,6 +1189,7 @@ extern void fix_overlays_before (struct buffer *,
ptrdiff_t, ptrdiff_t);
extern void mmap_set_vars (bool);
extern void restore_buffer (Lisp_Object);
extern void set_buffer_if_live (Lisp_Object);
+extern Lisp_Object build_overlay (bool, bool, Lisp_Object);
/* Return B as a struct buffer pointer, defaulting to the current buffer. */
@@ -1226,18 +1230,16 @@ record_unwind_current_buffer (void)
This macro might evaluate its args multiple times,
and it treat some args as lvalues. */
-#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)
@@ -1272,7 +1274,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
+ && (current_buffer->overlays->root != NULL);
}
/* Functions for accessing a character or byte,
@@ -1390,25 +1393,69 @@ 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 itree_node_begin (ov->buffer->overlays, ov->interval);
+}
+
+INLINE ptrdiff_t
+overlay_end (struct Lisp_Overlay *ov)
+{
+ if (! ov->buffer)
+ return -1;
+ return itree_node_end (ov->buffer->overlays, ov->interval);
+}
-#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. */
+INLINE ptrdiff_t
+OVERLAY_START (Lisp_Object ov)
+{
+ return overlay_start (XOVERLAY (ov));
+}
-#define OVERLAY_END(OV) XOVERLAY (OV)->end
+/* Return the end of OV in its buffer, or -1. */
+
+INLINE ptrdiff_t
+OVERLAY_END (Lisp_Object ov)
+{
+ return overlay_end (XOVERLAY (ov));
+}
/* Return the plist of overlay OV. */
-#define OVERLAY_PLIST(OV) XOVERLAY (OV)->plist
+INLINE Lisp_Object
+OVERLAY_PLIST (Lisp_Object ov)
+{
+ return XOVERLAY (ov)->plist;
+}
-/* Return the actual buffer position for the marker P.
- We assume you know which buffer it's pointing into. */
+/* Return the buffer of overlay OV. */
-INLINE ptrdiff_t
-OVERLAY_POSITION (Lisp_Object p)
+INLINE struct buffer *
+OVERLAY_BUFFER (Lisp_Object ov)
{
- return marker_position (p);
+ return XOVERLAY (ov)->buffer;
+}
+
+/* Return true, if OV's rear-advance is set. */
+
+INLINE bool
+OVERLAY_REAR_ADVANCE_P (Lisp_Object ov)
+{
+ return XOVERLAY (ov)->interval->rear_advance;
+}
+
+/* Return true, if OV's front-advance is set. */
+
+INLINE bool
+OVERLAY_FRONT_ADVANCE_P (Lisp_Object ov)
+{
+ return XOVERLAY (ov)->interval->front_advance;
}
@@ -1692,4 +1739,7 @@ dec_both (ptrdiff_t *charpos, ptrdiff_t *bytepos)
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 3f9618edb0..17dca4708e 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1,6 +1,6 @@
/* Lisp functions pertaining to editing. -*- coding: utf-8 -*-
-Copyright (C) 1985-1987, 1989, 1993-2022 Free Software Foundation, Inc.
+Copyright (C) 1985-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -265,51 +265,20 @@ If you set the marker not to point anywhere, the buffer
will have no mark. */)
/* Find all the overlays in the current buffer that touch position POS.
Return the number found, and store them in a vector in VEC
- of length LEN. */
+ of length LEN.
+
+ Note: this can return overlays that do not touch POS. The caller
+ should filter these out. */
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)
{
- ptrdiff_t idx = 0;
-
- for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- Lisp_Object end = OVERLAY_END (overlay);
- ptrdiff_t endpos = OVERLAY_POSITION (end);
- if (endpos < pos)
- break;
- Lisp_Object start = OVERLAY_START (overlay);
- ptrdiff_t 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 (struct Lisp_Overlay *tail = current_buffer->overlays_after;
- tail; tail = tail->next)
- {
- Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- Lisp_Object start = OVERLAY_START (overlay);
- ptrdiff_t startpos = OVERLAY_POSITION (start);
- if (pos < startpos)
- break;
- Lisp_Object end = OVERLAY_END (overlay);
- ptrdiff_t endpos = OVERLAY_POSITION (end);
- if (pos <= endpos)
- {
- if (idx < len)
- vec[idx] = overlay;
- idx++;
- }
- }
-
- return idx;
+ /* Find all potentially rear-advance overlays at (POS - 1). Find
+ all overlays at POS, so end at (POS + 1). Find even empty
+ overlays, which due to the way 'overlays-in' works implies that
+ we might also fetch empty overlays starting at (POS + 1). */
+ return overlays_in (pos - 1, pos + 1, false, &vec, &len,
+ true, false, NULL);
}
DEFUN ("get-pos-property", Fget_pos_property, Sget_pos_property, 2, 3, 0,
@@ -369,11 +338,12 @@ 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))
+ || OVERLAY_START (ol) > posn
+ || OVERLAY_END (ol) < posn)
; /* The overlay will not cover a char inserted at point. */
else
{
@@ -4526,7 +4496,6 @@ ring. */)
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/eval.c b/src/eval.c
index 2928a45ac1..e1399d6a05 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1716,6 +1716,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object
data, bool keyboard_quit)
Lisp_Object clause = Qnil;
struct handler *h;
+ eassert (!itree_iterator_busy_p ());
if (gc_in_progress || waiting_for_input)
emacs_abort ();
diff --git a/src/fileio.c b/src/fileio.c
index 8f96e973b2..92335b639c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4167,8 +4167,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 c35f40357b..035fa12935 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1,7 +1,6 @@
/* Random utility Lisp functions.
-Copyright (C) 1985-1987, 1993-1995, 1997-2022 Free Software Foundation,
-Inc.
+Copyright (C) 1985-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -2797,10 +2796,9 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum
equal_kind equal_kind,
return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0;
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_BUFFER (o1) != OVERLAY_BUFFER (o2)
+ || OVERLAY_START (o1) != OVERLAY_START (o2)
+ || OVERLAY_END (o1) != OVERLAY_END (o2))
return false;
o1 = XOVERLAY (o1)->plist;
o2 = XOVERLAY (o2)->plist;
@@ -5094,6 +5092,7 @@ sxhash_obj (Lisp_Object obj, int depth)
? 42
: sxhash_vector (obj, depth));
}
+ /* FIXME: Use `switch`. */
else if (pvec_type == PVEC_BIGNUM)
return sxhash_bignum (obj);
else if (pvec_type == PVEC_MARKER)
@@ -5108,8 +5107,8 @@ sxhash_obj (Lisp_Object obj, int depth)
return sxhash_bool_vector (obj);
else if (pvec_type == PVEC_OVERLAY)
{
- EMACS_UINT hash = sxhash_obj (OVERLAY_START (obj), depth);
- hash = sxhash_combine (hash, sxhash_obj (OVERLAY_END (obj), depth));
+ EMACS_UINT hash = OVERLAY_START (obj);
+ hash = sxhash_combine (hash, OVERLAY_END (obj));
hash = sxhash_combine (hash, sxhash_obj (XOVERLAY (obj)->plist,
depth));
return SXHASH_REDUCE (hash);
}
diff --git a/src/indent.c b/src/indent.c
index 4bf597a339..4671ccccf9 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -224,9 +224,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. */
@@ -518,7 +515,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 38d5fbda00..6d56a76c77 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -284,7 +284,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;
@@ -300,8 +299,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)
@@ -310,15 +307,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 7f11981557..78f4f6b617 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -1836,8 +1836,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 0000000000..e824f2c891
--- /dev/null
+++ b/src/itree.c
@@ -0,0 +1,1421 @@
+/* This file implements an efficient interval data-structure.
+
+Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+This file is 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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <math.h>
+
+#include "itree.h"
+
+/*
+ Intervals of the form [BEGIN, END), are stored as nodes inside a RB
+ tree, ordered 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, 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.
+
+ ==== FIXME: bug#58342 some important operations remain slow ===
+
+ The amortized costs of Emacs' previous-overlay-change and
+ next-overlay-change functions are O(N) with this data structure.
+ The root problem is that we only have an order for the BEG field,
+ but not the END. The previous/next overlay change operations need
+ to find the nearest point where there is *either* an interval BEG
+ or END point, but there is no efficient way to narrow the search
+ space over END postions.
+
+ Consider the case where next-overlay-change is called at POS, all
+ interval BEG positions are less than pos POS and all interval END
+ posistions are after. These END positions have no order, and so
+ *every* interval must be examined. This is at least O(N). The
+ previous-overlay-change case is similar. The root issue is that
+ the iterative "narrowing" approach is not guaranteed to reduce the
+ search space in logarithmic time, since END is not ordered in the
+ tree.
+
+ One might argue that the LIMIT value will do this narrowing, but
+ this narrowing is O(K*log(N)) where K is the size of the result
+ set. If we are interested in finding the node in a range with the
+ smallest END, we might have to examine all K nodes in that range.
+ In the case of the *-overlay-channge functions, K may well be equal
+ to N.
+
+ Ideally, a tree based data structure for overlays would have
+ O(log(N)) performance for previous-overlay-change and
+ next-overlay-change, as these are called in performance sensitive
+ situations such as redisplay. The only way I can think of
+ achieving this is by keeping one ordering by BEG and a separate
+ ordering by END, and then performing logic quite similar to the
+ current Emacs overlays-before and overlays-after lists.
+
+ ==== Adjusting intervals ====
+
+ Since this data-structure will be used for overlays in an Emacs
+ buffer, a second core operation is the ability to insert and delete
+ gaps in the tree. This models the insertion and 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 actual buffer positions.
+ 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.
+*/
+
+/* +=======================================================================+
+ * | Stack
+ * +=======================================================================+ */
+
+typedef uintptr_t nodeptr_and_flag;
+
+static inline nodeptr_and_flag
+make_nav (struct itree_node *ptr, bool flag)
+{
+ uintptr_t v = (uintptr_t) ptr;
+ /* We assume alignment imposes the LSB is clear for us to use it. */
+ eassert (!(v & 1));
+ return v | !!flag;
+}
+
+static inline struct itree_node *
+nav_nodeptr (nodeptr_and_flag nav)
+{
+ return (struct itree_node *) (nav & (~(uintptr_t)1));
+}
+
+static inline bool
+nav_flag (nodeptr_and_flag nav)
+{
+ return (bool) (nav & 1);
+}
+
+/* Simple dynamic array. */
+struct interval_stack
+{
+ nodeptr_and_flag *nodes;
+ size_t size;
+ size_t length;
+};
+
+/* 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 itree_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));
+ }
+}
+
+/* Push NODE on the STACK, while settings its visited flag to FLAG. */
+
+static inline void
+interval_stack_push_flagged (struct interval_stack *stack,
+ struct itree_node *node, bool flag)
+{
+ eassert (node && node != NULL);
+
+ /* FIXME: While the stack used in the iterator is bounded by the tree
+ depth and could be easily pre-allocated to a large enough size to avoid
+ this "ensure" check, `interval_stack_push` is also used elsewhere to
+ simply collect some subset of the overlays, where it's only bounded by
+ the total number of overlays in the buffer (which can be large and thus
+ preferably not pre-allocated needlessly). */
+ interval_stack_ensure_space (stack, stack->length + 1);
+
+ stack->nodes[stack->length] = make_nav (node, flag);
+ stack->length++;
+}
+
+static inline void
+interval_stack_push (struct interval_stack *stack, struct itree_node *node)
+{
+ interval_stack_push_flagged (stack, node, false);
+}
+
+static inline nodeptr_and_flag
+interval_stack_pop (struct interval_stack *stack)
+{
+ if (stack->length == 0)
+ return make_nav (NULL, false);
+ return stack->nodes[--stack->length];
+}
+
+
+/* +-----------------------------------------------------------------------+ */
+
+/* State used when iterating interval. */
+struct itree_iterator
+{
+ struct interval_stack *stack;
+ ptrdiff_t begin;
+ ptrdiff_t end;
+ uintmax_t otick; /* A copy of the tree's `otick`. */
+ enum itree_order order;
+ bool running;
+ const char* file;
+ int line;
+};
+
+/* Ideally, every iteration would use its own `iter` object, so we could
+ have several iterations active at the same time. In practice, iterations
+ are limited by the fact we don't allow modifying the tree at the same
+ time, making the use of nested iterations quite rare anyway.
+ So we just use a single global iterator instead for now. */
+static struct itree_iterator *iter;
+
+static int
+interval_tree_max_height (const struct itree_tree *tree)
+{
+ return 2 * log (tree->size + 1) / log (2) + 0.5;
+}
+
+/* Allocate a new iterator for TREE. */
+
+static struct itree_iterator *
+itree_iterator_create (struct itree_tree *tree)
+{
+ struct itree_iterator *g = xmalloc (sizeof *g);
+ /* 19 here just avoids starting with a silly-small stack.
+ FIXME: Since this stack only needs to be about 2*max_depth
+ in the worst case, we could completely pre-allocate it to something
+ like word-bit-size * 2 and then never worry about growing it. */
+ const int size = (tree ? interval_tree_max_height (tree) : 19) + 1;
+
+ g->stack = interval_stack_create (size);
+ g->running = false;
+ g->begin = 0;
+ g->end = 0;
+ g->file = NULL;
+ g->line = 0;
+ return g;
+}
+
+static void
+itree_init (void)
+{
+ iter = itree_iterator_create (NULL);
+}
+
+struct check_subtree_result
+{
+ int size; /* Node count of the tree. */
+ ptrdiff_t limit; /* Limit of the tree (max END). */
+ int black_height; /* Black height of the tree. */
+};
+
+static struct check_subtree_result
+check_subtree (struct itree_node *node,
+ bool check_red_black_invariants, uintmax_t tree_otick,
+ ptrdiff_t offset, ptrdiff_t min_begin,
+ ptrdiff_t max_begin)
+{
+ struct check_subtree_result result = { .size = 0,
+ .limit = PTRDIFF_MIN,
+ .black_height = 0 };
+ if (node == NULL)
+ return result;
+
+ /* Validate structure. */
+ eassert (node->left == NULL || node->left->parent == node);
+ eassert (node->right == NULL || node->right->parent == node);
+
+ /* Validate otick. A node's otick must be <= to the tree's otick
+ and <= to its parent's otick.
+
+ Note: we cannot assert that (NODE.otick == NODE.parent.otick)
+ implies (NODE.offset == 0) because interval_tree_inherit_offset()
+ doesn't always update otick. It could, but it is not clear there
+ is a need. */
+ eassert (node->otick <= tree_otick);
+ eassert (node->parent == NULL || node->otick <= node->parent->otick);
+ eassert (node->otick != tree_otick || node->offset == 0);
+
+ offset += node->offset;
+ ptrdiff_t begin = node->begin + offset;
+ ptrdiff_t end = node->end + offset;
+ ptrdiff_t limit = node->limit + offset;
+
+ eassert (min_begin <= max_begin);
+ eassert (min_begin <= begin);
+ eassert (begin <= max_begin);
+ eassert (end <= limit);
+
+ struct check_subtree_result left_result
+ = check_subtree (node->left, check_red_black_invariants,
+ tree_otick, offset, min_begin, begin);
+ struct check_subtree_result right_result
+ = check_subtree (node->right, check_red_black_invariants,
+ tree_otick, offset, begin, max_begin);
+
+ eassert (left_result.limit <= limit);
+ eassert (right_result.limit <= limit);
+ eassert (limit == max (end, max (left_result.limit, right_result.limit)));
+
+ if (check_red_black_invariants)
+ {
+ eassert (left_result.black_height == right_result.black_height);
+ eassert (node->parent == NULL || !node->red || !node->parent->red);
+ }
+
+ result.size = 1 + left_result.size + right_result.size;
+ result.limit = limit;
+ result.black_height = (node->red ? 0 : 1) + left_result.black_height;
+ return result;
+}
+
+/* Validate invariants for TREE. If CHECK_RED_BLACK_INVARIANTS, red
+ nodes with red children are considered invalid.
+
+ This runs in constant time when ENABLE_OVERLAY_CHECKING is 0
+ (i.e. Emacs is not configured with
+ "--enable_checking=yes,overlays"). In this mode it can't check all
+ the invariants. When ENABLE_OVERLAY_CHECKING is 1 it checks the
+ entire tree and validates all invariants.
+*/
+static bool
+check_tree (struct itree_tree *tree,
+ bool check_red_black_invariants)
+{
+ eassert (tree != NULL);
+ eassert (tree->size >= 0);
+ eassert ((tree->size == 0) == (tree->root == NULL));
+ if (tree->root == NULL)
+ return true;
+ eassert (tree->root->parent == NULL);
+ eassert (!check_red_black_invariants || !tree->root->red);
+
+ struct itree_node *node = tree->root;
+ struct check_subtree_result result
+ = check_subtree (node, check_red_black_invariants, tree->otick,
+ node->offset, PTRDIFF_MIN,
+ PTRDIFF_MAX);
+ eassert (result.size == tree->size);
+
+ /* The only way this function fails is eassert(). */
+ return true;
+}
+
+/* +=======================================================================+
+ * | Internal Functions
+ * +=======================================================================+ */
+
+static bool
+null_safe_is_red (struct itree_node *node)
+{
+ return node != NULL && node->red;
+}
+
+static bool
+null_safe_is_black (struct itree_node *node)
+{
+ return node == NULL || !node->red; /* NULL nodes are black */
+}
+
+static inline ptrdiff_t
+itree_newlimit (struct itree_node *node)
+{
+ eassert (node != NULL);
+ return max (node->end,
+ max (node->left == NULL
+ ? PTRDIFF_MIN
+ : node->left->limit + node->left->offset,
+ node->right == NULL
+ ? PTRDIFF_MIN
+ : node->right->limit + node->right->offset));
+}
+
+/* Update NODE's limit attribute according to its children. */
+
+static void
+interval_tree_update_limit (struct itree_node *node)
+{
+ if (node == NULL)
+ return;
+
+ node->limit = itree_newlimit (node);
+}
+
+/* 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 (uintmax_t otick, struct itree_node *node)
+{
+ eassert (node->parent == NULL || node->parent->otick >= node->otick);
+ if (node->otick == otick)
+ {
+ eassert (node->offset == 0);
+ return;
+ }
+
+ /* Offsets can be inherited from dirty nodes (with out of date
+ otick) during removal, since we do not travel down from the root
+ in that case. In this case rotations are performed on
+ potentially "dirty" nodes, where we only need to make sure the
+ *local* offsets are zero. */
+
+ if (node->offset)
+ {
+ node->begin += node->offset;
+ node->end += node->offset;
+ node->limit += node->offset;
+ if (node->left != NULL)
+ node->left->offset += node->offset;
+ if (node->right != NULL)
+ node->right->offset += node->offset;
+ node->offset = 0;
+ }
+ /* The only thing that matters about `otick` is whether it's equal to
+ that of the tree. We could also "blindly" inherit from parent->otick,
+ but we need to tree's `otick` anyway for when there's no parent. */
+ if (node->parent == NULL || node->parent->otick == otick)
+ node->otick = otick;
+}
+
+/* Update limit of NODE and its ancestors. Stop when it becomes
+ stable, i.e. new_limit = old_limit. */
+
+static void
+interval_tree_propagate_limit (struct itree_node *node)
+{
+ if (node == NULL)
+ return;
+
+ while (1) {
+ ptrdiff_t newlimit = itree_newlimit (node);
+ if (newlimit == node->limit)
+ break;
+ node->limit = newlimit;
+ if (node->parent == NULL)
+ break;
+ node = node->parent;
+ }
+}
+
+static struct itree_node*
+interval_tree_validate (struct itree_tree *tree, struct itree_node *node)
+{
+
+ if (tree->otick == node->otick || node == NULL)
+ return node;
+ if (node != tree->root)
+ interval_tree_validate (tree, node->parent);
+
+ interval_tree_inherit_offset (tree->otick, node);
+ return node;
+}
+
+/* +=======================================================================+
+ * | Tree operations
+ * +=======================================================================+ */
+
+/* Initialize an allocated node. */
+
+void
+itree_node_init (struct itree_node *node,
+ bool front_advance, bool rear_advance,
+ Lisp_Object data)
+{
+ node->parent = NULL;
+ node->left = NULL;
+ node->right = NULL;
+ node->begin = -1;
+ node->end = -1;
+ node->front_advance = front_advance;
+ node->rear_advance = rear_advance;
+ node->data = data;
+}
+
+/* Return NODE's begin value, computing it if necessary. */
+
+ptrdiff_t
+itree_node_begin (struct itree_tree *tree,
+ struct itree_node *node)
+{
+ interval_tree_validate (tree, node);
+ return node->begin;
+}
+
+/* Return NODE's end value, computing it if necessary. */
+
+ptrdiff_t
+itree_node_end (struct itree_tree *tree,
+ struct itree_node *node)
+{
+ interval_tree_validate (tree, node);
+ return node->end;
+}
+
+/* Allocate an interval_tree. Free with interval_tree_destroy. */
+
+struct itree_tree*
+itree_create (void)
+{
+ /* FIXME? Maybe avoid the initialization of itree_null in the same
+ way that is used to call mem_init in alloc.c? It's not really
+ important though. */
+ itree_init ();
+
+ struct itree_tree *tree = xmalloc (sizeof (*tree));
+ itree_clear (tree);
+ return tree;
+}
+
+/* Reset the tree TREE to its empty state. */
+
+void
+itree_clear (struct itree_tree *tree)
+{
+ tree->root = NULL;
+ tree->otick = 1;
+ tree->size = 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 = itree_iterator_create (tree); */
+}
+#endif
+
+/* Release a tree, freeing its allocated memory. */
+void
+itree_destroy (struct itree_tree *tree)
+{
+ eassert (tree->root == NULL);
+ /* if (tree->iter)
+ * itree_iterator_destroy (tree->iter); */
+ xfree (tree);
+}
+
+/* Return the number of nodes in TREE. */
+
+intmax_t
+itree_size (struct itree_tree *tree)
+{
+ return tree->size;
+}
+
+/* Perform the familiar left-rotation on node NODE. */
+
+static void
+interval_tree_rotate_left (struct itree_tree *tree,
+ struct itree_node *node)
+{
+ eassert (node->right != NULL);
+
+ struct itree_node *right = node->right;
+
+ interval_tree_inherit_offset (tree->otick, node);
+ interval_tree_inherit_offset (tree->otick, right);
+
+ /* Turn right's left subtree into node's right subtree. */
+ node->right = right->left;
+ if (right->left != NULL)
+ right->left->parent = node;
+
+ /* right's parent was node's parent. */
+ if (right != NULL)
+ 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 != NULL)
+ node->parent = right;
+
+ /* Order matters here. */
+ interval_tree_update_limit (node);
+ interval_tree_update_limit (right);
+}
+
+/* Perform the familiar right-rotation on node NODE. */
+
+static void
+interval_tree_rotate_right (struct itree_tree *tree,
+ struct itree_node *node)
+{
+ eassert (tree && node && node->left != NULL);
+
+ struct itree_node *left = node->left;
+
+ interval_tree_inherit_offset (tree->otick, node);
+ interval_tree_inherit_offset (tree->otick, left);
+
+ node->left = left->right;
+ if (left->right != NULL)
+ left->right->parent = node;
+
+ if (left != NULL)
+ 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 != NULL)
+ node->parent = left;
+
+ interval_tree_update_limit (left);
+ interval_tree_update_limit (node);
+}
+
+/* Repair the tree after an insertion.
+ The new NODE was added as red, so we may have 2 reds in a row.
+ Rebalance the parents as needed to re-establish the RB invariants. */
+
+static void
+interval_tree_insert_fix (struct itree_tree *tree,
+ struct itree_node *node)
+{
+ eassert (tree->root->red == false);
+
+ while (null_safe_is_red (node->parent))
+ {
+ /* NODE is red and its parent is red. This is a violation of
+ red-black tree property #3. */
+ eassert (node->red);
+
+ if (node->parent == node->parent->parent->left)
+ {
+ /* We're on the left side of our grandparent, and OTHER is
+ our "uncle". */
+ struct itree_node *uncle = node->parent->parent->right;
+
+ if (null_safe_is_red (uncle)) /* 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->red = false;
+ uncle->red = false;
+ node->parent->parent->red = true;
+ 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->red = false;
+ node->parent->parent->red = true;
+ interval_tree_rotate_right (tree, node->parent->parent);
+ }
+ }
+ else
+ {
+ /* This is the symmetrical case of above. */
+ struct itree_node *uncle = node->parent->parent->left;
+
+ if (null_safe_is_red (uncle)) /* case 1.b */
+ {
+ node->parent->red = false;
+ uncle->red = false;
+ node->parent->parent->red = true;
+ 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->red = false;
+ node->parent->parent->red = true;
+ 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->red = false;
+ eassert (check_tree (tree, true)); /* FIXME: Too expensive. */
+}
+
+/* Insert a NODE into the TREE.
+ Note, that inserting a node twice results in undefined behaviour. */
+
+static void
+interval_tree_insert (struct itree_tree *tree, struct itree_node *node)
+{
+ eassert (node->begin <= node->end && node != NULL);
+ /* FIXME: The assertion below fails because `delete_all_overlays`
+ doesn't set left/right/parent to NULL. */
+ /* eassert (node->left == NULL && node->right == NULL
+ && node->parent == NULL) */;
+ eassert (check_tree (tree, true)); /* FIXME: Too expensive. */
+
+ struct itree_node *parent = NULL;
+ struct itree_node *child = tree->root;
+ uintmax_t otick = tree->otick;
+ /* It's the responsability of the caller to set `otick` on the node,
+ to "confirm" that the begin/end fields are up to date. */
+ eassert (node->otick == otick);
+
+ /* Find the insertion point, accumulate node's offset and update
+ ancestors limit values. */
+ while (child != NULL)
+ {
+ interval_tree_inherit_offset (otick, child);
+ parent = child;
+ eassert (child->offset == 0);
+ child->limit = max (child->limit, node->end);
+ /* 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 == NULL)
+ tree->root = node;
+ else if (node->begin <= parent->begin)
+ parent->left = node;
+ else
+ parent->right = node;
+
+ /* Init the node */
+ node->parent = parent;
+ node->left = NULL;
+ node->right = NULL;
+ node->offset = 0;
+ node->limit = node->end;
+ eassert (node->parent == NULL || node->parent->otick >= node->otick);
+
+ /* Fix/update the tree */
+ ++tree->size;
+ if (node == tree->root)
+ node->red = false;
+ else
+ {
+ node->red = true;
+ eassert (check_tree (tree, false)); /* FIXME: Too expensive. */
+ interval_tree_insert_fix (tree, node);
+ }
+}
+
+void
+itree_insert (struct itree_tree *tree, struct itree_node *node,
+ ptrdiff_t begin, ptrdiff_t end)
+{
+ node->begin = begin;
+ node->end = end;
+ node->otick = tree->otick;
+ interval_tree_insert (tree, node);
+}
+
+/* Safely modify a node's interval. */
+
+void
+itree_node_set_region (struct itree_tree *tree,
+ struct itree_node *node,
+ ptrdiff_t begin, ptrdiff_t end)
+{
+ interval_tree_validate (tree, node);
+ if (begin != node->begin)
+ {
+ itree_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);
+ eassert (node != NULL);
+ interval_tree_propagate_limit (node);
+ }
+}
+
+/* Return true, if NODE is a member of TREE. */
+
+static bool
+interval_tree_contains (struct itree_tree *tree, struct itree_node *node)
+{
+ eassert (node);
+ struct itree_node *other;
+ ITREE_FOREACH (other, tree, node->begin, PTRDIFF_MAX, ASCENDING)
+ if (other == node)
+ {
+ ITREE_FOREACH_ABORT ();
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+itree_limit_is_stable (struct itree_node *node)
+{
+ if (node == NULL)
+ return true;
+ ptrdiff_t newlimit = itree_newlimit (node);
+ return (newlimit == node->limit);
+}
+
+static struct itree_node*
+interval_tree_subtree_min (uintmax_t otick, struct itree_node *node)
+{
+ if (node == NULL)
+ return node;
+ while ((interval_tree_inherit_offset (otick, node),
+ node->left != NULL))
+ node = node->left;
+ return node;
+}
+
+/* Repair the tree after a deletion.
+ The black-depth of NODE is one less than that of its sibling,
+ so re-balance the parents to re-establish the RB invariants. */
+
+static void
+interval_tree_remove_fix (struct itree_tree *tree,
+ struct itree_node *node,
+ struct itree_node *parent)
+{
+ if (parent == NULL)
+ eassert (node == tree->root);
+ else
+ eassert (node == NULL || node->parent == parent);
+
+ while (parent != NULL && null_safe_is_black (node))
+ {
+ eassert (node == parent->left || node == parent->right);
+
+ if (node == parent->left)
+ {
+ struct itree_node *other = parent->right;
+
+ if (null_safe_is_red (other)) /* case 1.a */
+ {
+ other->red = false;
+ parent->red = true;
+ interval_tree_rotate_left (tree, parent);
+ other = parent->right;
+ }
+ eassume (other != NULL);
+
+ if (null_safe_is_black (other->left) /* 2.a */
+ && null_safe_is_black (other->right))
+ {
+ other->red = true;
+ node = parent;
+ eassert (node != NULL);
+ parent = node->parent;
+ }
+ else
+ {
+ if (null_safe_is_black (other->right)) /* 3.a */
+ {
+ other->left->red = false;
+ other->red = true;
+ interval_tree_rotate_right (tree, other);
+ other = parent->right;
+ }
+ other->red = parent->red; /* 4.a */
+ parent->red = false;
+ other->right->red = false;
+ interval_tree_rotate_left (tree, parent);
+ node = tree->root;
+ parent = NULL;
+ }
+ }
+ else
+ {
+ struct itree_node *other = parent->left;
+
+ if (null_safe_is_red (other)) /* 1.b */
+ {
+ other->red = false;
+ parent->red = true;
+ interval_tree_rotate_right (tree, parent);
+ other = parent->left;
+ }
+ eassume (other != NULL);
+
+ if (null_safe_is_black (other->right) /* 2.b */
+ && null_safe_is_black (other->left))
+ {
+ other->red = true;
+ node = parent;
+ eassert (node != NULL);
+ parent = node->parent;
+ }
+ else
+ {
+ if (null_safe_is_black (other->left)) /* 3.b */
+ {
+ other->right->red = false;
+ other->red = true;
+ interval_tree_rotate_left (tree, other);
+ other = parent->left;
+ }
+
+ other->red = parent->red; /* 4.b */
+ parent->red = false;
+ other->left->red = false;
+ interval_tree_rotate_right (tree, parent);
+ node = tree->root;
+ parent = NULL;
+ }
+ }
+ }
+
+ if (node != NULL)
+ node->red = false;
+}
+
+/* Return accumulated offsets of NODE's parents. */
+static ptrdiff_t
+itree_total_offset (struct itree_node *node)
+{
+ eassert (node != NULL);
+ ptrdiff_t offset = 0;
+ while (node->parent != NULL)
+ {
+ node = node->parent;
+ offset += node->offset;
+ }
+ return offset;
+}
+
+/* Replace DEST with SOURCE as a child of DEST's parent. Adjusts
+ *only* the parent linkage of SOURCE and either the parent's child
+ link the tree root.
+
+ Warning: DEST is left unmodified. SOURCE's child links are
+ unchanged. Caller is responsible for recalculation of `limit`.
+ Requires both nodes to be using the same effective `offset`. */
+static void
+interval_tree_replace_child (struct itree_tree *tree,
+ struct itree_node *source,
+ struct itree_node *dest)
+{
+ eassert (tree && dest != NULL);
+ eassert (source == NULL
+ || itree_total_offset (source) == itree_total_offset (dest));
+
+ if (dest == tree->root)
+ tree->root = source;
+ else if (dest == dest->parent->left)
+ dest->parent->left = source;
+ else
+ dest->parent->right = source;
+
+ if (source != NULL)
+ source->parent = dest->parent;
+}
+/* Replace DEST with SOURCE in the tree. Copies the following fields
+ from DEST to SOURCE: red, parent, left, right. Also updates
+ parent, left and right in surrounding nodes to point to SOURCE.
+
+ Warning: DEST is left unmodified. Caller is responsible for
+ recalculation of `limit`. Requires both nodes to be using the same
+ effective `offset`. */
+static void
+interval_tree_transplant (struct itree_tree *tree,
+ struct itree_node *source,
+ struct itree_node *dest)
+{
+ interval_tree_replace_child (tree, source, dest);
+ source->left = dest->left;
+ if (source->left != NULL)
+ source->left->parent = source;
+ source->right = dest->right;
+ if (source->right != NULL)
+ source->right->parent = source;
+ source->red = dest->red;
+}
+
+/* Remove NODE from TREE and return it. NODE must exist in TREE. */
+
+struct itree_node*
+itree_remove (struct itree_tree *tree, struct itree_node *node)
+{
+ eassert (interval_tree_contains (tree, node));
+ eassert (check_tree (tree, true)); /* FIXME: Too expensive. */
+
+ /* Find `splice`, the leaf node to splice out of the tree. When
+ `node` has at most one child this is `node` itself. Otherwise,
+ it is the in order successor of `node`. */
+ interval_tree_inherit_offset (tree->otick, node);
+ struct itree_node *splice
+ = (node->left == NULL || node->right == NULL)
+ ? node
+ : interval_tree_subtree_min (tree->otick, node->right);
+
+ /* Find `subtree`, the only child of `splice` (may be NULL). Note:
+ `subtree` will not be modified other than changing its parent to
+ `splice`. */
+ eassert (splice->left == NULL || splice->right == NULL);
+ struct itree_node *subtree
+ = (splice->left != NULL) ? splice->left : splice->right;
+
+ /* Save a pointer to the parent of where `subtree` will eventually
+ be in `subtree_parent`. */
+ struct itree_node *subtree_parent
+ = (splice->parent != node) ? splice->parent : splice;
+
+ /* If `splice` is black removing it may violate Red-Black
+ invariants, so note this for later. */
+
+ /* Replace `splice` with `subtree` under subtree's parent. If
+ `splice` is black, this creates a red-red violation, so remember
+ this now as the field can be overwritten when splice is
+ transplanted below. */
+ interval_tree_replace_child (tree, subtree, splice);
+ bool removed_black = !splice->red;
+
+ /* Replace `node` with `splice` in the tree and propagate limit
+ upwards, if necessary. Note: Limit propagation can stabilize at
+ any point, so we must call from bottom to top for every node that
+ has a new child. */
+ if (splice != node)
+ {
+ interval_tree_transplant (tree, splice, node);
+ interval_tree_propagate_limit (subtree_parent);
+ if (splice != subtree_parent)
+ interval_tree_update_limit (splice);
+ }
+ interval_tree_propagate_limit (splice->parent);
+
+ --tree->size;
+
+ /* Fix any black height violation caused by removing a black node. */
+ if (removed_black)
+ interval_tree_remove_fix (tree, subtree, subtree_parent);
+
+ eassert ((tree->size == 0) == (tree->root == NULL));
+ eassert (check_tree (tree, true)); /* FIXME: Too expensive. */
+
+ /* Clear fields related to the tree for sanity while debugging. */
+ node->red = false;
+ node->right = node->left = node->parent = NULL;
+ node->limit = 0;
+
+ /* Must be clean (all offsets applied). Also, some callers rely on
+ node's otick being the tree's otick. */
+ eassert (node->otick == tree->otick);
+ eassert (node->offset == 0);
+
+ return node;
+}
+
+bool
+itree_iterator_busy_p (void)
+{
+ return (iter && iter->running);
+}
+
+/* Start a iterator enumerating all intervals in [BEGIN,END) in the
+ given ORDER. Only one iterator per tree can be running at any time. */
+
+struct itree_iterator *
+itree_iterator_start (struct itree_tree *tree, ptrdiff_t begin,
+ ptrdiff_t end, enum itree_order order,
+ const char *file, int line)
+{
+ /* struct itree_iterator *iter = tree->iter; */
+ if (iter->running)
+ {
+ fprintf (stderr,
+ "Detected nested iteration!\nOuter: %s:%d\nInner: %s:%d\n",
+ iter->file, iter->line, file, line);
+ emacs_abort ();
+ }
+ iter->begin = begin;
+ iter->end = end;
+ iter->otick = tree->otick;
+ iter->order = order;
+ interval_stack_clear (iter->stack);
+ if (begin <= end && tree->root != NULL)
+ interval_stack_push_flagged (iter->stack, tree->root, false);
+ iter->file = file;
+ iter->line = line;
+ iter->running = true;
+ /* interval_stack_ensure_space (iter->stack,
+ 2 * interval_tree_max_height (tree)); */
+ return iter;
+}
+
+/* Stop using the iterator. */
+
+void
+itree_iterator_finish (struct itree_iterator *iter)
+{
+ eassert (iter->running);
+ iter->running = false;
+}
+
+
+/* +=======================================================================+
+ * | 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
+itree_insert_gap (struct itree_tree *tree,
+ ptrdiff_t pos, ptrdiff_t length)
+{
+ if (length <= 0 || tree->root == NULL)
+ return;
+ uintmax_t ootick = tree->otick;
+
+ /* FIXME: Don't allocate iterator/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 itree_node *node = NULL;
+ ITREE_FOREACH (node, tree, pos, pos + 1, PRE_ORDER)
+ {
+ if (node->begin == pos && node->front_advance
+ && (node->begin != node->end || node->rear_advance))
+ interval_stack_push (saved, node);
+ }
+ for (int i = 0; i < saved->length; ++i)
+ itree_remove (tree, nav_nodeptr (saved->nodes[i]));
+
+ /* We can't use an iterator here, because we can't effectively
+ narrow AND shift some subtree at the same time. */
+ if (tree->root != NULL)
+ {
+ const int size = interval_tree_max_height (tree) + 1;
+ struct interval_stack *stack = interval_stack_create (size);
+ interval_stack_push (stack, tree->root);
+ nodeptr_and_flag nav;
+ while ((nav = interval_stack_pop (stack),
+ node = nav_nodeptr (nav)))
+ {
+ /* Process in pre-order. */
+ interval_tree_inherit_offset (tree->otick, node);
+ if (node->right != NULL)
+ {
+ 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 != NULL
+ && pos <= node->left->limit + node->left->offset)
+ 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;
+ eassert (node != NULL);
+ interval_tree_propagate_limit (node);
+ }
+ }
+ interval_stack_destroy (stack);
+ }
+
+ /* Reinsert nodes starting at POS having front-advance. */
+ uintmax_t notick = tree->otick;
+ nodeptr_and_flag nav;
+ while ((nav = interval_stack_pop (saved),
+ node = nav_nodeptr (nav)))
+ {
+ eassert (node->otick == ootick);
+ node->begin += length;
+ if (node->end != pos || node->rear_advance)
+ node->end += length;
+ node->otick = notick;
+ interval_tree_insert (tree, node);
+ }
+
+ interval_stack_destroy (saved);
+}
+
+/* Delete a gap at POS of length LENGTH, contracting all intervals
+ intersecting it. */
+
+void
+itree_delete_gap (struct itree_tree *tree,
+ ptrdiff_t pos, ptrdiff_t length)
+{
+ if (length <= 0 || tree->root == NULL)
+ return;
+
+ /* FIXME: Don't allocate stack anew every time. */
+
+ /* Can't use the iterator 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 itree_node *node;
+
+ interval_stack_push (stack, tree->root);
+ nodeptr_and_flag nav;
+ while ((nav = interval_stack_pop (stack)))
+ {
+ node = nav_nodeptr (nav);
+ interval_tree_inherit_offset (tree->otick, node);
+ if (node->right != NULL)
+ {
+ 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 != NULL
+ && pos <= node->left->limit + node->left->offset)
+ 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);
+ eassert (node != NULL);
+ interval_tree_propagate_limit (node);
+ }
+ }
+ interval_stack_destroy (stack);
+}
+
+
+
+/* +=======================================================================+
+ * | Iterator
+ * +=======================================================================+ */
+
+/* Return true, if NODE's interval intersects with [BEGIN, END).
+ Note: We always include empty nodes at BEGIN (and not at END),
+ but if BEGIN==END, then we don't include non-empty nodes starting
+ at BEGIN or ending at END. This seems to match the behavior of the
+ old overlays code but it's not clear if it's The Right Thing
+ (e.g. it breaks the expectation that if NODE1 is included, then
+ a NODE2 strictly bigger than NODE1 should also be included). */
+
+static inline bool
+interval_node_intersects (const struct itree_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 the iterator in the order given when it was
+ started; or NULL if there are no more nodes. */
+
+struct itree_node *
+itree_iterator_next (struct itree_iterator *g)
+{
+ eassert (g->running);
+
+ struct itree_node * const null = NULL;
+ struct itree_node *node;
+
+ /* The `visited` flag stored in each node is used here (and only here):
+ We keep a "workstack" of nodes we need to consider. This stack
+ consist of nodes of two types: nodes that we have decided
+ should be returned by the iterator, and nodes which we may
+ need to consider (including checking their children).
+ We start an iteration with a stack containing just the root
+ node marked as "not visited" which means that it (and its children)
+ needs to be considered but we haven't yet decided whether it's included
+ in the iterator's output. */
+
+ do {
+ nodeptr_and_flag nav;
+ bool visited;
+ while ((nav = interval_stack_pop (g->stack),
+ node = nav_nodeptr (nav),
+ visited = nav_flag (nav),
+ node && !visited))
+ {
+ struct itree_node * const left = node->left;
+ struct itree_node * const right = node->right;
+
+ interval_tree_inherit_offset (g->otick, node);
+ eassert (itree_limit_is_stable (node));
+ switch (g->order)
+ {
+ case ITREE_ASCENDING:
+ if (right != null && 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 != null && g->begin <= left->limit + left->offset)
+ interval_stack_push_flagged (g->stack, left, false);
+ break;
+ case ITREE_DESCENDING:
+ if (left != null && 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 != null && node->begin <= g->end)
+ interval_stack_push_flagged (g->stack, right, false);
+ break;
+ case ITREE_PRE_ORDER:
+ if (right != null && node->begin <= g->end)
+ interval_stack_push_flagged (g->stack, right, false);
+ if (left != null && 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 may have been invalidated by itree_iterator_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. */
+
+void
+itree_iterator_narrow (struct itree_iterator *g,
+ ptrdiff_t begin, ptrdiff_t end)
+{
+ eassert (g->running);
+ eassert (begin >= g->begin);
+ eassert (end <= g->end);
+ g->begin = max (begin, g->begin);
+ g->end = min (end, g->end);
+}
diff --git a/src/itree.h b/src/itree.h
new file mode 100644
index 0000000000..3df07ac1b7
--- /dev/null
+++ b/src/itree.h
@@ -0,0 +1,181 @@
+/* This file implements an efficient interval data-structure.
+
+Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+This file is 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef ITREE_H
+#define ITREE_H
+#include <config.h>
+#include <stddef.h>
+#include <inttypes.h>
+
+#include "lisp.h"
+
+/* 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 an iterator, because it validates the nodes it
+ returns as a side-effect. See ITREE_FOREACH.
+ */
+
+struct itree_node
+{
+ /* The normal parent, left and right links found in binary trees.
+ See also `red`, below, which completes the Red-Black tree
+ representation. */
+ struct itree_node *parent;
+ struct itree_node *left;
+ struct itree_node *right;
+
+ /* The following five fields comprise the interval abstraction.
+
+ BEGIN, END are buffer positions describing the range. When a
+ node is in a tree these fields are read only, written only by
+ itree functions.
+
+ The LIMIT, OFFSET and OTICK fields should be considered internal
+ to itree.c and used only by itree functions.
+
+ LIMIT is a buffer position, the maximum of END of this node and
+ its children. See itree.c for its use.
+
+ OFFSET is in buffer position units, and will be non-zero only
+ when the node is dirty.
+
+ OTICK determines whether BEGIN, END, LIMIT and OFFSET are
+ considered dirty. A node is clean when its OTICK is equal to the
+ OTICK of its tree (see struct itree_tree). Otherwise, it is
+ dirty.
+
+ In a clean node, BEGIN, END and LIMIT are correct buffer
+ positions, and OFFSET is zero. The parent of a clean node is
+ also clean, recursively.
+
+ In a dirty node, the node's OTICK won't equal its tree's OTICK,
+ and its OFFSET may be non-zero. At all times the descendents of
+ a dirty node are also dirty. BEGIN, END and LIMIT require
+ adjustment before use as buffer positions.
+
+ NOTE: BEGIN and END must not be modified while the node is part
+ of a tree. Use itree_insert_gap and itree_delete_gap instead.
+
+ NOTE: The interval iterators ensure nodes are clean before
+ yielding them, so BEGIN and END may be safely used as buffer
+ positions then.
+ */
+
+ 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 red : 1;
+ bool_bf rear_advance : 1; /* Same as for marker and overlays. */
+ bool_bf front_advance : 1; /* Same as for marker and overlays. */
+};
+
+struct itree_tree
+{
+ struct itree_node *root;
+ uintmax_t otick; /* offset tick, compared with node's otick. */
+ intmax_t size; /* Number of nodes in the tree. */
+};
+
+enum itree_order {
+ ITREE_ASCENDING,
+ ITREE_DESCENDING,
+ ITREE_PRE_ORDER,
+};
+
+void itree_node_init (struct itree_node *, bool, bool, Lisp_Object);
+ptrdiff_t itree_node_begin (struct itree_tree *, struct itree_node *);
+ptrdiff_t itree_node_end (struct itree_tree *, struct itree_node *);
+void itree_node_set_region (struct itree_tree *, struct itree_node *,
+ ptrdiff_t, ptrdiff_t);
+struct itree_tree *itree_create (void);
+void itree_destroy (struct itree_tree *);
+intmax_t itree_size (struct itree_tree *);
+void itree_clear (struct itree_tree *);
+void itree_insert (struct itree_tree *tree, struct itree_node *node,
+ ptrdiff_t begin, ptrdiff_t end);
+struct itree_node *itree_remove (struct itree_tree *,
+ struct itree_node *);
+void itree_insert_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t);
+void itree_delete_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t);
+
+/* Iteration functions. Almost all code should use ITREE_FOREACH
+ instead. */
+bool itree_iterator_busy_p (void);
+struct itree_iterator *
+itree_iterator_start (struct itree_tree *tree, ptrdiff_t begin,
+ ptrdiff_t end, enum itree_order order,
+ const char *file, int line);
+void itree_iterator_narrow (struct itree_iterator *, ptrdiff_t,
+ ptrdiff_t);
+void itree_iterator_finish (struct itree_iterator *);
+struct itree_node *itree_iterator_next (struct itree_iterator *);
+
+/* Iterate over the intervals between BEG and END in the tree T.
+ N will hold successive nodes. ORDER can be one of : `ASCENDING`,
+ `DESCENDING`, or `PRE_ORDER`.
+ It should be used as:
+
+ ITREE_FOREACH (n, t, beg, end, order)
+ {
+ .. do the thing with n ..
+ }
+
+ BEWARE:
+ - The expression T may be evaluated more than once, so make sure
+ it is cheap a pure.
+ - Only a single iteration can happen at a time, so make sure none of the
+ code within the loop can start another tree iteration, i.e. it shouldn't
+ be able to run ELisp code, nor GC since GC can run ELisp by way
+ of `post-gc-hook`.
+ - If you need to exit the loop early, you *have* to call `ITREE_ABORT`
+ just before exiting (e.g. with `break` or `return`).
+ - Non-local exits are not supported within the body of the loop.
+ - Don't modify the tree during the iteration.
+ */
+#define ITREE_FOREACH(n, t, beg, end, order) \
+ /* FIXME: We'd want to declare `x` right here, but I can't figure out
+ how to make that work here: the `for` syntax only allows a single
+ clause for the var declarations where we need 2 different types.
+ We could use the `struct {foo x; bar y; } p;` trick to declare two
+ vars `p.x` and `p.y` of unrelated types, but then none of the names
+ of the vars matches the `n` we receive :-(. */ \
+ if (!t) \
+ { } \
+ else \
+ for (struct itree_iterator *itree_iter_ \
+ = itree_iterator_start (t, beg, end, ITREE_##order, \
+ __FILE__, __LINE__); \
+ ((n = itree_iterator_next (itree_iter_)) \
+ || (itree_iterator_finish (itree_iter_), false));)
+
+#define ITREE_FOREACH_ABORT() \
+ itree_iterator_finish (itree_iter_)
+
+#define ITREE_FOREACH_NARROW(beg, end) \
+ itree_iterator_narrow (itree_iter_, beg, end)
+
+#endif
diff --git a/src/keyboard.c b/src/keyboard.c
index b9a08ab91b..a978d6f02b 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1695,8 +1695,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 1eed323133..4701dfa868 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1,7 +1,6 @@
/* Fundamental definitions for GNU Emacs Lisp interpreter. -*- coding: utf-8
-*-
-Copyright (C) 1985-1987, 1993-1995, 1997-2022 Free Software Foundation,
-Inc.
+Copyright (C) 1985-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -2606,10 +2605,9 @@ struct Lisp_Overlay
*/
{
union vectorlike_header header;
- Lisp_Object start;
- Lisp_Object end;
Lisp_Object plist;
- struct Lisp_Overlay *next;
+ struct buffer *buffer; /* eassert (live buffer || NULL). */
+ struct itree_node *interval;
} GCALIGNED_STRUCT;
struct Lisp_Misc_Ptr
@@ -4420,7 +4418,6 @@ extern Lisp_Object make_float (double);
extern void display_malloc_warning (void);
extern specpdl_ref inhibit_garbage_collection (void);
extern Lisp_Object build_symbol_with_pos (Lisp_Object, Lisp_Object);
-extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
extern void free_cons (struct Lisp_Cons *);
extern void init_alloc_once (void);
extern void init_alloc (void);
diff --git a/src/pdumper.c b/src/pdumper.c
index 5e6ccd9bd8..d6ae57afb2 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2133,17 +2133,64 @@ dump_marker (struct dump_context *ctx, const struct
Lisp_Marker *marker)
return finish_dump_pvec (ctx, &out->header);
}
+static dump_off
+dump_interval_node (struct dump_context *ctx, struct itree_node *node,
+ dump_off parent_offset)
+{
+#if CHECK_STRUCTS && !defined (HASH_interval_node_5765524F7E)
+# error "interval_node changed. See CHECK_STRUCTS comment in config.h."
+#endif
+ struct itree_node out;
+ dump_object_start (ctx, &out, sizeof (out));
+ if (node->parent)
+ dump_field_fixup_later (ctx, &out, node, &node->parent);
+ if (node->left)
+ dump_field_fixup_later (ctx, &out, node, &node->parent);
+ if (node->right)
+ dump_field_fixup_later (ctx, &out, node, &node->parent);
+ DUMP_FIELD_COPY (&out, node, begin);
+ DUMP_FIELD_COPY (&out, node, end);
+ DUMP_FIELD_COPY (&out, node, limit);
+ DUMP_FIELD_COPY (&out, node, offset);
+ DUMP_FIELD_COPY (&out, node, otick);
+ dump_field_lv (ctx, &out, node, &node->data, WEIGHT_STRONG);
+ DUMP_FIELD_COPY (&out, node, red);
+ DUMP_FIELD_COPY (&out, node, rear_advance);
+ DUMP_FIELD_COPY (&out, node, front_advance);
+ dump_off offset = dump_object_finish (ctx, &out, sizeof (out));
+ if (node->parent)
+ dump_remember_fixup_ptr_raw
+ (ctx,
+ offset + dump_offsetof (struct itree_node, parent),
+ dump_interval_node (ctx, node->parent, offset));
+ if (node->left)
+ dump_remember_fixup_ptr_raw
+ (ctx,
+ offset + dump_offsetof (struct itree_node, left),
+ dump_interval_node (ctx, node->left, offset));
+ if (node->right)
+ dump_remember_fixup_ptr_raw
+ (ctx,
+ offset + dump_offsetof (struct itree_node, right),
+ dump_interval_node (ctx, node->right, offset));
+ return offset;
+}
+
static dump_off
dump_overlay (struct dump_context *ctx, const struct Lisp_Overlay *overlay)
{
-#if CHECK_STRUCTS && !defined (HASH_Lisp_Overlay_72EADA9882)
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Overlay_1CD4249AEC)
# error "Lisp_Overlay changed. See CHECK_STRUCTS comment in config.h."
#endif
START_DUMP_PVEC (ctx, &overlay->header, struct Lisp_Overlay, out);
dump_pseudovector_lisp_fields (ctx, &out->header, &overlay->header);
- dump_field_lv_rawptr (ctx, out, overlay, &overlay->next,
- Lisp_Vectorlike, WEIGHT_STRONG);
- return finish_dump_pvec (ctx, &out->header);
+ dump_field_fixup_later (ctx, &out, overlay, &overlay->interval);
+ dump_off offset = finish_dump_pvec (ctx, &out->header);
+ dump_remember_fixup_ptr_raw
+ (ctx,
+ offset + dump_offsetof (struct Lisp_Overlay, interval),
+ dump_interval_node (ctx, overlay->interval, offset));
+ return offset;
}
static void
@@ -2701,7 +2748,7 @@ dump_hash_table (struct dump_context *ctx,
static dump_off
dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer)
{
-#if CHECK_STRUCTS && !defined HASH_buffer_AA373AEE10
+#if CHECK_STRUCTS && !defined HASH_buffer_F0F08347A5
# error "buffer changed. See CHECK_STRUCTS comment in config.h."
#endif
struct buffer munged_buffer = *in_buffer;
@@ -2816,13 +2863,12 @@ dump_buffer (struct dump_context *ctx, const struct
buffer *in_buffer)
DUMP_FIELD_COPY (out, buffer, inhibit_buffer_hooks);
DUMP_FIELD_COPY (out, buffer, long_line_optimizations_p);
- dump_field_lv_rawptr (ctx, out, buffer, &buffer->overlays_before,
- Lisp_Vectorlike, WEIGHT_NORMAL);
-
- dump_field_lv_rawptr (ctx, out, buffer, &buffer->overlays_after,
- Lisp_Vectorlike, WEIGHT_NORMAL);
+ if (buffer->overlays && buffer->overlays->root != NULL)
+ /* We haven't implemented the code to dump overlays. */
+ emacs_abort ();
+ else
+ out->overlays = NULL;
- DUMP_FIELD_COPY (out, buffer, overlay_center);
dump_field_lv (ctx, out, buffer, &buffer->undo_list_,
WEIGHT_STRONG);
dump_off offset = finish_dump_pvec (ctx, &out->header);
diff --git a/src/print.c b/src/print.c
index 1c96ec14b8..65218084a4 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1,7 +1,6 @@
/* Lisp object printing and output streams.
-Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2022 Free Software
-Foundation, Inc.
+Copyright (C) 1985-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -594,8 +593,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);
@@ -1745,15 +1743,15 @@ print_vectorlike (Lisp_Object obj, Lisp_Object
printcharfun, bool escapeflag,
case PVEC_OVERLAY:
print_c_string ("#<overlay ", printcharfun);
- if (! XMARKER (OVERLAY_START (obj))->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 c22b579af2..ca693fd680 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -1,6 +1,5 @@
/* Interface code for dealing with text properties.
- Copyright (C) 1993-1995, 1997, 1999-2022 Free Software Foundation,
- Inc.
+ Copyright (C) 1993-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -634,36 +633,40 @@ 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;
-
- if (! (BUF_BEGV (XBUFFER (object)) <= pos
- && pos <= BUF_ZV (XBUFFER (object))))
+ struct buffer *b = XBUFFER (object);
+ struct itree_node *node;
+ struct sortvec items[2];
+ struct sortvec *result = NULL;
+ Lisp_Object result_tem = Qnil;
+
+ if (! (BUF_BEGV (b) <= pos
+ && pos <= BUF_ZV (b)))
xsignal1 (Qargs_out_of_range, position);
- set_buffer_temp (XBUFFER (object));
-
- USE_SAFE_ALLOCA;
- GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
- noverlays = sort_overlays (overlay_vec, noverlays, w);
-
- set_buffer_temp (obuf);
-
/* Now check the overlays in order of decreasing priority. */
- while (--noverlays >= 0)
+ ITREE_FOREACH (node, b->overlays, pos, pos + 1, ASCENDING)
{
- 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) || node->end < pos + 1
+ || (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 ();
+ if (result)
+ {
+ if (overlay)
+ *overlay = result->overlay;
+ return result_tem;
+ }
}
if (overlay)
diff --git a/src/window.h b/src/window.h
index 93817a9544..b5d0c69ab5 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1212,6 +1212,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 32675cd76a..dd243eca98 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1,7 +1,6 @@
/* Display generation from window structure and buffer text.
-Copyright (C) 1985-1988, 1993-1995, 1997-2022 Free Software Foundation,
-Inc.
+Copyright (C) 1985-2022 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -1159,7 +1158,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,
@@ -4168,39 +4166,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. */
@@ -5838,7 +5803,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
@@ -6572,6 +6537,8 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
struct overlay_entry entriesbuf[20];
ptrdiff_t size = ARRAYELTS (entriesbuf);
struct overlay_entry *entries = entriesbuf;
+ struct itree_node *node;
+
USE_SAFE_ALLOCA;
if (charpos <= 0)
@@ -6603,27 +6570,24 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
} \
while (false)
- /* Process overlay before the overlay center. */
- for (struct Lisp_Overlay *ov = current_buffer->overlays_before;
- ov; ov = ov->next)
+
+ /* Process overlays. */
+ ITREE_FOREACH (node, current_buffer->overlays, charpos - 1, charpos + 1,
DESCENDING)
{
- Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
+ Lisp_Object overlay = node->data;
eassert (OVERLAYP (overlay));
- ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
- ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
-
- if (end < charpos)
- break;
+ ptrdiff_t start = node->begin;
+ ptrdiff_t end = node->end;
/* Skip this overlay if it doesn't start or end at IT's current
- position. */
+ position. */
if (end != charpos && start != charpos)
- continue;
+ continue;
/* Skip this overlay if it doesn't apply to IT->w. */
Lisp_Object window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != it->w)
- continue;
+ continue;
/* If the text ``under'' the overlay is invisible, both before-
and after-strings from this overlay are visible; start and
@@ -6634,56 +6598,15 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
/* If overlay has a non-empty before-string, record it. */
Lisp_Object str;
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 (struct Lisp_Overlay *ov = current_buffer->overlays_after;
- ov; ov = ov->next)
- {
- Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
- eassert (OVERLAYP (overlay));
- ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
- ptrdiff_t 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. */
- Lisp_Object 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. */
- Lisp_Object invisible = Foverlay_get (overlay, Qinvisible);
- int invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
-
- /* If overlay has a non-empty before-string, record it. */
- Lisp_Object str;
- if ((start == charpos || (end == charpos && invis != 0))
- && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
- && SCHARS (str))
- RECORD_OVERLAY_STRING (overlay, str, false);
+ && (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);
+ && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
+ && SCHARS (str))
+ RECORD_OVERLAY_STRING (overlay, str, true);
}
#undef RECORD_OVERLAY_STRING
@@ -7088,11 +7011,11 @@ back_to_previous_line_start (struct it *it)
static bool
strings_with_newlines (ptrdiff_t startpos, ptrdiff_t endpos, struct window *w)
{
- /* Process overlays before the overlay center. */
- for (struct Lisp_Overlay *ov = current_buffer->overlays_before;
- ov; ov = ov->next)
+ struct itree_node *node;
+ /* Process overlays. */
+ ITREE_FOREACH (node, current_buffer->overlays, startpos, endpos, DESCENDING)
{
- Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
+ Lisp_Object overlay = node->data;
eassert (OVERLAYP (overlay));
/* Skip this overlay if it doesn't apply to our window. */
@@ -7100,14 +7023,8 @@ strings_with_newlines (ptrdiff_t startpos, ptrdiff_t
endpos, struct window *w)
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
- ptrdiff_t ostart = OVERLAY_POSITION (OVERLAY_START (overlay));
- ptrdiff_t oend = OVERLAY_POSITION (OVERLAY_END (overlay));
-
- /* Due to the order of overlays in overlays_before, once we get
- to an overlay whose end position is before STARTPOS, all the
- rest also end before STARTPOS, and thus are of no concern to us. */
- if (oend < startpos)
- break;
+ ptrdiff_t ostart = node->begin;
+ ptrdiff_t oend = node->end;
/* Skip overlays that don't overlap the range. */
if (!((startpos < oend && ostart < endpos)
@@ -7119,49 +7036,17 @@ strings_with_newlines (ptrdiff_t startpos, ptrdiff_t
endpos, struct window *w)
str = Foverlay_get (overlay, Qbefore_string);
if (STRINGP (str) && SCHARS (str)
&& memchr (SDATA (str), '\n', SBYTES (str)))
- return true;
- str = Foverlay_get (overlay, Qafter_string);
- if (STRINGP (str) && SCHARS (str)
- && memchr (SDATA (str), '\n', SBYTES (str)))
- return true;
- }
-
- /* Process overlays after the overlay center. */
- for (struct Lisp_Overlay *ov = current_buffer->overlays_after;
- ov; ov = ov->next)
- {
- Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
- eassert (OVERLAYP (overlay));
-
- /* Skip this overlay if it doesn't apply to our window. */
- Lisp_Object window = Foverlay_get (overlay, Qwindow);
- if (WINDOWP (window) && XWINDOW (window) != w)
- continue;
-
- ptrdiff_t ostart = OVERLAY_POSITION (OVERLAY_START (overlay));
- ptrdiff_t oend = OVERLAY_POSITION (OVERLAY_END (overlay));
-
- /* Due to the order of overlays in overlays_after, once we get
- to an overlay whose start position is after ENDPOS, all the
- rest also start after ENDPOS, and thus are of no concern to us. */
- if (ostart > endpos)
- break;
-
- /* Skip overlays that don't overlap the range. */
- if (!((startpos < oend && ostart < endpos)
- || (ostart == oend
- && (startpos == oend || (endpos == ZV && oend == endpos)))))
- continue;
-
- Lisp_Object str;
- str = Foverlay_get (overlay, Qbefore_string);
- if (STRINGP (str) && SCHARS (str)
- && memchr (SDATA (str), '\n', SBYTES (str)))
- return true;
+ {
+ ITREE_FOREACH_ABORT ();
+ return true;
+ }
str = Foverlay_get (overlay, Qafter_string);
if (STRINGP (str) && SCHARS (str)
&& memchr (SDATA (str), '\n', SBYTES (str)))
- return true;
+ {
+ ITREE_FOREACH_ABORT ();
+ return true;
+ }
}
/* Check for 'display' properties whose values include strings. */
@@ -7404,7 +7289,7 @@ back_to_previous_visible_line_start (struct it *it)
&& !NILP (val = get_char_property_and_overlay
(make_fixnum (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);
@@ -10639,7 +10524,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;
@@ -24618,13 +24502,6 @@ display_line (struct it *it, int cursor_vpos)
it->stretch_adjust = 0;
it->line_number_produced_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. */
@@ -35256,7 +35133,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);
}
@@ -35284,7 +35161,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
|| (!hlinfo->mouse_face_hidden
&& OVERLAYP (hlinfo->mouse_face_overlay)
/* It's possible the overlay was deleted (Bug#35273). */
- && XMARKER (OVERLAY_START (hlinfo->mouse_face_overlay))->buffer
+ && OVERLAY_BUFFER (hlinfo->mouse_face_overlay)
&& mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
{
/* Find the highest priority overlay with a mouse-face. */
diff --git a/src/xfaces.c b/src/xfaces.c
index 5e3a47d7f8..ed76db9adb 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6540,8 +6540,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;
}
@@ -6594,7 +6593,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);
@@ -6607,8 +6605,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
}
- oend = OVERLAY_END (overlay_vec[i]);
- oendpos = OVERLAY_POSITION (oend);
+ oendpos = OVERLAY_END (overlay_vec[i]);
if (oendpos < endpos)
endpos = oendpos;
}
@@ -6617,7 +6614,6 @@ 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);
@@ -6625,11 +6621,10 @@ face_at_buffer_position (struct window *w, ptrdiff_t
pos,
if (!NILP (prop))
merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
- 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 0000000000..ca7fc452b8
--- /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 0000000000..beef1dbc09
--- /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 0000000000..03eedce8a6
--- /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 0000000000..812f8e48a3
--- /dev/null
+++ b/test/manual/noverlay/emacs-compat.h
@@ -0,0 +1,52 @@
+#ifndef TEST_COMPAT_H
+#define TEST_COMPAT_H
+
+#include <stdio.h>
+#include <limits.h>
+
+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 0000000000..a318389213
--- /dev/null
+++ b/test/manual/noverlay/itree-tests.c
@@ -0,0 +1,1381 @@
+#include <config.h>
+#include <check.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#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 0000000000..fa4ef5f98d
--- /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 0000000000..e84941c08f
--- /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 558d05de14..e020732524 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -20,6 +20,7 @@
;;; Code:
(require 'ert)
+(require 'seq)
(require 'ert-x)
(require 'cl-lib)
(require 'let-alist)
@@ -859,6 +860,33 @@ with parameters from the *Messages* buffer modification."
(should-length 1 (overlays-at 15))
(should-length 1 (overlays-at (point-max))))))
+(defun sorted-overlays (overlays)
+ (sort
+ (mapcar (lambda (overlay)
+ (list (overlay-start overlay)
+ (overlay-end overlay)))
+ overlays)
+ (lambda (first second)
+ (cl-loop for a in first
+ for b in second
+ thereis (< a b)
+ until (> a b)))))
+
+(defun sorted-overlays-at (pos)
+ (sorted-overlays (overlays-at pos)))
+
+(defun sorted-overlays-in (beg end)
+ (sorted-overlays (overlays-in beg end)))
+
+(ert-deftest test-overlays-at-narrow-to-region-end ()
+ ;; See bug#58703.
+ (with-temp-buffer
+ (insert (make-string 30 ?x))
+ (make-overlay 10 11)
+ (narrow-to-region 10 10)
+ (should (equal
+ '((10 11))
+ (sorted-overlays-at 10)))))
;; +==========================================================================+
;; | overlay-in
@@ -936,6 +964,39 @@ with parameters from the *Messages* buffer modification."
(deftest-overlays-in-1 ae 9 11 (a) (a 10 10))
(deftest-overlays-in-1 af 10 11 (a) (a 10 10))
+;; behavior for empty range
+(ert-deftest test-overlays-in-empty-range ()
+ (with-temp-buffer
+ (insert (make-string 4 ?x))
+ (cl-loop for start from (point-min) to (point-max)
+ do (cl-loop for end from start to (point-max)
+ do (when (<= start end)
+ (make-overlay start end))))
+
+ (cl-loop for pos from (point-min) to (point-max)
+ do (ert-info ((format "after (overlay-recenter %d)" pos))
+ (overlay-recenter pos)
+ (should (equal
+ '((1 1))
+ (sorted-overlays-in (point-min) (point-min))))
+ (should (equal
+ '((1 3) (1 4) (1 5) (2 2))
+ (sorted-overlays-in 2 2)))
+ (should (equal
+ '((1 4) (1 5) (2 4) (2 5) (3 3))
+ (sorted-overlays-in 3 3)))
+ (should (equal
+ '((1 5) (2 5) (3 5) (4 4))
+ (sorted-overlays-in 4 4)))
+ (should (equal
+ '((5 5))
+ (sorted-overlays-in (point-max) (point-max))))))))
+
+(ert-deftest test-overlays-in-empty-range-bug58672 ()
+ (with-temp-buffer
+ (insert (make-string 10 ?=))
+ (make-overlay 5 7 nil nil t)
+ (should (equal nil (overlays-in 5 5)))))
;; behavior at point-max
(ert-deftest test-overlays-in-2 ()
@@ -1047,6 +1108,49 @@ with parameters from the *Messages* buffer modification."
(should-not (delete-all-overlays))))
+;; +==========================================================================+
+;; | get-pos-property
+;; +==========================================================================+
+
+(ert-deftest get-pos-property-overlay-beg ()
+ "Test `get-pos-property' at the beginning of an overlay.
+Regression test for bug#58706."
+ (with-temp-buffer
+ (insert (make-string 10000 ?x))
+ (let ((overlay (make-overlay 9999 10001)))
+ (overlay-put overlay 'forty-two 42))
+ (should (equal 42 (get-pos-property 9999 'forty-two)))))
+
+(ert-deftest get-pos-property-overlay-empty-rear-advance ()
+ "Test `get-pos-property' at the end of an empty rear-advance overlay.
+Regression test for bug#58706."
+ (with-temp-buffer
+ (insert (make-string 10000 ?x))
+ (let ((overlay (make-overlay 9999 9999 nil nil t)))
+ (overlay-put overlay 'forty-two 42))
+ (should (equal 42 (get-pos-property 9999 'forty-two)))))
+
+(ert-deftest get-pos-property-overlay-past-rear-advance ()
+ "Test `get-pos-property' past the end of an empty rear-advance overlay.
+Regression test for bug#58706."
+ (with-temp-buffer
+ (insert (make-string 10000 ?x))
+ (let ((overlay (make-overlay 9998 9998 nil nil t)))
+ (overlay-put overlay 'forty-two 42))
+ (should (equal nil (get-pos-property 9999 'forty-two)))))
+
+(ert-deftest get-pos-property-overlay-at-narrowed-end ()
+ "Test `get-pos-property' at the end of a narrowed region.
+Regression test for bug#58706."
+ (with-temp-buffer
+ (insert (make-string 11000 ?x))
+ (narrow-to-region 9998 10000)
+ (let ((overlay (make-overlay 10000 10000 nil t nil)))
+ (overlay-put overlay 'forty-two 42))
+ (should (equal nil (get-pos-property 9999 'forty-two)))))
+
+;; FIXME: add more `get-pos-property' tests
+
;; +==========================================================================+
;; | get-char-property(-and-overlay)
;; +==========================================================================+
@@ -1339,6 +1443,14 @@ with parameters from the *Messages* buffer modification."
(overlay-put ov 'value i)))
(should (eq 9 (get-char-property 1 'value)))))
+(ert-deftest buffer-tests--overlay-bug58479 ()
+ (with-temp-buffer
+ (insert "ab")
+ (let* ((pos (+ (point-min) 1))
+ (ol (make-overlay pos pos)))
+ (overlay-put ol 'my-prop 'set)
+ (should (null (get-char-property pos 'my-prop))))))
+
;; +==========================================================================+
;; | Other
@@ -1507,6 +1619,6559 @@ with parameters from the *Messages* buffer
modification."
(ovshould nonempty-eob-end 4 5)
(ovshould empty-eob 5 5)))))
+(ert-deftest test-overlay-randomly ()
+ "Exercise overlay code, but perform few assertions.
+
+This test works best when Emacs is configured with
+--enable-checking=yes. This is a little bit like fuzz testing,
+except this test has no way to reduce to a minimal failng test
+case. Regardless, by exercising many corner cases bugs can be
+found using Emacs' internal consistency assertions."
+ (let* (
+ ;; The size and slack for the test buffer size.
+ (buffer-size-target 1000)
+ (buffer-size-slack 200)
+
+ ;; Use up to 100 overlays. We need not use more to observe
+ ;; reasonable variation in the overlay data structures.
+ (overlay-count-limit 100)
+
+ ;; This test maintains a vector of overlays. Each iteration
+ ;; may append or erase one overlay.
+ (overlays (make-vector overlay-count-limit nil))
+ (overlay-count 0)
+
+ ;; The test is either slowly growing or shrinking the overlay
+ ;; count. Deletions still occur while growing, and additions
+ ;; still occur while shrinking. The GROWING variable only
+ ;; controls the relative probability of doing one or the
+ ;; other.
+ (growing t)
+
+ ;; Loop up to 1M times.
+ (iteration-count 0)
+ (iteration-target 100000))
+ (with-temp-buffer
+ (while (< (buffer-size) buffer-size-target)
+ (insert "Sed ut perspiciatis, unde omnis iste natus error sit
voluptatem
+accusantium doloremque laudantium, totam rem aperiam eaque ipsa,
+quae ab illo inventore veritatis et quasi architecto beatae vitae
+dicta sunt, explicabo. "))
+
+ (while (< iteration-count iteration-target)
+ (cl-incf iteration-count)
+
+ ;; Toggle GROWING if we've reached a size boundary. The idea
+ ;; is to initially steadily increase the overlay count, then
+ ;; steadily decrease it, then repeat.
+ (when (and growing (= overlay-count overlay-count-limit))
+ (setq growing nil))
+ (when (and (not growing) (= overlay-count 0))
+ (setq growing t))
+
+ ;; Create or delete a random overlay according to a
+ ;; probability chosen by GROWING.
+ (let ((create-overlay (>= (random 100) (if growing 40 60))))
+ (cond
+ ;; Possibly create a new overlay in a random place in the
+ ;; buffer. We have two easy choices. We can choose the
+ ;; overlay BEGIN randomly, then choose its END among the
+ ;; valid remaining buffer posiitions. Or we could choose
+ ;; the overlay width randomly, then choose a valid BEGIN.
+ ;; We take the former approach, because the overlay data
+ ;; structure is ordered primarily by BEGIN.
+ ((and create-overlay (< overlay-count overlay-count-limit))
+ (let* ((begin (random (buffer-size)))
+ (end (+ begin (random (- (buffer-size) begin))))
+ (ov (make-overlay begin end nil
+ (= 0 (random 2)) (= 0 (random 2)))))
+ (aset overlays overlay-count ov)
+ (cl-incf overlay-count)))
+ ((and (not create-overlay) (> overlay-count 0))
+
+ ;; Possibly delete a random overlay.
+ (let* ((last-index (1- overlay-count))
+ (index (random overlay-count))
+ (ov (aref overlays index)))
+ (when (< index last-index)
+ (aset overlays index (aref overlays last-index)))
+ (aset overlays last-index nil)
+ (cl-decf overlay-count)
+ (delete-overlay ov)))))
+
+ ;; Modify the buffer on occasion, which exercises the
+ ;; insert/remove gap logic in the overlay implementation.
+ (when (and (< (buffer-size) (+ buffer-size-target buffer-size-slack))
+ (zerop (random 10)))
+ (goto-char (1+ (random (buffer-size))))
+ (insert (+ ?a (random 26))))
+ (when (and (> (buffer-size) (- buffer-size-target buffer-size-slack))
+ (zerop (random 10)))
+ (goto-char (1+ (random (buffer-size))))
+ (delete-char 1))))))
+
+
+
+;;
+===================================================================================+
+;; | Autogenerated insert/delete/narrow tests
+;;
+===================================================================================+
+
+(when nil ;; Let's comment these out for now.
+
+;; (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))))))
+
+(ert-deftest overlay-autogenerated-test-64 nil
+ (with-temp-buffer
+ (insert "................................................................")
+ (make-overlay 31 10 nil nil nil)
+ (make-overlay 17 58 nil nil t)
+ (make-overlay 20 21 nil t nil)
+ (make-overlay 3 47 nil t t)
+ (make-overlay 47 43 nil t t)
+ (make-overlay 54 8 nil nil t)
+ (make-overlay 51 26 nil t nil)
+ (make-overlay 60 14 nil t nil)
+ (make-overlay 38 6 nil nil t)
+ (make-overlay 41 9 nil nil nil)
+ (make-overlay 44 38 nil nil t)
+ (make-overlay 55 48 nil nil t)
+ (make-overlay 10 41 nil nil t)
+ (make-overlay 35 49 nil t nil)
+ (make-overlay 50 46 nil nil nil)
+ (make-overlay 28 28 nil t nil)
+ (goto-char 59)
+ (delete-char 3)
+ (goto-char 28)
+ (widen)
+ (narrow-to-region 13 7)
+ (goto-char 11)
+ (insert ".")
+ (goto-char 9)
+ (delete-char 3)
+ (goto-char 8)
+ (delete-char 0)
+ (goto-char 7)
+ (insert ".............")
+ (goto-char 9)
+ (insert "..........")
+ (goto-char 22)
+ (delete-char 1)
+ (goto-char 31)
+ (delete-char 2)
+ (goto-char 22)
+ (insert ".........")
+ (goto-char 33)
+ (delete-char 1)
+ (goto-char 29)
+ (widen)
+ (narrow-to-region 59 51)
+ (goto-char 52)
+ (insert ".........")
+ (goto-char 53)
+ (insert "........")
+ (goto-char 53)
+ (delete-char 4)
+ (goto-char 54)
+ (insert "........")
+ (goto-char 53)
+ (insert "....")
+ (goto-char 75)
+ (widen)
+ (goto-char 70)
+ (delete-char 2)
+ (goto-char 108)
+ (delete-char 1)
+ (goto-char 80)
+ (widen)
+ (goto-char 70)
+ (widen)
+ (narrow-to-region 49 63)
+ (goto-char 49)
+ (insert "...")
+ (goto-char 66)
+ (delete-char 0)
+ (goto-char 63)
+ (delete-char 3)
+ (goto-char 59)
+ (insert "..........")
+ (goto-char 56)
+ (delete-char 6)
+ (goto-char 60)
+ (insert ".........")
+ (goto-char 62)
+ (widen)
+ (goto-char 58)
+ (insert ".............")
+ (goto-char 105)
+ (widen)
+ (narrow-to-region 94 109)
+ (goto-char 103)
+ (insert "............")
+ (should
+ (equal
+ (test-overlay-regions)
+ '((3 . 134)
+ (6 . 125)
+ (38 . 141)
+ (39 . 118)
+ (39 . 128)
+ (39 . 128)
+ (40 . 146)
+ (43 . 145)
+ (101 . 138)
+ (103 . 103))))))
+
+) ;; End of `when nil' for autogenerated insert/delete/narrow tests.
+
(ert-deftest buffer-multibyte-overlong-sequences ()
(dolist (uni '("\xE0\x80\x80"
"\xF0\x80\x80\x80"