/* vi:set ts=8 sts=4 sw=4:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

/* for debugging */
/* #define CHECK(c, s)	if (c) EMSG(s) */
#define CHECK(c, s)

/*
 * memline.c: Contains the functions for appending, deleting and changing the
 * text lines. The memfile functions are used to store the information in
 * blocks of memory, backed up by a file. The structure of the information is
 * a tree.  The root of the tree is a pointer block. The leaves of the tree
 * are data blocks. In between may be several layers of pointer blocks,
 * forming branches.
 *
 * Three types of blocks are used:
 * - Block nr 0 contains information for recovery
 * - Pointer blocks contain list of pointers to other blocks.
 * - Data blocks contain the actual text.
 *
 * Block nr 0 contains the block0 structure (see below).
 *
 * Block nr 1 is the first pointer block. It is the root of the tree.
 * Other pointer blocks are branches.
 *
 *  If a line is too big to fit in a single page, the block containing that
 *  line is made big enough to hold the line. It may span several pages.
 *  Otherwise all blocks are one page.
 *
 *  A data block that was filled when starting to edit a file and was not
 *  changed since then, can have a negative block number. This means that it
 *  has not yet been assigned a place in the file. When recovering, the lines
 *  in this data block can be read from the original file. When the block is
 *  changed (lines appended/deleted/changed) or when it is flushed it gets a
 *  positive number. Use mf_trans_del() to get the new number, before calling
 *  mf_get().
 */

#include "vim.h"

#ifndef UNIX		/* it's in os_unix.h for Unix */
# include <time.h>
#endif

#if defined(SASC) || defined(__amigaos4__)
# include <proto/dos.h>	    /* for Open() and Close() */
#endif

#ifdef HAVE_ERRNO_H
# include <errno.h>
#endif

typedef struct block0		ZERO_BL;    /* contents of the first block */
typedef struct pointer_block	PTR_BL;	    /* contents of a pointer block */
typedef struct data_block	DATA_BL;    /* contents of a data block */
typedef struct pointer_entry	PTR_EN;	    /* block/line-count pair */

#define DATA_ID	       (('d' << 8) + 'a')   /* data block id */
#define PTR_ID	       (('p' << 8) + 't')   /* pointer block id */
#define BLOCK0_ID0     'b'		    /* block 0 id 0 */
#define BLOCK0_ID1     '0'		    /* block 0 id 1 */
#define BLOCK0_ID1_C0  'c'		    /* block 0 id 1 'cm' 0 */
#define BLOCK0_ID1_C1  'C'		    /* block 0 id 1 'cm' 1 */

/*
 * pointer to a block, used in a pointer block
 */
struct pointer_entry
{
    blocknr_T	pe_bnum;	/* block number */
    linenr_T	pe_line_count;	/* number of lines in this branch */
    linenr_T	pe_old_lnum;	/* lnum for this block (for recovery) */
    int		pe_page_count;	/* number of pages in block pe_bnum */
};

/*
 * A pointer block contains a list of branches in the tree.
 */
struct pointer_block
{
    short_u	pb_id;		/* ID for pointer block: PTR_ID */
    short_u	pb_count;	/* number of pointers in this block */
    short_u	pb_count_max;	/* maximum value for pb_count */
    PTR_EN	pb_pointer[1];	/* list of pointers to blocks (actually longer)
				 * followed by empty space until end of page */
};

/*
 * A data block is a leaf in the tree.
 *
 * The text of the lines is at the end of the block. The text of the first line
 * in the block is put at the end, the text of the second line in front of it,
 * etc. Thus the order of the lines is the opposite of the line number.
 */
struct data_block
{
    short_u	db_id;		/* ID for data block: DATA_ID */
    unsigned	db_free;	/* free space available */
    unsigned	db_txt_start;	/* byte where text starts */
    unsigned	db_txt_end;	/* byte just after data block */
    linenr_T	db_line_count;	/* number of lines in this block */
    unsigned	db_index[1];	/* index for start of line (actually bigger)
				 * followed by empty space upto db_txt_start
				 * followed by the text in the lines until
				 * end of page */
};

/*
 * The low bits of db_index hold the actual index. The topmost bit is
 * used for the global command to be able to mark a line.
 * This method is not clean, but otherwise there would be at least one extra
 * byte used for each line.
 * The mark has to be in this place to keep it with the correct line when other
 * lines are inserted or deleted.
 */
#define DB_MARKED	((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
#define DB_INDEX_MASK	(~DB_MARKED)

#define INDEX_SIZE  (sizeof(unsigned))	    /* size of one db_index entry */
#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE)  /* size of data block header */

#define B0_FNAME_SIZE_ORG	900	/* what it was in older versions */
#define B0_FNAME_SIZE_NOCRYPT	898	/* 2 bytes used for other things */
#define B0_FNAME_SIZE_CRYPT	890	/* 10 bytes used for other things */
#define B0_UNAME_SIZE		40
#define B0_HNAME_SIZE		40
/*
 * Restrict the numbers to 32 bits, otherwise most compilers will complain.
 * This won't detect a 64 bit machine that only swaps a byte in the top 32
 * bits, but that is crazy anyway.
 */
#define B0_MAGIC_LONG	0x30313233L
#define B0_MAGIC_INT	0x20212223L
#define B0_MAGIC_SHORT	0x10111213L
#define B0_MAGIC_CHAR	0x55

/*
 * Block zero holds all info about the swap file.
 *
 * NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing
 * swap files unusable!
 *
 * If size of block0 changes anyway, adjust MIN_SWAP_PAGE_SIZE in vim.h!!
 *
 * This block is built up of single bytes, to make it portable across
 * different machines. b0_magic_* is used to check the byte order and size of
 * variables, because the rest of the swap file is not portable.
 */
struct block0
{
    char_u	b0_id[2];	/* id for block 0: BLOCK0_ID0 and BLOCK0_ID1,
				 * BLOCK0_ID1_C0, BLOCK0_ID1_C1 */
    char_u	b0_version[10];	/* Vim version string */
    char_u	b0_page_size[4];/* number of bytes per page */
    char_u	b0_mtime[4];	/* last modification time of file */
    char_u	b0_ino[4];	/* inode of b0_fname */
    char_u	b0_pid[4];	/* process id of creator (or 0) */
    char_u	b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */
    char_u	b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */
    char_u	b0_fname[B0_FNAME_SIZE_ORG]; /* name of file being edited */
    long	b0_magic_long;	/* check for byte order of long */
    int		b0_magic_int;	/* check for byte order of int */
    short	b0_magic_short;	/* check for byte order of short */
    char_u	b0_magic_char;	/* check for last char */
};

/*
 * Note: b0_dirty and b0_flags are put at the end of the file name.  For very
 * long file names in older versions of Vim they are invalid.
 * The 'fileencoding' comes before b0_flags, with a NUL in front.  But only
 * when there is room, for very long file names it's omitted.
 */
#define B0_DIRTY	0x55
#define b0_dirty	b0_fname[B0_FNAME_SIZE_ORG - 1]

/*
 * The b0_flags field is new in Vim 7.0.
 */
#define b0_flags	b0_fname[B0_FNAME_SIZE_ORG - 2]

/*
 * Crypt seed goes here, 8 bytes.  New in Vim 7.3.
 * Without encryption these bytes may be used for 'fenc'.
 */
#define b0_seed		b0_fname[B0_FNAME_SIZE_ORG - 2 - MF_SEED_LEN]

/* The lowest two bits contain the fileformat.  Zero means it's not set
 * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
 * EOL_MAC + 1. */
#define B0_FF_MASK	3

/* Swap file is in directory of edited file.  Used to find the file from
 * different mount points. */
#define B0_SAME_DIR	4

/* The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
 * When empty there is only the NUL. */
#define B0_HAS_FENC	8

#define STACK_INCR	5	/* nr of entries added to ml_stack at a time */

/*
 * The line number where the first mark may be is remembered.
 * If it is 0 there are no marks at all.
 * (always used for the current buffer only, no buffer change possible while
 * executing a global command).
 */
static linenr_T	lowest_marked = 0;

/*
 * arguments for ml_find_line()
 */
#define ML_DELETE	0x11	    /* delete line */
#define ML_INSERT	0x12	    /* insert line */
#define ML_FIND		0x13	    /* just find the line */
#define ML_FLUSH	0x02	    /* flush locked block */
#define ML_SIMPLE(x)	(x & 0x10)  /* DEL, INS or FIND */

/* argument for ml_upd_block0() */
typedef enum {
      UB_FNAME = 0	/* update timestamp and filename */
    , UB_SAME_DIR       /* update the B0_SAME_DIR flag */
    , UB_CRYPT		/* update crypt key */
} upd_block0_T;

#ifdef FEAT_CRYPT
static void ml_set_b0_crypt __ARGS((buf_T *buf, ZERO_BL *b0p));
#endif
static int ml_check_b0_id __ARGS((ZERO_BL *b0p));
static void ml_upd_block0 __ARGS((buf_T *buf, upd_block0_T what));
static void set_b0_fname __ARGS((ZERO_BL *, buf_T *buf));
static void set_b0_dir_flag __ARGS((ZERO_BL *b0p, buf_T *buf));
#ifdef FEAT_MBYTE
static void add_b0_fenc __ARGS((ZERO_BL *b0p, buf_T *buf));
#endif
static time_t swapfile_info __ARGS((char_u *));
static int recov_file_names __ARGS((char_u **, char_u *, int prepend_dot));
static int ml_append_int __ARGS((buf_T *, linenr_T, char_u *, colnr_T, int, int));
static int ml_delete_int __ARGS((buf_T *, linenr_T, int));
static char_u *findswapname __ARGS((buf_T *, char_u **, char_u *));
static void ml_flush_line __ARGS((buf_T *));
static bhdr_T *ml_new_data __ARGS((memfile_T *, int, int));
static bhdr_T *ml_new_ptr __ARGS((memfile_T *));
static bhdr_T *ml_find_line __ARGS((buf_T *, linenr_T, int));
static int ml_add_stack __ARGS((buf_T *));
static void ml_lineadd __ARGS((buf_T *, int));
static int b0_magic_wrong __ARGS((ZERO_BL *));
#ifdef CHECK_INODE
static int fnamecmp_ino __ARGS((char_u *, char_u *, long));
#endif
static void long_to_char __ARGS((long, char_u *));
static long char_to_long __ARGS((char_u *));
#if defined(UNIX) || defined(WIN3264)
static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name));
#endif
#ifdef FEAT_CRYPT
static void ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading));
#endif
#ifdef FEAT_BYTEOFF
static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
#endif

/*
 * Open a new memline for "buf".
 *
 * Return FAIL for failure, OK otherwise.
 */
    int
ml_open(buf)
    buf_T	*buf;
{
    memfile_T	*mfp;
    bhdr_T	*hp = NULL;
    ZERO_BL	*b0p;
    PTR_BL	*pp;
    DATA_BL	*dp;

    /*
     * init fields in memline struct
     */
    buf->b_ml.ml_stack_size = 0; /* no stack yet */
    buf->b_ml.ml_stack = NULL;	/* no stack yet */
    buf->b_ml.ml_stack_top = 0;	/* nothing in the stack */
    buf->b_ml.ml_locked = NULL;	/* no cached block */
    buf->b_ml.ml_line_lnum = 0;	/* no cached line */
#ifdef FEAT_BYTEOFF
    buf->b_ml.ml_chunksize = NULL;
#endif

    /*
     * When 'updatecount' is non-zero swap file may be opened later.
     */
    if (p_uc && buf->b_p_swf)
	buf->b_may_swap = TRUE;
    else
	buf->b_may_swap = FALSE;

    /*
     * Open the memfile.  No swap file is created yet.
     */
    mfp = mf_open(NULL, 0);
    if (mfp == NULL)
	goto error;

    buf->b_ml.ml_mfp = mfp;
#ifdef FEAT_CRYPT
    mfp->mf_buffer = buf;
#endif
    buf->b_ml.ml_flags = ML_EMPTY;
    buf->b_ml.ml_line_count = 1;
#ifdef FEAT_LINEBREAK
    curwin->w_nrwidth_line_count = 0;
#endif

#if defined(MSDOS) && !defined(DJGPP)
    /* for 16 bit MS-DOS create a swapfile now, because we run out of
     * memory very quickly */
    if (p_uc != 0)
	ml_open_file(buf);
#endif

/*
 * fill block0 struct and write page 0
 */
    if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
	goto error;
    if (hp->bh_bnum != 0)
    {
	EMSG(_("E298: Didn't get block nr 0?"));
	goto error;
    }
    b0p = (ZERO_BL *)(hp->bh_data);

    b0p->b0_id[0] = BLOCK0_ID0;
    b0p->b0_id[1] = BLOCK0_ID1;
    b0p->b0_magic_long = (long)B0_MAGIC_LONG;
    b0p->b0_magic_int = (int)B0_MAGIC_INT;
    b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
    b0p->b0_magic_char = B0_MAGIC_CHAR;
    STRNCPY(b0p->b0_version, "VIM ", 4);
    STRNCPY(b0p->b0_version + 4, Version, 6);
    long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);

#ifdef FEAT_SPELL
    if (!buf->b_spell)
#endif
    {
	b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
	b0p->b0_flags = get_fileformat(buf) + 1;
	set_b0_fname(b0p, buf);
	(void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE);
	b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
	mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE);
	b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
	long_to_char(mch_get_pid(), b0p->b0_pid);
#ifdef FEAT_CRYPT
	if (*buf->b_p_key != NUL)
	    ml_set_b0_crypt(buf, b0p);
#endif
    }

    /*
     * Always sync block number 0 to disk, so we can check the file name in
     * the swap file in findswapname(). Don't do this for a help files or
     * a spell buffer though.
     * Only works when there's a swapfile, otherwise it's done when the file
     * is created.
     */
    mf_put(mfp, hp, TRUE, FALSE);
    if (!buf->b_help && !B_SPELL(buf))
	(void)mf_sync(mfp, 0);

    /*
     * Fill in root pointer block and write page 1.
     */
    if ((hp = ml_new_ptr(mfp)) == NULL)
	goto error;
    if (hp->bh_bnum != 1)
    {
	EMSG(_("E298: Didn't get block nr 1?"));
	goto error;
    }
    pp = (PTR_BL *)(hp->bh_data);
    pp->pb_count = 1;
    pp->pb_pointer[0].pe_bnum = 2;
    pp->pb_pointer[0].pe_page_count = 1;
    pp->pb_pointer[0].pe_old_lnum = 1;
    pp->pb_pointer[0].pe_line_count = 1;    /* line count after insertion */
    mf_put(mfp, hp, TRUE, FALSE);

    /*
     * Allocate first data block and create an empty line 1.
     */
    if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL)
	goto error;
    if (hp->bh_bnum != 2)
    {
	EMSG(_("E298: Didn't get block nr 2?"));
	goto error;
    }

    dp = (DATA_BL *)(hp->bh_data);
    dp->db_index[0] = --dp->db_txt_start;	/* at end of block */
    dp->db_free -= 1 + INDEX_SIZE;
    dp->db_line_count = 1;
    *((char_u *)dp + dp->db_txt_start) = NUL;	/* empty line */

    return OK;

error:
    if (mfp != NULL)
    {
	if (hp)
	    mf_put(mfp, hp, FALSE, FALSE);
	mf_close(mfp, TRUE);	    /* will also free(mfp->mf_fname) */
    }
    buf->b_ml.ml_mfp = NULL;
    return FAIL;
}

#if defined(FEAT_CRYPT) || defined(PROTO)
/*
 * Prepare encryption for "buf" with block 0 "b0p".
 */
    static void
ml_set_b0_crypt(buf, b0p)
    buf_T	*buf;
    ZERO_BL	*b0p;
{
    if (*buf->b_p_key == NUL)
	b0p->b0_id[1] = BLOCK0_ID1;
    else
    {
	if (get_crypt_method(buf) == 0)
	    b0p->b0_id[1] = BLOCK0_ID1_C0;
	else
	{
	    b0p->b0_id[1] = BLOCK0_ID1_C1;
	    /* Generate a seed and store it in block 0 and in the memfile. */
	    sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
	    mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
	}
    }
}

/*
 * Called after the crypt key or 'cryptmethod' was changed for "buf".
 * Will apply this to the swapfile.
 * "old_key" is the previous key.  It is equal to buf->b_p_key when
 * 'cryptmethod' is changed.
 * "old_cm" is the previous 'cryptmethod'.  It is equal to the current
 * 'cryptmethod' when 'key' is changed.
 */
    void
ml_set_crypt_key(buf, old_key, old_cm)
    buf_T	*buf;
    char_u	*old_key;
    int		old_cm;
{
    memfile_T	*mfp = buf->b_ml.ml_mfp;
    bhdr_T	*hp;
    int		page_count;
    int		idx;
    long	error;
    infoptr_T	*ip;
    PTR_BL	*pp;
    DATA_BL	*dp;
    blocknr_T	bnum;
    int		top;

    if (mfp == NULL)
	return;  /* no memfile yet, nothing to do */

    /* Set the key, method and seed to be used for reading, these must be the
     * old values. */
    mfp->mf_old_key = old_key;
    mfp->mf_old_cm = old_cm;
    if (old_cm > 0)
	mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN);

    /* Update block 0 with the crypt flag and may set a new seed. */
    ml_upd_block0(buf, UB_CRYPT);

    if (mfp->mf_infile_count > 2)
    {
	/*
	 * Need to read back all data blocks from disk, decrypt them with the
	 * old key/method and mark them to be written. The algorithm is
	 * similar to what happens in ml_recover(), but we skip negative block
	 * numbers.
	 */
	ml_flush_line(buf);		    /* flush buffered line */
	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */

	hp = NULL;
	bnum = 1;		/* start with block 1 */
	page_count = 1;		/* which is 1 page */
	idx = 0;		/* start with first index in block 1 */
	error = 0;
	buf->b_ml.ml_stack_top = 0;
	vim_free(buf->b_ml.ml_stack);
	buf->b_ml.ml_stack = NULL;
	buf->b_ml.ml_stack_size = 0;	/* no stack yet */

	for ( ; !got_int; line_breakcheck())
	{
	    if (hp != NULL)
		mf_put(mfp, hp, FALSE, FALSE);	/* release previous block */

	    /* get the block (pointer or data) */
	    if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
	    {
		if (bnum == 1)
		    break;
		++error;
	    }
	    else
	    {
		pp = (PTR_BL *)(hp->bh_data);
		if (pp->pb_id == PTR_ID)	/* it is a pointer block */
		{
		    if (pp->pb_count == 0)
		    {
			/* empty block? */
			++error;
		    }
		    else if (idx < (int)pp->pb_count)	/* go a block deeper */
		    {
			if (pp->pb_pointer[idx].pe_bnum < 0)
			{
			    /* Skip data block with negative block number. */
			    ++idx;    /* get same block again for next index */
			    continue;
			}

			/* going one block deeper in the tree, new entry in
			 * stack */
			if ((top = ml_add_stack(buf)) < 0)
			{
			    ++error;
			    break;		    /* out of memory */
			}
			ip = &(buf->b_ml.ml_stack[top]);
			ip->ip_bnum = bnum;
			ip->ip_index = idx;

			bnum = pp->pb_pointer[idx].pe_bnum;
			page_count = pp->pb_pointer[idx].pe_page_count;
			continue;
		    }
		}
		else	    /* not a pointer block */
		{
		    dp = (DATA_BL *)(hp->bh_data);
		    if (dp->db_id != DATA_ID)	/* block id wrong */
			++error;
		    else
		    {
			/* It is a data block, need to write it back to disk. */
			mf_put(mfp, hp, TRUE, FALSE);
			hp = NULL;
		    }
		}
	    }

	    if (buf->b_ml.ml_stack_top == 0)	/* finished */
		break;

	    /* go one block up in the tree */
	    ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
	    bnum = ip->ip_bnum;
	    idx = ip->ip_index + 1;	    /* go to next index */
	    page_count = 1;
	}

	if (error > 0)
	    EMSG(_("E843: Error while updating swap file crypt"));
    }

    mfp->mf_old_key = NULL;
}
#endif

