Skip to content

Commit 5e7a6a4

Browse files
Millychrisbra
authored andcommitted
patch 9.1.0803: tests: no error check when setting global 'isk'
Problem: tests: no error check when setting global 'isk' Solution: also parse and check global 'isk' value (Milly) closes: #15915 Signed-off-by: Milly <milly.ca@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent 142cad1 commit 5e7a6a4

7 files changed

Lines changed: 152 additions & 96 deletions

File tree

src/charset.c

Lines changed: 127 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# include <wchar.h> // for towupper() and towlower()
1414
#endif
1515

16+
static int parse_isopt(char_u *var, buf_T *buf, int only_check);
1617
static int win_nolbr_chartabsize(chartabsize_T *cts, int *headp);
1718
static unsigned nr2hex(unsigned c);
1819

@@ -75,11 +76,8 @@ buf_init_chartab(
7576
int global) // FALSE: only set buf->b_chartab[]
7677
{
7778
int c;
78-
int c2;
7979
char_u *p;
8080
int i;
81-
int tilde;
82-
int do_isalpha;
8381

8482
if (global)
8583
{
@@ -135,9 +133,7 @@ buf_init_chartab(
135133
if (buf->b_p_lisp)
136134
SET_CHARTAB(buf, '-');
137135

138-
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
139-
// options Each option is a list of characters, character numbers or
140-
// ranges, separated by commas, e.g.: "200-210,x,#-178,-"
136+
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint' options.
141137
for (i = global ? 0 : 3; i <= 3; ++i)
142138
{
143139
if (i == 0)
@@ -149,114 +145,152 @@ buf_init_chartab(
149145
else // i == 3
150146
p = buf->b_p_isk; // fourth round: 'iskeyword'
151147

152-
while (*p)
148+
if (parse_isopt(p, buf, FALSE) == FAIL)
149+
return FAIL;
150+
}
151+
152+
chartab_initialized = TRUE;
153+
return OK;
154+
}
155+
156+
/**
157+
* Checks the format for the option settings 'iskeyword', 'isident', 'isfname'
158+
* or 'isprint'.
159+
* Returns FAIL if has an error, OK otherwise.
160+
*/
161+
int
162+
check_isopt(char_u *var)
163+
{
164+
return parse_isopt(var, NULL, TRUE);
165+
}
166+
167+
static int
168+
parse_isopt(
169+
char_u *var,
170+
buf_T *buf,
171+
int only_check) // FALSE: refill g_chartab[]
172+
{
173+
char_u *p = var;
174+
int c;
175+
int c2;
176+
int tilde;
177+
int do_isalpha;
178+
int trail_comma;
179+
180+
// Parses the 'isident', 'iskeyword', 'isfname' and 'isprint' options.
181+
// Each option is a list of characters, character numbers or ranges,
182+
// separated by commas, e.g.: "200-210,x,#-178,-"
183+
while (*p)
184+
{
185+
tilde = FALSE;
186+
do_isalpha = FALSE;
187+
if (*p == '^' && p[1] != NUL)
153188
{
154-
tilde = FALSE;
155-
do_isalpha = FALSE;
156-
if (*p == '^' && p[1] != NUL)
157-
{
158-
tilde = TRUE;
159-
++p;
160-
}
189+
tilde = TRUE;
190+
++p;
191+
}
192+
if (VIM_ISDIGIT(*p))
193+
c = getdigits(&p);
194+
else if (has_mbyte)
195+
c = mb_ptr2char_adv(&p);
196+
else
197+
c = *p++;
198+
c2 = -1;
199+
if (*p == '-' && p[1] != NUL)
200+
{
201+
++p;
161202
if (VIM_ISDIGIT(*p))
162-
c = getdigits(&p);
203+
c2 = getdigits(&p);
163204
else if (has_mbyte)
164-
c = mb_ptr2char_adv(&p);
205+
c2 = mb_ptr2char_adv(&p);
165206
else
166-
c = *p++;
167-
c2 = -1;
168-
if (*p == '-' && p[1] != NUL)
207+
c2 = *p++;
208+
}
209+
if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256
210+
|| !(*p == NUL || *p == ','))
211+
return FAIL;
212+
213+
trail_comma = *p == ',';
214+
p = skip_to_option_part(p);
215+
if (trail_comma && *p == NUL)
216+
// Trailing comma is not allowed.
217+
return FAIL;
218+
219+
if (only_check)
220+
continue;
221+
222+
if (c2 == -1) // not a range
223+
{
224+
/*
225+
* A single '@' (not "@-@"):
226+
* Decide on letters being ID/printable/keyword chars with
227+
* standard function isalpha(). This takes care of locale for
228+
* single-byte characters).
229+
*/
230+
if (c == '@')
169231
{
170-
++p;
171-
if (VIM_ISDIGIT(*p))
172-
c2 = getdigits(&p);
173-
else if (has_mbyte)
174-
c2 = mb_ptr2char_adv(&p);
175-
else
176-
c2 = *p++;
232+
do_isalpha = TRUE;
233+
c = 1;
234+
c2 = 255;
177235
}
178-
if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256
179-
|| !(*p == NUL || *p == ','))
180-
return FAIL;
236+
else
237+
c2 = c;
238+
}
181239

182-
if (c2 == -1) // not a range
240+
while (c <= c2)
241+
{
242+
// Use the MB_ functions here, because isalpha() doesn't
243+
// work properly when 'encoding' is "latin1" and the locale is
244+
// "C".
245+
if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c))
183246
{
184-
/*
185-
* A single '@' (not "@-@"):
186-
* Decide on letters being ID/printable/keyword chars with
187-
* standard function isalpha(). This takes care of locale for
188-
* single-byte characters).
189-
*/
190-
if (c == '@')
247+
if (var == p_isi) // (re)set ID flag
191248
{
192-
do_isalpha = TRUE;
193-
c = 1;
194-
c2 = 255;
249+
if (tilde)
250+
g_chartab[c] &= ~CT_ID_CHAR;
251+
else
252+
g_chartab[c] |= CT_ID_CHAR;
195253
}
196-
else
197-
c2 = c;
198-
}
199-
while (c <= c2)
200-
{
201-
// Use the MB_ functions here, because isalpha() doesn't
202-
// work properly when 'encoding' is "latin1" and the locale is
203-
// "C".
204-
if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c))
254+
else if (var == p_isp) // (re)set printable
205255
{
206-
if (i == 0) // (re)set ID flag
256+
if ((c < ' ' || c > '~'
257+
// For double-byte we keep the cell width, so
258+
// that we can detect it from the first byte.
259+
) && !(enc_dbcs && MB_BYTE2LEN(c) == 2))
207260
{
208261
if (tilde)
209-
g_chartab[c] &= ~CT_ID_CHAR;
210-
else
211-
g_chartab[c] |= CT_ID_CHAR;
212-
}
213-
else if (i == 1) // (re)set printable
214-
{
215-
if ((c < ' ' || c > '~'
216-
// For double-byte we keep the cell width, so
217-
// that we can detect it from the first byte.
218-
) && !(enc_dbcs && MB_BYTE2LEN(c) == 2))
219262
{
220-
if (tilde)
221-
{
222-
g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK)
223-
+ ((dy_flags & DY_UHEX) ? 4 : 2);
224-
g_chartab[c] &= ~CT_PRINT_CHAR;
225-
}
226-
else
227-
{
228-
g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK)
229-
+ 1;
230-
g_chartab[c] |= CT_PRINT_CHAR;
231-
}
263+
g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK)
264+
+ ((dy_flags & DY_UHEX) ? 4 : 2);
265+
g_chartab[c] &= ~CT_PRINT_CHAR;
232266
}
233-
}
234-
else if (i == 2) // (re)set fname flag
235-
{
236-
if (tilde)
237-
g_chartab[c] &= ~CT_FNAME_CHAR;
238-
else
239-
g_chartab[c] |= CT_FNAME_CHAR;
240-
}
241-
else // i == 3 (re)set keyword flag
242-
{
243-
if (tilde)
244-
RESET_CHARTAB(buf, c);
245267
else
246-
SET_CHARTAB(buf, c);
268+
{
269+
g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK) + 1;
270+
g_chartab[c] |= CT_PRINT_CHAR;
271+
}
247272
}
248273
}
249-
++c;
274+
else if (var == p_isf) // (re)set fname flag
275+
{
276+
if (tilde)
277+
g_chartab[c] &= ~CT_FNAME_CHAR;
278+
else
279+
g_chartab[c] |= CT_FNAME_CHAR;
280+
}
281+
else // var == p_isk || var == buf->b_p_isk
282+
// (re)set keyword flag
283+
{
284+
if (tilde)
285+
RESET_CHARTAB(buf, c);
286+
else
287+
SET_CHARTAB(buf, c);
288+
}
250289
}
251-
252-
c = *p;
253-
p = skip_to_option_part(p);
254-
if (c == ',' && *p == NUL)
255-
// Trailing comma is not allowed.
256-
return FAIL;
290+
++c;
257291
}
258292
}
259-
chartab_initialized = TRUE;
293+
260294
return OK;
261295
}
262296

