commit cee20e50c627a7493b8455b242237f64fc10435e
parent 03ee3326406269c9e4b476063afe64420f86f348
Author: David Lawrence Ramsey <pooka109@gmail.com>
Date: Thu, 13 Apr 2006 02:43:54 +0000
at long last, add the ability to use self-contained color syntaxes from
separate files, accessible in the nanorc via the "include" command
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3372 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Diffstat:
5 files changed, 134 insertions(+), 20 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -30,6 +30,11 @@ CVS code -
titlebar(), statusbar(), onekey(), edit_draw(),
do_replace_highlight(), nano.1, nanorc.5, nano.texi, and
nanorc.sample. (DLR, suggested by Benno Schulenberg)
+ - Add the ability to use self-contained color syntaxes from
+ separate files, accessible in the nanorc via the "include"
+ command. New function parse_include(); changes to
+ parse_rcfile(), do_nanorc(), nanorc.5, and nanorc.sample.
+ (Victor Ananievsky, Brand Huntsman and DLR)
- files.c:
open_file()
- Remove redundant wording in the error message when we try to
@@ -49,14 +54,19 @@ CVS code -
- Simplify the routine for closing the file just before we
indicate success on the statusbar. (DLR)
- rcfile.c:
+ parse_argument()
+ - Rename variable ptr_bak to ptr_save, for consistency. (DLR)
+ parse_colors()
+ - Check for a color command's not following a syntax line before
+ anything else. (DLR)
do_rcfile()
- Check for the rcfile's being a directory or device file and
reject it if it is, for consistency with file handling
elsewhere. (DLR)
- Remove SYSCONFDIR #ifdef, as SYSCONFDIR should always be set.
(DLR)
- parse_argument()
- - Rename variable ptr_bak to ptr_save, for consistency. (DLR)
+ - Change all rcfile error messages to refer to commands instead
+ of directives, for consistency with nanorc.5. (DLR)
- doc/nano.1, doc/nanorc.5, doc/rnano.1, doc/nano.texi:
- Update the copyright years to include 2006. (DLR)
- Explicitly mention that all regexes should be extended regular
diff --git a/doc/man/nanorc.5 b/doc/man/nanorc.5
@@ -231,7 +231,11 @@ the first instance of \fIer\fP.
.TP
.B icolor \fIfgcolor\fP,\fIbgcolor\fP start="\fIsr\fP" end="\fIer\fP"
Same as above, except that the expression matching is case insensitive.
-
+.TP
+.B include "\fIsyntaxfile\fP"
+Read in self-contained color syntaxes from \fIsyntaxfile\fP. Note that
+\fIsyntaxfile\fP can only contain \fBsyntax\fP, \fBcolor\fP, and
+\fBicolor\fP commands.
.SH FILES
.TP
.I SYSCONFDIR/nanorc
diff --git a/doc/nanorc.sample b/doc/nanorc.sample
@@ -356,7 +356,7 @@
##
# syntax "nanorc" "(\.|/|)nanorc$"
## highlight possible errors and parameters
-# icolor brightwhite "^[[:space:]]*(set|unset|syntax|i?color).*$"
+# icolor brightwhite "^[[:space:]]*(set|unset|include|syntax|i?color).*$"
## set, unset and syntax
# icolor cyan "^[[:space:]]*(set|unset)[[:space:]]+(autoindent|backup|backupdir|backwards|boldtext|brackets|casesensitive|const|cut|fill|historylog|matchbrackets|morespace|mouse|multibuffer|noconvert|nofollow|nohelp|nonewlines|nowrap|operatingdir|preserve|punct)\>" "^[[:space:]]*(set|unset)[[:space:]]+(quickblank|quotestr|rebinddelete|rebindkeypad|regexp|smarthome|smooth|speller|suspend|tabsize|tabstospaces|tempfile|view|whitespace|wordbounds)\>"
# icolor green "^[[:space:]]*(set|unset|syntax)\>"
diff --git a/src/proto.h b/src/proto.h
@@ -518,9 +518,14 @@ short color_to_short(const char *colorname, bool *bright);
char *parse_next_regex(char *ptr);
bool nregcomp(const char *regex, int eflags);
void parse_syntax(char *ptr);
+void parse_include(char *ptr);
void parse_colors(char *ptr, bool icase);
#endif
-void parse_rcfile(FILE *rcstream);
+void parse_rcfile(FILE *rcstream
+#ifdef ENABLE_COLOR
+ , bool syntax_only
+#endif
+ );
void do_rcfile(void);
#endif
diff --git a/src/rcfile.c b/src/rcfile.c
@@ -380,6 +380,66 @@ void parse_syntax(char *ptr)
}
}
+/* Read and parse additional syntax files. */
+void parse_include(char *ptr)
+{
+ struct stat rcinfo;
+ FILE *rcstream;
+ char *option, *full_option, *nanorc_save = nanorc;
+ size_t lineno_save = lineno;
+
+ option = ptr;
+ if (*option == '"')
+ option++;
+ ptr = parse_argument(ptr);
+
+ /* Get the specified file's full path. */
+ full_option = get_full_path(option);
+
+ if (full_option == NULL) {
+ rcfile_error(_("Error reading %s: %s"), option, strerror(errno));
+ goto cleanup_include;
+ }
+
+ /* Don't open directories, character files, or block files. */
+ if (stat(nanorc, &rcinfo) != -1) {
+ if (S_ISDIR(rcinfo.st_mode) || S_ISCHR(rcinfo.st_mode) ||
+ S_ISBLK(rcinfo.st_mode)) {
+ rcfile_error(S_ISDIR(rcinfo.st_mode) ?
+ _("\"%s\" is a directory") :
+ _("\"%s\" is a device file"), nanorc);
+ goto cleanup_include;
+ }
+ }
+
+ /* Open the new syntax file. */
+ if ((rcstream = fopen(full_option, "rb")) == NULL) {
+ rcfile_error(_("Error reading %s: %s"), full_option,
+ strerror(errno));
+ goto cleanup_include;
+ }
+
+ /* Use the name and line number position of the new syntax file
+ * while parsing it, so we can know where any errors in it are. */
+ nanorc = full_option;
+ lineno = 0;
+
+ parse_rcfile(rcstream
+#ifdef ENABLE_COLOR
+ , TRUE
+#endif
+ );
+ fclose(rcstream);
+
+ /* We're done with the new syntax file. Restore the original
+ * filename and line number position. */
+ nanorc = nanorc_save;
+ lineno = lineno_save;
+
+ cleanup_include:
+ free(full_option);
+}
+
/* Parse the color string in the line at ptr, and add it to the current
* file's associated colors. If icase is TRUE, treat the color string
* as case insensitive. */
@@ -391,6 +451,12 @@ void parse_colors(char *ptr, bool icase)
assert(ptr != NULL);
+ if (syntaxes == NULL) {
+ rcfile_error(
+ N_("Cannot add a color command without a syntax line"));
+ return;
+ }
+
if (*ptr == '\0') {
rcfile_error(N_("Missing color name"));
return;
@@ -429,12 +495,6 @@ void parse_colors(char *ptr, bool icase)
} else
fg = -1;
- if (syntaxes == NULL) {
- rcfile_error(
- N_("Cannot add a color directive without a syntax line"));
- return;
- }
-
if (*ptr == '\0') {
rcfile_error(N_("Missing regex string"));
return;
@@ -539,8 +599,13 @@ void parse_colors(char *ptr, bool icase)
#endif /* ENABLE_COLOR */
/* Parse the rcfile, once it has been opened successfully at
- * rcstream. */
-void parse_rcfile(FILE *rcstream)
+ * rcstream. If syntax_only is TRUE, only allow the file to contain
+ * color syntax commands: syntax, color, and icolor. */
+void parse_rcfile(FILE *rcstream
+#ifdef ENABLE_COLOR
+ , bool syntax_only
+#endif
+ )
{
char *buf = NULL;
ssize_t len;
@@ -568,12 +633,34 @@ void parse_rcfile(FILE *rcstream)
ptr = parse_next_word(ptr);
/* Try to parse the keyword. */
- if (strcasecmp(keyword, "set") == 0)
- set = 1;
- else if (strcasecmp(keyword, "unset") == 0)
- set = -1;
+ if (strcasecmp(keyword, "set") == 0) {
#ifdef ENABLE_COLOR
- else if (strcasecmp(keyword, "syntax") == 0)
+ if (syntax_only)
+ rcfile_error(
+ N_("Command %s not allowed in included file"),
+ keyword);
+ else
+#endif
+ set = 1;
+ } else if (strcasecmp(keyword, "unset") == 0) {
+#ifdef ENABLE_COLOR
+ if (syntax_only)
+ rcfile_error(
+ N_("Command %s not allowed in included file"),
+ keyword);
+ else
+#endif
+ set = -1;
+ }
+#ifdef ENABLE_COLOR
+ else if (strcasecmp(keyword, "include") == 0) {
+ if (syntax_only)
+ rcfile_error(
+ N_("Command %s not allowed in included file"),
+ keyword);
+ else
+ parse_include(ptr);
+ } else if (strcasecmp(keyword, "syntax") == 0)
parse_syntax(ptr);
else if (strcasecmp(keyword, "color") == 0)
parse_colors(ptr, FALSE);
@@ -773,7 +860,11 @@ void do_rcfile(void)
/* Try to open the system-wide nanorc. */
rcstream = fopen(nanorc, "rb");
if (rcstream != NULL)
- parse_rcfile(rcstream);
+ parse_rcfile(rcstream
+#ifdef ENABLE_COLOR
+ , FALSE
+#endif
+ );
#if defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING)
/* We've already read SYSCONFDIR/nanorc, if it's there. If we're
@@ -808,7 +899,11 @@ void do_rcfile(void)
rcfile_error(N_("Error reading %s: %s"), nanorc,
strerror(errno));
} else
- parse_rcfile(rcstream);
+ parse_rcfile(rcstream
+#ifdef ENABLE_COLOR
+ , FALSE
+#endif
+ );
}
free(nanorc);