diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-08-02 09:12:38 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-02 01:12:38 +0000 |
commit | 3bc864e7739d9fa8b086f5606a666abb4a34054d (patch) | |
tree | 0bd65f3e033b09372f2b7377124b63ceb45d807e /src/nvim/syntax.c | |
parent | b782a37cf58b5ae5e47fd15fb2a5096639c64a23 (diff) | |
download | rneovim-3bc864e7739d9fa8b086f5606a666abb4a34054d.tar.gz rneovim-3bc864e7739d9fa8b086f5606a666abb4a34054d.tar.bz2 rneovim-3bc864e7739d9fa8b086f5606a666abb4a34054d.zip |
vim-patch:9.1.0652: too many strlen() calls in syntax.c (#29949)
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: vim/vim#15368
https://github.com/vim/vim/commit/b4ea77185c7deeb6f7c8d5aa14f8c97a097e5dee
Co-authored-by: John Marriott <basilisk@internode.on.net>
Diffstat (limited to 'src/nvim/syntax.c')
-rw-r--r-- | src/nvim/syntax.c | 106 |
1 files changed, 59 insertions, 47 deletions
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index d1af8f304c..9eeed3fbd2 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -158,11 +158,6 @@ typedef struct { char *pattern; } time_entry_T; -struct name_list { - int flag; - char *name; -}; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "syntax.c.generated.h" #endif @@ -2287,7 +2282,7 @@ static void update_si_end(stateitem_T *sip, int startcol, bool force) // 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 { // continues in the next line sip->si_ends = false; @@ -2659,6 +2654,12 @@ static char *syn_getcurline(void) return ml_get_buf(syn_buf, current_lnum); } +/// 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. static bool syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T *st) @@ -3327,24 +3328,22 @@ static int last_matchgroup; static void syn_list_one(const int id, const bool syncing, const bool link_only) { bool did_header = false; - static struct name_list 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" }, - { HL_CONCEAL, "conceal" }, - { HL_CONCEALENDS, "concealends" }, - { 0, NULL } + static keyvalue_T namelist1[] = { + 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"), + KEYVALUE_ENTRY(HL_CONCEAL, "conceal"), + KEYVALUE_ENTRY(HL_CONCEALENDS, "concealends"), }; - static struct name_list namelist2[] = { - { HL_SKIPWHITE, "skipwhite" }, - { HL_SKIPNL, "skipnl" }, - { HL_SKIPEMPTY, "skipempty" }, - { 0, NULL } + static keyvalue_T namelist2[] = { + KEYVALUE_ENTRY(HL_SKIPWHITE, "skipwhite"), + KEYVALUE_ENTRY(HL_SKIPNL, "skipnl"), + KEYVALUE_ENTRY(HL_SKIPEMPTY, "skipempty"), }; const int attr = HL_ATTR(HLF_D); // highlight like directories @@ -3385,7 +3384,7 @@ static void syn_list_one(const int id, const bool syncing, const bool link_only) idx--; msg_putchar(' '); } - syn_list_flags(namelist1, spp->sp_flags, attr); + syn_list_flags(namelist1, ARRAY_SIZE(namelist1), spp->sp_flags, attr); if (spp->sp_cont_list != NULL) { put_id_list("contains", spp->sp_cont_list, attr); @@ -3397,7 +3396,7 @@ static void syn_list_one(const int id, const bool syncing, const bool link_only) if (spp->sp_next_list != NULL) { put_id_list("nextgroup", spp->sp_next_list, attr); - syn_list_flags(namelist2, spp->sp_flags, attr); + syn_list_flags(namelist2, ARRAY_SIZE(namelist2), spp->sp_flags, attr); } if (spp->sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE)) { if (spp->sp_flags & HL_SYNC_HERE) { @@ -3425,11 +3424,11 @@ static void syn_list_one(const int id, const bool syncing, const bool link_only) } } -static void syn_list_flags(struct name_list *nlist, int flags, int attr) +static void syn_list_flags(keyvalue_T *nlist, size_t nr_entries, int flags, int attr) { - for (int i = 0; nlist[i].flag != 0; i++) { - if (flags & nlist[i].flag) { - msg_puts_attr(nlist[i].name, attr); + for (size_t i = 0; i < nr_entries; i++) { + if (flags & nlist[i].key) { + msg_puts_attr(nlist[i].value, attr); msg_putchar(' '); } } @@ -3701,17 +3700,22 @@ static void clear_keywtab(hashtab_T *ht) /// @param flags flags for this keyword /// @param cont_in_list containedin for this keyword /// @param next_list nextgroup for this keyword -static void add_keyword(char *const name, const int id, const int flags, +static void add_keyword(char *const name, size_t namelen, const int id, const int flags, int16_t *const cont_in_list, int16_t *const next_list, const int conceal_char) { char name_folded[MAXKEYWLEN + 1]; - const char *const name_ic = (curwin->w_s->b_syn_ic) - ? str_foldcase(name, (int)strlen(name), name_folded, - sizeof(name_folded)) - : name; + const char *name_ic; + size_t name_iclen; + if (curwin->w_s->b_syn_ic) { + name_ic = str_foldcase(name, (int)namelen, name_folded, MAXKEYWLEN + 1); + name_iclen = strlen(name_ic); + } else { + name_ic = name; + name_iclen = namelen; + } - keyentry_T *const kp = xmalloc(offsetof(keyentry_T, keyword) + strlen(name_ic) + 1); + keyentry_T *const kp = xmalloc(offsetof(keyentry_T, keyword) + name_iclen + 1); STRCPY(kp->keyword, name_ic); kp->k_syn.id = (int16_t)id; kp->k_syn.inc_tag = current_syn_inc_tag; @@ -4062,12 +4066,16 @@ static void syn_cmd_keyword(exarg_T *eap, int syncing) syn_incl_toplevel(syn_id, &syn_opt_arg.flags); // 2: Add an entry for each keyword. - for (char *kw = keyword_copy; --cnt >= 0; kw += strlen(kw) + 1) { + size_t kwlen = 0; + for (char *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; + kwlen = (size_t)(p - kw); } - add_keyword(kw, syn_id, syn_opt_arg.flags, + 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) { @@ -4083,6 +4091,7 @@ static void syn_cmd_keyword(exarg_T *eap, int syncing) goto error; } kw = p + 1; + kwlen = 1; break; // skip over the "]" } const int l = utfc_ptr2len(p + 1); @@ -5206,7 +5215,6 @@ static struct subcommand subcommands[] = { { "spell", syn_cmd_spell }, { "sync", syn_cmd_sync }, { "", syn_cmd_list }, - { NULL, NULL } }; /// ":syntax". @@ -5225,17 +5233,19 @@ void ex_syntax(exarg_T *eap) if (eap->skip) { // skip error messages for all subcommands emsg_skip++; } - for (int i = 0;; i++) { - if (subcommands[i].name == NULL) { - semsg(_("E410: Invalid :syntax subcommand: %s"), subcmd_name); - break; - } + size_t i; + for (i = 0; i < ARRAY_SIZE(subcommands); i++) { if (strcmp(subcmd_name, subcommands[i].name) == 0) { eap->arg = skipwhite(subcmd_end); (subcommands[i].func)(eap, false); break; } } + + if (i == ARRAY_SIZE(subcommands)) { + semsg(_("E410: Invalid :syntax subcommand: %s"), subcmd_name); + } + xfree(subcmd_name); if (eap->skip) { emsg_skip--; @@ -5366,6 +5376,9 @@ char *get_syntax_name(expand_T *xp, int idx) { switch (expand_what) { case EXP_SUBCMD: + if (idx < 0 || idx >= (int)ARRAY_SIZE(subcommands)) { + return NULL; + } return subcommands[idx].name; case EXP_CASE: { static char *case_args[] = { "match", "ignore", NULL }; @@ -5646,9 +5659,8 @@ static void syntime_report(void) } else { len = Columns - 70; } - if (len > (int)strlen(p->pattern)) { - len = (int)strlen(p->pattern); - } + int patlen = (int)strlen(p->pattern); + len = MIN(len, patlen); msg_outtrans_len(p->pattern, len, 0); msg_puts("\n"); } |