forked from aniani/vim
patch 8.2.1666: the initial value of 'backupskip' can have duplicate items
Problem: The initial value of 'backupskip' can have duplicate items.
Solution: Remove duplicates, like when it is set later. (Tom Ryder,
closes #6940)
This commit is contained in:
91
src/option.c
91
src/option.c
@@ -37,6 +37,7 @@
|
||||
|
||||
static void set_options_default(int opt_flags);
|
||||
static void set_string_default_esc(char *name, char_u *val, int escape);
|
||||
static char_u *find_dup_item(char_u *origval, char_u *newval, long_u flags);
|
||||
static char_u *option_expand(int opt_idx, char_u *val);
|
||||
static void didset_options(void);
|
||||
static void didset_options2(void);
|
||||
@@ -139,6 +140,9 @@ set_init_1(int clean_arg)
|
||||
int len;
|
||||
garray_T ga;
|
||||
int mustfree;
|
||||
char_u *item;
|
||||
|
||||
opt_idx = findoption((char_u *)"backupskip");
|
||||
|
||||
ga_init2(&ga, 1, 100);
|
||||
for (n = 0; n < (long)(sizeof(names) / sizeof(char *)); ++n)
|
||||
@@ -158,15 +162,20 @@ set_init_1(int clean_arg)
|
||||
{
|
||||
// First time count the NUL, otherwise count the ','.
|
||||
len = (int)STRLEN(p) + 3;
|
||||
if (ga_grow(&ga, len) == OK)
|
||||
item = alloc(len);
|
||||
STRCPY(item, p);
|
||||
add_pathsep(item);
|
||||
STRCAT(item, "*");
|
||||
if (find_dup_item(ga.ga_data, item, options[opt_idx].flags)
|
||||
== NULL
|
||||
&& ga_grow(&ga, len) == OK)
|
||||
{
|
||||
if (ga.ga_len > 0)
|
||||
STRCAT(ga.ga_data, ",");
|
||||
STRCAT(ga.ga_data, p);
|
||||
add_pathsep(ga.ga_data);
|
||||
STRCAT(ga.ga_data, "*");
|
||||
STRCAT(ga.ga_data, item);
|
||||
ga.ga_len += len;
|
||||
}
|
||||
vim_free(item);
|
||||
}
|
||||
if (mustfree)
|
||||
vim_free(p);
|
||||
@@ -667,6 +676,46 @@ set_string_default(char *name, char_u *val)
|
||||
set_string_default_esc(name, val, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* For an option value that contains comma separated items, find "newval" in
|
||||
* "origval". Return NULL if not found.
|
||||
*/
|
||||
static char_u *
|
||||
find_dup_item(char_u *origval, char_u *newval, long_u flags)
|
||||
{
|
||||
int bs;
|
||||
size_t newlen;
|
||||
char_u *s;
|
||||
|
||||
if (origval == NULL)
|
||||
return NULL;
|
||||
|
||||
newlen = STRLEN(newval);
|
||||
for (s = origval; *s != NUL; ++s)
|
||||
{
|
||||
if ((!(flags & P_COMMA)
|
||||
|| s == origval
|
||||
|| (s[-1] == ',' && !(bs & 1)))
|
||||
&& STRNCMP(s, newval, newlen) == 0
|
||||
&& (!(flags & P_COMMA)
|
||||
|| s[newlen] == ','
|
||||
|| s[newlen] == NUL))
|
||||
return s;
|
||||
// Count backslashes. Only a comma with an even number of backslashes
|
||||
// or a single backslash preceded by a comma before it is recognized as
|
||||
// a separator.
|
||||
if ((s > origval + 1
|
||||
&& s[-1] == '\\'
|
||||
&& s[-2] != ',')
|
||||
|| (s == origval + 1
|
||||
&& s[-1] == '\\'))
|
||||
++bs;
|
||||
else
|
||||
bs = 0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the Vi-default value of a number option.
|
||||
* Used for 'lines' and 'columns'.
|
||||
@@ -1572,7 +1621,6 @@ do_set(
|
||||
#endif
|
||||
unsigned newlen;
|
||||
int comma;
|
||||
int bs;
|
||||
int new_value_alloced; // new string option
|
||||
// was allocated
|
||||
|
||||
@@ -1811,39 +1859,20 @@ do_set(
|
||||
if (removing || (flags & P_NODUP))
|
||||
{
|
||||
i = (int)STRLEN(newval);
|
||||
bs = 0;
|
||||
for (s = origval; *s; ++s)
|
||||
{
|
||||
if ((!(flags & P_COMMA)
|
||||
|| s == origval
|
||||
|| (s[-1] == ',' && !(bs & 1)))
|
||||
&& STRNCMP(s, newval, i) == 0
|
||||
&& (!(flags & P_COMMA)
|
||||
|| s[i] == ','
|
||||
|| s[i] == NUL))
|
||||
break;
|
||||
// Count backslashes. Only a comma with an
|
||||
// even number of backslashes or a single
|
||||
// backslash preceded by a comma before it
|
||||
// is recognized as a separator
|
||||
if ((s > origval + 1
|
||||
&& s[-1] == '\\'
|
||||
&& s[-2] != ',')
|
||||
|| (s == origval + 1
|
||||
&& s[-1] == '\\'))
|
||||
|
||||
++bs;
|
||||
else
|
||||
bs = 0;
|
||||
}
|
||||
s = find_dup_item(origval, newval, flags);
|
||||
|
||||
// do not add if already there
|
||||
if ((adding || prepending) && *s)
|
||||
if ((adding || prepending) && s != NULL)
|
||||
{
|
||||
prepending = FALSE;
|
||||
adding = FALSE;
|
||||
STRCPY(newval, origval);
|
||||
}
|
||||
|
||||
// if no duplicate, move pointer to end of
|
||||
// original value
|
||||
if (s == NULL)
|
||||
s = origval + (int)STRLEN(origval);
|
||||
}
|
||||
|
||||
// concatenate the two strings; add a ',' if
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
" Test for options
|
||||
|
||||
source shared.vim
|
||||
source check.vim
|
||||
source view_util.vim
|
||||
|
||||
@@ -587,6 +588,35 @@ func Test_backupskip()
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Duplicates from environment variables should be filtered out (option has
|
||||
" P_NODUP). Run this in a separate instance and write v:errors in a file,
|
||||
" so that we see what happens on startup.
|
||||
let after =<< trim [CODE]
|
||||
let bsklist = split(&backupskip, ',')
|
||||
call assert_equal(uniq(copy(bsklist)), bsklist)
|
||||
call writefile(['errors:'] + v:errors, 'Xtestout')
|
||||
qall
|
||||
[CODE]
|
||||
call writefile(after, 'Xafter')
|
||||
let cmd = GetVimProg() . ' --not-a-term -S Xafter --cmd "set enc=utf8"'
|
||||
|
||||
let saveenv = {}
|
||||
for var in ['TMPDIR', 'TMP', 'TEMP']
|
||||
let saveenv[var] = getenv(var)
|
||||
call setenv(var, '/duplicate/path')
|
||||
endfor
|
||||
|
||||
exe 'silent !' . cmd
|
||||
call assert_equal(['errors:'], readfile('Xtestout'))
|
||||
|
||||
" restore environment variables
|
||||
for var in ['TMPDIR', 'TMP', 'TEMP']
|
||||
call setenv(var, saveenv[var])
|
||||
endfor
|
||||
|
||||
call delete('Xtestout')
|
||||
call delete('Xafter')
|
||||
|
||||
" Duplicates should be filtered out (option has P_NODUP)
|
||||
let backupskip = &backupskip
|
||||
set backupskip=
|
||||
|
||||
@@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1666,
|
||||
/**/
|
||||
1665,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user