src/optiondefs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ static struct vimoption options[] =
14561456
#endif
14571457
(char_u *)0L} SCTX_INIT},
14581458
{"iskeyword", "isk", P_STRING|P_ALLOCED|P_VIM|P_COMMA|P_NODUP,
1459-
(char_u *)&p_isk, PV_ISK, did_set_isopt, NULL,
1459+
(char_u *)&p_isk, PV_ISK, did_set_iskeyword, NULL,
14601460
{
14611461
(char_u *)"@,48-57,_",
14621462
#if defined(MSWIN)

src/optionstr.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2774,14 +2774,33 @@ did_set_imactivatekey(optset_T *args UNUSED)
27742774
}
27752775
#endif
27762776

2777+
/*
2778+
* The 'iskeyword' option is changed.
2779+
*/
2780+
char *
2781+
did_set_iskeyword(optset_T *args)
2782+
{
2783+
char_u **varp = (char_u **)args->os_varp;
2784+
2785+
if (varp == &p_isk) // only check for global-value
2786+
{
2787+
if (check_isopt(*varp) == FAIL)
2788+
return e_invalid_argument;
2789+
}
2790+
else // fallthrough for local-value
2791+
return did_set_isopt(args);
2792+
2793+
return NULL;
2794+
}
2795+
27772796
/*
27782797
* The 'isident' or the 'iskeyword' or the 'isprint' or the 'isfname' option is
27792798
* changed.
27802799
*/
27812800
char *
27822801
did_set_isopt(optset_T *args)
27832802
{
2784-
// 'isident', 'iskeyword', 'isprint or 'isfname' option: refill g_chartab[]
2803+
// 'isident', 'iskeyword', 'isprint' or 'isfname' option: refill g_chartab[]
27852804
// If the new option is invalid, use old value.
27862805
// 'lisp' option: refill g_chartab[] for '-' char.
27872806
if (init_chartab() == FAIL)

src/proto/charset.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* charset.c */
22
int init_chartab(void);
33
int buf_init_chartab(buf_T *buf, int global);
4+
int check_isopt(char_u *isopt);
45
void trans_characters(char_u *buf, int bufsize);
56
char_u *transstr(char_u *s);
67
char_u *str_foldcase(char_u *str, int orglen, char_u *buf, int buflen);

src/proto/optionstr.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ char *did_set_highlight(optset_T *args);
9999
int expand_set_highlight(optexpand_T *args, int *numMatches, char_u ***matches);
100100
char *did_set_iconstring(optset_T *args);
101101
char *did_set_imactivatekey(optset_T *args);
102+
char *did_set_iskeyword(optset_T *args);
102103
char *did_set_isopt(optset_T *args);
103104
char *did_set_jumpoptions(optset_T *args);
104105
int expand_set_jumpoptions(optexpand_T *args, int *numMatches, char_u ***matches);

src/testdir/gen_opt_test.vim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ let skip_setglobal_reasons = #{
4949
\ colorcolumn: 'TODO: fix missing error handling for setglobal',
5050
\ conceallevel: 'TODO: fix missing error handling for setglobal',
5151
\ foldcolumn: 'TODO: fix missing error handling for setglobal',
52-
\ iskeyword: 'TODO: fix missing error handling for setglobal',
5352
\ numberwidth: 'TODO: fix missing error handling for setglobal',
5453
\ scrolloff: 'TODO: fix missing error handling for setglobal',
5554
\ shiftwidth: 'TODO: fix missing error handling for setglobal',

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ static char *(features[]) =
704704

705705
static int included_patches[] =
706706
{ /* Add new patch number below this line */
707+
/**/
708+
803,
707709
/**/
708710
802,
709711
/**/

0 commit comments

Comments
 (0)