startup: save the compiled file-matching regexes, to avoid recompiling

This reduces startup time by seven percent (when using the standard set
of syntaxes) when opening just one file that doesn't match any syntax,
and more than ten percent when opening multiple files.  It takes some
extra memory, but... not wasting CPU cycles is more important.

This addresses https://savannah.gnu.org/bugs/?56433.
master
Benno Schulenberg 2021-01-20 15:18:33 +01:00
parent 6283557d2f
commit c96e62e33a
3 changed files with 7 additions and 14 deletions

View File

@ -120,17 +120,10 @@ void prepare_palette(void)
bool found_in_list(regexlisttype *head, const char *shibboleth)
{
regexlisttype *item;
regex_t rgx;
for (item = head; item != NULL; item = item->next) {
regcomp(&rgx, item->full_regex, NANO_REG_EXTENDED | REG_NOSUB);
if (regexec(&rgx, shibboleth, 0, NULL, 0) == 0) {
regfree(&rgx);
if (regexec(item->one_rgx, shibboleth, 0, NULL, 0) == 0)
return TRUE;
}
regfree(&rgx);
}
return FALSE;

View File

@ -366,8 +366,8 @@ typedef struct colortype {
} colortype;
typedef struct regexlisttype {
char *full_regex;
/* A regex string to match things that imply a certain syntax. */
regex_t *one_rgx;
/* A regex to match things that imply a certain syntax. */
struct regexlisttype *next;
/* The next regex. */
} regexlisttype;

View File

@ -622,9 +622,7 @@ bool compile(const char *expression, int rex_flags, regex_t **packed)
regerror(outcome, compiled, message, length);
jot_error(N_("Bad regex \"%s\": %s"), expression, message);
free(message);
}
if (packed == NULL || outcome != 0) {
regfree(compiled);
free(compiled);
} else
@ -1239,6 +1237,8 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
/* Now gather any valid regexes and add them to the linked list. */
while (*ptr != '\0') {
regex_t *packed_rgx = NULL;
regexstring = ++ptr;
ptr = parse_next_regex(ptr);
@ -1246,12 +1246,12 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
return;
/* If the regex string is malformed, skip it. */
if (!compile(regexstring, NANO_REG_EXTENDED | REG_NOSUB, NULL))
if (!compile(regexstring, NANO_REG_EXTENDED | REG_NOSUB, &packed_rgx))
continue;
/* Copy the regex into a struct, and hook this in at the end. */
newthing = nmalloc(sizeof(regexlisttype));
newthing->full_regex = copy_of(regexstring);
newthing->one_rgx = packed_rgx;
newthing->next = NULL;
if (lastthing == NULL)