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 vim_dev+unsubscr...@googlegroups.com. 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 {