#include "mutt_crypt.h"
#include "mutt_idna.h"
#include "group.h"
+#include "version.h"
#if defined(USE_SSL)
#include "mutt_ssl.h"
}
}
+/**
+ * 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
* @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
/* 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++) {
/* 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;
}
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;
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(¤tline);
break;
}
- }
- else
- {
+ } else if (line_rc == 1) {
+ break; /* Found "finish" command */
+ } else {
if (rc < 0)
rc = -1;
}
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)
{
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;
}
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);
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 *);
{ "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