diff options
-rw-r--r-- | globals.h | 2 | ||||
-rw-r--r-- | hcache.c | 2 | ||||
-rw-r--r-- | init.c | 58 | ||||
-rw-r--r-- | mutt.h | 10 | ||||
-rw-r--r-- | muttlib.c | 98 | ||||
-rw-r--r-- | protos.h | 3 |
6 files changed, 133 insertions, 40 deletions
@@ -182,7 +182,7 @@ WHERE RX_LIST *MailLists INITVAL(0); WHERE RX_LIST *UnMailLists INITVAL(0); WHERE RX_LIST *SubscribedLists INITVAL(0); WHERE RX_LIST *UnSubscribedLists INITVAL(0); -WHERE SPAM_LIST *SpamList INITVAL(0); +WHERE REPLACE_LIST *SpamList INITVAL(0); WHERE RX_LIST *NoSpamList INITVAL(0); @@ -1160,7 +1160,7 @@ mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer) unsigned int intval; } digest; struct md5_ctx ctx; - SPAM_LIST *spam; + REPLACE_LIST *spam; RX_LIST *nospam; hcachever = HCACHEVER; @@ -453,11 +453,11 @@ int mutt_add_to_rx_list (RX_LIST **list, const char *s, int flags, BUFFER *err) return 0; } -static int remove_from_spam_list (SPAM_LIST **list, const char *pat); +static int remove_from_replace_list (REPLACE_LIST **list, const char *pat); -static int add_to_spam_list (SPAM_LIST **list, const char *pat, const char *templ, BUFFER *err) +static int add_to_replace_list (REPLACE_LIST **list, const char *pat, const char *templ, BUFFER *err) { - SPAM_LIST *t = NULL, *last = NULL; + REPLACE_LIST *t = NULL, *last = NULL; REGEXP *rx; int n; const char *p; @@ -490,12 +490,12 @@ static int add_to_spam_list (SPAM_LIST **list, const char *pat, const char *temp break; } - /* If t is set, it's pointing into an extant SPAM_LIST* that we want to + /* If t is set, it's pointing into an extant REPLACE_LIST* that we want to * update. Otherwise we want to make a new one to link at the list's end. */ if (!t) { - t = mutt_new_spam_list(); + t = mutt_new_replace_list(); t->rx = rx; if (last) last->next = t; @@ -503,7 +503,7 @@ static int add_to_spam_list (SPAM_LIST **list, const char *pat, const char *temp *list = t; } - /* Now t is the SPAM_LIST* that we want to modify. It is prepared. */ + /* Now t is the REPLACE_LIST* that we want to modify. It is prepared. */ t->template = safe_strdup(templ); /* Find highest match number in template string */ @@ -524,9 +524,9 @@ static int add_to_spam_list (SPAM_LIST **list, const char *pat, const char *temp if (t->nmatch > t->rx->rx->re_nsub) { - snprintf (err->data, err->dsize, _("Not enough subexpressions for spam " + snprintf (err->data, err->dsize, _("Not enough subexpressions for " "template")); - remove_from_spam_list(list, pat); + remove_from_replace_list(list, pat); return -1; } @@ -535,38 +535,38 @@ static int add_to_spam_list (SPAM_LIST **list, const char *pat, const char *temp return 0; } -static int remove_from_spam_list (SPAM_LIST **list, const char *pat) +static int remove_from_replace_list (REPLACE_LIST **list, const char *pat) { - SPAM_LIST *spam, *prev; + REPLACE_LIST *cur, *prev; int nremoved = 0; /* Being first is a special case. */ - spam = *list; - if (!spam) + cur = *list; + if (!cur) return 0; - if (spam->rx && !mutt_strcmp(spam->rx->pattern, pat)) + if (cur->rx && !mutt_strcmp(cur->rx->pattern, pat)) { - *list = spam->next; - mutt_free_regexp(&spam->rx); - FREE(&spam->template); - FREE(&spam); + *list = cur->next; + mutt_free_regexp(&cur->rx); + FREE(&cur->template); + FREE(&cur); return 1; } - prev = spam; - for (spam = prev->next; spam;) + prev = cur; + for (cur = prev->next; cur;) { - if (!mutt_strcmp(spam->rx->pattern, pat)) + if (!mutt_strcmp(cur->rx->pattern, pat)) { - prev->next = spam->next; - mutt_free_regexp(&spam->rx); - FREE(&spam->template); - FREE(&spam); - spam = prev->next; + prev->next = cur->next; + mutt_free_regexp(&cur->rx); + FREE(&cur->template); + FREE(&cur); + cur = prev->next; ++nremoved; } else - spam = spam->next; + cur = cur->next; } return nremoved; @@ -785,7 +785,7 @@ static int parse_spam_list (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER * mutt_extract_token (&templ, s, 0); /* Add to the spam list. */ - if (add_to_spam_list (&SpamList, buf->data, templ.data, err) != 0) { + if (add_to_replace_list (&SpamList, buf->data, templ.data, err) != 0) { FREE(&templ.data); return -1; } @@ -809,13 +809,13 @@ static int parse_spam_list (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER * /* "*" is a special case. */ if (!mutt_strcmp(buf->data, "*")) { - mutt_free_spam_list (&SpamList); + mutt_free_replace_list (&SpamList); mutt_free_rx_list (&NoSpamList); return 0; } /* If it's on the spam list, just remove it. */ - if (remove_from_spam_list(&SpamList, buf->data) != 0) + if (remove_from_replace_list(&SpamList, buf->data) != 0) return 0; /* Otherwise, add it to the nospam list. */ @@ -569,20 +569,20 @@ typedef struct rx_list_t struct rx_list_t *next; } RX_LIST; -typedef struct spam_list_t +typedef struct replace_list_t { REGEXP *rx; int nmatch; char *template; - struct spam_list_t *next; -} SPAM_LIST; + struct replace_list_t *next; +} REPLACE_LIST; #define mutt_new_list() safe_calloc (1, sizeof (LIST)) #define mutt_new_rx_list() safe_calloc (1, sizeof (RX_LIST)) -#define mutt_new_spam_list() safe_calloc (1, sizeof (SPAM_LIST)) +#define mutt_new_replace_list() safe_calloc (1, sizeof (REPLACE_LIST)) void mutt_free_list (LIST **); void mutt_free_rx_list (RX_LIST **); -void mutt_free_spam_list (SPAM_LIST **); +void mutt_free_replace_list (REPLACE_LIST **); LIST *mutt_copy_list (LIST *); int mutt_matches_ignore (const char *, LIST *); @@ -1074,6 +1074,98 @@ void mutt_safe_path (char *s, size_t l, ADDRESS *a) *p = '_'; } +/* Note this function uses a fixed size buffer of LONG_STRING and so + * should only be used for visual modifications, such as disp_subj. */ +char *mutt_apply_replace (char *dbuf, size_t dlen, char *sbuf, REPLACE_LIST *rlist) +{ + REPLACE_LIST *l; + static regmatch_t *pmatch = NULL; + static int nmatch = 0; + static char twinbuf[2][LONG_STRING]; + int switcher = 0; + char *p; + int i, n; + size_t cpysize, tlen; + char *src, *dst; + + if (dbuf && dlen) + dbuf[0] = '\0'; + + if (sbuf == NULL || *sbuf == '\0' || (dbuf && !dlen)) + return dbuf; + + twinbuf[0][0] = '\0'; + twinbuf[1][0] = '\0'; + src = twinbuf[switcher]; + dst = src; + + strfcpy(src, sbuf, LONG_STRING); + + for (l = rlist; l; l = l->next) + { + /* If this pattern needs more matches, expand pmatch. */ + if (l->nmatch > nmatch) + { + safe_realloc (&pmatch, l->nmatch * sizeof(regmatch_t)); + nmatch = l->nmatch; + } + + if (regexec (l->rx->rx, src, l->nmatch, pmatch, 0) == 0) + { + tlen = 0; + switcher ^= 1; + dst = twinbuf[switcher]; + + dprint (5, (debugfile, "mutt_apply_replace: %s matches %s\n", src, l->rx->pattern)); + + /* Copy into other twinbuf with substitutions */ + if (l->template) + { + for (p = l->template; *p && (tlen < LONG_STRING - 1); ) + { + if (*p == '%') + { + p++; + if (*p == 'L') + { + p++; + cpysize = MIN (pmatch[0].rm_so, LONG_STRING - tlen - 1); + strncpy(&dst[tlen], src, cpysize); + tlen += cpysize; + } + else if (*p == 'R') + { + p++; + cpysize = MIN (strlen (src) - pmatch[0].rm_eo, LONG_STRING - tlen - 1); + strncpy(&dst[tlen], &src[pmatch[0].rm_eo], cpysize); + tlen += cpysize; + } + else + { + n = strtoul(p, &p, 10); /* get subst number */ + while (isdigit((unsigned char)*p)) /* skip subst token */ + ++p; + for (i = pmatch[n].rm_so; (i < pmatch[n].rm_eo) && (tlen < LONG_STRING-1); i++) + dst[tlen++] = src[i]; + } + } + else + dst[tlen++] = *p++; + } + } + dst[tlen] = '\0'; + dprint (5, (debugfile, "mutt_apply_replace: subst %s\n", dst)); + } + src = dst; + } + + if (dbuf) + strfcpy(dbuf, dst, dlen); + else + dbuf = safe_strdup(dst); + return dbuf; +} + void mutt_FormatString (char *dest, /* output buffer */ size_t destlen, /* output buffer len */ @@ -1888,9 +1980,9 @@ void mutt_free_rx_list (RX_LIST **list) } } -void mutt_free_spam_list (SPAM_LIST **list) +void mutt_free_replace_list (REPLACE_LIST **list) { - SPAM_LIST *p; + REPLACE_LIST *p; if (!list) return; while (*list) @@ -1926,7 +2018,7 @@ int mutt_match_rx_list (const char *s, RX_LIST *l) * * Returns 1 if the argument `s` matches a pattern in the spam list, otherwise * 0. */ -int mutt_match_spam_list (const char *s, SPAM_LIST *l, char *text, int textsize) +int mutt_match_spam_list (const char *s, REPLACE_LIST *l, char *text, int textsize) { static regmatch_t *pmatch = NULL; static int nmatch = 0; @@ -271,6 +271,7 @@ void mutt_alias_add_reverse (ALIAS *t); void mutt_alias_delete_reverse (ALIAS *t); int mutt_alloc_color (int fg, int bg); int mutt_any_key_to_continue (const char *); +char *mutt_apply_replace (char *, size_t, char *, REPLACE_LIST *); int mutt_buffy_check (int); int mutt_buffy_notify (void); int mutt_builtin_editor (const char *, HEADER *, HEADER *); @@ -324,7 +325,7 @@ int mutt_is_valid_mailbox (const char *); int mutt_link_threads (HEADER *, HEADER *, CONTEXT *); int mutt_lookup_mime_type (BODY *, const char *); int mutt_match_rx_list (const char *, RX_LIST *); -int mutt_match_spam_list (const char *, SPAM_LIST *, char *, int); +int mutt_match_spam_list (const char *, REPLACE_LIST *, char *, int); int mutt_messages_in_thread (CONTEXT *, HEADER *, int); int mutt_multi_choice (char *prompt, char *letters); int mutt_needs_mailcap (BODY *); |