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
master
Chris Allegretta 2002-01-18 21:54:35 +00:00
parent 5285ca9d0a
commit f478f8361e
4 changed files with 116 additions and 56 deletions

View File

@ -11,6 +11,10 @@ CVS code -
do_colorinit() do_colorinit()
- Moved some comments and braces around so color can work - Moved some comments and braces around so color can work
w/slang (DLR). 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: - nano.c:
usage() usage()
- Remove extra \n in --keypad description (Jordi). - Remove extra \n in --keypad description (Jordi).
@ -26,10 +30,22 @@ CVS code -
version() version()
- Show --enable-multibuffer independently of --enable-extra being - Show --enable-multibuffer independently of --enable-extra being
compiled in (Jordi). compiled in (Jordi).
- global.c: - nano.h:
shorcut_init() - Changed color struct slightly, because of previous issue with
- Replace hard coded ALT_G and ALT_H values in the replace applying color painting in order, the "str" portion was
and goto shortcuts with their macro counterparts NANO_ALT_*_KEY. 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: - search.c:
findnextstr() findnextstr()
- Fix off by one in check for wrap around (Rocco Corsi). - Fix off by one in check for wrap around (Rocco Corsi).
@ -37,6 +53,11 @@ CVS code -
edit_refresh() edit_refresh()
- Rename lines to nlines to fix AIX breakage (reported by - Rename lines to nlines to fix AIX breakage (reported by
Dennis Cranston, re-reported by arh14@cornell.edu). 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: - THANKS:
- Oops, correct Eivind's entry. His translation was Norwegian nynorsk, - Oops, correct Eivind's entry. His translation was Norwegian nynorsk,
not bokmål as we claimed (Jordi). not bokmål as we claimed (Jordi).

8
nano.h
View File

@ -121,17 +121,13 @@ typedef struct rcoption {
#define COLORSTRNUM 16 #define COLORSTRNUM 16
typedef struct colorstr {
char *val;
struct colorstr *next;
} colorstr;
typedef struct colortype { typedef struct colortype {
int fg; int fg;
int bg; int bg;
int bright; int bright;
int pairnum; int pairnum;
colorstr *str; char *start;
char *end;
struct colortype *next; struct colortype *next;
} colortype; } colortype;

126
rcfile.c
View File

@ -72,6 +72,10 @@ rcoption rcopts[NUM_RCOPTS] =
{"smooth", SMOOTHSCROLL}, {"smooth", SMOOTHSCROLL},
{"keypad", ALT_KEYPAD}}; {"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 /* 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 */ make the user hit return to continue starting up nano */
void rcfile_error(char *msg, ...) void rcfile_error(char *msg, ...)
@ -79,6 +83,7 @@ void rcfile_error(char *msg, ...)
va_list ap; va_list ap;
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, _("Error in %s on line %d: "), nanorc, lineno);
va_start(ap, msg); va_start(ap, msg);
vfprintf(stderr, msg, ap); vfprintf(stderr, msg, ap);
va_end(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 */ /* 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; va_list ap;
if (!*errors) { if (!errors) {
*errors = 1; errors = 1;
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
va_start(ap, msg); 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 */ /* Parse the next word from the string. Returns NULL if we hit EOL */
char *parse_next_word(char *ptr) 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++; ptr++;
prev = ptr;
}
if (*ptr == '\0') if (*ptr == '\0')
return NULL; return NULL;
/* Null terminate and advance ptr */ /* Null terminate and advance ptr */
*ptr++ = 0; *ptr++ = 0;
@ -123,7 +133,7 @@ char *parse_next_word(char *ptr)
return ptr; return ptr;
} }
int colortoint(char *colorname, int *bright, char *filename, int *lineno) int colortoint(char *colorname, int *bright)
{ {
int mcolor = 0; int mcolor = 0;
@ -152,11 +162,10 @@ int colortoint(char *colorname, int *bright, char *filename, int *lineno)
else if (!strcasecmp(colorname, "black")) else if (!strcasecmp(colorname, "black"))
mcolor += COLOR_BLACK; mcolor += COLOR_BLACK;
else { else {
printf("Error in %s on line %d: color %s not understood.\n", rcfile_error(_("color %s not understood.\n"
filename, *lineno, colorname); "Valid colors are \"green\", \"red\", \"blue\", \n"
printf("Valid colors are \"green\", \"red\", \"blue\", " "\"white\", \"yellow\", \"cyan\", \"magenta\" and \n"
"\"white\", \"yellow\", \"cyan\", \"magenta\" and " "\"black\", with the optional prefix \"bright\".\n"));
"\"black\", with the optional prefix \"bright\".\n");
exit(1); exit(1);
} }
@ -166,9 +175,10 @@ int colortoint(char *colorname, int *bright, char *filename, int *lineno)
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
/* Parse the color stuff into the colorstrings array */ /* 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 prev = '\\';
char *tmp = NULL, *beginning, *fgstr, *bgstr; char *tmp = NULL, *beginning, *fgstr, *bgstr;
colortype *tmpcolor = NULL; colortype *tmpcolor = NULL;
@ -177,8 +187,7 @@ void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char *
ptr = parse_next_word(ptr); ptr = parse_next_word(ptr);
if (ptr == NULL) { if (ptr == NULL) {
printf("Error in %s on line %d: Missing color name.\n", rcfile_error(_("Missing color name"));
filename, *lineno);
exit(1); exit(1);
} }
@ -188,29 +197,39 @@ void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char *
} else } else
bgstr = NULL; bgstr = NULL;
fg = colortoint(fgstr, &bright, filename, lineno); fg = colortoint(fgstr, &bright);
bg = colortoint(bgstr, &bright, filename, lineno); bg = colortoint(bgstr, &bright);
/* Now the fun part, start adding regexps to individual strings /* Now the fun part, start adding regexps to individual strings
in the colorstrings array, woo! */ in the colorstrings array, woo! */
if (!strncasecmp(ptr, "start=", 6)) {
ptr += 6;
expectend = 1;
}
i = 0; i = 0;
beginning = ptr; beginning = ptr;
while (*ptr != '\0') { while (*ptr != '\0' && !loopdone) {
switch (*ptr) { switch (*ptr) {
case '\n': case '\n':
*ptr = ' '; *ptr = ' ';
/* i++; */
case ' ': case ' ':
if (prev != '\\') { if (prev != '\\') {
/* This is the end of the regex, uh I guess. /* This is the end of the regex, uh I guess.
Add it to the colorstrings array for this color */ Add it to the colorstrings array for this color */
if (i == 0) {
rcfile_error(_("regex length much be > 0"));
continue;
}
tmp = NULL; tmp = NULL;
tmp = charalloc(i + 1); tmp = charalloc(i + 1);
strncpy(tmp, beginning, i); strncpy(tmp, beginning, i);
tmp[i] = '\0'; tmp[i] = '\0';
/* Get rid of the leading space */
ptr = parse_next_word(ptr); ptr = parse_next_word(ptr);
if (ptr == NULL) if (ptr == NULL)
return; return;
@ -220,31 +239,39 @@ void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char *
colorstrings->fg = fg; colorstrings->fg = fg;
colorstrings->bg = bg; colorstrings->bg = bg;
colorstrings->bright = bright; colorstrings->bright = bright;
colorstrings->str = NULL; colorstrings->start = tmp;
colorstrings->str = nmalloc(sizeof(colorstr));
colorstrings->str->val = tmp;
colorstrings->str->next = NULL;
colorstrings->next = NULL; 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 { } else {
for (tmpcolor = colorstrings; tmpcolor->next != NULL; for (tmpcolor = colorstrings; tmpcolor->next != NULL;
tmpcolor = tmpcolor->next) tmpcolor = tmpcolor->next)
; ;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Adding new entry for fg %d bg %d\n", fg, bg); fprintf(stderr, "Adding new entry for fg %d bg %d\n", fg, bg);
fprintf(stderr, "string val=%s\n", tmp);
#endif #endif
tmpcolor->next = nmalloc(sizeof(colortype)); tmpcolor->next = nmalloc(sizeof(colortype));
tmpcolor->next->fg = fg; tmpcolor->next->fg = fg;
tmpcolor->next->bg = bg; tmpcolor->next->bg = bg;
tmpcolor->next->bright = bright; tmpcolor->next->bright = bright;
tmpcolor->next->str = nmalloc(sizeof(colorstr)); tmpcolor->next->start = tmp;
tmpcolor->next->str->val = tmp;
tmpcolor->next->str->next = NULL;
tmpcolor->next->next = NULL; tmpcolor->next->next = NULL;
tmpcolor = tmpcolor->next;
} }
i = 0; i = 0;
beginning = ptr; beginning = ptr;
if (expectend)
loopdone = 1;
break; break;
} }
/* Else drop through to the default case */ /* 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 */ #endif /* ENABLE_COLOR */
/* Parse the RC file, once it has been opened successfully */ /* 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; char *buf, *ptr, *keyword, *option;
int set = 0, lineno = 0, i; int set = 0, i;
int errors = 0;
buf = charalloc(1024); buf = charalloc(1024);
while (fgets(buf, 1023, rcstream) > 0) { while (fgets(buf, 1023, rcstream) > 0) {
@ -297,11 +343,10 @@ void parse_rcfile(FILE *rcstream, char *filename)
set = -1; set = -1;
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
else if (!strcasecmp(keyword, "color")) else if (!strcasecmp(keyword, "color"))
parse_colors(rcstream, filename, &lineno, buf, ptr); parse_colors(rcstream, buf, ptr);
#endif /* ENABLE_COLOR */ #endif /* ENABLE_COLOR */
else { else {
rcfile_msg(&errors, _("Error in %s on line %d: command %s not understood"), rcfile_msg(_("command %s not understood"), keyword);
filename, lineno, keyword);
continue; continue;
} }
@ -331,8 +376,8 @@ void parse_rcfile(FILE *rcstream, char *filename)
) { ) {
if (*ptr == '\n' || *ptr == '\0') { if (*ptr == '\n' || *ptr == '\0') {
rcfile_msg(&errors, _("Error in %s on line %d: option %s requires an argument"), rcfile_error(_("option %s requires an argument"),
filename, lineno, rcopts[i].name); rcopts[i].name);
continue; continue;
} }
option = ptr; option = ptr;
@ -341,18 +386,16 @@ void parse_rcfile(FILE *rcstream, char *filename)
#ifndef DISABLE_WRAPJUSTIFY #ifndef DISABLE_WRAPJUSTIFY
if ((i = atoi(option)) < MIN_FILL_LENGTH) { if ((i = atoi(option)) < MIN_FILL_LENGTH) {
rcfile_msg(&errors, rcfile_error(
_("Error in %s on line %d: requested fill size %d too small"), _("requested fill size %d too small"), i);
filename, lineno, i);
} }
else else
fill = i; fill = i;
#endif #endif
} else if (!strcasecmp(rcopts[i].name, "tabsize")) { } else if (!strcasecmp(rcopts[i].name, "tabsize")) {
if ((i = atoi(option)) <= 0) { if ((i = atoi(option)) <= 0) {
rcfile_msg(&errors, rcfile_error(
_("Error in %s on line %d: requested tab size %d too small"), _("requested tab size %d too small"), i);
filename, lineno, i);
} else { } else {
tabsize = i; tabsize = i;
} }
@ -387,7 +430,6 @@ void parse_rcfile(FILE *rcstream, char *filename)
/* The main rc file function, tries to open the rc file */ /* The main rc file function, tries to open the rc file */
void do_rcfile(void) void do_rcfile(void)
{ {
char *nanorc;
char *unable = _("Unable to open ~/.nanorc file, %s"); char *unable = _("Unable to open ~/.nanorc file, %s");
struct stat fileinfo; struct stat fileinfo;
FILE *rcstream; FILE *rcstream;
@ -413,7 +455,7 @@ void do_rcfile(void)
return; return;
} }
parse_rcfile(rcstream, nanorc); parse_rcfile(rcstream);
fclose(rcstream); fclose(rcstream);
} }

View File

@ -773,7 +773,6 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
colortype *tmpcolor = NULL; colortype *tmpcolor = NULL;
colorstr *tmpstr = NULL;
int k, paintlen; int k, paintlen;
#endif #endif
@ -787,13 +786,16 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
if (colorstrings != NULL) if (colorstrings != NULL)
for (tmpcolor = colorstrings; tmpcolor != NULL; tmpcolor = tmpcolor->next) { for (tmpcolor = colorstrings; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
for (tmpstr = tmpcolor->str; tmpstr != NULL; tmpstr = tmpstr->next) {
k = start; k = start;
regcomp(&search_regexp, tmpstr->val, 0); regcomp(&search_regexp, tmpcolor->start, 0);
while (!regexec(&search_regexp, &fileptr->data[k], 1, while (!regexec(&search_regexp, &fileptr->data[k], 1,
regmatches, 0)) { regmatches, 0)) {
if (regmatches[0].rm_eo - regmatches[0].rm_so < 1) {
statusbar("Refusing 0 length regex match");
break;
}
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Match! (%d chars) \"%s\"\n", fprintf(stderr, "Match! (%d chars) \"%s\"\n",
regmatches[0].rm_eo - regmatches[0].rm_so, 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)); wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
k += regmatches[0].rm_eo; k += regmatches[0].rm_eo;
}
} }
} }
#endif /* ENABLE_COLOR */ #endif /* ENABLE_COLOR */