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");
     }
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    652,
+/**/
     651,
 /**/
     650,