]> granicus.if.org Git - neomutt/commitdiff
add 'finish' function
authorRichard Russon <rich@flatcap.org>
Thu, 10 Mar 2016 18:28:39 +0000 (18:28 +0000)
committerRichard Russon <rich@flatcap.org>
Mon, 4 Apr 2016 02:33:19 +0000 (03:33 +0100)
Add config command 'finish' -- stop reading current config file.

hook.c
init.c
init.h

diff --git a/hook.c b/hook.c
index a89b615231c6e48698ca13f8cf3123eef35277b2..3a0756e4146e617731af6df510759ce534d52f37 100644 (file)
--- a/hook.c
+++ b/hook.c
@@ -362,7 +362,7 @@ void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type)
 
     if (hook->type & type)
       if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not)
-       if (mutt_parse_rc_line (hook->command, &token, &err) != 0)
+       if (mutt_parse_rc_line (hook->command, &token, &err) == -1)
        {
          FREE (&token.data);
          mutt_error ("%s", err.data);
diff --git a/init.c b/init.c
index 1cb3e806a5ba8c1a924ed6d150b4dde520964e6b..c10f44835686f2c528d57c522ca922d77a6cc737 100644 (file)
--- a/init.c
+++ b/init.c
@@ -32,6 +32,7 @@
 #include "mutt_crypt.h"
 #include "mutt_idna.h"
 #include "group.h"
+#include "version.h"
 
 #if defined(USE_SSL)
 #include "mutt_ssl.h"
@@ -601,6 +602,29 @@ static void remove_from_list (LIST **l, const char *str)
   }
 }
 
