mirror of
https://github.com/vim/vim.git
synced 2026-05-25 03:27:39 +02:00
patch 9.2.0291: too many strlen() calls
Problem: too many strlen() calls
Solution: refactor concat_fname() and remove calls to strlen()
(John Marriott)
Function `concat_fnames()` can make up to 5 calls to `STRLEN()` (either
directly or indirectly via `STRCAT()`). In many cases the lengths of
arguments `fname1` and/or `fname2` are either known or can simply be
calculated.
This Commit refactors this function to accept the lengths of arguments
`fname1` and `fname2` as arguments. It also adds new argument `ret` to
return the resulting string as a `string_T`.
Additionally:
- function `add_pack_dir_to_rtp()` in `scriptfile.c`:
Use a `string_T` to store local variables `new_rtp` and `afterdir`.
Replace calls to `STRCAT()` with calls to `STRCPY()`.
Change type of variable `keep` to `size_t` for consistency with
other lengths.
- function `qf_get_fnum()` in `quickfix.c`:
Use a `string_T` to store local variables `ptr` and `bufname`
- function `qf_push_dir()` in `quickfix.c`:
Use a `string_T` to store local variable `dirname`.
Replace call to `vim_strsave()` with `vim_strnsave()`.
- function `qf_guess_filepath()` in `quickfix.c`:
Use a `string_T` to store local variable `fullname`.
- function `make_percent_swname()` in `memline.c`:
Rename some variables to better reflect their use.
Use a `string_T` to store local variables `d` and `fixed_name`.
Slightly refactor to remove need to create an extra string.
- function `get_file_in_dir()` in `memline.c`:
Use a `string_T` to store local variables `tail` and `retval`.
Move some variables closer to where they are used.
- function `cs_resolve_file()` in `if_cscope.c`:
Use a `string_T` to store local variable `csdir`.
Remove one call to `STRLEN()`.
- function `add_pathsep()` in `filepath.c`:
Refactor and remove 1 call to `STRLEN()`
- function `set_init_xdg_rtp()` in `option.c`:
Use a `string_T` to store local variable `vimrc_xdg`.
closes: #19854
Co-authored-by: Christian Brabandt <cb@256bit.org>
Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
b7205b6426
commit
cb51add7ae
+25
-13
@@ -3178,19 +3178,25 @@ vim_fnamencmp(char_u *x, char_u *y, size_t len)
|
||||
* Only add a '/' or '\\' when 'sep' is TRUE and it is necessary.
|
||||
*/
|
||||
char_u *
|
||||
concat_fnames(char_u *fname1, char_u *fname2, int sep)
|
||||
concat_fnames(char_u *fname1, size_t fname1len, char_u *fname2, size_t fname2len, int sep, string_T *ret)
|
||||
{
|
||||
char_u *dest;
|
||||
ret->string = alloc(fname1len + (sep ? STRLEN_LITERAL(PATHSEPSTR) : 0) + fname2len + 1);
|
||||
if (ret->string == NULL)
|
||||
ret->length = 0;
|
||||
else
|
||||
{
|
||||
STRCPY(ret->string, fname1);
|
||||
ret->length = fname1len;
|
||||
if (sep && *ret->string != NUL && !after_pathsep(ret->string, ret->string + ret->length))
|
||||
{
|
||||
STRCPY(ret->string + ret->length, PATHSEPSTR);
|
||||
ret->length += STRLEN_LITERAL(PATHSEPSTR);
|
||||
}
|
||||
STRCPY(ret->string + ret->length, fname2);
|
||||
ret->length += fname2len;
|
||||
}
|
||||
|
||||
dest = alloc(STRLEN(fname1) + STRLEN(fname2) + 3);
|
||||
if (dest == NULL)
|
||||
return NULL;
|
||||
|
||||
STRCPY(dest, fname1);
|
||||
if (sep)
|
||||
add_pathsep(dest);
|
||||
STRCAT(dest, fname2);
|
||||
return dest;
|
||||
return ret->string;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3200,8 +3206,14 @@ concat_fnames(char_u *fname1, char_u *fname2, int sep)
|
||||
void
|
||||
add_pathsep(char_u *p)
|
||||
{
|
||||
if (*p != NUL && !after_pathsep(p, p + STRLEN(p)))
|
||||
STRCAT(p, PATHSEPSTR);
|
||||
size_t plen;
|
||||
|
||||
if (*p == NUL)
|
||||
return;
|
||||
|
||||
plen = STRLEN(p);
|
||||
if (!after_pathsep(p, p + plen))
|
||||
STRCPY(p + plen, PATHSEPSTR);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+21
-12
@@ -2413,28 +2413,35 @@ cs_reset(exarg_T *eap UNUSED)
|
||||
cs_resolve_file(int i, char *name)
|
||||
{
|
||||
char *fullname;
|
||||
string_T csdir = {NULL, 0};
|
||||
size_t namelen;
|
||||
size_t ppathlen = 0;
|
||||
int len;
|
||||
char_u *csdir = NULL;
|
||||
|
||||
/*
|
||||
* Ppath is freed when we destroy the cscope connection.
|
||||
* Fullname is freed after cs_make_vim_style_matches, after it's been
|
||||
* copied into the tag buffer used by Vim.
|
||||
*/
|
||||
len = (int)(strlen(name) + 2);
|
||||
namelen = STRLEN(name);
|
||||
len = (int)namelen + 2;
|
||||
if (csinfo[i].ppath != NULL)
|
||||
len += (int)strlen(csinfo[i].ppath);
|
||||
{
|
||||
ppathlen = STRLEN(csinfo[i].ppath);
|
||||
len += (int)ppathlen;
|
||||
}
|
||||
else if (p_csre && csinfo[i].fname != NULL)
|
||||
{
|
||||
// If 'cscoperelative' is set and ppath is not set, use cscope.out
|
||||
// path in path resolution.
|
||||
csdir = alloc(MAXPATHL);
|
||||
if (csdir != NULL)
|
||||
csdir.string = alloc(MAXPATHL);
|
||||
if (csdir.string != NULL)
|
||||
{
|
||||
vim_strncpy(csdir, (char_u *)csinfo[i].fname,
|
||||
vim_strncpy(csdir.string, (char_u *)csinfo[i].fname,
|
||||
gettail((char_u *)csinfo[i].fname)
|
||||
- (char_u *)csinfo[i].fname);
|
||||
len += (int)STRLEN(csdir);
|
||||
csdir.length = STRLEN(csdir.string);
|
||||
len += (int)csdir.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2442,7 +2449,7 @@ cs_resolve_file(int i, char *name)
|
||||
// "../.." and the prefix path is also "../..". if something like this
|
||||
// happens, you are screwed up and need to fix how you're using cscope.
|
||||
if (csinfo[i].ppath != NULL
|
||||
&& (strncmp(name, csinfo[i].ppath, strlen(csinfo[i].ppath)) != 0)
|
||||
&& (strncmp(name, csinfo[i].ppath, ppathlen) != 0)
|
||||
&& (name[0] != '/')
|
||||
# ifdef MSWIN
|
||||
&& name[0] != '\\' && name[1] != ':'
|
||||
@@ -2452,18 +2459,20 @@ cs_resolve_file(int i, char *name)
|
||||
if ((fullname = alloc(len)) != NULL)
|
||||
(void)sprintf(fullname, "%s/%s", csinfo[i].ppath, name);
|
||||
}
|
||||
else if (csdir != NULL && csinfo[i].fname != NULL && *csdir != NUL)
|
||||
else if (csdir.string != NULL && csinfo[i].fname != NULL && *csdir.string != NUL)
|
||||
{
|
||||
string_T ret;
|
||||
|
||||
// Check for csdir to be non empty to avoid empty path concatenated to
|
||||
// cscope output.
|
||||
fullname = (char *)concat_fnames(csdir, (char_u *)name, TRUE);
|
||||
fullname = (char *)concat_fnames(csdir.string, csdir.length, (char_u *)name, namelen, TRUE, &ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
fullname = (char *)vim_strsave((char_u *)name);
|
||||
fullname = (char *)vim_strnsave((char_u *)name, namelen);
|
||||
}
|
||||
|
||||
vim_free(csdir);
|
||||
vim_free(csdir.string);
|
||||
return fullname;
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -2771,13 +2771,15 @@ scripterror:
|
||||
if (parmp->diff_mode && mch_isdir(p) && GARGCOUNT > 0
|
||||
&& !mch_isdir(alist_name(&GARGLIST[0])))
|
||||
{
|
||||
char_u *r;
|
||||
char_u *tail;
|
||||
string_T ret;
|
||||
|
||||
r = concat_fnames(p, gettail(alist_name(&GARGLIST[0])), TRUE);
|
||||
if (r != NULL)
|
||||
tail = gettail(alist_name(&GARGLIST[0]));
|
||||
concat_fnames(p, STRLEN(p), tail, STRLEN(tail), TRUE, &ret);
|
||||
if (ret.string != NULL)
|
||||
{
|
||||
vim_free(p);
|
||||
p = r;
|
||||
p = ret.string;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
+85
-52
@@ -1892,7 +1892,6 @@ recover_names(
|
||||
{
|
||||
int num_names;
|
||||
char_u *(names[6]);
|
||||
char_u *tail;
|
||||
char_u *p;
|
||||
int num_files;
|
||||
int file_count = 0;
|
||||
@@ -1969,20 +1968,27 @@ recover_names(
|
||||
{
|
||||
if (fname == NULL)
|
||||
{
|
||||
string_T ret;
|
||||
|
||||
#ifdef VMS
|
||||
names[0] = concat_fnames(dir_name.string, (char_u *)"*_sw%", TRUE);
|
||||
names[0] = concat_fnames(dir_name.string, dir_name.length,
|
||||
(char_u *)"*_sw%", STRLEN_LITERAL("*_sw%"), TRUE, &ret);
|
||||
#else
|
||||
names[0] = concat_fnames(dir_name.string, (char_u *)"*.sw?", TRUE);
|
||||
names[0] = concat_fnames(dir_name.string, dir_name.length,
|
||||
(char_u *)"*.sw?", STRLEN_LITERAL("*.sw?"), TRUE, &ret);
|
||||
#endif
|
||||
#if defined(UNIX) || defined(MSWIN)
|
||||
// For Unix names starting with a dot are special. MS-Windows
|
||||
// supports this too, on some file systems.
|
||||
names[1] = concat_fnames(dir_name.string, (char_u *)".*.sw?", TRUE);
|
||||
names[2] = concat_fnames(dir_name.string, (char_u *)".sw?", TRUE);
|
||||
names[1] = concat_fnames(dir_name.string, dir_name.length,
|
||||
(char_u *)".*.sw?", STRLEN_LITERAL(".*.sw?"), TRUE, &ret);
|
||||
names[2] = concat_fnames(dir_name.string, dir_name.length,
|
||||
(char_u *)".sw?", STRLEN_LITERAL(".sw?"), TRUE, &ret);
|
||||
num_names = 3;
|
||||
#else
|
||||
# ifdef VMS
|
||||
names[1] = concat_fnames(dir_name.string, (char_u *)".*_sw%", TRUE);
|
||||
names[1] = concat_fnames(dir_name.string, dir_name.length,
|
||||
(char_u *)".*_sw%", STRLEN_LITERAL(".*_sw%"), TRUE, &ret);
|
||||
num_names = 2;
|
||||
# else
|
||||
num_names = 1;
|
||||
@@ -1991,6 +1997,8 @@ recover_names(
|
||||
}
|
||||
else
|
||||
{
|
||||
char_u *tail;
|
||||
|
||||
#if defined(UNIX) || defined(MSWIN)
|
||||
p = dir_name.string + dir_name.length;
|
||||
if (after_pathsep(dir_name.string, p) && dir_name.length > 1 && p[-1] == p[-2])
|
||||
@@ -2001,8 +2009,11 @@ recover_names(
|
||||
else
|
||||
#endif
|
||||
{
|
||||
string_T ret;
|
||||
|
||||
tail = gettail(fname_res);
|
||||
tail = concat_fnames(dir_name.string, tail, TRUE);
|
||||
tail = concat_fnames(dir_name.string, dir_name.length,
|
||||
tail, STRLEN(tail), TRUE, &ret);
|
||||
}
|
||||
if (tail == NULL)
|
||||
num_names = 0;
|
||||
@@ -2132,13 +2143,16 @@ recover_names(
|
||||
#ifdef FEAT_EVAL
|
||||
else if (ret_list != NULL)
|
||||
{
|
||||
string_T name;
|
||||
|
||||
for (int i = 0; i < num_files; ++i)
|
||||
{
|
||||
char_u *name = concat_fnames(dir_name.string, files[i], TRUE);
|
||||
if (name != NULL)
|
||||
concat_fnames(dir_name.string, dir_name.length,
|
||||
files[i], STRLEN(files[i]), TRUE, &name);
|
||||
if (name.string != NULL)
|
||||
{
|
||||
list_append_string(ret_list, name, -1);
|
||||
vim_free(name);
|
||||
list_append_string(ret_list, name.string, (int)name.length);
|
||||
vim_free(name.string);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2166,26 +2180,26 @@ recover_names(
|
||||
char_u *
|
||||
make_percent_swname(char_u *dir, char_u *dir_end, char_u *name)
|
||||
{
|
||||
char_u *d = NULL, *s, *f;
|
||||
string_T d = {NULL, 0};
|
||||
string_T fixed_fname;
|
||||
char_u *p;
|
||||
|
||||
f = fix_fname(name != NULL ? name : (char_u *)"");
|
||||
if (f == NULL)
|
||||
fixed_fname.string = fix_fname(name != NULL ? name : (char_u *)"");
|
||||
if (fixed_fname.string == NULL)
|
||||
return NULL;
|
||||
|
||||
s = alloc(STRLEN(f) + 1);
|
||||
if (s != NULL)
|
||||
{
|
||||
STRCPY(s, f);
|
||||
for (d = s; *d != NUL; MB_PTR_ADV(d))
|
||||
if (vim_ispathsep(*d))
|
||||
*d = '%';
|
||||
for (p = fixed_fname.string; *p != NUL; MB_PTR_ADV(p))
|
||||
if (vim_ispathsep(*p))
|
||||
*p = '%';
|
||||
fixed_fname.length = (size_t)(p - fixed_fname.string);
|
||||
|
||||
dir_end[-1] = NUL; // remove one trailing slash
|
||||
d = concat_fnames(dir, s, TRUE);
|
||||
vim_free(s);
|
||||
}
|
||||
vim_free(f);
|
||||
return d;
|
||||
// remove one trailing slash
|
||||
p = &dir_end[-1];
|
||||
*p = NUL;
|
||||
concat_fnames(dir, (size_t)(p - dir), fixed_fname.string, fixed_fname.length, TRUE, &d);
|
||||
vim_free(fixed_fname.string);
|
||||
|
||||
return d.string;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2432,6 +2446,7 @@ recov_file_names(char_u **names, char_u *path, int prepend_dot)
|
||||
|
||||
curbuf->b_shortname = FALSE;
|
||||
#endif
|
||||
string_T ret;
|
||||
|
||||
num_names = 0;
|
||||
|
||||
@@ -2451,9 +2466,11 @@ recov_file_names(char_u **names, char_u *path, int prepend_dot)
|
||||
* Form the normal swap file name pattern by appending ".sw?".
|
||||
*/
|
||||
#ifdef VMS
|
||||
names[num_names] = concat_fnames(path, (char_u *)"_sw%", FALSE);
|
||||
names[num_names] = concat_fnames(path, STRLEN(path),
|
||||
(char_u *)"_sw%", STRLEN_LITERAL("_sw%"), FALSE, &ret);
|
||||
#else
|
||||
names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE);
|
||||
names[num_names] = concat_fnames(path, STRLEN(path),
|
||||
(char_u *)".sw?", STRLEN_LITERAL(".sw?"), FALSE, &ret);
|
||||
#endif
|
||||
if (names[num_names] == NULL)
|
||||
goto end;
|
||||
@@ -4746,45 +4763,61 @@ get_file_in_dir(
|
||||
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;
|
||||
string_T tail;
|
||||
string_T retval;
|
||||
|
||||
tail = gettail(fname);
|
||||
tail.string = gettail(fname);
|
||||
tail.length = STRLEN(tail.string);
|
||||
|
||||
if (dname[0] == '.' && dname[1] == NUL)
|
||||
retval = vim_strsave(fname);
|
||||
else if (dname[0] == '.' && vim_ispathsep(dname[1]))
|
||||
retval.string =
|
||||
vim_strnsave(fname, (size_t)(tail.string - fname) + tail.length);
|
||||
else
|
||||
{
|
||||
if (tail == fname) // no path before file name
|
||||
retval = concat_fnames(dname + 2, tail, TRUE);
|
||||
else
|
||||
size_t dname_len = STRLEN(dname);
|
||||
|
||||
if (dname[0] == '.' && vim_ispathsep(dname[1]))
|
||||
{
|
||||
save_char = *tail;
|
||||
*tail = NUL;
|
||||
t = concat_fnames(fname, dname + 2, TRUE);
|
||||
*tail = save_char;
|
||||
if (t == NULL) // out of memory
|
||||
retval = NULL;
|
||||
if (tail.string == fname) // no path before file name
|
||||
concat_fnames(dname + 2, dname_len - 2,
|
||||
tail.string, tail.length, TRUE, &retval);
|
||||
else
|
||||
{
|
||||
retval = concat_fnames(t, tail, TRUE);
|
||||
vim_free(t);
|
||||
int save_char;
|
||||
string_T tmp;
|
||||
|
||||
save_char = *tail.string;
|
||||
*tail.string = NUL;
|
||||
concat_fnames(fname, (size_t)(tail.string - fname),
|
||||
dname + 2, dname_len - 2, TRUE, &tmp);
|
||||
*tail.string = save_char;
|
||||
if (tmp.string == NULL) // out of memory
|
||||
retval.string = NULL;
|
||||
else
|
||||
{
|
||||
concat_fnames(tmp.string, tmp.length,
|
||||
tail.string, tail.length, TRUE, &retval);
|
||||
vim_free(tmp.string);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
concat_fnames(dname, dname_len, tail.string, tail.length,
|
||||
TRUE, &retval);
|
||||
}
|
||||
else
|
||||
retval = concat_fnames(dname, tail, TRUE);
|
||||
|
||||
#ifdef MSWIN
|
||||
if (retval != NULL)
|
||||
for (t = gettail(retval); *t != NUL; MB_PTR_ADV(t))
|
||||
if (retval.string != NULL)
|
||||
{
|
||||
char_u *t;
|
||||
|
||||
for (t = gettail(retval.string); *t != NUL; MB_PTR_ADV(t))
|
||||
if (*t == ':')
|
||||
*t = '%';
|
||||
}
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
return retval.string;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+20
-13
@@ -1752,32 +1752,39 @@ remove_tail(char_u *p, char_u *pend, char_u *name)
|
||||
static char_u *
|
||||
vim_version_dir(char_u *vimdir)
|
||||
{
|
||||
char_u *p;
|
||||
string_T p;
|
||||
size_t vimdir_len;
|
||||
|
||||
if (vimdir == NULL || *vimdir == NUL)
|
||||
return NULL;
|
||||
p = concat_fnames(vimdir, (char_u *)VIM_VERSION_NODOT, TRUE);
|
||||
if (p != NULL && mch_isdir(p))
|
||||
return p;
|
||||
vim_free(p);
|
||||
p = concat_fnames(vimdir, (char_u *)RUNTIME_DIRNAME, TRUE);
|
||||
if (p != NULL && mch_isdir(p))
|
||||
vimdir_len = STRLEN(vimdir);
|
||||
concat_fnames(vimdir, vimdir_len,
|
||||
(char_u *)VIM_VERSION_NODOT, STRLEN_LITERAL(VIM_VERSION_NODOT), TRUE, &p);
|
||||
if (p.string != NULL && mch_isdir(p.string))
|
||||
return p.string;
|
||||
vim_free(p.string);
|
||||
concat_fnames(vimdir, vimdir_len,
|
||||
(char_u *)RUNTIME_DIRNAME, STRLEN_LITERAL(RUNTIME_DIRNAME), TRUE, &p);
|
||||
if (p.string != NULL && mch_isdir(p.string))
|
||||
{
|
||||
char_u *fname = concat_fnames(p, (char_u *)"defaults.vim", TRUE);
|
||||
string_T fname;
|
||||
|
||||
concat_fnames(p.string, p.length,
|
||||
(char_u *)"defaults.vim", STRLEN_LITERAL("defaults.vim"), TRUE, &fname);
|
||||
|
||||
// Check that "defaults.vim" exists in this directory, to avoid picking
|
||||
// up a stray "runtime" directory, it would make many tests fail in
|
||||
// mysterious ways.
|
||||
if (fname != NULL)
|
||||
if (fname.string != NULL)
|
||||
{
|
||||
int exists = file_is_readable(fname);
|
||||
int exists = file_is_readable(fname.string);
|
||||
|
||||
vim_free(fname);
|
||||
vim_free(fname.string);
|
||||
if (exists)
|
||||
return p;
|
||||
return p.string;
|
||||
}
|
||||
}
|
||||
vim_free(p);
|
||||
vim_free(p.string);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -404,7 +404,7 @@ set_init_xdg_rtp(void)
|
||||
char_u *vimrc2 = NULL;
|
||||
char_u *xdg_dir = NULL;
|
||||
char_u *xdg_rtp = NULL;
|
||||
char_u *vimrc_xdg = NULL;
|
||||
string_T vimrc_xdg = {NULL, 0};
|
||||
|
||||
// initialize chartab, so we can expand $HOME
|
||||
(void)init_chartab();
|
||||
@@ -418,10 +418,11 @@ set_init_xdg_rtp(void)
|
||||
should_free_xdg_dir = TRUE;
|
||||
has_xdg_env = FALSE;
|
||||
}
|
||||
vimrc_xdg = concat_fnames(xdg_dir, (char_u *)"vim/vimrc", TRUE);
|
||||
concat_fnames(xdg_dir, STRLEN(xdg_dir),
|
||||
(char_u *)"vim/vimrc", STRLEN_LITERAL("vim/vimrc"), TRUE, &vimrc_xdg);
|
||||
|
||||
if (file_is_readable(vimrc1) || file_is_readable(vimrc2) ||
|
||||
!file_is_readable(vimrc_xdg))
|
||||
!file_is_readable(vimrc_xdg.string))
|
||||
goto theend;
|
||||
|
||||
xdg_rtp = has_xdg_env ? (char_u *)XDG_RUNTIMEPATH
|
||||
@@ -450,7 +451,7 @@ set_init_xdg_rtp(void)
|
||||
theend:
|
||||
vim_free(vimrc1);
|
||||
vim_free(vimrc2);
|
||||
vim_free(vimrc_xdg);
|
||||
vim_free(vimrc_xdg.string);
|
||||
if (should_free_xdg_dir)
|
||||
vim_free(xdg_dir);
|
||||
}
|
||||
|
||||
+6
-4
@@ -8614,13 +8614,15 @@ fix_arg_enc(void)
|
||||
if (used_file_diff_mode && mch_isdir(str) && GARGCOUNT > 0
|
||||
&& !mch_isdir(alist_name(&GARGLIST[0])))
|
||||
{
|
||||
char_u *r;
|
||||
char_u *tail;
|
||||
string_T ret;
|
||||
|
||||
r = concat_fnames(str, gettail(alist_name(&GARGLIST[0])), TRUE);
|
||||
if (r != NULL)
|
||||
tail = gettail(alist_name(&GARGLIST[0]));
|
||||
concat_fnames(str, STRLEN(str), tail, STRLEN(tail), TRUE, &ret);
|
||||
if (ret.string != NULL)
|
||||
{
|
||||
vim_free(str);
|
||||
str = r;
|
||||
str = ret.string;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -48,7 +48,7 @@ int vim_ispathsep_nocolon(int c);
|
||||
int dir_of_file_exists(char_u *fname);
|
||||
int vim_fnamecmp(char_u *x, char_u *y);
|
||||
int vim_fnamencmp(char_u *x, char_u *y, size_t len);
|
||||
char_u *concat_fnames(char_u *fname1, char_u *fname2, int sep);
|
||||
char_u *concat_fnames(char_u *fname1, size_t fname1len, char_u *fname2, size_t fname2len, int sep, string_T *ret);
|
||||
void add_pathsep(char_u *p);
|
||||
char_u *FullName_save(char_u *fname, int force);
|
||||
int vim_fexists(char_u *fname);
|
||||
|
||||
+46
-29
@@ -2728,9 +2728,10 @@ copy_loclist_stack(win_T *from, win_T *to)
|
||||
static int
|
||||
qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname)
|
||||
{
|
||||
char_u *ptr = NULL;
|
||||
string_T ptr = {NULL, 0};
|
||||
buf_T *buf;
|
||||
char_u *bufname;
|
||||
string_T bufname;
|
||||
size_t fname_len;
|
||||
|
||||
if (fname == NULL || *fname == NUL) // no file name
|
||||
return 0;
|
||||
@@ -2743,44 +2744,52 @@ qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname)
|
||||
slash_adjust(directory);
|
||||
slash_adjust(fname);
|
||||
# endif
|
||||
fname_len = STRLEN(fname);
|
||||
if (directory != NULL && !vim_isAbsName(fname)
|
||||
&& (ptr = concat_fnames(directory, fname, TRUE)) != NULL)
|
||||
&& concat_fnames(directory, STRLEN(directory), fname, fname_len, TRUE, &ptr) != NULL)
|
||||
{
|
||||
// Here we check if the file really exists.
|
||||
// This should normally be true, but if make works without
|
||||
// "leaving directory"-messages we might have missed a
|
||||
// directory change.
|
||||
if (mch_getperm(ptr) < 0)
|
||||
if (mch_getperm(ptr.string) < 0)
|
||||
{
|
||||
vim_free(ptr);
|
||||
vim_free(ptr.string);
|
||||
directory = qf_guess_filepath(qfl, fname);
|
||||
if (directory)
|
||||
ptr = concat_fnames(directory, fname, TRUE);
|
||||
concat_fnames(directory, STRLEN(directory), fname, fname_len, TRUE, &ptr);
|
||||
else
|
||||
ptr = vim_strsave(fname);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
ptr.length = fname_len;
|
||||
ptr.string = vim_strnsave(fname, fname_len);
|
||||
}
|
||||
if (ptr.string == NULL)
|
||||
return 0;
|
||||
}
|
||||
// Use concatenated directory name and file name
|
||||
bufname = ptr;
|
||||
bufname.string = ptr.string;
|
||||
bufname.length = ptr.length;
|
||||
}
|
||||
else
|
||||
bufname = fname;
|
||||
{
|
||||
bufname.string = fname;
|
||||
bufname.length = fname_len;
|
||||
}
|
||||
|
||||
if (qf_last_bufname != NULL && STRCMP(bufname, qf_last_bufname) == 0
|
||||
if (qf_last_bufname != NULL && STRCMP(bufname.string, qf_last_bufname) == 0
|
||||
&& bufref_valid(&qf_last_bufref))
|
||||
{
|
||||
buf = qf_last_bufref.br_buf;
|
||||
vim_free(ptr);
|
||||
vim_free(ptr.string);
|
||||
}
|
||||
else
|
||||
{
|
||||
vim_free(qf_last_bufname);
|
||||
buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT);
|
||||
if (bufname == ptr)
|
||||
qf_last_bufname = bufname;
|
||||
buf = buflist_new(bufname.string, NULL, (linenr_T)0, BLN_NOOPT);
|
||||
if (bufname.string == ptr.string)
|
||||
qf_last_bufname = bufname.string;
|
||||
else
|
||||
qf_last_bufname = vim_strsave(bufname);
|
||||
qf_last_bufname = vim_strnsave(bufname.string, bufname.length);
|
||||
set_bufref(&qf_last_bufref, buf);
|
||||
}
|
||||
if (buf == NULL)
|
||||
@@ -2817,17 +2826,21 @@ qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, int is_file_stack)
|
||||
(*stackptr)->dirname = vim_strsave(dirbuf);
|
||||
else
|
||||
{
|
||||
size_t dirbuf_len;
|
||||
|
||||
// Okay we don't have an absolute path.
|
||||
// dirbuf must be a subdir of one of the directories on the stack.
|
||||
// Let's search...
|
||||
dirbuf_len = STRLEN(dirbuf);
|
||||
ds_new = (*stackptr)->next;
|
||||
(*stackptr)->dirname = NULL;
|
||||
while (ds_new)
|
||||
{
|
||||
char_u *dirname;
|
||||
string_T dirname;
|
||||
|
||||
dirname = concat_fnames(ds_new->dirname, dirbuf, TRUE);
|
||||
if (dirname == NULL)
|
||||
concat_fnames(ds_new->dirname, STRLEN(ds_new->dirname),
|
||||
dirbuf, dirbuf_len, TRUE, &dirname);
|
||||
if (dirname.string == NULL)
|
||||
{
|
||||
// pop the new element from the stack and free it
|
||||
ds_ptr = *stackptr;
|
||||
@@ -2836,13 +2849,13 @@ qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, int is_file_stack)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
if (mch_isdir(dirname) == TRUE)
|
||||
if (mch_isdir(dirname.string) == TRUE)
|
||||
{
|
||||
vim_free((*stackptr)->dirname);
|
||||
(*stackptr)->dirname = dirname;
|
||||
(*stackptr)->dirname = dirname.string;
|
||||
break;
|
||||
}
|
||||
vim_free(dirname);
|
||||
vim_free(dirname.string);
|
||||
ds_new = ds_new->next;
|
||||
}
|
||||
|
||||
@@ -2859,7 +2872,7 @@ qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, int is_file_stack)
|
||||
if (ds_new == NULL)
|
||||
{
|
||||
vim_free((*stackptr)->dirname);
|
||||
(*stackptr)->dirname = vim_strsave(dirbuf);
|
||||
(*stackptr)->dirname = vim_strnsave(dirbuf, dirbuf_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2940,28 +2953,32 @@ qf_guess_filepath(qf_list_T *qfl, char_u *filename)
|
||||
{
|
||||
struct dir_stack_T *ds_ptr;
|
||||
struct dir_stack_T *ds_tmp;
|
||||
char_u *fullname;
|
||||
string_T fullname;
|
||||
size_t filename_len;
|
||||
|
||||
// no dirs on the stack - there's nothing we can do
|
||||
if (qfl->qf_dir_stack == NULL)
|
||||
return NULL;
|
||||
|
||||
ds_ptr = qfl->qf_dir_stack->next;
|
||||
fullname = NULL;
|
||||
fullname.string = NULL;
|
||||
fullname.length = 0;
|
||||
filename_len = STRLEN(filename);
|
||||
while (ds_ptr)
|
||||
{
|
||||
vim_free(fullname);
|
||||
fullname = concat_fnames(ds_ptr->dirname, filename, TRUE);
|
||||
vim_free(fullname.string);
|
||||
concat_fnames(ds_ptr->dirname, STRLEN(ds_ptr->dirname),
|
||||
filename, filename_len, TRUE, &fullname);
|
||||
|
||||
// If concat_fnames failed, just go on. The worst thing that can happen
|
||||
// is that we delete the entire stack.
|
||||
if ((fullname != NULL) && (mch_getperm(fullname) >= 0))
|
||||
if ((fullname.string != NULL) && (mch_getperm(fullname.string) >= 0))
|
||||
break;
|
||||
|
||||
ds_ptr = ds_ptr->next;
|
||||
}
|
||||
|
||||
vim_free(fullname);
|
||||
vim_free(fullname.string);
|
||||
|
||||
// clean up all dirs we already left
|
||||
while (qfl->qf_dir_stack->next != ds_ptr)
|
||||
|
||||
+52
-42
@@ -841,19 +841,14 @@ add_pack_dir_to_rtp(char_u *fname)
|
||||
char_u *entry;
|
||||
char_u *insp = NULL;
|
||||
int c;
|
||||
char_u *new_rtp;
|
||||
int keep;
|
||||
size_t oldlen;
|
||||
size_t addlen;
|
||||
size_t new_rtp_len;
|
||||
char_u *afterdir = NULL;
|
||||
size_t afterlen = 0;
|
||||
string_T new_rtp;
|
||||
size_t keep;
|
||||
size_t p_rtp_len;
|
||||
string_T afterdir = {NULL, 0};
|
||||
char_u *after_insp = NULL;
|
||||
char_u *ffname = NULL;
|
||||
size_t fname_len;
|
||||
string_T buf = {NULL, 0};
|
||||
char_u *rtp_ffname;
|
||||
int match;
|
||||
int retval = FAIL;
|
||||
|
||||
p4 = p3 = p2 = p1 = get_past_head(fname);
|
||||
@@ -881,12 +876,17 @@ add_pack_dir_to_rtp(char_u *fname)
|
||||
buf.string = alloc(MAXPATHL);
|
||||
if (buf.string == NULL)
|
||||
goto theend;
|
||||
|
||||
p_rtp_len = 0;
|
||||
for (entry = p_rtp; *entry != NUL; )
|
||||
{
|
||||
char_u *cur_entry = entry;
|
||||
|
||||
buf.length = (size_t)copy_option_part(&entry, buf.string, MAXPATHL, ",");
|
||||
|
||||
// keep track of p_rtp length as we go to make the STRLEN() below have less work to do
|
||||
p_rtp_len += (*(p_rtp + buf.length) == ',') ? buf.length + 1 : buf.length;
|
||||
|
||||
if ((p = (char_u *)strstr((char *)buf.string, "after")) != NULL
|
||||
&& p > buf.string
|
||||
&& vim_ispathsep(p[-1])
|
||||
@@ -902,6 +902,9 @@ add_pack_dir_to_rtp(char_u *fname)
|
||||
|
||||
if (insp == NULL)
|
||||
{
|
||||
char_u *rtp_ffname;
|
||||
int match;
|
||||
|
||||
if (*buf.string != NUL && !after_pathsep(buf.string, buf.string + buf.length))
|
||||
STRCPY(buf.string + buf.length, PATHSEPSTR);
|
||||
rtp_ffname = fix_fname(buf.string);
|
||||
@@ -915,69 +918,76 @@ add_pack_dir_to_rtp(char_u *fname)
|
||||
}
|
||||
}
|
||||
|
||||
// finish measuring the length of p_rtp
|
||||
p_rtp_len += STRLEN(p_rtp + p_rtp_len);
|
||||
if (insp == NULL)
|
||||
// Both "fname" and "after" not found, append at the end.
|
||||
insp = p_rtp + STRLEN(p_rtp);
|
||||
insp = p_rtp + p_rtp_len;
|
||||
|
||||
// check if rtp/pack/name/start/name/after exists
|
||||
afterdir = concat_fnames(fname, (char_u *)"after", TRUE);
|
||||
if (afterdir != NULL && mch_isdir(afterdir))
|
||||
afterlen = STRLEN(afterdir) + 1; // add one for comma
|
||||
fname_len = STRLEN(fname);
|
||||
concat_fnames(fname, fname_len, (char_u *)"after", STRLEN_LITERAL("after"), TRUE, &afterdir);
|
||||
if (afterdir.string == NULL || !mch_isdir(afterdir.string))
|
||||
afterdir.length = 0;
|
||||
|
||||
oldlen = STRLEN(p_rtp);
|
||||
addlen = STRLEN(fname) + 1; // add one for comma
|
||||
new_rtp = alloc(oldlen + addlen + afterlen + 1); // add one for NUL
|
||||
if (new_rtp == NULL)
|
||||
new_rtp.string = alloc(p_rtp_len + fname_len + afterdir.length + 3); // add two for commas and one for NUL
|
||||
if (new_rtp.string == NULL)
|
||||
goto theend;
|
||||
|
||||
// We now have 'rtp' parts: {keep}{keep_after}{rest}.
|
||||
// Create new_rtp, first: {keep},{fname}
|
||||
keep = (int)(insp - p_rtp);
|
||||
mch_memmove(new_rtp, p_rtp, keep);
|
||||
new_rtp_len = keep;
|
||||
keep = (size_t)(insp - p_rtp);
|
||||
mch_memmove(new_rtp.string, p_rtp, keep);
|
||||
new_rtp.length = keep;
|
||||
if (*insp == NUL)
|
||||
new_rtp[new_rtp_len++] = ','; // add comma before
|
||||
mch_memmove(new_rtp + new_rtp_len, fname, addlen - 1);
|
||||
new_rtp_len += addlen - 1;
|
||||
new_rtp.string[new_rtp.length++] = ','; // add comma before
|
||||
mch_memmove(new_rtp.string + new_rtp.length, fname, fname_len);
|
||||
new_rtp.length += fname_len;
|
||||
if (*insp != NUL)
|
||||
new_rtp[new_rtp_len++] = ','; // add comma after
|
||||
new_rtp.string[new_rtp.length++] = ','; // add comma after
|
||||
|
||||
if (afterlen > 0 && after_insp != NULL)
|
||||
if (afterdir.length > 0 && after_insp != NULL)
|
||||
{
|
||||
int keep_after = (int)(after_insp - p_rtp);
|
||||
size_t keep_after = (size_t)(after_insp - p_rtp);
|
||||
size_t append_len = keep_after - keep;
|
||||
|
||||
// Add to new_rtp: {keep},{fname}{keep_after},{afterdir}
|
||||
mch_memmove(new_rtp + new_rtp_len, p_rtp + keep,
|
||||
keep_after - keep);
|
||||
new_rtp_len += keep_after - keep;
|
||||
mch_memmove(new_rtp + new_rtp_len, afterdir, afterlen - 1);
|
||||
new_rtp_len += afterlen - 1;
|
||||
new_rtp[new_rtp_len++] = ',';
|
||||
mch_memmove(new_rtp.string + new_rtp.length, p_rtp + keep,
|
||||
append_len);
|
||||
new_rtp.length += append_len;
|
||||
mch_memmove(new_rtp.string + new_rtp.length, afterdir.string, afterdir.length);
|
||||
new_rtp.length += afterdir.length;
|
||||
new_rtp.string[new_rtp.length++] = ',';
|
||||
keep = keep_after;
|
||||
}
|
||||
|
||||
if (p_rtp[keep] != NUL)
|
||||
// Append rest: {keep},{fname}{keep_after},{afterdir}{rest}
|
||||
mch_memmove(new_rtp + new_rtp_len, p_rtp + keep, oldlen - keep + 1);
|
||||
else
|
||||
new_rtp[new_rtp_len] = NUL;
|
||||
{
|
||||
size_t append_len = p_rtp_len - keep;
|
||||
|
||||
if (afterlen > 0 && after_insp == NULL)
|
||||
// Append rest: {keep},{fname}{keep_after},{afterdir}{rest}
|
||||
mch_memmove(new_rtp.string + new_rtp.length, p_rtp + keep, append_len + 1); // add one for NUL
|
||||
new_rtp.length += append_len;
|
||||
}
|
||||
else
|
||||
new_rtp.string[new_rtp.length] = NUL;
|
||||
|
||||
if (afterdir.length > 0 && after_insp == NULL)
|
||||
{
|
||||
// Append afterdir when "after" was not found:
|
||||
// {keep},{fname}{rest},{afterdir}
|
||||
STRCAT(new_rtp, ",");
|
||||
STRCAT(new_rtp, afterdir);
|
||||
new_rtp.string[new_rtp.length++] = ',';
|
||||
STRCPY(new_rtp.string + new_rtp.length, afterdir.string);
|
||||
}
|
||||
|
||||
set_option_value_give_err((char_u *)"rtp", 0L, new_rtp, 0);
|
||||
vim_free(new_rtp);
|
||||
set_option_value_give_err((char_u *)"rtp", 0L, new_rtp.string, 0);
|
||||
vim_free(new_rtp.string);
|
||||
retval = OK;
|
||||
|
||||
theend:
|
||||
vim_free(buf.string);
|
||||
vim_free(ffname);
|
||||
vim_free(afterdir);
|
||||
vim_free(afterdir.string);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
+11
-7
@@ -804,7 +804,7 @@ u_get_undo_file_name(char_u *buf_ffname, int reading)
|
||||
{
|
||||
char_u *dirp;
|
||||
char_u dir_name[IOSIZE + 1];
|
||||
char_u *munged_name = NULL;
|
||||
string_T munged_name = {NULL, 0};
|
||||
char_u *undo_file_name = NULL;
|
||||
int dir_len;
|
||||
char_u *p;
|
||||
@@ -862,16 +862,20 @@ u_get_undo_file_name(char_u *buf_ffname, int reading)
|
||||
dir_name[dir_len] = NUL;
|
||||
if (mch_isdir(dir_name))
|
||||
{
|
||||
if (munged_name == NULL)
|
||||
string_T ret;
|
||||
|
||||
if (munged_name.string == NULL)
|
||||
{
|
||||
munged_name = vim_strnsave(ffname, ffnamelen);
|
||||
if (munged_name == NULL)
|
||||
munged_name.string = vim_strnsave(ffname, ffnamelen);
|
||||
if (munged_name.string == NULL)
|
||||
return NULL;
|
||||
for (p = munged_name; *p != NUL; MB_PTR_ADV(p))
|
||||
munged_name.length = ffnamelen;
|
||||
for (p = munged_name.string; *p != NUL; MB_PTR_ADV(p))
|
||||
if (vim_ispathsep(*p))
|
||||
*p = '%';
|
||||
}
|
||||
undo_file_name = concat_fnames(dir_name, munged_name, TRUE);
|
||||
undo_file_name = concat_fnames(dir_name, (size_t)dir_len,
|
||||
munged_name.string, munged_name.length, TRUE, &ret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -882,7 +886,7 @@ u_get_undo_file_name(char_u *buf_ffname, int reading)
|
||||
VIM_CLEAR(undo_file_name);
|
||||
}
|
||||
|
||||
vim_free(munged_name);
|
||||
vim_free(munged_name.string);
|
||||
return undo_file_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -734,6 +734,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
291,
|
||||
/**/
|
||||
290,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user