From: David Lawrence Ramsey Date: Thu, 10 Mar 2005 20:55:11 +0000 (+0000) Subject: add DB's overhaul of the rcfile parsing code and related miscellaneous X-Git-Tag: v1.3.6~58 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=202d3c2f9756d4c05a19839bc73eb5c643737691;p=nano.git add DB's overhaul of the rcfile parsing code and related miscellaneous bits git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2345 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- diff --git a/ChangeLog b/ChangeLog index 2766216d..b13c15dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -162,6 +162,15 @@ CVS code - routine to get the current user's home directory into the new function get_homedir(), and use it where necessary. Also add a few miscellaneous tweaks. + - Overhaul the rcfile parsing code to make it simpler and more + accurate, remove now-redundant checks from the color code, + change the COLOR_SYNTAX toggle to the NO_COLOR_SYMTAX toggle, + and improve various debugging messsages. Changes to + set_colorpairs(), do_colorinit(), parse_next_word(), + parse_argument(), colortoint(), parse_next_regex(), + parse_syntax(), parse_colors(), parse_rcfile(), do_rcfile(), + etc. (David Benbennick) DLR: Rename colortoint() to + color_to_int(), and add a few miscellaneous tweaks. - cut.c: do_cut_text() - If keep_cutbuffer is FALSE, only blow away the text in the diff --git a/src/color.c b/src/color.c index fc87958c..4eed7d67 100644 --- a/src/color.c +++ b/src/color.c @@ -2,7 +2,7 @@ /************************************************************************** * color.c * * * - * Copyright (C) 1999-2004 Chris Allegretta * + * Copyright (C) 1999-2005 Chris Allegretta * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2, or (at your option) * @@ -46,14 +46,14 @@ void set_colorpairs(void) for (; this_color != NULL; this_color = this_color->next) { const colortype *beforenow = this_syntax->color; - for (; beforenow != NULL && beforenow != this_color && - (beforenow->fg != this_color->fg || - beforenow->bg != this_color->bg || - beforenow->bright != this_color->bright); - beforenow = beforenow->next) + for (; beforenow != this_color && + (beforenow->fg != this_color->fg || + beforenow->bg != this_color->bg || + beforenow->bright != this_color->bright); + beforenow = beforenow->next) ; - if (beforenow != NULL && beforenow != this_color) + if (beforenow != this_color) this_color->pairnum = beforenow->pairnum; else { this_color->pairnum = color_pair; @@ -68,14 +68,14 @@ void do_colorinit(void) if (has_colors()) { const colortype *tmpcolor = NULL; #ifdef HAVE_USE_DEFAULT_COLORS - int defok; + bool defok; #endif start_color(); - /* Add in colors, if available */ + /* Add in colors, if available. */ #ifdef HAVE_USE_DEFAULT_COLORS - defok = use_default_colors() != ERR; + defok = (use_default_colors() != ERR); #endif for (tmpcolor = colorstrings; tmpcolor != NULL; @@ -91,8 +91,8 @@ void do_colorinit(void) init_pair(tmpcolor->pairnum, tmpcolor->fg, background); #ifdef DEBUG - fprintf(stderr, "Running %s with fg = %d and bg = %d\n", - "init_pair()", tmpcolor->fg, tmpcolor->bg); + fprintf(stderr, "init_pair(): fg = %d, bg = %d\n", + tmpcolor->fg, tmpcolor->bg); #endif } } @@ -104,11 +104,12 @@ void update_color(void) const syntaxtype *tmpsyntax; colorstrings = NULL; - for (tmpsyntax = syntaxes; tmpsyntax != NULL; tmpsyntax = tmpsyntax->next) { + for (tmpsyntax = syntaxes; tmpsyntax != NULL; + tmpsyntax = tmpsyntax->next) { const exttype *e; for (e = tmpsyntax->extensions; e != NULL; e = e->next) { - /* Set colorstrings if we matched the extension regex */ + /* Set colorstrings if we matched the extension regex. */ if (regexec(&e->val, filename, 0, NULL, 0) == 0) colorstrings = tmpsyntax->color; @@ -117,10 +118,10 @@ void update_color(void) } } - /* if we haven't found a match, use the override string */ + /* If we haven't found a match, use the override string. */ if (colorstrings == NULL && syntaxstr != NULL) { for (tmpsyntax = syntaxes; tmpsyntax != NULL; - tmpsyntax = tmpsyntax->next) { + tmpsyntax = tmpsyntax->next) { if (strcasecmp(tmpsyntax->desc, syntaxstr) == 0) colorstrings = tmpsyntax->color; } diff --git a/src/files.c b/src/files.c index a80249cc..f0b99de5 100644 --- a/src/files.c +++ b/src/files.c @@ -54,7 +54,7 @@ void new_file(void) #ifdef ENABLE_COLOR update_color(); - if (ISSET(COLOR_SYNTAX)) + if (!ISSET(NO_COLOR_SYNTAX)) edit_refresh(); #endif } @@ -675,7 +675,7 @@ void do_insertfile( break; } - } /* while (TRUE) */ + } free(ans); } @@ -1640,7 +1640,7 @@ int write_file(const char *name, bool tmp, int append, bool filename = mallocstrcpy(filename, realname); #ifdef ENABLE_COLOR update_color(); - if (ISSET(COLOR_SYNTAX)) + if (!ISSET(NO_COLOR_SYNTAX)) edit_refresh(); #endif } diff --git a/src/global.c b/src/global.c index 54556f78..5c2996bd 100644 --- a/src/global.c +++ b/src/global.c @@ -1106,7 +1106,7 @@ void toggle_init(void) SMART_HOME); #ifdef ENABLE_COLOR toggle_init_one(TOGGLE_SYNTAX_KEY, N_("Color syntax highlighting"), - COLOR_SYNTAX); + NO_COLOR_SYNTAX); #endif #ifdef ENABLE_NANORC toggle_init_one(TOGGLE_WHITESPACE_KEY, N_("Whitespace display"), diff --git a/src/nano.c b/src/nano.c index 08ebcbe6..4c1b4960 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1299,7 +1299,7 @@ void do_delete(void) #ifdef ENABLE_COLOR /* If color syntaxes are turned on, we need to call * edit_refresh(). */ - if (ISSET(COLOR_SYNTAX)) + if (!ISSET(NO_COLOR_SYNTAX)) do_refresh = TRUE; #endif @@ -3833,7 +3833,7 @@ void do_output(char *output, size_t output_len) #ifdef ENABLE_COLOR /* If color syntaxes are turned on, we need to call * edit_refresh(). */ - if (ISSET(COLOR_SYNTAX)) + if (!ISSET(NO_COLOR_SYNTAX)) do_refresh = TRUE; #endif } diff --git a/src/nano.h b/src/nano.h index 51457f33..c3c80d6f 100644 --- a/src/nano.h +++ b/src/nano.h @@ -291,7 +291,7 @@ typedef struct historyheadtype { #define NO_CONVERT (1<<19) #define BACKUP_FILE (1<<20) #define NO_RCFILE (1<<21) -#define COLOR_SYNTAX (1<<22) +#define NO_COLOR_SYNTAX (1<<22) #define PRESERVE (1<<23) #define HISTORY_CHANGED (1<<24) #define HISTORYLOG (1<<25) diff --git a/src/proto.h b/src/proto.h index 7618c12d..a39217a6 100644 --- a/src/proto.h +++ b/src/proto.h @@ -462,9 +462,9 @@ void rcfile_error(const char *msg, ...); char *parse_next_word(char *ptr); char *parse_argument(char *ptr); #ifdef ENABLE_COLOR -int colortoint(const char *colorname, int *bright); +int color_to_int(const char *colorname, bool *bright); char *parse_next_regex(char *ptr); -int nregcomp(regex_t *preg, const char *regex, int eflags); +bool nregcomp(regex_t *preg, const char *regex, int eflags); void parse_syntax(char *ptr); void parse_colors(char *ptr); #endif /* ENABLE_COLOR */ diff --git a/src/rcfile.c b/src/rcfile.c index 467fa0ef..a1b60e2f 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include "proto.h" @@ -102,10 +101,16 @@ const static rcoption rcopts[] = { static bool errors = FALSE; static int lineno = 0; -static const char *nanorc; +static char *nanorc = NULL; +#ifdef ENABLE_COLOR +static syntaxtype *endsyntax = NULL; + /* The end of the list of syntaxes. */ +static colortype *endcolor = NULL; + /* The end of the color list for the current syntax. */ +#endif -/* 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. */ +/* 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(const char *msg, ...) { va_list ap; @@ -123,17 +128,18 @@ void rcfile_error(const char *msg, ...) fprintf(stderr, "\n"); } -/* Parse the next word from the string. Returns NULL if we hit EOL. */ +/* Parse the next word from the string. Return points to '\0' if we hit + * the end of the line. */ char *parse_next_word(char *ptr) { - while (!is_blank_char(*ptr) && *ptr != '\n' && *ptr != '\0') + while (!is_blank_char(*ptr) && *ptr != '\0') ptr++; if (*ptr == '\0') - return NULL; + return ptr; - /* Null terminate and advance ptr */ - *ptr++ = 0; + /* Null-terminate and advance ptr. */ + *ptr++ = '\0'; while (is_blank_char(*ptr)) ptr++; @@ -141,13 +147,13 @@ char *parse_next_word(char *ptr) return ptr; } -/* The keywords operatingdir, backupdir, fill, tabsize, speller, - * punct, brackets, quotestr, and whitespace take an argument when set. - * Among these, operatingdir, backupdir, speller, punct, brackets, - * quotestr, and whitespace have to allow tabs and spaces in the - * argument. Thus, if the next word starts with a ", we say it ends - * with the last " of the line. Otherwise, the word is interpreted as - * usual. That is so the arguments can contain "s too. */ +/* The keywords operatingdir, backupdir, fill, tabsize, speller, punct, + * brackets, quotestr, and whitespace take an argument when set. Among + * these, operatingdir, backupdir, speller, punct, brackets, quotestr, + * and whitespace have to allow tabs and spaces in the argument. Thus, + * if the next word starts with a ", we say it ends with the last " of + * the line. Otherwise, the word is interpreted as usual. That is so + * the arguments can contain "s too. */ char *parse_argument(char *ptr) { const char *ptr_bak = ptr; @@ -162,7 +168,7 @@ char *parse_argument(char *ptr) ptr++; if (*ptr == '"') last_quote = ptr; - } while (*ptr != '\n' && *ptr != '\0'); + } while (*ptr != '\0'); if (last_quote == NULL) { if (*ptr == '\0') @@ -181,16 +187,19 @@ char *parse_argument(char *ptr) } #ifdef ENABLE_COLOR - -int colortoint(const char *colorname, int *bright) +int color_to_int(const char *colorname, bool *bright) { - int mcolor = 0; + int mcolor = -1; - if (colorname == NULL) + if (colorname == NULL) { + rcfile_error(N_("Missing color name")); return -1; + } + + assert(bright != NULL); if (strncasecmp(colorname, "bright", 6) == 0) { - *bright = 1; + *bright = TRUE; colorname += 6; } @@ -210,25 +219,32 @@ int colortoint(const char *colorname, int *bright) mcolor = COLOR_MAGENTA; else if (strcasecmp(colorname, "black") == 0) mcolor = COLOR_BLACK; - else { + else rcfile_error(N_("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" + "Valid colors are \"green\", \"red\", \"blue\",\n" + "\"white\", \"yellow\", \"cyan\", \"magenta\" and\n" + "\"black\", with the optional prefix \"bright\"\n" "for foreground colors."), colorname); - mcolor = -1; - } + return mcolor; } char *parse_next_regex(char *ptr) { - while ((*ptr != '"' || (*(ptr + 1) != ' ' && *(ptr + 1) != '\n')) - && *ptr != '\n' && *ptr != '\0') + assert(ptr != NULL); + + /* Continue until the end of the line, or a " followed by a space, a + * blank character, or \0. */ + while ((*ptr != '"' || (!is_blank_char(*(ptr + 1)) && + *(ptr + 1) != '\0')) && *ptr != '\0') ptr++; - if (*ptr == '\0') + assert(*ptr == '"' || *ptr == '\0'); + + if (*ptr == '\0') { + rcfile_error(N_("Regex strings must begin and end with a \" character")); return NULL; + } /* Null terminate and advance ptr. */ *ptr++ = '\0'; @@ -239,9 +255,9 @@ char *parse_next_regex(char *ptr) return ptr; } -/* Compile the regular expression regex to preg. Returns FALSE on +/* Compile the regular expression regex to preg. Return FALSE on * success, or TRUE if the expression is invalid. */ -int nregcomp(regex_t *preg, const char *regex, int eflags) +bool nregcomp(regex_t *preg, const char *regex, int eflags) { int rc = regcomp(preg, regex, REG_EXTENDED | eflags); @@ -259,75 +275,73 @@ int nregcomp(regex_t *preg, const char *regex, int eflags) void parse_syntax(char *ptr) { - syntaxtype *tmpsyntax = NULL; const char *fileregptr = NULL, *nameptr = NULL; exttype *endext = NULL; /* The end of the extensions list for this syntax. */ - while (*ptr == ' ') - ptr++; + assert(ptr != NULL); - if (*ptr == '\n' || *ptr == '\0') + if (*ptr == '\0') { + rcfile_error(N_("Missing syntax name")); return; + } if (*ptr != '"') { rcfile_error(N_("Regex strings must begin and end with a \" character")); return; } + ptr++; nameptr = ptr; ptr = parse_next_regex(ptr); - if (ptr == NULL) { - rcfile_error(N_("Missing syntax name")); + if (ptr == NULL) return; - } if (syntaxes == NULL) { syntaxes = (syntaxtype *)nmalloc(sizeof(syntaxtype)); - tmpsyntax = syntaxes; - SET(COLOR_SYNTAX); + endsyntax = syntaxes; } else { - for (tmpsyntax = syntaxes; tmpsyntax->next != NULL; - tmpsyntax = tmpsyntax->next) - ; - tmpsyntax->next = (syntaxtype *)nmalloc(sizeof(syntaxtype)); - tmpsyntax = tmpsyntax->next; + endsyntax->next = (syntaxtype *)nmalloc(sizeof(syntaxtype)); + endsyntax = endsyntax->next; #ifdef DEBUG - fprintf(stderr, "Adding new syntax after 1st\n"); + fprintf(stderr, "Adding new syntax after first one\n"); #endif } - tmpsyntax->desc = mallocstrcpy(NULL, nameptr); - tmpsyntax->color = NULL; - tmpsyntax->extensions = NULL; - tmpsyntax->next = NULL; + endsyntax->desc = mallocstrcpy(NULL, nameptr); + endsyntax->color = NULL; + endcolor = NULL; + endsyntax->extensions = NULL; + endsyntax->next = NULL; #ifdef DEBUG - fprintf(stderr, "Starting a new syntax type\n"); - fprintf(stderr, "string val=%s\n", nameptr); + fprintf(stderr, "Starting a new syntax type: \"%s\"\n", nameptr); #endif - /* Now load in the extensions to their part of the struct */ - while (*ptr != '\n' && *ptr != '\0') { + /* Now load the extensions into their part of the struct. */ + while (*ptr != '\0') { exttype *newext; /* The new extension structure. */ - while (*ptr != '"' && *ptr != '\n' && *ptr != '\0') + while (*ptr != '"' && *ptr != '\0') ptr++; - if (*ptr == '\n' || *ptr == '\0') + if (*ptr == '\0') return; + ptr++; fileregptr = ptr; ptr = parse_next_regex(ptr); + if (ptr == NULL) + break; newext = (exttype *)nmalloc(sizeof(exttype)); - if (nregcomp(&newext->val, fileregptr, REG_NOSUB) != 0) + if (nregcomp(&newext->val, fileregptr, REG_NOSUB)) free(newext); else { if (endext == NULL) - tmpsyntax->extensions = newext; + endsyntax->extensions = newext; else endext->next = newext; endext = newext; @@ -336,24 +350,24 @@ void parse_syntax(char *ptr) } } -/* Parse the color stuff into the colorstrings array */ +/* Parse the color stuff into the colorstrings array. */ void parse_colors(char *ptr) { - int fg, bg, bright = 0; - int expectend = 0; /* Do we expect an end= line? */ + int fg, bg; + bool bright = FALSE; char *fgstr; - colortype *tmpcolor = NULL; - syntaxtype *tmpsyntax = NULL; - fgstr = ptr; - ptr = parse_next_word(ptr); + assert(ptr != NULL); - if (ptr == NULL) { + if (*ptr == '\0') { rcfile_error(N_("Missing color name")); return; } - if (strstr(fgstr, ",")) { + fgstr = ptr; + ptr = parse_next_word(ptr); + + if (strchr(fgstr, ',') != NULL) { char *bgcolorname; strtok(fgstr, ","); bgcolorname = strtok(NULL, ","); @@ -361,13 +375,14 @@ void parse_colors(char *ptr) rcfile_error(N_("Background color %s cannot be bright"), bgcolorname); return; } - bg = colortoint(bgcolorname, &bright); + + bg = color_to_int(bgcolorname, &bright); } else bg = -1; - fg = colortoint(fgstr, &bright); + fg = color_to_int(fgstr, &bright); - /* Don't try and parse screwed up fg colors */ + /* Don't try to parse screwed-up foreground colors. */ if (fg == -1) return; @@ -376,28 +391,20 @@ void parse_colors(char *ptr) return; } - for (tmpsyntax = syntaxes; tmpsyntax->next != NULL; - tmpsyntax = tmpsyntax->next) - ; - - /* Now the fun part, start adding regexps to individual strings - in the colorstrings array, woo! */ + /* Now for the fun part. Start adding regexps to individual strings + * in the colorstrings array, woo! */ - while (*ptr != '\0') { + while (ptr != NULL && *ptr != '\0') { colortype *newcolor; /* The new color structure. */ - int cancelled = 0; + bool cancelled = FALSE; /* The start expression was bad. */ - - while (*ptr == ' ') - ptr++; - - if (*ptr == '\n' || *ptr == '\0') - break; + bool expectend = FALSE; + /* Do we expect an end= line? */ if (strncasecmp(ptr, "start=", 6) == 0) { ptr += 6; - expectend = 1; + expectend = TRUE; } if (*ptr != '"') { @@ -405,14 +412,18 @@ void parse_colors(char *ptr) ptr = parse_next_regex(ptr); continue; } + ptr++; newcolor = (colortype *)nmalloc(sizeof(colortype)); fgstr = ptr; ptr = parse_next_regex(ptr); - if (nregcomp(&newcolor->start, fgstr, 0) != 0) { + if (ptr == NULL) + break; + + if (nregcomp(&newcolor->start, fgstr, 0)) { free(newcolor); - cancelled = 1; + cancelled = TRUE; } else { newcolor->fg = fg; newcolor->bg = bg; @@ -420,20 +431,18 @@ void parse_colors(char *ptr) newcolor->next = NULL; newcolor->end = NULL; - if (tmpsyntax->color == NULL) { - tmpsyntax->color = newcolor; + if (endcolor == NULL) { + endsyntax->color = newcolor; #ifdef DEBUG - fprintf(stderr, "Starting a new colorstring for fg %d bg %d\n", fg, bg); + 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); + fprintf(stderr, "Adding new entry for fg %d, bg %d\n", fg, bg); #endif - tmpcolor->next = newcolor; + endcolor->next = newcolor; } + endcolor = newcolor; } if (expectend) { @@ -441,63 +450,63 @@ void parse_colors(char *ptr) rcfile_error(N_("\"start=\" requires a corresponding \"end=\"")); return; } - ptr += 4; - if (*ptr != '"') { rcfile_error(N_("Regex strings must begin and end with a \" character")); continue; } + ptr++; fgstr = ptr; ptr = parse_next_regex(ptr); + if (ptr == NULL) + break; /* 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) != 0) { + if (nregcomp(newcolor->end, fgstr, 0)) { free(newcolor->end); newcolor->end = NULL; } } } } - #endif /* ENABLE_COLOR */ -/* Parse the RC file, once it has been opened successfully */ +/* Parse the rcfile, once it has been opened successfully. */ void parse_rcfile(FILE *rcstream) { - char *buf, *ptr, *keyword, *option; - int set = 0, i; + char *buf = NULL; + ssize_t len; + size_t n; + + while ((len = getline(&buf, &n, rcstream)) > 0) { + char *ptr, *keyword, *option; + int set = 0, i; + + /* Ignore the \n. */ + buf[len - 1] = '\0'; - buf = charalloc(1024); - while (fgets(buf, 1023, rcstream) != 0) { lineno++; ptr = buf; while (is_blank_char(*ptr)) ptr++; - if (*ptr == '\n' || *ptr == '\0') + /* If we have a blank line or a comment, skip to the next + * line. */ + if (*ptr == '\0' || *ptr == '#') continue; - if (*ptr == '#') { -#ifdef DEBUG - fprintf(stderr, "%s: Read a comment\n", "parse_rcfile()"); -#endif - continue; /* Skip past commented lines */ - } - - /* Else skip to the next space */ + /* Otherwise, skip to the next space. */ keyword = ptr; ptr = parse_next_word(ptr); - if (ptr == NULL) - continue; - /* Else try to parse the keyword */ + /* Try to parse the keyword. */ if (strcasecmp(keyword, "set") == 0) set = 1; else if (strcasecmp(keyword, "unset") == 0) @@ -507,135 +516,124 @@ void parse_rcfile(FILE *rcstream) parse_syntax(ptr); else if (strcasecmp(keyword, "color") == 0) parse_colors(ptr); -#endif /* ENABLE_COLOR */ - else { +#endif /* ENABLE_COLOR */ + else rcfile_error(N_("Command %s not understood"), keyword); + + if (set == 0) + continue; + + if (*ptr == '\0') { + rcfile_error(N_("Missing flag")); continue; } option = ptr; ptr = parse_next_word(ptr); - /* We don't care if ptr == NULL, as it should if using proper syntax */ - if (set != 0) { - for (i = 0; rcopts[i].name != NULL; i++) { - if (strcasecmp(option, rcopts[i].name) == 0) { + for (i = 0; rcopts[i].name != NULL; i++) { + if (strcasecmp(option, rcopts[i].name) == 0) { #ifdef DEBUG - fprintf(stderr, "%s: Parsing option %s\n", - "parse_rcfile()", rcopts[i].name); -#endif - if (set == 1) { - if (strcasecmp(rcopts[i].name, "tabsize") == 0 -#ifndef DISABLE_OPERATINGDIR - || strcasecmp(rcopts[i].name, "operatingdir") == 0 -#endif -#ifndef DISABLE_WRAPJUSTIFY - || strcasecmp(rcopts[i].name, "fill") == 0 -#endif -#ifndef NANO_SMALL - || strcasecmp(rcopts[i].name, "whitespace") == 0 -#endif -#ifndef DISABLE_JUSTIFY - || strcasecmp(rcopts[i].name, "punct") == 0 - || strcasecmp(rcopts[i].name, "brackets") == 0 - || strcasecmp(rcopts[i].name, "quotestr") == 0 -#endif -#ifndef NANO_SMALL - || strcasecmp(rcopts[i].name, "backupdir") == 0 -#endif -#ifndef DISABLE_SPELLER - || strcasecmp(rcopts[i].name, "speller") == 0 -#endif - ) { - if (*ptr == '\n' || *ptr == '\0') { - rcfile_error(N_("Option %s requires an argument"), rcopts[i].name); - continue; - } - option = ptr; - if (*option == '"') - option++; - ptr = parse_argument(ptr); + fprintf(stderr, "parse_rcfile(): name = \"%s\"\n", rcopts[i].name); +#endif + if (set == 1) { + if (rcopts[i].flag != 0) + /* This option has a flag, so it doesn't take an + * argument. */ + SET(rcopts[i].flag); + else { + /* This option doesn't have a flag, so it takes + * an argument. */ + if (*ptr == '\0') { + rcfile_error(N_("Option %s requires an argument"), rcopts[i].name); + break; + } + option = ptr; + if (*option == '"') + option++; + ptr = parse_argument(ptr); #ifdef DEBUG - fprintf(stderr, "option = %s\n", option); + fprintf(stderr, "option = \"%s\"\n", option); #endif #ifndef DISABLE_OPERATINGDIR - if (strcasecmp(rcopts[i].name, "operatingdir") == 0) - operating_dir = mallocstrcpy(NULL, option); - else + if (strcasecmp(rcopts[i].name, "operatingdir") == 0) + operating_dir = mallocstrcpy(NULL, option); + else #endif #ifndef DISABLE_WRAPJUSTIFY - if (strcasecmp(rcopts[i].name, "fill") == 0) { - if (!parse_num(option, &wrap_at)) { - rcfile_error(N_("Requested fill size %s invalid"), option); - wrap_at = -CHARS_FROM_EOL; - } - } else + if (strcasecmp(rcopts[i].name, "fill") == 0) { + if (!parse_num(option, &wrap_at)) { + rcfile_error(N_("Requested fill size %s invalid"), option); + wrap_at = -CHARS_FROM_EOL; + } + } else #endif #ifndef NANO_SMALL - if (strcasecmp(rcopts[i].name, "whitespace") == 0) { - size_t ws_len; - whitespace = mallocstrcpy(NULL, option); - ws_len = strlen(whitespace); - if (ws_len != 2 || (ws_len == 2 && (is_cntrl_char(whitespace[0]) || is_cntrl_char(whitespace[1])))) { - rcfile_error(N_("Two non-control characters required")); - free(whitespace); - whitespace = NULL; - } - } else + if (strcasecmp(rcopts[i].name, "whitespace") == 0) { + size_t ws_len; + whitespace = mallocstrcpy(NULL, option); + ws_len = strlen(whitespace); + if (ws_len != 2 || (ws_len == 2 && (is_cntrl_char(whitespace[0]) || is_cntrl_char(whitespace[1])))) { + rcfile_error(N_("Two non-control characters required")); + free(whitespace); + whitespace = NULL; + } + } else #endif #ifndef DISABLE_JUSTIFY - if (strcasecmp(rcopts[i].name, "punct") == 0) { - punct = mallocstrcpy(NULL, option); - if (strchr(punct, '\t') != NULL || strchr(punct, ' ') != NULL) { - rcfile_error(N_("Non-tab and non-space characters required")); - free(punct); - punct = NULL; - } - } else if (strcasecmp(rcopts[i].name, "brackets") == 0) { - brackets = mallocstrcpy(NULL, option); - if (strchr(brackets, '\t') != NULL || strchr(brackets, ' ') != NULL) { - rcfile_error(N_("Non-tab and non-space characters required")); - free(brackets); - brackets = NULL; - } - } else if (strcasecmp(rcopts[i].name, "quotestr") == 0) - quotestr = mallocstrcpy(NULL, option); - else + if (strcasecmp(rcopts[i].name, "punct") == 0) { + punct = mallocstrcpy(NULL, option); + if (strchr(punct, '\t') != NULL || strchr(punct, ' ') != NULL) { + rcfile_error(N_("Non-tab and non-space characters required")); + free(punct); + punct = NULL; + } + } else if (strcasecmp(rcopts[i].name, "brackets") == 0) { + brackets = mallocstrcpy(NULL, option); + if (strchr(brackets, '\t') != NULL || strchr(brackets, ' ') != NULL) { + rcfile_error(N_("Non-tab and non-space characters required")); + free(brackets); + brackets = NULL; + } + } else if (strcasecmp(rcopts[i].name, "quotestr") == 0) + quotestr = mallocstrcpy(NULL, option); + else #endif #ifndef NANO_SMALL - if (strcasecmp(rcopts[i].name, "backupdir") == 0) - backup_dir = mallocstrcpy(NULL, option); - else + if (strcasecmp(rcopts[i].name, "backupdir") == 0) + backup_dir = mallocstrcpy(NULL, option); + else #endif #ifndef DISABLE_SPELLER - if (strcasecmp(rcopts[i].name, "speller") == 0) - alt_speller = mallocstrcpy(NULL, option); - else -#endif - if (strcasecmp(rcopts[i].name, "tabsize") == 0) { - if (!parse_num(option, &tabsize) || tabsize <= 0) { - rcfile_error(N_("Requested tab size %s invalid"), option); - tabsize = -1; - } + if (strcasecmp(rcopts[i].name, "speller") == 0) + alt_speller = mallocstrcpy(NULL, option); + else +#endif + if (strcasecmp(rcopts[i].name, "tabsize") == 0) { + if (!parse_num(option, &tabsize) || tabsize <= 0) { + rcfile_error(N_("Requested tab size %s invalid"), option); + tabsize = -1; } } else - SET(rcopts[i].flag); -#ifdef DEBUG - fprintf(stderr, "set flag %ld!\n", - rcopts[i].flag); -#endif - } else { - UNSET(rcopts[i].flag); + assert(FALSE); + } #ifdef DEBUG - fprintf(stderr, "unset flag %ld!\n", - rcopts[i].flag); + fprintf(stderr, "flag = %d\n", rcopts[i].flag); #endif - } - } + } else if (rcopts[i].flag != 0) + UNSET(rcopts[i].flag); + else + rcfile_error(N_("Cannot unset flag %s"), rcopts[i].name); + break; } } + if (rcopts[i].name == NULL) + rcfile_error(N_("Unknown flag %s"), option); } + free(buf); + fclose(rcstream); + lineno = 0; if (errors) { errors = FALSE; @@ -655,52 +653,40 @@ void do_rcfile(void) #ifdef SYSCONFDIR assert(sizeof(SYSCONFDIR) == strlen(SYSCONFDIR) + 1); - nanorc = SYSCONFDIR "/nanorc"; - /* Try to open system nanorc */ + nanorc = mallocstrcpy(nanorc, SYSCONFDIR "/nanorc"); + /* Try to open the system-wide nanorc. */ rcstream = fopen(nanorc, "r"); - if (rcstream != NULL) { - /* Parse it! */ + if (rcstream != NULL) parse_rcfile(rcstream); - fclose(rcstream); - } #endif - lineno = 0; +#if defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING) + /* We've already read SYSCONFDIR/nanorc, if it's there. If we're + * root and --disable-wrapping-as-root is used, turn wrapping + * off now. */ + if (geteuid() == NANO_ROOT_UID) + SET(NO_WRAP); +#endif get_homedir(); - if (homedir == NULL) { + if (homedir == NULL) rcfile_error(N_("I can't find my home directory! Wah!")); - SET(NO_RCFILE); - } else { - size_t homelen = strlen(homedir); - char *nanorcf = charalloc(homelen + 9); - - nanorc = nanorcf; - strcpy(nanorcf, homedir); - strcpy(nanorcf + homelen, "/.nanorc"); - -#if defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING) - /* If we've already read SYSCONFDIR/nanorc (if it's there), we're - root, and --disable-wrapping-as-root is used, turn wrapping off */ - if (geteuid() == NANO_ROOT_UID) - SET(NO_WRAP); -#endif + else { + nanorc = charealloc(nanorc, strlen(homedir) + 9); + sprintf(nanorc, "%s/.nanorc", homedir); rcstream = fopen(nanorc, "r"); + if (rcstream == NULL) { - /* Don't complain about the file not existing */ - if (errno != ENOENT) { + /* Don't complain about the file's not existing. */ + if (errno != ENOENT) rcfile_error(N_("Error reading %s: %s"), nanorc, strerror(errno)); - SET(NO_RCFILE); - } - } else { + } else parse_rcfile(rcstream); - fclose(rcstream); - } - free(nanorcf); } - lineno = 0; + free(nanorc); + nanorc = NULL; #ifdef ENABLE_COLOR set_colorpairs(); diff --git a/src/search.c b/src/search.c index c8608fe3..5cac8b1b 100644 --- a/src/search.c +++ b/src/search.c @@ -844,7 +844,7 @@ ssize_t do_replace_loop(const char *needle, const filestruct if (!replaceall) { #ifdef ENABLE_COLOR - if (ISSET(COLOR_SYNTAX)) + if (!ISSET(NO_COLOR_SYNTAX)) edit_refresh(); else #endif diff --git a/src/winio.c b/src/winio.c index fb9651d7..67185526 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2658,7 +2658,7 @@ int statusq(bool allow_tabs, const shortcut *s, const char *def, blank_statusbar(); #ifdef DEBUG - fprintf(stderr, "I got \"%s\"\n", answer); + fprintf(stderr, "answer = \"%s\"\n", answer); #endif #ifndef DISABLE_TABCOMP @@ -3052,7 +3052,7 @@ void edit_add(const filestruct *fileptr, const char *converted, int mvwaddstr(edit, yval, 0, converted); #ifdef ENABLE_COLOR - if (colorstrings != NULL && ISSET(COLOR_SYNTAX)) { + if (colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) { const colortype *tmpcolor = colorstrings; for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) { @@ -3087,17 +3087,19 @@ void edit_add(const filestruct *fileptr, const char *converted, int * unless k is 0. If regexec() returns REG_NOMATCH, * there are no more matches in the line. */ if (regexec(&tmpcolor->start, &fileptr->data[k], 1, - &startmatch, k == 0 ? 0 : + &startmatch, (k == 0) ? 0 : REG_NOTBOL) == REG_NOMATCH) break; - /* Translate the match to the beginning of the line. */ + /* Translate the match to the beginning of the + * line. */ startmatch.rm_so += k; startmatch.rm_eo += k; if (startmatch.rm_so == startmatch.rm_eo) { startmatch.rm_eo++; - statusbar(_("Refusing 0 length regex match")); + statusbar( + _("Refusing zero-length regex match")); } else if (startmatch.rm_so < endpos && - startmatch.rm_eo > startpos) { + startmatch.rm_eo > startpos) { if (startmatch.rm_so <= startpos) x_start = 0; else @@ -3157,7 +3159,7 @@ void edit_add(const filestruct *fileptr, const char *converted, int startmatch.rm_eo -= startmatch.rm_so; if (regexec(tmpcolor->end, start_line->data + start_col + startmatch.rm_eo, 0, NULL, - start_col + startmatch.rm_eo == 0 ? 0 : + (start_col + startmatch.rm_eo == 0) ? 0 : REG_NOTBOL) == REG_NOMATCH) /* No end found after this start. */ break; @@ -3209,7 +3211,8 @@ void edit_add(const filestruct *fileptr, const char *converted, int while (start_col < endpos) { if (regexec(&tmpcolor->start, fileptr->data + start_col, 1, &startmatch, - start_col == 0 ? 0 : REG_NOTBOL) == REG_NOMATCH || + (start_col == 0) ? 0 : + REG_NOTBOL) == REG_NOMATCH || start_col + startmatch.rm_so >= endpos) /* No more starts on this line. */ break; @@ -3228,7 +3231,8 @@ void edit_add(const filestruct *fileptr, const char *converted, int if (regexec(tmpcolor->end, fileptr->data + startmatch.rm_eo, 1, &endmatch, - startmatch.rm_eo == 0 ? 0 : REG_NOTBOL) == 0) { + (startmatch.rm_eo == 0) ? 0 : + REG_NOTBOL) == 0) { /* Translate the end match to be relative to the * beginning of the line. */ endmatch.rm_so += startmatch.rm_eo; @@ -3268,12 +3272,12 @@ void edit_add(const filestruct *fileptr, const char *converted, int } } start_col = startmatch.rm_so + 1; - } /* while start_col < endpos */ - } /* if (tmp_color->end != NULL) */ + } + } wattroff(edit, A_BOLD); wattroff(edit, COLOR_PAIR(tmpcolor->pairnum)); - } /* for tmpcolor in colorstrings */ + } } #endif /* ENABLE_COLOR */