/*
 * ml_setname() is called when the file name of "buf" has been changed.
 * It may rename the swap file.
 */
    void
ml_setname(buf)
    buf_T	*buf;
{
    int		success = FALSE;
    memfile_T	*mfp;
    char_u	*fname;
    char_u	*dirp;
#if defined(MSDOS) || defined(MSWIN)
    char_u	*p;
#endif

    mfp = buf->b_ml.ml_mfp;
    if (mfp->mf_fd < 0)		    /* there is no swap file yet */
    {
	/*
	 * When 'updatecount' is 0 and 'noswapfile' there is no swap file.
	 * For help files we will make a swap file now.
	 */
	if (p_uc != 0)
	    ml_open_file(buf);	    /* create a swap file */
	return;
    }

    /*
     * Try all directories in the 'directory' option.
     */
    dirp = p_dir;
    for (;;)
    {
	if (*dirp == NUL)	    /* tried all directories, fail */
	    break;
	fname = findswapname(buf, &dirp, mfp->mf_fname);
						    /* alloc's fname */
	if (fname == NULL)	    /* no file name found for this dir */
	    continue;

#if defined(MSDOS) || defined(MSWIN)
	/*
	 * Set full pathname for swap file now, because a ":!cd dir" may
	 * change directory without us knowing it.
	 */
	p = FullName_save(fname, FALSE);
	vim_free(fname);
	fname = p;
	if (fname == NULL)
	    continue;
#endif
	/* if the file name is the same we don't have to do anything */
	if (fnamecmp(fname, mfp->mf_fname) == 0)
	{
	    vim_free(fname);
	    success = TRUE;
	    break;
	}
	/* need to close the swap file before renaming */
	if (mfp->mf_fd >= 0)
	{
	    close(mfp->mf_fd);
	    mfp->mf_fd = -1;
	}

	/* try to rename the swap file */
	if (vim_rename(mfp->mf_fname, fname) == 0)
	{
	    success = TRUE;
	    vim_free(mfp->mf_fname);
	    mfp->mf_fname = fname;
	    vim_free(mfp->mf_ffname);
#if defined(MSDOS) || defined(MSWIN)
	    mfp->mf_ffname = NULL;  /* mf_fname is full pathname already */
#else
	    mf_set_ffname(mfp);
#endif
	    ml_upd_block0(buf, UB_SAME_DIR);
	    break;
	}
	vim_free(fname);	    /* this fname didn't work, try another */
    }

    if (mfp->mf_fd == -1)	    /* need to (re)open the swap file */
    {
	mfp->mf_fd = mch_open((char *)mfp->mf_fname, O_RDWR | O_EXTRA, 0);
	if (mfp->mf_fd < 0)
	{
	    /* could not (re)open the swap file, what can we do???? */
	    EMSG(_("E301: Oops, lost the swap file!!!"));
	    return;
	}
#ifdef HAVE_FD_CLOEXEC
	{
	    int fdflags = fcntl(mfp->mf_fd, F_GETFD);
	    if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
		fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
	}
#endif
    }
    if (!success)
	EMSG(_("E302: Could not rename swap file"));
}

/*
 * Open a file for the memfile for all buffers that are not readonly or have
 * been modified.
 * Used when 'updatecount' changes from zero to non-zero.
 */
    void
ml_open_files()
{
    buf_T	*buf;

    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
	if (!buf->b_p_ro || buf->b_changed)
	    ml_open_file(buf);
}

/*
 * Open a swap file for an existing memfile, if there is no swap file yet.
 * If we are unable to find a file name, mf_fname will be NULL
 * and the memfile will be in memory only (no recovery possible).
 */
    void
ml_open_file(buf)
    buf_T	*buf;
{
    memfile_T	*mfp;
    char_u	*fname;
    char_u	*dirp;

    mfp = buf->b_ml.ml_mfp;
    if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf)
	return;		/* nothing to do */

#ifdef FEAT_SPELL
    /* For a spell buffer use a temp file name. */
    if (buf->b_spell)
    {
	fname = vim_tempname('s');
	if (fname != NULL)
	    (void)mf_open_file(mfp, fname);	/* consumes fname! */
	buf->b_may_swap = FALSE;
	return;
    }
#endif

    /*
     * Try all directories in 'directory' option.
     */
    dirp = p_dir;
    for (;;)
    {
	if (*dirp == NUL)
	    break;
	/* There is a small chance that between choosing the swap file name
	 * and creating it, another Vim creates the file.  In that case the
	 * creation will fail and we will use another directory. */
	fname = findswapname(buf, &dirp, NULL); /* allocates fname */
	if (fname == NULL)
	    continue;
	if (mf_open_file(mfp, fname) == OK)	/* consumes fname! */
	{
#if defined(MSDOS) || defined(MSWIN) || defined(RISCOS)
	    /*
	     * set full pathname for swap file now, because a ":!cd dir" may
	     * change directory without us knowing it.
	     */
	    mf_fullname(mfp);
#endif
	    ml_upd_block0(buf, UB_SAME_DIR);

	    /* Flush block zero, so others can read it */
	    if (mf_sync(mfp, MFS_ZERO) == OK)
	    {
		/* Mark all blocks that should be in the swapfile as dirty.
		 * Needed for when the 'swapfile' option was reset, so that
		 * the swap file was deleted, and then on again. */
		mf_set_dirty(mfp);
		break;
	    }
	    /* Writing block 0 failed: close the file and try another dir */
	    mf_close_file(buf, FALSE);
	}
    }

    if (mfp->mf_fname == NULL)		/* Failed! */
    {
	need_wait_return = TRUE;	/* call wait_return later */
	++no_wait_return;
	(void)EMSG2(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
		    buf_spname(buf) != NULL
			? (char_u *)buf_spname(buf)
			: buf->b_fname);
	--no_wait_return;
    }

    /* don't try to open a swap file again */
    buf->b_may_swap = FALSE;
}

/*
 * If still need to create a swap file, and starting to edit a not-readonly
 * file, or reading into an existing buffer, create a swap file now.
 */
    void
check_need_swap(newfile)
    int	    newfile;		/* reading file into new buffer */
{
    if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
	ml_open_file(curbuf);
}

/*
 * Close memline for buffer 'buf'.
 * If 'del_file' is TRUE, delete the swap file
 */
    void
ml_close(buf, del_file)
    buf_T	*buf;
    int		del_file;
{
    if (buf->b_ml.ml_mfp == NULL)		/* not open */
	return;
    mf_close(buf->b_ml.ml_mfp, del_file);	/* close the .swp file */
    if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
	vim_free(buf->b_ml.ml_line_ptr);
    vim_free(buf->b_ml.ml_stack);
#ifdef FEAT_BYTEOFF
    vim_free(buf->b_ml.ml_chunksize);
    buf->b_ml.ml_chunksize = NULL;
#endif
    buf->b_ml.ml_mfp = NULL;

    /* Reset the "recovered" flag, give the ATTENTION prompt the next time
     * this buffer is loaded. */
    buf->b_flags &= ~BF_RECOVERED;
}

/*
 * Close all existing memlines and memfiles.
 * Only used when exiting.
 * When 'del_file' is TRUE, delete the memfiles.
 * But don't delete files that were ":preserve"d when we are POSIX compatible.
 */
    void
ml_close_all(del_file)
    int		del_file;
{
    buf_T	*buf;

    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
	ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0
				 || vim_strchr(p_cpo, CPO_PRESERVE) == NULL));
#ifdef TEMPDIRNAMES
    vim_deltempdir();	    /* delete created temp directory */
#endif
}

/*
 * Close all memfiles for not modified buffers.
 * Only use just before exiting!
 */
    void
ml_close_notmod()
{
    buf_T	*buf;

    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
	if (!bufIsChanged(buf))
	    ml_close(buf, TRUE);    /* close all not-modified buffers */
}

/*
 * Update the timestamp in the .swp file.
 * Used when the file has been written.
 */
    void
ml_timestamp(buf)
    buf_T	*buf;
{
    ml_upd_block0(buf, UB_FNAME);
}

/*
 * Return FAIL when the ID of "b0p" is wrong.
 */
    static int
ml_check_b0_id(b0p)
    ZERO_BL	*b0p;
{
    if (b0p->b0_id[0] != BLOCK0_ID0
	    || (b0p->b0_id[1] != BLOCK0_ID1
		&& b0p->b0_id[1] != BLOCK0_ID1_C0
		&& b0p->b0_id[1] != BLOCK0_ID1_C1)
	    )
	return FAIL;
    return OK;
}

/*
 * Update the timestamp or the B0_SAME_DIR flag of the .swp file.
 */
    static void
ml_upd_block0(buf, what)
    buf_T	*buf;
    upd_block0_T what;
{
    memfile_T	*mfp;
    bhdr_T	*hp;
    ZERO_BL	*b0p;

    mfp = buf->b_ml.ml_mfp;
    if (mfp == NULL || (hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
	return;
    b0p = (ZERO_BL *)(hp->bh_data);
    if (ml_check_b0_id(b0p) == FAIL)
	EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
    else
    {
	if (what == UB_FNAME)
	    set_b0_fname(b0p, buf);
#ifdef FEAT_CRYPT
	else if (what == UB_CRYPT)
	    ml_set_b0_crypt(buf, b0p);
#endif
	else /* what == UB_SAME_DIR */
	    set_b0_dir_flag(b0p, buf);
    }
    mf_put(mfp, hp, TRUE, FALSE);
}

/*
 * Write file name and timestamp into block 0 of a swap file.
 * Also set buf->b_mtime.
 * Don't use NameBuff[]!!!
 */
    static void
set_b0_fname(b0p, buf)
    ZERO_BL	*b0p;
    buf_T	*buf;
{
    struct stat	st;

    if (buf->b_ffname == NULL)
	b0p->b0_fname[0] = NUL;
    else
    {
#if defined(MSDOS) || defined(MSWIN) || defined(AMIGA) || defined(RISCOS)
	/* Systems that cannot translate "~user" back into a path: copy the
	 * file name unmodified.  Do use slashes instead of backslashes for
	 * portability. */
	vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT - 1);
# ifdef BACKSLASH_IN_FILENAME
	forward_slash(b0p->b0_fname);
# endif
#else
	size_t	flen, ulen;
	char_u	uname[B0_UNAME_SIZE];

	/*
	 * For a file under the home directory of the current user, we try to
	 * replace the home directory path with "~user". This helps when
	 * editing the same file on different machines over a network.
	 * First replace home dir path with "~/" with home_replace().
	 * Then insert the user name to get "~user/".
	 */
	home_replace(NULL, buf->b_ffname, b0p->b0_fname,
						   B0_FNAME_SIZE_CRYPT, TRUE);
	if (b0p->b0_fname[0] == '~')
	{
	    flen = STRLEN(b0p->b0_fname);
	    /* If there is no user name or it is too long, don't use "~/" */
	    if (get_user_name(uname, B0_UNAME_SIZE) == FAIL
		   || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1)
		vim_strncpy(b0p->b0_fname, buf->b_ffname,
						     B0_FNAME_SIZE_CRYPT - 1);
	    else
	    {
		mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
		mch_memmove(b0p->b0_fname + 1, uname, ulen);
	    }
	}
#endif
	if (mch_stat((char *)buf->b_ffname, &st) >= 0)
	{
	    long_to_char((long)st.st_mtime, b0p->b0_mtime);
#ifdef CHECK_INODE
	    long_to_char((long)st.st_ino, b0p->b0_ino);
#endif
	    buf_store_time(buf, &st, buf->b_ffname);
	    buf->b_mtime_read = buf->b_mtime;
	}
	else
	{
	    long_to_char(0L, b0p->b0_mtime);
#ifdef CHECK_INODE
	    long_to_char(0L, b0p->b0_ino);
#endif
	    buf->b_mtime = 0;
	    buf->b_mtime_read = 0;
	    buf->b_orig_size = 0;
	    buf->b_orig_mode = 0;
	}
    }

#ifdef FEAT_MBYTE
    /* Also add the 'fileencoding' if there is room. */
    add_b0_fenc(b0p, curbuf);
#endif
}

/*
 * Update the B0_SAME_DIR flag of the swap file.  It's set if the file and the
 * swapfile for "buf" are in the same directory.
 * This is fail safe: if we are not sure the directories are equal the flag is
 * not set.
 */
    static void
set_b0_dir_flag(b0p, buf)
    ZERO_BL	*b0p;
    buf_T	*buf;
{
    if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
	b0p->b0_flags |= B0_SAME_DIR;
    else
	b0p->b0_flags &= ~B0_SAME_DIR;
}

#ifdef FEAT_MBYTE
/*
 * When there is room, add the 'fileencoding' to block zero.
 */
    static void
add_b0_fenc(b0p, buf)
    ZERO_BL	*b0p;
    buf_T	*buf;
{
    int		n;
    int		size = B0_FNAME_SIZE_NOCRYPT;

# ifdef FEAT_CRYPT
    /* Without encryption use the same offset as in Vim 7.2 to be compatible.
     * With encryption it's OK to move elsewhere, the swap file is not
     * compatible anyway. */
    if (*buf->b_p_key != NUL)
	size = B0_FNAME_SIZE_CRYPT;
# endif

    n = (int)STRLEN(buf->b_p_fenc);
    if ((int)STRLEN(b0p->b0_fname) + n + 1 > size)
	b0p->b0_flags &= ~B0_HAS_FENC;
    else
    {
	mch_memmove((char *)b0p->b0_fname + size - n,
					    (char *)buf->b_p_fenc, (size_t)n);
	*(b0p->b0_fname + size - n - 1) = NUL;
	b0p->b0_flags |= B0_HAS_FENC;
    }
}
#endif


/*
 * Try to recover curbuf from the .swp file.
 */
    void
ml_recover()
{
    buf_T	*buf = NULL;
    memfile_T	*mfp = NULL;
    char_u	*fname;
    char_u	*fname_used = NULL;
    bhdr_T	*hp = NULL;
    ZERO_BL	*b0p;
    int		b0_ff;
    char_u	*b0_fenc = NULL;
#ifdef FEAT_CRYPT
    int		b0_cm = -1;
#endif
    PTR_BL	*pp;
    DATA_BL	*dp;
    infoptr_T	*ip;
    blocknr_T	bnum;
    int		page_count;
    struct stat	org_stat, swp_stat;
    int		len;
    int		directly;
    linenr_T	lnum;
    char_u	*p;
    int		i;
    long	error;
    int		cannot_open;
    linenr_T	line_count;
    int		has_error;
    int		idx;
    int		top;
    int		txt_start;
    off_t	size;
    int		called_from_main;
    int		serious_error = TRUE;
    long	mtime;
    int		attr;
    int		orig_file_status = NOTDONE;

    recoverymode = TRUE;
    called_from_main = (curbuf->b_ml.ml_mfp == NULL);
    attr = hl_attr(HLF_E);

    /*
     * If the file name ends in ".s[uvw][a-z]" we assume this is the swap file.
     * Otherwise a search is done to find the swap file(s).
     */
    fname = curbuf->b_fname;
    if (fname == NULL)		    /* When there is no file name */
	fname = (char_u *)"";
    len = (int)STRLEN(fname);
    if (len >= 4 &&
#if defined(VMS) || defined(RISCOS)
	    STRNICMP(fname + len - 4, "_s" , 2)
#else
	    STRNICMP(fname + len - 4, ".s" , 2)
#endif
		== 0
		&& vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
		&& ASCII_ISALPHA(fname[len - 1]))
    {
	directly = TRUE;
	fname_used = vim_strsave(fname); /* make a copy for mf_open() */
    }
    else
    {
	directly = FALSE;

	/* count the number of matching swap files */
	len = recover_names(fname, FALSE, 0, NULL);
	if (len == 0)		    /* no swap files found */
	{
	    EMSG2(_("E305: No swap file found for %s"), fname);
	    goto theend;
	}
	if (len == 1)		    /* one swap file found, use it */
	    i = 1;
	else			    /* several swap files found, choose */
	{
	    /* list the names of the swap files */
	    (void)recover_names(fname, TRUE, 0, NULL);
	    msg_putchar('\n');
	    MSG_PUTS(_("Enter number of swap file to use (0 to quit): "));
	    i = get_number(FALSE, NULL);
	    if (i < 1 || i > len)
		goto theend;
	}
	/* get the swap file name that will be used */
	(void)recover_names(fname, FALSE, i, &fname_used);
    }
    if (fname_used == NULL)
	goto theend;			/* out of memory */

    /* When called from main() still need to initialize storage structure */
    if (called_from_main && ml_open(curbuf) == FAIL)
	getout(1);

    /*
     * Allocate a buffer structure for the swap file that is used for recovery.
     * Only the memline and crypt information in it are really used.
     */
    buf = (buf_T *)alloc((unsigned)sizeof(buf_T));
    if (buf == NULL)
	goto theend;

    /*
     * init fields in memline struct
     */
    buf->b_ml.ml_stack_size = 0;	/* no stack yet */
    buf->b_ml.ml_stack = NULL;		/* no stack yet */
    buf->b_ml.ml_stack_top = 0;		/* nothing in the stack */
    buf->b_ml.ml_line_lnum = 0;		/* no cached line */
    buf->b_ml.ml_locked = NULL;		/* no locked block */
    buf->b_ml.ml_flags = 0;
#ifdef FEAT_CRYPT
    buf->b_p_key = empty_option;
    buf->b_p_cm = empty_option;
#endif

    /*
     * open the memfile from the old swap file
     */
    p = vim_strsave(fname_used); /* save "fname_used" for the message:
				    mf_open() will consume "fname_used"! */
    mfp = mf_open(fname_used, O_RDONLY);
    fname_used = p;
    if (mfp == NULL || mfp->mf_fd < 0)
    {
	if (fname_used != NULL)
	    EMSG2(_("E306: Cannot open %s"), fname_used);
	goto theend;
    }
    buf->b_ml.ml_mfp = mfp;
#ifdef FEAT_CRYPT
    mfp->mf_buffer = buf;
#endif

    /*
     * The page size set in mf_open() might be different from the page size
     * used in the swap file, we must get it from block 0.  But to read block
     * 0 we need a page size.  Use the minimal size for block 0 here, it will
     * be set to the real value below.
     */
    mfp->mf_page_size = MIN_SWAP_PAGE_SIZE;

    /*
     * try to read block 0
     */
    if ((hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
    {
	msg_start();
	MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST);
	msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
	MSG_PUTS_ATTR(_("\nMaybe no changes were made or Vim did not update the swap file."),
		attr | MSG_HIST);
	msg_end();
	goto theend;
    }
    b0p = (ZERO_BL *)(hp->bh_data);
    if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0)
    {
	msg_start();
	msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
	MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
								    MSG_HIST);
	MSG_PUTS_ATTR(_("Use Vim version 3.0.\n"), MSG_HIST);
	msg_end();
	goto theend;
    }
    if (ml_check_b0_id(b0p) == FAIL)
    {
	EMSG2(_("E307: %s does not look like a Vim swap file"), mfp->mf_fname);
	goto theend;
    }
    if (b0_magic_wrong(b0p))
    {
	msg_start();
	msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
#if defined(MSDOS) || defined(MSWIN)
	if (STRNCMP(b0p->b0_hname, "PC ", 3) == 0)
	    MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
							     attr | MSG_HIST);
	else
#endif
	    MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"),
							     attr | MSG_HIST);
	MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST);
	/* avoid going past the end of a corrupted hostname */
	b0p->b0_fname[0] = NUL;
	MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST);
	MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST);
	msg_end();
	goto theend;
    }

