1
0
forked from aniani/vim

updated for version 7.0023

This commit is contained in:
Bram Moolenaar
2004-12-19 22:46:22 +00:00
parent 46c9c73de8
commit 1cd871b534
76 changed files with 2397 additions and 1391 deletions

View File

@@ -125,9 +125,10 @@ struct data_block
#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 900
#define B0_UNAME_SIZE 40
#define B0_HNAME_SIZE 40
#define B0_FNAME_SIZE_ORG 900 /* what it was in older versions */
#define B0_FNAME_SIZE 898
#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
@@ -160,13 +161,39 @@ struct block0
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]; /* name of file being edited */
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 */
};
#define b0_dirty b0_fname[B0_FNAME_SIZE-1]
/*
* Note: b0_fname 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]
/* 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 */
@@ -187,7 +214,12 @@ static linenr_T lowest_marked = 0;
#define ML_FLUSH 0x02 /* flush locked block */
#define ML_SIMPLE(x) (x & 0x10) /* DEL, INS or FIND */
static void ml_upd_block0 __ARGS((buf_T *buf, int setfname));
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));
@@ -282,7 +314,8 @@ ml_open()
b0p->b0_id[0] = BLOCK0_ID0;
b0p->b0_id[1] = BLOCK0_ID1;
b0p->b0_dirty = curbuf->b_changed ? 0x55 : 0;
b0p->b0_dirty = curbuf->b_changed ? B0_DIRTY : 0;
b0p->b0_flags = get_fileformat(curbuf) + 1;
b0p->b0_magic_long = (long)B0_MAGIC_LONG;
b0p->b0_magic_int = (int)B0_MAGIC_INT;
b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
@@ -433,6 +466,7 @@ ml_setname(buf)
#else
mf_set_ffname(mfp);
#endif
ml_upd_block0(buf, FALSE);
break;
}
vim_free(fname); /* this fname didn't work, try another */
@@ -507,6 +541,8 @@ ml_open_file(buf)
*/
mf_fullname(mfp);
#endif
ml_upd_block0(buf, FALSE);
/* Flush block zero, so others can read it */
if (mf_sync(mfp, MFS_ZERO) == OK)
break;
@@ -607,20 +643,35 @@ ml_close_notmod()
void
ml_timestamp(buf)
buf_T *buf;
{
ml_upd_block0(buf, TRUE);
}
/*
* Update the timestamp or the B0_SAME_DIR flag of the .swp file.
*/
static void
ml_upd_block0(buf, setfname)
buf_T *buf;
int setfname;
{
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 (b0p->b0_id[0] != BLOCK0_ID0 || b0p->b0_id[1] != BLOCK0_ID1)
EMSG(_("E304: ml_timestamp: Didn't get block 0??"));
EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
else
set_b0_fname(b0p, buf);
{
if (setfname)
set_b0_fname(b0p, buf);
else
set_b0_dir_flag(b0p, buf);
}
mf_put(mfp, hp, TRUE, FALSE);
}
@@ -641,9 +692,14 @@ set_b0_fname(b0p, buf)
else
{
#if defined(MSDOS) || defined(MSWIN) || defined(AMIGA) || defined(RISCOS)
/* systems that cannot translate "~user" back into a path: copy the
* file name unmodified */
/* Systems that cannot translate "~user" back into a path: copy the
* file name unmodified. Do use slashes instead of backslashes for
* portability. */
STRNCPY(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE);
b0p->b0_fname[B0_FNAME_SIZE - 1] = NUL;
# ifdef BACKSLASH_IN_FILENAME
forward_slash(b0p->b0_fname);
# endif
#else
size_t flen, ulen;
char_u uname[B0_UNAME_SIZE];
@@ -662,7 +718,10 @@ set_b0_fname(b0p, buf)
/* 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 - 1)
{
STRNCPY(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE);
b0p->b0_fname[B0_FNAME_SIZE - 1] = NUL;
}
else
{
mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
@@ -691,8 +750,55 @@ set_b0_fname(b0p, buf)
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;
n = STRLEN(buf->b_p_fenc);
if (STRLEN(b0p->b0_fname) + n + 1 > B0_FNAME_SIZE)
b0p->b0_flags &= ~B0_HAS_FENC;
else
{
mch_memmove((char *)b0p->b0_fname + B0_FNAME_SIZE - n,
(char *)buf->b_p_fenc, (size_t)n);
*(b0p->b0_fname + B0_FNAME_SIZE - n - 1) = NUL;
b0p->b0_flags |= B0_HAS_FENC;
}
}
#endif
/*
* try to recover curbuf from the .swp file
*/
@@ -704,6 +810,8 @@ ml_recover()
char_u *fname;
bhdr_T *hp = NULL;
ZERO_BL *b0p;
int b0_ff;
char_u *b0_fenc = NULL;
PTR_BL *pp;
DATA_BL *dp;
infoptr_T *ip;
@@ -926,6 +1034,17 @@ ml_recover()
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)
{
for (p = b0p->b0_fname + B0_FNAME_SIZE;
p > b0p->b0_fname && p[-1] != NUL; --p)
;
b0_fenc = vim_strnsave(p, b0p->b0_fname + B0_FNAME_SIZE - p);
}
mf_put(mfp, hp, FALSE, FALSE); /* release block 0 */
hp = NULL;
@@ -948,6 +1067,16 @@ ml_recover()
ml_delete((linenr_T)1, FALSE);
}
/* 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 */
@@ -1295,7 +1424,7 @@ recover_names(fname, list, nr)
{
#if defined(UNIX) || defined(WIN3264)
p = dir_name + STRLEN(dir_name);
if (vim_ispathsep(p[-1]) && p[-1] == p[-2])
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);
@@ -1441,7 +1570,7 @@ make_percent_swname(dir, name)
char_u *dir;
char_u *name;
{
char_u *d, *s, *f, *p;
char_u *d, *s, *f;
f = fix_fname(name != NULL ? name : (char_u *) "");
d = NULL;
@@ -1450,9 +1579,10 @@ make_percent_swname(dir, name)
s = alloc((unsigned)(STRLEN(f) + 1));
if (s != NULL)
{
for (d = s, p = f; *p; p++, d++)
*d = vim_ispathsep(*p) ? '%' : *p;
*d = 0;
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);
}
@@ -3266,7 +3396,7 @@ makeswapname(buf, dir_name)
#if defined(UNIX) || defined(WIN3264) /* Need _very_ long file names */
s = dir_name + STRLEN(dir_name);
if (vim_ispathsep(s[-1]) && s[-1] == s[-2])
if (after_pathsep(dir_name, s) && s[-1] == s[-2])
{ /* Ends with '//', Use Full path */
r = NULL;
if ((s = make_percent_swname(dir_name, buf->b_fname)) != NULL)
@@ -3617,18 +3747,33 @@ findswapname(buf, dirp, old_fname)
if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
{
/*
* The name in the swap file may be "~user/path/file".
* Expand it first.
* If the swapfile has the same directory as the
* buffer don't compare the directory names, they can
* have a different mountpoint.
*/
expand_env(b0.b0_fname, NameBuff, MAXPATHL);
if (b0.b0_flags & B0_SAME_DIR)
{
if (fnamecmp(gettail(buf->b_ffname),
gettail(b0.b0_fname)) != 0
|| !same_directory(fname, buf->b_ffname))
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;
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;
if (fnamecmp(NameBuff, buf->b_ffname) != 0)
differ = TRUE;
#endif
}
}
close(fd);
}
@@ -3956,10 +4101,15 @@ char_to_long(s)
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_setdirty(buf, flag)
ml_setflags(buf)
buf_T *buf;
int flag;
{
bhdr_T *hp;
ZERO_BL *b0p;
@@ -3971,7 +4121,12 @@ ml_setdirty(buf, flag)
if (hp->bh_bnum == 0)
{
b0p = (ZERO_BL *)(hp->bh_data);
b0p->b0_dirty = flag ? 0x55 : 0;
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;