DB's debug and multibuffer and regcomp fix to make nano less of a complete cpu hog
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1411 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
diff --git a/ChangeLog b/ChangeLog
index e8a6673..612c7a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -21,6 +21,10 @@
regex (try "^*"). Changed regexp_init() to return
1 or 0 based on regcomp()'s return value and search_init
to exit with an error message (sorry Jordi!)
+ - Move regcomp into rcfile.c rather than each display refresh
+ of winio.c. New function rcfile.c:nregcomp().
+ This fixes much of nano's resource hogging behavior
+ in syntax higlighting. (David Benbennick).
- cut.c:
do_cut_text()
- Fix incorrect cursor location when cutting long lines
@@ -46,6 +50,9 @@
mode on. (DLR; found by David Benbennick)
save_history()
- Fix nrealloc return value being ignored (David Benbennick).
+- global.c:
+ thanks_for_all_the_fish()
+ - Fix compiling with DEBUG and multibuffer (David Benbennick).
- nano.c:
do_char()
- Remove unneeded check_statblank() (David Benbennick).
diff --git a/color.c b/color.c
index e118889..c2d0daa 100644
--- a/color.c
+++ b/color.c
@@ -108,15 +108,10 @@
const exttype *e;
for (e = tmpsyntax->extensions; e != NULL; e = e->next) {
- regex_t syntaxfile_regexp;
-
- regcomp(&syntaxfile_regexp, e->val, REG_EXTENDED | REG_NOSUB);
-
/* Set colorstrings if we matched the extension regex */
- if (!regexec(&syntaxfile_regexp, filename, 0, NULL, 0))
+ if (!regexec(&e->val, filename, 0, NULL, 0))
colorstrings = tmpsyntax->color;
- regfree(&syntaxfile_regexp);
if (colorstrings != NULL)
break;
}
diff --git a/global.c b/global.c
index 8fdd288..9cda438 100644
--- a/global.c
+++ b/global.c
@@ -856,10 +856,12 @@
#ifdef ENABLE_MULTIBUFFER
if (open_files != NULL) {
/* We free the memory associated with each open file. */
+ while (open_files->prev != NULL)
+ open_files = open_files->prev;
free_openfilestruct(open_files);
+ }
#else
- if (fileage != NULL)
- free_filestruct(fileage);
+ free_filestruct(fileage);
#endif
#ifdef ENABLE_COLOR
@@ -881,7 +883,8 @@
syntaxes->color = bob->next;
regfree(&bob->start);
if (bob->end != NULL)
- regfree(&bob->end);
+ regfree(bob->end);
+ free(bob->end);
free(bob);
}
syntaxes = syntaxes->next;
diff --git a/nano.h b/nano.h
index c85743e..de0fe7c 100644
--- a/nano.h
+++ b/nano.h
@@ -182,13 +182,13 @@
int bg; /* bg color */
int bright; /* Is this color A_BOLD? */
int pairnum; /* Color pair number used for this fg/bg */
- char *start; /* Start (or all) of the regex string */
- char *end; /* End of the regex string */
+ regex_t start; /* Start (or all) of the regex string */
+ regex_t *end; /* End of the regex string */
struct colortype *next;
} colortype;
typedef struct exttype {
- char *val;
+ regex_t val; /* The extensions that match this syntax. */
struct exttype *next;
} exttype;
diff --git a/proto.h b/proto.h
index 530f552..9809362 100644
--- a/proto.h
+++ b/proto.h
@@ -326,6 +326,7 @@
#ifdef ENABLE_COLOR
int colortoint(const char *colorname, int *bright);
char *parse_next_regex(char *ptr);
+int nregcomp(regex_t *preg, const char *regex, int flags);
void parse_syntax(char *ptr);
void parse_colors(char *ptr);
#endif /* ENABLE_COLOR */
diff --git a/rcfile.c b/rcfile.c
index ac37ac8..0c43b50 100644
--- a/rcfile.c
+++ b/rcfile.c
@@ -240,11 +240,29 @@
return ptr;
}
+/* Compile the regular expression regex to preg. Returns FALSE on success,
+ TRUE if the expression is invalid. */
+int nregcomp(regex_t *preg, const char *regex, int flags)
+{
+ int rc = regcomp(preg, regex, REG_EXTENDED | flags);
+
+ if (rc != 0) {
+ size_t len = regerror(rc, preg, NULL, 0);
+ char *str = charalloc(len);
+
+ regerror(rc, preg, str, len);
+ rcfile_error(_("Bad regex \"%s\": %s"), regex, str);
+ free(str);
+ }
+ return rc != 0;
+}
+
void parse_syntax(char *ptr)
{
syntaxtype *tmpsyntax = NULL;
const char *fileregptr = NULL, *nameptr = NULL;
- exttype *exttmp = NULL;
+ exttype *endext = NULL;
+ /* The end of the extensions list for this syntax. */
while (*ptr == ' ')
ptr++;
@@ -291,6 +309,9 @@
/* Now load in the extensions to their part of the struct */
while (*ptr != '\n' && *ptr != '\0') {
+ exttype *newext;
+ /* The new extension structure. */
+
while (*ptr != '"' && *ptr != '\n' && *ptr != '\0')
ptr++;
@@ -301,17 +322,17 @@
fileregptr = ptr;
ptr = parse_next_regex(ptr);
- if (tmpsyntax->extensions == NULL) {
- tmpsyntax->extensions = (exttype *)nmalloc(sizeof(exttype));
- exttmp = tmpsyntax->extensions;
- } else {
- for (exttmp = tmpsyntax->extensions; exttmp->next != NULL;
- exttmp = exttmp->next);
- exttmp->next = (exttype *)nmalloc(sizeof(exttype));
- exttmp = exttmp->next;
+ newext = (exttype *)nmalloc(sizeof(exttype));
+ if (nregcomp(&newext->val, fileregptr, REG_NOSUB))
+ free(newext);
+ else {
+ if (endext == NULL)
+ tmpsyntax->extensions = newext;
+ else
+ endext->next = newext;
+ endext = newext;
+ endext->next = NULL;
}
- exttmp->val = mallocstrcpy(NULL, fileregptr);
- exttmp->next = NULL;
}
}
@@ -353,6 +374,11 @@
in the colorstrings array, woo! */
while (*ptr != '\0') {
+ colortype *newcolor;
+ /* The new color structure. */
+ int cancelled = 0;
+ /* The start expression was bad. */
+
while (*ptr == ' ')
ptr++;
@@ -371,37 +397,37 @@
}
ptr++;
- if (tmpsyntax->color == NULL) {
- tmpsyntax->color = nmalloc(sizeof(colortype));
- tmpcolor = tmpsyntax->color;
-#ifdef DEBUG
- fprintf(stderr, _("Starting a new colorstring for fg %d bg %d\n"),
- fg, bg);
-#endif
- } else {
- for (tmpcolor = tmpsyntax->color;
- tmpcolor->next != NULL; tmpcolor = tmpcolor->next);
-#ifdef DEBUG
- fprintf(stderr, _("Adding new entry for fg %d bg %d\n"), fg, bg);
-#endif
- tmpcolor->next = nmalloc(sizeof(colortype));
- tmpcolor = tmpcolor->next;
- }
- tmpcolor->fg = fg;
- tmpcolor->bg = bg;
- tmpcolor->bright = bright;
- tmpcolor->next = NULL;
-
- tmpcolor->start = ptr;
+ newcolor = (colortype *)nmalloc(sizeof(colortype));
+ fgstr = ptr;
ptr = parse_next_regex(ptr);
- tmpcolor->start = mallocstrcpy(NULL, tmpcolor->start);
-#ifdef DEBUG
- fprintf(stderr, _("string val=%s\n"), tmpcolor->start);
-#endif
+ if (nregcomp(&newcolor->start, fgstr, 0)) {
+ free(newcolor);
+ cancelled = 1;
+ } else {
+ newcolor->fg = fg;
+ newcolor->bg = bg;
+ newcolor->bright = bright;
+ newcolor->next = NULL;
+ newcolor->end = NULL;
- if (!expectend)
- tmpcolor->end = NULL;
- else {
+ if (tmpsyntax->color == NULL) {
+ tmpsyntax->color = newcolor;
+#ifdef DEBUG
+ fprintf(stderr, _("Starting a new colorstring for fg %d bg %d\n"),
+ fg, bg);
+#endif
+ } else {
+ for (tmpcolor = tmpsyntax->color; tmpcolor->next != NULL;
+ tmpcolor = tmpcolor->next)
+ ;
+#ifdef DEBUG
+ fprintf(stderr, _("Adding new entry for fg %d bg %d\n"), fg, bg);
+#endif
+ tmpcolor->next = newcolor;
+ }
+ }
+
+ if (expectend) {
if (ptr == NULL || strncasecmp(ptr, "end=", 4)) {
rcfile_error(_
("\"start=\" requires a corresponding \"end=\""));
@@ -417,13 +443,18 @@
}
ptr++;
- tmpcolor->end = ptr;
+ fgstr = ptr;
ptr = parse_next_regex(ptr);
- tmpcolor->end = mallocstrcpy(NULL, tmpcolor->end);
-#ifdef DEBUG
- fprintf(stderr, _("For end part, beginning = \"%s\"\n"),
- tmpcolor->end);
-#endif
+
+ /* If the start regex was invalid, skip past the end regex to
+ * stay in sync. */
+ if (cancelled)
+ continue;
+ newcolor->end = (regex_t *)nmalloc(sizeof(regex_t));
+ if (nregcomp(newcolor->end, fgstr, 0)) {
+ free(newcolor->end);
+ newcolor->end = NULL;
+ }
}
}
}
diff --git a/winio.c b/winio.c
index e2afb3d..740cf98 100644
--- a/winio.c
+++ b/winio.c
@@ -708,12 +708,9 @@
int paintlen;
/* number of chars to paint on this line. There are COLS
* characters on a whole line. */
- regex_t start_regexp; /* Compiled search regexp */
regmatch_t startmatch; /* match position for start_regexp*/
regmatch_t endmatch; /* match position for end_regexp*/
- regcomp(&start_regexp, tmpcolor->start, REG_EXTENDED);
-
if (tmpcolor->bright)
wattron(edit, A_BOLD);
wattron(edit, COLOR_PAIR(tmpcolor->pairnum));
@@ -734,7 +731,7 @@
* match the beginning-of-line character unless
* k == 0. If regexec returns nonzero, there are no
* more matches in the line. */
- if (regexec(&start_regexp, &fileptr->data[k], 1,
+ if (regexec(&tmpcolor->start, &fileptr->data[k], 1,
&startmatch, k == 0 ? 0 : REG_NOTBOL))
break;
/* Translate the match to the beginning of the line. */
@@ -771,7 +768,6 @@
* after start_line matching the end. If that line is not
* before fileptr, then paint the beginning of this line. */
- regex_t end_regexp; /* Compiled search regexp */
const filestruct *start_line = fileptr->prev;
/* the first line before fileptr matching start*/
regoff_t start_col;
@@ -781,14 +777,12 @@
/* Used in step 2. Have we looked for an end on
* lines after fileptr? */
- regcomp(&end_regexp, tmpcolor->end, REG_EXTENDED);
-
while (start_line != NULL &&
- regexec(&start_regexp, start_line->data, 1,
+ regexec(&tmpcolor->start, start_line->data, 1,
&startmatch, 0)) {
/* If there is an end on this line, there is no need
* to look for starts on earlier lines. */
- if (!regexec(&end_regexp, start_line->data, 1,
+ if (!regexec(tmpcolor->end, start_line->data, 1,
&endmatch, 0))
goto step_two;
start_line = start_line->prev;
@@ -804,14 +798,14 @@
while (1) {
start_col += startmatch.rm_so;
startmatch.rm_eo -= startmatch.rm_so;
- if (regexec(&end_regexp,
+ if (regexec(tmpcolor->end,
start_line->data + start_col + startmatch.rm_eo,
1, &endmatch,
start_col + startmatch.rm_eo == 0 ? 0 : REG_NOTBOL))
/* No end found after this start */
break;
start_col++;
- if (regexec(&start_regexp,
+ if (regexec(&tmpcolor->start,
start_line->data + start_col, 1, &startmatch,
REG_NOTBOL))
/* No later start on this line. */
@@ -824,8 +818,8 @@
* fileptr and after the start. Is there an end after
* the start at all? We don't paint unterminated starts. */
end_line = fileptr;
- while (end_line != NULL && regexec(&end_regexp, end_line->data,
- 1, &endmatch, 0))
+ while (end_line != NULL &&
+ regexec(tmpcolor->end, end_line->data, 1, &endmatch, 0))
end_line = end_line->next;
/* No end found, or it is too early. */
@@ -850,7 +844,7 @@
step_two: /* Second step, we look for starts on this line. */
start_col = 0;
while (start_col < start + COLS) {
- if (regexec(&start_regexp, fileptr->data + start_col, 1,
+ if (regexec(&tmpcolor->start, fileptr->data + start_col, 1,
&startmatch, start_col == 0 ? 0 : REG_NOTBOL)
|| start_col + startmatch.rm_so >= start + COLS)
/* No more starts on this line. */
@@ -865,7 +859,7 @@
x_start = 0;
startmatch.rm_so = start;
}
- if (!regexec(&end_regexp, fileptr->data + startmatch.rm_eo,
+ if (!regexec(tmpcolor->end, fileptr->data + startmatch.rm_eo,
1, &endmatch,
startmatch.rm_eo == 0 ? 0 : REG_NOTBOL)) {
/* Translate the end match to be relative to the
@@ -891,7 +885,7 @@
/* There is no end on this line. But we haven't
* yet looked for one on later lines. */
end_line = fileptr->next;
- while (end_line != NULL && regexec(&end_regexp,
+ while (end_line != NULL && regexec(tmpcolor->end,
end_line->data, 1, &endmatch, 0))
end_line = end_line->next;
if (end_line != NULL) {
@@ -906,12 +900,9 @@
}
start_col = startmatch.rm_so + 1;
} /* while start_col < start + COLS */
-
- skip_step_two:
- regfree(&end_regexp);
} /* if (tmp_color->end != NULL) */
- regfree(&start_regexp);
+ skip_step_two:
wattroff(edit, A_BOLD);
wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
} /* for tmpcolor in colorstrings */