patch 9.1.0652: too many strlen() calls in syntax.c

Commit: 
https://github.com/vim/vim/commit/b4ea77185c7deeb6f7c8d5aa14f8c97a097e5dee
Author: John Marriott <basil...@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 <basil...@internode.on.net>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/syntax.c b/src/syntax.c
index 02120529f..eec57999d 100644
--- 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, lpos_T *limit);
 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
        {
@@ -3129,6 +3128,15 @@ syn_getcurline(void)
     return ml_get_buf(syn_buf, current_lnum, FALSE);
 }
 
+/*
+ * 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 syncing UNUSED)
 
            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 syncing UNUSED)
                                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("
");
     }
diff --git a/src/version.c b/src/version.c
index 07622ac3d..ea418160f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    652,
 /**/
     651,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1sZd8Y-008mVv-Vc%40256bit.org.

Raspunde prin e-mail lui