#ifdef FEAT_CRYPT
    if (b0p->b0_id[1] == BLOCK0_ID1_C0)
	b0_cm = 0;
    else if (b0p->b0_id[1] == BLOCK0_ID1_C1)
    {
	b0_cm = 1;
	mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
    }
    set_crypt_method(buf, b0_cm);
#else
    if (b0p->b0_id[1] != BLOCK0_ID1)
    {
	EMSG2(_("E833: %s is encrypted and this version of Vim does not support encryption"), mfp->mf_fname);
	goto theend;
    }
#endif

    /*
     * If we guessed the wrong page size, we have to recalculate the
     * highest block number in the file.
     */
    if (mfp->mf_page_size != (unsigned)char_to_long(b0p->b0_page_size))
    {
	unsigned previous_page_size = mfp->mf_page_size;

	mf_new_page_size(mfp, (unsigned)char_to_long(b0p->b0_page_size));
	if (mfp->mf_page_size < previous_page_size)
	{
	    msg_start();
	    msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
	    MSG_PUTS_ATTR(_(" has been damaged (page size is smaller than minimum value).\n"),
			attr | MSG_HIST);
	    msg_end();
	    goto theend;
	}
	if ((size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
	    mfp->mf_blocknr_max = 0;	    /* no file or empty file */
	else
	    mfp->mf_blocknr_max = (blocknr_T)(size / mfp->mf_page_size);
	mfp->mf_infile_count = mfp->mf_blocknr_max;

	/* need to reallocate the memory used to store the data */
	p = alloc(mfp->mf_page_size);
	if (p == NULL)
	    goto theend;
	mch_memmove(p, hp->bh_data, previous_page_size);
	vim_free(hp->bh_data);
	hp->bh_data = p;
	b0p = (ZERO_BL *)(hp->bh_data);
    }

    /*
     * If .swp file name given directly, use name from swap file for buffer.
     */
    if (directly)
    {
	expand_env(b0p->b0_fname, NameBuff, MAXPATHL);
	if (setfname(curbuf, NameBuff, NULL, TRUE) == FAIL)
	    goto theend;
    }

    home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
    smsg((char_u *)_("Using swap file \"%s\""), NameBuff);

    if (buf_spname(curbuf) != NULL)
	STRCPY(NameBuff, buf_spname(curbuf));
    else
	home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
    smsg((char_u *)_("Original file \"%s\""), NameBuff);
    msg_putchar('\n');

    /*
     * check date of swap file and original file
     */
    mtime = char_to_long(b0p->b0_mtime);
    if (curbuf->b_ffname != NULL
	    && mch_stat((char *)curbuf->b_ffname, &org_stat) != -1
	    && ((mch_stat((char *)mfp->mf_fname, &swp_stat) != -1
		    && org_stat.st_mtime > swp_stat.st_mtime)
		|| org_stat.st_mtime != mtime))
    {
	EMSG(_("E308: Warning: Original file may have been changed"));
    }
    out_flush();

    /* Get the 'fileformat' and 'fileencoding' from block zero. */
    b0_ff = (b0p->b0_flags & B0_FF_MASK);
    if (b0p->b0_flags & B0_HAS_FENC)
    {
	int fnsize = B0_FNAME_SIZE_NOCRYPT;

#ifdef FEAT_CRYPT
	/* Use the same size as in add_b0_fenc(). */
	if (b0p->b0_id[1] != BLOCK0_ID1)
	    fnsize = B0_FNAME_SIZE_CRYPT;
#endif
	for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; --p)
	    ;
	b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + fnsize - p));
    }

    mf_put(mfp, hp, FALSE, FALSE);	/* release block 0 */
    hp = NULL;

    /*
     * Now that we are sure that the file is going to be recovered, clear the
     * contents of the current buffer.
     */
    while (!(curbuf->b_ml.ml_flags & ML_EMPTY))
	ml_delete((linenr_T)1, FALSE);

    /*
     * Try reading the original file to obtain the values of 'fileformat',
     * 'fileencoding', etc.  Ignore errors.  The text itself is not used.
     * When the file is encrypted the user is asked to enter the key.
     */
    if (curbuf->b_ffname != NULL)
	orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0,
			      (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);

#ifdef FEAT_CRYPT
    if (b0_cm >= 0)
    {
	/* Need to ask the user for the crypt key.  If this fails we continue
	 * without a key, will probably get garbage text. */
	if (*curbuf->b_p_key != NUL)
	{
	    smsg((char_u *)_("Swap file is encrypted: \"%s\""), fname_used);
	    MSG_PUTS(_("\nIf you entered a new crypt key but did not write the text file,"));
	    MSG_PUTS(_("\nenter the new crypt key."));
	    MSG_PUTS(_("\nIf you wrote the text file after changing the crypt key press enter"));
	    MSG_PUTS(_("\nto use the same key for text file and swap file"));
	}
	else
	    smsg((char_u *)_(need_key_msg), fname_used);
	buf->b_p_key = get_crypt_key(FALSE, FALSE);
	if (buf->b_p_key == NULL)
	    buf->b_p_key = curbuf->b_p_key;
	else if (*buf->b_p_key == NUL)
	{
	    vim_free(buf->b_p_key);
	    buf->b_p_key = curbuf->b_p_key;
	}
	if (buf->b_p_key == NULL)
	    buf->b_p_key = empty_option;
    }
#endif

    /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */
    if (b0_ff != 0)
	set_fileformat(b0_ff - 1, OPT_LOCAL);
    if (b0_fenc != NULL)
    {
	set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL);
	vim_free(b0_fenc);
    }
    unchanged(curbuf, TRUE);

    bnum = 1;		/* start with block 1 */
    page_count = 1;	/* which is 1 page */
    lnum = 0;		/* append after line 0 in curbuf */
    line_count = 0;
    idx = 0;		/* start with first index in block 1 */
    error = 0;
    buf->b_ml.ml_stack_top = 0;
    buf->b_ml.ml_stack = NULL;
    buf->b_ml.ml_stack_size = 0;	/* no stack yet */

    if (curbuf->b_ffname == NULL)
	cannot_open = TRUE;
    else
	cannot_open = FALSE;

    serious_error = FALSE;
    for ( ; !got_int; line_breakcheck())
    {
	if (hp != NULL)
	    mf_put(mfp, hp, FALSE, FALSE);	/* release previous block */

	/*
	 * get block
	 */
	if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
	{
	    if (bnum == 1)
	    {
		EMSG2(_("E309: Unable to read block 1 from %s"), mfp->mf_fname);
		goto theend;
	    }
	    ++error;
	    ml_append(lnum++, (char_u *)_("???MANY LINES MISSING"),
							    (colnr_T)0, TRUE);
	}
	else		/* there is a block */
	{
	    pp = (PTR_BL *)(hp->bh_data);
	    if (pp->pb_id == PTR_ID)		/* it is a pointer block */
	    {
		/* check line count when using pointer block first time */
		if (idx == 0 && line_count != 0)
		{
		    for (i = 0; i < (int)pp->pb_count; ++i)
			line_count -= pp->pb_pointer[i].pe_line_count;
		    if (line_count != 0)
		    {
			++error;
			ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"),
							    (colnr_T)0, TRUE);
		    }
		}

		if (pp->pb_count == 0)
		{
		    ml_append(lnum++, (char_u *)_("???EMPTY BLOCK"),
							    (colnr_T)0, TRUE);
		    ++error;
		}
		else if (idx < (int)pp->pb_count)	/* go a block deeper */
		{
		    if (pp->pb_pointer[idx].pe_bnum < 0)
		    {
			/*
			 * Data block with negative block number.
			 * Try to read lines from the original file.
			 * This is slow, but it works.
			 */
			if (!cannot_open)
			{
			    line_count = pp->pb_pointer[idx].pe_line_count;
			    if (readfile(curbuf->b_ffname, NULL, lnum,
					pp->pb_pointer[idx].pe_old_lnum - 1,
					line_count, NULL, 0) == FAIL)
				cannot_open = TRUE;
			    else
				lnum += line_count;
			}
			if (cannot_open)
			{
			    ++error;
			    ml_append(lnum++, (char_u *)_("???LINES MISSING"),
							    (colnr_T)0, TRUE);
			}
			++idx;	    /* get same block again for next index */
			continue;
		    }

		    /*
		     * going one block deeper in the tree
		     */
		    if ((top = ml_add_stack(buf)) < 0)	/* new entry in stack */
		    {
			++error;
			break;		    /* out of memory */
		    }
		    ip = &(buf->b_ml.ml_stack[top]);
		    ip->ip_bnum = bnum;
		    ip->ip_index = idx;

		    bnum = pp->pb_pointer[idx].pe_bnum;
		    line_count = pp->pb_pointer[idx].pe_line_count;
		    page_count = pp->pb_pointer[idx].pe_page_count;
		    continue;
		}
	    }
	    else	    /* not a pointer block */
	    {
		dp = (DATA_BL *)(hp->bh_data);
		if (dp->db_id != DATA_ID)	/* block id wrong */
		{
		    if (bnum == 1)
		    {
			EMSG2(_("E310: Block 1 ID wrong (%s not a .swp file?)"),
							       mfp->mf_fname);
			goto theend;
		    }
		    ++error;
		    ml_append(lnum++, (char_u *)_("???BLOCK MISSING"),
							    (colnr_T)0, TRUE);
		}
		else
		{
		    /*
		     * it is a data block
		     * Append all the lines in this block
		     */
		    has_error = FALSE;
			/*
			 * check length of block
			 * if wrong, use length in pointer block
			 */
		    if (page_count * mfp->mf_page_size != dp->db_txt_end)
		    {
			ml_append(lnum++, (char_u *)_("??? from here until ???END lines may be messed up"),
							    (colnr_T)0, TRUE);
			++error;
			has_error = TRUE;
			dp->db_txt_end = page_count * mfp->mf_page_size;
		    }

			/* make sure there is a NUL at the end of the block */
		    *((char_u *)dp + dp->db_txt_end - 1) = NUL;

			/*
			 * check number of lines in block
			 * if wrong, use count in data block
			 */
		    if (line_count != dp->db_line_count)
		    {
			ml_append(lnum++, (char_u *)_("??? from here until ???END lines may have been inserted/deleted"),
							    (colnr_T)0, TRUE);
			++error;
			has_error = TRUE;
		    }

		    for (i = 0; i < dp->db_line_count; ++i)
		    {
			txt_start = (dp->db_index[i] & DB_INDEX_MASK);
			if (txt_start <= (int)HEADER_SIZE
					  || txt_start >= (int)dp->db_txt_end)
			{
			    p = (char_u *)"???";
			    ++error;
			}
			else
			    p = (char_u *)dp + txt_start;
			ml_append(lnum++, p, (colnr_T)0, TRUE);
		    }
		    if (has_error)
			ml_append(lnum++, (char_u *)_("???END"),
							    (colnr_T)0, TRUE);
		}
	    }
	}

	if (buf->b_ml.ml_stack_top == 0)	/* finished */
	    break;

	/*
	 * go one block up in the tree
	 */
	ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
	bnum = ip->ip_bnum;
	idx = ip->ip_index + 1;	    /* go to next index */
	page_count = 1;
    }

    /*
     * Compare the buffer contents with the original file.  When they differ
     * set the 'modified' flag.
     * Lines 1 - lnum are the new contents.
     * Lines lnum + 1 to ml_line_count are the original contents.
     * Line ml_line_count + 1 in the dummy empty line.
     */
    if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1)
    {
	/* Recovering an empty file results in two lines and the first line is
	 * empty.  Don't set the modified flag then. */
	if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
	{
	    changed_int();
	    ++curbuf->b_changedtick;
	}
    }
    else
    {
	for (idx = 1; idx <= lnum; ++idx)
	{
	    /* Need to copy one line, fetching the other one may flush it. */
	    p = vim_strsave(ml_get(idx));
	    i = STRCMP(p, ml_get(idx + lnum));
	    vim_free(p);
	    if (i != 0)
	    {
		changed_int();
		++curbuf->b_changedtick;
		break;
	    }
	}
    }

    /*
     * Delete the lines from the original file and the dummy line from the
     * empty buffer.  These will now be after the last line in the buffer.
     */
    while (curbuf->b_ml.ml_line_count > lnum
				       && !(curbuf->b_ml.ml_flags & ML_EMPTY))
	ml_delete(curbuf->b_ml.ml_line_count, FALSE);
    curbuf->b_flags |= BF_RECOVERED;

    recoverymode = FALSE;
    if (got_int)
	EMSG(_("E311: Recovery Interrupted"));
    else if (error)
    {
	++no_wait_return;
	MSG(">>>>>>>>>>>>>");
	EMSG(_("E312: Errors detected while recovering; look for lines starting with ???"));
	--no_wait_return;
	MSG(_("See \":help E312\" for more information."));
	MSG(">>>>>>>>>>>>>");
    }
    else
    {
	if (curbuf->b_changed)
	{
	    MSG(_("Recovery completed. You should check if everything is OK."));
	    MSG_PUTS(_("\n(You might want to write out this file under another name\n"));
	    MSG_PUTS(_("and run diff with the original file to check for changes)"));
	}
	else
	    MSG(_("Recovery completed. Buffer contents equals file contents."));
	MSG_PUTS(_("\nYou may want to delete the .swp file now.\n\n"));
	cmdline_row = msg_row;
    }
#ifdef FEAT_CRYPT
    if (*buf->b_p_key != NUL && STRCMP(curbuf->b_p_key, buf->b_p_key) != 0)
    {
	MSG_PUTS(_("Using crypt key from swap file for the text file.\n"));
	set_option_value((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL);
    }
#endif
    redraw_curbuf_later(NOT_VALID);

theend:
    vim_free(fname_used);
    recoverymode = FALSE;
    if (mfp != NULL)
    {
	if (hp != NULL)
	    mf_put(mfp, hp, FALSE, FALSE);
	mf_close(mfp, FALSE);	    /* will also vim_free(mfp->mf_fname) */
    }
    if (buf != NULL)
    {
#ifdef FEAT_CRYPT
	if (buf->b_p_key != curbuf->b_p_key)
	    free_string_option(buf->b_p_key);
	free_string_option(buf->b_p_cm);
#endif
	vim_free(buf->b_ml.ml_stack);
	vim_free(buf);
    }
    if (serious_error && called_from_main)
	ml_close(curbuf, TRUE);
#ifdef FEAT_AUTOCMD
    else
    {
	apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf);
	apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf);
    }
#endif
    return;
}

/*
 * Find the names of swap files in current directory and the directory given
 * with the 'directory' option.
 *
 * Used to:
 * - list the swap files for "vim -r"
 * - count the number of swap files when recovering
 * - list the swap files when recovering
 * - find the name of the n'th swap file when recovering
 */
    int
