summaryrefslogtreecommitdiffstats
path: root/src/option.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-09-12 14:53:53 +0200
committerBram Moolenaar <Bram@vim.org>2020-09-12 14:53:53 +0200
commitb00ef0508b22905379953a164bdb4300015d3705 (patch)
treeba2fc4de9e8d4febac6475338c7bc8509fb3ffde /src/option.c
parent635414dd2f3ae7d4d972d79b806348a6516cb91a (diff)
patch 8.2.1666: the initial value of 'backupskip' can have duplicate itemsv8.2.1666
Problem: The initial value of 'backupskip' can have duplicate items. Solution: Remove duplicates, like when it is set later. (Tom Ryder, closes #6940)
Diffstat (limited to 'src/option.c')
-rw-r--r--src/option.c91
1 files changed, 60 insertions, 31 deletions
diff --git a/src/option.c b/src/option.c
index 648f22db32..6ebc2bd9b5 100644
--- a/src/option.c
+++ b/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);
@@ -668,6 +677,46 @@ set_string_default(char *name, char_u *val)
}
/*
+ * 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