commit 57b3f83cfee9a0ba3c4d02825ab03afc9be22a04
parent edbdcb9b9ad67a0062af79fe5c343b5e28e934f6
Author: Brand Huntsman <alpha@qzx.com>
Date: Mon, 3 Jun 2019 17:37:02 -0600
rcfile: compile the color regexes just once
When a syntax gets parsed, store the compiled color regexes right away,
instead of compiling them a second time in color_update().
This addresses https://savannah.gnu.org/bugs/?56432.
Signed-off-by: Brand Huntsman <alpha@qzx.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
Diffstat:
3 files changed, 19 insertions(+), 40 deletions(-)
diff --git a/src/color.c b/src/color.c
@@ -169,7 +169,6 @@ bool found_in_list(regexlisttype *head, const char *shibboleth)
void color_update(void)
{
syntaxtype *sint = NULL;
- colortype *ink;
/* If the rcfiles were not read, or contained no syntaxes, get out. */
if (syntaxes == NULL)
@@ -281,20 +280,6 @@ void color_update(void)
openfile->syntax = sint;
openfile->colorstrings = (sint == NULL ? NULL : sint->color);
-
- /* If a syntax was found, compile its specified regexes (which have
- * already been checked for validity when they were read in). */
- for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
- if (ink->start == NULL) {
- ink->start = (regex_t *)nmalloc(sizeof(regex_t));
- regcomp(ink->start, ink->start_regex, ink->rex_flags);
- }
-
- if (ink->end_regex != NULL && ink->end == NULL) {
- ink->end = (regex_t *)nmalloc(sizeof(regex_t));
- regcomp(ink->end, ink->end_regex, ink->rex_flags);
- }
- }
}
/* Determine whether the matches of multiline regexes are still the same,
diff --git a/src/nano.h b/src/nano.h
@@ -192,14 +192,8 @@ typedef struct colortype {
* background color. */
int attributes;
/* Pair number and brightness composed into ready-to-use attributes. */
- int rex_flags;
- /* The regex compilation flags (with or without REG_ICASE). */
- char *start_regex;
- /* The start (or all) of the regex string. */
regex_t *start;
/* The compiled start (or all) of the regex string. */
- char *end_regex;
- /* The end (if any) of the regex string. */
regex_t *end;
/* The compiled end (if any) of the regex string. */
struct colortype *next;
diff --git a/src/rcfile.c b/src/rcfile.c
@@ -269,21 +269,26 @@ char *parse_next_regex(char *ptr)
/* Compile the regular expression regex to see if it's valid. Return
* TRUE if it is, and FALSE otherwise. */
-bool nregcomp(const char *regex, int compile_flags)
+bool nregcomp(regex_t **compiled, const char *regex, int compile_flags)
{
- regex_t preg;
- int rc = regcomp(&preg, regex, compile_flags);
+ regex_t *preg = nmalloc(sizeof(regex_t));
+ int rc = regcomp(preg, regex, compile_flags);
if (rc != 0) {
- size_t len = regerror(rc, &preg, NULL, 0);
+ size_t len = regerror(rc, preg, NULL, 0);
char *str = charalloc(len);
- regerror(rc, &preg, str, len);
+ regerror(rc, preg, str, len);
rcfile_error(N_("Bad regex \"%s\": %s"), regex, str);
free(str);
}
- regfree(&preg);
+ if (compiled == NULL || rc != 0) {
+ regfree(preg);
+ free(preg);
+ } else
+ *compiled = preg;
+
return (rc == 0);
}
@@ -760,23 +765,18 @@ void parse_colors(char *ptr, int rex_flags)
if (*item == '\0') {
rcfile_error(N_("Empty regex string"));
goodstart = FALSE;
- } else
- goodstart = nregcomp(item, rex_flags);
+ } else {
+ newcolor = (colortype *)nmalloc(sizeof(colortype));
+ goodstart = nregcomp(&newcolor->start, item, rex_flags);
+ }
/* If the starting regex is valid, initialize a new color struct,
* and hook it in at the tail of the linked list. */
if (goodstart) {
- newcolor = (colortype *)nmalloc(sizeof(colortype));
-
newcolor->fg = fg;
newcolor->bg = bg;
newcolor->attributes = attributes;
- newcolor->rex_flags = rex_flags;
-
- newcolor->start_regex = mallocstrcpy(NULL, item);
- newcolor->start = NULL;
- newcolor->end_regex = NULL;
newcolor->end = NULL;
newcolor->next = NULL;
@@ -787,7 +787,8 @@ void parse_colors(char *ptr, int rex_flags)
lastcolor->next = newcolor;
lastcolor = newcolor;
- }
+ } else
+ free(newcolor);
if (!expectend)
continue;
@@ -819,8 +820,7 @@ void parse_colors(char *ptr, int rex_flags)
continue;
/* If it's valid, save the ending regex string. */
- if (nregcomp(item, rex_flags))
- newcolor->end_regex = mallocstrcpy(NULL, item);
+ nregcomp(&newcolor->end, item, rex_flags);
/* Lame way to skip another static counter. */
newcolor->id = live_syntax->nmultis;
@@ -889,7 +889,7 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
return;
/* If the regex string is malformed, skip it. */
- if (!nregcomp(regexstring, NANO_REG_EXTENDED | REG_NOSUB))
+ if (!nregcomp(NULL, regexstring, NANO_REG_EXTENDED | REG_NOSUB))
continue;
/* Copy the regex into a struct, and hook this in at the end. */