+/**
+ * finish_source - 'finish' command: stop processing current config file
+ * @tmp:  Temporary space shared by all command handlers
+ * @s:    Current line of the config file
+ * @data: data field from init.h:struct command_t
+ * @err:  Buffer for any error message
+ *
+ * If the 'finish' command is found, we should stop reading the current file.
+ *
+ * Returns:
+ *      1 Stop processing the current file
+ *     -1 Failed
+ */
+static int finish_source (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
+{
+       if (MoreArgs (s)) {
+               snprintf (err->data, err->dsize, _("finish: too many arguments"));
+               return -1;
+       }
+
+       return 1;
+}
+
 /**
  * parse_ifdef - 'ifdef' command: conditional config
  * @tmp:  Temporary space shared by all command handlers
@@ -609,12 +633,14 @@ static void remove_from_list (LIST **l, const char *str)
  * @err:  Buffer for any error message
  *
  * The 'ifdef' command allows conditional elements in the config file.
- * If a given variable, function or command exists, then read the rest of the
- * line of config commands. e.g.
- *
- *     ifdef sidebar_visible source ~/.mutt/sidebar.rc
+ * If a given variable, function, command or compile-time symbol exists, then
+ * read the rest of the line of config commands.
+ * e.g.
+ *     ifdef USE_SIDEBAR source ~/.mutt/sidebar.rc
  *
  * If (data == 1) then it means use the 'ifndef' (if-not-defined) command.
+ * e.g.
+ *     ifndef USE_IMAP finish
  *
  * Returns:
  *      0 Success
@@ -631,6 +657,11 @@ static int parse_ifdef (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
        /* is the item defined as a variable? */
        res = (mutt_option_index (tmp->data) != -1);
 
+       /* is the item a compiled-in feature? */
+       if (!res) {
+               res = feature_enabled (tmp->data);
+       }
+
        /* or a function? */
        if (!res) {
                for (i = 0; !res && (i < MENU_MAX); i++) {
@@ -666,12 +697,14 @@ static int parse_ifdef (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
 
         /* ifdef KNOWN_SYMBOL or ifndef UNKNOWN_SYMBOL */
        if ((res && (data == 0)) || (!res && (data == 1))) {
-               if (mutt_parse_rc_line (tmp->data, &token, err) == -1) {
+                int rc = mutt_parse_rc_line (tmp->data, &token, err);
+               if (rc == -1) {
                        mutt_error ("Error: %s", err->data);
                        FREE(&token.data);
                        return -1;
                }
                FREE(&token.data);
+                return rc;
        }
        return 0;
 }
@@ -2313,7 +2346,7 @@ static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
 static int source_rc (const char *rcfile, BUFFER *err)
 {
   FILE *f;
-  int line = 0, rc = 0, conv = 0;
+  int line = 0, rc = 0, conv = 0, line_rc;
   BUFFER token;
   char *linebuf = NULL;
   char *currentline = NULL;
@@ -2342,17 +2375,17 @@ static int source_rc (const char *rcfile, BUFFER *err)
     else 
       currentline=linebuf;
 
-    if (mutt_parse_rc_line (currentline, &token, err) == -1)
-    {
+    line_rc = mutt_parse_rc_line (currentline, &token, err);
+    if (line_rc == -1) {
       mutt_error (_("Error in %s, line %d: %s"), rcfile, line, err->data);
       if (--rc < -MAXERRS) 
       {
         if (conv) FREE(&currentline);
         break;
       }
-    }
-    else
-    {
+    } else if (line_rc == 1) {
+      break;   /* Found "finish" command */
+    } else {
       if (rc < 0)
         rc = -1;
     }
@@ -2407,7 +2440,7 @@ static int parse_source (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err
    err         where to write error messages */
 int mutt_parse_rc_line (/* const */ char *line, BUFFER *token, BUFFER *err)
 {
-  int i, r = -1;
+  int i, r = 0;
   BUFFER expn;
 
   if (!line || !*line)
@@ -2434,22 +2467,24 @@ int mutt_parse_rc_line (/* const */ char *line, BUFFER *token, BUFFER *err)
     {
       if (!mutt_strcmp (token->data, Commands[i].name))
       {
-       if (Commands[i].func (token, &expn, Commands[i].data, err) != 0)
-         goto finish;
-        break;
+        r = Commands[i].func (token, &expn, Commands[i].data, err);
+        if (r != 0) {   /* -1 Error, +1 Finish */
+          goto finish;  /* Propagate return code */
+        }
+        break;          /* Continue with next command */
       }
     }
     if (!Commands[i].name)
     {
       snprintf (err->data, err->dsize, _("%s: unknown command"), NONULL (token->data));
-      goto finish;
+      r = -1;
+      break;            /* Ignore the rest of the line */
     }
   }
-  r = 0;
 finish:
   if (expn.destroy)
     FREE (&expn.data);
-  return (r);
+  return r;
 }
 
 
@@ -2927,7 +2962,7 @@ static int mutt_execute_commands (LIST *p)
   mutt_buffer_init (&token);
   for (; p; p = p->next)
   {
-    if (mutt_parse_rc_line (p->data, &token, &err) != 0)
+    if (mutt_parse_rc_line (p->data, &token, &err) == -1)
     {
       fprintf (stderr, _("Error in command line: %s\n"), err.data);
       FREE (&token.data);
diff --git a/init.h b/init.h
index 5ef101b8471e7e239a859f4455ba17244c3e3896..8e87aa08aff94445af5592072bcc046c8055af7a 100644 (file)
--- a/init.h
+++ b/init.h
@@ -3665,6 +3665,7 @@ static int parse_lists (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 static int parse_unlists (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 static int parse_alias (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 static int parse_unalias (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+static int finish_source (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 static int parse_ifdef (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 static int parse_ignore (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 static int parse_unignore (BUFFER *, BUFFER *, unsigned long, BUFFER *);
@@ -3718,6 +3719,7 @@ const struct command_t Commands[] = {
   { "hdr_order",       parse_list,             UL &HeaderOrderList },
   { "ifdef",           parse_ifdef,            0 },
   { "ifndef",          parse_ifdef,            1 },
+  { "finish",          finish_source,          0 },
 #ifdef HAVE_ICONV
   { "iconv-hook",      mutt_parse_hook,        M_ICONVHOOK },
 #endif