Mercurial > vim
changeset 35881:7c3cb86855e1 v9.1.0652
patch 9.1.0652: too many strlen() calls in syntax.c
Commit: https://github.com/vim/vim/commit/b4ea77185c7deeb6f7c8d5aa14f8c97a097e5dee
Author: John Marriott <basilisk@internode.on.net>
Date: Thu Aug 1 23:01:25 2024 +0200
patch 9.1.0652: too many strlen() calls in syntax.c
Problem: too many strlen() calls in syntax.c
Solution: refactor code to reduce the number or strlen() calls,
get rid of un-used SYN_NAMELEN macro
(John Marriott)
closes: #15368
Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 01 Aug 2024 23:15:02 +0200 |
parents | 53415ce3472f |
children | 63f46f7b3908 |
files | src/syntax.c src/version.c |
diffstat | 2 files changed, 69 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/src/syntax.c +++ b/src/syntax.c @@ -15,8 +15,6 @@ #if defined(FEAT_SYN_HL) || defined(PROTO) -#define SYN_NAMELEN 50 // maximum length of a syntax name - // different types of offsets that are possible #define SPO_MS_OFF 0 // match start offset #define SPO_ME_OFF 1 // match end offset @@ -323,6 +321,7 @@ static void limit_pos_zero(lpos_T *pos, static void syn_add_end_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra); static void syn_add_start_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, int extra); static char_u *syn_getcurline(void); +static colnr_T syn_getcurline_len(void); static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T *st); static int check_keyword_id(char_u *line, int startcol, int *endcol, long *flags, short **next_list, stateitem_T *cur_si, int *ccharp); static void syn_remove_pattern(synblock_T *block, int idx); @@ -2692,7 +2691,7 @@ update_si_end( // a "oneline" never continues in the next line sip->si_ends = TRUE; sip->si_m_endpos.lnum = current_lnum; - sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline()); + sip->si_m_endpos.col = syn_getcurline_len(); } else { @@ -3130,6 +3129,15 @@ syn_getcurline(void) } /* + * Get length of current line in syntax buffer. + */ + static colnr_T +syn_getcurline_len(void) +{ + return ml_get_buf_len(syn_buf, current_lnum); +} + +/* * Call vim_regexec() to find a match with "rmp" in "syn_buf". * Returns TRUE when there is a match. */ @@ -3935,13 +3943,7 @@ syn_match_msg(void) static int last_matchgroup; -struct name_list -{ - int flag; - char *name; -}; - -static void syn_list_flags(struct name_list *nl, int flags, int attr); +static void syn_list_flags(keyvalue_T *nlist, int nr_entries, int flags, int attr); /* * List one syntax item, for ":syntax" or "syntax list syntax_name". @@ -3956,28 +3958,27 @@ syn_list_one( int idx; int did_header = FALSE; synpat_T *spp; - static struct name_list namelist1[] = + static keyvalue_T namelist1[] = { - {HL_DISPLAY, "display"}, - {HL_CONTAINED, "contained"}, - {HL_ONELINE, "oneline"}, - {HL_KEEPEND, "keepend"}, - {HL_EXTEND, "extend"}, - {HL_EXCLUDENL, "excludenl"}, - {HL_TRANSP, "transparent"}, - {HL_FOLD, "fold"}, + KEYVALUE_ENTRY(HL_DISPLAY, "display"), + KEYVALUE_ENTRY(HL_CONTAINED, "contained"), + KEYVALUE_ENTRY(HL_ONELINE, "oneline"), + KEYVALUE_ENTRY(HL_KEEPEND, "keepend"), + KEYVALUE_ENTRY(HL_EXTEND, "extend"), + KEYVALUE_ENTRY(HL_EXCLUDENL, "excludenl"), + KEYVALUE_ENTRY(HL_TRANSP, "transparent"), + KEYVALUE_ENTRY(HL_FOLD, "fold") #ifdef FEAT_CONCEAL - {HL_CONCEAL, "conceal"}, - {HL_CONCEALENDS, "concealends"}, + , + KEYVALUE_ENTRY(HL_CONCEAL, "conceal"), + KEYVALUE_ENTRY(HL_CONCEALENDS, "concealends") #endif - {0, NULL} }; - static struct name_list namelist2[] = + static keyvalue_T namelist2[] = { - {HL_SKIPWHITE, "skipwhite"}, - {HL_SKIPNL, "skipnl"}, - {HL_SKIPEMPTY, "skipempty"}, - {0, NULL} + KEYVALUE_ENTRY(HL_SKIPWHITE, "skipwhite"), + KEYVALUE_ENTRY(HL_SKIPNL, "skipnl"), + KEYVALUE_ENTRY(HL_SKIPEMPTY, "skipempty") }; attr = HL_ATTR(HLF_D); // highlight like directories @@ -4017,7 +4018,7 @@ syn_list_one( --idx; msg_putchar(' '); } - syn_list_flags(namelist1, spp->sp_flags, attr); + syn_list_flags(namelist1, (int)ARRAY_LENGTH(namelist1), spp->sp_flags, attr); if (spp->sp_cont_list != NULL) put_id_list((char_u *)"contains", spp->sp_cont_list, attr); @@ -4029,7 +4030,7 @@ syn_list_one( if (spp->sp_next_list != NULL) { put_id_list((char_u *)"nextgroup", spp->sp_next_list, attr); - syn_list_flags(namelist2, spp->sp_flags, attr); + syn_list_flags(namelist2, (int)ARRAY_LENGTH(namelist2), spp->sp_flags, attr); } if (spp->sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE)) { @@ -4058,14 +4059,14 @@ syn_list_one( } static void -syn_list_flags(struct name_list *nlist, int flags, int attr) +syn_list_flags(keyvalue_T *nlist, int nr_entries, int flags, int attr) { int i; - for (i = 0; nlist[i].flag != 0; ++i) - if (flags & nlist[i].flag) + for (i = 0; i < nr_entries; ++i) + if (flags & nlist[i].key) { - msg_puts_attr(nlist[i].name, attr); + msg_puts_attr(nlist[i].value, attr); msg_putchar(' '); } } @@ -4393,6 +4394,7 @@ clear_keywtab(hashtab_T *ht) static void add_keyword( char_u *name, // name of keyword + size_t namelen, // length of keyword (excluding the NUL) int id, // group ID for this keyword int flags, // flags for this keyword short *cont_in_list, // containedin for this keyword @@ -4403,15 +4405,22 @@ add_keyword( hashtab_T *ht; hashitem_T *hi; char_u *name_ic; + size_t name_iclen; long_u hash; char_u name_folded[MAXKEYWLEN + 1]; if (curwin->w_s->b_syn_ic) - name_ic = str_foldcase(name, (int)STRLEN(name), + { + name_ic = str_foldcase(name, (int)namelen, name_folded, MAXKEYWLEN + 1); + name_iclen = STRLEN(name_ic); + } else + { name_ic = name; - kp = alloc(offsetof(keyentry_T, keyword) + STRLEN(name_ic) + 1); + name_iclen = namelen; + } + kp = alloc(offsetof(keyentry_T, keyword) + name_iclen + 1); if (kp == NULL) return; STRCPY(kp->keyword, name_ic); @@ -4828,19 +4837,26 @@ syn_cmd_keyword(exarg_T *eap, int syncin if (!eap->skip) { + size_t kwlen = 0; + // Adjust flags for use of ":syn include". syn_incl_toplevel(syn_id, &syn_opt_arg.flags); /* * 2: Add an entry for each keyword. */ - for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) + for (kw = keyword_copy; --cnt >= 0; kw += kwlen + 1) { for (p = vim_strchr(kw, '['); ; ) { - if (p != NULL) + if (p == NULL) + kwlen = STRLEN(kw); + else + { *p = NUL; - add_keyword(kw, syn_id, syn_opt_arg.flags, + kwlen = (size_t)(p - kw); + } + add_keyword(kw, kwlen, syn_id, syn_opt_arg.flags, syn_opt_arg.cont_in_list, syn_opt_arg.next_list, conceal_char); if (p == NULL) @@ -4859,6 +4875,7 @@ syn_cmd_keyword(exarg_T *eap, int syncin goto error; } kw = p + 1; // skip over the "]" + kwlen = 1; break; } if (has_mbyte) @@ -6229,8 +6246,7 @@ static struct subcommand subcommands[] = {"reset", syn_cmd_reset}, {"spell", syn_cmd_spell}, {"sync", syn_cmd_sync}, - {"", syn_cmd_list}, - {NULL, NULL} + {"", syn_cmd_list} }; /* @@ -6257,13 +6273,8 @@ ex_syntax(exarg_T *eap) if (eap->skip) // skip error messages for all subcommands ++emsg_skip; - for (i = 0; ; ++i) + for (i = 0; i < (int)ARRAY_LENGTH(subcommands); ++i) { - if (subcommands[i].name == NULL) - { - semsg(_(e_invalid_syntax_subcommand_str), subcmd_name); - break; - } if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0) { eap->arg = skipwhite(subcmd_end); @@ -6271,6 +6282,10 @@ ex_syntax(exarg_T *eap) break; } } + + if (i == (int)ARRAY_LENGTH(subcommands)) + semsg(_(e_invalid_syntax_subcommand_str), subcmd_name); + vim_free(subcmd_name); if (eap->skip) --emsg_skip; @@ -6424,6 +6439,8 @@ get_syntax_name(expand_T *xp, int idx) switch (expand_what) { case EXP_SUBCMD: + if (idx < 0 || idx >= (int)ARRAY_LENGTH(subcommands)) + return NULL; return (char_u *)subcommands[idx].name; case EXP_CASE: { @@ -6697,6 +6714,7 @@ syntime_report(void) proftime_T tm; # endif int len; + int patlen; proftime_T total_total; int total_count = 0; garray_T ga; @@ -6768,8 +6786,9 @@ syntime_report(void) len = 20; // will wrap anyway else len = Columns - 70; - if (len > (int)STRLEN(p->pattern)) - len = (int)STRLEN(p->pattern); + patlen = (int)STRLEN(p->pattern); + if (len > patlen) + len = patlen; msg_outtrans_len(p->pattern, len); msg_puts("\n"); }