xref: /vim-8.2.3635/src/memline.c (revision 2bf24176)
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 /* for debugging */
11 /* #define CHECK(c, s)	if (c) EMSG(s) */
12 #define CHECK(c, s)
13 
14 /*
15  * memline.c: Contains the functions for appending, deleting and changing the
16  * text lines. The memfile functions are used to store the information in
17  * blocks of memory, backed up by a file. The structure of the information is
18  * a tree.  The root of the tree is a pointer block. The leaves of the tree
19  * are data blocks. In between may be several layers of pointer blocks,
20  * forming branches.
21  *
22  * Three types of blocks are used:
23  * - Block nr 0 contains information for recovery
24  * - Pointer blocks contain list of pointers to other blocks.
25  * - Data blocks contain the actual text.
26  *
27  * Block nr 0 contains the block0 structure (see below).
28  *
29  * Block nr 1 is the first pointer block. It is the root of the tree.
30  * Other pointer blocks are branches.
31  *
32  *  If a line is too big to fit in a single page, the block containing that
33  *  line is made big enough to hold the line. It may span several pages.
34  *  Otherwise all blocks are one page.
35  *
36  *  A data block that was filled when starting to edit a file and was not
37  *  changed since then, can have a negative block number. This means that it
38  *  has not yet been assigned a place in the file. When recovering, the lines
39  *  in this data block can be read from the original file. When the block is
40  *  changed (lines appended/deleted/changed) or when it is flushed it gets a
41  *  positive number. Use mf_trans_del() to get the new number, before calling
42  *  mf_get().
43  */
44 
45 #include "vim.h"
46 
47 #ifndef UNIX		/* it's in os_unix.h for Unix */
48 # include <time.h>
49 #endif
50 
51 #if defined(SASC) || defined(__amigaos4__)
52 # include <proto/dos.h>	    /* for Open() and Close() */
53 #endif
54 
55 typedef struct block0		ZERO_BL;    /* contents of the first block */
56 typedef struct pointer_block	PTR_BL;	    /* contents of a pointer block */
57 typedef struct data_block	DATA_BL;    /* contents of a data block */
58 typedef struct pointer_entry	PTR_EN;	    /* block/line-count pair */
59 
60 #define DATA_ID	       (('d' << 8) + 'a')   /* data block id */
61 #define PTR_ID	       (('p' << 8) + 't')   /* pointer block id */
62 #define BLOCK0_ID0     'b'		    /* block 0 id 0 */
63 #define BLOCK0_ID1     '0'		    /* block 0 id 1 */
64 #define BLOCK0_ID1_C0  'c'		    /* block 0 id 1 'cm' 0 */
65 #define BLOCK0_ID1_C1  'C'		    /* block 0 id 1 'cm' 1 */
66 #define BLOCK0_ID1_C2  'd'		    /* block 0 id 1 'cm' 2 */
67 
68 #if defined(FEAT_CRYPT)
69 static int id1_codes[] = {
70     BLOCK0_ID1_C0,  /* CRYPT_M_ZIP */
71     BLOCK0_ID1_C1,  /* CRYPT_M_BF */
72     BLOCK0_ID1_C2,  /* CRYPT_M_BF2 */
73 };
74 #endif
75 
76 /*
77  * pointer to a block, used in a pointer block
78  */
79 struct pointer_entry
80 {
81     blocknr_T	pe_bnum;	/* block number */
82     linenr_T	pe_line_count;	/* number of lines in this branch */
83     linenr_T	pe_old_lnum;	/* lnum for this block (for recovery) */
84     int		pe_page_count;	/* number of pages in block pe_bnum */
85 };
86 
87 /*
88  * A pointer block contains a list of branches in the tree.
89  */
90 struct pointer_block
91 {
92     short_u	pb_id;		/* ID for pointer block: PTR_ID */
93     short_u	pb_count;	/* number of pointers in this block */
94     short_u	pb_count_max;	/* maximum value for pb_count */
95     PTR_EN	pb_pointer[1];	/* list of pointers to blocks (actually longer)
96 				 * followed by empty space until end of page */
97 };
98 
99 /*
100  * A data block is a leaf in the tree.
101  *
102  * The text of the lines is at the end of the block. The text of the first line
103  * in the block is put at the end, the text of the second line in front of it,
104  * etc. Thus the order of the lines is the opposite of the line number.
105  */
106 struct data_block
107 {
108     short_u	db_id;		/* ID for data block: DATA_ID */
109     unsigned	db_free;	/* free space available */
110     unsigned	db_txt_start;	/* byte where text starts */
111     unsigned	db_txt_end;	/* byte just after data block */
112     linenr_T	db_line_count;	/* number of lines in this block */
113     unsigned	db_index[1];	/* index for start of line (actually bigger)
114 				 * followed by empty space upto db_txt_start
115 				 * followed by the text in the lines until
116 				 * end of page */
117 };
118 
119 /*
120  * The low bits of db_index hold the actual index. The topmost bit is
121  * used for the global command to be able to mark a line.
122  * This method is not clean, but otherwise there would be at least one extra
123  * byte used for each line.
124  * The mark has to be in this place to keep it with the correct line when other
125  * lines are inserted or deleted.
126  */
127 #define DB_MARKED	((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
128 #define DB_INDEX_MASK	(~DB_MARKED)
129 
130 #define INDEX_SIZE  (sizeof(unsigned))	    /* size of one db_index entry */
131 #define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE)  /* size of data block header */
132 
133 #define B0_FNAME_SIZE_ORG	900	/* what it was in older versions */
134 #define B0_FNAME_SIZE_NOCRYPT	898	/* 2 bytes used for other things */
135 #define B0_FNAME_SIZE_CRYPT	890	/* 10 bytes used for other things */
136 #define B0_UNAME_SIZE		40
137 #define B0_HNAME_SIZE		40
138 /*
139  * Restrict the numbers to 32 bits, otherwise most compilers will complain.
140  * This won't detect a 64 bit machine that only swaps a byte in the top 32
141  * bits, but that is crazy anyway.
142  */
143 #define B0_MAGIC_LONG	0x30313233L
144 #define B0_MAGIC_INT	0x20212223L
145 #define B0_MAGIC_SHORT	0x10111213L
146 #define B0_MAGIC_CHAR	0x55
147 
148 /*
149  * Block zero holds all info about the swap file.
150  *
151  * NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing
152  * swap files unusable!
153  *
154  * If size of block0 changes anyway, adjust MIN_SWAP_PAGE_SIZE in vim.h!!
155  *
156  * This block is built up of single bytes, to make it portable across
157  * different machines. b0_magic_* is used to check the byte order and size of
158  * variables, because the rest of the swap file is not portable.
159  */
160 struct block0
161 {
162     char_u	b0_id[2];	/* id for block 0: BLOCK0_ID0 and BLOCK0_ID1,
163 				 * BLOCK0_ID1_C0, BLOCK0_ID1_C1, etc. */
164     char_u	b0_version[10];	/* Vim version string */
165     char_u	b0_page_size[4];/* number of bytes per page */
166     char_u	b0_mtime[4];	/* last modification time of file */
167     char_u	b0_ino[4];	/* inode of b0_fname */
168     char_u	b0_pid[4];	/* process id of creator (or 0) */
169     char_u	b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */
170     char_u	b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */
171     char_u	b0_fname[B0_FNAME_SIZE_ORG]; /* name of file being edited */
172     long	b0_magic_long;	/* check for byte order of long */
173     int		b0_magic_int;	/* check for byte order of int */
174     short	b0_magic_short;	/* check for byte order of short */
175     char_u	b0_magic_char;	/* check for last char */
176 };
177 
178 /*
179  * Note: b0_dirty and b0_flags are put at the end of the file name.  For very
180  * long file names in older versions of Vim they are invalid.
181  * The 'fileencoding' comes before b0_flags, with a NUL in front.  But only
182  * when there is room, for very long file names it's omitted.
183  */
184 #define B0_DIRTY	0x55
185 #define b0_dirty	b0_fname[B0_FNAME_SIZE_ORG - 1]
186 
187 /*
188  * The b0_flags field is new in Vim 7.0.
189  */
190 #define b0_flags	b0_fname[B0_FNAME_SIZE_ORG - 2]
191 
192 /*
193  * Crypt seed goes here, 8 bytes.  New in Vim 7.3.
194  * Without encryption these bytes may be used for 'fenc'.
195  */
196 #define b0_seed		b0_fname[B0_FNAME_SIZE_ORG - 2 - MF_SEED_LEN]
197 
198 /* The lowest two bits contain the fileformat.  Zero means it's not set
199  * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
200  * EOL_MAC + 1. */
201 #define B0_FF_MASK	3
202 
203 /* Swap file is in directory of edited file.  Used to find the file from
204  * different mount points. */
205 #define B0_SAME_DIR	4
206 
207 /* The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
208  * When empty there is only the NUL. */
209 #define B0_HAS_FENC	8
210 
211 #define STACK_INCR	5	/* nr of entries added to ml_stack at a time */
212 
213 /*
214  * The line number where the first mark may be is remembered.
215  * If it is 0 there are no marks at all.
216  * (always used for the current buffer only, no buffer change possible while
217  * executing a global command).
218  */
219 static linenr_T	lowest_marked = 0;
220 
221 /*
222  * arguments for ml_find_line()
223  */
224 #define ML_DELETE	0x11	    /* delete line */
225 #define ML_INSERT	0x12	    /* insert line */
226 #define ML_FIND		0x13	    /* just find the line */
227 #define ML_FLUSH	0x02	    /* flush locked block */
228 #define ML_SIMPLE(x)	(x & 0x10)  /* DEL, INS or FIND */
229 
230 /* argument for ml_upd_block0() */
231 typedef enum {
232       UB_FNAME = 0	/* update timestamp and filename */
233     , UB_SAME_DIR       /* update the B0_SAME_DIR flag */
234     , UB_CRYPT		/* update crypt key */
235 } upd_block0_T;
236 
237 #ifdef FEAT_CRYPT
238 static void ml_set_mfp_crypt __ARGS((buf_T *buf));
239 static void ml_set_b0_crypt __ARGS((buf_T *buf, ZERO_BL *b0p));
240 #endif
241 static int ml_check_b0_id __ARGS((ZERO_BL *b0p));
242 static void ml_upd_block0 __ARGS((buf_T *buf, upd_block0_T what));
243 static void set_b0_fname __ARGS((ZERO_BL *, buf_T *buf));
244 static void set_b0_dir_flag __ARGS((ZERO_BL *b0p, buf_T *buf));
245 #ifdef FEAT_MBYTE
246 static void add_b0_fenc __ARGS((ZERO_BL *b0p, buf_T *buf));
247 #endif
248 static time_t swapfile_info __ARGS((char_u *));
249 static int recov_file_names __ARGS((char_u **, char_u *, int prepend_dot));
250 static int ml_append_int __ARGS((buf_T *, linenr_T, char_u *, colnr_T, int, int));
251 static int ml_delete_int __ARGS((buf_T *, linenr_T, int));
252 static char_u *findswapname __ARGS((buf_T *, char_u **, char_u *));
253 static void ml_flush_line __ARGS((buf_T *));
254 static bhdr_T *ml_new_data __ARGS((memfile_T *, int, int));
255 static bhdr_T *ml_new_ptr __ARGS((memfile_T *));
256 static bhdr_T *ml_find_line __ARGS((buf_T *, linenr_T, int));
257 static int ml_add_stack __ARGS((buf_T *));
258 static void ml_lineadd __ARGS((buf_T *, int));
259 static int b0_magic_wrong __ARGS((ZERO_BL *));
260 #ifdef CHECK_INODE
261 static int fnamecmp_ino __ARGS((char_u *, char_u *, long));
262 #endif
263 static void long_to_char __ARGS((long, char_u *));
264 static long char_to_long __ARGS((char_u *));
265 #if defined(UNIX) || defined(WIN3264)
266 static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name));
267 #endif
268 #ifdef FEAT_CRYPT
269 static cryptstate_T *ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading));
270 #endif
271 #ifdef FEAT_BYTEOFF
272 static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
273 #endif
274 
275 /*
276  * Open a new memline for "buf".
277  *
278  * Return FAIL for failure, OK otherwise.
279  */
280     int
281 ml_open(buf)
282     buf_T	*buf;
283 {
284     memfile_T	*mfp;
285     bhdr_T	*hp = NULL;
286     ZERO_BL	*b0p;
287     PTR_BL	*pp;
288     DATA_BL	*dp;
289 
290     /*
291      * init fields in memline struct
292      */
293     buf->b_ml.ml_stack_size = 0; /* no stack yet */
294     buf->b_ml.ml_stack = NULL;	/* no stack yet */
295     buf->b_ml.ml_stack_top = 0;	/* nothing in the stack */
296     buf->b_ml.ml_locked = NULL;	/* no cached block */
297     buf->b_ml.ml_line_lnum = 0;	/* no cached line */
298 #ifdef FEAT_BYTEOFF
299     buf->b_ml.ml_chunksize = NULL;
300 #endif
301 
302     if (cmdmod.noswapfile)
303 	buf->b_p_swf = FALSE;
304 
305     /*
306      * When 'updatecount' is non-zero swap file may be opened later.
307      */
308     if (p_uc && buf->b_p_swf)
309 	buf->b_may_swap = TRUE;
310     else
311 	buf->b_may_swap = FALSE;
312 
313     /*
314      * Open the memfile.  No swap file is created yet.
315      */
316     mfp = mf_open(NULL, 0);
317     if (mfp == NULL)
318 	goto error;
319 
320     buf->b_ml.ml_mfp = mfp;
321 #ifdef FEAT_CRYPT
322     mfp->mf_buffer = buf;
323 #endif
324     buf->b_ml.ml_flags = ML_EMPTY;
325     buf->b_ml.ml_line_count = 1;
326 #ifdef FEAT_LINEBREAK
327     curwin->w_nrwidth_line_count = 0;
328 #endif
329 
330 #if defined(MSDOS) && !defined(DJGPP)
331     /* for 16 bit MS-DOS create a swapfile now, because we run out of
332      * memory very quickly */
333     if (p_uc != 0)
334 	ml_open_file(buf);
335 #endif
336 
337 /*
338  * fill block0 struct and write page 0
339  */
340     if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
341 	goto error;
342     if (hp->bh_bnum != 0)
343     {
344 	EMSG(_("E298: Didn't get block nr 0?"));
345 	goto error;
346     }
347     b0p = (ZERO_BL *)(hp->bh_data);
348 
349     b0p->b0_id[0] = BLOCK0_ID0;
350     b0p->b0_id[1] = BLOCK0_ID1;
351     b0p->b0_magic_long = (long)B0_MAGIC_LONG;
352     b0p->b0_magic_int = (int)B0_MAGIC_INT;
353     b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
354     b0p->b0_magic_char = B0_MAGIC_CHAR;
355     STRNCPY(b0p->b0_version, "VIM ", 4);
356     STRNCPY(b0p->b0_version + 4, Version, 6);
357     long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
358 
359 #ifdef FEAT_SPELL
360     if (!buf->b_spell)
361 #endif
362     {
363 	b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
364 	b0p->b0_flags = get_fileformat(buf) + 1;
365 	set_b0_fname(b0p, buf);
366 	(void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE);
367 	b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
368 	mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE);
369 	b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
370 	long_to_char(mch_get_pid(), b0p->b0_pid);
371 #ifdef FEAT_CRYPT
372 	ml_set_b0_crypt(buf, b0p);
373 #endif
374     }
375 
376     /*
377      * Always sync block number 0 to disk, so we can check the file name in
378      * the swap file in findswapname(). Don't do this for a help files or
379      * a spell buffer though.
380      * Only works when there's a swapfile, otherwise it's done when the file
381      * is created.
382      */
383     mf_put(mfp, hp, TRUE, FALSE);
384     if (!buf->b_help && !B_SPELL(buf))
385 	(void)mf_sync(mfp, 0);
386 
387     /*
388      * Fill in root pointer block and write page 1.
389      */
390     if ((hp = ml_new_ptr(mfp)) == NULL)
391 	goto error;
392     if (hp->bh_bnum != 1)
393     {
394 	EMSG(_("E298: Didn't get block nr 1?"));
395 	goto error;
396     }
397     pp = (PTR_BL *)(hp->bh_data);
398     pp->pb_count = 1;
399     pp->pb_pointer[0].pe_bnum = 2;
400     pp->pb_pointer[0].pe_page_count = 1;
401     pp->pb_pointer[0].pe_old_lnum = 1;
402     pp->pb_pointer[0].pe_line_count = 1;    /* line count after insertion */
403     mf_put(mfp, hp, TRUE, FALSE);
404 
405     /*
406      * Allocate first data block and create an empty line 1.
407      */
408     if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL)
409 	goto error;
410     if (hp->bh_bnum != 2)
411     {
412 	EMSG(_("E298: Didn't get block nr 2?"));
413 	goto error;
414     }
415 
416     dp = (DATA_BL *)(hp->bh_data);
417     dp->db_index[0] = --dp->db_txt_start;	/* at end of block */
418     dp->db_free -= 1 + INDEX_SIZE;
419     dp->db_line_count = 1;
420     *((char_u *)dp + dp->db_txt_start) = NUL;	/* empty line */
421 
422     return OK;
423 
424 error:
425     if (mfp != NULL)
426     {
427 	if (hp)
428 	    mf_put(mfp, hp, FALSE, FALSE);
429 	mf_close(mfp, TRUE);	    /* will also free(mfp->mf_fname) */
430     }
431     buf->b_ml.ml_mfp = NULL;
432     return FAIL;
433 }
434 
435 #if defined(FEAT_CRYPT) || defined(PROTO)
436 /*
437  * Prepare encryption for "buf" for the current key and method.
438  */
439     static void
440 ml_set_mfp_crypt(buf)
441     buf_T	*buf;
442 {
443     if (*buf->b_p_key != NUL)
444     {
445 	int method_nr = crypt_get_method_nr(buf);
446 
447 	if (method_nr > CRYPT_M_ZIP)
448 	{
449 	    /* Generate a seed and store it in the memfile. */
450 	    sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
451 	}
452     }
453 }
454 
455 /*
456  * Prepare encryption for "buf" with block 0 "b0p".
457  */
458     static void
459 ml_set_b0_crypt(buf, b0p)
460     buf_T	*buf;
461     ZERO_BL	*b0p;
462 {
463     if (*buf->b_p_key == NUL)
464 	b0p->b0_id[1] = BLOCK0_ID1;
465     else
466     {
467 	int method_nr = crypt_get_method_nr(buf);
468 
469 	b0p->b0_id[1] = id1_codes[method_nr];
470 	if (method_nr > CRYPT_M_ZIP)
471 	{
472 	    /* Generate a seed and store it in block 0 and in the memfile. */
473 	    sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
474 	    mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
475 	}
476     }
477 }
478 
479 /*
480  * Called after the crypt key or 'cryptmethod' was changed for "buf".
481  * Will apply this to the swapfile.
482  * "old_key" is the previous key.  It is equal to buf->b_p_key when
483  * 'cryptmethod' is changed.
484  * "old_cm" is the previous 'cryptmethod'.  It is equal to the current
485  * 'cryptmethod' when 'key' is changed.
486  */
487     void
488 ml_set_crypt_key(buf, old_key, old_cm)
489     buf_T	*buf;
490     char_u	*old_key;
491     char_u	*old_cm;
492 {
493     memfile_T	*mfp = buf->b_ml.ml_mfp;
494     bhdr_T	*hp;
495     int		page_count;
496     int		idx;
497     long	error;
498     infoptr_T	*ip;
499     PTR_BL	*pp;
500     DATA_BL	*dp;
501     blocknr_T	bnum;
502     int		top;
503     int		old_method;
504 
505     if (mfp == NULL)
506 	return;  /* no memfile yet, nothing to do */
507     old_method = crypt_method_nr_from_name(old_cm);
508 
509     /* First make sure the swapfile is in a consistent state, using the old
510      * key and method. */
511     {
512 	char_u *new_key = buf->b_p_key;
513 	char_u *new_buf_cm = buf->b_p_cm;
514 
515 	buf->b_p_key = old_key;
516 	buf->b_p_cm = old_cm;
517 	ml_preserve(buf, FALSE);
518 	buf->b_p_key = new_key;
519 	buf->b_p_cm = new_buf_cm;
520     }
521 
522     /* Set the key, method and seed to be used for reading, these must be the
523      * old values. */
524     mfp->mf_old_key = old_key;
525     mfp->mf_old_cm = old_method;
526     if (old_method > 0 && *old_key != NUL)
527 	mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN);
528 
529     /* Update block 0 with the crypt flag and may set a new seed. */
530     ml_upd_block0(buf, UB_CRYPT);
531 
532     if (mfp->mf_infile_count > 2)
533     {
534 	/*
535 	 * Need to read back all data blocks from disk, decrypt them with the
536 	 * old key/method and mark them to be written. The algorithm is
537 	 * similar to what happens in ml_recover(), but we skip negative block
538 	 * numbers.
539 	 */
540 	ml_flush_line(buf);		    /* flush buffered line */
541 	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
542 
543 	hp = NULL;
544 	bnum = 1;		/* start with block 1 */
545 	page_count = 1;		/* which is 1 page */
546 	idx = 0;		/* start with first index in block 1 */
547 	error = 0;
548 	buf->b_ml.ml_stack_top = 0;
549 	vim_free(buf->b_ml.ml_stack);
550 	buf->b_ml.ml_stack = NULL;
551 	buf->b_ml.ml_stack_size = 0;	/* no stack yet */
552 
553 	for ( ; !got_int; line_breakcheck())
554 	{
555 	    if (hp != NULL)
556 		mf_put(mfp, hp, FALSE, FALSE);	/* release previous block */
557 
558 	    /* get the block (pointer or data) */
559 	    if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
560 	    {
561 		if (bnum == 1)
562 		    break;
563 		++error;
564 	    }
565 	    else
566 	    {
567 		pp = (PTR_BL *)(hp->bh_data);
568 		if (pp->pb_id == PTR_ID)	/* it is a pointer block */
569 		{
570 		    if (pp->pb_count == 0)
571 		    {
572 			/* empty block? */
573 			++error;
574 		    }
575 		    else if (idx < (int)pp->pb_count)	/* go a block deeper */
576 		    {
577 			if (pp->pb_pointer[idx].pe_bnum < 0)
578 			{
579 			    /* Skip data block with negative block number.
580 			     * Should not happen, because of the ml_preserve()
581 			     * above. Get same block again for next index. */
582 			    ++idx;
583 			    continue;
584 			}
585 
586 			/* going one block deeper in the tree, new entry in
587 			 * stack */
588 			if ((top = ml_add_stack(buf)) < 0)
589 			{
590 			    ++error;
591 			    break;		    /* out of memory */
592 			}
593 			ip = &(buf->b_ml.ml_stack[top]);
594 			ip->ip_bnum = bnum;
595 			ip->ip_index = idx;
596 
597 			bnum = pp->pb_pointer[idx].pe_bnum;
598 			page_count = pp->pb_pointer[idx].pe_page_count;
599 			idx = 0;
600 			continue;
601 		    }
602 		}
603 		else	    /* not a pointer block */
604 		{
605 		    dp = (DATA_BL *)(hp->bh_data);
606 		    if (dp->db_id != DATA_ID)	/* block id wrong */
607 			++error;
608 		    else
609 		    {
610 			/* It is a data block, need to write it back to disk. */
611 			mf_put(mfp, hp, TRUE, FALSE);
612 			hp = NULL;
613 		    }
614 		}
615 	    }
616 
617 	    if (buf->b_ml.ml_stack_top == 0)	/* finished */
618 		break;
619 
620 	    /* go one block up in the tree */
621 	    ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
622 	    bnum = ip->ip_bnum;
623 	    idx = ip->ip_index + 1;	    /* go to next index */
624 	    page_count = 1;
625 	}
626 	if (hp != NULL)
627 	    mf_put(mfp, hp, FALSE, FALSE);  /* release previous block */
628 
629 	if (error > 0)
630 	    EMSG(_("E843: Error while updating swap file crypt"));
631     }
632 
633     mfp->mf_old_key = NULL;
634 }
635 #endif
636 
637 /*
638  * ml_setname() is called when the file name of "buf" has been changed.
639  * It may rename the swap file.
640  */
641     void
642 ml_setname(buf)
643     buf_T	*buf;
644 {
645     int		success = FALSE;
646     memfile_T	*mfp;
647     char_u	*fname;
648     char_u	*dirp;
649 #if defined(MSDOS) || defined(MSWIN)
650     char_u	*p;
651 #endif
652 
653     mfp = buf->b_ml.ml_mfp;
654     if (mfp->mf_fd < 0)		    /* there is no swap file yet */
655     {
656 	/*
657 	 * When 'updatecount' is 0 and 'noswapfile' there is no swap file.
658 	 * For help files we will make a swap file now.
659 	 */
660 	if (p_uc != 0 && !cmdmod.noswapfile)
661 	    ml_open_file(buf);	    /* create a swap file */
662 	return;
663     }
664 
665     /*
666      * Try all directories in the 'directory' option.
667      */
668     dirp = p_dir;
669     for (;;)
670     {
671 	if (*dirp == NUL)	    /* tried all directories, fail */
672 	    break;
673 	fname = findswapname(buf, &dirp, mfp->mf_fname);
674 						    /* alloc's fname */
675 	if (dirp == NULL)	    /* out of memory */
676 	    break;
677 	if (fname == NULL)	    /* no file name found for this dir */
678 	    continue;
679 
680 #if defined(MSDOS) || defined(MSWIN)
681 	/*
682 	 * Set full pathname for swap file now, because a ":!cd dir" may
683 	 * change directory without us knowing it.
684 	 */
685 	p = FullName_save(fname, FALSE);
686 	vim_free(fname);
687 	fname = p;
688 	if (fname == NULL)
689 	    continue;
690 #endif
691 	/* if the file name is the same we don't have to do anything */
692 	if (fnamecmp(fname, mfp->mf_fname) == 0)
693 	{
694 	    vim_free(fname);
695 	    success = TRUE;
696 	    break;
697 	}
698 	/* need to close the swap file before renaming */
699 	if (mfp->mf_fd >= 0)
700 	{
701 	    close(mfp->mf_fd);
702 	    mfp->mf_fd = -1;
703 	}
704 
705 	/* try to rename the swap file */
706 	if (vim_rename(mfp->mf_fname, fname) == 0)
707 	{
708 	    success = TRUE;
709 	    vim_free(mfp->mf_fname);
710 	    mfp->mf_fname = fname;
711 	    vim_free(mfp->mf_ffname);
712 #if defined(MSDOS) || defined(MSWIN)
713 	    mfp->mf_ffname = NULL;  /* mf_fname is full pathname already */
714 #else
715 	    mf_set_ffname(mfp);
716 #endif
717 	    ml_upd_block0(buf, UB_SAME_DIR);
718 	    break;
719 	}
720 	vim_free(fname);	    /* this fname didn't work, try another */
721     }
722 
723     if (mfp->mf_fd == -1)	    /* need to (re)open the swap file */
724     {
725 	mfp->mf_fd = mch_open((char *)mfp->mf_fname, O_RDWR | O_EXTRA, 0);
726 	if (mfp->mf_fd < 0)
727 	{
728 	    /* could not (re)open the swap file, what can we do???? */
729 	    EMSG(_("E301: Oops, lost the swap file!!!"));
730 	    return;
731 	}
732 #ifdef HAVE_FD_CLOEXEC
733 	{
734 	    int fdflags = fcntl(mfp->mf_fd, F_GETFD);
735 	    if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
736 		fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
737 	}
738 #endif
739     }
740     if (!success)
741 	EMSG(_("E302: Could not rename swap file"));
742 }
743 
744 /*
745  * Open a file for the memfile for all buffers that are not readonly or have
746  * been modified.
747  * Used when 'updatecount' changes from zero to non-zero.
748  */
749     void
750 ml_open_files()
751 {
752     buf_T	*buf;
753 
754     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
755 	if (!buf->b_p_ro || buf->b_changed)
756 	    ml_open_file(buf);
757 }
758 
759 /*
760  * Open a swap file for an existing memfile, if there is no swap file yet.
761  * If we are unable to find a file name, mf_fname will be NULL
762  * and the memfile will be in memory only (no recovery possible).
763  */
764     void
765 ml_open_file(buf)
766     buf_T	*buf;
767 {
768     memfile_T	*mfp;
769     char_u	*fname;
770     char_u	*dirp;
771 
772     mfp = buf->b_ml.ml_mfp;
773     if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf || cmdmod.noswapfile)
774 	return;		/* nothing to do */
775 
776 #ifdef FEAT_SPELL
777     /* For a spell buffer use a temp file name. */
778     if (buf->b_spell)
779     {
780 	fname = vim_tempname('s', FALSE);
781 	if (fname != NULL)
782 	    (void)mf_open_file(mfp, fname);	/* consumes fname! */
783 	buf->b_may_swap = FALSE;
784 	return;
785     }
786 #endif
787 
788     /*
789      * Try all directories in 'directory' option.
790      */
791     dirp = p_dir;
792     for (;;)
793     {
794 	if (*dirp == NUL)
795 	    break;
796 	/* There is a small chance that between choosing the swap file name
797 	 * and creating it, another Vim creates the file.  In that case the
798 	 * creation will fail and we will use another directory. */
799 	fname = findswapname(buf, &dirp, NULL); /* allocates fname */
800 	if (dirp == NULL)
801 	    break;  /* out of memory */
802 	if (fname == NULL)
803 	    continue;
804 	if (mf_open_file(mfp, fname) == OK)	/* consumes fname! */
805 	{
806 #if defined(MSDOS) || defined(MSWIN)
807 	    /*
808 	     * set full pathname for swap file now, because a ":!cd dir" may
809 	     * change directory without us knowing it.
810 	     */
811 	    mf_fullname(mfp);
812 #endif
813 	    ml_upd_block0(buf, UB_SAME_DIR);
814 
815 	    /* Flush block zero, so others can read it */
816 	    if (mf_sync(mfp, MFS_ZERO) == OK)
817 	    {
818 		/* Mark all blocks that should be in the swapfile as dirty.
819 		 * Needed for when the 'swapfile' option was reset, so that
820 		 * the swap file was deleted, and then on again. */
821 		mf_set_dirty(mfp);
822 		break;
823 	    }
824 	    /* Writing block 0 failed: close the file and try another dir */
825 	    mf_close_file(buf, FALSE);
826 	}
827     }
828 
829     if (mfp->mf_fname == NULL)		/* Failed! */
830     {
831 	need_wait_return = TRUE;	/* call wait_return later */
832 	++no_wait_return;
833 	(void)EMSG2(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
834 		    buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
835 	--no_wait_return;
836     }
837 
838     /* don't try to open a swap file again */
839     buf->b_may_swap = FALSE;
840 }
841 
842 /*
843  * If still need to create a swap file, and starting to edit a not-readonly
844  * file, or reading into an existing buffer, create a swap file now.
845  */
846     void
847 check_need_swap(newfile)
848     int	    newfile;		/* reading file into new buffer */
849 {
850     if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
851 	ml_open_file(curbuf);
852 }
853 
854 /*
855  * Close memline for buffer 'buf'.
856  * If 'del_file' is TRUE, delete the swap file
857  */
858     void
859 ml_close(buf, del_file)
860     buf_T	*buf;
861     int		del_file;
862 {
863     if (buf->b_ml.ml_mfp == NULL)		/* not open */
864 	return;
865     mf_close(buf->b_ml.ml_mfp, del_file);	/* close the .swp file */
866     if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
867 	vim_free(buf->b_ml.ml_line_ptr);
868     vim_free(buf->b_ml.ml_stack);
869 #ifdef FEAT_BYTEOFF
870     vim_free(buf->b_ml.ml_chunksize);
871     buf->b_ml.ml_chunksize = NULL;
872 #endif
873     buf->b_ml.ml_mfp = NULL;
874 
875     /* Reset the "recovered" flag, give the ATTENTION prompt the next time
876      * this buffer is loaded. */
877     buf->b_flags &= ~BF_RECOVERED;
878 }
879 
880 /*
881  * Close all existing memlines and memfiles.
882  * Only used when exiting.
883  * When 'del_file' is TRUE, delete the memfiles.
884  * But don't delete files that were ":preserve"d when we are POSIX compatible.
885  */
886     void
887 ml_close_all(del_file)
888     int		del_file;
889 {
890     buf_T	*buf;
891 
892     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
893 	ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0
894 				 || vim_strchr(p_cpo, CPO_PRESERVE) == NULL));
895 #ifdef FEAT_SPELL
896     spell_delete_wordlist();	/* delete the internal wordlist */
897 #endif
898 #ifdef TEMPDIRNAMES
899     vim_deltempdir();		/* delete created temp directory */
900 #endif
901 }
902 
903 /*
904  * Close all memfiles for not modified buffers.
905  * Only use just before exiting!
906  */
907     void
908 ml_close_notmod()
909 {
910     buf_T	*buf;
911 
912     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
913 	if (!bufIsChanged(buf))
914 	    ml_close(buf, TRUE);    /* close all not-modified buffers */
915 }
916 
917 /*
918  * Update the timestamp in the .swp file.
919  * Used when the file has been written.
920  */
921     void
922 ml_timestamp(buf)
923     buf_T	*buf;
924 {
925     ml_upd_block0(buf, UB_FNAME);
926 }
927 
928 /*
929  * Return FAIL when the ID of "b0p" is wrong.
930  */
931     static int
932 ml_check_b0_id(b0p)
933     ZERO_BL	*b0p;
934 {
935     if (b0p->b0_id[0] != BLOCK0_ID0
936 	    || (b0p->b0_id[1] != BLOCK0_ID1
937 		&& b0p->b0_id[1] != BLOCK0_ID1_C0
938 		&& b0p->b0_id[1] != BLOCK0_ID1_C1
939 		&& b0p->b0_id[1] != BLOCK0_ID1_C2)
940 	    )
941 	return FAIL;
942     return OK;
943 }
944 
945 /*
946  * Update the timestamp or the B0_SAME_DIR flag of the .swp file.
947  */
948     static void
949 ml_upd_block0(buf, what)
950     buf_T	*buf;
951     upd_block0_T what;
952 {
953     memfile_T	*mfp;
954     bhdr_T	*hp;
955     ZERO_BL	*b0p;
956 
957     mfp = buf->b_ml.ml_mfp;
958     if (mfp == NULL)
959 	return;
960     hp = mf_get(mfp, (blocknr_T)0, 1);
961     if (hp == NULL)
962     {
963 #ifdef FEAT_CRYPT
964 	/* Possibly update the seed in the memfile before there is a block0. */
965 	if (what == UB_CRYPT)
966 	    ml_set_mfp_crypt(buf);
967 #endif
968 	return;
969     }
970 
971     b0p = (ZERO_BL *)(hp->bh_data);
972     if (ml_check_b0_id(b0p) == FAIL)
973 	EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
974     else
975     {
976 	if (what == UB_FNAME)
977 	    set_b0_fname(b0p, buf);
978 #ifdef FEAT_CRYPT
979 	else if (what == UB_CRYPT)
980 	    ml_set_b0_crypt(buf, b0p);
981 #endif
982 	else /* what == UB_SAME_DIR */
983 	    set_b0_dir_flag(b0p, buf);
984     }
985     mf_put(mfp, hp, TRUE, FALSE);
986 }
987 
988 /*
989  * Write file name and timestamp into block 0 of a swap file.
990  * Also set buf->b_mtime.
991  * Don't use NameBuff[]!!!
992  */
993     static void
994 set_b0_fname(b0p, buf)
995     ZERO_BL	*b0p;
996     buf_T	*buf;
997 {
998     struct stat	st;
999 
1000     if (buf->b_ffname == NULL)
1001 	b0p->b0_fname[0] = NUL;
1002     else
1003     {
1004 #if defined(MSDOS) || defined(MSWIN) || defined(AMIGA)
1005 	/* Systems that cannot translate "~user" back into a path: copy the
1006 	 * file name unmodified.  Do use slashes instead of backslashes for
1007 	 * portability. */
1008 	vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT - 1);
1009 # ifdef BACKSLASH_IN_FILENAME
1010 	forward_slash(b0p->b0_fname);
1011 # endif
1012 #else
1013 	size_t	flen, ulen;
1014 	char_u	uname[B0_UNAME_SIZE];
1015 
1016 	/*
1017 	 * For a file under the home directory of the current user, we try to
1018 	 * replace the home directory path with "~user". This helps when
1019 	 * editing the same file on different machines over a network.
1020 	 * First replace home dir path with "~/" with home_replace().
1021 	 * Then insert the user name to get "~user/".
1022 	 */
1023 	home_replace(NULL, buf->b_ffname, b0p->b0_fname,
1024 						   B0_FNAME_SIZE_CRYPT, TRUE);
1025 	if (b0p->b0_fname[0] == '~')
1026 	{
1027 	    flen = STRLEN(b0p->b0_fname);
1028 	    /* If there is no user name or it is too long, don't use "~/" */
1029 	    if (get_user_name(uname, B0_UNAME_SIZE) == FAIL
1030 		   || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1)
1031 		vim_strncpy(b0p->b0_fname, buf->b_ffname,
1032 						     B0_FNAME_SIZE_CRYPT - 1);
1033 	    else
1034 	    {
1035 		mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
1036 		mch_memmove(b0p->b0_fname + 1, uname, ulen);
1037 	    }
1038 	}
1039 #endif
1040 	if (mch_stat((char *)buf->b_ffname, &st) >= 0)
1041 	{
1042 	    long_to_char((long)st.st_mtime, b0p->b0_mtime);
1043 #ifdef CHECK_INODE
1044 	    long_to_char((long)st.st_ino, b0p->b0_ino);
1045 #endif
1046 	    buf_store_time(buf, &st, buf->b_ffname);
1047 	    buf->b_mtime_read = buf->b_mtime;
1048 	}
1049 	else
1050 	{
1051 	    long_to_char(0L, b0p->b0_mtime);
1052 #ifdef CHECK_INODE
1053 	    long_to_char(0L, b0p->b0_ino);
1054 #endif
1055 	    buf->b_mtime = 0;
1056 	    buf->b_mtime_read = 0;
1057 	    buf->b_orig_size = 0;
1058 	    buf->b_orig_mode = 0;
1059 	}
1060     }
1061 
1062 #ifdef FEAT_MBYTE
1063     /* Also add the 'fileencoding' if there is room. */
1064     add_b0_fenc(b0p, curbuf);
1065 #endif
1066 }
1067 
1068 /*
1069  * Update the B0_SAME_DIR flag of the swap file.  It's set if the file and the
1070  * swapfile for "buf" are in the same directory.
1071  * This is fail safe: if we are not sure the directories are equal the flag is
1072  * not set.
1073  */
1074     static void
1075 set_b0_dir_flag(b0p, buf)
1076     ZERO_BL	*b0p;
1077     buf_T	*buf;
1078 {
1079     if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
1080 	b0p->b0_flags |= B0_SAME_DIR;
1081     else
1082 	b0p->b0_flags &= ~B0_SAME_DIR;
1083 }
1084 
1085 #ifdef FEAT_MBYTE
1086 /*
1087  * When there is room, add the 'fileencoding' to block zero.
1088  */
1089     static void
1090 add_b0_fenc(b0p, buf)
1091     ZERO_BL	*b0p;
1092     buf_T	*buf;
1093 {
1094     int		n;
1095     int		size = B0_FNAME_SIZE_NOCRYPT;
1096 
1097 # ifdef FEAT_CRYPT
1098     /* Without encryption use the same offset as in Vim 7.2 to be compatible.
1099      * With encryption it's OK to move elsewhere, the swap file is not
1100      * compatible anyway. */
1101     if (*buf->b_p_key != NUL)
1102 	size = B0_FNAME_SIZE_CRYPT;
1103 # endif
1104 
1105     n = (int)STRLEN(buf->b_p_fenc);
1106     if ((int)STRLEN(b0p->b0_fname) + n + 1 > size)
1107 	b0p->b0_flags &= ~B0_HAS_FENC;
1108     else
1109     {
1110 	mch_memmove((char *)b0p->b0_fname + size - n,
1111 					    (char *)buf->b_p_fenc, (size_t)n);
1112 	*(b0p->b0_fname + size - n - 1) = NUL;
1113 	b0p->b0_flags |= B0_HAS_FENC;
1114     }
1115 }
1116 #endif
1117 
1118 
1119 /*
1120  * Try to recover curbuf from the .swp file.
1121  */
1122     void
1123 ml_recover()
1124 {
1125     buf_T	*buf = NULL;
1126     memfile_T	*mfp = NULL;
1127     char_u	*fname;
1128     char_u	*fname_used = NULL;
1129     bhdr_T	*hp = NULL;
1130     ZERO_BL	*b0p;
1131     int		b0_ff;
1132     char_u	*b0_fenc = NULL;
1133 #ifdef FEAT_CRYPT
1134     int		b0_cm = -1;
1135 #endif
1136     PTR_BL	*pp;
1137     DATA_BL	*dp;
1138     infoptr_T	*ip;
1139     blocknr_T	bnum;
1140     int		page_count;
1141     struct stat	org_stat, swp_stat;
1142     int		len;
1143     int		directly;
1144     linenr_T	lnum;
1145     char_u	*p;
1146     int		i;
1147     long	error;
1148     int		cannot_open;
1149     linenr_T	line_count;
1150     int		has_error;
1151     int		idx;
1152     int		top;
1153     int		txt_start;
1154     off_t	size;
1155     int		called_from_main;
1156     int		serious_error = TRUE;
1157     long	mtime;
1158     int		attr;
1159     int		orig_file_status = NOTDONE;
1160 
1161     recoverymode = TRUE;
1162     called_from_main = (curbuf->b_ml.ml_mfp == NULL);
1163     attr = hl_attr(HLF_E);
1164 
1165     /*
1166      * If the file name ends in ".s[uvw][a-z]" we assume this is the swap file.
1167      * Otherwise a search is done to find the swap file(s).
1168      */
1169     fname = curbuf->b_fname;
1170     if (fname == NULL)		    /* When there is no file name */
1171 	fname = (char_u *)"";
1172     len = (int)STRLEN(fname);
1173     if (len >= 4 &&
1174 #if defined(VMS)
1175 	    STRNICMP(fname + len - 4, "_s" , 2)
1176 #else
1177 	    STRNICMP(fname + len - 4, ".s" , 2)
1178 #endif
1179 		== 0
1180 		&& vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
1181 		&& ASCII_ISALPHA(fname[len - 1]))
1182     {
1183 	directly = TRUE;
1184 	fname_used = vim_strsave(fname); /* make a copy for mf_open() */
1185     }
1186     else
1187     {
1188 	directly = FALSE;
1189 
1190 	/* count the number of matching swap files */
1191 	len = recover_names(fname, FALSE, 0, NULL);
1192 	if (len == 0)		    /* no swap files found */
1193 	{
1194 	    EMSG2(_("E305: No swap file found for %s"), fname);
1195 	    goto theend;
1196 	}
1197 	if (len == 1)		    /* one swap file found, use it */
1198 	    i = 1;
1199 	else			    /* several swap files found, choose */
1200 	{
1201 	    /* list the names of the swap files */
1202 	    (void)recover_names(fname, TRUE, 0, NULL);
1203 	    msg_putchar('\n');
1204 	    MSG_PUTS(_("Enter number of swap file to use (0 to quit): "));
1205 	    i = get_number(FALSE, NULL);
1206 	    if (i < 1 || i > len)
1207 		goto theend;
1208 	}
1209 	/* get the swap file name that will be used */
1210 	(void)recover_names(fname, FALSE, i, &fname_used);
1211     }
1212     if (fname_used == NULL)
1213 	goto theend;			/* out of memory */
1214 
1215     /* When called from main() still need to initialize storage structure */
1216     if (called_from_main && ml_open(curbuf) == FAIL)
1217 	getout(1);
1218 
1219     /*
1220      * Allocate a buffer structure for the swap file that is used for recovery.
1221      * Only the memline and crypt information in it are really used.
1222      */
1223     buf = (buf_T *)alloc((unsigned)sizeof(buf_T));
1224     if (buf == NULL)
1225 	goto theend;
1226 
1227     /*
1228      * init fields in memline struct
1229      */
1230     buf->b_ml.ml_stack_size = 0;	/* no stack yet */
1231     buf->b_ml.ml_stack = NULL;		/* no stack yet */
1232     buf->b_ml.ml_stack_top = 0;		/* nothing in the stack */
1233     buf->b_ml.ml_line_lnum = 0;		/* no cached line */
1234     buf->b_ml.ml_locked = NULL;		/* no locked block */
1235     buf->b_ml.ml_flags = 0;
1236 #ifdef FEAT_CRYPT
1237     buf->b_p_key = empty_option;
1238     buf->b_p_cm = empty_option;
1239 #endif
1240 
1241     /*
1242      * open the memfile from the old swap file
1243      */
1244     p = vim_strsave(fname_used); /* save "fname_used" for the message:
1245 				    mf_open() will consume "fname_used"! */
1246     mfp = mf_open(fname_used, O_RDONLY);
1247     fname_used = p;
1248     if (mfp == NULL || mfp->mf_fd < 0)
1249     {
1250 	if (fname_used != NULL)
1251 	    EMSG2(_("E306: Cannot open %s"), fname_used);
1252 	goto theend;
1253     }
1254     buf->b_ml.ml_mfp = mfp;
1255 #ifdef FEAT_CRYPT
1256     mfp->mf_buffer = buf;
1257 #endif
1258 
1259     /*
1260      * The page size set in mf_open() might be different from the page size
1261      * used in the swap file, we must get it from block 0.  But to read block
1262      * 0 we need a page size.  Use the minimal size for block 0 here, it will
1263      * be set to the real value below.
1264      */
1265     mfp->mf_page_size = MIN_SWAP_PAGE_SIZE;
1266 
1267     /*
1268      * try to read block 0
1269      */
1270     if ((hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
1271     {
1272 	msg_start();
1273 	MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST);
1274 	msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
1275 	MSG_PUTS_ATTR(_("\nMaybe no changes were made or Vim did not update the swap file."),
1276 		attr | MSG_HIST);
1277 	msg_end();
1278 	goto theend;
1279     }
1280     b0p = (ZERO_BL *)(hp->bh_data);
1281     if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0)
1282     {
1283 	msg_start();
1284 	msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
1285 	MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
1286 								    MSG_HIST);
1287 	MSG_PUTS_ATTR(_("Use Vim version 3.0.\n"), MSG_HIST);
1288 	msg_end();
1289 	goto theend;
1290     }
1291     if (ml_check_b0_id(b0p) == FAIL)
1292     {
1293 	EMSG2(_("E307: %s does not look like a Vim swap file"), mfp->mf_fname);
1294 	goto theend;
1295     }
1296     if (b0_magic_wrong(b0p))
1297     {
1298 	msg_start();
1299 	msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
1300 #if defined(MSDOS) || defined(MSWIN)
1301 	if (STRNCMP(b0p->b0_hname, "PC ", 3) == 0)
1302 	    MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
1303 							     attr | MSG_HIST);
1304 	else
1305 #endif
1306 	    MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"),
1307 							     attr | MSG_HIST);
1308 	MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST);
1309 	/* avoid going past the end of a corrupted hostname */
1310 	b0p->b0_fname[0] = NUL;
1311 	MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST);
1312 	MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST);
1313 	msg_end();
1314 	goto theend;
1315     }
1316 
1317 #ifdef FEAT_CRYPT
1318     for (i = 0; i < (int)(sizeof(id1_codes) / sizeof(int)); ++i)
1319 	if (id1_codes[i] == b0p->b0_id[1])
1320 	    b0_cm = i;
1321     if (b0_cm > 0)
1322 	mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
1323     crypt_set_cm_option(buf, b0_cm < 0 ? 0 : b0_cm);
1324 #else
1325     if (b0p->b0_id[1] != BLOCK0_ID1)
1326     {
1327 	EMSG2(_("E833: %s is encrypted and this version of Vim does not support encryption"), mfp->mf_fname);
1328 	goto theend;
1329     }
1330 #endif
1331 
1332     /*
1333      * If we guessed the wrong page size, we have to recalculate the
1334      * highest block number in the file.
1335      */
1336     if (mfp->mf_page_size != (unsigned)char_to_long(b0p->b0_page_size))
1337     {
1338 	unsigned previous_page_size = mfp->mf_page_size;
1339 
1340 	mf_new_page_size(mfp, (unsigned)char_to_long(b0p->b0_page_size));
1341 	if (mfp->mf_page_size < previous_page_size)
1342 	{
1343 	    msg_start();
1344 	    msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
1345 	    MSG_PUTS_ATTR(_(" has been damaged (page size is smaller than minimum value).\n"),
1346 			attr | MSG_HIST);
1347 	    msg_end();
1348 	    goto theend;
1349 	}
1350 	if ((size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
1351 	    mfp->mf_blocknr_max = 0;	    /* no file or empty file */
1352 	else
1353 	    mfp->mf_blocknr_max = (blocknr_T)(size / mfp->mf_page_size);
1354 	mfp->mf_infile_count = mfp->mf_blocknr_max;
1355 
1356 	/* need to reallocate the memory used to store the data */
1357 	p = alloc(mfp->mf_page_size);
1358 	if (p == NULL)
1359 	    goto theend;
1360 	mch_memmove(p, hp->bh_data, previous_page_size);
1361 	vim_free(hp->bh_data);
1362 	hp->bh_data = p;
1363 	b0p = (ZERO_BL *)(hp->bh_data);
1364     }
1365 
1366     /*
1367      * If .swp file name given directly, use name from swap file for buffer.
1368      */
1369     if (directly)
1370     {
1371 	expand_env(b0p->b0_fname, NameBuff, MAXPATHL);
1372 	if (setfname(curbuf, NameBuff, NULL, TRUE) == FAIL)
1373 	    goto theend;
1374     }
1375 
1376     home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
1377     smsg((char_u *)_("Using swap file \"%s\""), NameBuff);
1378 
1379     if (buf_spname(curbuf) != NULL)
1380 	vim_strncpy(NameBuff, buf_spname(curbuf), MAXPATHL - 1);
1381     else
1382 	home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
1383     smsg((char_u *)_("Original file \"%s\""), NameBuff);
1384     msg_putchar('\n');
1385 
1386     /*
1387      * check date of swap file and original file
1388      */
1389     mtime = char_to_long(b0p->b0_mtime);
1390     if (curbuf->b_ffname != NULL
1391 	    && mch_stat((char *)curbuf->b_ffname, &org_stat) != -1
1392 	    && ((mch_stat((char *)mfp->mf_fname, &swp_stat) != -1
1393 		    && org_stat.st_mtime > swp_stat.st_mtime)
1394 		|| org_stat.st_mtime != mtime))
1395     {
1396 	EMSG(_("E308: Warning: Original file may have been changed"));
1397     }
1398     out_flush();
1399 
1400     /* Get the 'fileformat' and 'fileencoding' from block zero. */
1401     b0_ff = (b0p->b0_flags & B0_FF_MASK);
1402     if (b0p->b0_flags & B0_HAS_FENC)
1403     {
1404 	int fnsize = B0_FNAME_SIZE_NOCRYPT;
1405 
1406 #ifdef FEAT_CRYPT
1407 	/* Use the same size as in add_b0_fenc(). */
1408 	if (b0p->b0_id[1] != BLOCK0_ID1)
1409 	    fnsize = B0_FNAME_SIZE_CRYPT;
1410 #endif
1411 	for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; --p)
1412 	    ;
1413 	b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + fnsize - p));
1414     }
1415 
1416     mf_put(mfp, hp, FALSE, FALSE);	/* release block 0 */
1417     hp = NULL;
1418 
1419     /*
1420      * Now that we are sure that the file is going to be recovered, clear the
1421      * contents of the current buffer.
1422      */
1423     while (!(curbuf->b_ml.ml_flags & ML_EMPTY))
1424 	ml_delete((linenr_T)1, FALSE);
1425 
1426     /*
1427      * Try reading the original file to obtain the values of 'fileformat',
1428      * 'fileencoding', etc.  Ignore errors.  The text itself is not used.
1429      * When the file is encrypted the user is asked to enter the key.
1430      */
1431     if (curbuf->b_ffname != NULL)
1432 	orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0,
1433 			      (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);
1434 
1435 #ifdef FEAT_CRYPT
1436     if (b0_cm >= 0)
1437     {
1438 	/* Need to ask the user for the crypt key.  If this fails we continue
1439 	 * without a key, will probably get garbage text. */
1440 	if (*curbuf->b_p_key != NUL)
1441 	{
1442 	    smsg((char_u *)_("Swap file is encrypted: \"%s\""), fname_used);
1443 	    MSG_PUTS(_("\nIf you entered a new crypt key but did not write the text file,"));
1444 	    MSG_PUTS(_("\nenter the new crypt key."));
1445 	    MSG_PUTS(_("\nIf you wrote the text file after changing the crypt key press enter"));
1446 	    MSG_PUTS(_("\nto use the same key for text file and swap file"));
1447 	}
1448 	else
1449 	    smsg((char_u *)_(need_key_msg), fname_used);
1450 	buf->b_p_key = crypt_get_key(FALSE, FALSE);
1451 	if (buf->b_p_key == NULL)
1452 	    buf->b_p_key = curbuf->b_p_key;
1453 	else if (*buf->b_p_key == NUL)
1454 	{
1455 	    vim_free(buf->b_p_key);
1456 	    buf->b_p_key = curbuf->b_p_key;
1457 	}
1458 	if (buf->b_p_key == NULL)
1459 	    buf->b_p_key = empty_option;
1460     }
1461 #endif
1462 
1463     /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */
1464     if (b0_ff != 0)
1465 	set_fileformat(b0_ff - 1, OPT_LOCAL);
1466     if (b0_fenc != NULL)
1467     {
1468 	set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL);
1469 	vim_free(b0_fenc);
1470     }
1471     unchanged(curbuf, TRUE);
1472 
1473     bnum = 1;		/* start with block 1 */
1474     page_count = 1;	/* which is 1 page */
1475     lnum = 0;		/* append after line 0 in curbuf */
1476     line_count = 0;
1477     idx = 0;		/* start with first index in block 1 */
1478     error = 0;
1479     buf->b_ml.ml_stack_top = 0;
1480     buf->b_ml.ml_stack = NULL;
1481     buf->b_ml.ml_stack_size = 0;	/* no stack yet */
1482 
1483     if (curbuf->b_ffname == NULL)
1484 	cannot_open = TRUE;
1485     else
1486 	cannot_open = FALSE;
1487 
1488     serious_error = FALSE;
1489     for ( ; !got_int; line_breakcheck())
1490     {
1491 	if (hp != NULL)
1492 	    mf_put(mfp, hp, FALSE, FALSE);	/* release previous block */
1493 
1494 	/*
1495 	 * get block
1496 	 */
1497 	if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
1498 	{
1499 	    if (bnum == 1)
1500 	    {
1501 		EMSG2(_("E309: Unable to read block 1 from %s"), mfp->mf_fname);
1502 		goto theend;
1503 	    }
1504 	    ++error;
1505 	    ml_append(lnum++, (char_u *)_("???MANY LINES MISSING"),
1506 							    (colnr_T)0, TRUE);
1507 	}
1508 	else		/* there is a block */
1509 	{
1510 	    pp = (PTR_BL *)(hp->bh_data);
1511 	    if (pp->pb_id == PTR_ID)		/* it is a pointer block */
1512 	    {
1513 		/* check line count when using pointer block first time */
1514 		if (idx == 0 && line_count != 0)
1515 		{
1516 		    for (i = 0; i < (int)pp->pb_count; ++i)
1517 			line_count -= pp->pb_pointer[i].pe_line_count;
1518 		    if (line_count != 0)
1519 		    {
1520 			++error;
1521 			ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"),
1522 							    (colnr_T)0, TRUE);
1523 		    }
1524 		}
1525 
1526 		if (pp->pb_count == 0)
1527 		{
1528 		    ml_append(lnum++, (char_u *)_("???EMPTY BLOCK"),
1529 							    (colnr_T)0, TRUE);
1530 		    ++error;
1531 		}
1532 		else if (idx < (int)pp->pb_count)	/* go a block deeper */
1533 		{
1534 		    if (pp->pb_pointer[idx].pe_bnum < 0)
1535 		    {
1536 			/*
1537 			 * Data block with negative block number.
1538 			 * Try to read lines from the original file.
1539 			 * This is slow, but it works.
1540 			 */
1541 			if (!cannot_open)
1542 			{
1543 			    line_count = pp->pb_pointer[idx].pe_line_count;
1544 			    if (readfile(curbuf->b_ffname, NULL, lnum,
1545 					pp->pb_pointer[idx].pe_old_lnum - 1,
1546 					line_count, NULL, 0) == FAIL)
1547 				cannot_open = TRUE;
1548 			    else
1549 				lnum += line_count;
1550 			}
1551 			if (cannot_open)
1552 			{
1553 			    ++error;
1554 			    ml_append(lnum++, (char_u *)_("???LINES MISSING"),
1555 							    (colnr_T)0, TRUE);
1556 			}
1557 			++idx;	    /* get same block again for next index */
1558 			continue;
1559 		    }
1560 
1561 		    /*
1562 		     * going one block deeper in the tree
1563 		     */
1564 		    if ((top = ml_add_stack(buf)) < 0)	/* new entry in stack */
1565 		    {
1566 			++error;
1567 			break;		    /* out of memory */
1568 		    }
1569 		    ip = &(buf->b_ml.ml_stack[top]);
1570 		    ip->ip_bnum = bnum;
1571 		    ip->ip_index = idx;
1572 
1573 		    bnum = pp->pb_pointer[idx].pe_bnum;
1574 		    line_count = pp->pb_pointer[idx].pe_line_count;
1575 		    page_count = pp->pb_pointer[idx].pe_page_count;
1576 		    idx = 0;
1577 		    continue;
1578 		}
1579 	    }
1580 	    else	    /* not a pointer block */
1581 	    {
1582 		dp = (DATA_BL *)(hp->bh_data);
1583 		if (dp->db_id != DATA_ID)	/* block id wrong */
1584 		{
1585 		    if (bnum == 1)
1586 		    {
1587 			EMSG2(_("E310: Block 1 ID wrong (%s not a .swp file?)"),
1588 							       mfp->mf_fname);
1589 			goto theend;
1590 		    }
1591 		    ++error;
1592 		    ml_append(lnum++, (char_u *)_("???BLOCK MISSING"),
1593 							    (colnr_T)0, TRUE);
1594 		}
1595 		else
1596 		{
1597 		    /*
1598 		     * it is a data block
1599 		     * Append all the lines in this block
1600 		     */
1601 		    has_error = FALSE;
1602 			/*
1603 			 * check length of block
1604 			 * if wrong, use length in pointer block
1605 			 */
1606 		    if (page_count * mfp->mf_page_size != dp->db_txt_end)
1607 		    {
1608 			ml_append(lnum++, (char_u *)_("??? from here until ???END lines may be messed up"),
1609 							    (colnr_T)0, TRUE);
1610 			++error;
1611 			has_error = TRUE;
1612 			dp->db_txt_end = page_count * mfp->mf_page_size;
1613 		    }
1614 
1615 			/* make sure there is a NUL at the end of the block */
1616 		    *((char_u *)dp + dp->db_txt_end - 1) = NUL;
1617 
1618 			/*
1619 			 * check number of lines in block
1620 			 * if wrong, use count in data block
1621 			 */
1622 		    if (line_count != dp->db_line_count)
1623 		    {
1624 			ml_append(lnum++, (char_u *)_("??? from here until ???END lines may have been inserted/deleted"),
1625 							    (colnr_T)0, TRUE);
1626 			++error;
1627 			has_error = TRUE;
1628 		    }
1629 
1630 		    for (i = 0; i < dp->db_line_count; ++i)
1631 		    {
1632 			txt_start = (dp->db_index[i] & DB_INDEX_MASK);
1633 			if (txt_start <= (int)HEADER_SIZE
1634 					  || txt_start >= (int)dp->db_txt_end)
1635 			{
1636 			    p = (char_u *)"???";
1637 			    ++error;
1638 			}
1639 			else
1640 			    p = (char_u *)dp + txt_start;
1641 			ml_append(lnum++, p, (colnr_T)0, TRUE);
1642 		    }
1643 		    if (has_error)
1644 			ml_append(lnum++, (char_u *)_("???END"),
1645 							    (colnr_T)0, TRUE);
1646 		}
1647 	    }
1648 	}
1649 
1650 	if (buf->b_ml.ml_stack_top == 0)	/* finished */
1651 	    break;
1652 
1653 	/*
1654 	 * go one block up in the tree
1655 	 */
1656 	ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
1657 	bnum = ip->ip_bnum;
1658 	idx = ip->ip_index + 1;	    /* go to next index */
1659 	page_count = 1;
1660     }
1661 
1662     /*
1663      * Compare the buffer contents with the original file.  When they differ
1664      * set the 'modified' flag.
1665      * Lines 1 - lnum are the new contents.
1666      * Lines lnum + 1 to ml_line_count are the original contents.
1667      * Line ml_line_count + 1 in the dummy empty line.
1668      */
1669     if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1)
1670     {
1671 	/* Recovering an empty file results in two lines and the first line is
1672 	 * empty.  Don't set the modified flag then. */
1673 	if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
1674 	{
1675 	    changed_int();
1676 	    ++curbuf->b_changedtick;
1677 	}
1678     }
1679     else
1680     {
1681 	for (idx = 1; idx <= lnum; ++idx)
1682 	{
1683 	    /* Need to copy one line, fetching the other one may flush it. */
1684 	    p = vim_strsave(ml_get(idx));
1685 	    i = STRCMP(p, ml_get(idx + lnum));
1686 	    vim_free(p);
1687 	    if (i != 0)
1688 	    {
1689 		changed_int();
1690 		++curbuf->b_changedtick;
1691 		break;
1692 	    }
1693 	}
1694     }
1695 
1696     /*
1697      * Delete the lines from the original file and the dummy line from the
1698      * empty buffer.  These will now be after the last line in the buffer.
1699      */
1700     while (curbuf->b_ml.ml_line_count > lnum
1701 				       && !(curbuf->b_ml.ml_flags & ML_EMPTY))
1702 	ml_delete(curbuf->b_ml.ml_line_count, FALSE);
1703     curbuf->b_flags |= BF_RECOVERED;
1704 
1705     recoverymode = FALSE;
1706     if (got_int)
1707 	EMSG(_("E311: Recovery Interrupted"));
1708     else if (error)
1709     {
1710 	++no_wait_return;
1711 	MSG(">>>>>>>>>>>>>");
1712 	EMSG(_("E312: Errors detected while recovering; look for lines starting with ???"));
1713 	--no_wait_return;
1714 	MSG(_("See \":help E312\" for more information."));
1715 	MSG(">>>>>>>>>>>>>");
1716     }
1717     else
1718     {
1719 	if (curbuf->b_changed)
1720 	{
1721 	    MSG(_("Recovery completed. You should check if everything is OK."));
1722 	    MSG_PUTS(_("\n(You might want to write out this file under another name\n"));
1723 	    MSG_PUTS(_("and run diff with the original file to check for changes)"));
1724 	}
1725 	else
1726 	    MSG(_("Recovery completed. Buffer contents equals file contents."));
1727 	MSG_PUTS(_("\nYou may want to delete the .swp file now.\n\n"));
1728 	cmdline_row = msg_row;
1729     }
1730 #ifdef FEAT_CRYPT
1731     if (*buf->b_p_key != NUL && STRCMP(curbuf->b_p_key, buf->b_p_key) != 0)
1732     {
1733 	MSG_PUTS(_("Using crypt key from swap file for the text file.\n"));
1734 	set_option_value((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL);
1735     }
1736 #endif
1737     redraw_curbuf_later(NOT_VALID);
1738 
1739 theend:
1740     vim_free(fname_used);
1741     recoverymode = FALSE;
1742     if (mfp != NULL)
1743     {
1744 	if (hp != NULL)
1745 	    mf_put(mfp, hp, FALSE, FALSE);
1746 	mf_close(mfp, FALSE);	    /* will also vim_free(mfp->mf_fname) */
1747     }
1748     if (buf != NULL)
1749     {
1750 #ifdef FEAT_CRYPT
1751 	if (buf->b_p_key != curbuf->b_p_key)
1752 	    free_string_option(buf->b_p_key);
1753 	free_string_option(buf->b_p_cm);
1754 #endif
1755 	vim_free(buf->b_ml.ml_stack);
1756 	vim_free(buf);
1757     }
1758     if (serious_error && called_from_main)
1759 	ml_close(curbuf, TRUE);
1760 #ifdef FEAT_AUTOCMD
1761     else
1762     {
1763 	apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf);
1764 	apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf);
1765     }
1766 #endif
1767     return;
1768 }
1769 
1770 /*
1771  * Find the names of swap files in current directory and the directory given
1772  * with the 'directory' option.
1773  *
1774  * Used to:
1775  * - list the swap files for "vim -r"
1776  * - count the number of swap files when recovering
1777  * - list the swap files when recovering
1778  * - find the name of the n'th swap file when recovering
1779  */
1780     int
1781 recover_names(fname, list, nr, fname_out)
1782     char_u	*fname;		/* base for swap file name */
1783     int		list;		/* when TRUE, list the swap file names */
1784     int		nr;		/* when non-zero, return nr'th swap file name */
1785     char_u	**fname_out;	/* result when "nr" > 0 */
1786 {
1787     int		num_names;
1788     char_u	*(names[6]);
1789     char_u	*tail;
1790     char_u	*p;
1791     int		num_files;
1792     int		file_count = 0;
1793     char_u	**files;
1794     int		i;
1795     char_u	*dirp;
1796     char_u	*dir_name;
1797     char_u	*fname_res = NULL;
1798 #ifdef HAVE_READLINK
1799     char_u	fname_buf[MAXPATHL];
1800 #endif
1801 
1802     if (fname != NULL)
1803     {
1804 #ifdef HAVE_READLINK
1805 	/* Expand symlink in the file name, because the swap file is created
1806 	 * with the actual file instead of with the symlink. */
1807 	if (resolve_symlink(fname, fname_buf) == OK)
1808 	    fname_res = fname_buf;
1809 	else
1810 #endif
1811 	    fname_res = fname;
1812     }
1813 
1814     if (list)
1815     {
1816 	/* use msg() to start the scrolling properly */
1817 	msg((char_u *)_("Swap files found:"));
1818 	msg_putchar('\n');
1819     }
1820 
1821     /*
1822      * Do the loop for every directory in 'directory'.
1823      * First allocate some memory to put the directory name in.
1824      */
1825     dir_name = alloc((unsigned)STRLEN(p_dir) + 1);
1826     dirp = p_dir;
1827     while (dir_name != NULL && *dirp)
1828     {
1829 	/*
1830 	 * Isolate a directory name from *dirp and put it in dir_name (we know
1831 	 * it is large enough, so use 31000 for length).
1832 	 * Advance dirp to next directory name.
1833 	 */
1834 	(void)copy_option_part(&dirp, dir_name, 31000, ",");
1835 
1836 	if (dir_name[0] == '.' && dir_name[1] == NUL)	/* check current dir */
1837 	{
1838 	    if (fname == NULL)
1839 	    {
1840 #ifdef VMS
1841 		names[0] = vim_strsave((char_u *)"*_sw%");
1842 #else
1843 		names[0] = vim_strsave((char_u *)"*.sw?");
1844 #endif
1845 #if defined(UNIX) || defined(WIN3264)
1846 		/* For Unix names starting with a dot are special.  MS-Windows
1847 		 * supports this too, on some file systems. */
1848 		names[1] = vim_strsave((char_u *)".*.sw?");
1849 		names[2] = vim_strsave((char_u *)".sw?");
1850 		num_names = 3;
1851 #else
1852 # ifdef VMS
1853 		names[1] = vim_strsave((char_u *)".*_sw%");
1854 		num_names = 2;
1855 # else
1856 		num_names = 1;
1857 # endif
1858 #endif
1859 	    }
1860 	    else
1861 		num_names = recov_file_names(names, fname_res, TRUE);
1862 	}
1863 	else			    /* check directory dir_name */
1864 	{
1865 	    if (fname == NULL)
1866 	    {
1867 #ifdef VMS
1868 		names[0] = concat_fnames(dir_name, (char_u *)"*_sw%", TRUE);
1869 #else
1870 		names[0] = concat_fnames(dir_name, (char_u *)"*.sw?", TRUE);
1871 #endif
1872 #if defined(UNIX) || defined(WIN3264)
1873 		/* For Unix names starting with a dot are special.  MS-Windows
1874 		 * supports this too, on some file systems. */
1875 		names[1] = concat_fnames(dir_name, (char_u *)".*.sw?", TRUE);
1876 		names[2] = concat_fnames(dir_name, (char_u *)".sw?", TRUE);
1877 		num_names = 3;
1878 #else
1879 # ifdef VMS
1880 		names[1] = concat_fnames(dir_name, (char_u *)".*_sw%", TRUE);
1881 		num_names = 2;
1882 # else
1883 		num_names = 1;
1884 # endif
1885 #endif
1886 	    }
1887 	    else
1888 	    {
1889 #if defined(UNIX) || defined(WIN3264)
1890 		p = dir_name + STRLEN(dir_name);
1891 		if (after_pathsep(dir_name, p) && p[-1] == p[-2])
1892 		{
1893 		    /* Ends with '//', Use Full path for swap name */
1894 		    tail = make_percent_swname(dir_name, fname_res);
1895 		}
1896 		else
1897 #endif
1898 		{
1899 		    tail = gettail(fname_res);
1900 		    tail = concat_fnames(dir_name, tail, TRUE);
1901 		}
1902 		if (tail == NULL)
1903 		    num_names = 0;
1904 		else
1905 		{
1906 		    num_names = recov_file_names(names, tail, FALSE);
1907 		    vim_free(tail);
1908 		}
1909 	    }
1910 	}
1911 
1912 	    /* check for out-of-memory */
1913 	for (i = 0; i < num_names; ++i)
1914 	{
1915 	    if (names[i] == NULL)
1916 	    {
1917 		for (i = 0; i < num_names; ++i)
1918 		    vim_free(names[i]);
1919 		num_names = 0;
1920 	    }
1921 	}
1922 	if (num_names == 0)
1923 	    num_files = 0;
1924 	else if (expand_wildcards(num_names, names, &num_files, &files,
1925 					EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL)
1926 	    num_files = 0;
1927 
1928 	/*
1929 	 * When no swap file found, wildcard expansion might have failed (e.g.
1930 	 * not able to execute the shell).
1931 	 * Try finding a swap file by simply adding ".swp" to the file name.
1932 	 */
1933 	if (*dirp == NUL && file_count + num_files == 0 && fname != NULL)
1934 	{
1935 	    struct stat	    st;
1936 	    char_u	    *swapname;
1937 
1938 	    swapname = modname(fname_res,
1939 #if defined(VMS)
1940 			       (char_u *)"_swp", FALSE
1941 #else
1942 			       (char_u *)".swp", TRUE
1943 #endif
1944 			      );
1945 	    if (swapname != NULL)
1946 	    {
1947 		if (mch_stat((char *)swapname, &st) != -1)	    /* It exists! */
1948 		{
1949 		    files = (char_u **)alloc((unsigned)sizeof(char_u *));
1950 		    if (files != NULL)
1951 		    {
1952 			files[0] = swapname;
1953 			swapname = NULL;
1954 			num_files = 1;
1955 		    }
1956 		}
1957 		vim_free(swapname);
1958 	    }
1959 	}
1960 
1961 	/*
1962 	 * remove swapfile name of the current buffer, it must be ignored
1963 	 */
1964 	if (curbuf->b_ml.ml_mfp != NULL
1965 			       && (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL)
1966 	{
1967 	    for (i = 0; i < num_files; ++i)
1968 		if (fullpathcmp(p, files[i], TRUE) & FPC_SAME)
1969 		{
1970 		    /* Remove the name from files[i].  Move further entries
1971 		     * down.  When the array becomes empty free it here, since
1972 		     * FreeWild() won't be called below. */
1973 		    vim_free(files[i]);
1974 		    if (--num_files == 0)
1975 			vim_free(files);
1976 		    else
1977 			for ( ; i < num_files; ++i)
1978 			    files[i] = files[i + 1];
1979 		}
1980 	}
1981 	if (nr > 0)
1982 	{
1983 	    file_count += num_files;
1984 	    if (nr <= file_count)
1985 	    {
1986 		*fname_out = vim_strsave(
1987 				      files[nr - 1 + num_files - file_count]);
1988 		dirp = (char_u *)"";		    /* stop searching */
1989 	    }
1990 	}
1991 	else if (list)
1992 	{
1993 	    if (dir_name[0] == '.' && dir_name[1] == NUL)
1994 	    {
1995 		if (fname == NULL)
1996 		    MSG_PUTS(_("   In current directory:\n"));
1997 		else
1998 		    MSG_PUTS(_("   Using specified name:\n"));
1999 	    }
2000 	    else
2001 	    {
2002 		MSG_PUTS(_("   In directory "));
2003 		msg_home_replace(dir_name);
2004 		MSG_PUTS(":\n");
2005 	    }
2006 
2007 	    if (num_files)
2008 	    {
2009 		for (i = 0; i < num_files; ++i)
2010 		{
2011 		    /* print the swap file name */
2012 		    msg_outnum((long)++file_count);
2013 		    MSG_PUTS(".    ");
2014 		    msg_puts(gettail(files[i]));
2015 		    msg_putchar('\n');
2016 		    (void)swapfile_info(files[i]);
2017 		}
2018 	    }
2019 	    else
2020 		MSG_PUTS(_("      -- none --\n"));
2021 	    out_flush();
2022 	}
2023 	else
2024 	    file_count += num_files;
2025 
2026 	for (i = 0; i < num_names; ++i)
2027 	    vim_free(names[i]);
2028 	if (num_files > 0)
2029 	    FreeWild(num_files, files);
2030     }
2031     vim_free(dir_name);
2032     return file_count;
2033 }
2034 
2035 #if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
2036 /*
2037  * Append the full path to name with path separators made into percent
2038  * signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
2039  */
2040     static char_u *
2041 make_percent_swname(dir, name)
2042     char_u	*dir;
2043     char_u	*name;
2044 {
2045     char_u *d, *s, *f;
2046 
2047     f = fix_fname(name != NULL ? name : (char_u *) "");
2048     d = NULL;
2049     if (f != NULL)
2050     {
2051 	s = alloc((unsigned)(STRLEN(f) + 1));
2052 	if (s != NULL)
2053 	{
2054 	    STRCPY(s, f);
2055 	    for (d = s; *d != NUL; mb_ptr_adv(d))
2056 		if (vim_ispathsep(*d))
2057 		    *d = '%';
2058 	    d = concat_fnames(dir, s, TRUE);
2059 	    vim_free(s);
2060 	}
2061 	vim_free(f);
2062     }
2063     return d;
2064 }
2065 #endif
2066 
2067 #if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
2068 static int process_still_running;
2069 #endif
2070 
2071 /*
2072  * Give information about an existing swap file.
2073  * Returns timestamp (0 when unknown).
2074  */
2075     static time_t
2076 swapfile_info(fname)
2077     char_u	*fname;
2078 {
2079     struct stat	    st;
2080     int		    fd;
2081     struct block0   b0;
2082     time_t	    x = (time_t)0;
2083     char	    *p;
2084 #ifdef UNIX
2085     char_u	    uname[B0_UNAME_SIZE];
2086 #endif
2087 
2088     /* print the swap file date */
2089     if (mch_stat((char *)fname, &st) != -1)
2090     {
2091 #ifdef UNIX
2092 	/* print name of owner of the file */
2093 	if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK)
2094 	{
2095 	    MSG_PUTS(_("          owned by: "));
2096 	    msg_outtrans(uname);
2097 	    MSG_PUTS(_("   dated: "));
2098 	}
2099 	else
2100 #endif
2101 	    MSG_PUTS(_("             dated: "));
2102 	x = st.st_mtime;		    /* Manx C can't do &st.st_mtime */
2103 	p = ctime(&x);			    /* includes '\n' */
2104 	if (p == NULL)
2105 	    MSG_PUTS("(invalid)\n");
2106 	else
2107 	    MSG_PUTS(p);
2108     }
2109 
2110     /*
2111      * print the original file name
2112      */
2113     fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
2114     if (fd >= 0)
2115     {
2116 	if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
2117 	{
2118 	    if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0)
2119 	    {
2120 		MSG_PUTS(_("         [from Vim version 3.0]"));
2121 	    }
2122 	    else if (ml_check_b0_id(&b0) == FAIL)
2123 	    {
2124 		MSG_PUTS(_("         [does not look like a Vim swap file]"));
2125 	    }
2126 	    else
2127 	    {
2128 		MSG_PUTS(_("         file name: "));
2129 		if (b0.b0_fname[0] == NUL)
2130 		    MSG_PUTS(_("[No Name]"));
2131 		else
2132 		    msg_outtrans(b0.b0_fname);
2133 
2134 		MSG_PUTS(_("\n          modified: "));
2135 		MSG_PUTS(b0.b0_dirty ? _("YES") : _("no"));
2136 
2137 		if (*(b0.b0_uname) != NUL)
2138 		{
2139 		    MSG_PUTS(_("\n         user name: "));
2140 		    msg_outtrans(b0.b0_uname);
2141 		}
2142 
2143 		if (*(b0.b0_hname) != NUL)
2144 		{
2145 		    if (*(b0.b0_uname) != NUL)
2146 			MSG_PUTS(_("   host name: "));
2147 		    else
2148 			MSG_PUTS(_("\n         host name: "));
2149 		    msg_outtrans(b0.b0_hname);
2150 		}
2151 
2152 		if (char_to_long(b0.b0_pid) != 0L)
2153 		{
2154 		    MSG_PUTS(_("\n        process ID: "));
2155 		    msg_outnum(char_to_long(b0.b0_pid));
2156 #if defined(UNIX) || defined(__EMX__)
2157 		    /* EMX kill() not working correctly, it seems */
2158 		    if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0)
2159 		    {
2160 			MSG_PUTS(_(" (still running)"));
2161 # if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2162 			process_still_running = TRUE;
2163 # endif
2164 		    }
2165 #endif
2166 		}
2167 
2168 		if (b0_magic_wrong(&b0))
2169 		{
2170 #if defined(MSDOS) || defined(MSWIN)
2171 		    if (STRNCMP(b0.b0_hname, "PC ", 3) == 0)
2172 			MSG_PUTS(_("\n         [not usable with this version of Vim]"));
2173 		    else
2174 #endif
2175 			MSG_PUTS(_("\n         [not usable on this computer]"));
2176 		}
2177 	    }
2178 	}
2179 	else
2180 	    MSG_PUTS(_("         [cannot be read]"));
2181 	close(fd);
2182     }
2183     else
2184 	MSG_PUTS(_("         [cannot be opened]"));
2185     msg_putchar('\n');
2186 
2187     return x;
2188 }
2189 
2190     static int
2191 recov_file_names(names, path, prepend_dot)
2192     char_u	**names;
2193     char_u	*path;
2194     int		prepend_dot;
2195 {
2196     int		num_names;
2197 
2198 #ifdef SHORT_FNAME
2199     /*
2200      * (MS-DOS) always short names
2201      */
2202     names[0] = modname(path, (char_u *)".sw?", FALSE);
2203     num_names = 1;
2204 #else /* !SHORT_FNAME */
2205     /*
2206      * (Win32 and Win64) never short names, but do prepend a dot.
2207      * (Not MS-DOS or Win32 or Win64) maybe short name, maybe not: Try both.
2208      * Only use the short name if it is different.
2209      */
2210     char_u	*p;
2211     int		i;
2212 # ifndef WIN3264
2213     int	    shortname = curbuf->b_shortname;
2214 
2215     curbuf->b_shortname = FALSE;
2216 # endif
2217 
2218     num_names = 0;
2219 
2220     /*
2221      * May also add the file name with a dot prepended, for swap file in same
2222      * dir as original file.
2223      */
2224     if (prepend_dot)
2225     {
2226 	names[num_names] = modname(path, (char_u *)".sw?", TRUE);
2227 	if (names[num_names] == NULL)
2228 	    goto end;
2229 	++num_names;
2230     }
2231 
2232     /*
2233      * Form the normal swap file name pattern by appending ".sw?".
2234      */
2235 #ifdef VMS
2236     names[num_names] = concat_fnames(path, (char_u *)"_sw%", FALSE);
2237 #else
2238     names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE);
2239 #endif
2240     if (names[num_names] == NULL)
2241 	goto end;
2242     if (num_names >= 1)	    /* check if we have the same name twice */
2243     {
2244 	p = names[num_names - 1];
2245 	i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
2246 	if (i > 0)
2247 	    p += i;	    /* file name has been expanded to full path */
2248 
2249 	if (STRCMP(p, names[num_names]) != 0)
2250 	    ++num_names;
2251 	else
2252 	    vim_free(names[num_names]);
2253     }
2254     else
2255 	++num_names;
2256 
2257 # ifndef WIN3264
2258     /*
2259      * Also try with 'shortname' set, in case the file is on a DOS filesystem.
2260      */
2261     curbuf->b_shortname = TRUE;
2262 #ifdef VMS
2263     names[num_names] = modname(path, (char_u *)"_sw%", FALSE);
2264 #else
2265     names[num_names] = modname(path, (char_u *)".sw?", FALSE);
2266 #endif
2267     if (names[num_names] == NULL)
2268 	goto end;
2269 
2270     /*
2271      * Remove the one from 'shortname', if it's the same as with 'noshortname'.
2272      */
2273     p = names[num_names];
2274     i = STRLEN(names[num_names]) - STRLEN(names[num_names - 1]);
2275     if (i > 0)
2276 	p += i;		/* file name has been expanded to full path */
2277     if (STRCMP(names[num_names - 1], p) == 0)
2278 	vim_free(names[num_names]);
2279     else
2280 	++num_names;
2281 # endif
2282 
2283 end:
2284 # ifndef WIN3264
2285     curbuf->b_shortname = shortname;
2286 # endif
2287 
2288 #endif /* !SHORT_FNAME */
2289 
2290     return num_names;
2291 }
2292 
2293 /*
2294  * sync all memlines
2295  *
2296  * If 'check_file' is TRUE, check if original file exists and was not changed.
2297  * If 'check_char' is TRUE, stop syncing when character becomes available, but
2298  * always sync at least one block.
2299  */
2300     void
2301 ml_sync_all(check_file, check_char)
2302     int	    check_file;
2303     int	    check_char;
2304 {
2305     buf_T		*buf;
2306     struct stat		st;
2307 
2308     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
2309     {
2310 	if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
2311 	    continue;			    /* no file */
2312 
2313 	ml_flush_line(buf);		    /* flush buffered line */
2314 					    /* flush locked block */
2315 	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
2316 	if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
2317 						     && buf->b_ffname != NULL)
2318 	{
2319 	    /*
2320 	     * If the original file does not exist anymore or has been changed
2321 	     * call ml_preserve() to get rid of all negative numbered blocks.
2322 	     */
2323 	    if (mch_stat((char *)buf->b_ffname, &st) == -1
2324 		    || st.st_mtime != buf->b_mtime_read
2325 		    || st.st_size != buf->b_orig_size)
2326 	    {
2327 		ml_preserve(buf, FALSE);
2328 		did_check_timestamps = FALSE;
2329 		need_check_timestamps = TRUE;	/* give message later */
2330 	    }
2331 	}
2332 	if (buf->b_ml.ml_mfp->mf_dirty)
2333 	{
2334 	    (void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
2335 					| (bufIsChanged(buf) ? MFS_FLUSH : 0));
2336 	    if (check_char && ui_char_avail())	/* character available now */
2337 		break;
2338 	}
2339     }
2340 }
2341 
2342 /*
2343  * sync one buffer, including negative blocks
2344  *
2345  * after this all the blocks are in the swap file
2346  *
2347  * Used for the :preserve command and when the original file has been
2348  * changed or deleted.
2349  *
2350  * when message is TRUE the success of preserving is reported
2351  */
2352     void
2353 ml_preserve(buf, message)
2354     buf_T	*buf;
2355     int		message;
2356 {
2357     bhdr_T	*hp;
2358     linenr_T	lnum;
2359     memfile_T	*mfp = buf->b_ml.ml_mfp;
2360     int		status;
2361     int		got_int_save = got_int;
2362 
2363     if (mfp == NULL || mfp->mf_fname == NULL)
2364     {
2365 	if (message)
2366 	    EMSG(_("E313: Cannot preserve, there is no swap file"));
2367 	return;
2368     }
2369 
2370     /* We only want to stop when interrupted here, not when interrupted
2371      * before. */
2372     got_int = FALSE;
2373 
2374     ml_flush_line(buf);				    /* flush buffered line */
2375     (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
2376     status = mf_sync(mfp, MFS_ALL | MFS_FLUSH);
2377 
2378     /* stack is invalid after mf_sync(.., MFS_ALL) */
2379     buf->b_ml.ml_stack_top = 0;
2380 
2381     /*
2382      * Some of the data blocks may have been changed from negative to
2383      * positive block number. In that case the pointer blocks need to be
2384      * updated.
2385      *
2386      * We don't know in which pointer block the references are, so we visit
2387      * all data blocks until there are no more translations to be done (or
2388      * we hit the end of the file, which can only happen in case a write fails,
2389      * e.g. when file system if full).
2390      * ml_find_line() does the work by translating the negative block numbers
2391      * when getting the first line of each data block.
2392      */
2393     if (mf_need_trans(mfp) && !got_int)
2394     {
2395 	lnum = 1;
2396 	while (mf_need_trans(mfp) && lnum <= buf->b_ml.ml_line_count)
2397 	{
2398 	    hp = ml_find_line(buf, lnum, ML_FIND);
2399 	    if (hp == NULL)
2400 	    {
2401 		status = FAIL;
2402 		goto theend;
2403 	    }
2404 	    CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
2405 	    lnum = buf->b_ml.ml_locked_high + 1;
2406 	}
2407 	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);	/* flush locked block */
2408 	/* sync the updated pointer blocks */
2409 	if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL)
2410 	    status = FAIL;
2411 	buf->b_ml.ml_stack_top = 0;	    /* stack is invalid now */
2412     }
2413 theend:
2414     got_int |= got_int_save;
2415 
2416     if (message)
2417     {
2418 	if (status == OK)
2419 	    MSG(_("File preserved"));
2420 	else
2421 	    EMSG(_("E314: Preserve failed"));
2422     }
2423 }
2424 
2425 /*
2426  * NOTE: The pointer returned by the ml_get_*() functions only remains valid
2427  * until the next call!
2428  *  line1 = ml_get(1);
2429  *  line2 = ml_get(2);	// line1 is now invalid!
2430  * Make a copy of the line if necessary.
2431  */
2432 /*
2433  * Return a pointer to a (read-only copy of a) line.
2434  *
2435  * On failure an error message is given and IObuff is returned (to avoid
2436  * having to check for error everywhere).
2437  */
2438     char_u  *
2439 ml_get(lnum)
2440     linenr_T	lnum;
2441 {
2442     return ml_get_buf(curbuf, lnum, FALSE);
2443 }
2444 
2445 /*
2446  * Return pointer to position "pos".
2447  */
2448     char_u *
2449 ml_get_pos(pos)
2450     pos_T	*pos;
2451 {
2452     return (ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col);
2453 }
2454 
2455 /*
2456  * Return pointer to cursor line.
2457  */
2458     char_u *
2459 ml_get_curline()
2460 {
2461     return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE);
2462 }
2463 
2464 /*
2465  * Return pointer to cursor position.
2466  */
2467     char_u *
2468 ml_get_cursor()
2469 {
2470     return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
2471 							curwin->w_cursor.col);
2472 }
2473 
2474 /*
2475  * Return a pointer to a line in a specific buffer
2476  *
2477  * "will_change": if TRUE mark the buffer dirty (chars in the line will be
2478  * changed)
2479  */
2480     char_u  *
2481 ml_get_buf(buf, lnum, will_change)
2482     buf_T	*buf;
2483     linenr_T	lnum;
2484     int		will_change;		/* line will be changed */
2485 {
2486     bhdr_T	*hp;
2487     DATA_BL	*dp;
2488     char_u	*ptr;
2489     static int	recursive = 0;
2490 
2491     if (lnum > buf->b_ml.ml_line_count)	/* invalid line number */
2492     {
2493 	if (recursive == 0)
2494 	{
2495 	    /* Avoid giving this message for a recursive call, may happen when
2496 	     * the GUI redraws part of the text. */
2497 	    ++recursive;
2498 	    EMSGN(_("E315: ml_get: invalid lnum: %ld"), lnum);
2499 	    --recursive;
2500 	}
2501 errorret:
2502 	STRCPY(IObuff, "???");
2503 	return IObuff;
2504     }
2505     if (lnum <= 0)			/* pretend line 0 is line 1 */
2506 	lnum = 1;
2507 
2508     if (buf->b_ml.ml_mfp == NULL)	/* there are no lines */
2509 	return (char_u *)"";
2510 
2511     /*
2512      * See if it is the same line as requested last time.
2513      * Otherwise may need to flush last used line.
2514      * Don't use the last used line when 'swapfile' is reset, need to load all
2515      * blocks.
2516      */
2517     if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release)
2518     {
2519 	ml_flush_line(buf);
2520 
2521 	/*
2522 	 * Find the data block containing the line.
2523 	 * This also fills the stack with the blocks from the root to the data
2524 	 * block and releases any locked block.
2525 	 */
2526 	if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL)
2527 	{
2528 	    if (recursive == 0)
2529 	    {
2530 		/* Avoid giving this message for a recursive call, may happen
2531 		 * when the GUI redraws part of the text. */
2532 		++recursive;
2533 		EMSGN(_("E316: ml_get: cannot find line %ld"), lnum);
2534 		--recursive;
2535 	    }
2536 	    goto errorret;
2537 	}
2538 
2539 	dp = (DATA_BL *)(hp->bh_data);
2540 
2541 	ptr = (char_u *)dp + ((dp->db_index[lnum - buf->b_ml.ml_locked_low]) & DB_INDEX_MASK);
2542 	buf->b_ml.ml_line_ptr = ptr;
2543 	buf->b_ml.ml_line_lnum = lnum;
2544 	buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
2545     }
2546     if (will_change)
2547 	buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
2548 
2549     return buf->b_ml.ml_line_ptr;
2550 }
2551 
2552 /*
2553  * Check if a line that was just obtained by a call to ml_get
2554  * is in allocated memory.
2555  */
2556     int
2557 ml_line_alloced()
2558 {
2559     return (curbuf->b_ml.ml_flags & ML_LINE_DIRTY);
2560 }
2561 
2562 /*
2563  * Append a line after lnum (may be 0 to insert a line in front of the file).
2564  * "line" does not need to be allocated, but can't be another line in a
2565  * buffer, unlocking may make it invalid.
2566  *
2567  *   newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
2568  *		will be set for recovery
2569  * Check: The caller of this function should probably also call
2570  * appended_lines().
2571  *
2572  * return FAIL for failure, OK otherwise
2573  */
2574     int
2575 ml_append(lnum, line, len, newfile)
2576     linenr_T	lnum;		/* append after this line (can be 0) */
2577     char_u	*line;		/* text of the new line */
2578     colnr_T	len;		/* length of new line, including NUL, or 0 */
2579     int		newfile;	/* flag, see above */
2580 {
2581     /* When starting up, we might still need to create the memfile */
2582     if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
2583 	return FAIL;
2584 
2585     if (curbuf->b_ml.ml_line_lnum != 0)
2586 	ml_flush_line(curbuf);
2587     return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
2588 }
2589 
2590 #if defined(FEAT_SPELL) || defined(PROTO)
2591 /*
2592  * Like ml_append() but for an arbitrary buffer.  The buffer must already have
2593  * a memline.
2594  */
2595     int
2596 ml_append_buf(buf, lnum, line, len, newfile)
2597     buf_T	*buf;
2598     linenr_T	lnum;		/* append after this line (can be 0) */
2599     char_u	*line;		/* text of the new line */
2600     colnr_T	len;		/* length of new line, including NUL, or 0 */
2601     int		newfile;	/* flag, see above */
2602 {
2603     if (buf->b_ml.ml_mfp == NULL)
2604 	return FAIL;
2605 
2606     if (buf->b_ml.ml_line_lnum != 0)
2607 	ml_flush_line(buf);
2608     return ml_append_int(buf, lnum, line, len, newfile, FALSE);
2609 }
2610 #endif
2611 
2612     static int
2613 ml_append_int(buf, lnum, line, len, newfile, mark)
2614     buf_T	*buf;
2615     linenr_T	lnum;		/* append after this line (can be 0) */
2616     char_u	*line;		/* text of the new line */
2617     colnr_T	len;		/* length of line, including NUL, or 0 */
2618     int		newfile;	/* flag, see above */
2619     int		mark;		/* mark the new line */
2620 {
2621     int		i;
2622     int		line_count;	/* number of indexes in current block */
2623     int		offset;
2624     int		from, to;
2625     int		space_needed;	/* space needed for new line */
2626     int		page_size;
2627     int		page_count;
2628     int		db_idx;		/* index for lnum in data block */
2629     bhdr_T	*hp;
2630     memfile_T	*mfp;
2631     DATA_BL	*dp;
2632     PTR_BL	*pp;
2633     infoptr_T	*ip;
2634 
2635 					/* lnum out of range */
2636     if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
2637 	return FAIL;
2638 
2639     if (lowest_marked && lowest_marked > lnum)
2640 	lowest_marked = lnum + 1;
2641 
2642     if (len == 0)
2643 	len = (colnr_T)STRLEN(line) + 1;	/* space needed for the text */
2644     space_needed = len + INDEX_SIZE;	/* space needed for text + index */
2645 
2646     mfp = buf->b_ml.ml_mfp;
2647     page_size = mfp->mf_page_size;
2648 
2649 /*
2650  * find the data block containing the previous line
2651  * This also fills the stack with the blocks from the root to the data block
2652  * This also releases any locked block.
2653  */
2654     if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum,
2655 							  ML_INSERT)) == NULL)
2656 	return FAIL;
2657 
2658     buf->b_ml.ml_flags &= ~ML_EMPTY;
2659 
2660     if (lnum == 0)		/* got line one instead, correct db_idx */
2661 	db_idx = -1;		/* careful, it is negative! */
2662     else
2663 	db_idx = lnum - buf->b_ml.ml_locked_low;
2664 		/* get line count before the insertion */
2665     line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
2666 
2667     dp = (DATA_BL *)(hp->bh_data);
2668 
2669 /*
2670  * If
2671  * - there is not enough room in the current block
2672  * - appending to the last line in the block
2673  * - not appending to the last line in the file
2674  * insert in front of the next block.
2675  */
2676     if ((int)dp->db_free < space_needed && db_idx == line_count - 1
2677 					    && lnum < buf->b_ml.ml_line_count)
2678     {
2679 	/*
2680 	 * Now that the line is not going to be inserted in the block that we
2681 	 * expected, the line count has to be adjusted in the pointer blocks
2682 	 * by using ml_locked_lineadd.
2683 	 */
2684 	--(buf->b_ml.ml_locked_lineadd);
2685 	--(buf->b_ml.ml_locked_high);
2686 	if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
2687 	    return FAIL;
2688 
2689 	db_idx = -1;		    /* careful, it is negative! */
2690 		    /* get line count before the insertion */
2691 	line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
2692 	CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");
2693 
2694 	dp = (DATA_BL *)(hp->bh_data);
2695     }
2696 
2697     ++buf->b_ml.ml_line_count;
2698 
2699     if ((int)dp->db_free >= space_needed)	/* enough room in data block */
2700     {
2701 /*
2702  * Insert new line in existing data block, or in data block allocated above.
2703  */
2704 	dp->db_txt_start -= len;
2705 	dp->db_free -= space_needed;
2706 	++(dp->db_line_count);
2707 
2708 	/*
2709 	 * move the text of the lines that follow to the front
2710 	 * adjust the indexes of the lines that follow
2711 	 */
2712 	if (line_count > db_idx + 1)	    /* if there are following lines */
2713 	{
2714 	    /*
2715 	     * Offset is the start of the previous line.
2716 	     * This will become the character just after the new line.
2717 	     */
2718 	    if (db_idx < 0)
2719 		offset = dp->db_txt_end;
2720 	    else
2721 		offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
2722 	    mch_memmove((char *)dp + dp->db_txt_start,
2723 					  (char *)dp + dp->db_txt_start + len,
2724 				 (size_t)(offset - (dp->db_txt_start + len)));
2725 	    for (i = line_count - 1; i > db_idx; --i)
2726 		dp->db_index[i + 1] = dp->db_index[i] - len;
2727 	    dp->db_index[db_idx + 1] = offset - len;
2728 	}
2729 	else				    /* add line at the end */
2730 	    dp->db_index[db_idx + 1] = dp->db_txt_start;
2731 
2732 	/*
2733 	 * copy the text into the block
2734 	 */
2735 	mch_memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
2736 	if (mark)
2737 	    dp->db_index[db_idx + 1] |= DB_MARKED;
2738 
2739 	/*
2740 	 * Mark the block dirty.
2741 	 */
2742 	buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
2743 	if (!newfile)
2744 	    buf->b_ml.ml_flags |= ML_LOCKED_POS;
2745     }
2746     else	    /* not enough space in data block */
2747     {
2748 /*
2749  * If there is not enough room we have to create a new data block and copy some
2750  * lines into it.
2751  * Then we have to insert an entry in the pointer block.
2752  * If this pointer block also is full, we go up another block, and so on, up
2753  * to the root if necessary.
2754  * The line counts in the pointer blocks have already been adjusted by
2755  * ml_find_line().
2756  */
2757 	long	    line_count_left, line_count_right;
2758 	int	    page_count_left, page_count_right;
2759 	bhdr_T	    *hp_left;
2760 	bhdr_T	    *hp_right;
2761 	bhdr_T	    *hp_new;
2762 	int	    lines_moved;
2763 	int	    data_moved = 0;	    /* init to shut up gcc */
2764 	int	    total_moved = 0;	    /* init to shut up gcc */
2765 	DATA_BL	    *dp_right, *dp_left;
2766 	int	    stack_idx;
2767 	int	    in_left;
2768 	int	    lineadd;
2769 	blocknr_T   bnum_left, bnum_right;
2770 	linenr_T    lnum_left, lnum_right;
2771 	int	    pb_idx;
2772 	PTR_BL	    *pp_new;
2773 
2774 	/*
2775 	 * We are going to allocate a new data block. Depending on the
2776 	 * situation it will be put to the left or right of the existing
2777 	 * block.  If possible we put the new line in the left block and move
2778 	 * the lines after it to the right block. Otherwise the new line is
2779 	 * also put in the right block. This method is more efficient when
2780 	 * inserting a lot of lines at one place.
2781 	 */
2782 	if (db_idx < 0)		/* left block is new, right block is existing */
2783 	{
2784 	    lines_moved = 0;
2785 	    in_left = TRUE;
2786 	    /* space_needed does not change */
2787 	}
2788 	else			/* left block is existing, right block is new */
2789 	{
2790 	    lines_moved = line_count - db_idx - 1;
2791 	    if (lines_moved == 0)
2792 		in_left = FALSE;	/* put new line in right block */
2793 					/* space_needed does not change */
2794 	    else
2795 	    {
2796 		data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
2797 							    dp->db_txt_start;
2798 		total_moved = data_moved + lines_moved * INDEX_SIZE;
2799 		if ((int)dp->db_free + total_moved >= space_needed)
2800 		{
2801 		    in_left = TRUE;	/* put new line in left block */
2802 		    space_needed = total_moved;
2803 		}
2804 		else
2805 		{
2806 		    in_left = FALSE;	    /* put new line in right block */
2807 		    space_needed += total_moved;
2808 		}
2809 	    }
2810 	}
2811 
2812 	page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
2813 	if ((hp_new = ml_new_data(mfp, newfile, page_count)) == NULL)
2814 	{
2815 			/* correct line counts in pointer blocks */
2816 	    --(buf->b_ml.ml_locked_lineadd);
2817 	    --(buf->b_ml.ml_locked_high);
2818 	    return FAIL;
2819 	}
2820 	if (db_idx < 0)		/* left block is new */
2821 	{
2822 	    hp_left = hp_new;
2823 	    hp_right = hp;
2824 	    line_count_left = 0;
2825 	    line_count_right = line_count;
2826 	}
2827 	else			/* right block is new */
2828 	{
2829 	    hp_left = hp;
2830 	    hp_right = hp_new;
2831 	    line_count_left = line_count;
2832 	    line_count_right = 0;
2833 	}
2834 	dp_right = (DATA_BL *)(hp_right->bh_data);
2835 	dp_left = (DATA_BL *)(hp_left->bh_data);
2836 	bnum_left = hp_left->bh_bnum;
2837 	bnum_right = hp_right->bh_bnum;
2838 	page_count_left = hp_left->bh_page_count;
2839 	page_count_right = hp_right->bh_page_count;
2840 
2841 	/*
2842 	 * May move the new line into the right/new block.
2843 	 */
2844 	if (!in_left)
2845 	{
2846 	    dp_right->db_txt_start -= len;
2847 	    dp_right->db_free -= len + INDEX_SIZE;
2848 	    dp_right->db_index[0] = dp_right->db_txt_start;
2849 	    if (mark)
2850 		dp_right->db_index[0] |= DB_MARKED;
2851 
2852 	    mch_memmove((char *)dp_right + dp_right->db_txt_start,
2853 							   line, (size_t)len);
2854 	    ++line_count_right;
2855 	}
2856 	/*
2857 	 * may move lines from the left/old block to the right/new one.
2858 	 */
2859 	if (lines_moved)
2860 	{
2861 	    /*
2862 	     */
2863 	    dp_right->db_txt_start -= data_moved;
2864 	    dp_right->db_free -= total_moved;
2865 	    mch_memmove((char *)dp_right + dp_right->db_txt_start,
2866 			(char *)dp_left + dp_left->db_txt_start,
2867 			(size_t)data_moved);
2868 	    offset = dp_right->db_txt_start - dp_left->db_txt_start;
2869 	    dp_left->db_txt_start += data_moved;
2870 	    dp_left->db_free += total_moved;
2871 
2872 	    /*
2873 	     * update indexes in the new block
2874 	     */
2875 	    for (to = line_count_right, from = db_idx + 1;
2876 					 from < line_count_left; ++from, ++to)
2877 		dp_right->db_index[to] = dp->db_index[from] + offset;
2878 	    line_count_right += lines_moved;
2879 	    line_count_left -= lines_moved;
2880 	}
2881 
2882 	/*
2883 	 * May move the new line into the left (old or new) block.
2884 	 */
2885 	if (in_left)
2886 	{
2887 	    dp_left->db_txt_start -= len;
2888 	    dp_left->db_free -= len + INDEX_SIZE;
2889 	    dp_left->db_index[line_count_left] = dp_left->db_txt_start;
2890 	    if (mark)
2891 		dp_left->db_index[line_count_left] |= DB_MARKED;
2892 	    mch_memmove((char *)dp_left + dp_left->db_txt_start,
2893 							   line, (size_t)len);
2894 	    ++line_count_left;
2895 	}
2896 
2897 	if (db_idx < 0)		/* left block is new */
2898 	{
2899 	    lnum_left = lnum + 1;
2900 	    lnum_right = 0;
2901 	}
2902 	else			/* right block is new */
2903 	{
2904 	    lnum_left = 0;
2905 	    if (in_left)
2906 		lnum_right = lnum + 2;
2907 	    else
2908 		lnum_right = lnum + 1;
2909 	}
2910 	dp_left->db_line_count = line_count_left;
2911 	dp_right->db_line_count = line_count_right;
2912 
2913 	/*
2914 	 * release the two data blocks
2915 	 * The new one (hp_new) already has a correct blocknumber.
2916 	 * The old one (hp, in ml_locked) gets a positive blocknumber if
2917 	 * we changed it and we are not editing a new file.
2918 	 */
2919 	if (lines_moved || in_left)
2920 	    buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
2921 	if (!newfile && db_idx >= 0 && in_left)
2922 	    buf->b_ml.ml_flags |= ML_LOCKED_POS;
2923 	mf_put(mfp, hp_new, TRUE, FALSE);
2924 
2925 	/*
2926 	 * flush the old data block
2927 	 * set ml_locked_lineadd to 0, because the updating of the
2928 	 * pointer blocks is done below
2929 	 */
2930 	lineadd = buf->b_ml.ml_locked_lineadd;
2931 	buf->b_ml.ml_locked_lineadd = 0;
2932 	ml_find_line(buf, (linenr_T)0, ML_FLUSH);   /* flush data block */
2933 
2934 	/*
2935 	 * update pointer blocks for the new data block
2936 	 */
2937 	for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
2938 								  --stack_idx)
2939 	{
2940 	    ip = &(buf->b_ml.ml_stack[stack_idx]);
2941 	    pb_idx = ip->ip_index;
2942 	    if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
2943 		return FAIL;
2944 	    pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
2945 	    if (pp->pb_id != PTR_ID)
2946 	    {
2947 		EMSG(_("E317: pointer block id wrong 3"));
2948 		mf_put(mfp, hp, FALSE, FALSE);
2949 		return FAIL;
2950 	    }
2951 	    /*
2952 	     * TODO: If the pointer block is full and we are adding at the end
2953 	     * try to insert in front of the next block
2954 	     */
2955 	    /* block not full, add one entry */
2956 	    if (pp->pb_count < pp->pb_count_max)
2957 	    {
2958 		if (pb_idx + 1 < (int)pp->pb_count)
2959 		    mch_memmove(&pp->pb_pointer[pb_idx + 2],
2960 				&pp->pb_pointer[pb_idx + 1],
2961 			(size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
2962 		++pp->pb_count;
2963 		pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
2964 		pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
2965 		pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
2966 		pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
2967 		pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
2968 		pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
2969 
2970 		if (lnum_left != 0)
2971 		    pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
2972 		if (lnum_right != 0)
2973 		    pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
2974 
2975 		mf_put(mfp, hp, TRUE, FALSE);
2976 		buf->b_ml.ml_stack_top = stack_idx + 1;	    /* truncate stack */
2977 
2978 		if (lineadd)
2979 		{
2980 		    --(buf->b_ml.ml_stack_top);
2981 		    /* fix line count for rest of blocks in the stack */
2982 		    ml_lineadd(buf, lineadd);
2983 							/* fix stack itself */
2984 		    buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
2985 								      lineadd;
2986 		    ++(buf->b_ml.ml_stack_top);
2987 		}
2988 
2989 		/*
2990 		 * We are finished, break the loop here.
2991 		 */
2992 		break;
2993 	    }
2994 	    else			/* pointer block full */
2995 	    {
2996 		/*
2997 		 * split the pointer block
2998 		 * allocate a new pointer block
2999 		 * move some of the pointer into the new block
3000 		 * prepare for updating the parent block
3001 		 */
3002 		for (;;)	/* do this twice when splitting block 1 */
3003 		{
3004 		    hp_new = ml_new_ptr(mfp);
3005 		    if (hp_new == NULL)	    /* TODO: try to fix tree */
3006 			return FAIL;
3007 		    pp_new = (PTR_BL *)(hp_new->bh_data);
3008 
3009 		    if (hp->bh_bnum != 1)
3010 			break;
3011 
3012 		    /*
3013 		     * if block 1 becomes full the tree is given an extra level
3014 		     * The pointers from block 1 are moved into the new block.
3015 		     * block 1 is updated to point to the new block
3016 		     * then continue to split the new block
3017 		     */
3018 		    mch_memmove(pp_new, pp, (size_t)page_size);
3019 		    pp->pb_count = 1;
3020 		    pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum;
3021 		    pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
3022 		    pp->pb_pointer[0].pe_old_lnum = 1;
3023 		    pp->pb_pointer[0].pe_page_count = 1;
3024 		    mf_put(mfp, hp, TRUE, FALSE);   /* release block 1 */
3025 		    hp = hp_new;		/* new block is to be split */
3026 		    pp = pp_new;
3027 		    CHECK(stack_idx != 0, _("stack_idx should be 0"));
3028 		    ip->ip_index = 0;
3029 		    ++stack_idx;	/* do block 1 again later */
3030 		}
3031 		/*
3032 		 * move the pointers after the current one to the new block
3033 		 * If there are none, the new entry will be in the new block.
3034 		 */
3035 		total_moved = pp->pb_count - pb_idx - 1;
3036 		if (total_moved)
3037 		{
3038 		    mch_memmove(&pp_new->pb_pointer[0],
3039 				&pp->pb_pointer[pb_idx + 1],
3040 				(size_t)(total_moved) * sizeof(PTR_EN));
3041 		    pp_new->pb_count = total_moved;
3042 		    pp->pb_count -= total_moved - 1;
3043 		    pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
3044 		    pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
3045 		    pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
3046 		    if (lnum_right)
3047 			pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
3048 		}
3049 		else
3050 		{
3051 		    pp_new->pb_count = 1;
3052 		    pp_new->pb_pointer[0].pe_bnum = bnum_right;
3053 		    pp_new->pb_pointer[0].pe_line_count = line_count_right;
3054 		    pp_new->pb_pointer[0].pe_page_count = page_count_right;
3055 		    pp_new->pb_pointer[0].pe_old_lnum = lnum_right;
3056 		}
3057 		pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
3058 		pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
3059 		pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
3060 		if (lnum_left)
3061 		    pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
3062 		lnum_left = 0;
3063 		lnum_right = 0;
3064 
3065 		/*
3066 		 * recompute line counts
3067 		 */
3068 		line_count_right = 0;
3069 		for (i = 0; i < (int)pp_new->pb_count; ++i)
3070 		    line_count_right += pp_new->pb_pointer[i].pe_line_count;
3071 		line_count_left = 0;
3072 		for (i = 0; i < (int)pp->pb_count; ++i)
3073 		    line_count_left += pp->pb_pointer[i].pe_line_count;
3074 
3075 		bnum_left = hp->bh_bnum;
3076 		bnum_right = hp_new->bh_bnum;
3077 		page_count_left = 1;
3078 		page_count_right = 1;
3079 		mf_put(mfp, hp, TRUE, FALSE);
3080 		mf_put(mfp, hp_new, TRUE, FALSE);
3081 	    }
3082 	}
3083 
3084 	/*
3085 	 * Safety check: fallen out of for loop?
3086 	 */
3087 	if (stack_idx < 0)
3088 	{
3089 	    EMSG(_("E318: Updated too many blocks?"));
3090 	    buf->b_ml.ml_stack_top = 0;	/* invalidate stack */
3091 	}
3092     }
3093 
3094 #ifdef FEAT_BYTEOFF
3095     /* The line was inserted below 'lnum' */
3096     ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE);
3097 #endif
3098 #ifdef FEAT_NETBEANS_INTG
3099     if (netbeans_active())
3100     {
3101 	if (STRLEN(line) > 0)
3102 	    netbeans_inserted(buf, lnum+1, (colnr_T)0, line, (int)STRLEN(line));
3103 	netbeans_inserted(buf, lnum+1, (colnr_T)STRLEN(line),
3104 							   (char_u *)"\n", 1);
3105     }
3106 #endif
3107     return OK;
3108 }
3109 
3110 /*
3111  * Replace line lnum, with buffering, in current buffer.
3112  *
3113  * If "copy" is TRUE, make a copy of the line, otherwise the line has been
3114  * copied to allocated memory already.
3115  *
3116  * Check: The caller of this function should probably also call
3117  * changed_lines(), unless update_screen(NOT_VALID) is used.
3118  *
3119  * return FAIL for failure, OK otherwise
3120  */
3121     int
3122 ml_replace(lnum, line, copy)
3123     linenr_T	lnum;
3124     char_u	*line;
3125     int		copy;
3126 {
3127     if (line == NULL)		/* just checking... */
3128 	return FAIL;
3129 
3130     /* When starting up, we might still need to create the memfile */
3131     if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
3132 	return FAIL;
3133 
3134     if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */
3135 	return FAIL;
3136 #ifdef FEAT_NETBEANS_INTG
3137     if (netbeans_active())
3138     {
3139 	netbeans_removed(curbuf, lnum, 0, (long)STRLEN(ml_get(lnum)));
3140 	netbeans_inserted(curbuf, lnum, 0, line, (int)STRLEN(line));
3141     }
3142 #endif
3143     if (curbuf->b_ml.ml_line_lnum != lnum)	    /* other line buffered */
3144 	ml_flush_line(curbuf);			    /* flush it */
3145     else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */
3146 	vim_free(curbuf->b_ml.ml_line_ptr);	    /* free it */
3147     curbuf->b_ml.ml_line_ptr = line;
3148     curbuf->b_ml.ml_line_lnum = lnum;
3149     curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
3150 
3151     return OK;
3152 }
3153 
3154 /*
3155  * Delete line 'lnum' in the current buffer.
3156  *
3157  * Check: The caller of this function should probably also call
3158  * deleted_lines() after this.
3159  *
3160  * return FAIL for failure, OK otherwise
3161  */
3162     int
3163 ml_delete(lnum, message)
3164     linenr_T	lnum;
3165     int		message;
3166 {
3167     ml_flush_line(curbuf);
3168     return ml_delete_int(curbuf, lnum, message);
3169 }
3170 
3171     static int
3172 ml_delete_int(buf, lnum, message)
3173     buf_T	*buf;
3174     linenr_T	lnum;
3175     int		message;
3176 {
3177     bhdr_T	*hp;
3178     memfile_T	*mfp;
3179     DATA_BL	*dp;
3180     PTR_BL	*pp;
3181     infoptr_T	*ip;
3182     int		count;	    /* number of entries in block */
3183     int		idx;
3184     int		stack_idx;
3185     int		text_start;
3186     int		line_start;
3187     long	line_size;
3188     int		i;
3189 
3190     if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
3191 	return FAIL;
3192 
3193     if (lowest_marked && lowest_marked > lnum)
3194 	lowest_marked--;
3195 
3196 /*
3197  * If the file becomes empty the last line is replaced by an empty line.
3198  */
3199     if (buf->b_ml.ml_line_count == 1)	    /* file becomes empty */
3200     {
3201 	if (message
3202 #ifdef FEAT_NETBEANS_INTG
3203 		&& !netbeansSuppressNoLines
3204 #endif
3205 	   )
3206 	    set_keep_msg((char_u *)_(no_lines_msg), 0);
3207 
3208 	/* FEAT_BYTEOFF already handled in there, don't worry 'bout it below */
3209 	i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
3210 	buf->b_ml.ml_flags |= ML_EMPTY;
3211 
3212 	return i;
3213     }
3214 
3215 /*
3216  * find the data block containing the line
3217  * This also fills the stack with the blocks from the root to the data block
3218  * This also releases any locked block.
3219  */
3220     mfp = buf->b_ml.ml_mfp;
3221     if (mfp == NULL)
3222 	return FAIL;
3223 
3224     if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
3225 	return FAIL;
3226 
3227     dp = (DATA_BL *)(hp->bh_data);
3228     /* compute line count before the delete */
3229     count = (long)(buf->b_ml.ml_locked_high)
3230 					- (long)(buf->b_ml.ml_locked_low) + 2;
3231     idx = lnum - buf->b_ml.ml_locked_low;
3232 
3233     --buf->b_ml.ml_line_count;
3234 
3235     line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
3236     if (idx == 0)		/* first line in block, text at the end */
3237 	line_size = dp->db_txt_end - line_start;
3238     else
3239 	line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
3240 
3241 #ifdef FEAT_NETBEANS_INTG
3242     if (netbeans_active())
3243 	netbeans_removed(buf, lnum, 0, (long)line_size);
3244 #endif
3245 
3246 /*
3247  * special case: If there is only one line in the data block it becomes empty.
3248  * Then we have to remove the entry, pointing to this data block, from the
3249  * pointer block. If this pointer block also becomes empty, we go up another
3250  * block, and so on, up to the root if necessary.
3251  * The line counts in the pointer blocks have already been adjusted by
3252  * ml_find_line().
3253  */
3254     if (count == 1)
3255     {
3256 	mf_free(mfp, hp);	/* free the data block */
3257 	buf->b_ml.ml_locked = NULL;
3258 
3259 	for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
3260 								  --stack_idx)
3261 	{
3262 	    buf->b_ml.ml_stack_top = 0;	    /* stack is invalid when failing */
3263 	    ip = &(buf->b_ml.ml_stack[stack_idx]);
3264 	    idx = ip->ip_index;
3265 	    if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
3266 		return FAIL;
3267 	    pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
3268 	    if (pp->pb_id != PTR_ID)
3269 	    {
3270 		EMSG(_("E317: pointer block id wrong 4"));
3271 		mf_put(mfp, hp, FALSE, FALSE);
3272 		return FAIL;
3273 	    }
3274 	    count = --(pp->pb_count);
3275 	    if (count == 0)	    /* the pointer block becomes empty! */
3276 		mf_free(mfp, hp);
3277 	    else
3278 	    {
3279 		if (count != idx)	/* move entries after the deleted one */
3280 		    mch_memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
3281 				      (size_t)(count - idx) * sizeof(PTR_EN));
3282 		mf_put(mfp, hp, TRUE, FALSE);
3283 
3284 		buf->b_ml.ml_stack_top = stack_idx;	/* truncate stack */
3285 		/* fix line count for rest of blocks in the stack */
3286 		if (buf->b_ml.ml_locked_lineadd != 0)
3287 		{
3288 		    ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
3289 		    buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
3290 						  buf->b_ml.ml_locked_lineadd;
3291 		}
3292 		++(buf->b_ml.ml_stack_top);
3293 
3294 		break;
3295 	    }
3296 	}
3297 	CHECK(stack_idx < 0, _("deleted block 1?"));
3298     }
3299     else
3300     {
3301 	/*
3302 	 * delete the text by moving the next lines forwards
3303 	 */
3304 	text_start = dp->db_txt_start;
3305 	mch_memmove((char *)dp + text_start + line_size,
3306 		  (char *)dp + text_start, (size_t)(line_start - text_start));
3307 
3308 	/*
3309 	 * delete the index by moving the next indexes backwards
3310 	 * Adjust the indexes for the text movement.
3311 	 */
3312 	for (i = idx; i < count - 1; ++i)
3313 	    dp->db_index[i] = dp->db_index[i + 1] + line_size;
3314 
3315 	dp->db_free += line_size + INDEX_SIZE;
3316 	dp->db_txt_start += line_size;
3317 	--(dp->db_line_count);
3318 
3319 	/*
3320 	 * mark the block dirty and make sure it is in the file (for recovery)
3321 	 */
3322 	buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
3323     }
3324 
3325 #ifdef FEAT_BYTEOFF
3326     ml_updatechunk(buf, lnum, line_size, ML_CHNK_DELLINE);
3327 #endif
3328     return OK;
3329 }
3330 
3331 /*
3332  * set the B_MARKED flag for line 'lnum'
3333  */
3334     void
3335 ml_setmarked(lnum)
3336     linenr_T lnum;
3337 {
3338     bhdr_T    *hp;
3339     DATA_BL *dp;
3340 				    /* invalid line number */
3341     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count
3342 					       || curbuf->b_ml.ml_mfp == NULL)
3343 	return;			    /* give error message? */
3344 
3345     if (lowest_marked == 0 || lowest_marked > lnum)
3346 	lowest_marked = lnum;
3347 
3348     /*
3349      * find the data block containing the line
3350      * This also fills the stack with the blocks from the root to the data block
3351      * This also releases any locked block.
3352      */
3353     if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
3354 	return;		    /* give error message? */
3355 
3356     dp = (DATA_BL *)(hp->bh_data);
3357     dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
3358     curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
3359 }
3360 
3361 /*
3362  * find the first line with its B_MARKED flag set
3363  */
3364     linenr_T
3365 ml_firstmarked()
3366 {
3367     bhdr_T	*hp;
3368     DATA_BL	*dp;
3369     linenr_T	lnum;
3370     int		i;
3371 
3372     if (curbuf->b_ml.ml_mfp == NULL)
3373 	return (linenr_T) 0;
3374 
3375     /*
3376      * The search starts with lowest_marked line. This is the last line where
3377      * a mark was found, adjusted by inserting/deleting lines.
3378      */
3379     for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
3380     {
3381 	/*
3382 	 * Find the data block containing the line.
3383 	 * This also fills the stack with the blocks from the root to the data
3384 	 * block This also releases any locked block.
3385 	 */
3386 	if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
3387 	    return (linenr_T)0;		    /* give error message? */
3388 
3389 	dp = (DATA_BL *)(hp->bh_data);
3390 
3391 	for (i = lnum - curbuf->b_ml.ml_locked_low;
3392 			    lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
3393 	    if ((dp->db_index[i]) & DB_MARKED)
3394 	    {
3395 		(dp->db_index[i]) &= DB_INDEX_MASK;
3396 		curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
3397 		lowest_marked = lnum + 1;
3398 		return lnum;
3399 	    }
3400     }
3401 
3402     return (linenr_T) 0;
3403 }
3404 
3405 /*
3406  * clear all DB_MARKED flags
3407  */
3408     void
3409 ml_clearmarked()
3410 {
3411     bhdr_T	*hp;
3412     DATA_BL	*dp;
3413     linenr_T	lnum;
3414     int		i;
3415 
3416     if (curbuf->b_ml.ml_mfp == NULL)	    /* nothing to do */
3417 	return;
3418 
3419     /*
3420      * The search starts with line lowest_marked.
3421      */
3422     for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
3423     {
3424 	/*
3425 	 * Find the data block containing the line.
3426 	 * This also fills the stack with the blocks from the root to the data
3427 	 * block and releases any locked block.
3428 	 */
3429 	if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
3430 	    return;		/* give error message? */
3431 
3432 	dp = (DATA_BL *)(hp->bh_data);
3433 
3434 	for (i = lnum - curbuf->b_ml.ml_locked_low;
3435 			    lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
3436 	    if ((dp->db_index[i]) & DB_MARKED)
3437 	    {
3438 		(dp->db_index[i]) &= DB_INDEX_MASK;
3439 		curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
3440 	    }
3441     }
3442 
3443     lowest_marked = 0;
3444     return;
3445 }
3446 
3447 /*
3448  * flush ml_line if necessary
3449  */
3450     static void
3451 ml_flush_line(buf)
3452     buf_T	*buf;
3453 {
3454     bhdr_T	*hp;
3455     DATA_BL	*dp;
3456     linenr_T	lnum;
3457     char_u	*new_line;
3458     char_u	*old_line;
3459     colnr_T	new_len;
3460     int		old_len;
3461     int		extra;
3462     int		idx;
3463     int		start;
3464     int		count;
3465     int		i;
3466     static int  entered = FALSE;
3467 
3468     if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL)
3469 	return;		/* nothing to do */
3470 
3471     if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
3472     {
3473 	/* This code doesn't work recursively, but Netbeans may call back here
3474 	 * when obtaining the cursor position. */
3475 	if (entered)
3476 	    return;
3477 	entered = TRUE;
3478 
3479 	lnum = buf->b_ml.ml_line_lnum;
3480 	new_line = buf->b_ml.ml_line_ptr;
3481 
3482 	hp = ml_find_line(buf, lnum, ML_FIND);
3483 	if (hp == NULL)
3484 	    EMSGN(_("E320: Cannot find line %ld"), lnum);
3485 	else
3486 	{
3487 	    dp = (DATA_BL *)(hp->bh_data);
3488 	    idx = lnum - buf->b_ml.ml_locked_low;
3489 	    start = ((dp->db_index[idx]) & DB_INDEX_MASK);
3490 	    old_line = (char_u *)dp + start;
3491 	    if (idx == 0)	/* line is last in block */
3492 		old_len = dp->db_txt_end - start;
3493 	    else		/* text of previous line follows */
3494 		old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
3495 	    new_len = (colnr_T)STRLEN(new_line) + 1;
3496 	    extra = new_len - old_len;	    /* negative if lines gets smaller */
3497 
3498 	    /*
3499 	     * if new line fits in data block, replace directly
3500 	     */
3501 	    if ((int)dp->db_free >= extra)
3502 	    {
3503 		/* if the length changes and there are following lines */
3504 		count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
3505 		if (extra != 0 && idx < count - 1)
3506 		{
3507 		    /* move text of following lines */
3508 		    mch_memmove((char *)dp + dp->db_txt_start - extra,
3509 				(char *)dp + dp->db_txt_start,
3510 				(size_t)(start - dp->db_txt_start));
3511 
3512 		    /* adjust pointers of this and following lines */
3513 		    for (i = idx + 1; i < count; ++i)
3514 			dp->db_index[i] -= extra;
3515 		}
3516 		dp->db_index[idx] -= extra;
3517 
3518 		/* adjust free space */
3519 		dp->db_free -= extra;
3520 		dp->db_txt_start -= extra;
3521 
3522 		/* copy new line into the data block */
3523 		mch_memmove(old_line - extra, new_line, (size_t)new_len);
3524 		buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
3525 #ifdef FEAT_BYTEOFF
3526 		/* The else case is already covered by the insert and delete */
3527 		ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
3528 #endif
3529 	    }
3530 	    else
3531 	    {
3532 		/*
3533 		 * Cannot do it in one data block: Delete and append.
3534 		 * Append first, because ml_delete_int() cannot delete the
3535 		 * last line in a buffer, which causes trouble for a buffer
3536 		 * that has only one line.
3537 		 * Don't forget to copy the mark!
3538 		 */
3539 		/* How about handling errors??? */
3540 		(void)ml_append_int(buf, lnum, new_line, new_len, FALSE,
3541 					     (dp->db_index[idx] & DB_MARKED));
3542 		(void)ml_delete_int(buf, lnum, FALSE);
3543 	    }
3544 	}
3545 	vim_free(new_line);
3546 
3547 	entered = FALSE;
3548     }
3549 
3550     buf->b_ml.ml_line_lnum = 0;
3551 }
3552 
3553 /*
3554  * create a new, empty, data block
3555  */
3556     static bhdr_T *
3557 ml_new_data(mfp, negative, page_count)
3558     memfile_T	*mfp;
3559     int		negative;
3560     int		page_count;
3561 {
3562     bhdr_T	*hp;
3563     DATA_BL	*dp;
3564 
3565     if ((hp = mf_new(mfp, negative, page_count)) == NULL)
3566 	return NULL;
3567 
3568     dp = (DATA_BL *)(hp->bh_data);
3569     dp->db_id = DATA_ID;
3570     dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
3571     dp->db_free = dp->db_txt_start - HEADER_SIZE;
3572     dp->db_line_count = 0;
3573 
3574     return hp;
3575 }
3576 
3577 /*
3578  * create a new, empty, pointer block
3579  */
3580     static bhdr_T *
3581 ml_new_ptr(mfp)
3582     memfile_T	*mfp;
3583 {
3584     bhdr_T	*hp;
3585     PTR_BL	*pp;
3586 
3587     if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
3588 	return NULL;
3589 
3590     pp = (PTR_BL *)(hp->bh_data);
3591     pp->pb_id = PTR_ID;
3592     pp->pb_count = 0;
3593     pp->pb_count_max = (short_u)((mfp->mf_page_size - sizeof(PTR_BL))
3594 							/ sizeof(PTR_EN) + 1);
3595 
3596     return hp;
3597 }
3598 
3599 /*
3600  * lookup line 'lnum' in a memline
3601  *
3602  *   action: if ML_DELETE or ML_INSERT the line count is updated while searching
3603  *	     if ML_FLUSH only flush a locked block
3604  *	     if ML_FIND just find the line
3605  *
3606  * If the block was found it is locked and put in ml_locked.
3607  * The stack is updated to lead to the locked block. The ip_high field in
3608  * the stack is updated to reflect the last line in the block AFTER the
3609  * insert or delete, also if the pointer block has not been updated yet. But
3610  * if ml_locked != NULL ml_locked_lineadd must be added to ip_high.
3611  *
3612  * return: NULL for failure, pointer to block header otherwise
3613  */
3614     static bhdr_T *
3615 ml_find_line(buf, lnum, action)
3616     buf_T	*buf;
3617     linenr_T	lnum;
3618     int		action;
3619 {
3620     DATA_BL	*dp;
3621     PTR_BL	*pp;
3622     infoptr_T	*ip;
3623     bhdr_T	*hp;
3624     memfile_T	*mfp;
3625     linenr_T	t;
3626     blocknr_T	bnum, bnum2;
3627     int		dirty;
3628     linenr_T	low, high;
3629     int		top;
3630     int		page_count;
3631     int		idx;
3632 
3633     mfp = buf->b_ml.ml_mfp;
3634 
3635     /*
3636      * If there is a locked block check if the wanted line is in it.
3637      * If not, flush and release the locked block.
3638      * Don't do this for ML_INSERT_SAME, because the stack need to be updated.
3639      * Don't do this for ML_FLUSH, because we want to flush the locked block.
3640      * Don't do this when 'swapfile' is reset, we want to load all the blocks.
3641      */
3642     if (buf->b_ml.ml_locked)
3643     {
3644 	if (ML_SIMPLE(action)
3645 		&& buf->b_ml.ml_locked_low <= lnum
3646 		&& buf->b_ml.ml_locked_high >= lnum
3647 		&& !mf_dont_release)
3648 	{
3649 	    /* remember to update pointer blocks and stack later */
3650 	    if (action == ML_INSERT)
3651 	    {
3652 		++(buf->b_ml.ml_locked_lineadd);
3653 		++(buf->b_ml.ml_locked_high);
3654 	    }
3655 	    else if (action == ML_DELETE)
3656 	    {
3657 		--(buf->b_ml.ml_locked_lineadd);
3658 		--(buf->b_ml.ml_locked_high);
3659 	    }
3660 	    return (buf->b_ml.ml_locked);
3661 	}
3662 
3663 	mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
3664 					    buf->b_ml.ml_flags & ML_LOCKED_POS);
3665 	buf->b_ml.ml_locked = NULL;
3666 
3667 	/*
3668 	 * If lines have been added or deleted in the locked block, need to
3669 	 * update the line count in pointer blocks.
3670 	 */
3671 	if (buf->b_ml.ml_locked_lineadd != 0)
3672 	    ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
3673     }
3674 
3675     if (action == ML_FLUSH)	    /* nothing else to do */
3676 	return NULL;
3677 
3678     bnum = 1;			    /* start at the root of the tree */
3679     page_count = 1;
3680     low = 1;
3681     high = buf->b_ml.ml_line_count;
3682 
3683     if (action == ML_FIND)	/* first try stack entries */
3684     {
3685 	for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top)
3686 	{
3687 	    ip = &(buf->b_ml.ml_stack[top]);
3688 	    if (ip->ip_low <= lnum && ip->ip_high >= lnum)
3689 	    {
3690 		bnum = ip->ip_bnum;
3691 		low = ip->ip_low;
3692 		high = ip->ip_high;
3693 		buf->b_ml.ml_stack_top = top;	/* truncate stack at prev entry */
3694 		break;
3695 	    }
3696 	}
3697 	if (top < 0)
3698 	    buf->b_ml.ml_stack_top = 0;		/* not found, start at the root */
3699     }
3700     else	/* ML_DELETE or ML_INSERT */
3701 	buf->b_ml.ml_stack_top = 0;	/* start at the root */
3702 
3703 /*
3704  * search downwards in the tree until a data block is found
3705  */
3706     for (;;)
3707     {
3708 	if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
3709 	    goto error_noblock;
3710 
3711 	/*
3712 	 * update high for insert/delete
3713 	 */
3714 	if (action == ML_INSERT)
3715 	    ++high;
3716 	else if (action == ML_DELETE)
3717 	    --high;
3718 
3719 	dp = (DATA_BL *)(hp->bh_data);
3720 	if (dp->db_id == DATA_ID)	/* data block */
3721 	{
3722 	    buf->b_ml.ml_locked = hp;
3723 	    buf->b_ml.ml_locked_low = low;
3724 	    buf->b_ml.ml_locked_high = high;
3725 	    buf->b_ml.ml_locked_lineadd = 0;
3726 	    buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS);
3727 	    return hp;
3728 	}
3729 
3730 	pp = (PTR_BL *)(dp);		/* must be pointer block */
3731 	if (pp->pb_id != PTR_ID)
3732 	{
3733 	    EMSG(_("E317: pointer block id wrong"));
3734 	    goto error_block;
3735 	}
3736 
3737 	if ((top = ml_add_stack(buf)) < 0)	/* add new entry to stack */
3738 	    goto error_block;
3739 	ip = &(buf->b_ml.ml_stack[top]);
3740 	ip->ip_bnum = bnum;
3741 	ip->ip_low = low;
3742 	ip->ip_high = high;
3743 	ip->ip_index = -1;		/* index not known yet */
3744 
3745 	dirty = FALSE;
3746 	for (idx = 0; idx < (int)pp->pb_count; ++idx)
3747 	{
3748 	    t = pp->pb_pointer[idx].pe_line_count;
3749 	    CHECK(t == 0, _("pe_line_count is zero"));
3750 	    if ((low += t) > lnum)
3751 	    {
3752 		ip->ip_index = idx;
3753 		bnum = pp->pb_pointer[idx].pe_bnum;
3754 		page_count = pp->pb_pointer[idx].pe_page_count;
3755 		high = low - 1;
3756 		low -= t;
3757 
3758 		/*
3759 		 * a negative block number may have been changed
3760 		 */
3761 		if (bnum < 0)
3762 		{
3763 		    bnum2 = mf_trans_del(mfp, bnum);
3764 		    if (bnum != bnum2)
3765 		    {
3766 			bnum = bnum2;
3767 			pp->pb_pointer[idx].pe_bnum = bnum;
3768 			dirty = TRUE;
3769 		    }
3770 		}
3771 
3772 		break;
3773 	    }
3774 	}
3775 	if (idx >= (int)pp->pb_count)	    /* past the end: something wrong! */
3776 	{
3777 	    if (lnum > buf->b_ml.ml_line_count)
3778 		EMSGN(_("E322: line number out of range: %ld past the end"),
3779 					      lnum - buf->b_ml.ml_line_count);
3780 
3781 	    else
3782 		EMSGN(_("E323: line count wrong in block %ld"), bnum);
3783 	    goto error_block;
3784 	}
3785 	if (action == ML_DELETE)
3786 	{
3787 	    pp->pb_pointer[idx].pe_line_count--;
3788 	    dirty = TRUE;
3789 	}
3790 	else if (action == ML_INSERT)
3791 	{
3792 	    pp->pb_pointer[idx].pe_line_count++;
3793 	    dirty = TRUE;
3794 	}
3795 	mf_put(mfp, hp, dirty, FALSE);
3796     }
3797 
3798 error_block:
3799     mf_put(mfp, hp, FALSE, FALSE);
3800 error_noblock:
3801     /*
3802      * If action is ML_DELETE or ML_INSERT we have to correct the tree for
3803      * the incremented/decremented line counts, because there won't be a line
3804      * inserted/deleted after all.
3805      */
3806     if (action == ML_DELETE)
3807 	ml_lineadd(buf, 1);
3808     else if (action == ML_INSERT)
3809 	ml_lineadd(buf, -1);
3810     buf->b_ml.ml_stack_top = 0;
3811     return NULL;
3812 }
3813 
3814 /*
3815  * add an entry to the info pointer stack
3816  *
3817  * return -1 for failure, number of the new entry otherwise
3818  */
3819     static int
3820 ml_add_stack(buf)
3821     buf_T	*buf;
3822 {
3823     int		top;
3824     infoptr_T	*newstack;
3825 
3826     top = buf->b_ml.ml_stack_top;
3827 
3828     /* may have to increase the stack size */
3829     if (top == buf->b_ml.ml_stack_size)
3830     {
3831 	CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */
3832 
3833 	newstack = (infoptr_T *)alloc((unsigned)sizeof(infoptr_T) *
3834 					(buf->b_ml.ml_stack_size + STACK_INCR));
3835 	if (newstack == NULL)
3836 	    return -1;
3837 	if (top > 0)
3838 	    mch_memmove(newstack, buf->b_ml.ml_stack,
3839 					     (size_t)top * sizeof(infoptr_T));
3840 	vim_free(buf->b_ml.ml_stack);
3841 	buf->b_ml.ml_stack = newstack;
3842 	buf->b_ml.ml_stack_size += STACK_INCR;
3843     }
3844 
3845     buf->b_ml.ml_stack_top++;
3846     return top;
3847 }
3848 
3849 /*
3850  * Update the pointer blocks on the stack for inserted/deleted lines.
3851  * The stack itself is also updated.
3852  *
3853  * When a insert/delete line action fails, the line is not inserted/deleted,
3854  * but the pointer blocks have already been updated. That is fixed here by
3855  * walking through the stack.
3856  *
3857  * Count is the number of lines added, negative if lines have been deleted.
3858  */
3859     static void
3860 ml_lineadd(buf, count)
3861     buf_T	*buf;
3862     int		count;
3863 {
3864     int		idx;
3865     infoptr_T	*ip;
3866     PTR_BL	*pp;
3867     memfile_T	*mfp = buf->b_ml.ml_mfp;
3868     bhdr_T	*hp;
3869 
3870     for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx)
3871     {
3872 	ip = &(buf->b_ml.ml_stack[idx]);
3873 	if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
3874 	    break;
3875 	pp = (PTR_BL *)(hp->bh_data);	/* must be pointer block */
3876 	if (pp->pb_id != PTR_ID)
3877 	{
3878 	    mf_put(mfp, hp, FALSE, FALSE);
3879 	    EMSG(_("E317: pointer block id wrong 2"));
3880 	    break;
3881 	}
3882 	pp->pb_pointer[ip->ip_index].pe_line_count += count;
3883 	ip->ip_high += count;
3884 	mf_put(mfp, hp, TRUE, FALSE);
3885     }
3886 }
3887 
3888 #if defined(HAVE_READLINK) || defined(PROTO)
3889 /*
3890  * Resolve a symlink in the last component of a file name.
3891  * Note that f_resolve() does it for every part of the path, we don't do that
3892  * here.
3893  * If it worked returns OK and the resolved link in "buf[MAXPATHL]".
3894  * Otherwise returns FAIL.
3895  */
3896     int
3897 resolve_symlink(fname, buf)
3898     char_u	*fname;
3899     char_u	*buf;
3900 {
3901     char_u	tmp[MAXPATHL];
3902     int		ret;
3903     int		depth = 0;
3904 
3905     if (fname == NULL)
3906 	return FAIL;
3907 
3908     /* Put the result so far in tmp[], starting with the original name. */
3909     vim_strncpy(tmp, fname, MAXPATHL - 1);
3910 
3911     for (;;)
3912     {
3913 	/* Limit symlink depth to 100, catch recursive loops. */
3914 	if (++depth == 100)
3915 	{
3916 	    EMSG2(_("E773: Symlink loop for \"%s\""), fname);
3917 	    return FAIL;
3918 	}
3919 
3920 	ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
3921 	if (ret <= 0)
3922 	{
3923 	    if (errno == EINVAL || errno == ENOENT)
3924 	    {
3925 		/* Found non-symlink or not existing file, stop here.
3926 		 * When at the first level use the unmodified name, skip the
3927 		 * call to vim_FullName(). */
3928 		if (depth == 1)
3929 		    return FAIL;
3930 
3931 		/* Use the resolved name in tmp[]. */
3932 		break;
3933 	    }
3934 
3935 	    /* There must be some error reading links, use original name. */
3936 	    return FAIL;
3937 	}
3938 	buf[ret] = NUL;
3939 
3940 	/*
3941 	 * Check whether the symlink is relative or absolute.
3942 	 * If it's relative, build a new path based on the directory
3943 	 * portion of the filename (if any) and the path the symlink
3944 	 * points to.
3945 	 */
3946 	if (mch_isFullName(buf))
3947 	    STRCPY(tmp, buf);
3948 	else
3949 	{
3950 	    char_u *tail;
3951 
3952 	    tail = gettail(tmp);
3953 	    if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL)
3954 		return FAIL;
3955 	    STRCPY(tail, buf);
3956 	}
3957     }
3958 
3959     /*
3960      * Try to resolve the full name of the file so that the swapfile name will
3961      * be consistent even when opening a relative symlink from different
3962      * working directories.
3963      */
3964     return vim_FullName(tmp, buf, MAXPATHL, TRUE);
3965 }
3966 #endif
3967 
3968 /*
3969  * Make swap file name out of the file name and a directory name.
3970  * Returns pointer to allocated memory or NULL.
3971  */
3972     char_u *
3973 makeswapname(fname, ffname, buf, dir_name)
3974     char_u	*fname;
3975     char_u	*ffname UNUSED;
3976     buf_T	*buf;
3977     char_u	*dir_name;
3978 {
3979     char_u	*r, *s;
3980     char_u	*fname_res = fname;
3981 #ifdef HAVE_READLINK
3982     char_u	fname_buf[MAXPATHL];
3983 #endif
3984 
3985 #if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
3986     s = dir_name + STRLEN(dir_name);
3987     if (after_pathsep(dir_name, s) && s[-1] == s[-2])
3988     {			       /* Ends with '//', Use Full path */
3989 	r = NULL;
3990 	if ((s = make_percent_swname(dir_name, fname)) != NULL)
3991 	{
3992 	    r = modname(s, (char_u *)".swp", FALSE);
3993 	    vim_free(s);
3994 	}
3995 	return r;
3996     }
3997 #endif
3998 
3999 #ifdef HAVE_READLINK
4000     /* Expand symlink in the file name, so that we put the swap file with the
4001      * actual file instead of with the symlink. */
4002     if (resolve_symlink(fname, fname_buf) == OK)
4003 	fname_res = fname_buf;
4004 #endif
4005 
4006     r = buf_modname(
4007 #ifdef SHORT_FNAME
4008 	    TRUE,
4009 #else
4010 	    (buf->b_p_sn || buf->b_shortname),
4011 #endif
4012 	    fname_res,
4013 	    (char_u *)
4014 #if defined(VMS)
4015 	    "_swp",
4016 #else
4017 	    ".swp",
4018 #endif
4019 #ifdef SHORT_FNAME		/* always 8.3 file name */
4020 	    FALSE
4021 #else
4022 	    /* Prepend a '.' to the swap file name for the current directory. */
4023 	    dir_name[0] == '.' && dir_name[1] == NUL
4024 #endif
4025 	       );
4026     if (r == NULL)	    /* out of memory */
4027 	return NULL;
4028 
4029     s = get_file_in_dir(r, dir_name);
4030     vim_free(r);
4031     return s;
4032 }
4033 
4034 /*
4035  * Get file name to use for swap file or backup file.
4036  * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
4037  * option "dname".
4038  * - If "dname" is ".", return "fname" (swap file in dir of file).
4039  * - If "dname" starts with "./", insert "dname" in "fname" (swap file
4040  *   relative to dir of file).
4041  * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
4042  *   dir).
4043  *
4044  * The return value is an allocated string and can be NULL.
4045  */
4046     char_u *
4047 get_file_in_dir(fname, dname)
4048     char_u  *fname;
4049     char_u  *dname;	/* don't use "dirname", it is a global for Alpha */
4050 {
4051     char_u	*t;
4052     char_u	*tail;
4053     char_u	*retval;
4054     int		save_char;
4055 
4056     tail = gettail(fname);
4057 
4058     if (dname[0] == '.' && dname[1] == NUL)
4059 	retval = vim_strsave(fname);
4060     else if (dname[0] == '.' && vim_ispathsep(dname[1]))
4061     {
4062 	if (tail == fname)	    /* no path before file name */
4063 	    retval = concat_fnames(dname + 2, tail, TRUE);
4064 	else
4065 	{
4066 	    save_char = *tail;
4067 	    *tail = NUL;
4068 	    t = concat_fnames(fname, dname + 2, TRUE);
4069 	    *tail = save_char;
4070 	    if (t == NULL)	    /* out of memory */
4071 		retval = NULL;
4072 	    else
4073 	    {
4074 		retval = concat_fnames(t, tail, TRUE);
4075 		vim_free(t);
4076 	    }
4077 	}
4078     }
4079     else
4080 	retval = concat_fnames(dname, tail, TRUE);
4081 
4082 #ifdef WIN3264
4083     if (retval != NULL)
4084 	for (t = gettail(retval); *t != NUL; mb_ptr_adv(t))
4085 	    if (*t == ':')
4086 		*t = '%';
4087 #endif
4088 
4089     return retval;
4090 }
4091 
4092 static void attention_message __ARGS((buf_T *buf, char_u *fname));
4093 
4094 /*
4095  * Print the ATTENTION message: info about an existing swap file.
4096  */
4097     static void
4098 attention_message(buf, fname)
4099     buf_T   *buf;	/* buffer being edited */
4100     char_u  *fname;	/* swap file name */
4101 {
4102     struct stat st;
4103     time_t	x, sx;
4104     char	*p;
4105 
4106     ++no_wait_return;
4107     (void)EMSG(_("E325: ATTENTION"));
4108     MSG_PUTS(_("\nFound a swap file by the name \""));
4109     msg_home_replace(fname);
4110     MSG_PUTS("\"\n");
4111     sx = swapfile_info(fname);
4112     MSG_PUTS(_("While opening file \""));
4113     msg_outtrans(buf->b_fname);
4114     MSG_PUTS("\"\n");
4115     if (mch_stat((char *)buf->b_fname, &st) != -1)
4116     {
4117 	MSG_PUTS(_("             dated: "));
4118 	x = st.st_mtime;    /* Manx C can't do &st.st_mtime */
4119 	p = ctime(&x);			    /* includes '\n' */
4120 	if (p == NULL)
4121 	    MSG_PUTS("(invalid)\n");
4122 	else
4123 	    MSG_PUTS(p);
4124 	if (sx != 0 && x > sx)
4125 	    MSG_PUTS(_("      NEWER than swap file!\n"));
4126     }
4127     /* Some of these messages are long to allow translation to
4128      * other languages. */
4129     MSG_PUTS(_("\n(1) Another program may be editing the same file.  If this is the case,\n    be careful not to end up with two different instances of the same\n    file when making changes."));
4130     MSG_PUTS(_("  Quit, or continue with caution.\n"));
4131     MSG_PUTS(_("(2) An edit session for this file crashed.\n"));
4132     MSG_PUTS(_("    If this is the case, use \":recover\" or \"vim -r "));
4133     msg_outtrans(buf->b_fname);
4134     MSG_PUTS(_("\"\n    to recover the changes (see \":help recovery\").\n"));
4135     MSG_PUTS(_("    If you did this already, delete the swap file \""));
4136     msg_outtrans(fname);
4137     MSG_PUTS(_("\"\n    to avoid this message.\n"));
4138     cmdline_row = msg_row;
4139     --no_wait_return;
4140 }
4141 
4142 #ifdef FEAT_AUTOCMD
4143 static int do_swapexists __ARGS((buf_T *buf, char_u *fname));
4144 
4145 /*
4146  * Trigger the SwapExists autocommands.
4147  * Returns a value for equivalent to do_dialog() (see below):
4148  * 0: still need to ask for a choice
4149  * 1: open read-only
4150  * 2: edit anyway
4151  * 3: recover
4152  * 4: delete it
4153  * 5: quit
4154  * 6: abort
4155  */
4156     static int
4157 do_swapexists(buf, fname)
4158     buf_T	*buf;
4159     char_u	*fname;
4160 {
4161     set_vim_var_string(VV_SWAPNAME, fname, -1);
4162     set_vim_var_string(VV_SWAPCHOICE, NULL, -1);
4163 
4164     /* Trigger SwapExists autocommands with <afile> set to the file being
4165      * edited.  Disallow changing directory here. */
4166     ++allbuf_lock;
4167     apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL);
4168     --allbuf_lock;
4169 
4170     set_vim_var_string(VV_SWAPNAME, NULL, -1);
4171 
4172     switch (*get_vim_var_str(VV_SWAPCHOICE))
4173     {
4174 	case 'o': return 1;
4175 	case 'e': return 2;
4176 	case 'r': return 3;
4177 	case 'd': return 4;
4178 	case 'q': return 5;
4179 	case 'a': return 6;
4180     }
4181 
4182     return 0;
4183 }
4184 #endif
4185 
4186 /*
4187  * Find out what name to use for the swap file for buffer 'buf'.
4188  *
4189  * Several names are tried to find one that does not exist
4190  * Returns the name in allocated memory or NULL.
4191  * When out of memory "dirp" is set to NULL.
4192  *
4193  * Note: If BASENAMELEN is not correct, you will get error messages for
4194  *	 not being able to open the swap or undo file
4195  * Note: May trigger SwapExists autocmd, pointers may change!
4196  */
4197     static char_u *
4198 findswapname(buf, dirp, old_fname)
4199     buf_T	*buf;
4200     char_u	**dirp;		/* pointer to list of directories */
4201     char_u	*old_fname;	/* don't give warning for this file name */
4202 {
4203     char_u	*fname;
4204     int		n;
4205     char_u	*dir_name;
4206 #ifdef AMIGA
4207     BPTR	fh;
4208 #endif
4209 #ifndef SHORT_FNAME
4210     int		r;
4211 #endif
4212     char_u	*buf_fname = buf->b_fname;
4213 
4214 #if !defined(SHORT_FNAME) && !defined(UNIX)
4215 # define CREATE_DUMMY_FILE
4216     FILE	*dummyfd = NULL;
4217 
4218 # ifdef WIN3264
4219     if (buf_fname != NULL && !mch_isFullName(buf_fname)
4220 				       && vim_strchr(gettail(buf_fname), ':'))
4221     {
4222 	char_u *t;
4223 
4224 	buf_fname = vim_strsave(buf_fname);
4225 	if (buf_fname == NULL)
4226 	    buf_fname = buf->b_fname;
4227 	else
4228 	    for (t = gettail(buf_fname); *t != NUL; mb_ptr_adv(t))
4229 		if (*t == ':')
4230 		    *t = '%';
4231     }
4232 # endif
4233 
4234     /*
4235      * If we start editing a new file, e.g. "test.doc", which resides on an
4236      * MSDOS compatible filesystem, it is possible that the file
4237      * "test.doc.swp" which we create will be exactly the same file. To avoid
4238      * this problem we temporarily create "test.doc".  Don't do this when the
4239      * check below for a 8.3 file name is used.
4240      */
4241     if (!(buf->b_p_sn || buf->b_shortname) && buf_fname != NULL
4242 					     && mch_getperm(buf_fname) < 0)
4243 	dummyfd = mch_fopen((char *)buf_fname, "w");
4244 #endif
4245 
4246     /*
4247      * Isolate a directory name from *dirp and put it in dir_name.
4248      * First allocate some memory to put the directory name in.
4249      */
4250     dir_name = alloc((unsigned)STRLEN(*dirp) + 1);
4251     if (dir_name == NULL)
4252 	*dirp = NULL;
4253     else
4254 	(void)copy_option_part(dirp, dir_name, 31000, ",");
4255 
4256     /*
4257      * we try different names until we find one that does not exist yet
4258      */
4259     if (dir_name == NULL)	    /* out of memory */
4260 	fname = NULL;
4261     else
4262 	fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name);
4263 
4264     for (;;)
4265     {
4266 	if (fname == NULL)	/* must be out of memory */
4267 	    break;
4268 	if ((n = (int)STRLEN(fname)) == 0)	/* safety check */
4269 	{
4270 	    vim_free(fname);
4271 	    fname = NULL;
4272 	    break;
4273 	}
4274 #if defined(UNIX) && !defined(SHORT_FNAME)
4275 /*
4276  * Some systems have a MS-DOS compatible filesystem that use 8.3 character
4277  * file names. If this is the first try and the swap file name does not fit in
4278  * 8.3, detect if this is the case, set shortname and try again.
4279  */
4280 	if (fname[n - 2] == 'w' && fname[n - 1] == 'p'
4281 					&& !(buf->b_p_sn || buf->b_shortname))
4282 	{
4283 	    char_u	    *tail;
4284 	    char_u	    *fname2;
4285 	    struct stat	    s1, s2;
4286 	    int		    f1, f2;
4287 	    int		    created1 = FALSE, created2 = FALSE;
4288 	    int		    same = FALSE;
4289 
4290 	    /*
4291 	     * Check if swapfile name does not fit in 8.3:
4292 	     * It either contains two dots, is longer than 8 chars, or starts
4293 	     * with a dot.
4294 	     */
4295 	    tail = gettail(buf_fname);
4296 	    if (       vim_strchr(tail, '.') != NULL
4297 		    || STRLEN(tail) > (size_t)8
4298 		    || *gettail(fname) == '.')
4299 	    {
4300 		fname2 = alloc(n + 2);
4301 		if (fname2 != NULL)
4302 		{
4303 		    STRCPY(fname2, fname);
4304 		    /* if fname == "xx.xx.swp",	    fname2 = "xx.xx.swx"
4305 		     * if fname == ".xx.swp",	    fname2 = ".xx.swpx"
4306 		     * if fname == "123456789.swp", fname2 = "12345678x.swp"
4307 		     */
4308 		    if (vim_strchr(tail, '.') != NULL)
4309 			fname2[n - 1] = 'x';
4310 		    else if (*gettail(fname) == '.')
4311 		    {
4312 			fname2[n] = 'x';
4313 			fname2[n + 1] = NUL;
4314 		    }
4315 		    else
4316 			fname2[n - 5] += 1;
4317 		    /*
4318 		     * may need to create the files to be able to use mch_stat()
4319 		     */
4320 		    f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
4321 		    if (f1 < 0)
4322 		    {
4323 			f1 = mch_open_rw((char *)fname,
4324 					       O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
4325 			created1 = TRUE;
4326 		    }
4327 		    if (f1 >= 0)
4328 		    {
4329 			f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0);
4330 			if (f2 < 0)
4331 			{
4332 			    f2 = mch_open_rw((char *)fname2,
4333 					       O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
4334 			    created2 = TRUE;
4335 			}
4336 			if (f2 >= 0)
4337 			{
4338 			    /*
4339 			     * Both files exist now. If mch_stat() returns the
4340 			     * same device and inode they are the same file.
4341 			     */
4342 			    if (mch_fstat(f1, &s1) != -1
4343 				    && mch_fstat(f2, &s2) != -1
4344 				    && s1.st_dev == s2.st_dev
4345 				    && s1.st_ino == s2.st_ino)
4346 				same = TRUE;
4347 			    close(f2);
4348 			    if (created2)
4349 				mch_remove(fname2);
4350 			}
4351 			close(f1);
4352 			if (created1)
4353 			    mch_remove(fname);
4354 		    }
4355 		    vim_free(fname2);
4356 		    if (same)
4357 		    {
4358 			buf->b_shortname = TRUE;
4359 			vim_free(fname);
4360 			fname = makeswapname(buf_fname, buf->b_ffname,
4361 							       buf, dir_name);
4362 			continue;	/* try again with b_shortname set */
4363 		    }
4364 		}
4365 	    }
4366 	}
4367 #endif
4368 	/*
4369 	 * check if the swapfile already exists
4370 	 */
4371 	if (mch_getperm(fname) < 0)	/* it does not exist */
4372 	{
4373 #ifdef HAVE_LSTAT
4374 	    struct stat sb;
4375 
4376 	    /*
4377 	     * Extra security check: When a swap file is a symbolic link, this
4378 	     * is most likely a symlink attack.
4379 	     */
4380 	    if (mch_lstat((char *)fname, &sb) < 0)
4381 #else
4382 # ifdef AMIGA
4383 	    fh = Open((UBYTE *)fname, (long)MODE_NEWFILE);
4384 	    /*
4385 	     * on the Amiga mch_getperm() will return -1 when the file exists
4386 	     * but is being used by another program. This happens if you edit
4387 	     * a file twice.
4388 	     */
4389 	    if (fh != (BPTR)NULL)	/* can open file, OK */
4390 	    {
4391 		Close(fh);
4392 		mch_remove(fname);
4393 		break;
4394 	    }
4395 	    if (IoErr() != ERROR_OBJECT_IN_USE
4396 					    && IoErr() != ERROR_OBJECT_EXISTS)
4397 # endif
4398 #endif
4399 		break;
4400 	}
4401 
4402 	/*
4403 	 * A file name equal to old_fname is OK to use.
4404 	 */
4405 	if (old_fname != NULL && fnamecmp(fname, old_fname) == 0)
4406 	    break;
4407 
4408 	/*
4409 	 * get here when file already exists
4410 	 */
4411 	if (fname[n - 2] == 'w' && fname[n - 1] == 'p')	/* first try */
4412 	{
4413 #ifndef SHORT_FNAME
4414 	    /*
4415 	     * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp
4416 	     * and file.doc are the same file. To guess if this problem is
4417 	     * present try if file.doc.swx exists. If it does, we set
4418 	     * buf->b_shortname and try file_doc.swp (dots replaced by
4419 	     * underscores for this file), and try again. If it doesn't we
4420 	     * assume that "file.doc.swp" already exists.
4421 	     */
4422 	    if (!(buf->b_p_sn || buf->b_shortname))	/* not tried yet */
4423 	    {
4424 		fname[n - 1] = 'x';
4425 		r = mch_getperm(fname);		/* try "file.swx" */
4426 		fname[n - 1] = 'p';
4427 		if (r >= 0)		    /* "file.swx" seems to exist */
4428 		{
4429 		    buf->b_shortname = TRUE;
4430 		    vim_free(fname);
4431 		    fname = makeswapname(buf_fname, buf->b_ffname,
4432 							       buf, dir_name);
4433 		    continue;	    /* try again with '.' replaced with '_' */
4434 		}
4435 	    }
4436 #endif
4437 	    /*
4438 	     * If we get here the ".swp" file really exists.
4439 	     * Give an error message, unless recovering, no file name, we are
4440 	     * viewing a help file or when the path of the file is different
4441 	     * (happens when all .swp files are in one directory).
4442 	     */
4443 	    if (!recoverymode && buf_fname != NULL
4444 				&& !buf->b_help && !(buf->b_flags & BF_DUMMY))
4445 	    {
4446 		int		fd;
4447 		struct block0	b0;
4448 		int		differ = FALSE;
4449 
4450 		/*
4451 		 * Try to read block 0 from the swap file to get the original
4452 		 * file name (and inode number).
4453 		 */
4454 		fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
4455 		if (fd >= 0)
4456 		{
4457 		    if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
4458 		    {
4459 			/*
4460 			 * If the swapfile has the same directory as the
4461 			 * buffer don't compare the directory names, they can
4462 			 * have a different mountpoint.
4463 			 */
4464 			if (b0.b0_flags & B0_SAME_DIR)
4465 			{
4466 			    if (fnamecmp(gettail(buf->b_ffname),
4467 						   gettail(b0.b0_fname)) != 0
4468 				    || !same_directory(fname, buf->b_ffname))
4469 			    {
4470 #ifdef CHECK_INODE
4471 				/* Symlinks may point to the same file even
4472 				 * when the name differs, need to check the
4473 				 * inode too. */
4474 				expand_env(b0.b0_fname, NameBuff, MAXPATHL);
4475 				if (fnamecmp_ino(buf->b_ffname, NameBuff,
4476 						     char_to_long(b0.b0_ino)))
4477 #endif
4478 				    differ = TRUE;
4479 			    }
4480 			}
4481 			else
4482 			{
4483 			    /*
4484 			     * The name in the swap file may be
4485 			     * "~user/path/file".  Expand it first.
4486 			     */
4487 			    expand_env(b0.b0_fname, NameBuff, MAXPATHL);
4488 #ifdef CHECK_INODE
4489 			    if (fnamecmp_ino(buf->b_ffname, NameBuff,
4490 						     char_to_long(b0.b0_ino)))
4491 				differ = TRUE;
4492 #else
4493 			    if (fnamecmp(NameBuff, buf->b_ffname) != 0)
4494 				differ = TRUE;
4495 #endif
4496 			}
4497 		    }
4498 		    close(fd);
4499 		}
4500 
4501 		/* give the ATTENTION message when there is an old swap file
4502 		 * for the current file, and the buffer was not recovered. */
4503 		if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED)
4504 			&& vim_strchr(p_shm, SHM_ATTENTION) == NULL)
4505 		{
4506 #if defined(HAS_SWAP_EXISTS_ACTION)
4507 		    int		choice = 0;
4508 #endif
4509 #ifdef CREATE_DUMMY_FILE
4510 		    int		did_use_dummy = FALSE;
4511 
4512 		    /* Avoid getting a warning for the file being created
4513 		     * outside of Vim, it was created at the start of this
4514 		     * function.  Delete the file now, because Vim might exit
4515 		     * here if the window is closed. */
4516 		    if (dummyfd != NULL)
4517 		    {
4518 			fclose(dummyfd);
4519 			dummyfd = NULL;
4520 			mch_remove(buf_fname);
4521 			did_use_dummy = TRUE;
4522 		    }
4523 #endif
4524 
4525 #if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
4526 		    process_still_running = FALSE;
4527 #endif
4528 #ifdef FEAT_AUTOCMD
4529 		    /*
4530 		     * If there is an SwapExists autocommand and we can handle
4531 		     * the response, trigger it.  It may return 0 to ask the
4532 		     * user anyway.
4533 		     */
4534 		    if (swap_exists_action != SEA_NONE
4535 			    && has_autocmd(EVENT_SWAPEXISTS, buf_fname, buf))
4536 			choice = do_swapexists(buf, fname);
4537 
4538 		    if (choice == 0)
4539 #endif
4540 		    {
4541 #ifdef FEAT_GUI
4542 			/* If we are supposed to start the GUI but it wasn't
4543 			 * completely started yet, start it now.  This makes
4544 			 * the messages displayed in the Vim window when
4545 			 * loading a session from the .gvimrc file. */
4546 			if (gui.starting && !gui.in_use)
4547 			    gui_start();
4548 #endif
4549 			/* Show info about the existing swap file. */
4550 			attention_message(buf, fname);
4551 
4552 			/* We don't want a 'q' typed at the more-prompt
4553 			 * interrupt loading a file. */
4554 			got_int = FALSE;
4555 		    }
4556 
4557 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
4558 		    if (swap_exists_action != SEA_NONE && choice == 0)
4559 		    {
4560 			char_u	*name;
4561 
4562 			name = alloc((unsigned)(STRLEN(fname)
4563 				+ STRLEN(_("Swap file \""))
4564 				+ STRLEN(_("\" already exists!")) + 5));
4565 			if (name != NULL)
4566 			{
4567 			    STRCPY(name, _("Swap file \""));
4568 			    home_replace(NULL, fname, name + STRLEN(name),
4569 								  1000, TRUE);
4570 			    STRCAT(name, _("\" already exists!"));
4571 			}
4572 			choice = do_dialog(VIM_WARNING,
4573 				    (char_u *)_("VIM - ATTENTION"),
4574 				    name == NULL
4575 					?  (char_u *)_("Swap file already exists!")
4576 					: name,
4577 # if defined(UNIX) || defined(__EMX__) || defined(VMS)
4578 				    process_still_running
4579 					? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") :
4580 # endif
4581 					(char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"), 1, NULL, FALSE);
4582 
4583 # if defined(UNIX) || defined(__EMX__) || defined(VMS)
4584 			if (process_still_running && choice >= 4)
4585 			    choice++;	/* Skip missing "Delete it" button */
4586 # endif
4587 			vim_free(name);
4588 
4589 			/* pretend screen didn't scroll, need redraw anyway */
4590 			msg_scrolled = 0;
4591 			redraw_all_later(NOT_VALID);
4592 		    }
4593 #endif
4594 
4595 #if defined(HAS_SWAP_EXISTS_ACTION)
4596 		    if (choice > 0)
4597 		    {
4598 			switch (choice)
4599 			{
4600 			    case 1:
4601 				buf->b_p_ro = TRUE;
4602 				break;
4603 			    case 2:
4604 				break;
4605 			    case 3:
4606 				swap_exists_action = SEA_RECOVER;
4607 				break;
4608 			    case 4:
4609 				mch_remove(fname);
4610 				break;
4611 			    case 5:
4612 				swap_exists_action = SEA_QUIT;
4613 				break;
4614 			    case 6:
4615 				swap_exists_action = SEA_QUIT;
4616 				got_int = TRUE;
4617 				break;
4618 			}
4619 
4620 			/* If the file was deleted this fname can be used. */
4621 			if (mch_getperm(fname) < 0)
4622 			    break;
4623 		    }
4624 		    else
4625 #endif
4626 		    {
4627 			MSG_PUTS("\n");
4628 			if (msg_silent == 0)
4629 			    /* call wait_return() later */
4630 			    need_wait_return = TRUE;
4631 		    }
4632 
4633 #ifdef CREATE_DUMMY_FILE
4634 		    /* Going to try another name, need the dummy file again. */
4635 		    if (did_use_dummy)
4636 			dummyfd = mch_fopen((char *)buf_fname, "w");
4637 #endif
4638 		}
4639 	    }
4640 	}
4641 
4642 	/*
4643 	 * Change the ".swp" extension to find another file that can be used.
4644 	 * First decrement the last char: ".swo", ".swn", etc.
4645 	 * If that still isn't enough decrement the last but one char: ".svz"
4646 	 * Can happen when editing many "No Name" buffers.
4647 	 */
4648 	if (fname[n - 1] == 'a')	/* ".s?a" */
4649 	{
4650 	    if (fname[n - 2] == 'a')    /* ".saa": tried enough, give up */
4651 	    {
4652 		EMSG(_("E326: Too many swap files found"));
4653 		vim_free(fname);
4654 		fname = NULL;
4655 		break;
4656 	    }
4657 	    --fname[n - 2];		/* ".svz", ".suz", etc. */
4658 	    fname[n - 1] = 'z' + 1;
4659 	}
4660 	--fname[n - 1];			/* ".swo", ".swn", etc. */
4661     }
4662 
4663     vim_free(dir_name);
4664 #ifdef CREATE_DUMMY_FILE
4665     if (dummyfd != NULL)	/* file has been created temporarily */
4666     {
4667 	fclose(dummyfd);
4668 	mch_remove(buf_fname);
4669     }
4670 #endif
4671 #ifdef WIN3264
4672     if (buf_fname != buf->b_fname)
4673 	vim_free(buf_fname);
4674 #endif
4675     return fname;
4676 }
4677 
4678     static int
4679 b0_magic_wrong(b0p)
4680     ZERO_BL *b0p;
4681 {
4682     return (b0p->b0_magic_long != (long)B0_MAGIC_LONG
4683 	    || b0p->b0_magic_int != (int)B0_MAGIC_INT
4684 	    || b0p->b0_magic_short != (short)B0_MAGIC_SHORT
4685 	    || b0p->b0_magic_char != B0_MAGIC_CHAR);
4686 }
4687 
4688 #ifdef CHECK_INODE
4689 /*
4690  * Compare current file name with file name from swap file.
4691  * Try to use inode numbers when possible.
4692  * Return non-zero when files are different.
4693  *
4694  * When comparing file names a few things have to be taken into consideration:
4695  * - When working over a network the full path of a file depends on the host.
4696  *   We check the inode number if possible.  It is not 100% reliable though,
4697  *   because the device number cannot be used over a network.
4698  * - When a file does not exist yet (editing a new file) there is no inode
4699  *   number.
4700  * - The file name in a swap file may not be valid on the current host.  The
4701  *   "~user" form is used whenever possible to avoid this.
4702  *
4703  * This is getting complicated, let's make a table:
4704  *
4705  *		ino_c  ino_s  fname_c  fname_s	differ =
4706  *
4707  * both files exist -> compare inode numbers:
4708  *		!= 0   != 0	X	 X	ino_c != ino_s
4709  *
4710  * inode number(s) unknown, file names available -> compare file names
4711  *		== 0	X	OK	 OK	fname_c != fname_s
4712  *		 X     == 0	OK	 OK	fname_c != fname_s
4713  *
4714  * current file doesn't exist, file for swap file exist, file name(s) not
4715  * available -> probably different
4716  *		== 0   != 0    FAIL	 X	TRUE
4717  *		== 0   != 0	X	FAIL	TRUE
4718  *
4719  * current file exists, inode for swap unknown, file name(s) not
4720  * available -> probably different
4721  *		!= 0   == 0    FAIL	 X	TRUE
4722  *		!= 0   == 0	X	FAIL	TRUE
4723  *
4724  * current file doesn't exist, inode for swap unknown, one file name not
4725  * available -> probably different
4726  *		== 0   == 0    FAIL	 OK	TRUE
4727  *		== 0   == 0	OK	FAIL	TRUE
4728  *
4729  * current file doesn't exist, inode for swap unknown, both file names not
4730  * available -> probably same file
4731  *		== 0   == 0    FAIL	FAIL	FALSE
4732  *
4733  * Note that when the ino_t is 64 bits, only the last 32 will be used.  This
4734  * can't be changed without making the block 0 incompatible with 32 bit
4735  * versions.
4736  */
4737 
4738     static int
4739 fnamecmp_ino(fname_c, fname_s, ino_block0)
4740     char_u	*fname_c;	    /* current file name */
4741     char_u	*fname_s;	    /* file name from swap file */
4742     long	ino_block0;
4743 {
4744     struct stat	st;
4745     ino_t	ino_c = 0;	    /* ino of current file */
4746     ino_t	ino_s;		    /* ino of file from swap file */
4747     char_u	buf_c[MAXPATHL];    /* full path of fname_c */
4748     char_u	buf_s[MAXPATHL];    /* full path of fname_s */
4749     int		retval_c;	    /* flag: buf_c valid */
4750     int		retval_s;	    /* flag: buf_s valid */
4751 
4752     if (mch_stat((char *)fname_c, &st) == 0)
4753 	ino_c = (ino_t)st.st_ino;
4754 
4755     /*
4756      * First we try to get the inode from the file name, because the inode in
4757      * the swap file may be outdated.  If that fails (e.g. this path is not
4758      * valid on this machine), use the inode from block 0.
4759      */
4760     if (mch_stat((char *)fname_s, &st) == 0)
4761 	ino_s = (ino_t)st.st_ino;
4762     else
4763 	ino_s = (ino_t)ino_block0;
4764 
4765     if (ino_c && ino_s)
4766 	return (ino_c != ino_s);
4767 
4768     /*
4769      * One of the inode numbers is unknown, try a forced vim_FullName() and
4770      * compare the file names.
4771      */
4772     retval_c = vim_FullName(fname_c, buf_c, MAXPATHL, TRUE);
4773     retval_s = vim_FullName(fname_s, buf_s, MAXPATHL, TRUE);
4774     if (retval_c == OK && retval_s == OK)
4775 	return (STRCMP(buf_c, buf_s) != 0);
4776 
4777     /*
4778      * Can't compare inodes or file names, guess that the files are different,
4779      * unless both appear not to exist at all.
4780      */
4781     if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL)
4782 	return FALSE;
4783     return TRUE;
4784 }
4785 #endif /* CHECK_INODE */
4786 
4787 /*
4788  * Move a long integer into a four byte character array.
4789  * Used for machine independency in block zero.
4790  */
4791     static void
4792 long_to_char(n, s)
4793     long    n;
4794     char_u  *s;
4795 {
4796     s[0] = (char_u)(n & 0xff);
4797     n = (unsigned)n >> 8;
4798     s[1] = (char_u)(n & 0xff);
4799     n = (unsigned)n >> 8;
4800     s[2] = (char_u)(n & 0xff);
4801     n = (unsigned)n >> 8;
4802     s[3] = (char_u)(n & 0xff);
4803 }
4804 
4805     static long
4806 char_to_long(s)
4807     char_u  *s;
4808 {
4809     long    retval;
4810 
4811     retval = s[3];
4812     retval <<= 8;
4813     retval |= s[2];
4814     retval <<= 8;
4815     retval |= s[1];
4816     retval <<= 8;
4817     retval |= s[0];
4818 
4819     return retval;
4820 }
4821 
4822 /*
4823  * Set the flags in the first block of the swap file:
4824  * - file is modified or not: buf->b_changed
4825  * - 'fileformat'
4826  * - 'fileencoding'
4827  */
4828     void
4829 ml_setflags(buf)
4830     buf_T	*buf;
4831 {
4832     bhdr_T	*hp;
4833     ZERO_BL	*b0p;
4834 
4835     if (!buf->b_ml.ml_mfp)
4836 	return;
4837     for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
4838     {
4839 	if (hp->bh_bnum == 0)
4840 	{
4841 	    b0p = (ZERO_BL *)(hp->bh_data);
4842 	    b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
4843 	    b0p->b0_flags = (b0p->b0_flags & ~B0_FF_MASK)
4844 						  | (get_fileformat(buf) + 1);
4845 #ifdef FEAT_MBYTE
4846 	    add_b0_fenc(b0p, buf);
4847 #endif
4848 	    hp->bh_flags |= BH_DIRTY;
4849 	    mf_sync(buf->b_ml.ml_mfp, MFS_ZERO);
4850 	    break;
4851 	}
4852     }
4853 }
4854 
4855 #if defined(FEAT_CRYPT) || defined(PROTO)
4856 /*
4857  * If "data" points to a data block encrypt the text in it and return a copy
4858  * in allocated memory.  Return NULL when out of memory.
4859  * Otherwise return "data".
4860  */
4861     char_u *
4862 ml_encrypt_data(mfp, data, offset, size)
4863     memfile_T	*mfp;
4864     char_u	*data;
4865     off_t	offset;
4866     unsigned	size;
4867 {
4868     DATA_BL	*dp = (DATA_BL *)data;
4869     char_u	*head_end;
4870     char_u	*text_start;
4871     char_u	*new_data;
4872     int		text_len;
4873     cryptstate_T *state;
4874 
4875     if (dp->db_id != DATA_ID)
4876 	return data;
4877 
4878     state = ml_crypt_prepare(mfp, offset, FALSE);
4879     if (state == NULL)
4880 	return data;
4881 
4882     new_data = (char_u *)alloc(size);
4883     if (new_data == NULL)
4884 	return NULL;
4885     head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
4886     text_start = (char_u *)dp + dp->db_txt_start;
4887     text_len = size - dp->db_txt_start;
4888 
4889     /* Copy the header and the text. */
4890     mch_memmove(new_data, dp, head_end - (char_u *)dp);
4891 
4892     /* Encrypt the text. */
4893     crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start);
4894     crypt_free_state(state);
4895 
4896     /* Clear the gap. */
4897     if (head_end < text_start)
4898 	vim_memset(new_data + (head_end - data), 0, text_start - head_end);
4899 
4900     return new_data;
4901 }
4902 
4903 /*
4904  * Decrypt the text in "data" if it points to an encrypted data block.
4905  */
4906     void
4907 ml_decrypt_data(mfp, data, offset, size)
4908     memfile_T	*mfp;
4909     char_u	*data;
4910     off_t	offset;
4911     unsigned	size;
4912 {
4913     DATA_BL	*dp = (DATA_BL *)data;
4914     char_u	*head_end;
4915     char_u	*text_start;
4916     int		text_len;
4917     cryptstate_T *state;
4918 
4919     if (dp->db_id == DATA_ID)
4920     {
4921 	head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
4922 	text_start = (char_u *)dp + dp->db_txt_start;
4923 	text_len = dp->db_txt_end - dp->db_txt_start;
4924 
4925 	if (head_end > text_start || dp->db_txt_start > size
4926 						     || dp->db_txt_end > size)
4927 	    return;  /* data was messed up */
4928 
4929 	state = ml_crypt_prepare(mfp, offset, TRUE);
4930 	if (state != NULL)
4931 	{
4932 	    /* Decrypt the text in place. */
4933 	    crypt_decode_inplace(state, text_start, text_len);
4934 	    crypt_free_state(state);
4935 	}
4936     }
4937 }
4938 
4939 /*
4940  * Prepare for encryption/decryption, using the key, seed and offset.
4941  * Return an allocated cryptstate_T *.
4942  */
4943     static cryptstate_T *
4944 ml_crypt_prepare(mfp, offset, reading)
4945     memfile_T	*mfp;
4946     off_t	offset;
4947     int		reading;
4948 {
4949     buf_T	*buf = mfp->mf_buffer;
4950     char_u	salt[50];
4951     int		method_nr;
4952     char_u	*key;
4953     char_u	*seed;
4954 
4955     if (reading && mfp->mf_old_key != NULL)
4956     {
4957 	/* Reading back blocks with the previous key/method/seed. */
4958 	method_nr = mfp->mf_old_cm;
4959 	key = mfp->mf_old_key;
4960 	seed = mfp->mf_old_seed;
4961     }
4962     else
4963     {
4964 	method_nr = crypt_get_method_nr(buf);
4965 	key = buf->b_p_key;
4966 	seed = mfp->mf_seed;
4967     }
4968     if (*key == NUL)
4969 	return NULL;
4970 
4971     if (method_nr == CRYPT_M_ZIP)
4972     {
4973 	/* For PKzip: Append the offset to the key, so that we use a different
4974 	 * key for every block. */
4975 	vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset);
4976 	return crypt_create(method_nr, salt, NULL, 0, NULL, 0);
4977     }
4978 
4979     /* Using blowfish or better: add salt and seed. We use the byte offset
4980      * of the block for the salt. */
4981     vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
4982     return crypt_create(method_nr, key, salt, (int)STRLEN(salt),
4983 							   seed, MF_SEED_LEN);
4984 }
4985 
4986 #endif
4987 
4988 
4989 #if defined(FEAT_BYTEOFF) || defined(PROTO)
4990 
4991 #define MLCS_MAXL 800	/* max no of lines in chunk */
4992 #define MLCS_MINL 400   /* should be half of MLCS_MAXL */
4993 
4994 /*
4995  * Keep information for finding byte offset of a line, updtype may be one of:
4996  * ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it
4997  *	   Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
4998  * ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
4999  * ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
5000  */
5001     static void
5002 ml_updatechunk(buf, line, len, updtype)
5003     buf_T	*buf;
5004     linenr_T	line;
5005     long	len;
5006     int		updtype;
5007 {
5008     static buf_T	*ml_upd_lastbuf = NULL;
5009     static linenr_T	ml_upd_lastline;
5010     static linenr_T	ml_upd_lastcurline;
5011     static int		ml_upd_lastcurix;
5012 
5013     linenr_T		curline = ml_upd_lastcurline;
5014     int			curix = ml_upd_lastcurix;
5015     long		size;
5016     chunksize_T		*curchnk;
5017     int			rest;
5018     bhdr_T		*hp;
5019     DATA_BL		*dp;
5020 
5021     if (buf->b_ml.ml_usedchunks == -1 || len == 0)
5022 	return;
5023     if (buf->b_ml.ml_chunksize == NULL)
5024     {
5025 	buf->b_ml.ml_chunksize = (chunksize_T *)
5026 				  alloc((unsigned)sizeof(chunksize_T) * 100);
5027 	if (buf->b_ml.ml_chunksize == NULL)
5028 	{
5029 	    buf->b_ml.ml_usedchunks = -1;
5030 	    return;
5031 	}
5032 	buf->b_ml.ml_numchunks = 100;
5033 	buf->b_ml.ml_usedchunks = 1;
5034 	buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
5035 	buf->b_ml.ml_chunksize[0].mlcs_totalsize = 1;
5036     }
5037 
5038     if (updtype == ML_CHNK_UPDLINE && buf->b_ml.ml_line_count == 1)
5039     {
5040 	/*
5041 	 * First line in empty buffer from ml_flush_line() -- reset
5042 	 */
5043 	buf->b_ml.ml_usedchunks = 1;
5044 	buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
5045 	buf->b_ml.ml_chunksize[0].mlcs_totalsize =
5046 				  (long)STRLEN(buf->b_ml.ml_line_ptr) + 1;
5047 	return;
5048     }
5049 
5050     /*
5051      * Find chunk that our line belongs to, curline will be at start of the
5052      * chunk.
5053      */
5054     if (buf != ml_upd_lastbuf || line != ml_upd_lastline + 1
5055 	    || updtype != ML_CHNK_ADDLINE)
5056     {
5057 	for (curline = 1, curix = 0;
5058 	     curix < buf->b_ml.ml_usedchunks - 1
5059 	     && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines;
5060 	     curix++)
5061 	{
5062 	    curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
5063 	}
5064     }
5065     else if (line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines
5066 		 && curix < buf->b_ml.ml_usedchunks - 1)
5067     {
5068 	/* Adjust cached curix & curline */
5069 	curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
5070 	curix++;
5071     }
5072     curchnk = buf->b_ml.ml_chunksize + curix;
5073 
5074     if (updtype == ML_CHNK_DELLINE)
5075 	len = -len;
5076     curchnk->mlcs_totalsize += len;
5077     if (updtype == ML_CHNK_ADDLINE)
5078     {
5079 	curchnk->mlcs_numlines++;
5080 
5081 	/* May resize here so we don't have to do it in both cases below */
5082 	if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks)
5083 	{
5084 	    chunksize_T *t_chunksize = buf->b_ml.ml_chunksize;
5085 
5086 	    buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
5087 	    buf->b_ml.ml_chunksize = (chunksize_T *)
5088 		vim_realloc(buf->b_ml.ml_chunksize,
5089 			    sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
5090 	    if (buf->b_ml.ml_chunksize == NULL)
5091 	    {
5092 		/* Hmmmm, Give up on offset for this buffer */
5093 		vim_free(t_chunksize);
5094 		buf->b_ml.ml_usedchunks = -1;
5095 		return;
5096 	    }
5097 	}
5098 
5099 	if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL)
5100 	{
5101 	    int	    count;	    /* number of entries in block */
5102 	    int	    idx;
5103 	    int	    text_end;
5104 	    int	    linecnt;
5105 
5106 	    mch_memmove(buf->b_ml.ml_chunksize + curix + 1,
5107 			buf->b_ml.ml_chunksize + curix,
5108 			(buf->b_ml.ml_usedchunks - curix) *
5109 			sizeof(chunksize_T));
5110 	    /* Compute length of first half of lines in the split chunk */
5111 	    size = 0;
5112 	    linecnt = 0;
5113 	    while (curline < buf->b_ml.ml_line_count
5114 			&& linecnt < MLCS_MINL)
5115 	    {
5116 		if ((hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
5117 		{
5118 		    buf->b_ml.ml_usedchunks = -1;
5119 		    return;
5120 		}
5121 		dp = (DATA_BL *)(hp->bh_data);
5122 		count = (long)(buf->b_ml.ml_locked_high) -
5123 			(long)(buf->b_ml.ml_locked_low) + 1;
5124 		idx = curline - buf->b_ml.ml_locked_low;
5125 		curline = buf->b_ml.ml_locked_high + 1;
5126 		if (idx == 0)/* first line in block, text at the end */
5127 		    text_end = dp->db_txt_end;
5128 		else
5129 		    text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
5130 		/* Compute index of last line to use in this MEMLINE */
5131 		rest = count - idx;
5132 		if (linecnt + rest > MLCS_MINL)
5133 		{
5134 		    idx += MLCS_MINL - linecnt - 1;
5135 		    linecnt = MLCS_MINL;
5136 		}
5137 		else
5138 		{
5139 		    idx = count - 1;
5140 		    linecnt += rest;
5141 		}
5142 		size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
5143 	    }
5144 	    buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
5145 	    buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
5146 	    buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
5147 	    buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
5148 	    buf->b_ml.ml_usedchunks++;
5149 	    ml_upd_lastbuf = NULL;   /* Force recalc of curix & curline */
5150 	    return;
5151 	}
5152 	else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL
5153 		     && curix == buf->b_ml.ml_usedchunks - 1
5154 		     && buf->b_ml.ml_line_count - line <= 1)
5155 	{
5156 	    /*
5157 	     * We are in the last chunk and it is cheap to crate a new one
5158 	     * after this. Do it now to avoid the loop above later on
5159 	     */
5160 	    curchnk = buf->b_ml.ml_chunksize + curix + 1;
5161 	    buf->b_ml.ml_usedchunks++;
5162 	    if (line == buf->b_ml.ml_line_count)
5163 	    {
5164 		curchnk->mlcs_numlines = 0;
5165 		curchnk->mlcs_totalsize = 0;
5166 	    }
5167 	    else
5168 	    {
5169 		/*
5170 		 * Line is just prior to last, move count for last
5171 		 * This is the common case  when loading a new file
5172 		 */
5173 		hp = ml_find_line(buf, buf->b_ml.ml_line_count, ML_FIND);
5174 		if (hp == NULL)
5175 		{
5176 		    buf->b_ml.ml_usedchunks = -1;
5177 		    return;
5178 		}
5179 		dp = (DATA_BL *)(hp->bh_data);
5180 		if (dp->db_line_count == 1)
5181 		    rest = dp->db_txt_end - dp->db_txt_start;
5182 		else
5183 		    rest =
5184 			((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
5185 			- dp->db_txt_start;
5186 		curchnk->mlcs_totalsize = rest;
5187 		curchnk->mlcs_numlines = 1;
5188 		curchnk[-1].mlcs_totalsize -= rest;
5189 		curchnk[-1].mlcs_numlines -= 1;
5190 	    }
5191 	}
5192     }
5193     else if (updtype == ML_CHNK_DELLINE)
5194     {
5195 	curchnk->mlcs_numlines--;
5196 	ml_upd_lastbuf = NULL;   /* Force recalc of curix & curline */
5197 	if (curix < (buf->b_ml.ml_usedchunks - 1)
5198 		&& (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines)
5199 		   <= MLCS_MINL)
5200 	{
5201 	    curix++;
5202 	    curchnk = buf->b_ml.ml_chunksize + curix;
5203 	}
5204 	else if (curix == 0 && curchnk->mlcs_numlines <= 0)
5205 	{
5206 	    buf->b_ml.ml_usedchunks--;
5207 	    mch_memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
5208 			buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
5209 	    return;
5210 	}
5211 	else if (curix == 0 || (curchnk->mlcs_numlines > 10
5212 		    && (curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines)
5213 		       > MLCS_MINL))
5214 	{
5215 	    return;
5216 	}
5217 
5218 	/* Collapse chunks */
5219 	curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines;
5220 	curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
5221 	buf->b_ml.ml_usedchunks--;
5222 	if (curix < buf->b_ml.ml_usedchunks)
5223 	{
5224 	    mch_memmove(buf->b_ml.ml_chunksize + curix,
5225 			buf->b_ml.ml_chunksize + curix + 1,
5226 			(buf->b_ml.ml_usedchunks - curix) *
5227 			sizeof(chunksize_T));
5228 	}
5229 	return;
5230     }
5231     ml_upd_lastbuf = buf;
5232     ml_upd_lastline = line;
5233     ml_upd_lastcurline = curline;
5234     ml_upd_lastcurix = curix;
5235 }
5236 
5237 /*
5238  * Find offset for line or line with offset.
5239  * Find line with offset if "lnum" is 0; return remaining offset in offp
5240  * Find offset of line if "lnum" > 0
5241  * return -1 if information is not available
5242  */
5243     long
5244 ml_find_line_or_offset(buf, lnum, offp)
5245     buf_T	*buf;
5246     linenr_T	lnum;
5247     long	*offp;
5248 {
5249     linenr_T	curline;
5250     int		curix;
5251     long	size;
5252     bhdr_T	*hp;
5253     DATA_BL	*dp;
5254     int		count;		/* number of entries in block */
5255     int		idx;
5256     int		start_idx;
5257     int		text_end;
5258     long	offset;
5259     int		len;
5260     int		ffdos = (get_fileformat(buf) == EOL_DOS);
5261     int		extra = 0;
5262 
5263     /* take care of cached line first */
5264     ml_flush_line(curbuf);
5265 
5266     if (buf->b_ml.ml_usedchunks == -1
5267 	    || buf->b_ml.ml_chunksize == NULL
5268 	    || lnum < 0)
5269 	return -1;
5270 
5271     if (offp == NULL)
5272 	offset = 0;
5273     else
5274 	offset = *offp;
5275     if (lnum == 0 && offset <= 0)
5276 	return 1;   /* Not a "find offset" and offset 0 _must_ be in line 1 */
5277     /*
5278      * Find the last chunk before the one containing our line. Last chunk is
5279      * special because it will never qualify
5280      */
5281     curline = 1;
5282     curix = size = 0;
5283     while (curix < buf->b_ml.ml_usedchunks - 1
5284 	    && ((lnum != 0
5285 	     && lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
5286 		|| (offset != 0
5287 	       && offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize
5288 		      + ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines)))
5289     {
5290 	curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
5291 	size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize;
5292 	if (offset && ffdos)
5293 	    size += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
5294 	curix++;
5295     }
5296 
5297     while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset))
5298     {
5299 	if (curline > buf->b_ml.ml_line_count
5300 		|| (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
5301 	    return -1;
5302 	dp = (DATA_BL *)(hp->bh_data);
5303 	count = (long)(buf->b_ml.ml_locked_high) -
5304 		(long)(buf->b_ml.ml_locked_low) + 1;
5305 	start_idx = idx = curline - buf->b_ml.ml_locked_low;
5306 	if (idx == 0)/* first line in block, text at the end */
5307 	    text_end = dp->db_txt_end;
5308 	else
5309 	    text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
5310 	/* Compute index of last line to use in this MEMLINE */
5311 	if (lnum != 0)
5312 	{
5313 	    if (curline + (count - idx) >= lnum)
5314 		idx += lnum - curline - 1;
5315 	    else
5316 		idx = count - 1;
5317 	}
5318 	else
5319 	{
5320 	    extra = 0;
5321 	    while (offset >= size
5322 		       + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
5323 								      + ffdos)
5324 	    {
5325 		if (ffdos)
5326 		    size++;
5327 		if (idx == count - 1)
5328 		{
5329 		    extra = 1;
5330 		    break;
5331 		}
5332 		idx++;
5333 	    }
5334 	}
5335 	len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
5336 	size += len;
5337 	if (offset != 0 && size >= offset)
5338 	{
5339 	    if (size + ffdos == offset)
5340 		*offp = 0;
5341 	    else if (idx == start_idx)
5342 		*offp = offset - size + len;
5343 	    else
5344 		*offp = offset - size + len
5345 		     - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
5346 	    curline += idx - start_idx + extra;
5347 	    if (curline > buf->b_ml.ml_line_count)
5348 		return -1;	/* exactly one byte beyond the end */
5349 	    return curline;
5350 	}
5351 	curline = buf->b_ml.ml_locked_high + 1;
5352     }
5353 
5354     if (lnum != 0)
5355     {
5356 	/* Count extra CR characters. */
5357 	if (ffdos)
5358 	    size += lnum - 1;
5359 
5360 	/* Don't count the last line break if 'noeol' and ('bin' or
5361 	 * 'nofixeol'). */
5362 	if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
5363 					   && buf->b_ml.ml_line_count == lnum)
5364 	    size -= ffdos + 1;
5365     }
5366 
5367     return size;
5368 }
5369 
5370 /*
5371  * Goto byte in buffer with offset 'cnt'.
5372  */
5373     void
5374 goto_byte(cnt)
5375     long	cnt;
5376 {
5377     long	boff = cnt;
5378     linenr_T	lnum;
5379 
5380     ml_flush_line(curbuf);	/* cached line may be dirty */
5381     setpcmark();
5382     if (boff)
5383 	--boff;
5384     lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff);
5385     if (lnum < 1)	/* past the end */
5386     {
5387 	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
5388 	curwin->w_curswant = MAXCOL;
5389 	coladvance((colnr_T)MAXCOL);
5390     }
5391     else
5392     {
5393 	curwin->w_cursor.lnum = lnum;
5394 	curwin->w_cursor.col = (colnr_T)boff;
5395 # ifdef FEAT_VIRTUALEDIT
5396 	curwin->w_cursor.coladd = 0;
5397 # endif
5398 	curwin->w_set_curswant = TRUE;
5399     }
5400     check_cursor();
5401 
5402 # ifdef FEAT_MBYTE
5403     /* Make sure the cursor is on the first byte of a multi-byte char. */
5404     if (has_mbyte)
5405 	mb_adjust_cursor();
5406 # endif
5407 }
5408 #endif
5409