patch 9.1.0803: tests: no error check when setting global 'isk' Commit: https://github.com/vim/vim/commit/5e7a6a4a106923e45c67dae6810e4c9753f88025 Author: Milly <milly...@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...@gmail.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/charset.c b/src/charset.c index e02f719c1..b4bc812fa 100644 --- 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 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); + { + g_chartab[c] = (g_chartab[c] & ~CT_CELL_MASK) + 1; + g_chartab[c] |= CT_PRINT_CHAR; + } } } - ++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; } diff --git a/src/optiondefs.h b/src/optiondefs.h index 4a5bd638c..42e62e7d2 100644 --- 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) diff --git a/src/optionstr.c b/src/optionstr.c index 50adc48d1..2049633f8 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -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) diff --git a/src/proto/charset.pro b/src/proto/charset.pro index 2f6407783..54af280e9 100644 --- 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); diff --git a/src/proto/optionstr.pro b/src/proto/optionstr.pro index c034c1192..561faa86c 100644 --- 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); diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim index 83abadf1e..120ea9b18 100644 --- 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', diff --git a/src/version.c b/src/version.c index 4184b5528..b26e848c0 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 803, /**/ 802, /**/ -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/vim_dev/E1t3LVz-000Nyh-AK%40256bit.org.