Mercurial > vim
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) |