recover_names(fname, list, nr, fname_out)
    char_u	*fname;		/* base for swap file name */
    int		list;		/* when TRUE, list the swap file names */
    int		nr;		/* when non-zero, return nr'th swap file name */
    char_u	**fname_out;	/* result when "nr" > 0 */
{
    int		num_names;
    char_u	*(names[6]);
    char_u	*tail;
    char_u	*p;
    int		num_files;
    int		file_count = 0;
    char_u	**files;
    int		i;
    char_u	*dirp;
    char_u	*dir_name;
    char_u	*fname_res = NULL;
#ifdef HAVE_READLINK
    char_u	fname_buf[MAXPATHL];
#endif

    if (fname != NULL)
    {
#ifdef HAVE_READLINK
	/* Expand symlink in the file name, because the swap file is created
	 * with the actual file instead of with the symlink. */
	if (resolve_symlink(fname, fname_buf) == OK)
	    fname_res = fname_buf;
	else
#endif
	    fname_res = fname;
    }

    if (list)
    {
	/* use msg() to start the scrolling properly */
	msg((char_u *)_("Swap files found:"));
	msg_putchar('\n');
    }

    /*
     * Do the loop for every directory in 'directory'.
     * First allocate some memory to put the directory name in.
     */
    dir_name = alloc((unsigned)STRLEN(p_dir) + 1);
    dirp = p_dir;
    while (dir_name != NULL && *dirp)
    {
	/*
	 * Isolate a directory name from *dirp and put it in dir_name (we know
	 * it is large enough, so use 31000 for length).
	 * Advance dirp to next directory name.
	 */
	(void)copy_option_part(&dirp, dir_name, 31000, ",");

	if (dir_name[0] == '.' && dir_name[1] == NUL)	/* check current dir */
	{
	    if (fname == NULL)
	    {
#ifdef VMS
		names[0] = vim_strsave((char_u *)"*_sw%");
#else
# ifdef RISCOS
		names[0] = vim_strsave((char_u *)"*_sw#");
# else
		names[0] = vim_strsave((char_u *)"*.sw?");
# endif
#endif
#if defined(UNIX) || defined(WIN3264)
		/* For Unix names starting with a dot are special.  MS-Windows
		 * supports this too, on some file systems. */
		names[1] = vim_strsave((char_u *)".*.sw?");
		names[2] = vim_strsave((char_u *)".sw?");
		num_names = 3;
#else
# ifdef VMS
		names[1] = vim_strsave((char_u *)".*_sw%");
		num_names = 2;
# else
		num_names = 1;
# endif
#endif
	    }
	    else
		num_names = recov_file_names(names, fname_res, TRUE);
	}
	else			    /* check directory dir_name */
	{
	    if (fname == NULL)
	    {
#ifdef VMS
		names[0] = concat_fnames(dir_name, (char_u *)"*_sw%", TRUE);
#else
# ifdef RISCOS
		names[0] = concat_fnames(dir_name, (char_u *)"*_sw#", TRUE);
# else
		names[0] = concat_fnames(dir_name, (char_u *)"*.sw?", TRUE);
# endif
#endif
#if defined(UNIX) || defined(WIN3264)
		/* For Unix names starting with a dot are special.  MS-Windows
		 * supports this too, on some file systems. */
		names[1] = concat_fnames(dir_name, (char_u *)".*.sw?", TRUE);
		names[2] = concat_fnames(dir_name, (char_u *)".sw?", TRUE);
		num_names = 3;
#else
# ifdef VMS
		names[1] = concat_fnames(dir_name, (char_u *)".*_sw%", TRUE);
		num_names = 2;
# else
		num_names = 1;
# endif
#endif
	    }
	    else
	    {
#if defined(UNIX) || defined(WIN3264)
		p = dir_name + STRLEN(dir_name);
		if (after_pathsep(dir_name, p) && p[-1] == p[-2])
		{
		    /* Ends with '//', Use Full path for swap name */
		    tail = make_percent_swname(dir_name, fname_res);
		}
		else
#endif
		{
		    tail = gettail(fname_res);
		    tail = concat_fnames(dir_name, tail, TRUE);
		}
		if (tail == NULL)
		    num_names = 0;
		else
		{
		    num_names = recov_file_names(names, tail, FALSE);
		    vim_free(tail);
		}
	    }
	}

	    /* check for out-of-memory */
	for (i = 0; i < num_names; ++i)
	{
	    if (names[i] == NULL)
	    {
		for (i = 0; i < num_names; ++i)
		    vim_free(names[i]);
		num_names = 0;
	    }
	}
	if (num_names == 0)
	    num_files = 0;
	else if (expand_wildcards(num_names, names, &num_files, &files,
					EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL)
	    num_files = 0;

	/*
	 * When no swap file found, wildcard expansion might have failed (e.g.
	 * not able to execute the shell).
	 * Try finding a swap file by simply adding ".swp" to the file name.
	 */
	if (*dirp == NUL && file_count + num_files == 0 && fname != NULL)
	{
	    struct stat	    st;
	    char_u	    *swapname;

	    swapname = modname(fname_res,
#if defined(VMS) || defined(RISCOS)
			       (char_u *)"_swp", FALSE
#else
			       (char_u *)".swp", TRUE
#endif
			      );
	    if (swapname != NULL)
	    {
		if (mch_stat((char *)swapname, &st) != -1)	    /* It exists! */
		{
		    files = (char_u **)alloc((unsigned)sizeof(char_u *));
		    if (files != NULL)
		    {
			files[0] = swapname;
			swapname = NULL;
			num_files = 1;
		    }
		}
		vim_free(swapname);
	    }
	}

	/*
	 * remove swapfile name of the current buffer, it must be ignored
	 */
	if (curbuf->b_ml.ml_mfp != NULL
			       && (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL)
	{
	    for (i = 0; i < num_files; ++i)
		if (fullpathcmp(p, files[i], TRUE) & FPC_SAME)
		{
		    /* Remove the name from files[i].  Move further entries
		     * down.  When the array becomes empty free it here, since
		     * FreeWild() won't be called below. */
		    vim_free(files[i]);
		    if (--num_files == 0)
			vim_free(files);
		    else
			for ( ; i < num_files; ++i)
			    files[i] = files[i + 1];
		}
	}
	if (nr > 0)
	{
	    file_count += num_files;
	    if (nr <= file_count)
	    {
		*fname_out = vim_strsave(
				      files[nr - 1 + num_files - file_count]);
		dirp = (char_u *)"";		    /* stop searching */
	    }
	}
	else if (list)
	{
	    if (dir_name[0] == '.' && dir_name[1] == NUL)
	    {
		if (fname == NULL)
		    MSG_PUTS(_("   In current directory:\n"));
		else
		    MSG_PUTS(_("   Using specified name:\n"));
	    }
	    else
	    {
		MSG_PUTS(_("   In directory "));
		msg_home_replace(dir_name);
		MSG_PUTS(":\n");
	    }

	    if (num_files)
	    {
		for (i = 0; i < num_files; ++i)
		{
		    /* print the swap file name */
		    msg_outnum((long)++file_count);
		    MSG_PUTS(".    ");
		    msg_puts(gettail(files[i]));
		    msg_putchar('\n');
		    (void)swapfile_info(files[i]);
		}
	    }
	    else
		MSG_PUTS(_("      -- none --\n"));
	    out_flush();
	}
	else
	    file_count += num_files;

	for (i = 0; i < num_names; ++i)
	    vim_free(names[i]);
	if (num_files > 0)
	    FreeWild(num_files, files);
    }
    vim_free(dir_name);
    return file_count;
}

#if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
/*
 * Append the full path to name with path separators made into percent
 * signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
 */
    static char_u *
make_percent_swname(dir, name)
    char_u	*dir;
    char_u	*name;
{
    char_u *d, *s, *f;

    f = fix_fname(name != NULL ? name : (char_u *) "");
    d = NULL;
    if (f != NULL)
    {
	s = alloc((unsigned)(STRLEN(f) + 1));
	if (s != NULL)
	{
	    STRCPY(s, f);
	    for (d = s; *d != NUL; mb_ptr_adv(d))
		if (vim_ispathsep(*d))
		    *d = '%';
	    d = concat_fnames(dir, s, TRUE);
	    vim_free(s);
	}
	vim_free(f);
    }
    return d;
}
#endif

#if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
static int process_still_running;
#endif

/*
 * Give information about an existing swap file.
 * Returns timestamp (0 when unknown).
 */
    static time_t
swapfile_info(fname)
    char_u	*fname;
{
    struct stat	    st;
    int		    fd;
    struct block0   b0;
    time_t	    x = (time_t)0;
    char	    *p;
#ifdef UNIX
    char_u	    uname[B0_UNAME_SIZE];
#endif

    /* print the swap file date */
    if (mch_stat((char *)fname, &st) != -1)
    {
#ifdef UNIX
	/* print name of owner of the file */
	if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK)
	{
	    MSG_PUTS(_("          owned by: "));
	    msg_outtrans(uname);
	    MSG_PUTS(_("   dated: "));
	}
	else
#endif
	    MSG_PUTS(_("             dated: "));
	x = st.st_mtime;		    /* Manx C can't do &st.st_mtime */
	p = ctime(&x);			    /* includes '\n' */
	if (p == NULL)
	    MSG_PUTS("(invalid)\n");
	else
	    MSG_PUTS(p);
    }

    /*
     * print the original file name
     */
    fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
    if (fd >= 0)
    {
	if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
	{
	    if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0)
	    {
		MSG_PUTS(_("         [from Vim version 3.0]"));
	    }
	    else if (ml_check_b0_id(&b0) == FAIL)
	    {
		MSG_PUTS(_("         [does not look like a Vim swap file]"));
	    }
	    else
	    {
		MSG_PUTS(_("         file name: "));
		if (b0.b0_fname[0] == NUL)
		    MSG_PUTS(_("[No Name]"));
		else
		    msg_outtrans(b0.b0_fname);

		MSG_PUTS(_("\n          modified: "));
		MSG_PUTS(b0.b0_dirty ? _("YES") : _("no"));

		if (*(b0.b0_uname) != NUL)
		{
		    MSG_PUTS(_("\n         user name: "));
		    msg_outtrans(b0.b0_uname);
		}

		if (*(b0.b0_hname) != NUL)
		{
		    if (*(b0.b0_uname) != NUL)
			MSG_PUTS(_("   host name: "));
		    else
			MSG_PUTS(_("\n         host name: "));
		    msg_outtrans(b0.b0_hname);
		}

		if (char_to_long(b0.b0_pid) != 0L)
		{
		    MSG_PUTS(_("\n        process ID: "));
		    msg_outnum(char_to_long(b0.b0_pid));
#if defined(UNIX) || defined(__EMX__)
		    /* EMX kill() not working correctly, it seems */
		    if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0)
		    {
			MSG_PUTS(_(" (still running)"));
# if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
			process_still_running = TRUE;
# endif
		    }
#endif
		}

		if (b0_magic_wrong(&b0))
		{
#if defined(MSDOS) || defined(MSWIN)
		    if (STRNCMP(b0.b0_hname, "PC ", 3) == 0)
			MSG_PUTS(_("\n         [not usable with this version of Vim]"));
		    else
#endif
			MSG_PUTS(_("\n         [not usable on this computer]"));
		}
	    }
	}
	else
	    MSG_PUTS(_("         [cannot be read]"));
	close(fd);
    }
    else
	MSG_PUTS(_("         [cannot be opened]"));
    msg_putchar('\n');

    return x;
}

    static int
recov_file_names(names, path, prepend_dot)
    char_u	**names;
    char_u	*path;
    int		prepend_dot;
{
    int		num_names;

#ifdef SHORT_FNAME
    /*
     * (MS-DOS) always short names
     */
    names[0] = modname(path, (char_u *)".sw?", FALSE);
    num_names = 1;
#else /* !SHORT_FNAME */
    /*
     * (Win32 and Win64) never short names, but do prepend a dot.
     * (Not MS-DOS or Win32 or Win64) maybe short name, maybe not: Try both.
     * Only use the short name if it is different.
     */
    char_u	*p;
    int		i;
# ifndef WIN3264
    int	    shortname = curbuf->b_shortname;

    curbuf->b_shortname = FALSE;
# endif

    num_names = 0;

    /*
     * May also add the file name with a dot prepended, for swap file in same
     * dir as original file.
     */
    if (prepend_dot)
    {
	names[num_names] = modname(path, (char_u *)".sw?", TRUE);
	if (names[num_names] == NULL)
	    goto end;
	++num_names;
    }

    /*
     * Form the normal swap file name pattern by appending ".sw?".
     */
#ifdef VMS
    names[num_names] = concat_fnames(path, (char_u *)"_sw%", FALSE);
#else
# ifdef RISCOS
    names[num_names] = concat_fnames(path, (char_u *)"_sw#", FALSE);
# else
    names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE);
# endif
#endif
    if (names[num_names] == NULL)
	goto end;
    if (num_names >= 1)	    /* check if we have the same name twice */
    {
	p = names[num_names - 1];
	i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
	if (i > 0)
	    p += i;	    /* file name has been expanded to full path */

	if (STRCMP(p, names[num_names]) != 0)
	    ++num_names;
	else
	    vim_free(names[num_names]);
    }
    else
	++num_names;

# ifndef WIN3264
    /*
     * Also try with 'shortname' set, in case the file is on a DOS filesystem.
     */
    curbuf->b_shortname = TRUE;
#ifdef VMS
    names[num_names] = modname(path, (char_u *)"_sw%", FALSE);
#else
# ifdef RISCOS
    names[num_names] = modname(path, (char_u *)"_sw#", FALSE);
# else
    names[num_names] = modname(path, (char_u *)".sw?", FALSE);
# endif
#endif
    if (names[num_names] == NULL)
	goto end;

    /*
     * Remove the one from 'shortname', if it's the same as with 'noshortname'.
     */
    p = names[num_names];
    i = STRLEN(names[num_names]) - STRLEN(names[num_names - 1]);
    if (i > 0)
	p += i;		/* file name has been expanded to full path */
    if (STRCMP(names[num_names - 1], p) == 0)
	vim_free(names[num_names]);
    else
	++num_names;
# endif

end:
# ifndef WIN3264
    curbuf->b_shortname = shortname;
# endif

#endif /* !SHORT_FNAME */

    return num_names;
}

/*
 * sync all memlines
 *
 * If 'check_file' is TRUE, check if original file exists and was not changed.
 * If 'check_char' is TRUE, stop syncing when character becomes available, but
 * always sync at least one block.
 */
    void
ml_sync_all(check_file, check_char)
    int	    check_file;
    int	    check_char;
{
    buf_T		*buf;
    struct stat		st;

    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
    {
	if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
	    continue;			    /* no file */

	ml_flush_line(buf);		    /* flush buffered line */
					    /* flush locked block */
	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
	if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
						     && buf->b_ffname != NULL)
	{
	    /*
	     * If the original file does not exist anymore or has been changed
	     * call ml_preserve() to get rid of all negative numbered blocks.
	     */
	    if (mch_stat((char *)buf->b_ffname, &st) == -1
		    || st.st_mtime != buf->b_mtime_read
		    || st.st_size != buf->b_orig_size)
	    {
		ml_preserve(buf, FALSE);
		did_check_timestamps = FALSE;
		need_check_timestamps = TRUE;	/* give message later */
	    }
	}
	if (buf->b_ml.ml_mfp->mf_dirty)
	{
	    (void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
					| (bufIsChanged(buf) ? MFS_FLUSH : 0));
	    if (check_char && ui_char_avail())	/* character available now */
		break;
	}
    }
}

/*
 * sync one buffer, including negative blocks
 *
 * after this all the blocks are in the swap file
 *
 * Used for the :preserve command and when the original file has been
 * changed or deleted.
 *
 * when message is TRUE the success of preserving is reported
 */
    void
ml_preserve(buf, message)
    buf_T	*buf;
    int		message;
{
    bhdr_T	*hp;
    linenr_T	lnum;
    memfile_T	*mfp = buf->b_ml.ml_mfp;
    int		status;
    int		got_int_save = got_int;

    if (mfp == NULL || mfp->mf_fname == NULL)
    {
	if (message)
	    EMSG(_("E313: Cannot preserve, there is no swap file"));
	return;
    }

    /* We only want to stop when interrupted here, not when interrupted
     * before. */
    got_int = FALSE;

    ml_flush_line(buf);				    /* flush buffered line */
    (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
    status = mf_sync(mfp, MFS_ALL | MFS_FLUSH);

    /* stack is invalid after mf_sync(.., MFS_ALL) */
    buf->b_ml.ml_stack_top = 0;

    /*
     * Some of the data blocks may have been changed from negative to
     * positive block number. In that case the pointer blocks need to be
     * updated.
     *
     * We don't know in which pointer block the references are, so we visit
     * all data blocks until there are no more translations to be done (or
     * we hit the end of the file, which can only happen in case a write fails,
     * e.g. when file system if full).
     * ml_find_line() does the work by translating the negative block numbers
     * when getting the first line of each data block.
     */
    if (mf_need_trans(mfp) && !got_int)
    {
	lnum = 1;
	while (mf_need_trans(mfp) && lnum <= buf->b_ml.ml_line_count)
	{
	    hp = ml_find_line(buf, lnum, ML_FIND);
	    if (hp == NULL)
	    {
		status = FAIL;
		goto theend;
	    }
	    CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
	    lnum = buf->b_ml.ml_locked_high + 1;
	}
	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);	/* flush locked block */
	/* sync the updated pointer blocks */
	if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL)
	    status = FAIL;
	buf->b_ml.ml_stack_top = 0;	    /* stack is invalid now */
    }
theend:
    got_int |= got_int_save;

    if (message)
    {
	if (status == OK)
	    MSG(_("File preserved"));
	else
	    EMSG(_("E314: Preserve failed"));
    }
}

/*
 * NOTE: The pointer returned by the ml_get_*() functions only remains valid
 * until the next call!
 *  line1 = ml_get(1);
 *  line2 = ml_get(2);	// line1 is now invalid!
 * Make a copy of the line if necessary.
 */
/*
 * Return a pointer to a (read-only copy of a) line.
 *
 * On failure an error message is given and IObuff is returned (to avoid
 * having to check for error everywhere).
 */
    char_u  *
ml_get(lnum)
    linenr_T	lnum;
{
    return ml_get_buf(curbuf, lnum, FALSE);
}

/*
 * Return pointer to position "pos".
 */
    char_u *
ml_get_pos(pos)
    pos_T	*pos;
{
    return (ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col);
}

/*
 * Return pointer to cursor line.
 */
    char_u *
ml_get_curline()
{
    return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE);
}

/*
 * Return pointer to cursor position.
 */
    char_u *
ml_get_cursor()
{
    return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
							curwin->w_cursor.col);
}

/*
 * Return a pointer to a line in a specific buffer
 *
 * "will_change": if TRUE mark the buffer dirty (chars in the line will be
 * changed)
 */
    char_u  *
ml_get_buf(buf, lnum, will_change)
    buf_T	*buf;
    linenr_T	lnum;
    int		will_change;		/* line will be changed */
{
    bhdr_T	*hp;
    DATA_BL	*dp;
    char_u	*ptr;
    static int	recursive = 0;

    if (lnum > buf->b_ml.ml_line_count)	/* invalid line number */
    {
	if (recursive == 0)
	{
	    /* Avoid giving this message for a recursive call, may happen when
	     * the GUI redraws part of the text. */
	    ++recursive;
	    EMSGN(_("E315: ml_get: invalid lnum: %ld"), lnum);
	    --recursive;
	}
errorret:
	STRCPY(IObuff, "???");
	return IObuff;
    }
    if (lnum <= 0)			/* pretend line 0 is line 1 */
	lnum = 1;

    if (buf->b_ml.ml_mfp == NULL)	/* there are no lines */
	return (char_u *)"";

    /*
     * See if it is the same line as requested last time.
     * Otherwise may need to flush last used line.
     * Don't use the last used line when 'swapfile' is reset, need to load all
     * blocks.
     */
    if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release)
    {
	ml_flush_line(buf);

	/*
	 * Find the data block containing the line.
	 * This also fills the stack with the blocks from the root to the data
	 * block and releases any locked block.
	 */
	if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL)
	{
	    if (recursive == 0)
	    {
		/* Avoid giving this message for a recursive call, may happen
		 * when the GUI redraws part of the text. */
		++recursive;
		EMSGN(_("E316: ml_get: cannot find line %ld"), lnum);
		--recursive;
	    }
	    goto errorret;
	}

	dp = (DATA_BL *)(hp->bh_data);

	ptr = (char_u *)dp + ((dp->db_index[lnum - buf->b_ml.ml_locked_low]) & DB_INDEX_MASK);
	buf->b_ml.ml_line_ptr = ptr;
	buf->b_ml.ml_line_lnum = lnum;
	buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
    }
    if (will_change)
	buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);

    return buf->b_ml.ml_line_ptr;
}

/*
 * Check if a line that was just obtained by a call to ml_get
 * is in allocated memory.
 */
    int
ml_line_alloced()
{
    return (curbuf->b_ml.ml_flags & ML_LINE_DIRTY);
}

/*
 * Append a line after lnum (may be 0 to insert a line in front of the file).
 * "line" does not need to be allocated, but can't be another line in a
 * buffer, unlocking may make it invalid.
 *
 *   newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
 *		will be set for recovery
 * Check: The caller of this function should probably also call
 * appended_lines().
 *
 * return FAIL for failure, OK otherwise
 */
    int
ml_append(lnum, line, len, newfile)
    linenr_T	lnum;		/* append after this line (can be 0) */
    char_u	*line;		/* text of the new line */
    colnr_T	len;		/* length of new line, including NUL, or 0 */
    int		newfile;	/* flag, see above */
{
    /* When starting up, we might still need to create the memfile */
    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
	return FAIL;

    if (curbuf->b_ml.ml_line_lnum != 0)
	ml_flush_line(curbuf);
    return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
}

#if defined(FEAT_SPELL) || defined(PROTO)
/*
 * Like ml_append() but for an arbitrary buffer.  The buffer must already have
 * a memline.
 */
    int
ml_append_buf(buf, lnum, line, len, newfile)
    buf_T	*buf;
    linenr_T	lnum;		/* append after this line (can be 0) */
    char_u	*line;		/* text of the new line */
    colnr_T	len;		/* length of new line, including NUL, or 0 */
    int		newfile;	/* flag, see above */
{
    if (buf->b_ml.ml_mfp == NULL)
	return FAIL;

    if (buf->b_ml.ml_line_lnum != 0)
	ml_flush_line(buf);
    return ml_append_int(buf, lnum, line, len, newfile, FALSE);
}
#endif

    static int
ml_append_int(buf, lnum, line, len, newfile, mark)
    buf_T	*buf;
    linenr_T	lnum;		/* append after this line (can be 0) */
    char_u	*line;		/* text of the new line */
    colnr_T	len;		/* length of line, including NUL, or 0 */
    int		newfile;	/* flag, see above */
    int		mark;		/* mark the new line */
{
    int		i;
    int		line_count;	/* number of indexes in current block */
    int		offset;
    int		from, to;
    int		space_needed;	/* space needed for new line */
    int		page_size;
    int		page_count;
    int		db_idx;		/* index for lnum in data block */
    bhdr_T	*hp;
    memfile_T	*mfp;
    DATA_BL	*dp;
    PTR_BL	*pp;
    infoptr_T	*ip;

					/* lnum out of range */
    if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
	return FAIL;

    if (lowest_marked && lowest_marked > lnum)
	lowest_marked = lnum + 1;

    if (len == 0)
	len = (colnr_T)STRLEN(line) + 1;	/* space needed for the text */
    space_needed = len + INDEX_SIZE;	/* space needed for text + index */

    mfp = buf->b_ml.ml_mfp;
    page_size = mfp->mf_page_size;

/*
 * find the data block containing the previous line
 * This also fills the stack with the blocks from the root to the data block
 * This also releases any locked block.
 */
    if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum,
							  ML_INSERT)) == NULL)
	return FAIL;

    buf->b_ml.ml_flags &= ~ML_EMPTY;

    if (lnum == 0)		/* got line one instead, correct db_idx */
	db_idx = -1;		/* careful, it is negative! */
    else
	db_idx = lnum - buf->b_ml.ml_locked_low;
		/* get line count before the insertion */
    line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;

    dp = (DATA_BL *)(hp->bh_data);

