diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-09-12 14:53:53 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-09-12 14:53:53 +0200 |
commit | b00ef0508b22905379953a164bdb4300015d3705 (patch) | |
tree | ba2fc4de9e8d4febac6475338c7bc8509fb3ffde | |
parent | 635414dd2f3ae7d4d972d79b806348a6516cb91a (diff) | |
download | vim-git-b00ef0508b22905379953a164bdb4300015d3705.tar.gz |
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)
-rw-r--r-- | src/option.c | 91 | ||||
-rw-r--r-- | src/testdir/test_options.vim | 30 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 92 insertions, 31 deletions
diff --git a/src/option.c b/src/option.c index 648f22db3..6ebc2bd9b 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 diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index c5e5ab47c..ec40ccc5f 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -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= diff --git a/src/version.c b/src/version.c index e0afdf835..596f38d7e 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1666, +/**/ 1665, /**/ 1664, |