commit 8d8e01224b3fa7c7e64ed3b4622f13602cf7bb9e
parent 12f294c6516a5d7ca5d0a5cc5e9c67d6ecc37e37
Author: Chris Allegretta <chrisa@asty.org>
Date: Wed, 18 Apr 2001 04:28:54 +0000
Added rcfile.c source code and basic .nanorc functionality
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@598 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Diffstat:
9 files changed, 292 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -8,6 +8,12 @@ Cvs code -
this automatically, but now just mouse support can be disabled
if desired.
- File Browser supports the "Goto Directory"
+ - Added rcfile.c source file. Only includes much of anything when
+ --enable-nanorc is used. Tons of new funcs, most notably
+ do_rcfile() called from nano.c:main(). Added much needed
+ function ncalloc(), will have to go through source code later
+ and change the aproproate calls which used nmalloc for lack of
+ an apropriate calloc function *** FIXME ***
- configure.in:
- New option, --enable-nanorc which currently does nothing but
sets a define. Will do more later...
diff --git a/Makefile.am b/Makefile.am
@@ -7,6 +7,7 @@ nano_SOURCES = cut.c \
nano.c \
nano.h \
proto.h \
+ rcfile.c \
search.c \
utils.c \
winio.c
diff --git a/Makefile.in b/Makefile.in
@@ -91,7 +91,7 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
bin_PROGRAMS = nano
-nano_SOURCES = cut.c files.c global.c move.c nano.c nano.h proto.h search.c utils.c winio.c
+nano_SOURCES = cut.c files.c global.c move.c nano.c nano.h proto.h rcfile.c search.c utils.c winio.c
man_MANS = nano.1
@@ -118,8 +118,8 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
-nano_OBJECTS = cut.o files.o global.o move.o nano.o search.o utils.o \
-winio.o
+nano_OBJECTS = cut.o files.o global.o move.o nano.o rcfile.o search.o \
+utils.o winio.o
nano_DEPENDENCIES =
nano_LDFLAGS =
CFLAGS = @CFLAGS@
diff --git a/global.c b/global.c
@@ -70,6 +70,10 @@ char *help_text; /* The text in the help window */
filestruct *mark_beginbuf; /* the begin marker buffer */
int mark_beginx; /* X value in the string to start */
+#ifndef DISABLE_SPELLER
+char *alt_speller; /* Alternative spell command */
+#endif
+
shortcut main_list[MAIN_LIST_LEN];
shortcut whereis_list[WHEREIS_LIST_LEN];
shortcut replace_list[REPLACE_LIST_LEN];
diff --git a/nano.c b/nano.c
@@ -64,10 +64,6 @@
/* Former globals, now static */
int fill = 0; /* Fill - where to wrap lines, basically */
-#ifndef DISABLE_SPELLER
-static char *alt_speller; /* Alternative spell command */
-#endif
-
struct termios oldterm; /* The user's original term settings */
static struct sigaction act; /* For all out fun signal handlers */
@@ -2243,6 +2239,10 @@ int main(int argc, char *argv[])
#endif
#endif
+#ifdef ENABLE_NANORC
+ do_rcfile();
+#endif /* ENABLE_NANORC */
+
#ifdef HAVE_GETOPT_LONG
while ((optchr = getopt_long(argc, argv, "?T:RVbcefghijklmpr:s:tvwxz",
long_options, &option_index)) != EOF) {
diff --git a/nano.h b/nano.h
@@ -90,6 +90,14 @@ typedef struct toggle {
int flag; /* What flag actually gets toggled */
} toggle;
+#ifdef ENABLE_NANORC
+typedef struct rcoption {
+ char *name;
+ int flag;
+} rcoption;
+
+#endif /* ENABLE_NANORC */
+
/* Bitwise flags so we can save space (or more correctly, not waste it) */
#define MODIFIED (1<<0)
diff --git a/proto.h b/proto.h
@@ -44,6 +44,9 @@ extern char *answer;
extern char *hblank, *help_text;
extern char *last_search;
extern char *last_replace;
+#ifndef DISABLE_SPELLER
+extern char *alt_speller;
+#endif
extern struct stat fileinfo;
extern filestruct *current, *fileage, *edittop, *editbot, *filebot;
extern filestruct *cutbuffer, *mark_beginbuf;
@@ -121,6 +124,7 @@ void center_cursor(void);
void bottombars(shortcut s[], int slen);
void blank_statusbar_refresh(void);
void *nmalloc (size_t howmuch);
+void *ncalloc (size_t howmuch, size_t size);
void *mallocstrcpy(char *dest, char *src);
void wrap_reset(void);
void display_main_list(void);
@@ -143,10 +147,16 @@ void do_replace_highlight(int highlight_flag, char *word);
void nano_disabled_msg(void);
void window_init(void);
void do_mouse(void);
+
+#ifdef ENABLE_RCFILE
+void do_rcfile(void);
+#endif
+
#ifdef NANO_EXTRA
void do_credits(void);
#endif
+
int do_writeout_void(void), do_exit(void), do_gotoline_void(void);
int do_insertfile(void), do_search(void), page_up(void), page_down(void);
int do_cursorpos(void), do_spell(void);
diff --git a/rcfile.c b/rcfile.c
@@ -0,0 +1,243 @@
+/* $Id$ */
+/**************************************************************************
+ * cut.c *
+ * *
+ * Copyright (C) 1999 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 1, or (at your option) *
+ * any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ * *
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "config.h"
+#include "proto.h"
+#include "nano.h"
+
+#ifdef ENABLE_NANORC
+
+#ifndef NANO_SMALL
+#include <libintl.h>
+#define _(string) gettext(string)
+#else
+#define _(string) (string)
+#endif
+
+#define NUM_RCOPTS 14
+/* Static stuff for the nanorc file */
+rcoption rcopts[NUM_RCOPTS] =
+{
+{"regexp", USE_REGEXP},
+{"const", CONSTUPDATE},
+{"autoindent", AUTOINDENT},
+{"cut", CUT_TO_END},
+{"nofollow", FOLLOW_SYMLINKS},
+{"mouse", USE_MOUSE},
+{"pico", PICO_MODE},
+{"fill", 0},
+{"speller", 0},
+{"tempfile", TEMP_OPT},
+{"view", VIEW_MODE},
+{"nowrap", NO_WRAP},
+{"nohelp", NO_HELP},
+{"suspend", SUSPEND}};
+
+/* We have an error in some part of the rcfile, put it on stderr and
+ make the usr hit return to continue starting up nano */
+void rcfile_error(char *msg, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "\n");
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+ fprintf(stderr, _("\nPress return to continue starting nano\n"));
+
+ while (getchar() != '\n')
+ ;
+
+}
+
+/* Just print the error (one of many perhaps) but don't abort, yet */
+void rcfile_msg(int *errors, char *msg, ...)
+{
+ va_list ap;
+
+ if (!*errors) {
+ *errors = 1;
+ fprintf(stderr, "\n");
+ }
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+
+}
+
+/* Parse the next word from the string. Returns NULL of we hit EOL */
+char *parse_next_word(char *ptr)
+{
+ while (*ptr != ' ' && *ptr != '\n' && ptr != '\0')
+ ptr++;
+
+ if (*ptr == '\0')
+ return NULL;
+
+ /* Null terminate and advance ptr */
+ *ptr++ = 0;
+
+ return ptr;
+}
+
+/* Parse the RC file, once it has been opened successfully */
+void parse_rcfile(FILE *rcstream, char *filename)
+{
+ char *buf, *ptr, *keyword, *option;
+ int set = 0, lineno = 0, i;
+ int errors = 0;
+
+ buf = ncalloc(1024, sizeof(char));
+ while (fgets(buf, 1023, rcstream) > 0) {
+ lineno++;
+ ptr = buf;
+ while ((*ptr == ' ' || *ptr == '\t') &&
+ (*ptr != '\n' && *ptr != '\0'))
+ ptr++;
+
+ if (*ptr == '\n' || *ptr == '\0')
+ continue;
+
+ if (*ptr == '#') {
+#ifdef DEBUG
+ fprintf(stderr, _("parse_rcfile: Read a comment\n"));
+#endif
+ continue; /* Skip past commented lines */
+ }
+
+ /* Else skip to the next space */
+ keyword = ptr;
+ ptr = parse_next_word(ptr);
+ if (!ptr)
+ continue;
+
+ /* Else try to parse the keyword */
+ if (!strcasecmp(keyword, "set"))
+ set = 1;
+ else if (!strcasecmp(keyword, "unset"))
+ set = -1;
+ else {
+ rcfile_msg(&errors, _("Error in %s on line %d: command %s not understood"),
+ filename, lineno, keyword);
+ 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; i <= NUM_RCOPTS - 1; i++) {
+ if (!strcasecmp(option, rcopts[i].name)) {
+#ifdef DEBUG
+ fprintf(stderr, "parse_rcfile: Parsing option %s\n",
+ rcopts[i].name);
+#endif
+ if (set == 1 || rcopts[i].flag == FOLLOW_SYMLINKS) {
+ if (!strcasecmp(rcopts[i].name, "fill") ||
+ !strcasecmp(rcopts[i].name, "speller")) {
+
+ if (*ptr == '\n' || *ptr == '\0') {
+ rcfile_msg(&errors, _("Error in %s on line %d: option %s requires an argument"),
+ filename, lineno, rcopts[i].name);
+ continue;
+ }
+ option = ptr;
+ ptr = parse_next_word(ptr);
+ if (!strcasecmp(rcopts[i].name, "fill")) {
+ if ((i = atoi(option)) < MIN_FILL_LENGTH) {
+ rcfile_msg(&errors,
+ _("Error in %s on line %d: requested fill size %d too small"),
+ filename, lineno, option);
+ }
+ else
+ fill = i;
+ }
+ else {
+ alt_speller = ncalloc(strlen(option) + 1, sizeof(char));
+ strcpy(alt_speller, option);
+ }
+ } else
+ SET(rcopts[i].flag);
+#ifdef DEBUG
+ fprintf(stderr, "set flag %d!\n", rcopts[i].flag);
+#endif
+ } else {
+ UNSET(rcopts[i].flag);
+#ifdef DEBUG
+ fprintf(stderr, "unset flag %d!\n", rcopts[i].flag);
+#endif
+ }
+ }
+ }
+ }
+
+ }
+ if (errors)
+ rcfile_error(_("Errors found in .nanorc file"));
+
+ return;
+}
+
+/* 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;
+
+ if (getenv("HOME") == NULL)
+ return;
+
+ nanorc = nmalloc(strlen(getenv("HOME")) + 10);
+ sprintf(nanorc, "%s/.nanorc", getenv("HOME"));
+
+ if (stat(nanorc, &fileinfo) == -1) {
+
+ /* Abort if the file doesn't exist and there's some other kind
+ of error stat()ing it */
+ if (errno != ENOENT)
+ rcfile_error(unable, errno);
+ return;
+ }
+
+ if ((rcstream = fopen(nanorc, "r")) == NULL) {
+ rcfile_error(unable, strerror(errno));
+ return;
+ }
+
+ parse_rcfile(rcstream, nanorc);
+ fclose(rcstream);
+
+}
+
+
+#endif /* ENABLE_NANORC */
+
diff --git a/utils.c b/utils.c
@@ -109,6 +109,19 @@ void *nmalloc(size_t howmuch)
return r;
}
+/* We're going to need this too */
+void *ncalloc(size_t howmuch, size_t size)
+{
+ void *r;
+
+ /* Panic save? */
+
+ if (!(r = calloc(howmuch, size)))
+ die(_("nano: calloc: out of memory!"));
+
+ return r;
+}
+
void *nrealloc(void *ptr, size_t howmuch)
{
void *r;