/*
 * If
 * - there is not enough room in the current block
 * - appending to the last line in the block
 * - not appending to the last line in the file
 * insert in front of the next block.
 */
    if ((int)dp->db_free < space_needed && db_idx == line_count - 1
					    && lnum < buf->b_ml.ml_line_count)
    {
	/*
	 * Now that the line is not going to be inserted in the block that we
	 * expected, the line count has to be adjusted in the pointer blocks
	 * by using ml_locked_lineadd.
	 */
	--(buf->b_ml.ml_locked_lineadd);
	--(buf->b_ml.ml_locked_high);
	if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
	    return FAIL;

	db_idx = -1;		    /* careful, it is negative! */
		    /* get line count before the insertion */
	line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
	CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");

	dp = (DATA_BL *)(hp->bh_data);
    }

    ++buf->b_ml.ml_line_count;

    if ((int)dp->db_free >= space_needed)	/* enough room in data block */
    {
/*
 * Insert new line in existing data block, or in data block allocated above.
 */
	dp->db_txt_start -= len;
	dp->db_free -= space_needed;
	++(dp->db_line_count);

	/*
	 * move the text of the lines that follow to the front
	 * adjust the indexes of the lines that follow
	 */
	if (line_count > db_idx + 1)	    /* if there are following lines */
	{
	    /*
	     * Offset is the start of the previous line.
	     * This will become the character just after the new line.
	     */
	    if (db_idx < 0)
		offset = dp->db_txt_end;
	    else
		offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
	    mch_memmove((char *)dp + dp->db_txt_start,
					  (char *)dp + dp->db_txt_start + len,
				 (size_t)(offset - (dp->db_txt_start + len)));
	    for (i = line_count - 1; i > db_idx; --i)
		dp->db_index[i + 1] = dp->db_index[i] - len;
	    dp->db_index[db_idx + 1] = offset - len;
	}
	else				    /* add line at the end */
	    dp->db_index[db_idx + 1] = dp->db_txt_start;

	/*
	 * copy the text into the block
	 */
	mch_memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
	if (mark)
	    dp->db_index[db_idx + 1] |= DB_MARKED;

	/*
	 * Mark the block dirty.
	 */
	buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
	if (!newfile)
	    buf->b_ml.ml_flags |= ML_LOCKED_POS;
    }
    else	    /* not enough space in data block */
    {
/*
 * If there is not enough room we have to create a new data block and copy some
 * lines into it.
 * Then we have to insert an entry in the pointer block.
 * If this pointer block also is full, we go up another block, and so on, up
 * to the root if necessary.
 * The line counts in the pointer blocks have already been adjusted by
 * ml_find_line().
 */
	long	    line_count_left, line_count_right;
	int	    page_count_left, page_count_right;
	bhdr_T	    *hp_left;
	bhdr_T	    *hp_right;
	bhdr_T	    *hp_new;
	int	    lines_moved;
	int	    data_moved = 0;	    /* init to shut up gcc */
	int	    total_moved = 0;	    /* init to shut up gcc */
	DATA_BL	    *dp_right, *dp_left;
	int	    stack_idx;
	int	    in_left;
	int	    lineadd;
	blocknr_T   bnum_left, bnum_right;
	linenr_T    lnum_left, lnum_right;
	int	    pb_idx;
	PTR_BL	    *pp_new;

	/*
	 * We are going to allocate a new data block. Depending on the
	 * situation it will be put to the left or right of the existing
	 * block.  If possible we put the new line in the left block and move
	 * the lines after it to the right block. Otherwise the new line is
	 * also put in the right block. This method is more efficient when
	 * inserting a lot of lines at one place.
	 */
	if (db_idx < 0)		/* left block is new, right block is existing */
	{
	    lines_moved = 0;
	    in_left = TRUE;
	    /* space_needed does not change */
	}
	else			/* left block is existing, right block is new */
	{
	    lines_moved = line_count - db_idx - 1;
	    if (lines_moved == 0)
		in_left = FALSE;	/* put new line in right block */
					/* space_needed does not change */
	    else
	    {
		data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
							    dp->db_txt_start;
		total_moved = data_moved + lines_moved * INDEX_SIZE;
		if ((int)dp->db_free + total_moved >= space_needed)
		{
		    in_left = TRUE;	/* put new line in left block */
		    space_needed = total_moved;
		}
		else
		{
		    in_left = FALSE;	    /* put new line in right block */
		    space_needed += total_moved;
		}
	    }
	}

	page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
	if ((hp_new = ml_new_data(mfp, newfile, page_count)) == NULL)
	{
			/* correct line counts in pointer blocks */
	    --(buf->b_ml.ml_locked_lineadd);
	    --(buf->b_ml.ml_locked_high);
	    return FAIL;
	}
	if (db_idx < 0)		/* left block is new */
	{
	    hp_left = hp_new;
	    hp_right = hp;
	    line_count_left = 0;
	    line_count_right = line_count;
	}
	else			/* right block is new */
	{
	    hp_left = hp;
	    hp_right = hp_new;
	    line_count_left = line_count;
	    line_count_right = 0;
	}
	dp_right = (DATA_BL *)(hp_right->bh_data);
	dp_left = (DATA_BL *)(hp_left->bh_data);
	bnum_left = hp_left->bh_bnum;
	bnum_right = hp_right->bh_bnum;
	page_count_left = hp_left->bh_page_count;
	page_count_right = hp_right->bh_page_count;

	/*
	 * May move the new line into the right/new block.
	 */
	if (!in_left)
	{
	    dp_right->db_txt_start -= len;
	    dp_right->db_free -= len + INDEX_SIZE;
	    dp_right->db_index[0] = dp_right->db_txt_start;
	    if (mark)
		dp_right->db_index[0] |= DB_MARKED;

	    mch_memmove((char *)dp_right + dp_right->db_txt_start,
							   line, (size_t)len);
	    ++line_count_right;
	}
	/*
	 * may move lines from the left/old block to the right/new one.
	 */
	if (lines_moved)
	{
	    /*
	     */
	    dp_right->db_txt_start -= data_moved;
	    dp_right->db_free -= total_moved;
	    mch_memmove((char *)dp_right + dp_right->db_txt_start,
			(char *)dp_left + dp_left->db_txt_start,
			(size_t)data_moved);
	    offset = dp_right->db_txt_start - dp_left->db_txt_start;
	    dp_left->db_txt_start += data_moved;
	    dp_left->db_free += total_moved;

	    /*
	     * update indexes in the new block
	     */
	    for (to = line_count_right, from = db_idx + 1;
					 from < line_count_left; ++from, ++to)
		dp_right->db_index[to] = dp->db_index[from] + offset;
	    line_count_right += lines_moved;
	    line_count_left -= lines_moved;
	}

	/*
	 * May move the new line into the left (old or new) block.
	 */
	if (in_left)
	{
	    dp_left->db_txt_start -= len;
	    dp_left->db_free -= len + INDEX_SIZE;
	    dp_left->db_index[line_count_left] = dp_left->db_txt_start;
	    if (mark)
		dp_left->db_index[line_count_left] |= DB_MARKED;
	    mch_memmove((char *)dp_left + dp_left->db_txt_start,
							   line, (size_t)len);
	    ++line_count_left;
	}

	if (db_idx < 0)		/* left block is new */
	{
	    lnum_left = lnum + 1;
	    lnum_right = 0;
	}
	else			/* right block is new */
	{
	    lnum_left = 0;
	    if (in_left)
		lnum_right = lnum + 2;
	    else
		lnum_right = lnum + 1;
	}
	dp_left->db_line_count = line_count_left;
	dp_right->db_line_count = line_count_right;

	/*
	 * release the two data blocks
	 * The new one (hp_new) already has a correct blocknumber.
	 * The old one (hp, in ml_locked) gets a positive blocknumber if
	 * we changed it and we are not editing a new file.
	 */
	if (lines_moved || in_left)
	    buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
	if (!newfile && db_idx >= 0 && in_left)
	    buf->b_ml.ml_flags |= ML_LOCKED_POS;
	mf_put(mfp, hp_new, TRUE, FALSE);

	/*
	 * flush the old data block
	 * set ml_locked_lineadd to 0, because the updating of the
	 * pointer blocks is done below
	 */
	lineadd = buf->b_ml.ml_locked_lineadd;
	buf->b_ml.ml_locked_lineadd = 0;
	ml_find_line(buf, (linenr_T)0, ML_FLUSH);   /* flush data block */

	/*
	 * update pointer blocks for the new data block
	 */
	for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
								  --stack_idx)
	{
	    ip = &(buf->b_ml.ml_stack[stack_idx]);
	    pb_idx = ip->ip_index;
	    if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
		return FAIL;
	    pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
	    if (pp->pb_id != PTR_ID)
	    {
		EMSG(_("E317: pointer block id wrong 3"));
		mf_put(mfp, hp, FALSE, FALSE);
		return FAIL;
	    }
	    /*
	     * TODO: If the pointer block is full and we are adding at the end
	     * try to insert in front of the next block
	     */
	    /* block not full, add one entry */
	    if (pp->pb_count < pp->pb_count_max)
	    {
		if (pb_idx + 1 < (int)pp->pb_count)
		    mch_memmove(&pp->pb_pointer[pb_idx + 2],
				&pp->pb_pointer[pb_idx + 1],
			(size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
		++pp->pb_count;
		pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
		pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
		pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
		pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
		pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
		pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;

		if (lnum_left != 0)
		    pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
		if (lnum_right != 0)
		    pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;

		mf_put(mfp, hp, TRUE, FALSE);
		buf->b_ml.ml_stack_top = stack_idx + 1;	    /* truncate stack */

		if (lineadd)
		{
		    --(buf->b_ml.ml_stack_top);
		    /* fix line count for rest of blocks in the stack */
		    ml_lineadd(buf, lineadd);
							/* fix stack itself */
		    buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
								      lineadd;
		    ++(buf->b_ml.ml_stack_top);
		}

		/*
		 * We are finished, break the loop here.
		 */
		break;
	    }
	    else			/* pointer block full */
	    {
		/*
		 * split the pointer block
		 * allocate a new pointer block
		 * move some of the pointer into the new block
		 * prepare for updating the parent block
		 */
		for (;;)	/* do this twice when splitting block 1 */
		{
		    hp_new = ml_new_ptr(mfp);
		    if (hp_new == NULL)	    /* TODO: try to fix tree */
			return FAIL;
		    pp_new = (PTR_BL *)(hp_new->bh_data);

		    if (hp->bh_bnum != 1)
			break;

		    /*
		     * if block 1 becomes full the tree is given an extra level
		     * The pointers from block 1 are moved into the new block.
		     * block 1 is updated to point to the new block
		     * then continue to split the new block
		     */
		    mch_memmove(pp_new, pp, (size_t)page_size);
		    pp->pb_count = 1;
		    pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum;
		    pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
		    pp->pb_pointer[0].pe_old_lnum = 1;
		    pp->pb_pointer[0].pe_page_count = 1;
		    mf_put(mfp, hp, TRUE, FALSE);   /* release block 1 */
		    hp = hp_new;		/* new block is to be split */
		    pp = pp_new;
		    CHECK(stack_idx != 0, _("stack_idx should be 0"));
		    ip->ip_index = 0;
		    ++stack_idx;	/* do block 1 again later */
		}
		/*
		 * move the pointers after the current one to the new block
		 * If there are none, the new entry will be in the new block.
		 */
		total_moved = pp->pb_count - pb_idx - 1;
		if (total_moved)
		{
		    mch_memmove(&pp_new->pb_pointer[0],
				&pp->pb_pointer[pb_idx + 1],
				(size_t)(total_moved) * sizeof(PTR_EN));
		    pp_new->pb_count = total_moved;
		    pp->pb_count -= total_moved - 1;
		    pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
		    pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
		    pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
		    if (lnum_right)
			pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
		}
		else
		{
		    pp_new->pb_count = 1;
		    pp_new->pb_pointer[0].pe_bnum = bnum_right;
		    pp_new->pb_pointer[0].pe_line_count = line_count_right;
		    pp_new->pb_pointer[0].pe_page_count = page_count_right;
		    pp_new->pb_pointer[0].pe_old_lnum = lnum_right;
		}
		pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
		pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
		pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
		if (lnum_left)
		    pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
		lnum_left = 0;
		lnum_right = 0;

		/*
		 * recompute line counts
		 */
		line_count_right = 0;
		for (i = 0; i < (int)pp_new->pb_count; ++i)
		    line_count_right += pp_new->pb_pointer[i].pe_line_count;
		line_count_left = 0;
		for (i = 0; i < (int)pp->pb_count; ++i)
		    line_count_left += pp->pb_pointer[i].pe_line_count;

		bnum_left = hp->bh_bnum;
		bnum_right = hp_new->bh_bnum;
		page_count_left = 1;
		page_count_right = 1;
		mf_put(mfp, hp, TRUE, FALSE);
		mf_put(mfp, hp_new, TRUE, FALSE);
	    }
	}

	/*
	 * Safety check: fallen out of for loop?
	 */
	if (stack_idx < 0)
	{
	    EMSG(_("E318: Updated too many blocks?"));
	    buf->b_ml.ml_stack_top = 0;	/* invalidate stack */
	}
    }

#ifdef FEAT_BYTEOFF
    /* The line was inserted below 'lnum' */
    ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE);
#endif
#ifdef FEAT_NETBEANS_INTG
    if (netbeans_active())
    {
	if (STRLEN(line) > 0)
	    netbeans_inserted(buf, lnum+1, (colnr_T)0, line, (int)STRLEN(line));
	netbeans_inserted(buf, lnum+1, (colnr_T)STRLEN(line),
							   (char_u *)"\n", 1);
    }
#endif
    return OK;
}

/*
 * Replace line lnum, with buffering, in current buffer.
 *
 * If "copy" is TRUE, make a copy of the line, otherwise the line has been
 * copied to allocated memory already.
 *
 * Check: The caller of this function should probably also call
 * changed_lines(), unless update_screen(NOT_VALID) is used.
 *
 * return FAIL for failure, OK otherwise
 */
    int
ml_replace(lnum, line, copy)
    linenr_T	lnum;
    char_u	*line;
    int		copy;
{
    if (line == NULL)		/* just checking... */
	return FAIL;

    /* When starting up, we might still need to create the memfile */
    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
	return FAIL;

    if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */
	return FAIL;
#ifdef FEAT_NETBEANS_INTG
    if (netbeans_active())
    {
	netbeans_removed(curbuf, lnum, 0, (long)STRLEN(ml_get(lnum)));
	netbeans_inserted(curbuf, lnum, 0, line, (int)STRLEN(line));
    }
#endif
    if (curbuf->b_ml.ml_line_lnum != lnum)	    /* other line buffered */
	ml_flush_line(curbuf);			    /* flush it */
    else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */
	vim_free(curbuf->b_ml.ml_line_ptr);	    /* free it */
    curbuf->b_ml.ml_line_ptr = line;
    curbuf->b_ml.ml_line_lnum = lnum;
    curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;

    return OK;
}

/*
 * Delete line 'lnum' in the current buffer.
 *
 * Check: The caller of this function should probably also call
 * deleted_lines() after this.
 *
 * return FAIL for failure, OK otherwise
 */
    int
ml_delete(lnum, message)
    linenr_T	lnum;
    int		message;
{
    ml_flush_line(curbuf);
    return ml_delete_int(curbuf, lnum, message);
}

    static int
ml_delete_int(buf, lnum, message)
    buf_T	*buf;
    linenr_T	lnum;
    int		message;
{
    bhdr_T	*hp;
    memfile_T	*mfp;
    DATA_BL	*dp;
    PTR_BL	*pp;
    infoptr_T	*ip;
    int		count;	    /* number of entries in block */
    int		idx;
    int		stack_idx;
    int		text_start;
    int		line_start;
    long	line_size;
    int		i;

    if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
	return FAIL;

    if (lowest_marked && lowest_marked > lnum)
	lowest_marked--;

/*
 * If the file becomes empty the last line is replaced by an empty line.
 */
    if (buf->b_ml.ml_line_count == 1)	    /* file becomes empty */
    {
	if (message
#ifdef FEAT_NETBEANS_INTG
		&& !netbeansSuppressNoLines
#endif
	   )
	    set_keep_msg((char_u *)_(no_lines_msg), 0);

	/* FEAT_BYTEOFF already handled in there, dont worry 'bout it below */
	i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
	buf->b_ml.ml_flags |= ML_EMPTY;

	return i;
    }

/*
 * find the data block containing the line
 * This also fills the stack with the blocks from the root to the data block
 * This also releases any locked block.
 */
    mfp = buf->b_ml.ml_mfp;
    if (mfp == NULL)
	return FAIL;

    if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
	return FAIL;

    dp = (DATA_BL *)(hp->bh_data);
    /* compute line count before the delete */
    count = (long)(buf->b_ml.ml_locked_high)
					- (long)(buf->b_ml.ml_locked_low) + 2;
    idx = lnum - buf->b_ml.ml_locked_low;

    --buf->b_ml.ml_line_count;

    line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
    if (idx == 0)		/* first line in block, text at the end */
	line_size = dp->db_txt_end - line_start;
    else
	line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;

#ifdef FEAT_NETBEANS_INTG
    if (netbeans_active())
	netbeans_removed(buf, lnum, 0, (long)line_size);
#endif

/*
 * special case: If there is only one line in the data block it becomes empty.
 * Then we have to remove the entry, pointing to this data block, from the
 * pointer block. If this pointer block also becomes empty, we go up another
 * block, and so on, up to the root if necessary.
 * The line counts in the pointer blocks have already been adjusted by
 * ml_find_line().
 */
    if (count == 1)
    {
	mf_free(mfp, hp);	/* free the data block */
	buf->b_ml.ml_locked = NULL;

	for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; --stack_idx)
	{
	    buf->b_ml.ml_stack_top = 0;	    /* stack is invalid when failing */
	    ip = &(buf->b_ml.ml_stack[stack_idx]);
	    idx = ip->ip_index;
	    if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
		return FAIL;
	    pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
	    if (pp->pb_id != PTR_ID)
	    {
		EMSG(_("E317: pointer block id wrong 4"));
		mf_put(mfp, hp, FALSE, FALSE);
		return FAIL;
	    }
	    count = --(pp->pb_count);
	    if (count == 0)	    /* the pointer block becomes empty! */
		mf_free(mfp, hp);
	    else
	    {
		if (count != idx)	/* move entries after the deleted one */
		    mch_memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
				      (size_t)(count - idx) * sizeof(PTR_EN));
		mf_put(mfp, hp, TRUE, FALSE);

		buf->b_ml.ml_stack_top = stack_idx;	/* truncate stack */
		/* fix line count for rest of blocks in the stack */
		if (buf->b_ml.ml_locked_lineadd != 0)
		{
		    ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
		    buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
						  buf->b_ml.ml_locked_lineadd;
		}
		++(buf->b_ml.ml_stack_top);

		break;
	    }
	}
	CHECK(stack_idx < 0, _("deleted block 1?"));
    }
    else
    {
	/*
	 * delete the text by moving the next lines forwards
	 */
	text_start = dp->db_txt_start;
	mch_memmove((char *)dp + text_start + line_size,
		  (char *)dp + text_start, (size_t)(line_start - text_start));

	/*
	 * delete the index by moving the next indexes backwards
	 * Adjust the indexes for the text movement.
	 */
	for (i = idx; i < count - 1; ++i)
	    dp->db_index[i] = dp->db_index[i + 1] + line_size;

	dp->db_free += line_size + INDEX_SIZE;
	dp->db_txt_start += line_size;
	--(dp->db_line_count);

	/*
	 * mark the block dirty and make sure it is in the file (for recovery)
	 */
	buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
    }

#ifdef FEAT_BYTEOFF
    ml_updatechunk(buf, lnum, line_size, ML_CHNK_DELLINE);
#endif
    return OK;
}

/*
 * set the B_MARKED flag for line 'lnum'
 */
    void
