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;
 }