Bram,
while investigating tests for makeing 'ul' settings global-local, I see
some problems with the undo state.
./vim -u NONE -N -c ':set ul=5'
1):for i in range(1,10)| call feedkeys("o".i."\e", 't')|endfor
(i.e. make sure echo line is a single undoable change).
2)(undo as long as it is possible, e.g. press u 6 times)
3)(press o7<esc>)
Note: undo will be possible exactly once. If you enable the u_check
functions by e.g. defining U_DEBUG, you'll notice many b_u_newhead and
b_u_numhead invalid messages at step 3
Also I see some valgrind error:
==7292== 3,357 (568 direct, 2,789 indirect) bytes in 1 blocks are definitely
lost in loss record 342 of 363
==7292== at 0x4C2A2DB: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7292== by 0x4DA1D5: lalloc (misc2.c:929)
==7292== by 0x5B61FE: u_savecommon (undo.c:430)
==7292== by 0x5B604B: u_savedel (undo.c:301)
==7292== by 0x4CC7D1: del_lines (misc1.c:2586)
==7292== by 0x4FBB4A: op_delete (ops.c:1875)
==7292== by 0x471F86: ex_operators (ex_docmd.c:8563)
==7292== by 0x46829E: do_one_cmd (ex_docmd.c:2689)
==7292== by 0x465831: do_cmdline (ex_docmd.c:1127)
==7292== by 0x4F1C47: nv_colon (normal.c:5461)
==7292== by 0x4EB1E4: normal_cmd (normal.c:1200)
==7292== by 0x5CF277: main_loop (main.c:1329)
==7292== by 0x5CEB92: main (main.c:1020)
(here at step 3 I deleted the whole buffer, that's why you see the
op_delete function calls).
The problem is, when freeing the curbuf->b_u_oldhead branch, one loses
the connection to the newly created curbuf->b_u_newhead header.
The attached patch fixes it, by making sure, there always exist a link
between the oldhead header and the newhead header.
regards,
Christian
--
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.
diff --git a/src/undo.c b/src/undo.c
--- a/src/undo.c
+++ b/src/undo.c
@@ -83,6 +83,7 @@
#include "vim.h"
+static int u_header_linked __ARGS((u_header_T *uhp, u_header_T *uhq));
static void u_unch_branch __ARGS((u_header_T *uhp));
static u_entry_T *u_get_headentry __ARGS((void));
static void u_getbot __ARGS((void));
@@ -125,6 +126,30 @@
static int lastmark = 0;
+/* Check, that both headers are linked to each other */
+/* start from uhp, go backwards and try to find uhq */
+static int
+u_header_linked(uhp, uhq)
+ u_header_T *uhp;
+ u_header_T *uhq;
+{
+ if (uhp == NULL || uhq == NULL)
+ return FALSE;
+
+ if (uhp == uhq)
+ return TRUE;
+
+ /* Check the next alt tree. */
+ if (u_header_linked(uhp->uh_alt_next.ptr, uhq))
+ return TRUE;
+
+ /* Check the next header in this branch. */
+ if (u_header_linked(uhp->uh_prev.ptr, uhq))
+ return TRUE;
+
+ return FALSE;
+}
+
#if defined(U_DEBUG) || defined(PROTO)
/*
* Check the undo structures for being valid. Print a warning when something
@@ -526,7 +551,20 @@
curbuf->b_u_newhead = uhp;
if (curbuf->b_u_oldhead == NULL)
curbuf->b_u_oldhead = uhp;
+ /* check, curbuf->b_u_newhead is actually connected to curbuf->b_u_oldhead */
+ if (!u_header_linked(curbuf->b_u_oldhead, curbuf->b_u_newhead))
+ {
+ u_header_T *uh;
+ uh = curbuf->b_u_oldhead;
+ while (uh->uh_prev.ptr != NULL)
+ uh = uh->uh_prev.ptr;
+ uh->uh_prev.ptr = curbuf->b_u_newhead;
+ curbuf->b_u_newhead->uh_next.ptr = uh;
+ }
++curbuf->b_u_numhead;
+#ifdef U_DEBUG
+ u_check(FALSE);
+#endif
}
else
{