Mercurial > vim
changeset 36366:c57c92a46534 draft v9.1.0803
patch 9.1.0803: tests: no error check when setting global 'isk'
Commit: https://github.com/vim/vim/commit/5e7a6a4a106923e45c67dae6810e4c9753f88025
Author: Milly <milly.ca@gmail.com>
Date: Tue Oct 22 22:27:19 2024 +0200
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>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 22 Oct 2024 22:30:03 +0200 |
parents | fc26d11e435f |
children | 5bc2cab29bfd |
files | src/charset.c src/optiondefs.h src/optionstr.c src/proto/charset.pro src/proto/optionstr.pro src/testdir/gen_opt_test.vim src/version.c |
diffstat | 7 files changed, 153 insertions(+), 97 deletions(-) [+] |
line wrap: on
line diff
--- a/src/charset.c +++ b/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) + if (parse_isopt(p, buf, FALSE) == FAIL) + return FAIL; + } + + 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 = FALSE; - do_isalpha = FALSE; - if (*p == '^' && p[1] != NUL) - { - tilde = TRUE; - ++p; - } + 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)) - c = getdigits(&p); + c2 = getdigits(&p); else if (has_mbyte) - c = mb_ptr2char_adv(&p); + c2 = mb_ptr2char_adv(&p); else - c = *p++; - c2 = -1; - if (*p == '-' && p[1] != NUL) + 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 == '@') { - ++p; - if (VIM_ISDIGIT(*p)) - c2 = getdigits(&p); - else if (has_mbyte) - c2 = mb_ptr2char_adv(&p); - else - c2 = *p++; + do_isalpha = TRUE; + c = 1; + c2 = 255; } - if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256 - || !(*p == NUL || *p == ',')) - return FAIL; + else + c2 = c; + } - if (c2 == -1) // not a range + 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)) { - /* - * 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 == '@') + if (var == p_isi) // (re)set ID flag { - do_isalpha = TRUE; - c = 1; - c2 = 255; + if (tilde) + g_chartab[c] &= ~CT_ID_CHAR; + else + g_chartab[c] |= CT_ID_CHAR; } - 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)) + else if (var == p_isp) // (re)set printable { - if (i == 0) // (re)set ID flag + 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); - } + } + else if (var == p_isf) // (re)set fname flag + { + if (tilde) + g_chartab[c] &= ~CT_FNAME_CHAR; + else + g_chartab[c] |= CT_FNAME_CHAR; } - ++c; + 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; }
--- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -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)
--- a/src/optionstr.c +++ b/src/optionstr.c @@ -2775,13 +2775,32 @@ did_set_imactivatekey(optset_T *args UNU #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. */ 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)
--- a/src/proto/charset.pro +++ b/src/proto/charset.pro @@ -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);
--- a/src/proto/optionstr.pro +++ b/src/proto/optionstr.pro @@ -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);
--- a/src/testdir/gen_opt_test.vim +++ b/src/testdir/gen_opt_test.vim @@ -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',