]> git.wh0rd.org Git - nano.git/commitdiff
Added rcfile.c source code and basic .nanorc functionality
authorChris Allegretta <chrisa@asty.org>
Wed, 18 Apr 2001 04:28:54 +0000 (04:28 +0000)
committerChris Allegretta <chrisa@asty.org>
Wed, 18 Apr 2001 04:28:54 +0000 (04:28 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@598 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
Makefile.am
Makefile.in
global.c
nano.c
nano.h
proto.h
rcfile.c [new file with mode: 0644]
utils.c

index bd82492d767200db583aca5ca6c20f9469931ca9..0549898ecb034d768c9152e4537af72fde7c613f 100644 (file)
--- 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...
index 4cd0f14edd02cedd3ad04ec2c1ae41d615735d20..e67dd3486b36223051e0abc90429a22d72275899 100644 (file)
@@ -7,6 +7,7 @@ nano_SOURCES =  cut.c \
                nano.c \
                nano.h \
                proto.h \
+               rcfile.c \
                search.c \
                utils.c \
                winio.c 
index 0c3df2a4fabe16a89484bc195e9c008cefc4566f..dc08e69aed30a866edf5155c6bf1dc249d259d85 100644 (file)
@@ -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@
index 158175cdaa54cb4835e0ed301ed8253f099c474f..cb04e7500f85dd32a599c4bff9043d30761034c9 100644 (file)
--- 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 01c57ba09fa2466b04085a062690f782ea4d921a..c5beea6fa86808e483b44c449e1d8d89e4daa79b 100644 (file)
--- a/nano.c
+++ b/nano.c
 /* 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 223960156bc10c00f1acc6fdc4700c88e764ffaa..f8f013ac9e30e5fd2654c3c3b8994b4fe6f395bc 100644 (file)
--- 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 554a757916a65ea3281583fb1f7e79600851a7f1..70484fba70bd2ac3dd0eb3874ad00f451311e88e 100644 (file)
--- 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 (file)
index 0000000..59e03b4
--- /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 <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
index a13964198fa8c9a9eb4ea8dfaba8b655a9e09d43..1ce844cc77cbc9262977bc029153472d5b6e0c00 100644 (file)
--- 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;