mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
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>
This commit is contained in:
committed by
Christian Brabandt
parent
142cad1f88
commit
5e7a6a4a10
234
src/charset.c
234
src/charset.c
@@ -13,6 +13,7 @@
|
||||
# include <wchar.h> // for towupper() and towlower()
|
||||
#endif
|
||||
|
||||
static int parse_isopt(char_u *var, buf_T *buf, int only_check);
|
||||
static int win_nolbr_chartabsize(chartabsize_T *cts, int *headp);
|
||||
static unsigned nr2hex(unsigned c);
|
||||
|
||||
@@ -75,11 +76,8 @@ buf_init_chartab(
|
||||
int global) // FALSE: only set buf->b_chartab[]
|
||||
{
|
||||
int c;
|
||||
int c2;
|
||||
char_u *p;
|
||||
int i;
|
||||
int tilde;
|
||||
int do_isalpha;
|
||||
|
||||
if (global)
|
||||
{
|
||||
@@ -135,9 +133,7 @@ buf_init_chartab(
|
||||
if (buf->b_p_lisp)
|
||||
SET_CHARTAB(buf, '-');
|
||||
|
||||
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
|
||||
// options Each option is a list of characters, character numbers or
|
||||
// ranges, separated by commas, e.g.: "200-210,x,#-178,-"
|
||||
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint' options.
|
||||
for (i = global ? 0 : 3; i <= 3; ++i)
|
||||
{
|
||||
if (i == 0)
|
||||
@@ -149,114 +145,152 @@ buf_init_chartab(
|
||||
else // i == 3
|
||||
p = buf->b_p_isk; // fourth round: 'iskeyword'
|
||||
|
||||
while (*p)
|
||||
{
|
||||
tilde = FALSE;
|
||||
do_isalpha = FALSE;
|
||||
if (*p == '^' && p[1] != NUL)
|
||||
{
|
||||
tilde = TRUE;
|
||||
++p;
|
||||
}
|
||||
if (VIM_ISDIGIT(*p))
|
||||
c = getdigits(&p);
|
||||
else if (has_mbyte)
|
||||
c = mb_ptr2char_adv(&p);
|
||||
else
|
||||
c = *p++;
|
||||
c2 = -1;
|
||||
if (*p == '-' && p[1] != NUL)
|
||||
{
|
||||
++p;
|
||||
if (VIM_ISDIGIT(*p))
|
||||
c2 = getdigits(&p);
|
||||
else if (has_mbyte)
|
||||
c2 = mb_ptr2char_adv(&p);
|
||||
else
|
||||
c2 = *p++;
|
||||
}
|
||||
if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256
|
||||
|| !(*p == NUL || *p == ','))
|
||||
return FAIL;
|
||||
if (parse_isopt(p, buf, FALSE) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (c2 == -1) // not a range
|
||||
chartab_initialized = TRUE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the format for the option settings 'iskeyword', 'isident', 'isfname'
|
||||
* or 'isprint'.
|
||||
* Returns FAIL if has an error, OK otherwise.
|
||||
*/
|
||||
int
|
||||
check_isopt(char_u *var)
|
||||
{
|
||||
return parse_isopt(var, NULL, TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_isopt(
|
||||
char_u *var,
|
||||
buf_T *buf,
|
||||
int only_check) // FALSE: refill g_chartab[]
|
||||
{
|
||||
char_u *p = var;
|
||||
int c;
|
||||
int c2;
|
||||
int tilde;
|
||||
int do_isalpha;
|
||||
int trail_comma;
|
||||
|
||||
// Parses the 'isident', 'iskeyword', 'isfname' and 'isprint' options.
|
||||
// Each option is a list of characters, character numbers or ranges,
|
||||
// separated by commas, e.g.: "200-210,x,#-178,-"
|
||||
while (*p)
|
||||
{
|
||||
tilde = FALSE;
|
||||
do_isalpha = FALSE;
|
||||
if (*p == '^' && p[1] != NUL)
|
||||
{
|
||||
tilde = TRUE;
|
||||
++p;
|
||||
}
|
||||
if (VIM_ISDIGIT(*p))
|
||||
c = getdigits(&p);
|
||||
else if (has_mbyte)
|
||||
c = mb_ptr2char_adv(&p);
|
||||
else
|
||||
c = *p++;
|
||||
c2 = -1;
|
||||
if (*p == '-' && p[1] != NUL)
|
||||
{
|
||||
++p;
|
||||
if (VIM_ISDIGIT(*p))
|
||||
c2 = getdigits(&p);
|
||||
else if (has_mbyte)
|
||||
c2 = mb_ptr2char_adv(&p);
|
||||
else
|
||||
c2 = *p++;
|
||||
}
|
||||
if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256
|
||||
|| !(*p == NUL || *p == ','))
|
||||
return FAIL;
|
||||
|
||||
trail_comma = *p == ',';
|
||||
p = skip_to_option_part(p);
|
||||
if (trail_comma && *p == NUL)
|
||||
// Trailing comma is not allowed.
|
||||
return FAIL;
|
||||
|
||||
if (only_check)
|
||||
continue;
|
||||
|
||||
if (c2 == -1) // not a range
|
||||
{
|
||||
/*
|
||||
* A single '@' (not "@-@"):
|
||||
* Decide on letters being ID/printable/keyword chars with
|
||||
* standard function isalpha(). This takes care of locale for
|
||||
* single-byte characters).
|
||||
*/
|
||||
if (c == '@')
|
||||
{
|
||||
/*
|
||||
* A single '@' (not "@-@"):
|
||||
* Decide on letters being ID/printable/keyword chars with
|
||||
* standard function isalpha(). This takes care of locale for
|
||||
* single-byte characters).
|
||||
*/
|
||||
if (c == '@')
|
||||
{
|
||||
do_isalpha = TRUE;
|
||||
c = 1;
|
||||
c2 = 255;
|
||||
}
|
||||
else
|
||||
c2 = c;
|
||||
do_isalpha = TRUE;
|
||||
c = 1;
|
||||
c2 = 255;
|
||||
}
|
||||
while (c <= c2)
|
||||
else
|
||||
c2 = c;
|
||||
}
|
||||
|
||||
while (c <= c2)
|
||||
{
|
||||
// Use the MB_ functions here, because isalpha() doesn't
|
||||
// work properly when 'encoding' is "latin1" and the locale is
|
||||
// "C".
|
||||
if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c))
|
||||
{
|
||||
// Use the MB_ functions here, because isalpha() doesn't
|
||||
// work properly when 'encoding' is "latin1" and the locale is
|
||||
// "C".
|
||||
if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c))
|
||||
if (var == p_isi) // (re)set ID flag
|
||||
{
|
||||
if (i == 0) // (re)set ID flag
|
||||
if (tilde)
|
||||
g_chartab[c] &= ~CT_ID_CHAR;
|
||||
else
|
||||
g_chartab[c] |= CT_ID_CHAR;
|
||||
}
|
||||
else if (var == p_isp) // (re)set printable
|
||||
{
|
||||
if ((c < ' ' || c > '~'
|
||||
// For double-byte we keep the cell width, so
|
||||
// that we can detect it from the first byte.
|
||||
) && !(enc_dbcs && MB_BYTE2LEN(c) == 2))
|
||||
{
|
||||
if (tilde)
|
||||
g_chartab[c] &= ~CT_ID_CHAR;
|
||||
else
|
||||
g_chartab[c] |= CT_ID_CHAR;
|
||||
}
|
||||
else if (i == 1) // (re)set printable
|
||||
{
|
||||
if ((c < ' ' || c > '~'
|
||||
// For double-byte we keep the cell width, so
|
||||
// that we can detect it from the first byte.
|
||||
) && !(enc_dbcs && MB_BYTE2LEN(c) == 2))
|
||||
{
|
||||
if (tilde)
|
||||
{
|
||||
g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK)
|
||||
+ ((dy_flags & DY_UHEX) ? 4 : 2);
|
||||
g_chartab[c] &= ~CT_PRINT_CHAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK)
|
||||
+ 1;
|
||||
g_chartab[c] |= CT_PRINT_CHAR;
|
||||
}
|
||||
g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK)
|
||||
+ ((dy_flags & DY_UHEX) ? 4 : 2);
|
||||
g_chartab[c] &= ~CT_PRINT_CHAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK) + 1;
|
||||
g_chartab[c] |= CT_PRINT_CHAR;
|
||||
}
|
||||
}
|
||||
else if (i == 2) // (re)set fname flag
|
||||
{
|
||||
if (tilde)
|
||||
g_chartab[c] &= ~CT_FNAME_CHAR;
|
||||
else
|
||||
g_chartab[c] |= CT_FNAME_CHAR;
|
||||
}
|
||||
else // i == 3 (re)set keyword flag
|
||||
{
|
||||
if (tilde)
|
||||
RESET_CHARTAB(buf, c);
|
||||
else
|
||||
SET_CHARTAB(buf, c);
|
||||
}
|
||||
}
|
||||
++c;
|
||||
else if (var == p_isf) // (re)set fname flag
|
||||
{
|
||||
if (tilde)
|
||||
g_chartab[c] &= ~CT_FNAME_CHAR;
|
||||
else
|
||||
g_chartab[c] |= CT_FNAME_CHAR;
|
||||
}
|
||||
else // var == p_isk || var == buf->b_p_isk
|
||||
// (re)set keyword flag
|
||||
{
|
||||
if (tilde)
|
||||
RESET_CHARTAB(buf, c);
|
||||
else
|
||||
SET_CHARTAB(buf, c);
|
||||
}
|
||||
}
|
||||
|
||||
c = *p;
|
||||
p = skip_to_option_part(p);
|
||||
if (c == ',' && *p == NUL)
|
||||
// Trailing comma is not allowed.
|
||||
return FAIL;
|
||||
++c;
|
||||
}
|
||||
}
|
||||
chartab_initialized = TRUE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@@ -1456,7 +1456,7 @@ static struct vimoption options[] =
|
||||
#endif
|
||||
(char_u *)0L} SCTX_INIT},
|
||||
{"iskeyword", "isk", P_STRING|P_ALLOCED|P_VIM|P_COMMA|P_NODUP,
|
||||
(char_u *)&p_isk, PV_ISK, did_set_isopt, NULL,
|
||||
(char_u *)&p_isk, PV_ISK, did_set_iskeyword, NULL,
|
||||
{
|
||||
(char_u *)"@,48-57,_",
|
||||
#if defined(MSWIN)
|
||||
|
@@ -2774,6 +2774,25 @@ did_set_imactivatekey(optset_T *args UNUSED)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The 'iskeyword' option is changed.
|
||||
*/
|
||||
char *
|
||||
did_set_iskeyword(optset_T *args)
|
||||
{
|
||||
char_u **varp = (char_u **)args->os_varp;
|
||||
|
||||
if (varp == &p_isk) // only check for global-value
|
||||
{
|
||||
if (check_isopt(*varp) == FAIL)
|
||||
return e_invalid_argument;
|
||||
}
|
||||
else // fallthrough for local-value
|
||||
return did_set_isopt(args);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The 'isident' or the 'iskeyword' or the 'isprint' or the 'isfname' option is
|
||||
* changed.
|
||||
@@ -2781,7 +2800,7 @@ did_set_imactivatekey(optset_T *args UNUSED)
|
||||
char *
|
||||
did_set_isopt(optset_T *args)
|
||||
{
|
||||
// 'isident', 'iskeyword', 'isprint or 'isfname' option: refill g_chartab[]
|
||||
// 'isident', 'iskeyword', 'isprint' or 'isfname' option: refill g_chartab[]
|
||||
// If the new option is invalid, use old value.
|
||||
// 'lisp' option: refill g_chartab[] for '-' char.
|
||||
if (init_chartab() == FAIL)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/* charset.c */
|
||||
int init_chartab(void);
|
||||
int buf_init_chartab(buf_T *buf, int global);
|
||||
int check_isopt(char_u *isopt);
|
||||
void trans_characters(char_u *buf, int bufsize);
|
||||
char_u *transstr(char_u *s);
|
||||
char_u *str_foldcase(char_u *str, int orglen, char_u *buf, int buflen);
|
||||
|
@@ -99,6 +99,7 @@ char *did_set_highlight(optset_T *args);
|
||||
int expand_set_highlight(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||
char *did_set_iconstring(optset_T *args);
|
||||
char *did_set_imactivatekey(optset_T *args);
|
||||
char *did_set_iskeyword(optset_T *args);
|
||||
char *did_set_isopt(optset_T *args);
|
||||
char *did_set_jumpoptions(optset_T *args);
|
||||
int expand_set_jumpoptions(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||
|
@@ -49,7 +49,6 @@ let skip_setglobal_reasons = #{
|
||||
\ colorcolumn: 'TODO: fix missing error handling for setglobal',
|
||||
\ conceallevel: 'TODO: fix missing error handling for setglobal',
|
||||
\ foldcolumn: 'TODO: fix missing error handling for setglobal',
|
||||
\ iskeyword: 'TODO: fix missing error handling for setglobal',
|
||||
\ numberwidth: 'TODO: fix missing error handling for setglobal',
|
||||
\ scrolloff: 'TODO: fix missing error handling for setglobal',
|
||||
\ shiftwidth: 'TODO: fix missing error handling for setglobal',
|
||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
803,
|
||||
/**/
|
||||
802,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user