]> git.wh0rd.org Git - nano.git/commitdiff
DB's debug and multibuffer and regcomp fix to make nano less of a complete cpu hog
authorChris Allegretta <chrisa@asty.org>
Mon, 3 Feb 2003 02:56:44 +0000 (02:56 +0000)
committerChris Allegretta <chrisa@asty.org>
Mon, 3 Feb 2003 02:56:44 +0000 (02:56 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1411 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
color.c
global.c
nano.h
proto.h
rcfile.c
winio.c

index e8a66739f3f452b8c9e34bfd6f8ea2127d992ba3..612c7a8d94fe3d8ff3856b22cf13229f1de8883f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -21,6 +21,10 @@ CVS Code -
          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 @@ CVS Code -
          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 e11888909bf4506cbddd146a74f8801c84daedf0..c2d0daa302799d043373f2560d40343f7969d02c 100644 (file)
--- a/color.c
+++ b/color.c
@@ -108,15 +108,10 @@ void update_color(void)
        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;
        }
index 8fdd288f090322cd6d26b2bdfbe2dcb623af9d2f..9cda4384792f3dd2605008e05d690a3f78547bfa 100644 (file)
--- a/global.c
+++ b/global.c
@@ -856,10 +856,12 @@ void thanks_for_all_the_fish(void)
 #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 @@ void thanks_for_all_the_fish(void)
            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 c85743e07fc0a6d4bf4b608ed272219cfddebe91..de0fe7c304411ce020080d90a974f2bc6deb7157 100644 (file)
--- a/nano.h
+++ b/nano.h
@@ -182,13 +182,13 @@ typedef struct colortype {
     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 530f552a3950eb16252a8911c489bef58ed7860c..9809362371622ac4de996b4c3dcefc275626cd49 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -326,6 +326,7 @@ char *parse_argument(char *ptr);
 #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 */
index ac37ac870ef8bbc573a76dcc7ea5625a8d82a516..0c43b50000133b531d3cd895078af571384ad963 100644 (file)
--- a/rcfile.c
+++ b/rcfile.c
@@ -240,11 +240,29 @@ char *parse_next_regex(char *ptr)
     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 @@ void parse_syntax(char *ptr)
 
     /* 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 @@ void parse_syntax(char *ptr)
        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 @@ void parse_colors(char *ptr)
        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 @@ void parse_colors(char *ptr)
        }
        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
+       newcolor = (colortype *)nmalloc(sizeof(colortype));
+       fgstr = ptr;
+       ptr = parse_next_regex(ptr);
+       if (nregcomp(&newcolor->start, fgstr, 0)) {
+           free(newcolor);
+           cancelled = 1;
        } else {
-           for (tmpcolor = tmpsyntax->color;
-                tmpcolor->next != NULL; tmpcolor = tmpcolor->next);
+           newcolor->fg = fg;
+           newcolor->bg = bg;
+           newcolor->bright = bright;
+           newcolor->next = NULL;
+           newcolor->end = NULL;
+
+           if (tmpsyntax->color == NULL) {
+               tmpsyntax->color = newcolor;
 #ifdef DEBUG
-           fprintf(stderr, _("Adding new entry for fg %d bg %d\n"), fg, bg);
+               fprintf(stderr, _("Starting a new colorstring 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;
-       ptr = parse_next_regex(ptr);
-       tmpcolor->start = mallocstrcpy(NULL, tmpcolor->start);
+           } else {
+               for (tmpcolor = tmpsyntax->color; tmpcolor->next != NULL;
+                       tmpcolor = tmpcolor->next)
+                   ;
 #ifdef DEBUG
-       fprintf(stderr, _("string val=%s\n"), tmpcolor->start);
+               fprintf(stderr, _("Adding new entry for fg %d bg %d\n"), fg, bg);
 #endif
+               tmpcolor->next = newcolor;
+           }
+       }
 
-       if (!expectend)
-           tmpcolor->end = NULL;
-       else {
+       if (expectend) {
            if (ptr == NULL || strncasecmp(ptr, "end=", 4)) {
                rcfile_error(_
                             ("\"start=\" requires a corresponding \"end=\""));
@@ -417,13 +443,18 @@ void parse_colors(char *ptr)
            }
            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 e2afb3d7ea630801080907cf9f2f1382d4e68da5..740cf98b35962dc32d33f4ec1ab8ace7f7864d82 100644 (file)
--- a/winio.c
+++ b/winio.c
@@ -708,12 +708,9 @@ void edit_add(const filestruct *fileptr, int yval, int start
            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 @@ void edit_add(const filestruct *fileptr, int yval, int start
                     * 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 @@ void edit_add(const filestruct *fileptr, int yval, int start
                 * 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 @@ void edit_add(const filestruct *fileptr, int yval, int start
                    /* 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 @@ void edit_add(const filestruct *fileptr, int yval, int start
                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 @@ void edit_add(const filestruct *fileptr, int yval, int start
                 * 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 @@ void edit_add(const filestruct *fileptr, int yval, int start
   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 @@ void edit_add(const filestruct *fileptr, int yval, int start
                        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 @@ void edit_add(const filestruct *fileptr, int yval, int start
                        /* 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 @@ void edit_add(const filestruct *fileptr, int yval, int start
                    }
                    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 */