ml_setmarked(lnum)
    linenr_T lnum;
{
    bhdr_T    *hp;
    DATA_BL *dp;
				    /* invalid line number */
    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count
					       || curbuf->b_ml.ml_mfp == NULL)
	return;			    /* give error message? */

    if (lowest_marked == 0 || lowest_marked > lnum)
	lowest_marked = lnum;

    /*
     * find the data block containing the line
     * This also fills the stack with the blocks from the root to the data block
     * This also releases any locked block.
     */
    if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
	return;		    /* give error message? */

    dp = (DATA_BL *)(hp->bh_data);
    dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
    curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
}

/*
 * find the first line with its B_MARKED flag set
 */
    linenr_T
ml_firstmarked()
{
    bhdr_T	*hp;
    DATA_BL	*dp;
    linenr_T	lnum;
    int		i;

    if (curbuf->b_ml.ml_mfp == NULL)
	return (linenr_T) 0;

    /*
     * The search starts with lowest_marked line. This is the last line where
     * a mark was found, adjusted by inserting/deleting lines.
     */
    for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
    {
	/*
	 * Find the data block containing the line.
	 * This also fills the stack with the blocks from the root to the data
	 * block This also releases any locked block.
	 */
	if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
	    return (linenr_T)0;		    /* give error message? */

	dp = (DATA_BL *)(hp->bh_data);

	for (i = lnum - curbuf->b_ml.ml_locked_low;
			    lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
	    if ((dp->db_index[i]) & DB_MARKED)
	    {
		(dp->db_index[i]) &= DB_INDEX_MASK;
		curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
		lowest_marked = lnum + 1;
		return lnum;
	    }
    }

    return (linenr_T) 0;
}

/*
 * clear all DB_MARKED flags
 */
    void
ml_clearmarked()
{
    bhdr_T	*hp;
    DATA_BL	*dp;
    linenr_T	lnum;
    int		i;

    if (curbuf->b_ml.ml_mfp == NULL)	    /* nothing to do */
	return;

    /*
     * The search starts with line lowest_marked.
     */
    for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
    {
	/*
	 * Find the data block containing the line.
	 * This also fills the stack with the blocks from the root to the data
	 * block and releases any locked block.
	 */
	if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
	    return;		/* give error message? */

	dp = (DATA_BL *)(hp->bh_data);

	for (i = lnum - curbuf->b_ml.ml_locked_low;
			    lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
	    if ((dp->db_index[i]) & DB_MARKED)
	    {
		(dp->db_index[i]) &= DB_INDEX_MASK;
		curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
	    }
    }

    lowest_marked = 0;
    return;
}

/*
 * flush ml_line if necessary
 */
    static void
ml_flush_line(buf)
    buf_T	*buf;
{
    bhdr_T	*hp;
    DATA_BL	*dp;
    linenr_T	lnum;
    char_u	*new_line;
    char_u	*old_line;
    colnr_T	new_len;
    int		old_len;
    int		extra;
    int		idx;
    int		start;
    int		count;
    int		i;
    static int  entered = FALSE;

    if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL)
	return;		/* nothing to do */

    if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
    {
	/* This code doesn't work recursively, but Netbeans may call back here
	 * when obtaining the cursor position. */
	if (entered)
	    return;
	entered = TRUE;

	lnum = buf->b_ml.ml_line_lnum;
	new_line = buf->b_ml.ml_line_ptr;

	hp = ml_find_line(buf, lnum, ML_FIND);
	if (hp == NULL)
	    EMSGN(_("E320: Cannot find line %ld"), lnum);
	else
	{
	    dp = (DATA_BL *)(hp->bh_data);
	    idx = lnum - buf->b_ml.ml_locked_low;
	    start = ((dp->db_index[idx]) & DB_INDEX_MASK);
	    old_line = (char_u *)dp + start;
	    if (idx == 0)	/* line is last in block */
		old_len = dp->db_txt_end - start;
	    else		/* text of previous line follows */
		old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
	    new_len = (colnr_T)STRLEN(new_line) + 1;
	    extra = new_len - old_len;	    /* negative if lines gets smaller */

	    /*
	     * if new line fits in data block, replace directly
	     */
	    if ((int)dp->db_free >= extra)
	    {
		/* if the length changes and there are following lines */
		count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
		if (extra != 0 && idx < count - 1)
		{
		    /* move text of following lines */
		    mch_memmove((char *)dp + dp->db_txt_start - extra,
				(char *)dp + dp->db_txt_start,
				(size_t)(start - dp->db_txt_start));

		    /* adjust pointers of this and following lines */
		    for (i = idx + 1; i < count; ++i)
			dp->db_index[i] -= extra;
		}
		dp->db_index[idx] -= extra;

		/* adjust free space */
		dp->db_free -= extra;
		dp->db_txt_start -= extra;

		/* copy new line into the data block */
		mch_memmove(old_line - extra, new_line, (size_t)new_len);
		buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
#ifdef FEAT_BYTEOFF
		/* The else case is already covered by the insert and delete */
		ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
#endif
	    }
	    else
	    {
		/*
		 * Cannot do it in one data block: Delete and append.
		 * Append first, because ml_delete_int() cannot delete the
		 * last line in a buffer, which causes trouble for a buffer
		 * that has only one line.
		 * Don't forget to copy the mark!
		 */
		/* How about handling errors??? */
		(void)ml_append_int(buf, lnum, new_line, new_len, FALSE,
					     (dp->db_index[idx] & DB_MARKED));
		(void)ml_delete_int(buf, lnum, FALSE);
	    }
	}
	vim_free(new_line);

	entered = FALSE;
    }

    buf->b_ml.ml_line_lnum = 0;
}

/*
 * create a new, empty, data block
 */
    static bhdr_T *
ml_new_data(mfp, negative, page_count)
    memfile_T	*mfp;
    int		negative;
    int		page_count;
{
    bhdr_T	*hp;
    DATA_BL	*dp;

    if ((hp = mf_new(mfp, negative, page_count)) == NULL)
	return NULL;

    dp = (DATA_BL *)(hp->bh_data);
    dp->db_id = DATA_ID;
    dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
    dp->db_free = dp->db_txt_start - HEADER_SIZE;
    dp->db_line_count = 0;

    return hp;
}

/*
 * create a new, empty, pointer block
 */
    static bhdr_T *
ml_new_ptr(mfp)
    memfile_T	*mfp;
{
    bhdr_T	*hp;
    PTR_BL	*pp;

    if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
	return NULL;

    pp = (PTR_BL *)(hp->bh_data);
    pp->pb_id = PTR_ID;
    pp->pb_count = 0;
    pp->pb_count_max = (short_u)((mfp->mf_page_size - sizeof(PTR_BL))
							/ sizeof(PTR_EN) + 1);

    return hp;
}

/*
 * lookup line 'lnum' in a memline
 *
 *   action: if ML_DELETE or ML_INSERT the line count is updated while searching
 *	     if ML_FLUSH only flush a locked block
 *	     if ML_FIND just find the line
 *
 * If the block was found it is locked and put in ml_locked.
 * The stack is updated to lead to the locked block. The ip_high field in
 * the stack is updated to reflect the last line in the block AFTER the
 * insert or delete, also if the pointer block has not been updated yet. But
 * if ml_locked != NULL ml_locked_lineadd must be added to ip_high.
 *
 * return: NULL for failure, pointer to block header otherwise
 */
    static bhdr_T *
ml_find_line(buf, lnum, action)
    buf_T	*buf;
    linenr_T	lnum;
    int		action;
{
    DATA_BL	*dp;
    PTR_BL	*pp;
    infoptr_T	*ip;
    bhdr_T	*hp;
    memfile_T	*mfp;
    linenr_T	t;
    blocknr_T	bnum, bnum2;
    int		dirty;
    linenr_T	low, high;
    int		top;
    int		page_count;
    int		idx;

    mfp = buf->b_ml.ml_mfp;

    /*
     * If there is a locked block check if the wanted line is in it.
     * If not, flush and release the locked block.
     * Don't do this for ML_INSERT_SAME, because the stack need to be updated.
     * Don't do this for ML_FLUSH, because we want to flush the locked block.
     * Don't do this when 'swapfile' is reset, we want to load all the blocks.
     */
    if (buf->b_ml.ml_locked)
    {
	if (ML_SIMPLE(action)
		&& buf->b_ml.ml_locked_low <= lnum
		&& buf->b_ml.ml_locked_high >= lnum
		&& !mf_dont_release)
	{
	    /* remember to update pointer blocks and stack later */
	    if (action == ML_INSERT)
	    {
		++(buf->b_ml.ml_locked_lineadd);
		++(buf->b_ml.ml_locked_high);
	    }
	    else if (action == ML_DELETE)
	    {
		--(buf->b_ml.ml_locked_lineadd);
		--(buf->b_ml.ml_locked_high);
	    }
	    return (buf->b_ml.ml_locked);
	}

	mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
					    buf->b_ml.ml_flags & ML_LOCKED_POS);
	buf->b_ml.ml_locked = NULL;

	/*
	 * If lines have been added or deleted in the locked block, need to
	 * update the line count in pointer blocks.
	 */
	if (buf->b_ml.ml_locked_lineadd != 0)
	    ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
    }

    if (action == ML_FLUSH)	    /* nothing else to do */
	return NULL;

    bnum = 1;			    /* start at the root of the tree */
    page_count = 1;
    low = 1;
    high = buf->b_ml.ml_line_count;

    if (action == ML_FIND)	/* first try stack entries */
    {
	for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top)
	{
	    ip = &(buf->b_ml.ml_stack[top]);
	    if (ip->ip_low <= lnum && ip->ip_high >= lnum)
	    {
		bnum = ip->ip_bnum;
		low = ip->ip_low;
		high = ip->ip_high;
		buf->b_ml.ml_stack_top = top;	/* truncate stack at prev entry */
		break;
	    }
	}
	if (top < 0)
	    buf->b_ml.ml_stack_top = 0;		/* not found, start at the root */
    }
    else	/* ML_DELETE or ML_INSERT */
	buf->b_ml.ml_stack_top = 0;	/* start at the root */

/*
 * search downwards in the tree until a data block is found
 */
    for (;;)
    {
	if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
	    goto error_noblock;

	/*
	 * update high for insert/delete
	 */
	if (action == ML_INSERT)
	    ++high;
	else if (action == ML_DELETE)
	    --high;

	dp = (DATA_BL *)(hp->bh_data);
	if (dp->db_id == DATA_ID)	/* data block */
	{
	    buf->b_ml.ml_locked = hp;
	    buf->b_ml.ml_locked_low = low;
	    buf->b_ml.ml_locked_high = high;
	    buf->b_ml.ml_locked_lineadd = 0;
	    buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS);
	    return hp;
	}

	pp = (PTR_BL *)(dp);		/* must be pointer block */
	if (pp->pb_id != PTR_ID)
	{
	    EMSG(_("E317: pointer block id wrong"));
	    goto error_block;
	}

	if ((top = ml_add_stack(buf)) < 0)	/* add new entry to stack */
	    goto error_block;
	ip = &(buf->b_ml.ml_stack[top]);
	ip->ip_bnum = bnum;
	ip->ip_low = low;
	ip->ip_high = high;
	ip->ip_index = -1;		/* index not known yet */

	dirty = FALSE;
	for (idx = 0; idx < (int)pp->pb_count; ++idx)
	{
	    t = pp->pb_pointer[idx].pe_line_count;
	    CHECK(t == 0, _("pe_line_count is zero"));
	    if ((low += t) > lnum)
	    {
		ip->ip_index = idx;
		bnum = pp->pb_pointer[idx].pe_bnum;
		page_count = pp->pb_pointer[idx].pe_page_count;
		high = low - 1;
		low -= t;

		/*
		 * a negative block number may have been changed
		 */
		if (bnum < 0)
		{
		    bnum2 = mf_trans_del(mfp, bnum);
		    if (bnum != bnum2)
		    {
			bnum = bnum2;
			pp->pb_pointer[idx].pe_bnum = bnum;
			dirty = TRUE;
		    }
		}

		break;
	    }
	}
	if (idx >= (int)pp->pb_count)	    /* past the end: something wrong! */
	{
	    if (lnum > buf->b_ml.ml_line_count)
		EMSGN(_("E322: line number out of range: %ld past the end"),
					      lnum - buf->b_ml.ml_line_count);

	    else
		EMSGN(_("E323: line count wrong in block %ld"), bnum);
	    goto error_block;
	}
	if (action == ML_DELETE)
	{
	    pp->pb_pointer[idx].pe_line_count--;
	    dirty = TRUE;
	}
	else if (action == ML_INSERT)
	{
	    pp->pb_pointer[idx].pe_line_count++;
	    dirty = TRUE;
	}
	mf_put(mfp, hp, dirty, FALSE);
    }

error_block:
    mf_put(mfp, hp, FALSE, FALSE);
error_noblock:
    /*
     * If action is ML_DELETE or ML_INSERT we have to correct the tree for
     * the incremented/decremented line counts, because there won't be a line
     * inserted/deleted after all.
     */
    if (action == ML_DELETE)
	ml_lineadd(buf, 1);
    else if (action == ML_INSERT)
	ml_lineadd(buf, -1);
    buf->b_ml.ml_stack_top = 0;
    return NULL;
}

/*
 * add an entry to the info pointer stack
 *
 * return -1 for failure, number of the new entry otherwise
 */
    static int
ml_add_stack(buf)
    buf_T	*buf;
{
    int		top;
    infoptr_T	*newstack;

    top = buf->b_ml.ml_stack_top;

    /* may have to increase the stack size */
    if (top == buf->b_ml.ml_stack_size)
    {
	CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */

	newstack = (infoptr_T *)alloc((unsigned)sizeof(infoptr_T) *
					(buf->b_ml.ml_stack_size + STACK_INCR));
	if (newstack == NULL)
	    return -1;
	mch_memmove(newstack, buf->b_ml.ml_stack,
					     (size_t)top * sizeof(infoptr_T));
	vim_free(buf->b_ml.ml_stack);
	buf->b_ml.ml_stack = newstack;
	buf->b_ml.ml_stack_size += STACK_INCR;
    }

    buf->b_ml.ml_stack_top++;
    return top;
}

/*
 * Update the pointer blocks on the stack for inserted/deleted lines.
 * The stack itself is also updated.
 *
 * When a insert/delete line action fails, the line is not inserted/deleted,
 * but the pointer blocks have already been updated. That is fixed here by
 * walking through the stack.
 *
 * Count is the number of lines added, negative if lines have been deleted.
 */
    static void
ml_lineadd(buf, count)
    buf_T	*buf;
    int		count;
{
    int		idx;
    infoptr_T	*ip;
    PTR_BL	*pp;
    memfile_T	*mfp = buf->b_ml.ml_mfp;
    bhdr_T	*hp;

    for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx)
    {
	ip = &(buf->b_ml.ml_stack[idx]);
	if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
	    break;
	pp = (PTR_BL *)(hp->bh_data);	/* must be pointer block */
	if (pp->pb_id != PTR_ID)
	{
	    mf_put(mfp, hp, FALSE, FALSE);
	    EMSG(_("E317: pointer block id wrong 2"));
	    break;
	}
	pp->pb_pointer[ip->ip_index].pe_line_count += count;
	ip->ip_high += count;
	mf_put(mfp, hp, TRUE, FALSE);
    }
}

#if defined(HAVE_READLINK) || defined(PROTO)
/*
 * Resolve a symlink in the last component of a file name.
 * Note that f_resolve() does it for every part of the path, we don't do that
 * here.
 * If it worked returns OK and the resolved link in "buf[MAXPATHL]".
 * Otherwise returns FAIL.
 */
    int
resolve_symlink(fname, buf)
    char_u	*fname;
    char_u	*buf;
{
    char_u	tmp[MAXPATHL];
    int		ret;
    int		depth = 0;

    if (fname == NULL)
	return FAIL;

    /* Put the result so far in tmp[], starting with the original name. */
    vim_strncpy(tmp, fname, MAXPATHL - 1);

    for (;;)
    {
	/* Limit symlink depth to 100, catch recursive loops. */
	if (++depth == 100)
	{
	    EMSG2(_("E773: Symlink loop for \"%s\""), fname);
	    return FAIL;
	}

	ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
	if (ret <= 0)
	{
	    if (errno == EINVAL || errno == ENOENT)
	    {
		/* Found non-symlink or not existing file, stop here.
		 * When at the first level use the unmodified name, skip the
		 * call to vim_FullName(). */
		if (depth == 1)
		    return FAIL;

		/* Use the resolved name in tmp[]. */
		break;
	    }

	    /* There must be some error reading links, use original name. */
	    return FAIL;
	}
	buf[ret] = NUL;

	/*
	 * Check whether the symlink is relative or absolute.
	 * If it's relative, build a new path based on the directory
	 * portion of the filename (if any) and the path the symlink
	 * points to.
	 */
	if (mch_isFullName(buf))
	    STRCPY(tmp, buf);
	else
	{
	    char_u *tail;

	    tail = gettail(tmp);
	    if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL)
		return FAIL;
	    STRCPY(tail, buf);
	}
    }

    /*
     * Try to resolve the full name of the file so that the swapfile name will
     * be consistent even when opening a relative symlink from different
     * working directories.
     */
    return vim_FullName(tmp, buf, MAXPATHL, TRUE);
}
#endif

/*
 * Make swap file name out of the file name and a directory name.
 * Returns pointer to allocated memory or NULL.
 */
    char_u *
makeswapname(fname, ffname, buf, dir_name)
    char_u	*fname;
    char_u	*ffname UNUSED;
    buf_T	*buf;
    char_u	*dir_name;
{
    char_u	*r, *s;
    char_u	*fname_res = fname;
#ifdef HAVE_READLINK
    char_u	fname_buf[MAXPATHL];
#endif

#if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
    s = dir_name + STRLEN(dir_name);
    if (after_pathsep(dir_name, s) && s[-1] == s[-2])
    {			       /* Ends with '//', Use Full path */
	r = NULL;
	if ((s = make_percent_swname(dir_name, fname)) != NULL)
	{
	    r = modname(s, (char_u *)".swp", FALSE);
	    vim_free(s);
	}
	return r;
    }
#endif

#ifdef HAVE_READLINK
    /* Expand symlink in the file name, so that we put the swap file with the
     * actual file instead of with the symlink. */
    if (resolve_symlink(fname, fname_buf) == OK)
	fname_res = fname_buf;
#endif

    r = buf_modname(
#ifdef SHORT_FNAME
	    TRUE,
#else
	    (buf->b_p_sn || buf->b_shortname),
#endif
#ifdef RISCOS
	    /* Avoid problems if fname has special chars, eg <Wimp$Scrap> */
	    ffname,
#else
	    fname_res,
#endif
	    (char_u *)
#if defined(VMS) || defined(RISCOS)
	    "_swp",
#else
	    ".swp",
#endif
#ifdef SHORT_FNAME		/* always 8.3 file name */
	    FALSE
#else
	    /* Prepend a '.' to the swap file name for the current directory. */
	    dir_name[0] == '.' && dir_name[1] == NUL
#endif
	       );
    if (r == NULL)	    /* out of memory */
	return NULL;

    s = get_file_in_dir(r, dir_name);
    vim_free(r);
    return s;
}

/*
 * Get file name to use for swap file or backup file.
 * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
 * option "dname".
 * - If "dname" is ".", return "fname" (swap file in dir of file).
 * - If "dname" starts with "./", insert "dname" in "fname" (swap file
 *   relative to dir of file).
 * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
 *   dir).
 *
 * The return value is an allocated string and can be NULL.
 */
    char_u *
