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>
diff --git a/src/charset.c b/src/charset.c
index e02f719..b4bc812 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 @@
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 @@
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 @@
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;
}