From f478f8361e986e9fad2ff4e3716f87e0185f7e9f Mon Sep 17 00:00:00 2001 From: Chris Allegretta Date: Fri, 18 Jan 2002 21:54:35 +0000 Subject: [PATCH] Latest color and regex fixes. Multi-line color doesn't work yet, just syncing in case of disaster git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1016 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 29 +++++++++++-- nano.h | 8 +--- rcfile.c | 126 ++++++++++++++++++++++++++++++++++++------------------ winio.c | 9 ++-- 4 files changed, 116 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 37fb46b0..f0dbcae6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,10 @@ CVS code - do_colorinit() - Moved some comments and braces around so color can work w/slang (DLR). +- global.c: + shorcut_init() + - Replace hard coded ALT_G and ALT_H values in the replace + and goto shortcuts with their macro counterparts NANO_ALT_*_KEY. - nano.c: usage() - Remove extra \n in --keypad description (Jordi). @@ -26,10 +30,22 @@ CVS code - version() - Show --enable-multibuffer independently of --enable-extra being compiled in (Jordi). -- global.c: - shorcut_init() - - Replace hard coded ALT_G and ALT_H values in the replace - and goto shortcuts with their macro counterparts NANO_ALT_*_KEY. +- nano.h: + - Changed color struct slightly, because of previous issue with + applying color painting in order, the "str" portion was + uselss. Renamed "val" in colortype to "start", added "end" + for multi-line color strings. +- rcfile.c: + General + - Took silly variables being passed everywhere like lineno and + filename and made them static variables. + rcfile_error() + - Now automatically prpends the "error in line blah at foo" + message to error messages. + parse_colors() + - Added section for computing "end" section. + parse_next_word() + - Added support for "\ ", in word parsing. - search.c: findnextstr() - Fix off by one in check for wrap around (Rocco Corsi). @@ -37,6 +53,11 @@ CVS code - edit_refresh() - Rename lines to nlines to fix AIX breakage (reported by Dennis Cranston, re-reported by arh14@cornell.edu). + edit_add() + - Refuse to honor regex matches of 0 characters when applying + color highlighting, and say so on the statusbar. Otherwise + we go into an infinite loop, the error message should clue + users into the fact that their regex is doing something bad. - THANKS: - Oops, correct Eivind's entry. His translation was Norwegian nynorsk, not bokmål as we claimed (Jordi). diff --git a/nano.h b/nano.h index dd585d1b..7947fe87 100644 --- a/nano.h +++ b/nano.h @@ -121,17 +121,13 @@ typedef struct rcoption { #define COLORSTRNUM 16 -typedef struct colorstr { - char *val; - struct colorstr *next; -} colorstr; - typedef struct colortype { int fg; int bg; int bright; int pairnum; - colorstr *str; + char *start; + char *end; struct colortype *next; } colortype; diff --git a/rcfile.c b/rcfile.c index 48292206..8307450f 100644 --- a/rcfile.c +++ b/rcfile.c @@ -72,6 +72,10 @@ rcoption rcopts[NUM_RCOPTS] = {"smooth", SMOOTHSCROLL}, {"keypad", ALT_KEYPAD}}; +static int errors = 0; +static int lineno = 0; +static char *nanorc; + /* We have an error in some part of the rcfile; put it on stderr and make the user hit return to continue starting up nano */ void rcfile_error(char *msg, ...) @@ -79,6 +83,7 @@ void rcfile_error(char *msg, ...) va_list ap; fprintf(stderr, "\n"); + fprintf(stderr, _("Error in %s on line %d: "), nanorc, lineno); va_start(ap, msg); vfprintf(stderr, msg, ap); va_end(ap); @@ -90,12 +95,12 @@ void rcfile_error(char *msg, ...) } /* Just print the error (one of many, perhaps) but don't abort, yet */ -void rcfile_msg(int *errors, char *msg, ...) +void rcfile_msg(char *msg, ...) { va_list ap; - if (!*errors) { - *errors = 1; + if (!errors) { + errors = 1; fprintf(stderr, "\n"); } va_start(ap, msg); @@ -108,12 +113,17 @@ void rcfile_msg(int *errors, char *msg, ...) /* Parse the next word from the string. Returns NULL if we hit EOL */ char *parse_next_word(char *ptr) { - while (*ptr != ' ' && *ptr != '\t' && *ptr != '\n' && *ptr != '\0') + char *prev = " "; + + while ((*ptr != ' ' || *prev == '\\') + && *ptr != '\t' && *ptr != '\n' && *ptr != '\0') { ptr++; + prev = ptr; + } if (*ptr == '\0') return NULL; - + /* Null terminate and advance ptr */ *ptr++ = 0; @@ -123,7 +133,7 @@ char *parse_next_word(char *ptr) return ptr; } -int colortoint(char *colorname, int *bright, char *filename, int *lineno) +int colortoint(char *colorname, int *bright) { int mcolor = 0; @@ -152,11 +162,10 @@ int colortoint(char *colorname, int *bright, char *filename, int *lineno) else if (!strcasecmp(colorname, "black")) mcolor += COLOR_BLACK; else { - printf("Error in %s on line %d: color %s not understood.\n", - filename, *lineno, colorname); - printf("Valid colors are \"green\", \"red\", \"blue\", " - "\"white\", \"yellow\", \"cyan\", \"magenta\" and " - "\"black\", with the optional prefix \"bright\".\n"); + rcfile_error(_("color %s not understood.\n" + "Valid colors are \"green\", \"red\", \"blue\", \n" + "\"white\", \"yellow\", \"cyan\", \"magenta\" and \n" + "\"black\", with the optional prefix \"bright\".\n")); exit(1); } @@ -166,9 +175,10 @@ int colortoint(char *colorname, int *bright, char *filename, int *lineno) #ifdef ENABLE_COLOR /* Parse the color stuff into the colorstrings array */ -void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char *ptr) +void parse_colors(FILE *rcstream, char *buf, char *ptr) { - int i = 0, fg, bg, bright = 0; + int i = 0, fg, bg, bright = 0, loopdone = 0; + int expectend = 0; /* Do we expect an end= line? */ char prev = '\\'; char *tmp = NULL, *beginning, *fgstr, *bgstr; colortype *tmpcolor = NULL; @@ -177,8 +187,7 @@ void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char * ptr = parse_next_word(ptr); if (ptr == NULL) { - printf("Error in %s on line %d: Missing color name.\n", - filename, *lineno); + rcfile_error(_("Missing color name")); exit(1); } @@ -188,29 +197,39 @@ void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char * } else bgstr = NULL; - fg = colortoint(fgstr, &bright, filename, lineno); - bg = colortoint(bgstr, &bright, filename, lineno); + fg = colortoint(fgstr, &bright); + bg = colortoint(bgstr, &bright); /* Now the fun part, start adding regexps to individual strings in the colorstrings array, woo! */ + if (!strncasecmp(ptr, "start=", 6)) { + ptr += 6; + expectend = 1; + } + i = 0; beginning = ptr; - while (*ptr != '\0') { + while (*ptr != '\0' && !loopdone) { switch (*ptr) { case '\n': *ptr = ' '; -/* i++; */ case ' ': if (prev != '\\') { /* This is the end of the regex, uh I guess. Add it to the colorstrings array for this color */ + + if (i == 0) { + rcfile_error(_("regex length much be > 0")); + continue; + } tmp = NULL; tmp = charalloc(i + 1); strncpy(tmp, beginning, i); tmp[i] = '\0'; + /* Get rid of the leading space */ ptr = parse_next_word(ptr); if (ptr == NULL) return; @@ -220,31 +239,39 @@ void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char * colorstrings->fg = fg; colorstrings->bg = bg; colorstrings->bright = bright; - colorstrings->str = NULL; - colorstrings->str = nmalloc(sizeof(colorstr)); - colorstrings->str->val = tmp; - colorstrings->str->next = NULL; + colorstrings->start = tmp; colorstrings->next = NULL; + tmpcolor = colorstrings; + +#ifdef DEBUG + fprintf(stderr, "Starting a new colorstring for fg %d bg %d\n", fg, bg); + fprintf(stderr, "string val=%s\n", tmp); +#endif + } else { for (tmpcolor = colorstrings; tmpcolor->next != NULL; tmpcolor = tmpcolor->next) ; #ifdef DEBUG fprintf(stderr, "Adding new entry for fg %d bg %d\n", fg, bg); + fprintf(stderr, "string val=%s\n", tmp); #endif tmpcolor->next = nmalloc(sizeof(colortype)); tmpcolor->next->fg = fg; tmpcolor->next->bg = bg; tmpcolor->next->bright = bright; - tmpcolor->next->str = nmalloc(sizeof(colorstr)); - tmpcolor->next->str->val = tmp; - tmpcolor->next->str->next = NULL; + tmpcolor->next->start = tmp; tmpcolor->next->next = NULL; + tmpcolor = tmpcolor->next; } i = 0; beginning = ptr; + + if (expectend) + loopdone = 1; + break; } /* Else drop through to the default case */ @@ -256,15 +283,34 @@ void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char * } } + if (expectend) { + if (ptr == NULL || strncasecmp(ptr, "end=", 4)) { + rcfile_error( + _("\n\t\"start=\" requires a corresponding \"end=\"")); + return; + } + + ptr += 4; + beginning = ptr; + ptr = parse_next_word(ptr); +#ifdef DEBUG + fprintf(stderr, "For end part, beginning = \"%s\"\n", beginning); +#endif + tmp = NULL; + tmp = mallocstrcpy(tmp, beginning); + tmpcolor->end = tmp; + + } + + } #endif /* ENABLE_COLOR */ /* Parse the RC file, once it has been opened successfully */ -void parse_rcfile(FILE *rcstream, char *filename) +void parse_rcfile(FILE *rcstream) { char *buf, *ptr, *keyword, *option; - int set = 0, lineno = 0, i; - int errors = 0; + int set = 0, i; buf = charalloc(1024); while (fgets(buf, 1023, rcstream) > 0) { @@ -297,11 +343,10 @@ void parse_rcfile(FILE *rcstream, char *filename) set = -1; #ifdef ENABLE_COLOR else if (!strcasecmp(keyword, "color")) - parse_colors(rcstream, filename, &lineno, buf, ptr); + parse_colors(rcstream, buf, ptr); #endif /* ENABLE_COLOR */ else { - rcfile_msg(&errors, _("Error in %s on line %d: command %s not understood"), - filename, lineno, keyword); + rcfile_msg(_("command %s not understood"), keyword); continue; } @@ -331,8 +376,8 @@ void parse_rcfile(FILE *rcstream, char *filename) ) { if (*ptr == '\n' || *ptr == '\0') { - rcfile_msg(&errors, _("Error in %s on line %d: option %s requires an argument"), - filename, lineno, rcopts[i].name); + rcfile_error(_("option %s requires an argument"), + rcopts[i].name); continue; } option = ptr; @@ -341,18 +386,16 @@ void parse_rcfile(FILE *rcstream, char *filename) #ifndef DISABLE_WRAPJUSTIFY if ((i = atoi(option)) < MIN_FILL_LENGTH) { - rcfile_msg(&errors, - _("Error in %s on line %d: requested fill size %d too small"), - filename, lineno, i); + rcfile_error( + _("requested fill size %d too small"), i); } else fill = i; #endif } else if (!strcasecmp(rcopts[i].name, "tabsize")) { if ((i = atoi(option)) <= 0) { - rcfile_msg(&errors, - _("Error in %s on line %d: requested tab size %d too small"), - filename, lineno, i); + rcfile_error( + _("requested tab size %d too small"), i); } else { tabsize = i; } @@ -387,7 +430,6 @@ void parse_rcfile(FILE *rcstream, char *filename) /* The main rc file function, tries to open the rc file */ void do_rcfile(void) { - char *nanorc; char *unable = _("Unable to open ~/.nanorc file, %s"); struct stat fileinfo; FILE *rcstream; @@ -413,7 +455,7 @@ void do_rcfile(void) return; } - parse_rcfile(rcstream, nanorc); + parse_rcfile(rcstream); fclose(rcstream); } diff --git a/winio.c b/winio.c index d1a41cb2..634961c0 100644 --- a/winio.c +++ b/winio.c @@ -773,7 +773,6 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, #ifdef ENABLE_COLOR colortype *tmpcolor = NULL; - colorstr *tmpstr = NULL; int k, paintlen; #endif @@ -787,13 +786,16 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, #ifdef ENABLE_COLOR if (colorstrings != NULL) for (tmpcolor = colorstrings; tmpcolor != NULL; tmpcolor = tmpcolor->next) { - for (tmpstr = tmpcolor->str; tmpstr != NULL; tmpstr = tmpstr->next) { k = start; - regcomp(&search_regexp, tmpstr->val, 0); + regcomp(&search_regexp, tmpcolor->start, 0); while (!regexec(&search_regexp, &fileptr->data[k], 1, regmatches, 0)) { + if (regmatches[0].rm_eo - regmatches[0].rm_so < 1) { + statusbar("Refusing 0 length regex match"); + break; + } #ifdef DEBUG fprintf(stderr, "Match! (%d chars) \"%s\"\n", regmatches[0].rm_eo - regmatches[0].rm_so, @@ -821,7 +823,6 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, wattroff(edit, COLOR_PAIR(tmpcolor->pairnum)); k += regmatches[0].rm_eo; - } } } #endif /* ENABLE_COLOR */ -- 2.39.5