get_file_in_dir(fname, dname)
    char_u  *fname;
    char_u  *dname;	/* don't use "dirname", it is a global for Alpha */
{
    char_u	*t;
    char_u	*tail;
    char_u	*retval;
    int		save_char;

    tail = gettail(fname);

    if (dname[0] == '.' && dname[1] == NUL)
	retval = vim_strsave(fname);
    else if (dname[0] == '.' && vim_ispathsep(dname[1]))
    {
	if (tail == fname)	    /* no path before file name */
	    retval = concat_fnames(dname + 2, tail, TRUE);
	else
	{
	    save_char = *tail;
	    *tail = NUL;
	    t = concat_fnames(fname, dname + 2, TRUE);
	    *tail = save_char;
	    if (t == NULL)	    /* out of memory */
		retval = NULL;
	    else
	    {
		retval = concat_fnames(t, tail, TRUE);
		vim_free(t);
	    }
	}
    }
    else
	retval = concat_fnames(dname, tail, TRUE);

    return retval;
}

static void attention_message __ARGS((buf_T *buf, char_u *fname));

/*
 * Print the ATTENTION message: info about an existing swap file.
 */
    static void
attention_message(buf, fname)
    buf_T   *buf;	/* buffer being edited */
    char_u  *fname;	/* swap file name */
{
    struct stat st;
    time_t	x, sx;
    char	*p;

    ++no_wait_return;
    (void)EMSG(_("E325: ATTENTION"));
    MSG_PUTS(_("\nFound a swap file by the name \""));
    msg_home_replace(fname);
    MSG_PUTS("\"\n");
    sx = swapfile_info(fname);
    MSG_PUTS(_("While opening file \""));
    msg_outtrans(buf->b_fname);
    MSG_PUTS("\"\n");
    if (mch_stat((char *)buf->b_fname, &st) != -1)
    {
	MSG_PUTS(_("             dated: "));
	x = st.st_mtime;    /* Manx C can't do &st.st_mtime */
	p = ctime(&x);			    /* includes '\n' */
	if (p == NULL)
	    MSG_PUTS("(invalid)\n");
	else
	    MSG_PUTS(p);
	if (sx != 0 && x > sx)
	    MSG_PUTS(_("      NEWER than swap file!\n"));
    }
    /* Some of these messages are long to allow translation to
     * other languages. */
    MSG_PUTS(_("\n(1) Another program may be editing the same file.\n    If this is the case, be careful not to end up with two\n    different instances of the same file when making changes.\n"));
    MSG_PUTS(_("    Quit, or continue with caution.\n"));
    MSG_PUTS(_("\n(2) An edit session for this file crashed.\n"));
    MSG_PUTS(_("    If this is the case, use \":recover\" or \"vim -r "));
    msg_outtrans(buf->b_fname);
    MSG_PUTS(_("\"\n    to recover the changes (see \":help recovery\").\n"));
    MSG_PUTS(_("    If you did this already, delete the swap file \""));
    msg_outtrans(fname);
    MSG_PUTS(_("\"\n    to avoid this message.\n"));
    cmdline_row = msg_row;
    --no_wait_return;
}

#ifdef FEAT_AUTOCMD
static int do_swapexists __ARGS((buf_T *buf, char_u *fname));

/*
 * Trigger the SwapExists autocommands.
 * Returns a value for equivalent to do_dialog() (see below):
 * 0: still need to ask for a choice
 * 1: open read-only
 * 2: edit anyway
 * 3: recover
 * 4: delete it
 * 5: quit
 * 6: abort
 */
    static int
do_swapexists(buf, fname)
    buf_T	*buf;
    char_u	*fname;
{
    set_vim_var_string(VV_SWAPNAME, fname, -1);
    set_vim_var_string(VV_SWAPCHOICE, NULL, -1);

    /* Trigger SwapExists autocommands with <afile> set to the file being
     * edited.  Disallow changing directory here. */
    ++allbuf_lock;
    apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL);
    --allbuf_lock;

    set_vim_var_string(VV_SWAPNAME, NULL, -1);

    switch (*get_vim_var_str(VV_SWAPCHOICE))
    {
	case 'o': return 1;
	case 'e': return 2;
	case 'r': return 3;
	case 'd': return 4;
	case 'q': return 5;
	case 'a': return 6;
    }

    return 0;
}
#endif

/*
 * Find out what name to use for the swap file for buffer 'buf'.
 *
 * Several names are tried to find one that does not exist
 * Returns the name in allocated memory or NULL.
 *
 * Note: If BASENAMELEN is not correct, you will get error messages for
 *	 not being able to open the swap or undo file
 * Note: May trigger SwapExists autocmd, pointers may change!
 */
    static char_u *
findswapname(buf, dirp, old_fname)
    buf_T	*buf;
    char_u	**dirp;		/* pointer to list of directories */
    char_u	*old_fname;	/* don't give warning for this file name */
{
    char_u	*fname;
    int		n;
    char_u	*dir_name;
#ifdef AMIGA
    BPTR	fh;
#endif
#ifndef SHORT_FNAME
    int		r;
#endif

#if !defined(SHORT_FNAME) \
		     && ((!defined(UNIX) && !defined(OS2)) || defined(ARCHIE))
# define CREATE_DUMMY_FILE
    FILE	*dummyfd = NULL;

    /*
     * If we start editing a new file, e.g. "test.doc", which resides on an
     * MSDOS compatible filesystem, it is possible that the file
     * "test.doc.swp" which we create will be exactly the same file. To avoid
     * this problem we temporarily create "test.doc".  Don't do this when the
     * check below for a 8.3 file name is used.
     */
    if (!(buf->b_p_sn || buf->b_shortname) && buf->b_fname != NULL
					     && mch_getperm(buf->b_fname) < 0)
	dummyfd = mch_fopen((char *)buf->b_fname, "w");
#endif

    /*
     * Isolate a directory name from *dirp and put it in dir_name.
     * First allocate some memory to put the directory name in.
     */
    dir_name = alloc((unsigned)STRLEN(*dirp) + 1);
    if (dir_name != NULL)
	(void)copy_option_part(dirp, dir_name, 31000, ",");

    /*
     * we try different names until we find one that does not exist yet
     */
    if (dir_name == NULL)	    /* out of memory */
	fname = NULL;
    else
	fname = makeswapname(buf->b_fname, buf->b_ffname, buf, dir_name);

    for (;;)
    {
	if (fname == NULL)	/* must be out of memory */
	    break;
	if ((n = (int)STRLEN(fname)) == 0)	/* safety check */
	{
	    vim_free(fname);
	    fname = NULL;
	    break;
	}
#if (defined(UNIX) || defined(OS2)) && !defined(ARCHIE) && !defined(SHORT_FNAME)
/*
 * Some systems have a MS-DOS compatible filesystem that use 8.3 character
 * file names. If this is the first try and the swap file name does not fit in
 * 8.3, detect if this is the case, set shortname and try again.
 */
	if (fname[n - 2] == 'w' && fname[n - 1] == 'p'
					&& !(buf->b_p_sn || buf->b_shortname))
	{
	    char_u	    *tail;
	    char_u	    *fname2;
	    struct stat	    s1, s2;
	    int		    f1, f2;
	    int		    created1 = FALSE, created2 = FALSE;
	    int		    same = FALSE;

	    /*
	     * Check if swapfile name does not fit in 8.3:
	     * It either contains two dots, is longer than 8 chars, or starts
	     * with a dot.
	     */
	    tail = gettail(buf->b_fname);
	    if (       vim_strchr(tail, '.') != NULL
		    || STRLEN(tail) > (size_t)8
		    || *gettail(fname) == '.')
	    {
		fname2 = alloc(n + 2);
		if (fname2 != NULL)
		{
		    STRCPY(fname2, fname);
		    /* if fname == "xx.xx.swp",	    fname2 = "xx.xx.swx"
		     * if fname == ".xx.swp",	    fname2 = ".xx.swpx"
		     * if fname == "123456789.swp", fname2 = "12345678x.swp"
		     */
		    if (vim_strchr(tail, '.') != NULL)
			fname2[n - 1] = 'x';
		    else if (*gettail(fname) == '.')
		    {
			fname2[n] = 'x';
			fname2[n + 1] = NUL;
		    }
		    else
			fname2[n - 5] += 1;
		    /*
		     * may need to create the files to be able to use mch_stat()
		     */
		    f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
		    if (f1 < 0)
		    {
			f1 = mch_open_rw((char *)fname,
					       O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
#if defined(OS2)
			if (f1 < 0 && errno == ENOENT)
			    same = TRUE;
#endif
			created1 = TRUE;
		    }
		    if (f1 >= 0)
		    {
			f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0);
			if (f2 < 0)
			{
			    f2 = mch_open_rw((char *)fname2,
					       O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
			    created2 = TRUE;
			}
			if (f2 >= 0)
			{
			    /*
			     * Both files exist now. If mch_stat() returns the
			     * same device and inode they are the same file.
			     */
			    if (mch_fstat(f1, &s1) != -1
				    && mch_fstat(f2, &s2) != -1
				    && s1.st_dev == s2.st_dev
				    && s1.st_ino == s2.st_ino)
				same = TRUE;
			    close(f2);
			    if (created2)
				mch_remove(fname2);
			}
			close(f1);
			if (created1)
			    mch_remove(fname);
		    }
		    vim_free(fname2);
		    if (same)
		    {
			buf->b_shortname = TRUE;
			vim_free(fname);
			fname = makeswapname(buf->b_fname, buf->b_ffname,
							       buf, dir_name);
			continue;	/* try again with b_shortname set */
		    }
		}
	    }
	}
#endif
	/*
	 * check if the swapfile already exists
	 */
	if (mch_getperm(fname) < 0)	/* it does not exist */
	{
#ifdef HAVE_LSTAT
	    struct stat sb;

	    /*
	     * Extra security check: When a swap file is a symbolic link, this
	     * is most likely a symlink attack.
	     */
	    if (mch_lstat((char *)fname, &sb) < 0)
#else
# ifdef AMIGA
	    fh = Open((UBYTE *)fname, (long)MODE_NEWFILE);
	    /*
	     * on the Amiga mch_getperm() will return -1 when the file exists
	     * but is being used by another program. This happens if you edit
	     * a file twice.
	     */
	    if (fh != (BPTR)NULL)	/* can open file, OK */
	    {
		Close(fh);
		mch_remove(fname);
		break;
	    }
	    if (IoErr() != ERROR_OBJECT_IN_USE
					    && IoErr() != ERROR_OBJECT_EXISTS)
# endif
#endif
		break;
	}

	/*
	 * A file name equal to old_fname is OK to use.
	 */
	if (old_fname != NULL && fnamecmp(fname, old_fname) == 0)
	    break;

	/*
	 * get here when file already exists
	 */
	if (fname[n - 2] == 'w' && fname[n - 1] == 'p')	/* first try */
	{
#ifndef SHORT_FNAME
	    /*
	     * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp
	     * and file.doc are the same file. To guess if this problem is
	     * present try if file.doc.swx exists. If it does, we set
	     * buf->b_shortname and try file_doc.swp (dots replaced by
	     * underscores for this file), and try again. If it doesn't we
	     * assume that "file.doc.swp" already exists.
	     */
	    if (!(buf->b_p_sn || buf->b_shortname))	/* not tried yet */
	    {
		fname[n - 1] = 'x';
		r = mch_getperm(fname);		/* try "file.swx" */
		fname[n - 1] = 'p';
		if (r >= 0)		    /* "file.swx" seems to exist */
		{
		    buf->b_shortname = TRUE;
		    vim_free(fname);
		    fname = makeswapname(buf->b_fname, buf->b_ffname,
							       buf, dir_name);
		    continue;	    /* try again with '.' replaced with '_' */
		}
	    }
#endif
	    /*
	     * If we get here the ".swp" file really exists.
	     * Give an error message, unless recovering, no file name, we are
	     * viewing a help file or when the path of the file is different
	     * (happens when all .swp files are in one directory).
	     */
	    if (!recoverymode && buf->b_fname != NULL
				&& !buf->b_help && !(buf->b_flags & BF_DUMMY))
	    {
		int		fd;
		struct block0	b0;
		int		differ = FALSE;

		/*
		 * Try to read block 0 from the swap file to get the original
		 * file name (and inode number).
		 */
		fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
		if (fd >= 0)
		{
		    if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
		    {
			/*
			 * If the swapfile has the same directory as the
			 * buffer don't compare the directory names, they can
			 * have a different mountpoint.
			 */
			if (b0.b0_flags & B0_SAME_DIR)
			{
			    if (fnamecmp(gettail(buf->b_ffname),
						   gettail(b0.b0_fname)) != 0
				    || !same_directory(fname, buf->b_ffname))
			    {
#ifdef CHECK_INODE
				/* Symlinks may point to the same file even
				 * when the name differs, need to check the
				 * inode too. */
				expand_env(b0.b0_fname, NameBuff, MAXPATHL);
				if (fnamecmp_ino(buf->b_ffname, NameBuff,
						     char_to_long(b0.b0_ino)))
#endif
				    differ = TRUE;
			    }
			}
			else
			{
			    /*
			     * The name in the swap file may be
			     * "~user/path/file".  Expand it first.
			     */
			    expand_env(b0.b0_fname, NameBuff, MAXPATHL);
#ifdef CHECK_INODE
			    if (fnamecmp_ino(buf->b_ffname, NameBuff,
						     char_to_long(b0.b0_ino)))
				differ = TRUE;
#else
			    if (fnamecmp(NameBuff, buf->b_ffname) != 0)
				differ = TRUE;
#endif
			}
		    }
		    close(fd);
		}
#ifdef RISCOS
		else
		    /* Can't open swap file, though it does exist.
		     * Assume that the user is editing two files with
		     * the same name in different directories. No error.
		     */
		    differ = TRUE;
#endif

		/* give the ATTENTION message when there is an old swap file
		 * for the current file, and the buffer was not recovered. */
		if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED)
			&& vim_strchr(p_shm, SHM_ATTENTION) == NULL)
		{
#if defined(HAS_SWAP_EXISTS_ACTION)
		    int		choice = 0;
#endif
#ifdef CREATE_DUMMY_FILE
		    int		did_use_dummy = FALSE;

		    /* Avoid getting a warning for the file being created
		     * outside of Vim, it was created at the start of this
		     * function.  Delete the file now, because Vim might exit
		     * here if the window is closed. */
		    if (dummyfd != NULL)
		    {
			fclose(dummyfd);
			dummyfd = NULL;
			mch_remove(buf->b_fname);
			did_use_dummy = TRUE;
		    }
#endif

#if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
		    process_still_running = FALSE;
#endif
#ifdef FEAT_AUTOCMD
		    /*
		     * If there is an SwapExists autocommand and we can handle
		     * the response, trigger it.  It may return 0 to ask the
		     * user anyway.
		     */
		    if (swap_exists_action != SEA_NONE
			    && has_autocmd(EVENT_SWAPEXISTS, buf->b_fname, buf))
			choice = do_swapexists(buf, fname);

		    if (choice == 0)
#endif
		    {
#ifdef FEAT_GUI
			/* If we are supposed to start the GUI but it wasn't
			 * completely started yet, start it now.  This makes
			 * the messages displayed in the Vim window when
			 * loading a session from the .gvimrc file. */
			if (gui.starting && !gui.in_use)
			    gui_start();
#endif
			/* Show info about the existing swap file. */
			attention_message(buf, fname);

			/* We don't want a 'q' typed at the more-prompt
			 * interrupt loading a file. */
			got_int = FALSE;
		    }

#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
		    if (swap_exists_action != SEA_NONE && choice == 0)
		    {
			char_u	*name;

			name = alloc((unsigned)(STRLEN(fname)
				+ STRLEN(_("Swap file \""))
				+ STRLEN(_("\" already exists!")) + 5));
			if (name != NULL)
			{
			    STRCPY(name, _("Swap file \""));
			    home_replace(NULL, fname, name + STRLEN(name),
								  1000, TRUE);
			    STRCAT(name, _("\" already exists!"));
			}
			choice = do_dialog(VIM_WARNING,
				    (char_u *)_("VIM - ATTENTION"),
				    name == NULL
					?  (char_u *)_("Swap file already exists!")
					: name,
# if defined(UNIX) || defined(__EMX__) || defined(VMS)
				    process_still_running
					? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") :
# endif
					(char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"), 1, NULL);

# if defined(UNIX) || defined(__EMX__) || defined(VMS)
			if (process_still_running && choice >= 4)
			    choice++;	/* Skip missing "Delete it" button */
# endif
			vim_free(name);

			/* pretend screen didn't scroll, need redraw anyway */
			msg_scrolled = 0;
			redraw_all_later(NOT_VALID);
		    }
#endif

#if defined(HAS_SWAP_EXISTS_ACTION)
		    if (choice > 0)
		    {
			switch (choice)
			{
			    case 1:
				buf->b_p_ro = TRUE;
				break;
			    case 2:
				break;
			    case 3:
				swap_exists_action = SEA_RECOVER;
				break;
			    case 4:
				mch_remove(fname);
				break;
			    case 5:
				swap_exists_action = SEA_QUIT;
				break;
			    case 6:
				swap_exists_action = SEA_QUIT;
				got_int = TRUE;
				break;
			}

			/* If the file was deleted this fname can be used. */
			if (mch_getperm(fname) < 0)
			    break;
		    }
		    else
#endif
		    {
			MSG_PUTS("\n");
			if (msg_silent == 0)
			    /* call wait_return() later */
			    need_wait_return = TRUE;
		    }

#ifdef CREATE_DUMMY_FILE
		    /* Going to try another name, need the dummy file again. */
		    if (did_use_dummy)
			dummyfd = mch_fopen((char *)buf->b_fname, "w");
#endif
		}
	    }
	}

	/*
	 * Change the ".swp" extension to find another file that can be used.
	 * First decrement the last char: ".swo", ".swn", etc.
	 * If that still isn't enough decrement the last but one char: ".svz"
	 * Can happen when editing many "No Name" buffers.
	 */
	if (fname[n - 1] == 'a')	/* ".s?a" */
	{
	    if (fname[n - 2] == 'a')    /* ".saa": tried enough, give up */
	    {
		EMSG(_("E326: Too many swap files found"));
		vim_free(fname);
		fname = NULL;
		break;
	    }
	    --fname[n - 2];		/* ".svz", ".suz", etc. */
	    fname[n - 1] = 'z' + 1;
	}
	--fname[n - 1];			/* ".swo", ".swn", etc. */
    }

    vim_free(dir_name);
#ifdef CREATE_DUMMY_FILE
    if (dummyfd != NULL)	/* file has been created temporarily */
    {
	fclose(dummyfd);
	mch_remove(buf->b_fname);
    }
#endif
    return fname;
}

    static int
b0_magic_wrong(b0p)
    ZERO_BL *b0p;
{
    return (b0p->b0_magic_long != (long)B0_MAGIC_LONG
	    || b0p->b0_magic_int != (int)B0_MAGIC_INT
	    || b0p->b0_magic_short != (short)B0_MAGIC_SHORT
	    || b0p->b0_magic_char != B0_MAGIC_CHAR);
}

#ifdef CHECK_INODE
/*
 * Compare current file name with file name from swap file.
 * Try to use inode numbers when possible.
 * Return non-zero when files are different.
 *
 * When comparing file names a few things have to be taken into consideration:
 * - When working over a network the full path of a file depends on the host.
 *   We check the inode number if possible.  It is not 100% reliable though,
 *   because the device number cannot be used over a network.
 * - When a file does not exist yet (editing a new file) there is no inode
 *   number.
 * - The file name in a swap file may not be valid on the current host.  The
 *   "~user" form is used whenever possible to avoid this.
 *
 * This is getting complicated, let's make a table:
 *
 *		ino_c  ino_s  fname_c  fname_s	differ =
 *
 * both files exist -> compare inode numbers:
 *		!= 0   != 0	X	 X	ino_c != ino_s
 *
 * inode number(s) unknown, file names available -> compare file names
 *		== 0	X	OK	 OK	fname_c != fname_s
 *		 X     == 0	OK	 OK	fname_c != fname_s
 *
 * current file doesn't exist, file for swap file exist, file name(s) not
 * available -> probably different
 *		== 0   != 0    FAIL	 X	TRUE
 *		== 0   != 0	X	FAIL	TRUE
 *
 * current file exists, inode for swap unknown, file name(s) not
 * available -> probably different
 *		!= 0   == 0    FAIL	 X	TRUE
 *		!= 0   == 0	X	FAIL	TRUE
 *
 * current file doesn't exist, inode for swap unknown, one file name not
 * available -> probably different
 *		== 0   == 0    FAIL	 OK	TRUE
 *		== 0   == 0	OK	FAIL	TRUE
 *
 * current file doesn't exist, inode for swap unknown, both file names not
 * available -> probably same file
 *		== 0   == 0    FAIL	FAIL	FALSE
 *
 * Note that when the ino_t is 64 bits, only the last 32 will be used.  This
 * can't be changed without making the block 0 incompatible with 32 bit
 * versions.
 */

    static int
fnamecmp_ino(fname_c, fname_s, ino_block0)
    char_u	*fname_c;	    /* current file name */
    char_u	*fname_s;	    /* file name from swap file */
    long	ino_block0;
{
    struct stat	st;
    ino_t	ino_c = 0;	    /* ino of current file */
    ino_t	ino_s;		    /* ino of file from swap file */
    char_u	buf_c[MAXPATHL];    /* full path of fname_c */
    char_u	buf_s[MAXPATHL];    /* full path of fname_s */
    int		retval_c;	    /* flag: buf_c valid */
    int		retval_s;	    /* flag: buf_s valid */

    if (mch_stat((char *)fname_c, &st) == 0)
	ino_c = (ino_t)st.st_ino;

    /*
     * First we try to get the inode from the file name, because the inode in
     * the swap file may be outdated.  If that fails (e.g. this path is not
     * valid on this machine), use the inode from block 0.
     */
    if (mch_stat((char *)fname_s, &st) == 0)
	ino_s = (ino_t)st.st_ino;
    else
	ino_s = (ino_t)ino_block0;

    if (ino_c && ino_s)
	return (ino_c != ino_s);

    /*
     * One of the inode numbers is unknown, try a forced vim_FullName() and
     * compare the file names.
     */
    retval_c = vim_FullName(fname_c, buf_c, MAXPATHL, TRUE);
    retval_s = vim_FullName(fname_s, buf_s, MAXPATHL, TRUE);
    if (retval_c == OK && retval_s == OK)
	return (STRCMP(buf_c, buf_s) != 0);

    /*
     * Can't compare inodes or file names, guess that the files are different,
     * unless both appear not to exist at all.
     */
    if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL)
	return FALSE;
    return TRUE;
}
#endif /* CHECK_INODE */

