comparison src/syntax.c @ 154:1a145815483e

updated for version 7.0047
author vimboss
date Wed, 02 Feb 2005 23:07:25 +0000
parents 72aefd4c1e0d
children 4d9eabb1396e
comparison
equal deleted inserted replaced
153:19670b05ee32 154:1a145815483e
292 } stateitem_T; 292 } stateitem_T;
293 293
294 #define KEYWORD_IDX -1 /* value of si_idx for keywords */ 294 #define KEYWORD_IDX -1 /* value of si_idx for keywords */
295 #define ID_LIST_ALL (short *)-1 /* valid of si_cont_list for containing all 295 #define ID_LIST_ALL (short *)-1 /* valid of si_cont_list for containing all
296 but contained groups */ 296 but contained groups */
297
298 /*
299 * Struct to reduce the number of arguments to get_syn_options(), it's used
300 * very often.
301 */
302 typedef struct
303 {
304 int flags; /* flags for contained and transpartent */
305 int keyword; /* TRUE for ":syn keyword" */
306 int *sync_idx; /* syntax item for "grouphere" argument, NULL
307 if not allowed */
308 char has_cont_list; /* TRUE if "cont_list" can be used */
309 short *cont_list; /* group IDs for "contains" argument */
310 short *cont_in_list; /* group IDs for "containedin" argument */
311 short *next_list; /* group IDs for "nextgroup" argument */
312 } syn_opt_arg_T;
297 313
298 /* 314 /*
299 * The next possible match in the current line for any pattern is remembered, 315 * The next possible match in the current line for any pattern is remembered,
300 * to avoid having to try for a match in each column. 316 * to avoid having to try for a match in each column.
301 * If next_match_idx == -1, not tried (in this line) yet. 317 * If next_match_idx == -1, not tried (in this line) yet.
399 static int syn_list_keywords __ARGS((int id, hashtab_T *ht, int did_header, int attr)); 415 static int syn_list_keywords __ARGS((int id, hashtab_T *ht, int did_header, int attr));
400 static void syn_clear_keyword __ARGS((int id, hashtab_T *ht)); 416 static void syn_clear_keyword __ARGS((int id, hashtab_T *ht));
401 static void clear_keywtab __ARGS((hashtab_T *ht)); 417 static void clear_keywtab __ARGS((hashtab_T *ht));
402 static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list)); 418 static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list));
403 static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end)); 419 static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end));
404 static char_u *get_syn_options __ARGS((char_u *arg, int *flagsp, int keyword, int *sync_idx, short **cont_list, short **cont_in_list, short **next_list)); 420 static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt));
405 static void syn_cmd_include __ARGS((exarg_T *eap, int syncing)); 421 static void syn_cmd_include __ARGS((exarg_T *eap, int syncing));
406 static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing)); 422 static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing));
407 static void syn_cmd_match __ARGS((exarg_T *eap, int syncing)); 423 static void syn_cmd_match __ARGS((exarg_T *eap, int syncing));
408 static void syn_cmd_region __ARGS((exarg_T *eap, int syncing)); 424 static void syn_cmd_region __ARGS((exarg_T *eap, int syncing));
409 #ifdef __BORLANDC__ 425 #ifdef __BORLANDC__
3976 short *next_list; /* nextgroup for this keyword */ 3992 short *next_list; /* nextgroup for this keyword */
3977 { 3993 {
3978 keyentry_T *kp; 3994 keyentry_T *kp;
3979 hashtab_T *ht; 3995 hashtab_T *ht;
3980 hashitem_T *hi; 3996 hashitem_T *hi;
3981 char_u *name_ic = name; 3997 char_u *name_ic;
3982 long_u hash; 3998 long_u hash;
3999 char_u name_folded[MAXKEYWLEN + 1];
3983 4000
3984 if (curbuf->b_syn_ic) 4001 if (curbuf->b_syn_ic)
3985 { 4002 name_ic = str_foldcase(name, (int)STRLEN(name),
3986 name_ic = str_foldcase(name, (int)STRLEN(name), NULL, 0); 4003 name_folded, MAXKEYWLEN + 1);
3987 if (name_ic == NULL) 4004 else
3988 name_ic = name; 4005 name_ic = name;
3989 }
3990 kp = (keyentry_T *)alloc((int)(sizeof(keyentry_T) + STRLEN(name_ic))); 4006 kp = (keyentry_T *)alloc((int)(sizeof(keyentry_T) + STRLEN(name_ic)));
3991 if (kp == NULL) 4007 if (kp == NULL)
3992 return; 4008 return;
3993 STRCPY(kp->keyword, name_ic); 4009 STRCPY(kp->keyword, name_ic);
3994 if (name_ic != name)
3995 vim_free(name_ic);
3996 kp->k_syn.id = id; 4010 kp->k_syn.id = id;
3997 kp->k_syn.inc_tag = current_syn_inc_tag; 4011 kp->k_syn.inc_tag = current_syn_inc_tag;
3998 kp->flags = flags; 4012 kp->flags = flags;
3999 kp->k_syn.cont_in_list = copy_id_list(cont_in_list); 4013 kp->k_syn.cont_in_list = copy_id_list(cont_in_list);
4000 if (cont_in_list != NULL) 4014 if (cont_in_list != NULL)
4053 * collect all options in between other arguments. 4067 * collect all options in between other arguments.
4054 * Return a pointer to the next argument (which isn't an option). 4068 * Return a pointer to the next argument (which isn't an option).
4055 * Return NULL for any error; 4069 * Return NULL for any error;
4056 */ 4070 */
4057 static char_u * 4071 static char_u *
4058 get_syn_options(arg, flagsp, keyword, sync_idx, cont_list, 4072 get_syn_options(arg, opt)
4059 cont_in_list, next_list) 4073 char_u *arg; /* next argument to be checked */
4060 char_u *arg; /* next argument */ 4074 syn_opt_arg_T *opt; /* various things */
4061 int *flagsp; /* flags for contained and transpartent */ 4075 {
4062 int keyword; /* TRUE for ":syn keyword" */
4063 int *sync_idx; /* syntax item for "grouphere" argument, NULL
4064 if not allowed */
4065 short **cont_list; /* group IDs for "contains" argument, NULL if
4066 not allowed */
4067 short **cont_in_list; /* group IDs for "containedin" argument, NULL
4068 if not allowed */
4069 short **next_list; /* group IDs for "nextgroup" argument */
4070 {
4071 int flags;
4072 char_u *gname_start, *gname; 4076 char_u *gname_start, *gname;
4073 int syn_id; 4077 int syn_id;
4074 int len; 4078 int len;
4079 char *p;
4075 int i; 4080 int i;
4076 int fidx; 4081 int fidx;
4077 static struct flag 4082 static struct flag
4078 { 4083 {
4079 char *name; 4084 char *name;
4080 int len; 4085 int argtype;
4081 int val; 4086 int flags;
4082 } flagtab[] = { {"contained", 9, HL_CONTAINED}, 4087 } flagtab[] = { {"cCoOnNtTaAiInNeEdD", 0, HL_CONTAINED},
4083 {"oneline", 7, HL_ONELINE}, 4088 {"oOnNeElLiInNeE", 0, HL_ONELINE},
4084 {"keepend", 7, HL_KEEPEND}, 4089 {"kKeEeEpPeEnNdD", 0, HL_KEEPEND},
4085 {"extend", 6, HL_EXTEND}, 4090 {"eExXtTeEnNdD", 0, HL_EXTEND},
4086 {"excludenl", 9, HL_EXCLUDENL}, 4091 {"eExXcClLuUdDeEnNlL", 0, HL_EXCLUDENL},
4087 {"transparent", 11, HL_TRANSP}, 4092 {"tTrRaAnNsSpPaArReEnNtT", 0, HL_TRANSP},
4088 {"skipnl", 6, HL_SKIPNL}, 4093 {"sSkKiIpPnNlL", 0, HL_SKIPNL},
4089 {"skipwhite", 9, HL_SKIPWHITE}, 4094 {"sSkKiIpPwWhHiItTeE", 0, HL_SKIPWHITE},
4090 {"skipempty", 9, HL_SKIPEMPTY}, 4095 {"sSkKiIpPeEmMpPtTyY", 0, HL_SKIPEMPTY},
4091 {"grouphere", 9, HL_SYNC_HERE}, 4096 {"gGrRoOuUpPhHeErReE", 0, HL_SYNC_HERE},
4092 {"groupthere", 10, HL_SYNC_THERE}, 4097 {"gGrRoOuUpPtThHeErReE", 0, HL_SYNC_THERE},
4093 {"display", 7, HL_DISPLAY}, 4098 {"dDiIsSpPlLaAyY", 0, HL_DISPLAY},
4094 {"fold", 4, HL_FOLD}, 4099 {"fFoOlLdD", 0, HL_FOLD},
4100 {"cCoOnNtTaAiInNsS", 1, 0},
4101 {"cCoOnNtTaAiInNeEdDiInN", 2, 0},
4102 {"nNeExXtTgGrRoOuUpP", 3, 0},
4095 }; 4103 };
4096 #define MLEN 12 4104 static char *first_letters = "cCoOkKeEtTsSgGdDfFnN";
4097 char lowname[MLEN];
4098 int llen;
4099 4105
4100 if (arg == NULL) /* already detected error */ 4106 if (arg == NULL) /* already detected error */
4101 return NULL; 4107 return NULL;
4102 4108
4103 flags = *flagsp;
4104 for (;;) 4109 for (;;)
4105 { 4110 {
4106 /* STRNICMP() is a bit slow, change arg to lowercase first and use 4111 /*
4107 * STRNCMP() */ 4112 * This is used very often when a large number of keywords is defined.
4108 for (llen = 0; llen < MLEN; ++llen) 4113 * Need to skip quickly when no option name is found.
4109 { 4114 * Also avoid tolower(), it's slow.
4110 if (!isalpha(arg[llen])) 4115 */
4111 break; 4116 if (strchr(first_letters, *arg) == NULL)
4112 lowname[llen] = TOLOWER_ASC(arg[llen]); 4117 break;
4113 }
4114 4118
4115 for (fidx = sizeof(flagtab) / sizeof(struct flag); --fidx >= 0; ) 4119 for (fidx = sizeof(flagtab) / sizeof(struct flag); --fidx >= 0; )
4116 { 4120 {
4117 len = flagtab[fidx].len; 4121 p = flagtab[fidx].name;
4118 if (len == llen 4122 for (i = 0, len = 0; p[i] != NUL; i += 2, ++len)
4119 && STRNCMP(lowname, flagtab[fidx].name, len) == 0 4123 if (arg[len] != p[i] && arg[len] != p[i + 1])
4120 && (ends_excmd(arg[len]) || vim_iswhite(arg[len]))) 4124 break;
4121 { 4125 if (p[i] == NUL && (vim_iswhite(arg[len])
4122 if (keyword 4126 || (flagtab[fidx].argtype > 0
4123 && (flagtab[fidx].val == HL_DISPLAY 4127 ? arg[len] == '='
4124 || flagtab[fidx].val == HL_FOLD 4128 : ends_excmd(arg[len]))))
4125 || flagtab[fidx].val == HL_EXTEND)) 4129 {
4126 { 4130 if (opt->keyword
4131 && (flagtab[fidx].flags == HL_DISPLAY
4132 || flagtab[fidx].flags == HL_FOLD
4133 || flagtab[fidx].flags == HL_EXTEND))
4127 /* treat "display", "fold" and "extend" as a keyword */ 4134 /* treat "display", "fold" and "extend" as a keyword */
4128 fidx = -1; 4135 fidx = -1;
4129 break; 4136 break;
4137 }
4138 }
4139 if (fidx < 0) /* no match found */
4140 break;
4141
4142 if (flagtab[fidx].argtype == 1)
4143 {
4144 if (!opt->has_cont_list)
4145 {
4146 EMSG(_("E395: contains argument not accepted here"));
4147 return NULL;
4148 }
4149 if (get_id_list(&arg, 8, &opt->cont_list) == FAIL)
4150 return NULL;
4151 }
4152 else if (flagtab[fidx].argtype == 2)
4153 {
4154 #if 0 /* cannot happen */
4155 if (opt->cont_in_list == NULL)
4156 {
4157 EMSG(_("E396: containedin argument not accepted here"));
4158 return NULL;
4159 }
4160 #endif
4161 if (get_id_list(&arg, 11, &opt->cont_in_list) == FAIL)
4162 return NULL;
4163 }
4164 else if (flagtab[fidx].argtype == 3)
4165 {
4166 if (get_id_list(&arg, 9, &opt->next_list) == FAIL)
4167 return NULL;
4168 }
4169 else
4170 {
4171 opt->flags |= flagtab[fidx].flags;
4172 arg = skipwhite(arg + len);
4173
4174 if (flagtab[fidx].flags == HL_SYNC_HERE
4175 || flagtab[fidx].flags == HL_SYNC_THERE)
4176 {
4177 if (opt->sync_idx == NULL)
4178 {
4179 EMSG(_("E393: group[t]here not accepted here"));
4180 return NULL;
4130 } 4181 }
4131 4182 gname_start = arg;
4132 flags |= flagtab[fidx].val; 4183 arg = skiptowhite(arg);
4133 arg = skipwhite(arg + len); 4184 if (gname_start == arg)
4134 4185 return NULL;
4135 if (flagtab[fidx].val == HL_SYNC_HERE 4186 gname = vim_strnsave(gname_start, (int)(arg - gname_start));
4136 || flagtab[fidx].val == HL_SYNC_THERE) 4187 if (gname == NULL)
4188 return NULL;
4189 if (STRCMP(gname, "NONE") == 0)
4190 *opt->sync_idx = NONE_IDX;
4191 else
4137 { 4192 {
4138 if (sync_idx == NULL) 4193 syn_id = syn_name2id(gname);
4194 for (i = curbuf->b_syn_patterns.ga_len; --i >= 0; )
4195 if (SYN_ITEMS(curbuf)[i].sp_syn.id == syn_id
4196 && SYN_ITEMS(curbuf)[i].sp_type == SPTYPE_START)
4197 {
4198 *opt->sync_idx = i;
4199 break;
4200 }
4201 if (i < 0)
4139 { 4202 {
4140 EMSG(_("E393: group[t]here not accepted here")); 4203 EMSG2(_("E394: Didn't find region item for %s"), gname);
4204 vim_free(gname);
4141 return NULL; 4205 return NULL;
4142 } 4206 }
4143 gname_start = arg;
4144 arg = skiptowhite(arg);
4145 if (gname_start == arg)
4146 return NULL;
4147 gname = vim_strnsave(gname_start, (int)(arg - gname_start));
4148 if (gname == NULL)
4149 return NULL;
4150 if (STRCMP(gname, "NONE") == 0)
4151 *sync_idx = NONE_IDX;
4152 else
4153 {
4154 syn_id = syn_name2id(gname);
4155 for (i = curbuf->b_syn_patterns.ga_len; --i >= 0; )
4156 if (SYN_ITEMS(curbuf)[i].sp_syn.id == syn_id
4157 && SYN_ITEMS(curbuf)[i].sp_type == SPTYPE_START)
4158 {
4159 *sync_idx = i;
4160 break;
4161 }
4162 if (i < 0)
4163 {
4164 EMSG2(_("E394: Didn't find region item for %s"), gname);
4165 vim_free(gname);
4166 return NULL;
4167 }
4168 }
4169
4170 vim_free(gname);
4171 arg = skipwhite(arg);
4172 } 4207 }
4208
4209 vim_free(gname);
4210 arg = skipwhite(arg);
4211 }
4173 #ifdef FEAT_FOLDING 4212 #ifdef FEAT_FOLDING
4174 else if (flagtab[fidx].val == HL_FOLD 4213 else if (flagtab[fidx].flags == HL_FOLD
4175 && foldmethodIsSyntax(curwin)) 4214 && foldmethodIsSyntax(curwin))
4176 { 4215 /* Need to update folds later. */
4177 /* Need to update folds later. */ 4216 foldUpdateAll(curwin);
4178 foldUpdateAll(curwin);
4179 }
4180 #endif 4217 #endif
4181 break; 4218 }
4182 } 4219 }
4183 }
4184 if (fidx >= 0)
4185 continue;
4186
4187 if (llen == 8 && STRNCMP(lowname, "contains", 8) == 0
4188 && (vim_iswhite(arg[8]) || arg[8] == '='))
4189 {
4190 if (cont_list == NULL)
4191 {
4192 EMSG(_("E395: contains argument not accepted here"));
4193 return NULL;
4194 }
4195 if (get_id_list(&arg, 8, cont_list) == FAIL)
4196 return NULL;
4197 }
4198 else if (llen == 11 && STRNCMP(lowname, "containedin", 11) == 0
4199 && (vim_iswhite(arg[11]) || arg[11] == '='))
4200 {
4201 if (cont_in_list == NULL)
4202 {
4203 EMSG(_("E396: containedin argument not accepted here"));
4204 return NULL;
4205 }
4206 if (get_id_list(&arg, 11, cont_in_list) == FAIL)
4207 return NULL;
4208 }
4209 else if (llen == 9 && STRNCMP(lowname, "nextgroup", 9) == 0
4210 && (vim_iswhite(arg[9]) || arg[9] == '='))
4211 {
4212 if (get_id_list(&arg, 9, next_list) == FAIL)
4213 return NULL;
4214 }
4215 else
4216 break;
4217 }
4218
4219 *flagsp = flags;
4220 4220
4221 return arg; 4221 return arg;
4222 } 4222 }
4223 4223
4224 /* 4224 /*
4334 char_u *group_name_end; 4334 char_u *group_name_end;
4335 int syn_id; 4335 int syn_id;
4336 char_u *rest; 4336 char_u *rest;
4337 char_u *keyword_copy; 4337 char_u *keyword_copy;
4338 char_u *p; 4338 char_u *p;
4339 char_u *first_arg; 4339 char_u *kw;
4340 int round; 4340 syn_opt_arg_T syn_opt_arg;
4341 int flags = 0; 4341 int cnt;
4342 short *next_list = NULL;
4343 short *cont_in_list = NULL;
4344 4342
4345 rest = get_group_name(arg, &group_name_end); 4343 rest = get_group_name(arg, &group_name_end);
4346 4344
4347 if (rest != NULL) 4345 if (rest != NULL)
4348 { 4346 {
4350 4348
4351 /* allocate a buffer, for removing the backslashes in the keyword */ 4349 /* allocate a buffer, for removing the backslashes in the keyword */
4352 keyword_copy = alloc((unsigned)STRLEN(rest) + 1); 4350 keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
4353 if (keyword_copy != NULL) 4351 if (keyword_copy != NULL)
4354 { 4352 {
4353 syn_opt_arg.flags = 0;
4354 syn_opt_arg.keyword = TRUE;
4355 syn_opt_arg.sync_idx = NULL;
4356 syn_opt_arg.has_cont_list = FALSE;
4357 syn_opt_arg.cont_in_list = NULL;
4358 syn_opt_arg.next_list = NULL;
4359
4355 /* 4360 /*
4356 * The options given apply to ALL keywords, so all options must be 4361 * The options given apply to ALL keywords, so all options must be
4357 * found before keywords can be created. 4362 * found before keywords can be created.
4358 * round 1: collect the options. 4363 * 1: collect the options and copy the keywords to keyword_copy.
4359 * round 2: create the keywords.
4360 */ 4364 */
4361 first_arg = rest; 4365 cnt = 0;
4362 for (round = 1; round <= 2; ++round) 4366 p = keyword_copy;
4363 { 4367 for ( ; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest))
4368 {
4369 rest = get_syn_options(rest, &syn_opt_arg);
4370 if (rest == NULL || ends_excmd(*rest))
4371 break;
4372 /* Copy the keyword, removing backslashes, and add a NUL. */
4373 while (*rest != NUL && !vim_iswhite(*rest))
4374 {
4375 if (*rest == '\\' && rest[1] != NUL)
4376 ++rest;
4377 *p++ = *rest++;
4378 }
4379 *p++ = NUL;
4380 ++cnt;
4381 }
4382
4383 if (!eap->skip)
4384 {
4385 /* Adjust flags for use of ":syn include". */
4386 syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
4387
4364 /* 4388 /*
4365 * Isolate each keyword and add an entry for it. 4389 * 2: Add an entry for each keyword.
4366 */ 4390 */
4367 for (rest = first_arg; rest != NULL && !ends_excmd(*rest); 4391 for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1)
4368 rest = skipwhite(rest))
4369 { 4392 {
4370 rest = get_syn_options(rest, &flags, TRUE, NULL, 4393 for (p = vim_strchr(kw, '['); ; )
4371 NULL, &cont_in_list, &next_list);
4372 if (rest == NULL || ends_excmd(*rest))
4373 break;
4374 p = keyword_copy;
4375 while (*rest != 0 && !vim_iswhite(*rest))
4376 { 4394 {
4377 if (*rest == '\\' && rest[1] != NUL) 4395 if (p != NULL)
4378 ++rest; 4396 *p = NUL;
4379 *p++ = *rest++; 4397 add_keyword(kw, syn_id, syn_opt_arg.flags,
4380 } 4398 syn_opt_arg.cont_in_list,
4381 *p = NUL; 4399 syn_opt_arg.next_list);
4382 if (round == 2 && !eap->skip) 4400 if (p == NULL || p[1] == NUL || p[1] == ']')
4383 { 4401 break;
4384 for (p = vim_strchr(keyword_copy, '['); ; ) 4402 #ifdef FEAT_MBYTE
4403 if (has_mbyte)
4385 { 4404 {
4386 if (p != NULL) 4405 int l = (*mb_ptr2len_check)(p + 1);
4387 *p = NUL; 4406
4388 add_keyword(keyword_copy, syn_id, flags, 4407 mch_memmove(p, p + 1, l);
4389 cont_in_list, next_list); 4408 p += l;
4390 if (p == NULL || p[1] == NUL || p[1] == ']') 4409 }
4391 break; 4410 else
4392 #ifdef FEAT_MBYTE
4393 if (has_mbyte)
4394 {
4395 int l = (*mb_ptr2len_check)(p + 1);
4396
4397 mch_memmove(p, p + 1, l);
4398 p += l;
4399 }
4400 else
4401 #endif 4411 #endif
4402 { 4412 {
4403 p[0] = p[1]; 4413 p[0] = p[1];
4404 ++p; 4414 ++p;
4405 }
4406 } 4415 }
4407 } 4416 }
4408 } 4417 }
4409 if (round == 1) 4418 }
4410 syn_incl_toplevel(syn_id, &flags); 4419
4411 }
4412 vim_free(keyword_copy); 4420 vim_free(keyword_copy);
4413 } 4421 }
4414 } 4422 }
4415 4423
4416 if (rest != NULL) 4424 if (rest != NULL)
4417 eap->nextcmd = check_nextcmd(rest); 4425 eap->nextcmd = check_nextcmd(rest);
4418 else 4426 else
4419 EMSG2(_(e_invarg2), arg); 4427 EMSG2(_(e_invarg2), arg);
4420 4428
4421 vim_free(cont_in_list); 4429 vim_free(syn_opt_arg.cont_in_list);
4422 vim_free(next_list); 4430 vim_free(syn_opt_arg.next_list);
4423 redraw_curbuf_later(NOT_VALID); 4431 redraw_curbuf_later(NOT_VALID);
4424 syn_stack_free_all(curbuf); /* Need to recompute all syntax. */ 4432 syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
4425 } 4433 }
4426 4434
4427 /* 4435 /*
4438 char_u *group_name_end; 4446 char_u *group_name_end;
4439 char_u *rest; 4447 char_u *rest;
4440 synpat_T item; /* the item found in the line */ 4448 synpat_T item; /* the item found in the line */
4441 int syn_id; 4449 int syn_id;
4442 int idx; 4450 int idx;
4443 int flags = 0; 4451 syn_opt_arg_T syn_opt_arg;
4444 int sync_idx = 0; 4452 int sync_idx = 0;
4445 short *cont_list = NULL;
4446 short *cont_in_list = NULL;
4447 short *next_list = NULL;
4448 4453
4449 /* Isolate the group name, check for validity */ 4454 /* Isolate the group name, check for validity */
4450 rest = get_group_name(arg, &group_name_end); 4455 rest = get_group_name(arg, &group_name_end);
4451 4456
4452 /* Get options before the pattern */ 4457 /* Get options before the pattern */
4453 rest = get_syn_options(rest, &flags, FALSE, 4458 syn_opt_arg.flags = 0;
4454 syncing ? &sync_idx : NULL, &cont_list, &cont_in_list, &next_list); 4459 syn_opt_arg.keyword = FALSE;
4460 syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL;
4461 syn_opt_arg.has_cont_list = TRUE;
4462 syn_opt_arg.cont_list = NULL;
4463 syn_opt_arg.cont_in_list = NULL;
4464 syn_opt_arg.next_list = NULL;
4465 rest = get_syn_options(rest, &syn_opt_arg);
4455 4466
4456 /* get the pattern. */ 4467 /* get the pattern. */
4457 init_syn_patterns(); 4468 init_syn_patterns();
4458 vim_memset(&item, 0, sizeof(item)); 4469 vim_memset(&item, 0, sizeof(item));
4459 rest = get_syn_pattern(rest, &item); 4470 rest = get_syn_pattern(rest, &item);
4460 if (vim_regcomp_had_eol() && !(flags & HL_EXCLUDENL)) 4471 if (vim_regcomp_had_eol() && !(syn_opt_arg.flags & HL_EXCLUDENL))
4461 flags |= HL_HAS_EOL; 4472 syn_opt_arg.flags |= HL_HAS_EOL;
4462 4473
4463 /* Get options after the pattern */ 4474 /* Get options after the pattern */
4464 rest = get_syn_options(rest, &flags, FALSE, 4475 rest = get_syn_options(rest, &syn_opt_arg);
4465 syncing ? &sync_idx : NULL, &cont_list, &cont_in_list, &next_list);
4466 4476
4467 if (rest != NULL) /* all arguments are valid */ 4477 if (rest != NULL) /* all arguments are valid */
4468 { 4478 {
4469 /* 4479 /*
4470 * Check for trailing command and illegal trailing arguments. 4480 * Check for trailing command and illegal trailing arguments.
4474 rest = NULL; 4484 rest = NULL;
4475 else if (ga_grow(&curbuf->b_syn_patterns, 1) != FAIL 4485 else if (ga_grow(&curbuf->b_syn_patterns, 1) != FAIL
4476 && (syn_id = syn_check_group(arg, 4486 && (syn_id = syn_check_group(arg,
4477 (int)(group_name_end - arg))) != 0) 4487 (int)(group_name_end - arg))) != 0)
4478 { 4488 {
4479 syn_incl_toplevel(syn_id, &flags); 4489 syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
4480 /* 4490 /*
4481 * Store the pattern in the syn_items list 4491 * Store the pattern in the syn_items list
4482 */ 4492 */
4483 idx = curbuf->b_syn_patterns.ga_len; 4493 idx = curbuf->b_syn_patterns.ga_len;
4484 SYN_ITEMS(curbuf)[idx] = item; 4494 SYN_ITEMS(curbuf)[idx] = item;
4485 SYN_ITEMS(curbuf)[idx].sp_syncing = syncing; 4495 SYN_ITEMS(curbuf)[idx].sp_syncing = syncing;
4486 SYN_ITEMS(curbuf)[idx].sp_type = SPTYPE_MATCH; 4496 SYN_ITEMS(curbuf)[idx].sp_type = SPTYPE_MATCH;
4487 SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id; 4497 SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id;
4488 SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag; 4498 SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag;
4489 SYN_ITEMS(curbuf)[idx].sp_flags = flags; 4499 SYN_ITEMS(curbuf)[idx].sp_flags = syn_opt_arg.flags;
4490 SYN_ITEMS(curbuf)[idx].sp_sync_idx = sync_idx; 4500 SYN_ITEMS(curbuf)[idx].sp_sync_idx = sync_idx;
4491 SYN_ITEMS(curbuf)[idx].sp_cont_list = cont_list; 4501 SYN_ITEMS(curbuf)[idx].sp_cont_list = syn_opt_arg.cont_list;
4492 SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list = cont_in_list; 4502 SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list =
4493 if (cont_in_list != NULL) 4503 syn_opt_arg.cont_in_list;
4504 if (syn_opt_arg.cont_in_list != NULL)
4494 curbuf->b_syn_containedin = TRUE; 4505 curbuf->b_syn_containedin = TRUE;
4495 SYN_ITEMS(curbuf)[idx].sp_next_list = next_list; 4506 SYN_ITEMS(curbuf)[idx].sp_next_list = syn_opt_arg.next_list;
4496 ++curbuf->b_syn_patterns.ga_len; 4507 ++curbuf->b_syn_patterns.ga_len;
4497 4508
4498 /* remember that we found a match for syncing on */ 4509 /* remember that we found a match for syncing on */
4499 if (flags & (HL_SYNC_HERE|HL_SYNC_THERE)) 4510 if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE))
4500 curbuf->b_syn_sync_flags |= SF_MATCH; 4511 curbuf->b_syn_sync_flags |= SF_MATCH;
4501 #ifdef FEAT_FOLDING 4512 #ifdef FEAT_FOLDING
4502 if (flags & HL_FOLD) 4513 if (syn_opt_arg.flags & HL_FOLD)
4503 ++curbuf->b_syn_folditems; 4514 ++curbuf->b_syn_folditems;
4504 #endif 4515 #endif
4505 4516
4506 redraw_curbuf_later(NOT_VALID); 4517 redraw_curbuf_later(NOT_VALID);
4507 syn_stack_free_all(curbuf); /* Need to recompute all syntax. */ 4518 syn_stack_free_all(curbuf); /* Need to recompute all syntax. */
4512 /* 4523 /*
4513 * Something failed, free the allocated memory. 4524 * Something failed, free the allocated memory.
4514 */ 4525 */
4515 vim_free(item.sp_prog); 4526 vim_free(item.sp_prog);
4516 vim_free(item.sp_pattern); 4527 vim_free(item.sp_pattern);
4517 vim_free(cont_list); 4528 vim_free(syn_opt_arg.cont_list);
4518 vim_free(cont_in_list); 4529 vim_free(syn_opt_arg.cont_in_list);
4519 vim_free(next_list); 4530 vim_free(syn_opt_arg.next_list);
4520 4531
4521 if (rest == NULL) 4532 if (rest == NULL)
4522 EMSG2(_(e_invarg2), arg); 4533 EMSG2(_(e_invarg2), arg);
4523 } 4534 }
4524 4535
4556 int matchgroup_id = 0; 4567 int matchgroup_id = 0;
4557 int not_enough = FALSE; /* not enough arguments */ 4568 int not_enough = FALSE; /* not enough arguments */
4558 int illegal = FALSE; /* illegal arguments */ 4569 int illegal = FALSE; /* illegal arguments */
4559 int success = FALSE; 4570 int success = FALSE;
4560 int idx; 4571 int idx;
4561 int flags = 0; 4572 syn_opt_arg_T syn_opt_arg;
4562 short *cont_list = NULL;
4563 short *cont_in_list = NULL;
4564 short *next_list = NULL;
4565 4573
4566 /* Isolate the group name, check for validity */ 4574 /* Isolate the group name, check for validity */
4567 rest = get_group_name(arg, &group_name_end); 4575 rest = get_group_name(arg, &group_name_end);
4568 4576
4569 pat_ptrs[0] = NULL; 4577 pat_ptrs[0] = NULL;
4570 pat_ptrs[1] = NULL; 4578 pat_ptrs[1] = NULL;
4571 pat_ptrs[2] = NULL; 4579 pat_ptrs[2] = NULL;
4572 4580
4573 init_syn_patterns(); 4581 init_syn_patterns();
4582
4583 syn_opt_arg.flags = 0;
4584 syn_opt_arg.keyword = FALSE;
4585 syn_opt_arg.sync_idx = NULL;
4586 syn_opt_arg.has_cont_list = TRUE;
4587 syn_opt_arg.cont_list = NULL;
4588 syn_opt_arg.cont_in_list = NULL;
4589 syn_opt_arg.next_list = NULL;
4574 4590
4575 /* 4591 /*
4576 * get the options, patterns and matchgroup. 4592 * get the options, patterns and matchgroup.
4577 */ 4593 */
4578 while (rest != NULL && !ends_excmd(*rest)) 4594 while (rest != NULL && !ends_excmd(*rest))
4579 { 4595 {
4580 /* Check for option arguments */ 4596 /* Check for option arguments */
4581 rest = get_syn_options(rest, &flags, FALSE, NULL, 4597 rest = get_syn_options(rest, &syn_opt_arg);
4582 &cont_list, &cont_in_list, &next_list);
4583 if (rest == NULL || ends_excmd(*rest)) 4598 if (rest == NULL || ends_excmd(*rest))
4584 break; 4599 break;
4585 4600
4586 /* must be a pattern or matchgroup then */ 4601 /* must be a pattern or matchgroup then */
4587 key_end = rest; 4602 key_end = rest;
4672 else if (item == ITEM_SKIP || item == ITEM_END) 4687 else if (item == ITEM_SKIP || item == ITEM_END)
4673 reg_do_extmatch = REX_USE; 4688 reg_do_extmatch = REX_USE;
4674 rest = get_syn_pattern(rest, ppp->pp_synp); 4689 rest = get_syn_pattern(rest, ppp->pp_synp);
4675 reg_do_extmatch = 0; 4690 reg_do_extmatch = 0;
4676 if (item == ITEM_END && vim_regcomp_had_eol() 4691 if (item == ITEM_END && vim_regcomp_had_eol()
4677 && !(flags & HL_EXCLUDENL)) 4692 && !(syn_opt_arg.flags & HL_EXCLUDENL))
4678 ppp->pp_synp->sp_flags |= HL_HAS_EOL; 4693 ppp->pp_synp->sp_flags |= HL_HAS_EOL;
4679 ppp->pp_matchgroup_id = matchgroup_id; 4694 ppp->pp_matchgroup_id = matchgroup_id;
4680 ++pat_count; 4695 ++pat_count;
4681 } 4696 }
4682 } 4697 }
4705 rest = NULL; 4720 rest = NULL;
4706 else if (ga_grow(&(curbuf->b_syn_patterns), pat_count) != FAIL 4721 else if (ga_grow(&(curbuf->b_syn_patterns), pat_count) != FAIL
4707 && (syn_id = syn_check_group(arg, 4722 && (syn_id = syn_check_group(arg,
4708 (int)(group_name_end - arg))) != 0) 4723 (int)(group_name_end - arg))) != 0)
4709 { 4724 {
4710 syn_incl_toplevel(syn_id, &flags); 4725 syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
4711 /* 4726 /*
4712 * Store the start/skip/end in the syn_items list 4727 * Store the start/skip/end in the syn_items list
4713 */ 4728 */
4714 idx = curbuf->b_syn_patterns.ga_len; 4729 idx = curbuf->b_syn_patterns.ga_len;
4715 for (item = ITEM_START; item <= ITEM_END; ++item) 4730 for (item = ITEM_START; item <= ITEM_END; ++item)
4719 SYN_ITEMS(curbuf)[idx] = *(ppp->pp_synp); 4734 SYN_ITEMS(curbuf)[idx] = *(ppp->pp_synp);
4720 SYN_ITEMS(curbuf)[idx].sp_syncing = syncing; 4735 SYN_ITEMS(curbuf)[idx].sp_syncing = syncing;
4721 SYN_ITEMS(curbuf)[idx].sp_type = 4736 SYN_ITEMS(curbuf)[idx].sp_type =
4722 (item == ITEM_START) ? SPTYPE_START : 4737 (item == ITEM_START) ? SPTYPE_START :
4723 (item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END; 4738 (item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END;
4724 SYN_ITEMS(curbuf)[idx].sp_flags |= flags; 4739 SYN_ITEMS(curbuf)[idx].sp_flags |= syn_opt_arg.flags;
4725 SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id; 4740 SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id;
4726 SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag; 4741 SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag;
4727 SYN_ITEMS(curbuf)[idx].sp_syn_match_id = 4742 SYN_ITEMS(curbuf)[idx].sp_syn_match_id =
4728 ppp->pp_matchgroup_id; 4743 ppp->pp_matchgroup_id;
4729 if (item == ITEM_START) 4744 if (item == ITEM_START)
4730 { 4745 {
4731 SYN_ITEMS(curbuf)[idx].sp_cont_list = cont_list; 4746 SYN_ITEMS(curbuf)[idx].sp_cont_list =
4747 syn_opt_arg.cont_list;
4732 SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list = 4748 SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list =
4733 cont_in_list; 4749 syn_opt_arg.cont_in_list;
4734 if (cont_in_list != NULL) 4750 if (syn_opt_arg.cont_in_list != NULL)
4735 curbuf->b_syn_containedin = TRUE; 4751 curbuf->b_syn_containedin = TRUE;
4736 SYN_ITEMS(curbuf)[idx].sp_next_list = next_list; 4752 SYN_ITEMS(curbuf)[idx].sp_next_list =
4753 syn_opt_arg.next_list;
4737 } 4754 }
4738 ++curbuf->b_syn_patterns.ga_len; 4755 ++curbuf->b_syn_patterns.ga_len;
4739 ++idx; 4756 ++idx;
4740 #ifdef FEAT_FOLDING 4757 #ifdef FEAT_FOLDING
4741 if (flags & HL_FOLD) 4758 if (syn_opt_arg.flags & HL_FOLD)
4742 ++curbuf->b_syn_folditems; 4759 ++curbuf->b_syn_folditems;
4743 #endif 4760 #endif
4744 } 4761 }
4745 } 4762 }
4746 4763
4766 vim_free(ppp); 4783 vim_free(ppp);
4767 } 4784 }
4768 4785
4769 if (!success) 4786 if (!success)
4770 { 4787 {
4771 vim_free(cont_list); 4788 vim_free(syn_opt_arg.cont_list);
4772 vim_free(cont_in_list); 4789 vim_free(syn_opt_arg.cont_in_list);
4773 vim_free(next_list); 4790 vim_free(syn_opt_arg.next_list);
4774 if (not_enough) 4791 if (not_enough)
4775 EMSG2(_("E399: Not enough arguments: syntax region %s"), arg); 4792 EMSG2(_("E399: Not enough arguments: syntax region %s"), arg);
4776 else if (illegal || rest == NULL) 4793 else if (illegal || rest == NULL)
4777 EMSG2(_(e_invarg2), arg); 4794 EMSG2(_(e_invarg2), arg);
4778 } 4795 }