mutt stable branch with some hacks
at jcs 199 lines 5.0 kB view raw
1/* 2 * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19#if HAVE_CONFIG_H 20# include "config.h" 21#endif 22 23#include "mutt.h" 24#include "mutt_menu.h" 25#include "sort.h" 26#include <string.h> 27#include <stdlib.h> 28 29typedef struct score_t 30{ 31 char *str; 32 pattern_t *pat; 33 int val; 34 int exact; /* if this rule matches, don't evaluate any more */ 35 struct score_t *next; 36} SCORE; 37 38static SCORE *Score = NULL; 39 40void mutt_check_rescore (CONTEXT *ctx) 41{ 42 int i; 43 44 if (option (OPTNEEDRESCORE) && option (OPTSCORE)) 45 { 46 if ((Sort & SORT_MASK) == SORT_SCORE || 47 (SortAux & SORT_MASK) == SORT_SCORE) 48 { 49 set_option (OPTNEEDRESORT); 50 if ((Sort & SORT_MASK) == SORT_THREADS) 51 set_option (OPTSORTSUBTHREADS); 52 } 53 54 /* must redraw the index since the user might have %N in it */ 55 mutt_set_menu_redraw_full (MENU_MAIN); 56 mutt_set_menu_redraw_full (MENU_PAGER); 57 58 for (i = 0; ctx && i < ctx->msgcount; i++) 59 { 60 mutt_score_message (ctx, ctx->hdrs[i], 1); 61 ctx->hdrs[i]->pair = 0; 62 } 63 } 64 unset_option (OPTNEEDRESCORE); 65} 66 67int mutt_parse_score (BUFFER *buf, BUFFER *s, union pointer_long_t udata, BUFFER *err) 68{ 69 SCORE *ptr, *last; 70 char *pattern, *pc; 71 struct pattern_t *pat; 72 73 mutt_extract_token (buf, s, 0); 74 if (!MoreArgs (s)) 75 { 76 strfcpy (err->data, _("score: too few arguments"), err->dsize); 77 return (-1); 78 } 79 pattern = buf->data; 80 mutt_buffer_init (buf); 81 mutt_extract_token (buf, s, 0); 82 if (MoreArgs (s)) 83 { 84 FREE (&pattern); 85 strfcpy (err->data, _("score: too many arguments"), err->dsize); 86 return (-1); 87 } 88 89 /* look for an existing entry and update the value, else add it to the end 90 of the list */ 91 for (ptr = Score, last = NULL; ptr; last = ptr, ptr = ptr->next) 92 if (mutt_strcmp (pattern, ptr->str) == 0) 93 break; 94 if (!ptr) 95 { 96 if ((pat = mutt_pattern_comp (pattern, 0, err)) == NULL) 97 { 98 FREE (&pattern); 99 return (-1); 100 } 101 ptr = safe_calloc (1, sizeof (SCORE)); 102 if (last) 103 last->next = ptr; 104 else 105 Score = ptr; 106 ptr->pat = pat; 107 ptr->str = pattern; 108 } 109 else 110 /* 'buf' arg was cleared and 'pattern' holds the only reference; 111 * as here 'ptr' != NULL -> update the value only in which case 112 * ptr->str already has the string, so pattern should be freed. 113 */ 114 FREE (&pattern); 115 pc = buf->data; 116 if (*pc == '=') 117 { 118 ptr->exact = 1; 119 pc++; 120 } 121 if (mutt_atoi (pc, &ptr->val) < 0) 122 { 123 FREE (&pattern); 124 strfcpy (err->data, _("Error: score: invalid number"), err->dsize); 125 return (-1); 126 } 127 set_option (OPTNEEDRESCORE); 128 return 0; 129} 130 131void mutt_score_message (CONTEXT *ctx, HEADER *hdr, int upd_ctx) 132{ 133 SCORE *tmp; 134 pattern_cache_t cache; 135 136 memset (&cache, 0, sizeof (cache)); 137 hdr->score = 0; /* in case of re-scoring */ 138 for (tmp = Score; tmp; tmp = tmp->next) 139 { 140 if (mutt_pattern_exec (tmp->pat, MUTT_MATCH_FULL_ADDRESS, NULL, hdr, &cache) > 0) 141 { 142 if (tmp->exact || tmp->val == 9999 || tmp->val == -9999) 143 { 144 hdr->score = tmp->val; 145 break; 146 } 147 hdr->score += tmp->val; 148 } 149 } 150 if (hdr->score < 0) 151 hdr->score = 0; 152 153 if (hdr->score <= ScoreThresholdDelete) 154 _mutt_set_flag (ctx, hdr, MUTT_DELETE, 1, upd_ctx); 155 if (hdr->score <= ScoreThresholdRead) 156 _mutt_set_flag (ctx, hdr, MUTT_READ, 1, upd_ctx); 157 if (hdr->score >= ScoreThresholdFlag) 158 _mutt_set_flag (ctx, hdr, MUTT_FLAG, 1, upd_ctx); 159} 160 161int mutt_parse_unscore (BUFFER *buf, BUFFER *s, union pointer_long_t udata, BUFFER *err) 162{ 163 SCORE *tmp, *last = NULL; 164 165 while (MoreArgs (s)) 166 { 167 mutt_extract_token (buf, s, 0); 168 if (!mutt_strcmp ("*", buf->data)) 169 { 170 for (tmp = Score; tmp; ) 171 { 172 last = tmp; 173 tmp = tmp->next; 174 mutt_pattern_free (&last->pat); 175 FREE (&last); 176 } 177 Score = NULL; 178 } 179 else 180 { 181 for (tmp = Score; tmp; last = tmp, tmp = tmp->next) 182 { 183 if (!mutt_strcmp (buf->data, tmp->str)) 184 { 185 if (last) 186 last->next = tmp->next; 187 else 188 Score = tmp->next; 189 mutt_pattern_free (&tmp->pat); 190 FREE (&tmp); 191 /* there should only be one score per pattern, so we can stop here */ 192 break; 193 } 194 } 195 } 196 } 197 set_option (OPTNEEDRESCORE); 198 return 0; 199}