/*
 * Move a long integer into a four byte character array.
 * Used for machine independency in block zero.
 */
    static void
long_to_char(n, s)
    long    n;
    char_u  *s;
{
    s[0] = (char_u)(n & 0xff);
    n = (unsigned)n >> 8;
    s[1] = (char_u)(n & 0xff);
    n = (unsigned)n >> 8;
    s[2] = (char_u)(n & 0xff);
    n = (unsigned)n >> 8;
    s[3] = (char_u)(n & 0xff);
}

    static long
char_to_long(s)
    char_u  *s;
{
    long    retval;

    retval = s[3];
    retval <<= 8;
    retval |= s[2];
    retval <<= 8;
    retval |= s[1];
    retval <<= 8;
    retval |= s[0];

    return retval;
}

/*
 * Set the flags in the first block of the swap file:
 * - file is modified or not: buf->b_changed
 * - 'fileformat'
 * - 'fileencoding'
 */
    void
ml_setflags(buf)
    buf_T	*buf;
{
    bhdr_T	*hp;
    ZERO_BL	*b0p;

    if (!buf->b_ml.ml_mfp)
	return;
    for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
    {
	if (hp->bh_bnum == 0)
	{
	    b0p = (ZERO_BL *)(hp->bh_data);
	    b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
	    b0p->b0_flags = (b0p->b0_flags & ~B0_FF_MASK)
						  | (get_fileformat(buf) + 1);
#ifdef FEAT_MBYTE
	    add_b0_fenc(b0p, buf);
#endif
	    hp->bh_flags |= BH_DIRTY;
	    mf_sync(buf->b_ml.ml_mfp, MFS_ZERO);
	    break;
	}
    }
}

#if defined(FEAT_CRYPT) || defined(PROTO)
/*
 * If "data" points to a data block encrypt the text in it and return a copy
 * in allocated memory.  Return NULL when out of memory.
 * Otherwise return "data".
 */
    char_u *
ml_encrypt_data(mfp, data, offset, size)
    memfile_T	*mfp;
    char_u	*data;
    off_t	offset;
    unsigned	size;
{
    DATA_BL	*dp = (DATA_BL *)data;
    char_u	*head_end;
    char_u	*text_start;
    char_u	*new_data;
    int		text_len;

    if (dp->db_id != DATA_ID)
	return data;

    new_data = (char_u *)alloc(size);
    if (new_data == NULL)
	return NULL;
    head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
    text_start = (char_u *)dp + dp->db_txt_start;
    text_len = size - dp->db_txt_start;

    /* Copy the header and the text. */
    mch_memmove(new_data, dp, head_end - (char_u *)dp);

    /* Encrypt the text. */
    crypt_push_state();
    ml_crypt_prepare(mfp, offset, FALSE);
    crypt_encode(text_start, text_len, new_data + dp->db_txt_start);
    crypt_pop_state();

    /* Clear the gap. */
    if (head_end < text_start)
	vim_memset(new_data + (head_end - data), 0, text_start - head_end);

    return new_data;
}

/*
 * Decrypt the text in "data" if it points to a data block.
 */
    void
ml_decrypt_data(mfp, data, offset, size)
    memfile_T	*mfp;
    char_u	*data;
    off_t	offset;
    unsigned	size;
{
    DATA_BL	*dp = (DATA_BL *)data;
    char_u	*head_end;
    char_u	*text_start;
    int		text_len;

    if (dp->db_id == DATA_ID)
    {
	head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
	text_start = (char_u *)dp + dp->db_txt_start;
	text_len = dp->db_txt_end - dp->db_txt_start;

	if (head_end > text_start || dp->db_txt_start > size
						     || dp->db_txt_end > size)
	    return;  /* data was messed up */

	/* Decrypt the text in place. */
	crypt_push_state();
	ml_crypt_prepare(mfp, offset, TRUE);
	crypt_decode(text_start, text_len);
	crypt_pop_state();
    }
}

/*
 * Prepare for encryption/decryption, using the key, seed and offset.
 */
    static void
ml_crypt_prepare(mfp, offset, reading)
    memfile_T	*mfp;
    off_t	offset;
    int		reading;
{
    buf_T	*buf = mfp->mf_buffer;
    char_u	salt[50];
    int		method;
    char_u	*key;
    char_u	*seed;

    if (reading && mfp->mf_old_key != NULL)
    {
	/* Reading back blocks with the previous key/method/seed. */
	method = mfp->mf_old_cm;
	key = mfp->mf_old_key;
	seed = mfp->mf_old_seed;
    }
    else
    {
	method = get_crypt_method(buf);
	key = buf->b_p_key;
	seed = mfp->mf_seed;
    }

    use_crypt_method = method;  /* select pkzip or blowfish */
    if (method == 0)
    {
	vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset);
	crypt_init_keys(salt);
    }
    else
    {
	/* Using blowfish, add salt and seed. We use the byte offset of the
	 * block for the salt. */
	vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
	bf_key_init(key, salt, (int)STRLEN(salt));
	bf_ofb_init(seed, MF_SEED_LEN);
    }
}

#endif


#if defined(FEAT_BYTEOFF) || defined(PROTO)

#define MLCS_MAXL 800	/* max no of lines in chunk */
#define MLCS_MINL 400   /* should be half of MLCS_MAXL */

/*
 * Keep information for finding byte offset of a line, updtype may be one of:
 * ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it
 *	   Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
 * ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
 * ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
 */
    static void
ml_updatechunk(buf, line, len, updtype)
    buf_T	*buf;
    linenr_T	line;
    long	len;
    int		updtype;
{
    static buf_T	*ml_upd_lastbuf = NULL;
    static linenr_T	ml_upd_lastline;
    static linenr_T	ml_upd_lastcurline;
    static int		ml_upd_lastcurix;

    linenr_T		curline = ml_upd_lastcurline;
    int			curix = ml_upd_lastcurix;
    long		size;
    chunksize_T		*curchnk;
    int			rest;
    bhdr_T		*hp;
    DATA_BL		*dp;

    if (buf->b_ml.ml_usedchunks == -1 || len == 0)
	return;
    if (buf->b_ml.ml_chunksize == NULL)
    {
	buf->b_ml.ml_chunksize = (chunksize_T *)
				  alloc((unsigned)sizeof(chunksize_T) * 100);
	if (buf->b_ml.ml_chunksize == NULL)
	{
	    buf->b_ml.ml_usedchunks = -1;
	    return;
	}
	buf->b_ml.ml_numchunks = 100;
	buf->b_ml.ml_usedchunks = 1;
	buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
	buf->b_ml.ml_chunksize[0].mlcs_totalsize = 1;
    }

    if (updtype == ML_CHNK_UPDLINE && buf->b_ml.ml_line_count == 1)
    {
	/*
	 * First line in empty buffer from ml_flush_line() -- reset
	 */
	buf->b_ml.ml_usedchunks = 1;
	buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
	buf->b_ml.ml_chunksize[0].mlcs_totalsize =
				  (long)STRLEN(buf->b_ml.ml_line_ptr) + 1;
	return;
    }

    /*
     * Find chunk that our line belongs to, curline will be at start of the
     * chunk.
     */
    if (buf != ml_upd_lastbuf || line != ml_upd_lastline + 1
	    || updtype != ML_CHNK_ADDLINE)
    {
	for (curline = 1, curix = 0;
	     curix < buf->b_ml.ml_usedchunks - 1
	     && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	     curix++)
	{
	    curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	}
    }
    else if (line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines
		 && curix < buf->b_ml.ml_usedchunks - 1)
    {
	/* Adjust cached curix & curline */
	curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	curix++;
    }
    curchnk = buf->b_ml.ml_chunksize + curix;

    if (updtype == ML_CHNK_DELLINE)
	len = -len;
    curchnk->mlcs_totalsize += len;
    if (updtype == ML_CHNK_ADDLINE)
    {
	curchnk->mlcs_numlines++;

	/* May resize here so we don't have to do it in both cases below */
	if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks)
	{
	    buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
	    buf->b_ml.ml_chunksize = (chunksize_T *)
		vim_realloc(buf->b_ml.ml_chunksize,
			    sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
	    if (buf->b_ml.ml_chunksize == NULL)
	    {
		/* Hmmmm, Give up on offset for this buffer */
		buf->b_ml.ml_usedchunks = -1;
		return;
	    }
	}

	if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL)
	{
	    int	    count;	    /* number of entries in block */
	    int	    idx;
	    int	    text_end;
	    int	    linecnt;

	    mch_memmove(buf->b_ml.ml_chunksize + curix + 1,
			buf->b_ml.ml_chunksize + curix,
			(buf->b_ml.ml_usedchunks - curix) *
			sizeof(chunksize_T));
	    /* Compute length of first half of lines in the split chunk */
	    size = 0;
	    linecnt = 0;
	    while (curline < buf->b_ml.ml_line_count
			&& linecnt < MLCS_MINL)
	    {
		if ((hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
		{
		    buf->b_ml.ml_usedchunks = -1;
		    return;
		}
		dp = (DATA_BL *)(hp->bh_data);
		count = (long)(buf->b_ml.ml_locked_high) -
			(long)(buf->b_ml.ml_locked_low) + 1;
		idx = curline - buf->b_ml.ml_locked_low;
		curline = buf->b_ml.ml_locked_high + 1;
		if (idx == 0)/* first line in block, text at the end */
		    text_end = dp->db_txt_end;
		else
		    text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
		/* Compute index of last line to use in this MEMLINE */
		rest = count - idx;
		if (linecnt + rest > MLCS_MINL)
		{
		    idx += MLCS_MINL - linecnt - 1;
		    linecnt = MLCS_MINL;
		}
		else
		{
		    idx = count - 1;
		    linecnt += rest;
		}
		size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
	    }
	    buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
	    buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
	    buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
	    buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
	    buf->b_ml.ml_usedchunks++;
	    ml_upd_lastbuf = NULL;   /* Force recalc of curix & curline */
	    return;
	}
	else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL
		     && curix == buf->b_ml.ml_usedchunks - 1
		     && buf->b_ml.ml_line_count - line <= 1)
	{
	    /*
	     * We are in the last chunk and it is cheap to crate a new one
	     * after this. Do it now to avoid the loop above later on
	     */
	    curchnk = buf->b_ml.ml_chunksize + curix + 1;
	    buf->b_ml.ml_usedchunks++;
	    if (line == buf->b_ml.ml_line_count)
	    {
		curchnk->mlcs_numlines = 0;
		curchnk->mlcs_totalsize = 0;
	    }
	    else
	    {
		/*
		 * Line is just prior to last, move count for last
		 * This is the common case  when loading a new file
		 */
		hp = ml_find_line(buf, buf->b_ml.ml_line_count, ML_FIND);
		if (hp == NULL)
		{
		    buf->b_ml.ml_usedchunks = -1;
		    return;
		}
		dp = (DATA_BL *)(hp->bh_data);
		if (dp->db_line_count == 1)
		    rest = dp->db_txt_end - dp->db_txt_start;
		else
		    rest =
			((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
			- dp->db_txt_start;
		curchnk->mlcs_totalsize = rest;
		curchnk->mlcs_numlines = 1;
		curchnk[-1].mlcs_totalsize -= rest;
		curchnk[-1].mlcs_numlines -= 1;
	    }
	}
    }
    else if (updtype == ML_CHNK_DELLINE)
    {
	curchnk->mlcs_numlines--;
	ml_upd_lastbuf = NULL;   /* Force recalc of curix & curline */
	if (curix < (buf->b_ml.ml_usedchunks - 1)
		&& (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines)
		   <= MLCS_MINL)
	{
	    curix++;
	    curchnk = buf->b_ml.ml_chunksize + curix;
	}
	else if (curix == 0 && curchnk->mlcs_numlines <= 0)
	{
	    buf->b_ml.ml_usedchunks--;
	    mch_memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
			buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
	    return;
	}
	else if (curix == 0 || (curchnk->mlcs_numlines > 10
		    && (curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines)
		       > MLCS_MINL))
	{
	    return;
	}

	/* Collapse chunks */
	curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines;
	curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
	buf->b_ml.ml_usedchunks--;
	if (curix < buf->b_ml.ml_usedchunks)
	{
	    mch_memmove(buf->b_ml.ml_chunksize + curix,
			buf->b_ml.ml_chunksize + curix + 1,
			(buf->b_ml.ml_usedchunks - curix) *
			sizeof(chunksize_T));
	}
	return;
    }
    ml_upd_lastbuf = buf;
    ml_upd_lastline = line;
    ml_upd_lastcurline = curline;
    ml_upd_lastcurix = curix;
}

/*
 * Find offset for line or line with offset.
 * Find line with offset if "lnum" is 0; return remaining offset in offp
 * Find offset of line if "lnum" > 0
 * return -1 if information is not available
 */
    long
ml_find_line_or_offset(buf, lnum, offp)
    buf_T	*buf;
    linenr_T	lnum;
    long	*offp;
{
    linenr_T	curline;
    int		curix;
    long	size;
    bhdr_T	*hp;
    DATA_BL	*dp;
    int		count;		/* number of entries in block */
    int		idx;
    int		start_idx;
    int		text_end;
    long	offset;
    int		len;
    int		ffdos = (get_fileformat(buf) == EOL_DOS);
    int		extra = 0;

    /* take care of cached line first */
    ml_flush_line(curbuf);

    if (buf->b_ml.ml_usedchunks == -1
	    || buf->b_ml.ml_chunksize == NULL
	    || lnum < 0)
	return -1;

    if (offp == NULL)
	offset = 0;
    else
	offset = *offp;
    if (lnum == 0 && offset <= 0)
	return 1;   /* Not a "find offset" and offset 0 _must_ be in line 1 */
    /*
     * Find the last chunk before the one containing our line. Last chunk is
     * special because it will never qualify
     */
    curline = 1;
    curix = size = 0;
    while (curix < buf->b_ml.ml_usedchunks - 1
	    && ((lnum != 0
	     && lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
		|| (offset != 0
	       && offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize
		      + ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines)))
    {
	curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize;
	if (offset && ffdos)
	    size += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	curix++;
    }

    while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset))
    {
	if (curline > buf->b_ml.ml_line_count
		|| (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
	    return -1;
	dp = (DATA_BL *)(hp->bh_data);
	count = (long)(buf->b_ml.ml_locked_high) -
		(long)(buf->b_ml.ml_locked_low) + 1;
	start_idx = idx = curline - buf->b_ml.ml_locked_low;
	if (idx == 0)/* first line in block, text at the end */
	    text_end = dp->db_txt_end;
	else
	    text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
	/* Compute index of last line to use in this MEMLINE */
	if (lnum != 0)
	{
	    if (curline + (count - idx) >= lnum)
		idx += lnum - curline - 1;
	    else
		idx = count - 1;
	}
	else
	{
	    extra = 0;
	    while (offset >= size
		       + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
								      + ffdos)
	    {
		if (ffdos)
		    size++;
		if (idx == count - 1)
		{
		    extra = 1;
		    break;
		}
		idx++;
	    }
	}
	len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
	size += len;
	if (offset != 0 && size >= offset)
	{
	    if (size + ffdos == offset)
		*offp = 0;
	    else if (idx == start_idx)
		*offp = offset - size + len;
	    else
		*offp = offset - size + len
		     - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
	    curline += idx - start_idx + extra;
	    if (curline > buf->b_ml.ml_line_count)
		return -1;	/* exactly one byte beyond the end */
	    return curline;
	}
	curline = buf->b_ml.ml_locked_high + 1;
    }

    if (lnum != 0)
    {
	/* Count extra CR characters. */
	if (ffdos)
	    size += lnum - 1;

	/* Don't count the last line break if 'bin' and 'noeol'. */
	if (buf->b_p_bin && !buf->b_p_eol)
	    size -= ffdos + 1;
    }

    return size;
}

/*
 * Goto byte in buffer with offset 'cnt'.
 */
    void
goto_byte(cnt)
    long	cnt;
{
    long	boff = cnt;
    linenr_T	lnum;

    ml_flush_line(curbuf);	/* cached line may be dirty */
    setpcmark();
    if (boff)
	--boff;
    lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff);
    if (lnum < 1)	/* past the end */
    {
	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
	curwin->w_curswant = MAXCOL;
	coladvance((colnr_T)MAXCOL);
    }
    else
    {
	curwin->w_cursor.lnum = lnum;
	curwin->w_cursor.col = (colnr_T)boff;
# ifdef FEAT_VIRTUALEDIT
	curwin->w_cursor.coladd = 0;
# endif
	curwin->w_set_curswant = TRUE;
    }
    check_cursor();

# ifdef FEAT_MBYTE
    /* Make sure the cursor is on the first byte of a multi-byte char. */
    if (has_mbyte)
	mb_adjust_cursor();
# endif
}
#endif
