xref: /vim-8.2.3635/src/undo.c (revision fc39ecf8)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * undo.c: multi level undo facility
12  *
13  * The saved lines are stored in a list of lists (one for each buffer):
14  *
15  * b_u_oldhead------------------------------------------------+
16  *							      |
17  *							      V
18  *		  +--------------+    +--------------+	  +--------------+
19  * b_u_newhead--->| u_header	 |    | u_header     |	  | u_header	 |
20  *		  |	uh_next------>|     uh_next------>|	uh_next---->NULL
21  *	   NULL<--------uh_prev  |<---------uh_prev  |<---------uh_prev  |
22  *		  |	uh_entry |    |     uh_entry |	  |	uh_entry |
23  *		  +--------|-----+    +--------|-----+	  +--------|-----+
24  *			   |		       |		   |
25  *			   V		       V		   V
26  *		  +--------------+    +--------------+	  +--------------+
27  *		  | u_entry	 |    | u_entry      |	  | u_entry	 |
28  *		  |	ue_next  |    |     ue_next  |	  |	ue_next  |
29  *		  +--------|-----+    +--------|-----+	  +--------|-----+
30  *			   |		       |		   |
31  *			   V		       V		   V
32  *		  +--------------+	      NULL		  NULL
33  *		  | u_entry	 |
34  *		  |	ue_next  |
35  *		  +--------|-----+
36  *			   |
37  *			   V
38  *			  etc.
39  *
40  * Each u_entry list contains the information for one undo or redo.
41  * curbuf->b_u_curhead points to the header of the last undo (the next redo),
42  * or is NULL if nothing has been undone (end of the branch).
43  *
44  * For keeping alternate undo/redo branches the uh_alt field is used.  Thus at
45  * each point in the list a branch may appear for an alternate to redo.  The
46  * uh_seq field is numbered sequentially to be able to find a newer or older
47  * branch.
48  *
49  *		   +---------------+	+---------------+
50  * b_u_oldhead --->| u_header	   |	| u_header	|
51  *		   |   uh_alt_next ---->|   uh_alt_next ----> NULL
52  *	   NULL <----- uh_alt_prev |<------ uh_alt_prev |
53  *		   |   uh_prev	   |	|   uh_prev	|
54  *		   +-----|---------+	+-----|---------+
55  *			 |		      |
56  *			 V		      V
57  *		   +---------------+	+---------------+
58  *		   | u_header	   |	| u_header	|
59  *		   |   uh_alt_next |	|   uh_alt_next |
60  * b_u_newhead --->|   uh_alt_prev |	|   uh_alt_prev |
61  *		   |   uh_prev	   |	|   uh_prev	|
62  *		   +-----|---------+	+-----|---------+
63  *			 |		      |
64  *			 V		      V
65  *		       NULL		+---------------+    +---------------+
66  *					| u_header	|    | u_header      |
67  *					|   uh_alt_next ---->|	 uh_alt_next |
68  *					|   uh_alt_prev |<------ uh_alt_prev |
69  *					|   uh_prev	|    |	 uh_prev     |
70  *					+-----|---------+    +-----|---------+
71  *					      |			   |
72  *					     etc.		  etc.
73  *
74  *
75  * All data is allocated and will all be freed when the buffer is unloaded.
76  */
77 
78 /* Uncomment the next line for including the u_check() function.  This warns
79  * for errors in the debug information. */
80 /* #define U_DEBUG 1 */
81 #define UH_MAGIC 0x18dade	/* value for uh_magic when in use */
82 #define UE_MAGIC 0xabc123	/* value for ue_magic when in use */
83 
84 /* Size of buffer used for encryption. */
85 #define CRYPT_BUF_SIZE 8192
86 
87 #include "vim.h"
88 
89 /* Structure passed around between functions.
90  * Avoids passing cryptstate_T when encryption not available. */
91 typedef struct {
92     buf_T	*bi_buf;
93     FILE	*bi_fp;
94 #ifdef FEAT_CRYPT
95     cryptstate_T *bi_state;
96     char_u	*bi_buffer; /* CRYPT_BUF_SIZE, NULL when not buffering */
97     size_t	bi_used;    /* bytes written to/read from bi_buffer */
98     size_t	bi_avail;   /* bytes available in bi_buffer */
99 #endif
100 } bufinfo_T;
101 
102 
103 static long get_undolevel __ARGS((void));
104 static void u_unch_branch __ARGS((u_header_T *uhp));
105 static u_entry_T *u_get_headentry __ARGS((void));
106 static void u_getbot __ARGS((void));
107 static void u_doit __ARGS((int count));
108 static void u_undoredo __ARGS((int undo));
109 static void u_undo_end __ARGS((int did_undo, int absolute));
110 static void u_add_time __ARGS((char_u *buf, size_t buflen, time_t tt));
111 static void u_freeheader __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
112 static void u_freebranch __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
113 static void u_freeentries __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
114 static void u_freeentry __ARGS((u_entry_T *, long));
115 #ifdef FEAT_PERSISTENT_UNDO
116 static void corruption_error __ARGS((char *mesg, char_u *file_name));
117 static void u_free_uhp __ARGS((u_header_T *uhp));
118 static int undo_write __ARGS((bufinfo_T *bi, char_u *ptr, size_t len));
119 static int undo_flush __ARGS((bufinfo_T *bi));
120 static int fwrite_crypt __ARGS((bufinfo_T *bi, char_u *ptr, size_t len));
121 static int undo_write_bytes __ARGS((bufinfo_T *bi, long_u nr, int len));
122 static void put_header_ptr __ARGS((bufinfo_T *bi, u_header_T *uhp));
123 static int undo_read_4c __ARGS((bufinfo_T *bi));
124 static int undo_read_2c __ARGS((bufinfo_T *bi));
125 static int undo_read_byte __ARGS((bufinfo_T *bi));
126 static time_t undo_read_time __ARGS((bufinfo_T *bi));
127 static int undo_read __ARGS((bufinfo_T *bi, char_u *buffer, size_t size));
128 static char_u *read_string_decrypt __ARGS((bufinfo_T *bi, int len));
129 static int serialize_header __ARGS((bufinfo_T *bi, char_u *hash));
130 static int serialize_uhp __ARGS((bufinfo_T *bi, u_header_T *uhp));
131 static u_header_T *unserialize_uhp __ARGS((bufinfo_T *bi, char_u *file_name));
132 static int serialize_uep __ARGS((bufinfo_T *bi, u_entry_T *uep));
133 static u_entry_T *unserialize_uep __ARGS((bufinfo_T *bi, int *error, char_u *file_name));
134 static void serialize_pos __ARGS((bufinfo_T *bi, pos_T pos));
135 static void unserialize_pos __ARGS((bufinfo_T *bi, pos_T *pos));
136 static void serialize_visualinfo __ARGS((bufinfo_T *bi, visualinfo_T *info));
137 static void unserialize_visualinfo __ARGS((bufinfo_T *bi, visualinfo_T *info));
138 #endif
139 
140 #define U_ALLOC_LINE(size) lalloc((long_u)(size), FALSE)
141 static char_u *u_save_line __ARGS((linenr_T));
142 
143 /* used in undo_end() to report number of added and deleted lines */
144 static long	u_newcount, u_oldcount;
145 
146 /*
147  * When 'u' flag included in 'cpoptions', we behave like vi.  Need to remember
148  * the action that "u" should do.
149  */
150 static int	undo_undoes = FALSE;
151 
152 static int	lastmark = 0;
153 
154 #if defined(U_DEBUG) || defined(PROTO)
155 /*
156  * Check the undo structures for being valid.  Print a warning when something
157  * looks wrong.
158  */
159 static int seen_b_u_curhead;
160 static int seen_b_u_newhead;
161 static int header_count;
162 
163     static void
164 u_check_tree(u_header_T *uhp,
165 	u_header_T *exp_uh_next,
166 	u_header_T *exp_uh_alt_prev)
167 {
168     u_entry_T *uep;
169 
170     if (uhp == NULL)
171 	return;
172     ++header_count;
173     if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1)
174     {
175 	EMSG("b_u_curhead found twice (looping?)");
176 	return;
177     }
178     if (uhp == curbuf->b_u_newhead && ++seen_b_u_newhead > 1)
179     {
180 	EMSG("b_u_newhead found twice (looping?)");
181 	return;
182     }
183 
184     if (uhp->uh_magic != UH_MAGIC)
185 	EMSG("uh_magic wrong (may be using freed memory)");
186     else
187     {
188 	/* Check pointers back are correct. */
189 	if (uhp->uh_next.ptr != exp_uh_next)
190 	{
191 	    EMSG("uh_next wrong");
192 	    smsg((char_u *)"expected: 0x%x, actual: 0x%x",
193 					       exp_uh_next, uhp->uh_next.ptr);
194 	}
195 	if (uhp->uh_alt_prev.ptr != exp_uh_alt_prev)
196 	{
197 	    EMSG("uh_alt_prev wrong");
198 	    smsg((char_u *)"expected: 0x%x, actual: 0x%x",
199 				       exp_uh_alt_prev, uhp->uh_alt_prev.ptr);
200 	}
201 
202 	/* Check the undo tree at this header. */
203 	for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
204 	{
205 	    if (uep->ue_magic != UE_MAGIC)
206 	    {
207 		EMSG("ue_magic wrong (may be using freed memory)");
208 		break;
209 	    }
210 	}
211 
212 	/* Check the next alt tree. */
213 	u_check_tree(uhp->uh_alt_next.ptr, uhp->uh_next.ptr, uhp);
214 
215 	/* Check the next header in this branch. */
216 	u_check_tree(uhp->uh_prev.ptr, uhp, NULL);
217     }
218 }
219 
220     static void
221 u_check(int newhead_may_be_NULL)
222 {
223     seen_b_u_newhead = 0;
224     seen_b_u_curhead = 0;
225     header_count = 0;
226 
227     u_check_tree(curbuf->b_u_oldhead, NULL, NULL);
228 
229     if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL
230 	    && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL))
231 	EMSGN("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead);
232     if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0)
233 	EMSGN("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead);
234     if (header_count != curbuf->b_u_numhead)
235     {
236 	EMSG("b_u_numhead invalid");
237 	smsg((char_u *)"expected: %ld, actual: %ld",
238 			       (long)header_count, (long)curbuf->b_u_numhead);
239     }
240 }
241 #endif
242 
243 /*
244  * Save the current line for both the "u" and "U" command.
245  * Careful: may trigger autocommands that reload the buffer.
246  * Returns OK or FAIL.
247  */
248     int
249 u_save_cursor()
250 {
251     return (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
252 				      (linenr_T)(curwin->w_cursor.lnum + 1)));
253 }
254 
255 /*
256  * Save the lines between "top" and "bot" for both the "u" and "U" command.
257  * "top" may be 0 and bot may be curbuf->b_ml.ml_line_count + 1.
258  * Careful: may trigger autocommands that reload the buffer.
259  * Returns FAIL when lines could not be saved, OK otherwise.
260  */
261     int
262 u_save(top, bot)
263     linenr_T top, bot;
264 {
265     if (undo_off)
266 	return OK;
267 
268     if (top > curbuf->b_ml.ml_line_count
269 	    || top >= bot
270 	    || bot > curbuf->b_ml.ml_line_count + 1)
271 	return FALSE;	/* rely on caller to do error messages */
272 
273     if (top + 2 == bot)
274 	u_saveline((linenr_T)(top + 1));
275 
276     return (u_savecommon(top, bot, (linenr_T)0, FALSE));
277 }
278 
279 /*
280  * Save the line "lnum" (used by ":s" and "~" command).
281  * The line is replaced, so the new bottom line is lnum + 1.
282  * Careful: may trigger autocommands that reload the buffer.
283  * Returns FAIL when lines could not be saved, OK otherwise.
284  */
285     int
286 u_savesub(lnum)
287     linenr_T	lnum;
288 {
289     if (undo_off)
290 	return OK;
291 
292     return (u_savecommon(lnum - 1, lnum + 1, lnum + 1, FALSE));
293 }
294 
295 /*
296  * A new line is inserted before line "lnum" (used by :s command).
297  * The line is inserted, so the new bottom line is lnum + 1.
298  * Careful: may trigger autocommands that reload the buffer.
299  * Returns FAIL when lines could not be saved, OK otherwise.
300  */
301     int
302 u_inssub(lnum)
303     linenr_T	lnum;
304 {
305     if (undo_off)
306 	return OK;
307 
308     return (u_savecommon(lnum - 1, lnum, lnum + 1, FALSE));
309 }
310 
311 /*
312  * Save the lines "lnum" - "lnum" + nlines (used by delete command).
313  * The lines are deleted, so the new bottom line is lnum, unless the buffer
314  * becomes empty.
315  * Careful: may trigger autocommands that reload the buffer.
316  * Returns FAIL when lines could not be saved, OK otherwise.
317  */
318     int
319 u_savedel(lnum, nlines)
320     linenr_T	lnum;
321     long	nlines;
322 {
323     if (undo_off)
324 	return OK;
325 
326     return (u_savecommon(lnum - 1, lnum + nlines,
327 		     nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE));
328 }
329 
330 /*
331  * Return TRUE when undo is allowed.  Otherwise give an error message and
332  * return FALSE.
333  */
334     int
335 undo_allowed()
336 {
337     /* Don't allow changes when 'modifiable' is off.  */
338     if (!curbuf->b_p_ma)
339     {
340 	EMSG(_(e_modifiable));
341 	return FALSE;
342     }
343 
344 #ifdef HAVE_SANDBOX
345     /* In the sandbox it's not allowed to change the text. */
346     if (sandbox != 0)
347     {
348 	EMSG(_(e_sandbox));
349 	return FALSE;
350     }
351 #endif
352 
353     /* Don't allow changes in the buffer while editing the cmdline.  The
354      * caller of getcmdline() may get confused. */
355     if (textlock != 0)
356     {
357 	EMSG(_(e_secure));
358 	return FALSE;
359     }
360 
361     return TRUE;
362 }
363 
364 /*
365  * Get the undolevle value for the current buffer.
366  */
367     static long
368 get_undolevel()
369 {
370     if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL)
371 	return p_ul;
372     return curbuf->b_p_ul;
373 }
374 
375 /*
376  * Common code for various ways to save text before a change.
377  * "top" is the line above the first changed line.
378  * "bot" is the line below the last changed line.
379  * "newbot" is the new bottom line.  Use zero when not known.
380  * "reload" is TRUE when saving for a buffer reload.
381  * Careful: may trigger autocommands that reload the buffer.
382  * Returns FAIL when lines could not be saved, OK otherwise.
383  */
384     int
385 u_savecommon(top, bot, newbot, reload)
386     linenr_T	top, bot;
387     linenr_T	newbot;
388     int		reload;
389 {
390     linenr_T	lnum;
391     long	i;
392     u_header_T	*uhp;
393     u_header_T	*old_curhead;
394     u_entry_T	*uep;
395     u_entry_T	*prev_uep;
396     long	size;
397 
398     if (!reload)
399     {
400 	/* When making changes is not allowed return FAIL.  It's a crude way
401 	 * to make all change commands fail. */
402 	if (!undo_allowed())
403 	    return FAIL;
404 
405 #ifdef FEAT_NETBEANS_INTG
406 	/*
407 	 * Netbeans defines areas that cannot be modified.  Bail out here when
408 	 * trying to change text in a guarded area.
409 	 */
410 	if (netbeans_active())
411 	{
412 	    if (netbeans_is_guarded(top, bot))
413 	    {
414 		EMSG(_(e_guarded));
415 		return FAIL;
416 	    }
417 	    if (curbuf->b_p_ro)
418 	    {
419 		EMSG(_(e_nbreadonly));
420 		return FAIL;
421 	    }
422 	}
423 #endif
424 
425 #ifdef FEAT_AUTOCMD
426 	/*
427 	 * Saving text for undo means we are going to make a change.  Give a
428 	 * warning for a read-only file before making the change, so that the
429 	 * FileChangedRO event can replace the buffer with a read-write version
430 	 * (e.g., obtained from a source control system).
431 	 */
432 	change_warning(0);
433 	if (bot > curbuf->b_ml.ml_line_count + 1)
434 	{
435 	    /* This happens when the FileChangedRO autocommand changes the
436 	     * file in a way it becomes shorter. */
437 	    EMSG(_("E881: Line count changed unexpectedly"));
438 	    return FAIL;
439 	}
440 #endif
441     }
442 
443 #ifdef U_DEBUG
444     u_check(FALSE);
445 #endif
446 
447     size = bot - top - 1;
448 
449     /*
450      * If curbuf->b_u_synced == TRUE make a new header.
451      */
452     if (curbuf->b_u_synced)
453     {
454 #ifdef FEAT_JUMPLIST
455 	/* Need to create new entry in b_changelist. */
456 	curbuf->b_new_change = TRUE;
457 #endif
458 
459 	if (get_undolevel() >= 0)
460 	{
461 	    /*
462 	     * Make a new header entry.  Do this first so that we don't mess
463 	     * up the undo info when out of memory.
464 	     */
465 	    uhp = (u_header_T *)U_ALLOC_LINE(sizeof(u_header_T));
466 	    if (uhp == NULL)
467 		goto nomem;
468 #ifdef U_DEBUG
469 	    uhp->uh_magic = UH_MAGIC;
470 #endif
471 	}
472 	else
473 	    uhp = NULL;
474 
475 	/*
476 	 * If we undid more than we redid, move the entry lists before and
477 	 * including curbuf->b_u_curhead to an alternate branch.
478 	 */
479 	old_curhead = curbuf->b_u_curhead;
480 	if (old_curhead != NULL)
481 	{
482 	    curbuf->b_u_newhead = old_curhead->uh_next.ptr;
483 	    curbuf->b_u_curhead = NULL;
484 	}
485 
486 	/*
487 	 * free headers to keep the size right
488 	 */
489 	while (curbuf->b_u_numhead > get_undolevel()
490 					       && curbuf->b_u_oldhead != NULL)
491 	{
492 	    u_header_T	    *uhfree = curbuf->b_u_oldhead;
493 
494 	    if (uhfree == old_curhead)
495 		/* Can't reconnect the branch, delete all of it. */
496 		u_freebranch(curbuf, uhfree, &old_curhead);
497 	    else if (uhfree->uh_alt_next.ptr == NULL)
498 		/* There is no branch, only free one header. */
499 		u_freeheader(curbuf, uhfree, &old_curhead);
500 	    else
501 	    {
502 		/* Free the oldest alternate branch as a whole. */
503 		while (uhfree->uh_alt_next.ptr != NULL)
504 		    uhfree = uhfree->uh_alt_next.ptr;
505 		u_freebranch(curbuf, uhfree, &old_curhead);
506 	    }
507 #ifdef U_DEBUG
508 	    u_check(TRUE);
509 #endif
510 	}
511 
512 	if (uhp == NULL)		/* no undo at all */
513 	{
514 	    if (old_curhead != NULL)
515 		u_freebranch(curbuf, old_curhead, NULL);
516 	    curbuf->b_u_synced = FALSE;
517 	    return OK;
518 	}
519 
520 	uhp->uh_prev.ptr = NULL;
521 	uhp->uh_next.ptr = curbuf->b_u_newhead;
522 	uhp->uh_alt_next.ptr = old_curhead;
523 	if (old_curhead != NULL)
524 	{
525 	    uhp->uh_alt_prev.ptr = old_curhead->uh_alt_prev.ptr;
526 	    if (uhp->uh_alt_prev.ptr != NULL)
527 		uhp->uh_alt_prev.ptr->uh_alt_next.ptr = uhp;
528 	    old_curhead->uh_alt_prev.ptr = uhp;
529 	    if (curbuf->b_u_oldhead == old_curhead)
530 		curbuf->b_u_oldhead = uhp;
531 	}
532 	else
533 	    uhp->uh_alt_prev.ptr = NULL;
534 	if (curbuf->b_u_newhead != NULL)
535 	    curbuf->b_u_newhead->uh_prev.ptr = uhp;
536 
537 	uhp->uh_seq = ++curbuf->b_u_seq_last;
538 	curbuf->b_u_seq_cur = uhp->uh_seq;
539 	uhp->uh_time = time(NULL);
540 	uhp->uh_save_nr = 0;
541 	curbuf->b_u_time_cur = uhp->uh_time + 1;
542 
543 	uhp->uh_walk = 0;
544 	uhp->uh_entry = NULL;
545 	uhp->uh_getbot_entry = NULL;
546 	uhp->uh_cursor = curwin->w_cursor;	/* save cursor pos. for undo */
547 #ifdef FEAT_VIRTUALEDIT
548 	if (virtual_active() && curwin->w_cursor.coladd > 0)
549 	    uhp->uh_cursor_vcol = getviscol();
550 	else
551 	    uhp->uh_cursor_vcol = -1;
552 #endif
553 
554 	/* save changed and buffer empty flag for undo */
555 	uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
556 		       ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
557 
558 	/* save named marks and Visual marks for undo */
559 	mch_memmove(uhp->uh_namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS);
560 	uhp->uh_visual = curbuf->b_visual;
561 
562 	curbuf->b_u_newhead = uhp;
563 	if (curbuf->b_u_oldhead == NULL)
564 	    curbuf->b_u_oldhead = uhp;
565 	++curbuf->b_u_numhead;
566     }
567     else
568     {
569 	if (get_undolevel() < 0)	/* no undo at all */
570 	    return OK;
571 
572 	/*
573 	 * When saving a single line, and it has been saved just before, it
574 	 * doesn't make sense saving it again.  Saves a lot of memory when
575 	 * making lots of changes inside the same line.
576 	 * This is only possible if the previous change didn't increase or
577 	 * decrease the number of lines.
578 	 * Check the ten last changes.  More doesn't make sense and takes too
579 	 * long.
580 	 */
581 	if (size == 1)
582 	{
583 	    uep = u_get_headentry();
584 	    prev_uep = NULL;
585 	    for (i = 0; i < 10; ++i)
586 	    {
587 		if (uep == NULL)
588 		    break;
589 
590 		/* If lines have been inserted/deleted we give up.
591 		 * Also when the line was included in a multi-line save. */
592 		if ((curbuf->b_u_newhead->uh_getbot_entry != uep
593 			    ? (uep->ue_top + uep->ue_size + 1
594 				!= (uep->ue_bot == 0
595 				    ? curbuf->b_ml.ml_line_count + 1
596 				    : uep->ue_bot))
597 			    : uep->ue_lcount != curbuf->b_ml.ml_line_count)
598 			|| (uep->ue_size > 1
599 			    && top >= uep->ue_top
600 			    && top + 2 <= uep->ue_top + uep->ue_size + 1))
601 		    break;
602 
603 		/* If it's the same line we can skip saving it again. */
604 		if (uep->ue_size == 1 && uep->ue_top == top)
605 		{
606 		    if (i > 0)
607 		    {
608 			/* It's not the last entry: get ue_bot for the last
609 			 * entry now.  Following deleted/inserted lines go to
610 			 * the re-used entry. */
611 			u_getbot();
612 			curbuf->b_u_synced = FALSE;
613 
614 			/* Move the found entry to become the last entry.  The
615 			 * order of undo/redo doesn't matter for the entries
616 			 * we move it over, since they don't change the line
617 			 * count and don't include this line.  It does matter
618 			 * for the found entry if the line count is changed by
619 			 * the executed command. */
620 			prev_uep->ue_next = uep->ue_next;
621 			uep->ue_next = curbuf->b_u_newhead->uh_entry;
622 			curbuf->b_u_newhead->uh_entry = uep;
623 		    }
624 
625 		    /* The executed command may change the line count. */
626 		    if (newbot != 0)
627 			uep->ue_bot = newbot;
628 		    else if (bot > curbuf->b_ml.ml_line_count)
629 			uep->ue_bot = 0;
630 		    else
631 		    {
632 			uep->ue_lcount = curbuf->b_ml.ml_line_count;
633 			curbuf->b_u_newhead->uh_getbot_entry = uep;
634 		    }
635 		    return OK;
636 		}
637 		prev_uep = uep;
638 		uep = uep->ue_next;
639 	    }
640 	}
641 
642 	/* find line number for ue_bot for previous u_save() */
643 	u_getbot();
644     }
645 
646 #if !defined(UNIX) && !defined(DJGPP) && !defined(WIN32) && !defined(__EMX__)
647 	/*
648 	 * With Amiga and MSDOS 16 bit we can't handle big undo's, because
649 	 * then u_alloc_line would have to allocate a block larger than 32K
650 	 */
651     if (size >= 8000)
652 	goto nomem;
653 #endif
654 
655     /*
656      * add lines in front of entry list
657      */
658     uep = (u_entry_T *)U_ALLOC_LINE(sizeof(u_entry_T));
659     if (uep == NULL)
660 	goto nomem;
661     vim_memset(uep, 0, sizeof(u_entry_T));
662 #ifdef U_DEBUG
663     uep->ue_magic = UE_MAGIC;
664 #endif
665 
666     uep->ue_size = size;
667     uep->ue_top = top;
668     if (newbot != 0)
669 	uep->ue_bot = newbot;
670     /*
671      * Use 0 for ue_bot if bot is below last line.
672      * Otherwise we have to compute ue_bot later.
673      */
674     else if (bot > curbuf->b_ml.ml_line_count)
675 	uep->ue_bot = 0;
676     else
677     {
678 	uep->ue_lcount = curbuf->b_ml.ml_line_count;
679 	curbuf->b_u_newhead->uh_getbot_entry = uep;
680     }
681 
682     if (size > 0)
683     {
684 	if ((uep->ue_array = (char_u **)U_ALLOC_LINE(
685 					    sizeof(char_u *) * size)) == NULL)
686 	{
687 	    u_freeentry(uep, 0L);
688 	    goto nomem;
689 	}
690 	for (i = 0, lnum = top + 1; i < size; ++i)
691 	{
692 	    fast_breakcheck();
693 	    if (got_int)
694 	    {
695 		u_freeentry(uep, i);
696 		return FAIL;
697 	    }
698 	    if ((uep->ue_array[i] = u_save_line(lnum++)) == NULL)
699 	    {
700 		u_freeentry(uep, i);
701 		goto nomem;
702 	    }
703 	}
704     }
705     else
706 	uep->ue_array = NULL;
707     uep->ue_next = curbuf->b_u_newhead->uh_entry;
708     curbuf->b_u_newhead->uh_entry = uep;
709     curbuf->b_u_synced = FALSE;
710     undo_undoes = FALSE;
711 
712 #ifdef U_DEBUG
713     u_check(FALSE);
714 #endif
715     return OK;
716 
717 nomem:
718     msg_silent = 0;	/* must display the prompt */
719     if (ask_yesno((char_u *)_("No undo possible; continue anyway"), TRUE)
720 								       == 'y')
721     {
722 	undo_off = TRUE;	    /* will be reset when character typed */
723 	return OK;
724     }
725     do_outofmem_msg((long_u)0);
726     return FAIL;
727 }
728 
729 #if defined(FEAT_PERSISTENT_UNDO) || defined(PROTO)
730 
731 # define UF_START_MAGIC	    "Vim\237UnDo\345"  /* magic at start of undofile */
732 # define UF_START_MAGIC_LEN	9
733 # define UF_HEADER_MAGIC	0x5fd0	/* magic at start of header */
734 # define UF_HEADER_END_MAGIC	0xe7aa	/* magic after last header */
735 # define UF_ENTRY_MAGIC		0xf518	/* magic at start of entry */
736 # define UF_ENTRY_END_MAGIC	0x3581	/* magic after last entry */
737 # define UF_VERSION		2	/* 2-byte undofile version number */
738 # define UF_VERSION_CRYPT	0x8002	/* idem, encrypted */
739 
740 /* extra fields for header */
741 # define UF_LAST_SAVE_NR	1
742 
743 /* extra fields for uhp */
744 # define UHP_SAVE_NR		1
745 
746 static char_u e_not_open[] = N_("E828: Cannot open undo file for writing: %s");
747 
748 /*
749  * Compute the hash for the current buffer text into hash[UNDO_HASH_SIZE].
750  */
751     void
752 u_compute_hash(hash)
753     char_u *hash;
754 {
755     context_sha256_T	ctx;
756     linenr_T		lnum;
757     char_u		*p;
758 
759     sha256_start(&ctx);
760     for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
761     {
762 	p = ml_get(lnum);
763 	sha256_update(&ctx, p, (UINT32_T)(STRLEN(p) + 1));
764     }
765     sha256_finish(&ctx, hash);
766 }
767 
768 /*
769  * Return an allocated string of the full path of the target undofile.
770  * When "reading" is TRUE find the file to read, go over all directories in
771  * 'undodir'.
772  * When "reading" is FALSE use the first name where the directory exists.
773  * Returns NULL when there is no place to write or no file to read.
774  */
775     char_u *
776 u_get_undo_file_name(buf_ffname, reading)
777     char_u	*buf_ffname;
778     int		reading;
779 {
780     char_u	*dirp;
781     char_u	dir_name[IOSIZE + 1];
782     char_u	*munged_name = NULL;
783     char_u	*undo_file_name = NULL;
784     int		dir_len;
785     char_u	*p;
786     struct stat st;
787     char_u	*ffname = buf_ffname;
788 #ifdef HAVE_READLINK
789     char_u	fname_buf[MAXPATHL];
790 #endif
791 
792     if (ffname == NULL)
793 	return NULL;
794 
795 #ifdef HAVE_READLINK
796     /* Expand symlink in the file name, so that we put the undo file with the
797      * actual file instead of with the symlink. */
798     if (resolve_symlink(ffname, fname_buf) == OK)
799 	ffname = fname_buf;
800 #endif
801 
802     /* Loop over 'undodir'.  When reading find the first file that exists.
803      * When not reading use the first directory that exists or ".". */
804     dirp = p_udir;
805     while (*dirp != NUL)
806     {
807 	dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ",");
808 	if (dir_len == 1 && dir_name[0] == '.')
809 	{
810 	    /* Use same directory as the ffname,
811 	     * "dir/name" -> "dir/.name.un~" */
812 	    undo_file_name = vim_strnsave(ffname, (int)(STRLEN(ffname) + 5));
813 	    if (undo_file_name == NULL)
814 		break;
815 	    p = gettail(undo_file_name);
816 #ifdef VMS
817 	    /* VMS can not handle more than one dot in the filenames
818 	     * use "dir/name" -> "dir/_un_name" - add _un_
819 	     * at the beginning to keep the extension */
820 	    mch_memmove(p + 4,  p, STRLEN(p) + 1);
821 	    mch_memmove(p, "_un_", 4);
822 
823 #else
824 	    /* Use same directory as the ffname,
825 	     * "dir/name" -> "dir/.name.un~" */
826 	    mch_memmove(p + 1, p, STRLEN(p) + 1);
827 	    *p = '.';
828 	    STRCAT(p, ".un~");
829 #endif
830 	}
831 	else
832 	{
833 	    dir_name[dir_len] = NUL;
834 	    if (mch_isdir(dir_name))
835 	    {
836 		if (munged_name == NULL)
837 		{
838 		    munged_name = vim_strsave(ffname);
839 		    if (munged_name == NULL)
840 			return NULL;
841 		    for (p = munged_name; *p != NUL; mb_ptr_adv(p))
842 			if (vim_ispathsep(*p))
843 			    *p = '%';
844 		}
845 		undo_file_name = concat_fnames(dir_name, munged_name, TRUE);
846 	    }
847 	}
848 
849 	/* When reading check if the file exists. */
850 	if (undo_file_name != NULL && (!reading
851 			       || mch_stat((char *)undo_file_name, &st) >= 0))
852 	    break;
853 	vim_free(undo_file_name);
854 	undo_file_name = NULL;
855     }
856 
857     vim_free(munged_name);
858     return undo_file_name;
859 }
860 
861     static void
862 corruption_error(mesg, file_name)
863     char *mesg;
864     char_u *file_name;
865 {
866     EMSG3(_("E825: Corrupted undo file (%s): %s"), mesg, file_name);
867 }
868 
869     static void
870 u_free_uhp(uhp)
871     u_header_T	*uhp;
872 {
873     u_entry_T	*nuep;
874     u_entry_T	*uep;
875 
876     uep = uhp->uh_entry;
877     while (uep != NULL)
878     {
879 	nuep = uep->ue_next;
880 	u_freeentry(uep, uep->ue_size);
881 	uep = nuep;
882     }
883     vim_free(uhp);
884 }
885 
886 /*
887  * Write a sequence of bytes to the undo file.
888  * Buffers and encrypts as needed.
889  * Returns OK or FAIL.
890  */
891     static int
892 undo_write(bi, ptr, len)
893     bufinfo_T	*bi;
894     char_u	*ptr;
895     size_t	len;
896 {
897 #ifdef FEAT_CRYPT
898     if (bi->bi_buffer != NULL)
899     {
900 	size_t	len_todo = len;
901 	char_u  *p = ptr;
902 
903 	while (bi->bi_used + len_todo >= CRYPT_BUF_SIZE)
904 	{
905 	    size_t	n = CRYPT_BUF_SIZE - bi->bi_used;
906 
907 	    mch_memmove(bi->bi_buffer + bi->bi_used, p, n);
908 	    len_todo -= n;
909 	    p += n;
910 	    bi->bi_used = CRYPT_BUF_SIZE;
911 	    if (undo_flush(bi) == FAIL)
912 		return FAIL;
913 	}
914 	if (len_todo > 0)
915 	{
916 	    mch_memmove(bi->bi_buffer + bi->bi_used, p, len_todo);
917 	    bi->bi_used += len_todo;
918 	}
919 	return OK;
920     }
921 #endif
922     if (fwrite(ptr, len, (size_t)1, bi->bi_fp) != 1)
923 	return FAIL;
924     return OK;
925 }
926 
927 #ifdef FEAT_CRYPT
928     static int
929 undo_flush(bi)
930     bufinfo_T	*bi;
931 {
932     if (bi->bi_buffer != NULL && bi->bi_used > 0)
933     {
934 	crypt_encode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_used);
935 	if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1)
936 	    return FAIL;
937 	bi->bi_used = 0;
938     }
939     return OK;
940 }
941 #endif
942 
943 /*
944  * Write "ptr[len]" and crypt the bytes when needed.
945  * Returns OK or FAIL.
946  */
947     static int
948 fwrite_crypt(bi, ptr, len)
949     bufinfo_T	*bi;
950     char_u	*ptr;
951     size_t	len;
952 {
953 #ifdef FEAT_CRYPT
954     char_u  *copy;
955     char_u  small_buf[100];
956     size_t  i;
957 
958     if (bi->bi_state != NULL && bi->bi_buffer == NULL)
959     {
960 	/* crypting every piece of text separately */
961 	if (len < 100)
962 	    copy = small_buf;  /* no malloc()/free() for short strings */
963 	else
964 	{
965 	    copy = lalloc(len, FALSE);
966 	    if (copy == NULL)
967 		return 0;
968 	}
969 	crypt_encode(bi->bi_state, ptr, len, copy);
970 	i = fwrite(copy, len, (size_t)1, bi->bi_fp);
971 	if (copy != small_buf)
972 	    vim_free(copy);
973 	return i == 1 ? OK : FAIL;
974     }
975 #endif
976     return undo_write(bi, ptr, len);
977 }
978 
979 /*
980  * Write a number, MSB first, in "len" bytes.
981  * Must match with undo_read_?c() functions.
982  * Returns OK or FAIL.
983  */
984     static int
985 undo_write_bytes(bi, nr, len)
986     bufinfo_T *bi;
987     long_u  nr;
988     int	    len;
989 {
990     char_u  buf[8];
991     int	    i;
992     int	    bufi = 0;
993 
994     for (i = len - 1; i >= 0; --i)
995 	buf[bufi++] = (char_u)(nr >> (i * 8));
996     return undo_write(bi, buf, (size_t)len);
997 }
998 
999 /*
1000  * Write the pointer to an undo header.  Instead of writing the pointer itself
1001  * we use the sequence number of the header.  This is converted back to
1002  * pointers when reading. */
1003     static void
1004 put_header_ptr(bi, uhp)
1005     bufinfo_T	*bi;
1006     u_header_T	*uhp;
1007 {
1008     undo_write_bytes(bi, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4);
1009 }
1010 
1011     static int
1012 undo_read_4c(bi)
1013     bufinfo_T	*bi;
1014 {
1015 #ifdef FEAT_CRYPT
1016     if (bi->bi_buffer != NULL)
1017     {
1018 	char_u  buf[4];
1019 	int	n;
1020 
1021 	undo_read(bi, buf, (size_t)4);
1022 	n = ((unsigned)buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
1023 	return n;
1024     }
1025 #endif
1026     return get4c(bi->bi_fp);
1027 }
1028 
1029     static int
1030 undo_read_2c(bi)
1031     bufinfo_T	*bi;
1032 {
1033 #ifdef FEAT_CRYPT
1034     if (bi->bi_buffer != NULL)
1035     {
1036 	char_u  buf[2];
1037 	int	n;
1038 
1039 	undo_read(bi, buf, (size_t)2);
1040 	n = (buf[0] << 8) + buf[1];
1041 	return n;
1042     }
1043 #endif
1044     return get2c(bi->bi_fp);
1045 }
1046 
1047     static int
1048 undo_read_byte(bi)
1049     bufinfo_T	*bi;
1050 {
1051 #ifdef FEAT_CRYPT
1052     if (bi->bi_buffer != NULL)
1053     {
1054 	char_u  buf[1];
1055 
1056 	undo_read(bi, buf, (size_t)1);
1057 	return buf[0];
1058     }
1059 #endif
1060     return getc(bi->bi_fp);
1061 }
1062 
1063     static time_t
1064 undo_read_time(bi)
1065     bufinfo_T	*bi;
1066 {
1067 #ifdef FEAT_CRYPT
1068     if (bi->bi_buffer != NULL)
1069     {
1070 	char_u  buf[8];
1071 	time_t	n = 0;
1072 	int	i;
1073 
1074 	undo_read(bi, buf, (size_t)8);
1075 	for (i = 0; i < 8; ++i)
1076 	    n = (n << 8) + buf[i];
1077 	return n;
1078     }
1079 #endif
1080     return get8ctime(bi->bi_fp);
1081 }
1082 
1083 /*
1084  * Read "buffer[size]" from the undo file.
1085  * Return OK or FAIL.
1086  */
1087     static int
1088 undo_read(bi, buffer, size)
1089     bufinfo_T   *bi;
1090     char_u	*buffer;
1091     size_t	size;
1092 {
1093 #ifdef FEAT_CRYPT
1094     if (bi->bi_buffer != NULL)
1095     {
1096 	int	size_todo = (int)size;
1097 	char_u	*p = buffer;
1098 
1099 	while (size_todo > 0)
1100 	{
1101 	    size_t n;
1102 
1103 	    if (bi->bi_used >= bi->bi_avail)
1104 	    {
1105 		n = fread(bi->bi_buffer, 1, (size_t)CRYPT_BUF_SIZE, bi->bi_fp);
1106 		if (n <= 0)
1107 		{
1108 		    /* Error may be checked for only later.  Fill with zeros,
1109 		     * so that the reader won't use garbage. */
1110 		    vim_memset(p, 0, size_todo);
1111 		    return FAIL;
1112 		}
1113 		bi->bi_avail = n;
1114 		bi->bi_used = 0;
1115 		crypt_decode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_avail);
1116 	    }
1117 	    n = size_todo;
1118 	    if (n > bi->bi_avail - bi->bi_used)
1119 		n = bi->bi_avail - bi->bi_used;
1120 	    mch_memmove(p, bi->bi_buffer + bi->bi_used, n);
1121 	    bi->bi_used += n;
1122 	    size_todo -= (int)n;
1123 	    p += n;
1124 	}
1125 	return OK;
1126     }
1127 #endif
1128     if (fread(buffer, (size_t)size, 1, bi->bi_fp) != 1)
1129 	return FAIL;
1130     return OK;
1131 }
1132 
1133 /*
1134  * Read a string of length "len" from "bi->bi_fd".
1135  * "len" can be zero to allocate an empty line.
1136  * Decrypt the bytes if needed.
1137  * Append a NUL.
1138  * Returns a pointer to allocated memory or NULL for failure.
1139  */
1140     static char_u *
1141 read_string_decrypt(bi, len)
1142     bufinfo_T	*bi;
1143     int		len;
1144 {
1145     char_u  *ptr = alloc((unsigned)len + 1);
1146 
1147     if (ptr != NULL)
1148     {
1149 	if (len > 0 && undo_read(bi, ptr, len) == FAIL)
1150 	{
1151 	    vim_free(ptr);
1152 	    return NULL;
1153 	}
1154 	ptr[len] = NUL;
1155 #ifdef FEAT_CRYPT
1156 	if (bi->bi_state != NULL && bi->bi_buffer == NULL)
1157 	    crypt_decode_inplace(bi->bi_state, ptr, len);
1158 #endif
1159     }
1160     return ptr;
1161 }
1162 
1163 /*
1164  * Writes the (not encrypted) header and initializes encryption if needed.
1165  */
1166     static int
1167 serialize_header(bi, hash)
1168     bufinfo_T	*bi;
1169     char_u	*hash;
1170 {
1171     int		len;
1172     buf_T	*buf = bi->bi_buf;
1173     FILE	*fp = bi->bi_fp;
1174     char_u	time_buf[8];
1175 
1176     /* Start writing, first the magic marker and undo info version. */
1177     if (fwrite(UF_START_MAGIC, (size_t)UF_START_MAGIC_LEN, (size_t)1, fp) != 1)
1178 	return FAIL;
1179 
1180     /* If the buffer is encrypted then all text bytes following will be
1181      * encrypted.  Numbers and other info is not crypted. */
1182 #ifdef FEAT_CRYPT
1183     if (*buf->b_p_key != NUL)
1184     {
1185 	char_u *header;
1186 	int    header_len;
1187 
1188 	undo_write_bytes(bi, (long_u)UF_VERSION_CRYPT, 2);
1189 	bi->bi_state = crypt_create_for_writing(crypt_get_method_nr(buf),
1190 					  buf->b_p_key, &header, &header_len);
1191 	if (bi->bi_state == NULL)
1192 	    return FAIL;
1193 	len = (int)fwrite(header, (size_t)header_len, (size_t)1, fp);
1194 	vim_free(header);
1195 	if (len != 1)
1196 	{
1197 	    crypt_free_state(bi->bi_state);
1198 	    bi->bi_state = NULL;
1199 	    return FAIL;
1200 	}
1201 
1202 	if (crypt_whole_undofile(crypt_get_method_nr(buf)))
1203 	{
1204 	    bi->bi_buffer = alloc(CRYPT_BUF_SIZE);
1205 	    if (bi->bi_buffer == NULL)
1206 	    {
1207 		crypt_free_state(bi->bi_state);
1208 		bi->bi_state = NULL;
1209 		return FAIL;
1210 	    }
1211 	    bi->bi_used = 0;
1212 	}
1213     }
1214     else
1215 #endif
1216 	undo_write_bytes(bi, (long_u)UF_VERSION, 2);
1217 
1218 
1219     /* Write a hash of the buffer text, so that we can verify it is still the
1220      * same when reading the buffer text. */
1221     if (undo_write(bi, hash, (size_t)UNDO_HASH_SIZE) == FAIL)
1222 	return FAIL;
1223 
1224     /* buffer-specific data */
1225     undo_write_bytes(bi, (long_u)buf->b_ml.ml_line_count, 4);
1226     len = buf->b_u_line_ptr != NULL ? (int)STRLEN(buf->b_u_line_ptr) : 0;
1227     undo_write_bytes(bi, (long_u)len, 4);
1228     if (len > 0 && fwrite_crypt(bi, buf->b_u_line_ptr, (size_t)len) == FAIL)
1229 	return FAIL;
1230     undo_write_bytes(bi, (long_u)buf->b_u_line_lnum, 4);
1231     undo_write_bytes(bi, (long_u)buf->b_u_line_colnr, 4);
1232 
1233     /* Undo structures header data */
1234     put_header_ptr(bi, buf->b_u_oldhead);
1235     put_header_ptr(bi, buf->b_u_newhead);
1236     put_header_ptr(bi, buf->b_u_curhead);
1237 
1238     undo_write_bytes(bi, (long_u)buf->b_u_numhead, 4);
1239     undo_write_bytes(bi, (long_u)buf->b_u_seq_last, 4);
1240     undo_write_bytes(bi, (long_u)buf->b_u_seq_cur, 4);
1241     time_to_bytes(buf->b_u_time_cur, time_buf);
1242     undo_write(bi, time_buf, 8);
1243 
1244     /* Optional fields. */
1245     undo_write_bytes(bi, 4, 1);
1246     undo_write_bytes(bi, UF_LAST_SAVE_NR, 1);
1247     undo_write_bytes(bi, (long_u)buf->b_u_save_nr_last, 4);
1248 
1249     undo_write_bytes(bi, 0, 1);  /* end marker */
1250 
1251     return OK;
1252 }
1253 
1254     static int
1255 serialize_uhp(bi, uhp)
1256     bufinfo_T	*bi;
1257     u_header_T	*uhp;
1258 {
1259     int		i;
1260     u_entry_T	*uep;
1261     char_u	time_buf[8];
1262 
1263     if (undo_write_bytes(bi, (long_u)UF_HEADER_MAGIC, 2) == FAIL)
1264 	return FAIL;
1265 
1266     put_header_ptr(bi, uhp->uh_next.ptr);
1267     put_header_ptr(bi, uhp->uh_prev.ptr);
1268     put_header_ptr(bi, uhp->uh_alt_next.ptr);
1269     put_header_ptr(bi, uhp->uh_alt_prev.ptr);
1270     undo_write_bytes(bi, uhp->uh_seq, 4);
1271     serialize_pos(bi, uhp->uh_cursor);
1272 #ifdef FEAT_VIRTUALEDIT
1273     undo_write_bytes(bi, (long_u)uhp->uh_cursor_vcol, 4);
1274 #else
1275     undo_write_bytes(bi, (long_u)0, 4);
1276 #endif
1277     undo_write_bytes(bi, (long_u)uhp->uh_flags, 2);
1278     /* Assume NMARKS will stay the same. */
1279     for (i = 0; i < NMARKS; ++i)
1280 	serialize_pos(bi, uhp->uh_namedm[i]);
1281     serialize_visualinfo(bi, &uhp->uh_visual);
1282     time_to_bytes(uhp->uh_time, time_buf);
1283     undo_write(bi, time_buf, 8);
1284 
1285     /* Optional fields. */
1286     undo_write_bytes(bi, 4, 1);
1287     undo_write_bytes(bi, UHP_SAVE_NR, 1);
1288     undo_write_bytes(bi, (long_u)uhp->uh_save_nr, 4);
1289 
1290     undo_write_bytes(bi, 0, 1);  /* end marker */
1291 
1292     /* Write all the entries. */
1293     for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
1294     {
1295 	undo_write_bytes(bi, (long_u)UF_ENTRY_MAGIC, 2);
1296 	if (serialize_uep(bi, uep) == FAIL)
1297 	    return FAIL;
1298     }
1299     undo_write_bytes(bi, (long_u)UF_ENTRY_END_MAGIC, 2);
1300     return OK;
1301 }
1302 
1303     static u_header_T *
1304 unserialize_uhp(bi, file_name)
1305     bufinfo_T	*bi;
1306     char_u	*file_name;
1307 {
1308     u_header_T	*uhp;
1309     int		i;
1310     u_entry_T	*uep, *last_uep;
1311     int		c;
1312     int		error;
1313 
1314     uhp = (u_header_T *)U_ALLOC_LINE(sizeof(u_header_T));
1315     if (uhp == NULL)
1316 	return NULL;
1317     vim_memset(uhp, 0, sizeof(u_header_T));
1318 #ifdef U_DEBUG
1319     uhp->uh_magic = UH_MAGIC;
1320 #endif
1321     uhp->uh_next.seq = undo_read_4c(bi);
1322     uhp->uh_prev.seq = undo_read_4c(bi);
1323     uhp->uh_alt_next.seq = undo_read_4c(bi);
1324     uhp->uh_alt_prev.seq = undo_read_4c(bi);
1325     uhp->uh_seq = undo_read_4c(bi);
1326     if (uhp->uh_seq <= 0)
1327     {
1328 	corruption_error("uh_seq", file_name);
1329 	vim_free(uhp);
1330 	return NULL;
1331     }
1332     unserialize_pos(bi, &uhp->uh_cursor);
1333 #ifdef FEAT_VIRTUALEDIT
1334     uhp->uh_cursor_vcol = undo_read_4c(bi);
1335 #else
1336     (void)undo_read_4c(bi);
1337 #endif
1338     uhp->uh_flags = undo_read_2c(bi);
1339     for (i = 0; i < NMARKS; ++i)
1340 	unserialize_pos(bi, &uhp->uh_namedm[i]);
1341     unserialize_visualinfo(bi, &uhp->uh_visual);
1342     uhp->uh_time = undo_read_time(bi);
1343 
1344     /* Optional fields. */
1345     for (;;)
1346     {
1347 	int len = undo_read_byte(bi);
1348 	int what;
1349 
1350 	if (len == 0)
1351 	    break;
1352 	what = undo_read_byte(bi);
1353 	switch (what)
1354 	{
1355 	    case UHP_SAVE_NR:
1356 		uhp->uh_save_nr = undo_read_4c(bi);
1357 		break;
1358 	    default:
1359 		/* field not supported, skip */
1360 		while (--len >= 0)
1361 		    (void)undo_read_byte(bi);
1362 	}
1363     }
1364 
1365     /* Unserialize the uep list. */
1366     last_uep = NULL;
1367     while ((c = undo_read_2c(bi)) == UF_ENTRY_MAGIC)
1368     {
1369 	error = FALSE;
1370 	uep = unserialize_uep(bi, &error, file_name);
1371 	if (last_uep == NULL)
1372 	    uhp->uh_entry = uep;
1373 	else
1374 	    last_uep->ue_next = uep;
1375 	last_uep = uep;
1376 	if (uep == NULL || error)
1377 	{
1378 	    u_free_uhp(uhp);
1379 	    return NULL;
1380 	}
1381     }
1382     if (c != UF_ENTRY_END_MAGIC)
1383     {
1384 	corruption_error("entry end", file_name);
1385 	u_free_uhp(uhp);
1386 	return NULL;
1387     }
1388 
1389     return uhp;
1390 }
1391 
1392 /*
1393  * Serialize "uep".
1394  */
1395     static int
1396 serialize_uep(bi, uep)
1397     bufinfo_T	*bi;
1398     u_entry_T	*uep;
1399 {
1400     int		i;
1401     size_t	len;
1402 
1403     undo_write_bytes(bi, (long_u)uep->ue_top, 4);
1404     undo_write_bytes(bi, (long_u)uep->ue_bot, 4);
1405     undo_write_bytes(bi, (long_u)uep->ue_lcount, 4);
1406     undo_write_bytes(bi, (long_u)uep->ue_size, 4);
1407     for (i = 0; i < uep->ue_size; ++i)
1408     {
1409 	len = STRLEN(uep->ue_array[i]);
1410 	if (undo_write_bytes(bi, (long_u)len, 4) == FAIL)
1411 	    return FAIL;
1412 	if (len > 0 && fwrite_crypt(bi, uep->ue_array[i], len) == FAIL)
1413 	    return FAIL;
1414     }
1415     return OK;
1416 }
1417 
1418     static u_entry_T *
1419 unserialize_uep(bi, error, file_name)
1420     bufinfo_T	*bi;
1421     int		*error;
1422     char_u	*file_name;
1423 {
1424     int		i;
1425     u_entry_T	*uep;
1426     char_u	**array;
1427     char_u	*line;
1428     int		line_len;
1429 
1430     uep = (u_entry_T *)U_ALLOC_LINE(sizeof(u_entry_T));
1431     if (uep == NULL)
1432 	return NULL;
1433     vim_memset(uep, 0, sizeof(u_entry_T));
1434 #ifdef U_DEBUG
1435     uep->ue_magic = UE_MAGIC;
1436 #endif
1437     uep->ue_top = undo_read_4c(bi);
1438     uep->ue_bot = undo_read_4c(bi);
1439     uep->ue_lcount = undo_read_4c(bi);
1440     uep->ue_size = undo_read_4c(bi);
1441     if (uep->ue_size > 0)
1442     {
1443 	array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
1444 	if (array == NULL)
1445 	{
1446 	    *error = TRUE;
1447 	    return uep;
1448 	}
1449 	vim_memset(array, 0, sizeof(char_u *) * uep->ue_size);
1450     }
1451     else
1452 	array = NULL;
1453     uep->ue_array = array;
1454 
1455     for (i = 0; i < uep->ue_size; ++i)
1456     {
1457 	line_len = undo_read_4c(bi);
1458 	if (line_len >= 0)
1459 	    line = read_string_decrypt(bi, line_len);
1460 	else
1461 	{
1462 	    line = NULL;
1463 	    corruption_error("line length", file_name);
1464 	}
1465 	if (line == NULL)
1466 	{
1467 	    *error = TRUE;
1468 	    return uep;
1469 	}
1470 	array[i] = line;
1471     }
1472     return uep;
1473 }
1474 
1475 /*
1476  * Serialize "pos".
1477  */
1478     static void
1479 serialize_pos(bi, pos)
1480     bufinfo_T *bi;
1481     pos_T pos;
1482 {
1483     undo_write_bytes(bi, (long_u)pos.lnum, 4);
1484     undo_write_bytes(bi, (long_u)pos.col, 4);
1485 #ifdef FEAT_VIRTUALEDIT
1486     undo_write_bytes(bi, (long_u)pos.coladd, 4);
1487 #else
1488     undo_write_bytes(bi, (long_u)0, 4);
1489 #endif
1490 }
1491 
1492 /*
1493  * Unserialize the pos_T at the current position.
1494  */
1495     static void
1496 unserialize_pos(bi, pos)
1497     bufinfo_T *bi;
1498     pos_T *pos;
1499 {
1500     pos->lnum = undo_read_4c(bi);
1501     if (pos->lnum < 0)
1502 	pos->lnum = 0;
1503     pos->col = undo_read_4c(bi);
1504     if (pos->col < 0)
1505 	pos->col = 0;
1506 #ifdef FEAT_VIRTUALEDIT
1507     pos->coladd = undo_read_4c(bi);
1508     if (pos->coladd < 0)
1509 	pos->coladd = 0;
1510 #else
1511     (void)undo_read_4c(bi);
1512 #endif
1513 }
1514 
1515 /*
1516  * Serialize "info".
1517  */
1518     static void
1519 serialize_visualinfo(bi, info)
1520     bufinfo_T	    *bi;
1521     visualinfo_T    *info;
1522 {
1523     serialize_pos(bi, info->vi_start);
1524     serialize_pos(bi, info->vi_end);
1525     undo_write_bytes(bi, (long_u)info->vi_mode, 4);
1526     undo_write_bytes(bi, (long_u)info->vi_curswant, 4);
1527 }
1528 
1529 /*
1530  * Unserialize the visualinfo_T at the current position.
1531  */
1532     static void
1533 unserialize_visualinfo(bi, info)
1534     bufinfo_T	    *bi;
1535     visualinfo_T    *info;
1536 {
1537     unserialize_pos(bi, &info->vi_start);
1538     unserialize_pos(bi, &info->vi_end);
1539     info->vi_mode = undo_read_4c(bi);
1540     info->vi_curswant = undo_read_4c(bi);
1541 }
1542 
1543 /*
1544  * Write the undo tree in an undo file.
1545  * When "name" is not NULL, use it as the name of the undo file.
1546  * Otherwise use buf->b_ffname to generate the undo file name.
1547  * "buf" must never be null, buf->b_ffname is used to obtain the original file
1548  * permissions.
1549  * "forceit" is TRUE for ":wundo!", FALSE otherwise.
1550  * "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text.
1551  */
1552     void
1553 u_write_undo(name, forceit, buf, hash)
1554     char_u	*name;
1555     int		forceit;
1556     buf_T	*buf;
1557     char_u	*hash;
1558 {
1559     u_header_T	*uhp;
1560     char_u	*file_name;
1561     int		mark;
1562 #ifdef U_DEBUG
1563     int		headers_written = 0;
1564 #endif
1565     int		fd;
1566     FILE	*fp = NULL;
1567     int		perm;
1568     int		write_ok = FALSE;
1569 #ifdef UNIX
1570     int		st_old_valid = FALSE;
1571     struct stat	st_old;
1572     struct stat	st_new;
1573 #endif
1574     bufinfo_T	bi;
1575 
1576     vim_memset(&bi, 0, sizeof(bi));
1577 
1578     if (name == NULL)
1579     {
1580 	file_name = u_get_undo_file_name(buf->b_ffname, FALSE);
1581 	if (file_name == NULL)
1582 	{
1583 	    if (p_verbose > 0)
1584 	    {
1585 		verbose_enter();
1586 		smsg((char_u *)
1587 		   _("Cannot write undo file in any directory in 'undodir'"));
1588 		verbose_leave();
1589 	    }
1590 	    return;
1591 	}
1592     }
1593     else
1594 	file_name = name;
1595 
1596     /*
1597      * Decide about the permission to use for the undo file.  If the buffer
1598      * has a name use the permission of the original file.  Otherwise only
1599      * allow the user to access the undo file.
1600      */
1601     perm = 0600;
1602     if (buf->b_ffname != NULL)
1603     {
1604 #ifdef UNIX
1605 	if (mch_stat((char *)buf->b_ffname, &st_old) >= 0)
1606 	{
1607 	    perm = st_old.st_mode;
1608 	    st_old_valid = TRUE;
1609 	}
1610 #else
1611 	perm = mch_getperm(buf->b_ffname);
1612 	if (perm < 0)
1613 	    perm = 0600;
1614 #endif
1615     }
1616 
1617     /* strip any s-bit and executable bit */
1618     perm = perm & 0666;
1619 
1620     /* If the undo file already exists, verify that it actually is an undo
1621      * file, and delete it. */
1622     if (mch_getperm(file_name) >= 0)
1623     {
1624 	if (name == NULL || !forceit)
1625 	{
1626 	    /* Check we can read it and it's an undo file. */
1627 	    fd = mch_open((char *)file_name, O_RDONLY|O_EXTRA, 0);
1628 	    if (fd < 0)
1629 	    {
1630 		if (name != NULL || p_verbose > 0)
1631 		{
1632 		    if (name == NULL)
1633 			verbose_enter();
1634 		    smsg((char_u *)
1635 		      _("Will not overwrite with undo file, cannot read: %s"),
1636 								   file_name);
1637 		    if (name == NULL)
1638 			verbose_leave();
1639 		}
1640 		goto theend;
1641 	    }
1642 	    else
1643 	    {
1644 		char_u	mbuf[UF_START_MAGIC_LEN];
1645 		int	len;
1646 
1647 		len = read_eintr(fd, mbuf, UF_START_MAGIC_LEN);
1648 		close(fd);
1649 		if (len < UF_START_MAGIC_LEN
1650 		      || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0)
1651 		{
1652 		    if (name != NULL || p_verbose > 0)
1653 		    {
1654 			if (name == NULL)
1655 			    verbose_enter();
1656 			smsg((char_u *)
1657 			_("Will not overwrite, this is not an undo file: %s"),
1658 								   file_name);
1659 			if (name == NULL)
1660 			    verbose_leave();
1661 		    }
1662 		    goto theend;
1663 		}
1664 	    }
1665 	}
1666 	mch_remove(file_name);
1667     }
1668 
1669     /* If there is no undo information at all, quit here after deleting any
1670      * existing undo file. */
1671     if (buf->b_u_numhead == 0 && buf->b_u_line_ptr == NULL)
1672     {
1673 	if (p_verbose > 0)
1674 	    verb_msg((char_u *)_("Skipping undo file write, nothing to undo"));
1675 	goto theend;
1676     }
1677 
1678     fd = mch_open((char *)file_name,
1679 			    O_CREAT|O_EXTRA|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);
1680     if (fd < 0)
1681     {
1682 	EMSG2(_(e_not_open), file_name);
1683 	goto theend;
1684     }
1685     (void)mch_setperm(file_name, perm);
1686     if (p_verbose > 0)
1687     {
1688 	verbose_enter();
1689 	smsg((char_u *)_("Writing undo file: %s"), file_name);
1690 	verbose_leave();
1691     }
1692 
1693 #ifdef U_DEBUG
1694     /* Check there is no problem in undo info before writing. */
1695     u_check(FALSE);
1696 #endif
1697 
1698 #ifdef UNIX
1699     /*
1700      * Try to set the group of the undo file same as the original file. If
1701      * this fails, set the protection bits for the group same as the
1702      * protection bits for others.
1703      */
1704     if (st_old_valid
1705 	    && mch_stat((char *)file_name, &st_new) >= 0
1706 	    && st_new.st_gid != st_old.st_gid
1707 # ifdef HAVE_FCHOWN  /* sequent-ptx lacks fchown() */
1708 	    && fchown(fd, (uid_t)-1, st_old.st_gid) != 0
1709 # endif
1710        )
1711 	mch_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
1712 # if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
1713     if (buf->b_ffname != NULL)
1714 	mch_copy_sec(buf->b_ffname, file_name);
1715 # endif
1716 #endif
1717 
1718     fp = fdopen(fd, "w");
1719     if (fp == NULL)
1720     {
1721 	EMSG2(_(e_not_open), file_name);
1722 	close(fd);
1723 	mch_remove(file_name);
1724 	goto theend;
1725     }
1726 
1727     /* Undo must be synced. */
1728     u_sync(TRUE);
1729 
1730     /*
1731      * Write the header.  Initializes encryption, if enabled.
1732      */
1733     bi.bi_buf = buf;
1734     bi.bi_fp = fp;
1735     if (serialize_header(&bi, hash) == FAIL)
1736 	goto write_error;
1737 
1738     /*
1739      * Iteratively serialize UHPs and their UEPs from the top down.
1740      */
1741     mark = ++lastmark;
1742     uhp = buf->b_u_oldhead;
1743     while (uhp != NULL)
1744     {
1745 	/* Serialize current UHP if we haven't seen it */
1746 	if (uhp->uh_walk != mark)
1747 	{
1748 	    uhp->uh_walk = mark;
1749 #ifdef U_DEBUG
1750 	    ++headers_written;
1751 #endif
1752 	    if (serialize_uhp(&bi, uhp) == FAIL)
1753 		goto write_error;
1754 	}
1755 
1756 	/* Now walk through the tree - algorithm from undo_time(). */
1757 	if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark)
1758 	    uhp = uhp->uh_prev.ptr;
1759 	else if (uhp->uh_alt_next.ptr != NULL
1760 				     && uhp->uh_alt_next.ptr->uh_walk != mark)
1761 	    uhp = uhp->uh_alt_next.ptr;
1762 	else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
1763 					 && uhp->uh_next.ptr->uh_walk != mark)
1764 	    uhp = uhp->uh_next.ptr;
1765 	else if (uhp->uh_alt_prev.ptr != NULL)
1766 	    uhp = uhp->uh_alt_prev.ptr;
1767 	else
1768 	    uhp = uhp->uh_next.ptr;
1769     }
1770 
1771     if (undo_write_bytes(&bi, (long_u)UF_HEADER_END_MAGIC, 2) == OK)
1772 	write_ok = TRUE;
1773 #ifdef U_DEBUG
1774     if (headers_written != buf->b_u_numhead)
1775     {
1776 	EMSGN("Written %ld headers, ...", headers_written);
1777 	EMSGN("... but numhead is %ld", buf->b_u_numhead);
1778     }
1779 #endif
1780 
1781 #ifdef FEAT_CRYPT
1782     if (bi.bi_state != NULL && undo_flush(&bi) == FAIL)
1783 	write_ok = FALSE;
1784 #endif
1785 
1786 write_error:
1787     fclose(fp);
1788     if (!write_ok)
1789 	EMSG2(_("E829: write error in undo file: %s"), file_name);
1790 
1791 #if defined(MACOS_CLASSIC) || defined(WIN3264)
1792     /* Copy file attributes; for systems where this can only be done after
1793      * closing the file. */
1794     if (buf->b_ffname != NULL)
1795 	(void)mch_copy_file_attribute(buf->b_ffname, file_name);
1796 #endif
1797 #ifdef HAVE_ACL
1798     if (buf->b_ffname != NULL)
1799     {
1800 	vim_acl_T	    acl;
1801 
1802 	/* For systems that support ACL: get the ACL from the original file. */
1803 	acl = mch_get_acl(buf->b_ffname);
1804 	mch_set_acl(file_name, acl);
1805 	mch_free_acl(acl);
1806     }
1807 #endif
1808 
1809 theend:
1810 #ifdef FEAT_CRYPT
1811     if (bi.bi_state != NULL)
1812 	crypt_free_state(bi.bi_state);
1813     vim_free(bi.bi_buffer);
1814 #endif
1815     if (file_name != name)
1816 	vim_free(file_name);
1817 }
1818 
1819 /*
1820  * Load the undo tree from an undo file.
1821  * If "name" is not NULL use it as the undo file name.  This also means being
1822  * a bit more verbose.
1823  * Otherwise use curbuf->b_ffname to generate the undo file name.
1824  * "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text.
1825  */
1826     void
1827 u_read_undo(name, hash, orig_name)
1828     char_u *name;
1829     char_u *hash;
1830     char_u *orig_name;
1831 {
1832     char_u	*file_name;
1833     FILE	*fp;
1834     long	version, str_len;
1835     char_u	*line_ptr = NULL;
1836     linenr_T	line_lnum;
1837     colnr_T	line_colnr;
1838     linenr_T	line_count;
1839     int		num_head = 0;
1840     long	old_header_seq, new_header_seq, cur_header_seq;
1841     long	seq_last, seq_cur;
1842     long	last_save_nr = 0;
1843     short	old_idx = -1, new_idx = -1, cur_idx = -1;
1844     long	num_read_uhps = 0;
1845     time_t	seq_time;
1846     int		i, j;
1847     int		c;
1848     u_header_T	*uhp;
1849     u_header_T	**uhp_table = NULL;
1850     char_u	read_hash[UNDO_HASH_SIZE];
1851     char_u	magic_buf[UF_START_MAGIC_LEN];
1852 #ifdef U_DEBUG
1853     int		*uhp_table_used;
1854 #endif
1855 #ifdef UNIX
1856     struct stat	st_orig;
1857     struct stat	st_undo;
1858 #endif
1859     bufinfo_T	bi;
1860 
1861     vim_memset(&bi, 0, sizeof(bi));
1862     if (name == NULL)
1863     {
1864 	file_name = u_get_undo_file_name(curbuf->b_ffname, TRUE);
1865 	if (file_name == NULL)
1866 	    return;
1867 
1868 #ifdef UNIX
1869 	/* For safety we only read an undo file if the owner is equal to the
1870 	 * owner of the text file or equal to the current user. */
1871 	if (mch_stat((char *)orig_name, &st_orig) >= 0
1872 		&& mch_stat((char *)file_name, &st_undo) >= 0
1873 		&& st_orig.st_uid != st_undo.st_uid
1874 		&& st_undo.st_uid != getuid())
1875 	{
1876 	    if (p_verbose > 0)
1877 	    {
1878 		verbose_enter();
1879 		smsg((char_u *)_("Not reading undo file, owner differs: %s"),
1880 								   file_name);
1881 		verbose_leave();
1882 	    }
1883 	    return;
1884 	}
1885 #endif
1886     }
1887     else
1888 	file_name = name;
1889 
1890     if (p_verbose > 0)
1891     {
1892 	verbose_enter();
1893 	smsg((char_u *)_("Reading undo file: %s"), file_name);
1894 	verbose_leave();
1895     }
1896 
1897     fp = mch_fopen((char *)file_name, "r");
1898     if (fp == NULL)
1899     {
1900 	if (name != NULL || p_verbose > 0)
1901 	    EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name);
1902 	goto error;
1903     }
1904     bi.bi_buf = curbuf;
1905     bi.bi_fp = fp;
1906 
1907     /*
1908      * Read the undo file header.
1909      */
1910     if (fread(magic_buf, UF_START_MAGIC_LEN, 1, fp) != 1
1911 		|| memcmp(magic_buf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0)
1912     {
1913 	EMSG2(_("E823: Not an undo file: %s"), file_name);
1914 	goto error;
1915     }
1916     version = get2c(fp);
1917     if (version == UF_VERSION_CRYPT)
1918     {
1919 #ifdef FEAT_CRYPT
1920 	if (*curbuf->b_p_key == NUL)
1921 	{
1922 	    EMSG2(_("E832: Non-encrypted file has encrypted undo file: %s"),
1923 								   file_name);
1924 	    goto error;
1925 	}
1926 	bi.bi_state = crypt_create_from_file(fp, curbuf->b_p_key);
1927 	if (bi.bi_state == NULL)
1928 	{
1929 	    EMSG2(_("E826: Undo file decryption failed: %s"), file_name);
1930 	    goto error;
1931 	}
1932 	if (crypt_whole_undofile(bi.bi_state->method_nr))
1933 	{
1934 	    bi.bi_buffer = alloc(CRYPT_BUF_SIZE);
1935 	    if (bi.bi_buffer == NULL)
1936 	    {
1937 		crypt_free_state(bi.bi_state);
1938 		bi.bi_state = NULL;
1939 		goto error;
1940 	    }
1941 	    bi.bi_avail = 0;
1942 	    bi.bi_used = 0;
1943 	}
1944 #else
1945 	EMSG2(_("E827: Undo file is encrypted: %s"), file_name);
1946 	goto error;
1947 #endif
1948     }
1949     else if (version != UF_VERSION)
1950     {
1951 	EMSG2(_("E824: Incompatible undo file: %s"), file_name);
1952 	goto error;
1953     }
1954 
1955     if (undo_read(&bi, read_hash, (size_t)UNDO_HASH_SIZE) == FAIL)
1956     {
1957 	corruption_error("hash", file_name);
1958 	goto error;
1959     }
1960     line_count = (linenr_T)undo_read_4c(&bi);
1961     if (memcmp(hash, read_hash, UNDO_HASH_SIZE) != 0
1962 				  || line_count != curbuf->b_ml.ml_line_count)
1963     {
1964 	if (p_verbose > 0 || name != NULL)
1965 	{
1966 	    if (name == NULL)
1967 		verbose_enter();
1968 	    give_warning((char_u *)
1969 		      _("File contents changed, cannot use undo info"), TRUE);
1970 	    if (name == NULL)
1971 		verbose_leave();
1972 	}
1973 	goto error;
1974     }
1975 
1976     /* Read undo data for "U" command. */
1977     str_len = undo_read_4c(&bi);
1978     if (str_len < 0)
1979 	goto error;
1980     if (str_len > 0)
1981 	line_ptr = read_string_decrypt(&bi, str_len);
1982     line_lnum = (linenr_T)undo_read_4c(&bi);
1983     line_colnr = (colnr_T)undo_read_4c(&bi);
1984     if (line_lnum < 0 || line_colnr < 0)
1985     {
1986 	corruption_error("line lnum/col", file_name);
1987 	goto error;
1988     }
1989 
1990     /* Begin general undo data */
1991     old_header_seq = undo_read_4c(&bi);
1992     new_header_seq = undo_read_4c(&bi);
1993     cur_header_seq = undo_read_4c(&bi);
1994     num_head = undo_read_4c(&bi);
1995     seq_last = undo_read_4c(&bi);
1996     seq_cur = undo_read_4c(&bi);
1997     seq_time = undo_read_time(&bi);
1998 
1999     /* Optional header fields. */
2000     for (;;)
2001     {
2002 	int len = undo_read_byte(&bi);
2003 	int what;
2004 
2005 	if (len == 0 || len == EOF)
2006 	    break;
2007 	what = undo_read_byte(&bi);
2008 	switch (what)
2009 	{
2010 	    case UF_LAST_SAVE_NR:
2011 		last_save_nr = undo_read_4c(&bi);
2012 		break;
2013 	    default:
2014 		/* field not supported, skip */
2015 		while (--len >= 0)
2016 		    (void)undo_read_byte(&bi);
2017 	}
2018     }
2019 
2020     /* uhp_table will store the freshly created undo headers we allocate
2021      * until we insert them into curbuf. The table remains sorted by the
2022      * sequence numbers of the headers.
2023      * When there are no headers uhp_table is NULL. */
2024     if (num_head > 0)
2025     {
2026 	uhp_table = (u_header_T **)U_ALLOC_LINE(
2027 					     num_head * sizeof(u_header_T *));
2028 	if (uhp_table == NULL)
2029 	    goto error;
2030     }
2031 
2032     while ((c = undo_read_2c(&bi)) == UF_HEADER_MAGIC)
2033     {
2034 	if (num_read_uhps >= num_head)
2035 	{
2036 	    corruption_error("num_head too small", file_name);
2037 	    goto error;
2038 	}
2039 
2040 	uhp = unserialize_uhp(&bi, file_name);
2041 	if (uhp == NULL)
2042 	    goto error;
2043 	uhp_table[num_read_uhps++] = uhp;
2044     }
2045 
2046     if (num_read_uhps != num_head)
2047     {
2048 	corruption_error("num_head", file_name);
2049 	goto error;
2050     }
2051     if (c != UF_HEADER_END_MAGIC)
2052     {
2053 	corruption_error("end marker", file_name);
2054 	goto error;
2055     }
2056 
2057 #ifdef U_DEBUG
2058     uhp_table_used = (int *)alloc_clear(
2059 				     (unsigned)(sizeof(int) * num_head + 1));
2060 # define SET_FLAG(j) ++uhp_table_used[j]
2061 #else
2062 # define SET_FLAG(j)
2063 #endif
2064 
2065     /* We have put all of the headers into a table. Now we iterate through the
2066      * table and swizzle each sequence number we have stored in uh_*_seq into
2067      * a pointer corresponding to the header with that sequence number. */
2068     for (i = 0; i < num_head; i++)
2069     {
2070 	uhp = uhp_table[i];
2071 	if (uhp == NULL)
2072 	    continue;
2073 	for (j = 0; j < num_head; j++)
2074 	    if (uhp_table[j] != NULL && i != j
2075 			      && uhp_table[i]->uh_seq == uhp_table[j]->uh_seq)
2076 	    {
2077 		corruption_error("duplicate uh_seq", file_name);
2078 		goto error;
2079 	    }
2080 	for (j = 0; j < num_head; j++)
2081 	    if (uhp_table[j] != NULL
2082 				  && uhp_table[j]->uh_seq == uhp->uh_next.seq)
2083 	    {
2084 		uhp->uh_next.ptr = uhp_table[j];
2085 		SET_FLAG(j);
2086 		break;
2087 	    }
2088 	for (j = 0; j < num_head; j++)
2089 	    if (uhp_table[j] != NULL
2090 				  && uhp_table[j]->uh_seq == uhp->uh_prev.seq)
2091 	    {
2092 		uhp->uh_prev.ptr = uhp_table[j];
2093 		SET_FLAG(j);
2094 		break;
2095 	    }
2096 	for (j = 0; j < num_head; j++)
2097 	    if (uhp_table[j] != NULL
2098 			      && uhp_table[j]->uh_seq == uhp->uh_alt_next.seq)
2099 	    {
2100 		uhp->uh_alt_next.ptr = uhp_table[j];
2101 		SET_FLAG(j);
2102 		break;
2103 	    }
2104 	for (j = 0; j < num_head; j++)
2105 	    if (uhp_table[j] != NULL
2106 			      && uhp_table[j]->uh_seq == uhp->uh_alt_prev.seq)
2107 	    {
2108 		uhp->uh_alt_prev.ptr = uhp_table[j];
2109 		SET_FLAG(j);
2110 		break;
2111 	    }
2112 	if (old_header_seq > 0 && old_idx < 0 && uhp->uh_seq == old_header_seq)
2113 	{
2114 	    old_idx = i;
2115 	    SET_FLAG(i);
2116 	}
2117 	if (new_header_seq > 0 && new_idx < 0 && uhp->uh_seq == new_header_seq)
2118 	{
2119 	    new_idx = i;
2120 	    SET_FLAG(i);
2121 	}
2122 	if (cur_header_seq > 0 && cur_idx < 0 && uhp->uh_seq == cur_header_seq)
2123 	{
2124 	    cur_idx = i;
2125 	    SET_FLAG(i);
2126 	}
2127     }
2128 
2129     /* Now that we have read the undo info successfully, free the current undo
2130      * info and use the info from the file. */
2131     u_blockfree(curbuf);
2132     curbuf->b_u_oldhead = old_idx < 0 ? NULL : uhp_table[old_idx];
2133     curbuf->b_u_newhead = new_idx < 0 ? NULL : uhp_table[new_idx];
2134     curbuf->b_u_curhead = cur_idx < 0 ? NULL : uhp_table[cur_idx];
2135     curbuf->b_u_line_ptr = line_ptr;
2136     curbuf->b_u_line_lnum = line_lnum;
2137     curbuf->b_u_line_colnr = line_colnr;
2138     curbuf->b_u_numhead = num_head;
2139     curbuf->b_u_seq_last = seq_last;
2140     curbuf->b_u_seq_cur = seq_cur;
2141     curbuf->b_u_time_cur = seq_time;
2142     curbuf->b_u_save_nr_last = last_save_nr;
2143     curbuf->b_u_save_nr_cur = last_save_nr;
2144 
2145     curbuf->b_u_synced = TRUE;
2146     vim_free(uhp_table);
2147 
2148 #ifdef U_DEBUG
2149     for (i = 0; i < num_head; ++i)
2150 	if (uhp_table_used[i] == 0)
2151 	    EMSGN("uhp_table entry %ld not used, leaking memory", i);
2152     vim_free(uhp_table_used);
2153     u_check(TRUE);
2154 #endif
2155 
2156     if (name != NULL)
2157 	smsg((char_u *)_("Finished reading undo file %s"), file_name);
2158     goto theend;
2159 
2160 error:
2161     vim_free(line_ptr);
2162     if (uhp_table != NULL)
2163     {
2164 	for (i = 0; i < num_read_uhps; i++)
2165 	    if (uhp_table[i] != NULL)
2166 		u_free_uhp(uhp_table[i]);
2167 	vim_free(uhp_table);
2168     }
2169 
2170 theend:
2171 #ifdef FEAT_CRYPT
2172     if (bi.bi_state != NULL)
2173 	crypt_free_state(bi.bi_state);
2174     vim_free(bi.bi_buffer);
2175 #endif
2176     if (fp != NULL)
2177 	fclose(fp);
2178     if (file_name != name)
2179 	vim_free(file_name);
2180     return;
2181 }
2182 
2183 #endif /* FEAT_PERSISTENT_UNDO */
2184 
2185 
2186 /*
2187  * If 'cpoptions' contains 'u': Undo the previous undo or redo (vi compatible).
2188  * If 'cpoptions' does not contain 'u': Always undo.
2189  */
2190     void
2191 u_undo(count)
2192     int count;
2193 {
2194     /*
2195      * If we get an undo command while executing a macro, we behave like the
2196      * original vi. If this happens twice in one macro the result will not
2197      * be compatible.
2198      */
2199     if (curbuf->b_u_synced == FALSE)
2200     {
2201 	u_sync(TRUE);
2202 	count = 1;
2203     }
2204 
2205     if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
2206 	undo_undoes = TRUE;
2207     else
2208 	undo_undoes = !undo_undoes;
2209     u_doit(count);
2210 }
2211 
2212 /*
2213  * If 'cpoptions' contains 'u': Repeat the previous undo or redo.
2214  * If 'cpoptions' does not contain 'u': Always redo.
2215  */
2216     void
2217 u_redo(count)
2218     int count;
2219 {
2220     if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
2221 	undo_undoes = FALSE;
2222     u_doit(count);
2223 }
2224 
2225 /*
2226  * Undo or redo, depending on 'undo_undoes', 'count' times.
2227  */
2228     static void
2229 u_doit(startcount)
2230     int startcount;
2231 {
2232     int count = startcount;
2233 
2234     if (!undo_allowed())
2235 	return;
2236 
2237     u_newcount = 0;
2238     u_oldcount = 0;
2239     if (curbuf->b_ml.ml_flags & ML_EMPTY)
2240 	u_oldcount = -1;
2241     while (count--)
2242     {
2243 	/* Do the change warning now, so that it triggers FileChangedRO when
2244 	 * needed.  This may cause the file to be reloaded, that must happen
2245 	 * before we do anything, because it may change curbuf->b_u_curhead
2246 	 * and more. */
2247 	change_warning(0);
2248 
2249 	if (undo_undoes)
2250 	{
2251 	    if (curbuf->b_u_curhead == NULL)		/* first undo */
2252 		curbuf->b_u_curhead = curbuf->b_u_newhead;
2253 	    else if (get_undolevel() > 0)		/* multi level undo */
2254 		/* get next undo */
2255 		curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr;
2256 	    /* nothing to undo */
2257 	    if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL)
2258 	    {
2259 		/* stick curbuf->b_u_curhead at end */
2260 		curbuf->b_u_curhead = curbuf->b_u_oldhead;
2261 		beep_flush();
2262 		if (count == startcount - 1)
2263 		{
2264 		    MSG(_("Already at oldest change"));
2265 		    return;
2266 		}
2267 		break;
2268 	    }
2269 
2270 	    u_undoredo(TRUE);
2271 	}
2272 	else
2273 	{
2274 	    if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0)
2275 	    {
2276 		beep_flush();	/* nothing to redo */
2277 		if (count == startcount - 1)
2278 		{
2279 		    MSG(_("Already at newest change"));
2280 		    return;
2281 		}
2282 		break;
2283 	    }
2284 
2285 	    u_undoredo(FALSE);
2286 
2287 	    /* Advance for next redo.  Set "newhead" when at the end of the
2288 	     * redoable changes. */
2289 	    if (curbuf->b_u_curhead->uh_prev.ptr == NULL)
2290 		curbuf->b_u_newhead = curbuf->b_u_curhead;
2291 	    curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev.ptr;
2292 	}
2293     }
2294     u_undo_end(undo_undoes, FALSE);
2295 }
2296 
2297 /*
2298  * Undo or redo over the timeline.
2299  * When "step" is negative go back in time, otherwise goes forward in time.
2300  * When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as
2301  * seconds.
2302  * When "file" is TRUE use "step" as a number of file writes.
2303  * When "absolute" is TRUE use "step" as the sequence number to jump to.
2304  * "sec" must be FALSE then.
2305  */
2306     void
2307 undo_time(step, sec, file, absolute)
2308     long	step;
2309     int		sec;
2310     int		file;
2311     int		absolute;
2312 {
2313     long	    target;
2314     long	    closest;
2315     long	    closest_start;
2316     long	    closest_seq = 0;
2317     long	    val;
2318     u_header_T	    *uhp;
2319     u_header_T	    *last;
2320     int		    mark;
2321     int		    nomark;
2322     int		    round;
2323     int		    dosec = sec;
2324     int		    dofile = file;
2325     int		    above = FALSE;
2326     int		    did_undo = TRUE;
2327 
2328     /* First make sure the current undoable change is synced. */
2329     if (curbuf->b_u_synced == FALSE)
2330 	u_sync(TRUE);
2331 
2332     u_newcount = 0;
2333     u_oldcount = 0;
2334     if (curbuf->b_ml.ml_flags & ML_EMPTY)
2335 	u_oldcount = -1;
2336 
2337     /* "target" is the node below which we want to be.
2338      * Init "closest" to a value we can't reach. */
2339     if (absolute)
2340     {
2341 	target = step;
2342 	closest = -1;
2343     }
2344     else
2345     {
2346 	/* When doing computations with time_t subtract starttime, because
2347 	 * time_t converted to a long may result in a wrong number. */
2348 	if (dosec)
2349 	    target = (long)(curbuf->b_u_time_cur - starttime) + step;
2350 	else if (dofile)
2351 	{
2352 	    if (step < 0)
2353 	    {
2354 		/* Going back to a previous write. If there were changes after
2355 		 * the last write, count that as moving one file-write, so
2356 		 * that ":earlier 1f" undoes all changes since the last save. */
2357 		uhp = curbuf->b_u_curhead;
2358 		if (uhp != NULL)
2359 		    uhp = uhp->uh_next.ptr;
2360 		else
2361 		    uhp = curbuf->b_u_newhead;
2362 		if (uhp != NULL && uhp->uh_save_nr != 0)
2363 		    /* "uh_save_nr" was set in the last block, that means
2364 		     * there were no changes since the last write */
2365 		    target = curbuf->b_u_save_nr_cur + step;
2366 		else
2367 		    /* count the changes since the last write as one step */
2368 		    target = curbuf->b_u_save_nr_cur + step + 1;
2369 		if (target <= 0)
2370 		    /* Go to before first write: before the oldest change. Use
2371 		     * the sequence number for that. */
2372 		    dofile = FALSE;
2373 	    }
2374 	    else
2375 	    {
2376 		/* Moving forward to a newer write. */
2377 		target = curbuf->b_u_save_nr_cur + step;
2378 		if (target > curbuf->b_u_save_nr_last)
2379 		{
2380 		    /* Go to after last write: after the latest change. Use
2381 		     * the sequence number for that. */
2382 		    target = curbuf->b_u_seq_last + 1;
2383 		    dofile = FALSE;
2384 		}
2385 	    }
2386 	}
2387 	else
2388 	    target = curbuf->b_u_seq_cur + step;
2389 	if (step < 0)
2390 	{
2391 	    if (target < 0)
2392 		target = 0;
2393 	    closest = -1;
2394 	}
2395 	else
2396 	{
2397 	    if (dosec)
2398 		closest = (long)(time(NULL) - starttime + 1);
2399 	    else if (dofile)
2400 		closest = curbuf->b_u_save_nr_last + 2;
2401 	    else
2402 		closest = curbuf->b_u_seq_last + 2;
2403 	    if (target >= closest)
2404 		target = closest - 1;
2405 	}
2406     }
2407     closest_start = closest;
2408     closest_seq = curbuf->b_u_seq_cur;
2409 
2410     /*
2411      * May do this twice:
2412      * 1. Search for "target", update "closest" to the best match found.
2413      * 2. If "target" not found search for "closest".
2414      *
2415      * When using the closest time we use the sequence number in the second
2416      * round, because there may be several entries with the same time.
2417      */
2418     for (round = 1; round <= 2; ++round)
2419     {
2420 	/* Find the path from the current state to where we want to go.  The
2421 	 * desired state can be anywhere in the undo tree, need to go all over
2422 	 * it.  We put "nomark" in uh_walk where we have been without success,
2423 	 * "mark" where it could possibly be. */
2424 	mark = ++lastmark;
2425 	nomark = ++lastmark;
2426 
2427 	if (curbuf->b_u_curhead == NULL)	/* at leaf of the tree */
2428 	    uhp = curbuf->b_u_newhead;
2429 	else
2430 	    uhp = curbuf->b_u_curhead;
2431 
2432 	while (uhp != NULL)
2433 	{
2434 	    uhp->uh_walk = mark;
2435 	    if (dosec)
2436 		val = (long)(uhp->uh_time - starttime);
2437 	    else if (dofile)
2438 		val = uhp->uh_save_nr;
2439 	    else
2440 		val = uhp->uh_seq;
2441 
2442 	    if (round == 1 && !(dofile && val == 0))
2443 	    {
2444 		/* Remember the header that is closest to the target.
2445 		 * It must be at least in the right direction (checked with
2446 		 * "b_u_seq_cur").  When the timestamp is equal find the
2447 		 * highest/lowest sequence number. */
2448 		if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur
2449 			      : uhp->uh_seq > curbuf->b_u_seq_cur)
2450 			&& ((dosec && val == closest)
2451 			    ? (step < 0
2452 				? uhp->uh_seq < closest_seq
2453 				: uhp->uh_seq > closest_seq)
2454 			    : closest == closest_start
2455 				|| (val > target
2456 				    ? (closest > target
2457 					? val - target <= closest - target
2458 					: val - target <= target - closest)
2459 				    : (closest > target
2460 					? target - val <= closest - target
2461 					: target - val <= target - closest))))
2462 		{
2463 		    closest = val;
2464 		    closest_seq = uhp->uh_seq;
2465 		}
2466 	    }
2467 
2468 	    /* Quit searching when we found a match.  But when searching for a
2469 	     * time we need to continue looking for the best uh_seq. */
2470 	    if (target == val && !dosec)
2471 	    {
2472 		target = uhp->uh_seq;
2473 		break;
2474 	    }
2475 
2476 	    /* go down in the tree if we haven't been there */
2477 	    if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark
2478 					 && uhp->uh_prev.ptr->uh_walk != mark)
2479 		uhp = uhp->uh_prev.ptr;
2480 
2481 	    /* go to alternate branch if we haven't been there */
2482 	    else if (uhp->uh_alt_next.ptr != NULL
2483 		    && uhp->uh_alt_next.ptr->uh_walk != nomark
2484 		    && uhp->uh_alt_next.ptr->uh_walk != mark)
2485 		uhp = uhp->uh_alt_next.ptr;
2486 
2487 	    /* go up in the tree if we haven't been there and we are at the
2488 	     * start of alternate branches */
2489 	    else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
2490 		    && uhp->uh_next.ptr->uh_walk != nomark
2491 		    && uhp->uh_next.ptr->uh_walk != mark)
2492 	    {
2493 		/* If still at the start we don't go through this change. */
2494 		if (uhp == curbuf->b_u_curhead)
2495 		    uhp->uh_walk = nomark;
2496 		uhp = uhp->uh_next.ptr;
2497 	    }
2498 
2499 	    else
2500 	    {
2501 		/* need to backtrack; mark this node as useless */
2502 		uhp->uh_walk = nomark;
2503 		if (uhp->uh_alt_prev.ptr != NULL)
2504 		    uhp = uhp->uh_alt_prev.ptr;
2505 		else
2506 		    uhp = uhp->uh_next.ptr;
2507 	    }
2508 	}
2509 
2510 	if (uhp != NULL)    /* found it */
2511 	    break;
2512 
2513 	if (absolute)
2514 	{
2515 	    EMSGN(_("E830: Undo number %ld not found"), step);
2516 	    return;
2517 	}
2518 
2519 	if (closest == closest_start)
2520 	{
2521 	    if (step < 0)
2522 		MSG(_("Already at oldest change"));
2523 	    else
2524 		MSG(_("Already at newest change"));
2525 	    return;
2526 	}
2527 
2528 	target = closest_seq;
2529 	dosec = FALSE;
2530 	dofile = FALSE;
2531 	if (step < 0)
2532 	    above = TRUE;	/* stop above the header */
2533     }
2534 
2535     /* If we found it: Follow the path to go to where we want to be. */
2536     if (uhp != NULL)
2537     {
2538 	/*
2539 	 * First go up the tree as much as needed.
2540 	 */
2541 	while (!got_int)
2542 	{
2543 	    /* Do the change warning now, for the same reason as above. */
2544 	    change_warning(0);
2545 
2546 	    uhp = curbuf->b_u_curhead;
2547 	    if (uhp == NULL)
2548 		uhp = curbuf->b_u_newhead;
2549 	    else
2550 		uhp = uhp->uh_next.ptr;
2551 	    if (uhp == NULL || uhp->uh_walk != mark
2552 					 || (uhp->uh_seq == target && !above))
2553 		break;
2554 	    curbuf->b_u_curhead = uhp;
2555 	    u_undoredo(TRUE);
2556 	    uhp->uh_walk = nomark;	/* don't go back down here */
2557 	}
2558 
2559 	/*
2560 	 * And now go down the tree (redo), branching off where needed.
2561 	 */
2562 	while (!got_int)
2563 	{
2564 	    /* Do the change warning now, for the same reason as above. */
2565 	    change_warning(0);
2566 
2567 	    uhp = curbuf->b_u_curhead;
2568 	    if (uhp == NULL)
2569 		break;
2570 
2571 	    /* Go back to the first branch with a mark. */
2572 	    while (uhp->uh_alt_prev.ptr != NULL
2573 				     && uhp->uh_alt_prev.ptr->uh_walk == mark)
2574 		uhp = uhp->uh_alt_prev.ptr;
2575 
2576 	    /* Find the last branch with a mark, that's the one. */
2577 	    last = uhp;
2578 	    while (last->uh_alt_next.ptr != NULL
2579 				    && last->uh_alt_next.ptr->uh_walk == mark)
2580 		last = last->uh_alt_next.ptr;
2581 	    if (last != uhp)
2582 	    {
2583 		/* Make the used branch the first entry in the list of
2584 		 * alternatives to make "u" and CTRL-R take this branch. */
2585 		while (uhp->uh_alt_prev.ptr != NULL)
2586 		    uhp = uhp->uh_alt_prev.ptr;
2587 		if (last->uh_alt_next.ptr != NULL)
2588 		    last->uh_alt_next.ptr->uh_alt_prev.ptr =
2589 							last->uh_alt_prev.ptr;
2590 		last->uh_alt_prev.ptr->uh_alt_next.ptr = last->uh_alt_next.ptr;
2591 		last->uh_alt_prev.ptr = NULL;
2592 		last->uh_alt_next.ptr = uhp;
2593 		uhp->uh_alt_prev.ptr = last;
2594 
2595 		if (curbuf->b_u_oldhead == uhp)
2596 		    curbuf->b_u_oldhead = last;
2597 		uhp = last;
2598 		if (uhp->uh_next.ptr != NULL)
2599 		    uhp->uh_next.ptr->uh_prev.ptr = uhp;
2600 	    }
2601 	    curbuf->b_u_curhead = uhp;
2602 
2603 	    if (uhp->uh_walk != mark)
2604 		break;	    /* must have reached the target */
2605 
2606 	    /* Stop when going backwards in time and didn't find the exact
2607 	     * header we were looking for. */
2608 	    if (uhp->uh_seq == target && above)
2609 	    {
2610 		curbuf->b_u_seq_cur = target - 1;
2611 		break;
2612 	    }
2613 
2614 	    u_undoredo(FALSE);
2615 
2616 	    /* Advance "curhead" to below the header we last used.  If it
2617 	     * becomes NULL then we need to set "newhead" to this leaf. */
2618 	    if (uhp->uh_prev.ptr == NULL)
2619 		curbuf->b_u_newhead = uhp;
2620 	    curbuf->b_u_curhead = uhp->uh_prev.ptr;
2621 	    did_undo = FALSE;
2622 
2623 	    if (uhp->uh_seq == target)	/* found it! */
2624 		break;
2625 
2626 	    uhp = uhp->uh_prev.ptr;
2627 	    if (uhp == NULL || uhp->uh_walk != mark)
2628 	    {
2629 		/* Need to redo more but can't find it... */
2630 		EMSG2(_(e_intern2), "undo_time()");
2631 		break;
2632 	    }
2633 	}
2634     }
2635     u_undo_end(did_undo, absolute);
2636 }
2637 
2638 /*
2639  * u_undoredo: common code for undo and redo
2640  *
2641  * The lines in the file are replaced by the lines in the entry list at
2642  * curbuf->b_u_curhead. The replaced lines in the file are saved in the entry
2643  * list for the next undo/redo.
2644  *
2645  * When "undo" is TRUE we go up in the tree, when FALSE we go down.
2646  */
2647     static void
2648 u_undoredo(undo)
2649     int		undo;
2650 {
2651     char_u	**newarray = NULL;
2652     linenr_T	oldsize;
2653     linenr_T	newsize;
2654     linenr_T	top, bot;
2655     linenr_T	lnum;
2656     linenr_T	newlnum = MAXLNUM;
2657     long	i;
2658     u_entry_T	*uep, *nuep;
2659     u_entry_T	*newlist = NULL;
2660     int		old_flags;
2661     int		new_flags;
2662     pos_T	namedm[NMARKS];
2663     visualinfo_T visualinfo;
2664     int		empty_buffer;		    /* buffer became empty */
2665     u_header_T	*curhead = curbuf->b_u_curhead;
2666 
2667 #ifdef FEAT_AUTOCMD
2668     /* Don't want autocommands using the undo structures here, they are
2669      * invalid till the end. */
2670     block_autocmds();
2671 #endif
2672 
2673 #ifdef U_DEBUG
2674     u_check(FALSE);
2675 #endif
2676     old_flags = curhead->uh_flags;
2677     new_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
2678 	       ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
2679     setpcmark();
2680 
2681     /*
2682      * save marks before undo/redo
2683      */
2684     mch_memmove(namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS);
2685     visualinfo = curbuf->b_visual;
2686     curbuf->b_op_start.lnum = curbuf->b_ml.ml_line_count;
2687     curbuf->b_op_start.col = 0;
2688     curbuf->b_op_end.lnum = 0;
2689     curbuf->b_op_end.col = 0;
2690 
2691     for (uep = curhead->uh_entry; uep != NULL; uep = nuep)
2692     {
2693 	top = uep->ue_top;
2694 	bot = uep->ue_bot;
2695 	if (bot == 0)
2696 	    bot = curbuf->b_ml.ml_line_count + 1;
2697 	if (top > curbuf->b_ml.ml_line_count || top >= bot
2698 				      || bot > curbuf->b_ml.ml_line_count + 1)
2699 	{
2700 #ifdef FEAT_AUTOCMD
2701 	    unblock_autocmds();
2702 #endif
2703 	    EMSG(_("E438: u_undo: line numbers wrong"));
2704 	    changed();		/* don't want UNCHANGED now */
2705 	    return;
2706 	}
2707 
2708 	oldsize = bot - top - 1;    /* number of lines before undo */
2709 	newsize = uep->ue_size;	    /* number of lines after undo */
2710 
2711 	if (top < newlnum)
2712 	{
2713 	    /* If the saved cursor is somewhere in this undo block, move it to
2714 	     * the remembered position.  Makes "gwap" put the cursor back
2715 	     * where it was. */
2716 	    lnum = curhead->uh_cursor.lnum;
2717 	    if (lnum >= top && lnum <= top + newsize + 1)
2718 	    {
2719 		curwin->w_cursor = curhead->uh_cursor;
2720 		newlnum = curwin->w_cursor.lnum - 1;
2721 	    }
2722 	    else
2723 	    {
2724 		/* Use the first line that actually changed.  Avoids that
2725 		 * undoing auto-formatting puts the cursor in the previous
2726 		 * line. */
2727 		for (i = 0; i < newsize && i < oldsize; ++i)
2728 		    if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0)
2729 			break;
2730 		if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL)
2731 		{
2732 		    newlnum = top;
2733 		    curwin->w_cursor.lnum = newlnum + 1;
2734 		}
2735 		else if (i < newsize)
2736 		{
2737 		    newlnum = top + i;
2738 		    curwin->w_cursor.lnum = newlnum + 1;
2739 		}
2740 	    }
2741 	}
2742 
2743 	empty_buffer = FALSE;
2744 
2745 	/* delete the lines between top and bot and save them in newarray */
2746 	if (oldsize > 0)
2747 	{
2748 	    if ((newarray = (char_u **)U_ALLOC_LINE(
2749 					 sizeof(char_u *) * oldsize)) == NULL)
2750 	    {
2751 		do_outofmem_msg((long_u)(sizeof(char_u *) * oldsize));
2752 		/*
2753 		 * We have messed up the entry list, repair is impossible.
2754 		 * we have to free the rest of the list.
2755 		 */
2756 		while (uep != NULL)
2757 		{
2758 		    nuep = uep->ue_next;
2759 		    u_freeentry(uep, uep->ue_size);
2760 		    uep = nuep;
2761 		}
2762 		break;
2763 	    }
2764 	    /* delete backwards, it goes faster in most cases */
2765 	    for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum)
2766 	    {
2767 		/* what can we do when we run out of memory? */
2768 		if ((newarray[i] = u_save_line(lnum)) == NULL)
2769 		    do_outofmem_msg((long_u)0);
2770 		/* remember we deleted the last line in the buffer, and a
2771 		 * dummy empty line will be inserted */
2772 		if (curbuf->b_ml.ml_line_count == 1)
2773 		    empty_buffer = TRUE;
2774 		ml_delete(lnum, FALSE);
2775 	    }
2776 	}
2777 	else
2778 	    newarray = NULL;
2779 
2780 	/* insert the lines in u_array between top and bot */
2781 	if (newsize)
2782 	{
2783 	    for (lnum = top, i = 0; i < newsize; ++i, ++lnum)
2784 	    {
2785 		/*
2786 		 * If the file is empty, there is an empty line 1 that we
2787 		 * should get rid of, by replacing it with the new line
2788 		 */
2789 		if (empty_buffer && lnum == 0)
2790 		    ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
2791 		else
2792 		    ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
2793 		vim_free(uep->ue_array[i]);
2794 	    }
2795 	    vim_free((char_u *)uep->ue_array);
2796 	}
2797 
2798 	/* adjust marks */
2799 	if (oldsize != newsize)
2800 	{
2801 	    mark_adjust(top + 1, top + oldsize, (long)MAXLNUM,
2802 					       (long)newsize - (long)oldsize);
2803 	    if (curbuf->b_op_start.lnum > top + oldsize)
2804 		curbuf->b_op_start.lnum += newsize - oldsize;
2805 	    if (curbuf->b_op_end.lnum > top + oldsize)
2806 		curbuf->b_op_end.lnum += newsize - oldsize;
2807 	}
2808 
2809 	changed_lines(top + 1, 0, bot, newsize - oldsize);
2810 
2811 	/* set '[ and '] mark */
2812 	if (top + 1 < curbuf->b_op_start.lnum)
2813 	    curbuf->b_op_start.lnum = top + 1;
2814 	if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum)
2815 	    curbuf->b_op_end.lnum = top + 1;
2816 	else if (top + newsize > curbuf->b_op_end.lnum)
2817 	    curbuf->b_op_end.lnum = top + newsize;
2818 
2819 	u_newcount += newsize;
2820 	u_oldcount += oldsize;
2821 	uep->ue_size = oldsize;
2822 	uep->ue_array = newarray;
2823 	uep->ue_bot = top + newsize + 1;
2824 
2825 	/*
2826 	 * insert this entry in front of the new entry list
2827 	 */
2828 	nuep = uep->ue_next;
2829 	uep->ue_next = newlist;
2830 	newlist = uep;
2831     }
2832 
2833     curhead->uh_entry = newlist;
2834     curhead->uh_flags = new_flags;
2835     if ((old_flags & UH_EMPTYBUF) && bufempty())
2836 	curbuf->b_ml.ml_flags |= ML_EMPTY;
2837     if (old_flags & UH_CHANGED)
2838 	changed();
2839     else
2840 #ifdef FEAT_NETBEANS_INTG
2841 	/* per netbeans undo rules, keep it as modified */
2842 	if (!isNetbeansModified(curbuf))
2843 #endif
2844 	unchanged(curbuf, FALSE);
2845 
2846     /*
2847      * restore marks from before undo/redo
2848      */
2849     for (i = 0; i < NMARKS; ++i)
2850     {
2851 	if (curhead->uh_namedm[i].lnum != 0)
2852 	    curbuf->b_namedm[i] = curhead->uh_namedm[i];
2853 	if (namedm[i].lnum != 0)
2854 	    curhead->uh_namedm[i] = namedm[i];
2855 	else
2856 	    curhead->uh_namedm[i].lnum = 0;
2857     }
2858     if (curhead->uh_visual.vi_start.lnum != 0)
2859     {
2860 	curbuf->b_visual = curhead->uh_visual;
2861 	curhead->uh_visual = visualinfo;
2862     }
2863 
2864     /*
2865      * If the cursor is only off by one line, put it at the same position as
2866      * before starting the change (for the "o" command).
2867      * Otherwise the cursor should go to the first undone line.
2868      */
2869     if (curhead->uh_cursor.lnum + 1 == curwin->w_cursor.lnum
2870 						 && curwin->w_cursor.lnum > 1)
2871 	--curwin->w_cursor.lnum;
2872     if (curwin->w_cursor.lnum <= curbuf->b_ml.ml_line_count)
2873     {
2874 	if (curhead->uh_cursor.lnum == curwin->w_cursor.lnum)
2875 	{
2876 	    curwin->w_cursor.col = curhead->uh_cursor.col;
2877 #ifdef FEAT_VIRTUALEDIT
2878 	    if (virtual_active() && curhead->uh_cursor_vcol >= 0)
2879 		coladvance((colnr_T)curhead->uh_cursor_vcol);
2880 	    else
2881 		curwin->w_cursor.coladd = 0;
2882 #endif
2883 	}
2884 	else
2885 	    beginline(BL_SOL | BL_FIX);
2886     }
2887     else
2888     {
2889 	/* We get here with the current cursor line being past the end (eg
2890 	 * after adding lines at the end of the file, and then undoing it).
2891 	 * check_cursor() will move the cursor to the last line.  Move it to
2892 	 * the first column here. */
2893 	curwin->w_cursor.col = 0;
2894 #ifdef FEAT_VIRTUALEDIT
2895 	curwin->w_cursor.coladd = 0;
2896 #endif
2897     }
2898 
2899     /* Make sure the cursor is on an existing line and column. */
2900     check_cursor();
2901 
2902     /* Remember where we are for "g-" and ":earlier 10s". */
2903     curbuf->b_u_seq_cur = curhead->uh_seq;
2904     if (undo)
2905 	/* We are below the previous undo.  However, to make ":earlier 1s"
2906 	 * work we compute this as being just above the just undone change. */
2907 	--curbuf->b_u_seq_cur;
2908 
2909     /* Remember where we are for ":earlier 1f" and ":later 1f". */
2910     if (curhead->uh_save_nr != 0)
2911     {
2912 	if (undo)
2913 	    curbuf->b_u_save_nr_cur = curhead->uh_save_nr - 1;
2914 	else
2915 	    curbuf->b_u_save_nr_cur = curhead->uh_save_nr;
2916     }
2917 
2918     /* The timestamp can be the same for multiple changes, just use the one of
2919      * the undone/redone change. */
2920     curbuf->b_u_time_cur = curhead->uh_time;
2921 
2922 #ifdef FEAT_AUTOCMD
2923     unblock_autocmds();
2924 #endif
2925 #ifdef U_DEBUG
2926     u_check(FALSE);
2927 #endif
2928 }
2929 
2930 /*
2931  * If we deleted or added lines, report the number of less/more lines.
2932  * Otherwise, report the number of changes (this may be incorrect
2933  * in some cases, but it's better than nothing).
2934  */
2935     static void
2936 u_undo_end(did_undo, absolute)
2937     int		did_undo;	/* just did an undo */
2938     int		absolute;	/* used ":undo N" */
2939 {
2940     char	*msgstr;
2941     u_header_T	*uhp;
2942     char_u	msgbuf[80];
2943 
2944 #ifdef FEAT_FOLDING
2945     if ((fdo_flags & FDO_UNDO) && KeyTyped)
2946 	foldOpenCursor();
2947 #endif
2948 
2949     if (global_busy	    /* no messages now, wait until global is finished */
2950 	    || !messaging())  /* 'lazyredraw' set, don't do messages now */
2951 	return;
2952 
2953     if (curbuf->b_ml.ml_flags & ML_EMPTY)
2954 	--u_newcount;
2955 
2956     u_oldcount -= u_newcount;
2957     if (u_oldcount == -1)
2958 	msgstr = N_("more line");
2959     else if (u_oldcount < 0)
2960 	msgstr = N_("more lines");
2961     else if (u_oldcount == 1)
2962 	msgstr = N_("line less");
2963     else if (u_oldcount > 1)
2964 	msgstr = N_("fewer lines");
2965     else
2966     {
2967 	u_oldcount = u_newcount;
2968 	if (u_newcount == 1)
2969 	    msgstr = N_("change");
2970 	else
2971 	    msgstr = N_("changes");
2972     }
2973 
2974     if (curbuf->b_u_curhead != NULL)
2975     {
2976 	/* For ":undo N" we prefer a "after #N" message. */
2977 	if (absolute && curbuf->b_u_curhead->uh_next.ptr != NULL)
2978 	{
2979 	    uhp = curbuf->b_u_curhead->uh_next.ptr;
2980 	    did_undo = FALSE;
2981 	}
2982 	else if (did_undo)
2983 	    uhp = curbuf->b_u_curhead;
2984 	else
2985 	    uhp = curbuf->b_u_curhead->uh_next.ptr;
2986     }
2987     else
2988 	uhp = curbuf->b_u_newhead;
2989 
2990     if (uhp == NULL)
2991 	*msgbuf = NUL;
2992     else
2993 	u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time);
2994 
2995 #ifdef FEAT_CONCEAL
2996     {
2997 	win_T	*wp;
2998 
2999 	FOR_ALL_WINDOWS(wp)
3000 	{
3001 	    if (wp->w_buffer == curbuf && wp->w_p_cole > 0)
3002 		redraw_win_later(wp, NOT_VALID);
3003 	}
3004     }
3005 #endif
3006 
3007     smsg((char_u *)_("%ld %s; %s #%ld  %s"),
3008 	    u_oldcount < 0 ? -u_oldcount : u_oldcount,
3009 	    _(msgstr),
3010 	    did_undo ? _("before") : _("after"),
3011 	    uhp == NULL ? 0L : uhp->uh_seq,
3012 	    msgbuf);
3013 }
3014 
3015 /*
3016  * u_sync: stop adding to the current entry list
3017  */
3018     void
3019 u_sync(force)
3020     int	    force;	/* Also sync when no_u_sync is set. */
3021 {
3022     /* Skip it when already synced or syncing is disabled. */
3023     if (curbuf->b_u_synced || (!force && no_u_sync > 0))
3024 	return;
3025 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
3026     if (im_is_preediting())
3027 	return;		    /* XIM is busy, don't break an undo sequence */
3028 #endif
3029     if (get_undolevel() < 0)
3030 	curbuf->b_u_synced = TRUE;  /* no entries, nothing to do */
3031     else
3032     {
3033 	u_getbot();		    /* compute ue_bot of previous u_save */
3034 	curbuf->b_u_curhead = NULL;
3035     }
3036 }
3037 
3038 /*
3039  * ":undolist": List the leafs of the undo tree
3040  */
3041     void
3042 ex_undolist(eap)
3043     exarg_T *eap UNUSED;
3044 {
3045     garray_T	ga;
3046     u_header_T	*uhp;
3047     int		mark;
3048     int		nomark;
3049     int		changes = 1;
3050     int		i;
3051 
3052     /*
3053      * 1: walk the tree to find all leafs, put the info in "ga".
3054      * 2: sort the lines
3055      * 3: display the list
3056      */
3057     mark = ++lastmark;
3058     nomark = ++lastmark;
3059     ga_init2(&ga, (int)sizeof(char *), 20);
3060 
3061     uhp = curbuf->b_u_oldhead;
3062     while (uhp != NULL)
3063     {
3064 	if (uhp->uh_prev.ptr == NULL && uhp->uh_walk != nomark
3065 						      && uhp->uh_walk != mark)
3066 	{
3067 	    if (ga_grow(&ga, 1) == FAIL)
3068 		break;
3069 	    vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7ld  ",
3070 							uhp->uh_seq, changes);
3071 	    u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
3072 								uhp->uh_time);
3073 	    if (uhp->uh_save_nr > 0)
3074 	    {
3075 		while (STRLEN(IObuff) < 33)
3076 		    STRCAT(IObuff, " ");
3077 		vim_snprintf_add((char *)IObuff, IOSIZE,
3078 						   "  %3ld", uhp->uh_save_nr);
3079 	    }
3080 	    ((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strsave(IObuff);
3081 	}
3082 
3083 	uhp->uh_walk = mark;
3084 
3085 	/* go down in the tree if we haven't been there */
3086 	if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark
3087 					 && uhp->uh_prev.ptr->uh_walk != mark)
3088 	{
3089 	    uhp = uhp->uh_prev.ptr;
3090 	    ++changes;
3091 	}
3092 
3093 	/* go to alternate branch if we haven't been there */
3094 	else if (uhp->uh_alt_next.ptr != NULL
3095 		&& uhp->uh_alt_next.ptr->uh_walk != nomark
3096 		&& uhp->uh_alt_next.ptr->uh_walk != mark)
3097 	    uhp = uhp->uh_alt_next.ptr;
3098 
3099 	/* go up in the tree if we haven't been there and we are at the
3100 	 * start of alternate branches */
3101 	else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
3102 		&& uhp->uh_next.ptr->uh_walk != nomark
3103 		&& uhp->uh_next.ptr->uh_walk != mark)
3104 	{
3105 	    uhp = uhp->uh_next.ptr;
3106 	    --changes;
3107 	}
3108 
3109 	else
3110 	{
3111 	    /* need to backtrack; mark this node as done */
3112 	    uhp->uh_walk = nomark;
3113 	    if (uhp->uh_alt_prev.ptr != NULL)
3114 		uhp = uhp->uh_alt_prev.ptr;
3115 	    else
3116 	    {
3117 		uhp = uhp->uh_next.ptr;
3118 		--changes;
3119 	    }
3120 	}
3121     }
3122 
3123     if (ga.ga_len == 0)
3124 	MSG(_("Nothing to undo"));
3125     else
3126     {
3127 	sort_strings((char_u **)ga.ga_data, ga.ga_len);
3128 
3129 	msg_start();
3130 	msg_puts_attr((char_u *)_("number changes  when               saved"),
3131 							      hl_attr(HLF_T));
3132 	for (i = 0; i < ga.ga_len && !got_int; ++i)
3133 	{
3134 	    msg_putchar('\n');
3135 	    if (got_int)
3136 		break;
3137 	    msg_puts(((char_u **)ga.ga_data)[i]);
3138 	}
3139 	msg_end();
3140 
3141 	ga_clear_strings(&ga);
3142     }
3143 }
3144 
3145 /*
3146  * Put the timestamp of an undo header in "buf[buflen]" in a nice format.
3147  */
3148     static void
3149 u_add_time(buf, buflen, tt)
3150     char_u	*buf;
3151     size_t	buflen;
3152     time_t	tt;
3153 {
3154 #ifdef HAVE_STRFTIME
3155     struct tm	*curtime;
3156 
3157     if (time(NULL) - tt >= 100)
3158     {
3159 	curtime = localtime(&tt);
3160 	if (time(NULL) - tt < (60L * 60L * 12L))
3161 	    /* within 12 hours */
3162 	    (void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);
3163 	else
3164 	    /* longer ago */
3165 	    (void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime);
3166     }
3167     else
3168 #endif
3169 	vim_snprintf((char *)buf, buflen, _("%ld seconds ago"),
3170 						     (long)(time(NULL) - tt));
3171 }
3172 
3173 /*
3174  * ":undojoin": continue adding to the last entry list
3175  */
3176     void
3177 ex_undojoin(eap)
3178     exarg_T *eap UNUSED;
3179 {
3180     if (curbuf->b_u_newhead == NULL)
3181 	return;		    /* nothing changed before */
3182     if (curbuf->b_u_curhead != NULL)
3183     {
3184 	EMSG(_("E790: undojoin is not allowed after undo"));
3185 	return;
3186     }
3187     if (!curbuf->b_u_synced)
3188 	return;		    /* already unsynced */
3189     if (get_undolevel() < 0)
3190 	return;		    /* no entries, nothing to do */
3191     else
3192     {
3193 	/* Go back to the last entry */
3194 	curbuf->b_u_curhead = curbuf->b_u_newhead;
3195 	curbuf->b_u_synced = FALSE;  /* no entries, nothing to do */
3196     }
3197 }
3198 
3199 /*
3200  * Called after writing or reloading the file and setting b_changed to FALSE.
3201  * Now an undo means that the buffer is modified.
3202  */
3203     void
3204 u_unchanged(buf)
3205     buf_T	*buf;
3206 {
3207     u_unch_branch(buf->b_u_oldhead);
3208     buf->b_did_warn = FALSE;
3209 }
3210 
3211 /*
3212  * After reloading a buffer which was saved for 'undoreload': Find the first
3213  * line that was changed and set the cursor there.
3214  */
3215     void
3216 u_find_first_changed()
3217 {
3218     u_header_T	*uhp = curbuf->b_u_newhead;
3219     u_entry_T   *uep;
3220     linenr_T	lnum;
3221 
3222     if (curbuf->b_u_curhead != NULL || uhp == NULL)
3223 	return;  /* undid something in an autocmd? */
3224 
3225     /* Check that the last undo block was for the whole file. */
3226     uep = uhp->uh_entry;
3227     if (uep->ue_top != 0 || uep->ue_bot != 0)
3228 	return;
3229 
3230     for (lnum = 1; lnum < curbuf->b_ml.ml_line_count
3231 					      && lnum <= uep->ue_size; ++lnum)
3232 	if (STRCMP(ml_get_buf(curbuf, lnum, FALSE),
3233 						uep->ue_array[lnum - 1]) != 0)
3234 	{
3235 	    clearpos(&(uhp->uh_cursor));
3236 	    uhp->uh_cursor.lnum = lnum;
3237 	    return;
3238 	}
3239     if (curbuf->b_ml.ml_line_count != uep->ue_size)
3240     {
3241 	/* lines added or deleted at the end, put the cursor there */
3242 	clearpos(&(uhp->uh_cursor));
3243 	uhp->uh_cursor.lnum = lnum;
3244     }
3245 }
3246 
3247 /*
3248  * Increase the write count, store it in the last undo header, what would be
3249  * used for "u".
3250  */
3251     void
3252 u_update_save_nr(buf)
3253     buf_T *buf;
3254 {
3255     u_header_T	*uhp;
3256 
3257     ++buf->b_u_save_nr_last;
3258     buf->b_u_save_nr_cur = buf->b_u_save_nr_last;
3259     uhp = buf->b_u_curhead;
3260     if (uhp != NULL)
3261 	uhp = uhp->uh_next.ptr;
3262     else
3263 	uhp = buf->b_u_newhead;
3264     if (uhp != NULL)
3265 	uhp->uh_save_nr = buf->b_u_save_nr_last;
3266 }
3267 
3268     static void
3269 u_unch_branch(uhp)
3270     u_header_T	*uhp;
3271 {
3272     u_header_T	*uh;
3273 
3274     for (uh = uhp; uh != NULL; uh = uh->uh_prev.ptr)
3275     {
3276 	uh->uh_flags |= UH_CHANGED;
3277 	if (uh->uh_alt_next.ptr != NULL)
3278 	    u_unch_branch(uh->uh_alt_next.ptr);	    /* recursive */
3279     }
3280 }
3281 
3282 /*
3283  * Get pointer to last added entry.
3284  * If it's not valid, give an error message and return NULL.
3285  */
3286     static u_entry_T *
3287 u_get_headentry()
3288 {
3289     if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL)
3290     {
3291 	EMSG(_("E439: undo list corrupt"));
3292 	return NULL;
3293     }
3294     return curbuf->b_u_newhead->uh_entry;
3295 }
3296 
3297 /*
3298  * u_getbot(): compute the line number of the previous u_save
3299  *		It is called only when b_u_synced is FALSE.
3300  */
3301     static void
3302 u_getbot()
3303 {
3304     u_entry_T	*uep;
3305     linenr_T	extra;
3306 
3307     uep = u_get_headentry();	/* check for corrupt undo list */
3308     if (uep == NULL)
3309 	return;
3310 
3311     uep = curbuf->b_u_newhead->uh_getbot_entry;
3312     if (uep != NULL)
3313     {
3314 	/*
3315 	 * the new ue_bot is computed from the number of lines that has been
3316 	 * inserted (0 - deleted) since calling u_save. This is equal to the
3317 	 * old line count subtracted from the current line count.
3318 	 */
3319 	extra = curbuf->b_ml.ml_line_count - uep->ue_lcount;
3320 	uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra;
3321 	if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count)
3322 	{
3323 	    EMSG(_("E440: undo line missing"));
3324 	    uep->ue_bot = uep->ue_top + 1;  /* assume all lines deleted, will
3325 					     * get all the old lines back
3326 					     * without deleting the current
3327 					     * ones */
3328 	}
3329 
3330 	curbuf->b_u_newhead->uh_getbot_entry = NULL;
3331     }
3332 
3333     curbuf->b_u_synced = TRUE;
3334 }
3335 
3336 /*
3337  * Free one header "uhp" and its entry list and adjust the pointers.
3338  */
3339     static void
3340 u_freeheader(buf, uhp, uhpp)
3341     buf_T	    *buf;
3342     u_header_T	    *uhp;
3343     u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
3344 {
3345     u_header_T	    *uhap;
3346 
3347     /* When there is an alternate redo list free that branch completely,
3348      * because we can never go there. */
3349     if (uhp->uh_alt_next.ptr != NULL)
3350 	u_freebranch(buf, uhp->uh_alt_next.ptr, uhpp);
3351 
3352     if (uhp->uh_alt_prev.ptr != NULL)
3353 	uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL;
3354 
3355     /* Update the links in the list to remove the header. */
3356     if (uhp->uh_next.ptr == NULL)
3357 	buf->b_u_oldhead = uhp->uh_prev.ptr;
3358     else
3359 	uhp->uh_next.ptr->uh_prev.ptr = uhp->uh_prev.ptr;
3360 
3361     if (uhp->uh_prev.ptr == NULL)
3362 	buf->b_u_newhead = uhp->uh_next.ptr;
3363     else
3364 	for (uhap = uhp->uh_prev.ptr; uhap != NULL;
3365 						 uhap = uhap->uh_alt_next.ptr)
3366 	    uhap->uh_next.ptr = uhp->uh_next.ptr;
3367 
3368     u_freeentries(buf, uhp, uhpp);
3369 }
3370 
3371 /*
3372  * Free an alternate branch and any following alternate branches.
3373  */
3374     static void
3375 u_freebranch(buf, uhp, uhpp)
3376     buf_T	    *buf;
3377     u_header_T	    *uhp;
3378     u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
3379 {
3380     u_header_T	    *tofree, *next;
3381 
3382     /* If this is the top branch we may need to use u_freeheader() to update
3383      * all the pointers. */
3384     if (uhp == buf->b_u_oldhead)
3385     {
3386 	while (buf->b_u_oldhead != NULL)
3387 	    u_freeheader(buf, buf->b_u_oldhead, uhpp);
3388 	return;
3389     }
3390 
3391     if (uhp->uh_alt_prev.ptr != NULL)
3392 	uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL;
3393 
3394     next = uhp;
3395     while (next != NULL)
3396     {
3397 	tofree = next;
3398 	if (tofree->uh_alt_next.ptr != NULL)
3399 	    u_freebranch(buf, tofree->uh_alt_next.ptr, uhpp);   /* recursive */
3400 	next = tofree->uh_prev.ptr;
3401 	u_freeentries(buf, tofree, uhpp);
3402     }
3403 }
3404 
3405 /*
3406  * Free all the undo entries for one header and the header itself.
3407  * This means that "uhp" is invalid when returning.
3408  */
3409     static void
3410 u_freeentries(buf, uhp, uhpp)
3411     buf_T	    *buf;
3412     u_header_T	    *uhp;
3413     u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
3414 {
3415     u_entry_T	    *uep, *nuep;
3416 
3417     /* Check for pointers to the header that become invalid now. */
3418     if (buf->b_u_curhead == uhp)
3419 	buf->b_u_curhead = NULL;
3420     if (buf->b_u_newhead == uhp)
3421 	buf->b_u_newhead = NULL;  /* freeing the newest entry */
3422     if (uhpp != NULL && uhp == *uhpp)
3423 	*uhpp = NULL;
3424 
3425     for (uep = uhp->uh_entry; uep != NULL; uep = nuep)
3426     {
3427 	nuep = uep->ue_next;
3428 	u_freeentry(uep, uep->ue_size);
3429     }
3430 
3431 #ifdef U_DEBUG
3432     uhp->uh_magic = 0;
3433 #endif
3434     vim_free((char_u *)uhp);
3435     --buf->b_u_numhead;
3436 }
3437 
3438 /*
3439  * free entry 'uep' and 'n' lines in uep->ue_array[]
3440  */
3441     static void
3442 u_freeentry(uep, n)
3443     u_entry_T	*uep;
3444     long	    n;
3445 {
3446     while (n > 0)
3447 	vim_free(uep->ue_array[--n]);
3448     vim_free((char_u *)uep->ue_array);
3449 #ifdef U_DEBUG
3450     uep->ue_magic = 0;
3451 #endif
3452     vim_free((char_u *)uep);
3453 }
3454 
3455 /*
3456  * invalidate the undo buffer; called when storage has already been released
3457  */
3458     void
3459 u_clearall(buf)
3460     buf_T	*buf;
3461 {
3462     buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL;
3463     buf->b_u_synced = TRUE;
3464     buf->b_u_numhead = 0;
3465     buf->b_u_line_ptr = NULL;
3466     buf->b_u_line_lnum = 0;
3467 }
3468 
3469 /*
3470  * save the line "lnum" for the "U" command
3471  */
3472     void
3473 u_saveline(lnum)
3474     linenr_T lnum;
3475 {
3476     if (lnum == curbuf->b_u_line_lnum)	    /* line is already saved */
3477 	return;
3478     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) /* should never happen */
3479 	return;
3480     u_clearline();
3481     curbuf->b_u_line_lnum = lnum;
3482     if (curwin->w_cursor.lnum == lnum)
3483 	curbuf->b_u_line_colnr = curwin->w_cursor.col;
3484     else
3485 	curbuf->b_u_line_colnr = 0;
3486     if ((curbuf->b_u_line_ptr = u_save_line(lnum)) == NULL)
3487 	do_outofmem_msg((long_u)0);
3488 }
3489 
3490 /*
3491  * clear the line saved for the "U" command
3492  * (this is used externally for crossing a line while in insert mode)
3493  */
3494     void
3495 u_clearline()
3496 {
3497     if (curbuf->b_u_line_ptr != NULL)
3498     {
3499 	vim_free(curbuf->b_u_line_ptr);
3500 	curbuf->b_u_line_ptr = NULL;
3501 	curbuf->b_u_line_lnum = 0;
3502     }
3503 }
3504 
3505 /*
3506  * Implementation of the "U" command.
3507  * Differentiation from vi: "U" can be undone with the next "U".
3508  * We also allow the cursor to be in another line.
3509  * Careful: may trigger autocommands that reload the buffer.
3510  */
3511     void
3512 u_undoline()
3513 {
3514     colnr_T t;
3515     char_u  *oldp;
3516 
3517     if (undo_off)
3518 	return;
3519 
3520     if (curbuf->b_u_line_ptr == NULL
3521 			|| curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
3522     {
3523 	beep_flush();
3524 	return;
3525     }
3526 
3527     /* first save the line for the 'u' command */
3528     if (u_savecommon(curbuf->b_u_line_lnum - 1,
3529 		       curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
3530 	return;
3531     oldp = u_save_line(curbuf->b_u_line_lnum);
3532     if (oldp == NULL)
3533     {
3534 	do_outofmem_msg((long_u)0);
3535 	return;
3536     }
3537     ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
3538     changed_bytes(curbuf->b_u_line_lnum, 0);
3539     vim_free(curbuf->b_u_line_ptr);
3540     curbuf->b_u_line_ptr = oldp;
3541 
3542     t = curbuf->b_u_line_colnr;
3543     if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum)
3544 	curbuf->b_u_line_colnr = curwin->w_cursor.col;
3545     curwin->w_cursor.col = t;
3546     curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
3547     check_cursor_col();
3548 }
3549 
3550 /*
3551  * Free all allocated memory blocks for the buffer 'buf'.
3552  */
3553     void
3554 u_blockfree(buf)
3555     buf_T	*buf;
3556 {
3557     while (buf->b_u_oldhead != NULL)
3558 	u_freeheader(buf, buf->b_u_oldhead, NULL);
3559     vim_free(buf->b_u_line_ptr);
3560 }
3561 
3562 /*
3563  * u_save_line(): allocate memory and copy line 'lnum' into it.
3564  * Returns NULL when out of memory.
3565  */
3566     static char_u *
3567 u_save_line(lnum)
3568     linenr_T	lnum;
3569 {
3570     return vim_strsave(ml_get(lnum));
3571 }
3572 
3573 /*
3574  * Check if the 'modified' flag is set, or 'ff' has changed (only need to
3575  * check the first character, because it can only be "dos", "unix" or "mac").
3576  * "nofile" and "scratch" type buffers are considered to always be unchanged.
3577  */
3578     int
3579 bufIsChanged(buf)
3580     buf_T	*buf;
3581 {
3582     return
3583 #ifdef FEAT_QUICKFIX
3584 	    !bt_dontwrite(buf) &&
3585 #endif
3586 	    (buf->b_changed || file_ff_differs(buf, TRUE));
3587 }
3588 
3589     int
3590 curbufIsChanged()
3591 {
3592     return
3593 #ifdef FEAT_QUICKFIX
3594 	!bt_dontwrite(curbuf) &&
3595 #endif
3596 	(curbuf->b_changed || file_ff_differs(curbuf, TRUE));
3597 }
3598 
3599 #if defined(FEAT_EVAL) || defined(PROTO)
3600 /*
3601  * For undotree(): Append the list of undo blocks at "first_uhp" to "list".
3602  * Recursive.
3603  */
3604     void
3605 u_eval_tree(first_uhp, list)
3606     u_header_T  *first_uhp;
3607     list_T	*list;
3608 {
3609     u_header_T  *uhp = first_uhp;
3610     dict_T	*dict;
3611 
3612     while (uhp != NULL)
3613     {
3614 	dict = dict_alloc();
3615 	if (dict == NULL)
3616 	    return;
3617 	dict_add_nr_str(dict, "seq", uhp->uh_seq, NULL);
3618 	dict_add_nr_str(dict, "time", (long)uhp->uh_time, NULL);
3619 	if (uhp == curbuf->b_u_newhead)
3620 	    dict_add_nr_str(dict, "newhead", 1, NULL);
3621 	if (uhp == curbuf->b_u_curhead)
3622 	    dict_add_nr_str(dict, "curhead", 1, NULL);
3623 	if (uhp->uh_save_nr > 0)
3624 	    dict_add_nr_str(dict, "save", uhp->uh_save_nr, NULL);
3625 
3626 	if (uhp->uh_alt_next.ptr != NULL)
3627 	{
3628 	    list_T	*alt_list = list_alloc();
3629 
3630 	    if (alt_list != NULL)
3631 	    {
3632 		/* Recursive call to add alternate undo tree. */
3633 		u_eval_tree(uhp->uh_alt_next.ptr, alt_list);
3634 		dict_add_list(dict, "alt", alt_list);
3635 	    }
3636 	}
3637 
3638 	list_append_dict(list, dict);
3639 	uhp = uhp->uh_prev.ptr;
3640     }
3641 }
3642 #endif
3643