1313# include <wchar.h> // for towupper() and towlower()
1414#endif
1515
16+ static int parse_isopt (char_u * var , buf_T * buf , int only_check );
1617static int win_nolbr_chartabsize (chartabsize_T * cts , int * headp );
1718static unsigned nr2hex (unsigned c );
1819
@@ -75,11 +76,8 @@ buf_init_chartab(
7576 int global ) // FALSE: only set buf->b_chartab[]
7677{
7778 int c ;
78- int c2 ;
7979 char_u * p ;
8080 int i ;
81- int tilde ;
82- int do_isalpha ;
8381
8482 if (global )
8583 {
@@ -135,9 +133,7 @@ buf_init_chartab(
135133 if (buf -> b_p_lisp )
136134 SET_CHARTAB (buf , '-' );
137135
138- // Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
139- // options Each option is a list of characters, character numbers or
140- // ranges, separated by commas, e.g.: "200-210,x,#-178,-"
136+ // Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint' options.
141137 for (i = global ? 0 : 3 ; i <= 3 ; ++ i )
142138 {
143139 if (i == 0 )
@@ -149,114 +145,152 @@ buf_init_chartab(
149145 else // i == 3
150146 p = buf -> b_p_isk ; // fourth round: 'iskeyword'
151147
152- while (* p )
148+ if (parse_isopt (p , buf , FALSE) == FAIL )
149+ return FAIL ;
150+ }
151+
152+ chartab_initialized = TRUE;
153+ return OK ;
154+ }
155+
156+ /**
157+ * Checks the format for the option settings 'iskeyword', 'isident', 'isfname'
158+ * or 'isprint'.
159+ * Returns FAIL if has an error, OK otherwise.
160+ */
161+ int
162+ check_isopt (char_u * var )
163+ {
164+ return parse_isopt (var , NULL , TRUE);
165+ }
166+
167+ static int
168+ parse_isopt (
169+ char_u * var ,
170+ buf_T * buf ,
171+ int only_check ) // FALSE: refill g_chartab[]
172+ {
173+ char_u * p = var ;
174+ int c ;
175+ int c2 ;
176+ int tilde ;
177+ int do_isalpha ;
178+ int trail_comma ;
179+
180+ // Parses the 'isident', 'iskeyword', 'isfname' and 'isprint' options.
181+ // Each option is a list of characters, character numbers or ranges,
182+ // separated by commas, e.g.: "200-210,x,#-178,-"
183+ while (* p )
184+ {
185+ tilde = FALSE;
186+ do_isalpha = FALSE;
187+ if (* p == '^' && p [1 ] != NUL )
153188 {
154- tilde = FALSE;
155- do_isalpha = FALSE;
156- if (* p == '^' && p [1 ] != NUL )
157- {
158- tilde = TRUE;
159- ++ p ;
160- }
189+ tilde = TRUE;
190+ ++ p ;
191+ }
192+ if (VIM_ISDIGIT (* p ))
193+ c = getdigits (& p );
194+ else if (has_mbyte )
195+ c = mb_ptr2char_adv (& p );
196+ else
197+ c = * p ++ ;
198+ c2 = -1 ;
199+ if (* p == '-' && p [1 ] != NUL )
200+ {
201+ ++ p ;
161202 if (VIM_ISDIGIT (* p ))
162- c = getdigits (& p );
203+ c2 = getdigits (& p );
163204 else if (has_mbyte )
164- c = mb_ptr2char_adv (& p );
205+ c2 = mb_ptr2char_adv (& p );
165206 else
166- c = * p ++ ;
167- c2 = -1 ;
168- if (* p == '-' && p [1 ] != NUL )
207+ c2 = * p ++ ;
208+ }
209+ if (c <= 0 || c >= 256 || (c2 < c && c2 != -1 ) || c2 >= 256
210+ || !(* p == NUL || * p == ',' ))
211+ return FAIL ;
212+
213+ trail_comma = * p == ',' ;
214+ p = skip_to_option_part (p );
215+ if (trail_comma && * p == NUL )
216+ // Trailing comma is not allowed.
217+ return FAIL ;
218+
219+ if (only_check )
220+ continue ;
221+
222+ if (c2 == -1 ) // not a range
223+ {
224+ /*
225+ * A single '@' (not "@-@"):
226+ * Decide on letters being ID/printable/keyword chars with
227+ * standard function isalpha(). This takes care of locale for
228+ * single-byte characters).
229+ */
230+ if (c == '@' )
169231 {
170- ++ p ;
171- if (VIM_ISDIGIT (* p ))
172- c2 = getdigits (& p );
173- else if (has_mbyte )
174- c2 = mb_ptr2char_adv (& p );
175- else
176- c2 = * p ++ ;
232+ do_isalpha = TRUE;
233+ c = 1 ;
234+ c2 = 255 ;
177235 }
178- if ( c <= 0 || c >= 256 || ( c2 < c && c2 != -1 ) || c2 >= 256
179- || !( * p == NUL || * p == ',' ))
180- return FAIL ;
236+ else
237+ c2 = c ;
238+ }
181239
182- if (c2 == -1 ) // not a range
240+ while (c <= c2 )
241+ {
242+ // Use the MB_ functions here, because isalpha() doesn't
243+ // work properly when 'encoding' is "latin1" and the locale is
244+ // "C".
245+ if (!do_isalpha || MB_ISLOWER (c ) || MB_ISUPPER (c ))
183246 {
184- /*
185- * A single '@' (not "@-@"):
186- * Decide on letters being ID/printable/keyword chars with
187- * standard function isalpha(). This takes care of locale for
188- * single-byte characters).
189- */
190- if (c == '@' )
247+ if (var == p_isi ) // (re)set ID flag
191248 {
192- do_isalpha = TRUE;
193- c = 1 ;
194- c2 = 255 ;
249+ if (tilde )
250+ g_chartab [c ] &= ~CT_ID_CHAR ;
251+ else
252+ g_chartab [c ] |= CT_ID_CHAR ;
195253 }
196- else
197- c2 = c ;
198- }
199- while (c <= c2 )
200- {
201- // Use the MB_ functions here, because isalpha() doesn't
202- // work properly when 'encoding' is "latin1" and the locale is
203- // "C".
204- if (!do_isalpha || MB_ISLOWER (c ) || MB_ISUPPER (c ))
254+ else if (var == p_isp ) // (re)set printable
205255 {
206- if (i == 0 ) // (re)set ID flag
256+ if ((c < ' ' || c > '~'
257+ // For double-byte we keep the cell width, so
258+ // that we can detect it from the first byte.
259+ ) && !(enc_dbcs && MB_BYTE2LEN (c ) == 2 ))
207260 {
208261 if (tilde )
209- g_chartab [c ] &= ~CT_ID_CHAR ;
210- else
211- g_chartab [c ] |= CT_ID_CHAR ;
212- }
213- else if (i == 1 ) // (re)set printable
214- {
215- if ((c < ' ' || c > '~'
216- // For double-byte we keep the cell width, so
217- // that we can detect it from the first byte.
218- ) && !(enc_dbcs && MB_BYTE2LEN (c ) == 2 ))
219262 {
220- if (tilde )
221- {
222- g_chartab [c ] = (g_chartab [c ] & ~CT_CELL_MASK )
223- + ((dy_flags & DY_UHEX ) ? 4 : 2 );
224- g_chartab [c ] &= ~CT_PRINT_CHAR ;
225- }
226- else
227- {
228- g_chartab [c ] = (g_chartab [c ] & ~CT_CELL_MASK )
229- + 1 ;
230- g_chartab [c ] |= CT_PRINT_CHAR ;
231- }
263+ g_chartab [c ] = (g_chartab [c ] & ~CT_CELL_MASK )
264+ + ((dy_flags & DY_UHEX ) ? 4 : 2 );
265+ g_chartab [c ] &= ~CT_PRINT_CHAR ;
232266 }
233- }
234- else if (i == 2 ) // (re)set fname flag
235- {
236- if (tilde )
237- g_chartab [c ] &= ~CT_FNAME_CHAR ;
238- else
239- g_chartab [c ] |= CT_FNAME_CHAR ;
240- }
241- else // i == 3 (re)set keyword flag
242- {
243- if (tilde )
244- RESET_CHARTAB (buf , c );
245267 else
246- SET_CHARTAB (buf , c );
268+ {
269+ g_chartab [c ] = (g_chartab [c ] & ~CT_CELL_MASK ) + 1 ;
270+ g_chartab [c ] |= CT_PRINT_CHAR ;
271+ }
247272 }
248273 }
249- ++ c ;
274+ else if (var == p_isf ) // (re)set fname flag
275+ {
276+ if (tilde )
277+ g_chartab [c ] &= ~CT_FNAME_CHAR ;
278+ else
279+ g_chartab [c ] |= CT_FNAME_CHAR ;
280+ }
281+ else // var == p_isk || var == buf->b_p_isk
282+ // (re)set keyword flag
283+ {
284+ if (tilde )
285+ RESET_CHARTAB (buf , c );
286+ else
287+ SET_CHARTAB (buf , c );
288+ }
250289 }
251-
252- c = * p ;
253- p = skip_to_option_part (p );
254- if (c == ',' && * p == NUL )
255- // Trailing comma is not allowed.
256- return FAIL ;
290+ ++ c ;
257291 }
258292 }
259- chartab_initialized = TRUE;
293+
260294 return OK ;
261295}
262296
0 commit comments