comparison src/option.c @ 22234:b5abb88d5700 v8.2.1666

patch 8.2.1666: the initial value of 'backupskip' can have duplicate items Commit: https://github.com/vim/vim/commit/b00ef0508b22905379953a164bdb4300015d3705 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 12 14:53:53 2020 +0200 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)
author Bram Moolenaar <Bram@vim.org>
date Sat, 12 Sep 2020 15:00:04 +0200
parents 9099eb378758
children f7871f02ddcd
comparison
equal deleted inserted replaced
22233:0aeaeed4640d 22234:b5abb88d5700
35 #include "vim.h" 35 #include "vim.h"
36 #include "optiondefs.h" 36 #include "optiondefs.h"
37 37
38 static void set_options_default(int opt_flags); 38 static void set_options_default(int opt_flags);
39 static void set_string_default_esc(char *name, char_u *val, int escape); 39 static void set_string_default_esc(char *name, char_u *val, int escape);
40 static char_u *find_dup_item(char_u *origval, char_u *newval, long_u flags);
40 static char_u *option_expand(int opt_idx, char_u *val); 41 static char_u *option_expand(int opt_idx, char_u *val);
41 static void didset_options(void); 42 static void didset_options(void);
42 static void didset_options2(void); 43 static void didset_options2(void);
43 #if defined(FEAT_EVAL) || defined(PROTO) 44 #if defined(FEAT_EVAL) || defined(PROTO)
44 static long_u *insecure_flag(int opt_idx, int opt_flags); 45 static long_u *insecure_flag(int opt_idx, int opt_flags);
137 static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"}; 138 static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"};
138 # endif 139 # endif
139 int len; 140 int len;
140 garray_T ga; 141 garray_T ga;
141 int mustfree; 142 int mustfree;
143 char_u *item;
144
145 opt_idx = findoption((char_u *)"backupskip");
142 146
143 ga_init2(&ga, 1, 100); 147 ga_init2(&ga, 1, 100);
144 for (n = 0; n < (long)(sizeof(names) / sizeof(char *)); ++n) 148 for (n = 0; n < (long)(sizeof(names) / sizeof(char *)); ++n)
145 { 149 {
146 mustfree = FALSE; 150 mustfree = FALSE;
156 p = vim_getenv((char_u *)names[n], &mustfree); 160 p = vim_getenv((char_u *)names[n], &mustfree);
157 if (p != NULL && *p != NUL) 161 if (p != NULL && *p != NUL)
158 { 162 {
159 // First time count the NUL, otherwise count the ','. 163 // First time count the NUL, otherwise count the ','.
160 len = (int)STRLEN(p) + 3; 164 len = (int)STRLEN(p) + 3;
161 if (ga_grow(&ga, len) == OK) 165 item = alloc(len);
166 STRCPY(item, p);
167 add_pathsep(item);
168 STRCAT(item, "*");
169 if (find_dup_item(ga.ga_data, item, options[opt_idx].flags)
170 == NULL
171 && ga_grow(&ga, len) == OK)
162 { 172 {
163 if (ga.ga_len > 0) 173 if (ga.ga_len > 0)
164 STRCAT(ga.ga_data, ","); 174 STRCAT(ga.ga_data, ",");
165 STRCAT(ga.ga_data, p); 175 STRCAT(ga.ga_data, item);
166 add_pathsep(ga.ga_data);
167 STRCAT(ga.ga_data, "*");
168 ga.ga_len += len; 176 ga.ga_len += len;
169 } 177 }
178 vim_free(item);
170 } 179 }
171 if (mustfree) 180 if (mustfree)
172 vim_free(p); 181 vim_free(p);
173 } 182 }
174 if (ga.ga_data != NULL) 183 if (ga.ga_data != NULL)
663 672
664 void 673 void
665 set_string_default(char *name, char_u *val) 674 set_string_default(char *name, char_u *val)
666 { 675 {
667 set_string_default_esc(name, val, FALSE); 676 set_string_default_esc(name, val, FALSE);
677 }
678
679 /*
680 * For an option value that contains comma separated items, find "newval" in
681 * "origval". Return NULL if not found.
682 */
683 static char_u *
684 find_dup_item(char_u *origval, char_u *newval, long_u flags)
685 {
686 int bs;
687 size_t newlen;
688 char_u *s;
689
690 if (origval == NULL)
691 return NULL;
692
693 newlen = STRLEN(newval);
694 for (s = origval; *s != NUL; ++s)
695 {
696 if ((!(flags & P_COMMA)
697 || s == origval
698 || (s[-1] == ',' && !(bs & 1)))
699 && STRNCMP(s, newval, newlen) == 0
700 && (!(flags & P_COMMA)
701 || s[newlen] == ','
702 || s[newlen] == NUL))
703 return s;
704 // Count backslashes. Only a comma with an even number of backslashes
705 // or a single backslash preceded by a comma before it is recognized as
706 // a separator.
707 if ((s > origval + 1
708 && s[-1] == '\\'
709 && s[-2] != ',')
710 || (s == origval + 1
711 && s[-1] == '\\'))
712 ++bs;
713 else
714 bs = 0;
715 }
716 return NULL;
668 } 717 }
669 718
670 /* 719 /*
671 * Set the Vi-default value of a number option. 720 * Set the Vi-default value of a number option.
672 * Used for 'lines' and 'columns'. 721 * Used for 'lines' and 'columns'.
1570 char_u *saved_origval_g = NULL; 1619 char_u *saved_origval_g = NULL;
1571 char_u *saved_newval = NULL; 1620 char_u *saved_newval = NULL;
1572 #endif 1621 #endif
1573 unsigned newlen; 1622 unsigned newlen;
1574 int comma; 1623 int comma;
1575 int bs;
1576 int new_value_alloced; // new string option 1624 int new_value_alloced; // new string option
1577 // was allocated 1625 // was allocated
1578 1626
1579 // When using ":set opt=val" for a global option 1627 // When using ":set opt=val" for a global option
1580 // with a local value the local value will be 1628 // with a local value the local value will be
1809 // and when adding to avoid duplicates 1857 // and when adding to avoid duplicates
1810 i = 0; // init for GCC 1858 i = 0; // init for GCC
1811 if (removing || (flags & P_NODUP)) 1859 if (removing || (flags & P_NODUP))
1812 { 1860 {
1813 i = (int)STRLEN(newval); 1861 i = (int)STRLEN(newval);
1814 bs = 0; 1862 s = find_dup_item(origval, newval, flags);
1815 for (s = origval; *s; ++s)
1816 {
1817 if ((!(flags & P_COMMA)
1818 || s == origval
1819 || (s[-1] == ',' && !(bs & 1)))
1820 && STRNCMP(s, newval, i) == 0
1821 && (!(flags & P_COMMA)
1822 || s[i] == ','
1823 || s[i] == NUL))
1824 break;
1825 // Count backslashes. Only a comma with an
1826 // even number of backslashes or a single
1827 // backslash preceded by a comma before it
1828 // is recognized as a separator
1829 if ((s > origval + 1
1830 && s[-1] == '\\'
1831 && s[-2] != ',')
1832 || (s == origval + 1
1833 && s[-1] == '\\'))
1834
1835 ++bs;
1836 else
1837 bs = 0;
1838 }
1839 1863
1840 // do not add if already there 1864 // do not add if already there
1841 if ((adding || prepending) && *s) 1865 if ((adding || prepending) && s != NULL)
1842 { 1866 {
1843 prepending = FALSE; 1867 prepending = FALSE;
1844 adding = FALSE; 1868 adding = FALSE;
1845 STRCPY(newval, origval); 1869 STRCPY(newval, origval);
1846 } 1870 }
1871
1872 // if no duplicate, move pointer to end of
1873 // original value
1874 if (s == NULL)
1875 s = origval + (int)STRLEN(origval);
1847 } 1876 }
1848 1877
1849 // concatenate the two strings; add a ',' if 1878 // concatenate the two strings; add a ',' if
1850 // needed 1879 // needed
1851 if (adding || prepending) 1880 if (adding || prepending)