diff -udpr -X ex-r mutt-1.3.2-org/init.c mutt-1.3.2/init.c --- mutt-1.3.2-org/init.c Sun May 21 20:05:25 2000 +++ mutt-1.3.2/init.c Wed May 24 12:08:07 2000 @@ -100,7 +100,7 @@ int query_quadoption (int opt, const cha /* given the variable ``s'', return the index into the rc_vars array which matches, or -1 if the variable is not found. */ -int mutt_option_index (char *s) +static int mutt_option_index (const char *s) { int i; @@ -110,6 +110,70 @@ int mutt_option_index (char *s) return (-1); } +/* Puts the value of the variable "var" into "value". + * Returns zero if OK, and non-zero on error */ +static int query_value (const char *var, char *value, size_t len) +{ + int idx = mutt_option_index (var); + + if (idx == -1) + return (-1); /* no such variable */ + + { + char *vals[] = { "no", "yes", "ask-no", "ask-yes" }; + int type = DTYPE(MuttVars[idx].type); + + value[0] = '\0'; + + if (type == DT_STR || type == DT_PATH || type == DT_RX) + { + strfcpy (value, NONULL (*((char **) MuttVars[idx].data)), len); + if (type == DT_PATH) + mutt_pretty_mailbox (value); + } + else if (type == DT_ADDR) + { + rfc822_write_address (value, len, *((ADDRESS **) MuttVars[idx].data)); + } + else if (type == DT_QUAD) + strfcpy (value, vals[quadoption (MuttVars[idx].data)], len); + else if (type == DT_BOOL) + strfcpy (value, option (MuttVars[idx].data) ? "yes" : "no", len); + else if (type == DT_NUM) + snprintf (value, len, "%d", (*((short *) MuttVars[idx].data))); + else if (type == DT_SORT) + { + const struct mapping_t *map; + int method = *((short *) MuttVars[idx].data); + + switch (MuttVars[idx].type & DT_SUBTYPE_MASK) + { + case DT_SORT_ALIAS: + map = SortAliasMethods; + break; + case DT_SORT_BROWSER: + map = SortBrowserMethods; + break; +#ifdef HAVE_PGP + case DT_SORT_KEYS: + map = SortKeyMethods; + break; +#endif + default: + map = SortMethods; + break; + } + snprintf (value, len, "%s%s%s", + (method & SORT_REVERSE) ? "reverse-" : "", + (method & SORT_LAST) ? "last-" : "", + mutt_getnamebyvalue (method & SORT_MASK, map)); + } + else + return (-1); /* Unknown variable type? Should not happen */ + } + return 0; +} + static void add_char (BUFFER *buf, char ch) { size_t offset; @@ -616,6 +680,132 @@ static int parse_my_hdr (BUFFER *buf, BU return 0; } +static int parse_if (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) +{ + int var; + int do_command = 0; + char varvalue[LONG_STRING]; + char command[LONG_STRING]; + int op; + + /* First token: a variable name */ + mutt_extract_token (buf, s, 0); + if (query_value (buf->data, varvalue, sizeof (varvalue))) + { + snprintf (err->data, err->dsize, _("if: unknown variable %s"), buf->data); + return (-1); + } + var = mutt_option_index (buf->data); + + /* Second token: an operator */ + mutt_extract_token (buf, s, 0); + op = mutt_getvaluebyname (buf->data, IfOperators); + if (op == -1) + { + snprintf (err->data, err->dsize, _("if: unknown operator %s"), buf->data); + return (-1); + } + + /* Third token: a constant */ + mutt_extract_token (buf, s, 0); + if (!*buf->data) + { + strfcpy (err->data, _("if: no value"), err->dsize); + return (-1); + } + + if (op & IF_CMP_LESS) + { + char *t; + int varval; + int val; + + if (DTYPE (MuttVars[var].type != DT_NUM)) + { + snprintf (err->data, err->dsize, _("if: %s isn't numerical"), + MuttVars[var].option); + return (-1); + } + + varval = *((short *) MuttVars[var].data); + val = strtol (buf->data, &t, 0); + if (*t || (short) val != val) + { + snprintf (err->data, err->dsize, + _("if: invalid numeric value %s"), buf->data); + return (-1); + } + + if (varval == val) + do_command = (op & IF_CMP_EQUAL); + else if (varval < val) + do_command = (op & IF_CMP_LESS); + } + else if (op & IF_USE_RX) + { + regex_t re; + int res; + + if ((res = REGCOMP (&re, buf->data, + REG_NOSUB | mutt_which_case (buf->data)))) + { + regerror (res, &re, err->data, err->dsize); + regfree (&re); + mutt_error ("if: %s", buf); + return (-1); + } + do_command = ! REGEXEC (re, varvalue); + regfree (&re); + } + else /* simple string comparision */ + { + do_command = ! mutt_strcmp (varvalue, (char *) buf->data); + } + + if (op & IF_NEGATE) + do_command = ! do_command; + + /* fourth token: the command */ + if (MoreArgs (s)) + mutt_extract_token (buf, s, 0); + else + { + strfcpy (err->data, _("if: no command"), err->dsize); + return (-1); + } + if (do_command) + strncpy (command, buf->data, sizeof (command)); + else + command[0] = 0; + + /* fifth token: the else command (optional) */ + if (MoreArgs (s)) + { + mutt_extract_token (buf, s, 0); + if (!do_command) + strncpy (command, buf->data, sizeof (command)); + if (MoreArgs (s)) + { + strfcpy (err->data, _("if: too many arguments"), err->dsize); + return (-1); + } + } + + /* execute the command */ + if (*command) + { + BUFFER token; + int res; + + memset (&token, 0, sizeof (token)); + res = mutt_parse_rc_line (command, &token, err); + FREE (&token.data); + return res; + } + else + return 0; +} + static int parse_sort (short *val, const char *s, const struct mapping_t *map, BUFFER *err) { @@ -1525,7 +1715,7 @@ int mutt_var_value_complete (char *buffe { char var[STRING], *pt = buffer; int spaces; - + if (buffer[0] == 0) return 0; @@ -1541,83 +1731,29 @@ int mutt_var_value_complete (char *buffe if (mutt_strncmp (buffer, "set", 3) == 0) { - int idx; + char value[LONG_STRING], tmp[LONG_STRING]; + char *s, *d; + size_t dlen = buffer + len - pt - spaces; + strfcpy (var, pt, sizeof (var)); /* ignore the trailing '=' when comparing */ var[mutt_strlen (var) - 1] = 0; - if ((idx = mutt_option_index (var)) == -1) - return 0; /* no such variable. */ - else - { - char tmp [LONG_STRING], tmp2[LONG_STRING]; - char *s, *d; - size_t dlen = buffer + len - pt - spaces; - char *vals[] = { "no", "yes", "ask-no", "ask-yes" }; - - tmp[0] = '\0'; - if ((DTYPE(MuttVars[idx].type) == DT_STR) || - (DTYPE(MuttVars[idx].type) == DT_PATH) || - (DTYPE(MuttVars[idx].type) == DT_RX)) - { - strfcpy (tmp, NONULL (*((char **) MuttVars[idx].data)), sizeof (tmp)); - if (DTYPE (MuttVars[idx].type) == DT_PATH) - mutt_pretty_mailbox (tmp); - } - else if (DTYPE (MuttVars[idx].type) == DT_ADDR) - { - rfc822_write_address (tmp, sizeof (tmp), *((ADDRESS **) MuttVars[idx].data)); - } - else if (DTYPE (MuttVars[idx].type) == DT_QUAD) - strfcpy (tmp, vals[quadoption (MuttVars[idx].data)], sizeof (tmp)); - else if (DTYPE (MuttVars[idx].type) == DT_NUM) - snprintf (tmp, sizeof (tmp), "%d", (*((short *) MuttVars[idx].data))); - else if (DTYPE (MuttVars[idx].type) == DT_SORT) - { - const struct mapping_t *map; - char *p; + if (query_value (var, value, sizeof (value))) + return 0; - switch (MuttVars[idx].type & DT_SUBTYPE_MASK) - { - case DT_SORT_ALIAS: - map = SortAliasMethods; - break; - case DT_SORT_BROWSER: - map = SortBrowserMethods; - break; -#ifdef HAVE_PGP - case DT_SORT_KEYS: - map = SortKeyMethods; - break; -#endif - default: - map = SortMethods; - break; - } - p = mutt_getnamebyvalue (*((short *) MuttVars[idx].data) & SORT_MASK, map); - snprintf (tmp, sizeof (tmp), "%s%s%s", - (*((short *) MuttVars[idx].data) & SORT_REVERSE) ? "reverse-" : "", - (*((short *) MuttVars[idx].data) & SORT_LAST) ? "last-" : "", - p); - } - else if (DTYPE (MuttVars[idx].type) == DT_BOOL) - strfcpy (tmp, option (MuttVars[idx].data) ? "yes" : "no", sizeof (tmp)); - else - return 0; - - for (s = tmp, d = tmp2; *s && (d - tmp2) < sizeof (tmp2) - 2;) - { - if (*s == '\\' || *s == '"') - *d++ = '\\'; - *d++ = *s++; - } - *d = '\0'; - - strfcpy (tmp, pt, sizeof (tmp)); - snprintf (pt, dlen, "%s\"%s\"", tmp, tmp2); - - return 1; + for (s = value, d = tmp; *s && (d - tmp) < sizeof (tmp) - 2;) + { + if (*s == '\\' || *s == '"') + *d++ = '\\'; + *d++ = *s++; } + *d = '\0'; + + strfcpy (value, pt, sizeof (value)); + snprintf (pt, dlen, "%s\"%s\"", value, tmp); + + return 1; } return 0; } diff -udpr -X ex-r mutt-1.3.2-org/init.h mutt-1.3.2/init.h --- mutt-1.3.2-org/init.h Sun May 21 20:05:25 2000 +++ mutt-1.3.2/init.h Wed May 24 10:41:03 2000 @@ -2199,6 +2199,31 @@ const struct mapping_t SortKeyMethods[] }; #endif /* HAVE_PGP */ +#define IF_USE_RX (1<<0) +#define IF_CMP_LESS (1<<1) +#define IF_CMP_EQUAL (1<<2) +#define IF_NEGATE (1<<3) + +#define IF_RX (IF_USE_RX ) +#define IF_NOT_RX (IF_USE_RX | IF_NEGATE) +#define IF_GREATER ( IF_CMP_LESS | IF_CMP_EQUAL | IF_NEGATE) +#define IF_GREATER_EQUAL ( IF_CMP_LESS | IF_NEGATE) +#define IF_LESSER ( IF_CMP_LESS ) +#define IF_LESSER_EQUAL ( IF_CMP_LESS | IF_CMP_EQUAL ) +#define IF_EQUAL ( IF_CMP_EQUAL ) +#define IT_NOT_EQUAL ( IF_CMP_EQUAL | IF_NEGATE) + +const struct mapping_t IfOperators[] = { + { "=~", IF_RX }, + { "!~", IF_NOT_RX }, + { ">", IF_GREATER }, + { ">=", IF_GREATER_EQUAL }, + { "<", IF_LESSER }, + { "<=", IF_LESSER_EQUAL }, + { "==", IF_EQUAL }, + { "!=", IT_NOT_EQUAL }, + { NULL } +}; /* functions used to parse commands in a rc file */ @@ -2207,6 +2232,7 @@ static int parse_unlist (BUFFER *, BUFFE 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 parse_if (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_ignore (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_unignore (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_source (BUFFER *, BUFFER *, unsigned long, BUFFER *); @@ -2238,6 +2264,7 @@ struct command_t Commands[] = { { "fcc-save-hook", mutt_parse_hook, M_FCCHOOK | M_SAVEHOOK }, { "folder-hook", mutt_parse_hook, M_FOLDERHOOK }, { "hdr_order", parse_list, UL &HeaderOrderList }, + { "if", parse_if, 0 }, { "ignore", parse_ignore, 0 }, { "lists", parse_list, UL &MailLists }, { "macro", mutt_parse_macro, 0 },