From 8d8e01224b3fa7c7e64ed3b4622f13602cf7bb9e Mon Sep 17 00:00:00 2001 From: Chris Allegretta Date: Wed, 18 Apr 2001 04:28:54 +0000 Subject: [PATCH] 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 --- ChangeLog | 6 ++ Makefile.am | 1 + Makefile.in | 6 +- global.c | 4 + nano.c | 8 +- nano.h | 8 ++ proto.h | 10 +++ rcfile.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.c | 13 +++ 9 files changed, 292 insertions(+), 7 deletions(-) create mode 100644 rcfile.c diff --git a/ChangeLog b/ChangeLog index bd82492d..0549898e 100644 --- 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 index 4cd0f14e..e67dd348 100644 --- 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 index 0c3df2a4..dc08e69a 100644 --- 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 index 158175cd..cb04e750 100644 --- 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 index 01c57ba0..c5beea6f 100644 --- 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 index 22396015..f8f013ac 100644 --- 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 index 554a7579..70484fba 100644 --- 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 new file mode 100644 index 00000000..59e03b4c --- /dev/null +++ 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 +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "proto.h" +#include "nano.h" + +#ifdef ENABLE_NANORC + +#ifndef NANO_SMALL +#include +#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 index a1396419..1ce844cc 100644 --- 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; -- 2.39.5