3 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
4 * Copyright (c) 2001-2007 by Hiroyuki Yamamoto & The Claws Mail Team
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <glib/gi18n.h>
27 #include "filtering.h"
29 #include "matcher_parser.h"
30 #include "matcher_parser_lex.h"
31 #include "colorlabel.h"
33 static gint error = 0;
34 static gint bool_op = 0;
35 static gint match_type = 0;
36 static gchar *header = NULL;
38 static MatcherProp *prop;
40 static GSList *matchers_list = NULL;
42 static gboolean enabled = TRUE;
43 static gchar *name = NULL;
44 static gint account_id = 0;
45 static MatcherList *cond;
46 static GSList *action_list = NULL;
47 static FilteringAction *action = NULL;
48 static gboolean matcher_is_fast = TRUE;
50 static FilteringProp *filtering;
52 static GSList **prefs_filtering = NULL;
53 static int enable_compatibility = 0;
58 MATCHER_PARSE_ENABLED,
60 MATCHER_PARSE_ACCOUNT,
61 MATCHER_PARSE_CONDITION,
62 MATCHER_PARSE_FILTERING_ACTION,
65 static int matcher_parse_op = MATCHER_PARSE_FILE;
68 /* ******************************************************************** */
69 /* redeclarations to avoid warnings */
70 void matcher_parserrestart(FILE *input_file);
71 void matcher_parser_init(void);
72 void matcher_parser_switch_to_buffer(void * new_buffer);
73 void matcher_parser_delete_buffer(void * b);
74 void matcher_parserpop_buffer_state(void);
75 int matcher_parserlex(void);
77 void matcher_parser_start_parsing(FILE *f)
79 matcher_parserlineno = 1;
80 matcher_parserrestart(f);
82 matcher_parserparse();
86 void * matcher_parser_scan_string(const char * str);
88 FilteringProp *matcher_parser_get_filtering(gchar *str)
93 /* little hack to allow passing rules with no names */
94 if (!strncmp(str, "rulename ", 9))
95 tmp_str = g_strdup(str);
97 tmp_str = g_strconcat("rulename \"\" ", str, NULL);
99 /* bad coding to enable the sub-grammar matching
101 matcher_parserlineno = 1;
102 matcher_parse_op = MATCHER_PARSE_NO_EOL;
103 matcher_parserrestart(NULL);
104 matcher_parserpop_buffer_state();
105 matcher_parser_init();
106 bufstate = matcher_parser_scan_string((const char *) tmp_str);
107 matcher_parser_switch_to_buffer(bufstate);
108 if (matcher_parserparse() != 0)
110 matcher_parse_op = MATCHER_PARSE_FILE;
111 matcher_parser_delete_buffer(bufstate);
116 static gboolean check_quote_symetry(gchar *str)
122 return TRUE; /* heh, that's symetric */
125 for (walk = str; *walk; walk++) {
127 if (walk == str /* first char */
128 || *(walk - 1) != '\\') /* not escaped */
135 MatcherList *matcher_parser_get_name(gchar *str)
139 if (!check_quote_symetry(str)) {
144 /* bad coding to enable the sub-grammar matching
146 matcher_parserlineno = 1;
147 matcher_parse_op = MATCHER_PARSE_NAME;
148 matcher_parserrestart(NULL);
149 matcher_parserpop_buffer_state();
150 matcher_parser_init();
151 bufstate = matcher_parser_scan_string(str);
152 matcher_parserparse();
153 matcher_parse_op = MATCHER_PARSE_FILE;
154 matcher_parser_delete_buffer(bufstate);
158 MatcherList *matcher_parser_get_enabled(gchar *str)
162 if (!check_quote_symetry(str)) {
167 /* bad coding to enable the sub-grammar matching
169 matcher_parserlineno = 1;
170 matcher_parse_op = MATCHER_PARSE_ENABLED;
171 matcher_parserrestart(NULL);
172 matcher_parserpop_buffer_state();
173 matcher_parser_init();
174 bufstate = matcher_parser_scan_string(str);
175 matcher_parserparse();
176 matcher_parse_op = MATCHER_PARSE_FILE;
177 matcher_parser_delete_buffer(bufstate);
181 MatcherList *matcher_parser_get_account(gchar *str)
185 if (!check_quote_symetry(str)) {
190 /* bad coding to enable the sub-grammar matching
192 matcher_parserlineno = 1;
193 matcher_parse_op = MATCHER_PARSE_ACCOUNT;
194 matcher_parserrestart(NULL);
195 matcher_parserpop_buffer_state();
196 matcher_parser_init();
197 bufstate = matcher_parser_scan_string(str);
198 matcher_parserparse();
199 matcher_parse_op = MATCHER_PARSE_FILE;
200 matcher_parser_delete_buffer(bufstate);
204 MatcherList *matcher_parser_get_cond(gchar *str, gboolean *is_fast)
208 if (!check_quote_symetry(str)) {
213 matcher_is_fast = TRUE;
214 /* bad coding to enable the sub-grammar matching
216 matcher_parserlineno = 1;
217 matcher_parse_op = MATCHER_PARSE_CONDITION;
218 matcher_parserrestart(NULL);
219 matcher_parserpop_buffer_state();
220 matcher_parser_init();
221 bufstate = matcher_parser_scan_string(str);
222 matcher_parserparse();
223 matcher_parse_op = MATCHER_PARSE_FILE;
224 matcher_parser_delete_buffer(bufstate);
226 *is_fast = matcher_is_fast;
230 GSList *matcher_parser_get_action_list(gchar *str)
234 if (!check_quote_symetry(str)) {
239 /* bad coding to enable the sub-grammar matching
241 matcher_parserlineno = 1;
242 matcher_parse_op = MATCHER_PARSE_FILTERING_ACTION;
243 matcher_parserrestart(NULL);
244 matcher_parserpop_buffer_state();
245 matcher_parser_init();
246 bufstate = matcher_parser_scan_string(str);
247 matcher_parserparse();
248 matcher_parse_op = MATCHER_PARSE_FILE;
249 matcher_parser_delete_buffer(bufstate);
253 MatcherProp *matcher_parser_get_prop(gchar *str)
258 matcher_parserlineno = 1;
259 list = matcher_parser_get_cond(str, NULL);
263 if (list->matchers == NULL)
266 if (list->matchers->next != NULL)
269 prop = list->matchers->data;
271 g_slist_free(list->matchers);
277 void matcher_parsererror(char *str)
282 for (l = matchers_list; l != NULL; l = g_slist_next(l)) {
283 matcherprop_free((MatcherProp *)
287 g_slist_free(matchers_list);
288 matchers_list = NULL;
291 g_warning("filtering parsing: %i: %s\n",
292 matcher_parserlineno, str);
296 int matcher_parserwrap(void)
306 %token MATCHER_ALL MATCHER_UNREAD MATCHER_NOT_UNREAD
307 %token MATCHER_NEW MATCHER_NOT_NEW MATCHER_MARKED
308 %token MATCHER_NOT_MARKED MATCHER_DELETED MATCHER_NOT_DELETED
309 %token MATCHER_REPLIED MATCHER_NOT_REPLIED MATCHER_FORWARDED
310 %token MATCHER_NOT_FORWARDED MATCHER_SUBJECT MATCHER_NOT_SUBJECT
311 %token MATCHER_FROM MATCHER_NOT_FROM MATCHER_TO MATCHER_NOT_TO
312 %token MATCHER_CC MATCHER_NOT_CC MATCHER_TO_OR_CC MATCHER_NOT_TO_AND_NOT_CC
313 %token MATCHER_AGE_GREATER MATCHER_AGE_LOWER MATCHER_NEWSGROUPS
314 %token MATCHER_NOT_NEWSGROUPS MATCHER_INREPLYTO MATCHER_NOT_INREPLYTO
315 %token MATCHER_REFERENCES MATCHER_NOT_REFERENCES MATCHER_SCORE_GREATER
316 %token MATCHER_SCORE_LOWER MATCHER_HEADER MATCHER_NOT_HEADER
317 %token MATCHER_HEADERS_PART MATCHER_NOT_HEADERS_PART MATCHER_MESSAGE
318 %token MATCHER_NOT_MESSAGE MATCHER_BODY_PART MATCHER_NOT_BODY_PART
319 %token MATCHER_TEST MATCHER_NOT_TEST MATCHER_MATCHCASE MATCHER_MATCH
320 %token MATCHER_REGEXPCASE MATCHER_REGEXP MATCHER_SCORE MATCHER_MOVE
321 %token MATCHER_FOUND_IN_ADDRESSBOOK MATCHER_NOT_FOUND_IN_ADDRESSBOOK MATCHER_IN
322 %token MATCHER_COPY MATCHER_DELETE MATCHER_MARK MATCHER_UNMARK
323 %token MATCHER_LOCK MATCHER_UNLOCK
324 %token MATCHER_EXECUTE
325 %token MATCHER_MARK_AS_READ MATCHER_MARK_AS_UNREAD MATCHER_FORWARD
326 %token MATCHER_MARK_AS_SPAM MATCHER_MARK_AS_HAM
327 %token MATCHER_FORWARD_AS_ATTACHMENT MATCHER_EOL
328 %token MATCHER_OR MATCHER_AND
329 %token MATCHER_COLOR MATCHER_SCORE_EQUAL MATCHER_REDIRECT
330 %token MATCHER_SIZE_GREATER MATCHER_SIZE_SMALLER MATCHER_SIZE_EQUAL
331 %token MATCHER_LOCKED MATCHER_NOT_LOCKED
332 %token MATCHER_PARTIAL MATCHER_NOT_PARTIAL
333 %token MATCHER_COLORLABEL MATCHER_NOT_COLORLABEL
334 %token MATCHER_IGNORE_THREAD MATCHER_NOT_IGNORE_THREAD
335 %token MATCHER_WATCH_THREAD MATCHER_NOT_WATCH_THREAD
336 %token MATCHER_CHANGE_SCORE MATCHER_SET_SCORE
337 %token MATCHER_ADD_TO_ADDRESSBOOK
338 %token MATCHER_STOP MATCHER_HIDE MATCHER_IGNORE MATCHER_WATCH
339 %token MATCHER_SPAM MATCHER_NOT_SPAM
340 %token MATCHER_TAG MATCHER_NOT_TAG MATCHER_SET_TAG MATCHER_UNSET_TAG
341 %token MATCHER_TAGGED MATCHER_NOT_TAGGED MATCHER_CLEAR_TAGS
345 %token MATCHER_ENABLED MATCHER_DISABLED
346 %token MATCHER_RULENAME
347 %token MATCHER_ACCOUNT
348 %token <str> MATCHER_STRING
349 %token <str> MATCHER_SECTION
350 %token <str> MATCHER_INTEGER
356 if (matcher_parse_op == MATCHER_PARSE_FILE) {
357 prefs_filtering = &pre_global_processing;
371 { action_list = NULL; }
378 section_notification:
379 MATCHER_SECTION MATCHER_EOL
382 FolderItem *item = NULL;
384 if (matcher_parse_op == MATCHER_PARSE_FILE) {
385 enable_compatibility = 0;
386 if (!strcmp(folder, "global")) {
387 /* backward compatibility */
388 enable_compatibility = 1;
390 else if (!strcmp(folder, "preglobal")) {
391 prefs_filtering = &pre_global_processing;
393 else if (!strcmp(folder, "postglobal")) {
394 prefs_filtering = &post_global_processing;
396 else if (!strcmp(folder, "filtering")) {
397 prefs_filtering = &filtering_rules;
400 item = folder_find_item_from_identifier(folder);
402 prefs_filtering = &item->prefs->processing;
404 prefs_filtering = NULL;
412 enabled name account condition filtering MATCHER_EOL
413 | enabled name account condition filtering
414 | enabled name condition filtering MATCHER_EOL
415 | enabled name condition filtering
416 | name condition filtering MATCHER_EOL
417 | name condition filtering
419 if (matcher_parse_op == MATCHER_PARSE_NO_EOL)
422 matcher_parsererror("parse error [no eol]");
428 if (matcher_parse_op == MATCHER_PARSE_ENABLED)
431 matcher_parsererror("parse error [enabled]");
437 if (matcher_parse_op == MATCHER_PARSE_ACCOUNT)
440 matcher_parsererror("parse error [account]");
446 if (matcher_parse_op == MATCHER_PARSE_NAME)
449 matcher_parsererror("parse error [name]");
455 if (matcher_parse_op == MATCHER_PARSE_CONDITION)
458 matcher_parsererror("parse error [condition]");
462 | filtering_action_list
464 if (matcher_parse_op == MATCHER_PARSE_FILTERING_ACTION)
467 matcher_parsererror("parse error [filtering action]");
486 MATCHER_RULENAME MATCHER_STRING
493 MATCHER_ACCOUNT MATCHER_INTEGER
495 account_id = strtol($2, NULL, 10);
500 filtering_action_list
502 filtering = filteringprop_new(enabled, name, account_id, cond, action_list);
507 if (enable_compatibility) {
508 prefs_filtering = &filtering_rules;
509 if (action_list != NULL) {
510 FilteringAction * first_action;
512 first_action = action_list->data;
514 if (first_action->type == MATCHACTION_CHANGE_SCORE)
515 prefs_filtering = &pre_global_processing;
522 if ((matcher_parse_op == MATCHER_PARSE_FILE) &&
523 (prefs_filtering != NULL)) {
524 *prefs_filtering = g_slist_append(*prefs_filtering,
531 filtering_action_list:
532 filtering_action_b filtering_action_list
539 action_list = g_slist_append(action_list, action);
547 match_type = MATCHTYPE_MATCHCASE;
551 match_type = MATCHTYPE_MATCH;
555 match_type = MATCHTYPE_REGEXPCASE;
559 match_type = MATCHTYPE_REGEXP;
566 cond = matcherlist_new(matchers_list, (bool_op == MATCHERBOOL_AND));
567 matchers_list = NULL;
572 condition_list bool_op one_condition
574 matchers_list = g_slist_append(matchers_list, prop);
578 matchers_list = NULL;
579 matchers_list = g_slist_append(matchers_list, prop);
586 bool_op = MATCHERBOOL_AND;
590 bool_op = MATCHERBOOL_OR;
599 criteria = MATCHCRITERIA_ALL;
600 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
606 criteria = MATCHCRITERIA_UNREAD;
607 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
613 criteria = MATCHCRITERIA_NOT_UNREAD;
614 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
620 criteria = MATCHCRITERIA_NEW;
621 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
627 criteria = MATCHCRITERIA_NOT_NEW;
628 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
634 criteria = MATCHCRITERIA_MARKED;
635 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
641 criteria = MATCHCRITERIA_NOT_MARKED;
642 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
648 criteria = MATCHCRITERIA_DELETED;
649 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
651 | MATCHER_NOT_DELETED
655 criteria = MATCHCRITERIA_NOT_DELETED;
656 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
662 criteria = MATCHCRITERIA_REPLIED;
663 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
665 | MATCHER_NOT_REPLIED
669 criteria = MATCHCRITERIA_NOT_REPLIED;
670 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
676 criteria = MATCHCRITERIA_FORWARDED;
677 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
679 | MATCHER_NOT_FORWARDED
683 criteria = MATCHCRITERIA_NOT_FORWARDED;
684 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
690 criteria = MATCHCRITERIA_LOCKED;
691 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
697 criteria = MATCHCRITERIA_NOT_LOCKED;
698 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
704 criteria = MATCHCRITERIA_SPAM;
705 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
711 criteria = MATCHCRITERIA_NOT_SPAM;
712 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
718 criteria = MATCHCRITERIA_PARTIAL;
719 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
721 | MATCHER_NOT_PARTIAL
725 criteria = MATCHCRITERIA_NOT_PARTIAL;
726 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
728 | MATCHER_COLORLABEL MATCHER_INTEGER
733 criteria = MATCHCRITERIA_COLORLABEL;
734 value = strtol($2, NULL, 10);
735 if (value < 0) value = 0;
736 else if (value > COLORLABELS) value = COLORLABELS;
737 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
739 | MATCHER_NOT_COLORLABEL MATCHER_INTEGER
744 criteria = MATCHCRITERIA_NOT_COLORLABEL;
745 value = strtol($2, NULL, 0);
746 if (value < 0) value = 0;
747 else if (value > COLORLABELS) value = COLORLABELS;
748 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
750 | MATCHER_IGNORE_THREAD
754 criteria = MATCHCRITERIA_IGNORE_THREAD;
755 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
757 | MATCHER_NOT_IGNORE_THREAD
761 criteria = MATCHCRITERIA_NOT_IGNORE_THREAD;
762 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
764 | MATCHER_WATCH_THREAD
768 criteria = MATCHCRITERIA_WATCH_THREAD;
769 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
771 | MATCHER_NOT_WATCH_THREAD
775 criteria = MATCHCRITERIA_NOT_WATCH_THREAD;
776 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
778 | MATCHER_SUBJECT match_type MATCHER_STRING
783 criteria = MATCHCRITERIA_SUBJECT;
785 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
787 | MATCHER_NOT_SUBJECT match_type MATCHER_STRING
792 criteria = MATCHCRITERIA_NOT_SUBJECT;
794 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
796 | MATCHER_FROM match_type MATCHER_STRING
801 criteria = MATCHCRITERIA_FROM;
803 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
805 | MATCHER_NOT_FROM match_type MATCHER_STRING
810 criteria = MATCHCRITERIA_NOT_FROM;
812 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
814 | MATCHER_TO match_type MATCHER_STRING
819 criteria = MATCHCRITERIA_TO;
821 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
823 | MATCHER_NOT_TO match_type MATCHER_STRING
828 criteria = MATCHCRITERIA_NOT_TO;
830 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
832 | MATCHER_CC match_type MATCHER_STRING
837 criteria = MATCHCRITERIA_CC;
839 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
841 | MATCHER_NOT_CC match_type MATCHER_STRING
846 criteria = MATCHCRITERIA_NOT_CC;
848 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
850 | MATCHER_TO_OR_CC match_type MATCHER_STRING
855 criteria = MATCHCRITERIA_TO_OR_CC;
857 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
859 | MATCHER_NOT_TO_AND_NOT_CC match_type MATCHER_STRING
864 criteria = MATCHCRITERIA_NOT_TO_AND_NOT_CC;
866 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
868 | MATCHER_TAG match_type MATCHER_STRING
873 criteria = MATCHCRITERIA_TAG;
875 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
877 | MATCHER_NOT_TAG match_type MATCHER_STRING
882 criteria = MATCHCRITERIA_NOT_TAG;
884 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
890 criteria = MATCHCRITERIA_TAGGED;
891 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
897 criteria = MATCHCRITERIA_NOT_TAGGED;
898 prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
900 | MATCHER_AGE_GREATER MATCHER_INTEGER
905 criteria = MATCHCRITERIA_AGE_GREATER;
906 value = strtol($2, NULL, 0);
907 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
909 | MATCHER_AGE_LOWER MATCHER_INTEGER
914 criteria = MATCHCRITERIA_AGE_LOWER;
915 value = strtol($2, NULL, 0);
916 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
918 | MATCHER_NEWSGROUPS match_type MATCHER_STRING
923 criteria = MATCHCRITERIA_NEWSGROUPS;
925 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
927 | MATCHER_NOT_NEWSGROUPS match_type MATCHER_STRING
932 criteria = MATCHCRITERIA_NOT_NEWSGROUPS;
934 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
936 | MATCHER_INREPLYTO match_type MATCHER_STRING
941 criteria = MATCHCRITERIA_INREPLYTO;
943 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
945 | MATCHER_NOT_INREPLYTO match_type MATCHER_STRING
950 criteria = MATCHCRITERIA_NOT_INREPLYTO;
952 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
954 | MATCHER_REFERENCES match_type MATCHER_STRING
959 criteria = MATCHCRITERIA_REFERENCES;
961 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
963 | MATCHER_NOT_REFERENCES match_type MATCHER_STRING
968 criteria = MATCHCRITERIA_NOT_REFERENCES;
970 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
972 | MATCHER_SCORE_GREATER MATCHER_INTEGER
977 criteria = MATCHCRITERIA_SCORE_GREATER;
978 value = strtol($2, NULL, 0);
979 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
981 | MATCHER_SCORE_LOWER MATCHER_INTEGER
986 criteria = MATCHCRITERIA_SCORE_LOWER;
987 value = strtol($2, NULL, 0);
988 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
990 | MATCHER_SCORE_EQUAL MATCHER_INTEGER
995 criteria = MATCHCRITERIA_SCORE_EQUAL;
996 value = strtol($2, NULL, 0);
997 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
999 | MATCHER_SIZE_GREATER MATCHER_INTEGER
1003 criteria = MATCHCRITERIA_SIZE_GREATER;
1004 value = strtol($2, NULL, 0);
1005 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
1007 | MATCHER_SIZE_SMALLER MATCHER_INTEGER
1011 criteria = MATCHCRITERIA_SIZE_SMALLER;
1012 value = strtol($2, NULL, 0);
1013 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
1015 | MATCHER_SIZE_EQUAL MATCHER_INTEGER
1019 criteria = MATCHCRITERIA_SIZE_EQUAL;
1020 value = strtol($2, NULL, 0);
1021 prop = matcherprop_new(criteria, NULL, 0, NULL, value);
1023 | MATCHER_HEADER MATCHER_STRING
1025 header = g_strdup($2);
1026 } match_type MATCHER_STRING
1030 matcher_is_fast = FALSE;
1031 criteria = MATCHCRITERIA_HEADER;
1033 prop = matcherprop_new(criteria, header, match_type, expr, 0);
1036 | MATCHER_NOT_HEADER MATCHER_STRING
1038 header = g_strdup($2);
1039 } match_type MATCHER_STRING
1043 matcher_is_fast = FALSE;
1044 criteria = MATCHCRITERIA_NOT_HEADER;
1046 prop = matcherprop_new(criteria, header, match_type, expr, 0);
1049 | MATCHER_HEADERS_PART match_type MATCHER_STRING
1053 matcher_is_fast = FALSE;
1054 criteria = MATCHCRITERIA_HEADERS_PART;
1056 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
1058 | MATCHER_NOT_HEADERS_PART match_type MATCHER_STRING
1062 matcher_is_fast = FALSE;
1063 criteria = MATCHCRITERIA_NOT_HEADERS_PART;
1065 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
1067 | MATCHER_FOUND_IN_ADDRESSBOOK MATCHER_STRING
1069 header = g_strdup($2);
1070 } MATCHER_IN MATCHER_STRING
1075 criteria = MATCHCRITERIA_FOUND_IN_ADDRESSBOOK;
1077 prop = matcherprop_new(criteria, header, match_type, expr, 0);
1080 | MATCHER_NOT_FOUND_IN_ADDRESSBOOK MATCHER_STRING
1082 header = g_strdup($2);
1083 } MATCHER_IN MATCHER_STRING
1088 criteria = MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK;
1090 prop = matcherprop_new(criteria, header, match_type, expr, 0);
1093 | MATCHER_MESSAGE match_type MATCHER_STRING
1097 matcher_is_fast = FALSE;
1098 criteria = MATCHCRITERIA_MESSAGE;
1100 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
1102 | MATCHER_NOT_MESSAGE match_type MATCHER_STRING
1106 matcher_is_fast = FALSE;
1107 criteria = MATCHCRITERIA_NOT_MESSAGE;
1109 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
1111 | MATCHER_BODY_PART match_type MATCHER_STRING
1115 matcher_is_fast = FALSE;
1116 criteria = MATCHCRITERIA_BODY_PART;
1118 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
1120 | MATCHER_NOT_BODY_PART match_type MATCHER_STRING
1124 matcher_is_fast = FALSE;
1125 criteria = MATCHCRITERIA_NOT_BODY_PART;
1127 prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
1129 | MATCHER_TEST MATCHER_STRING
1133 matcher_is_fast = FALSE;
1134 criteria = MATCHCRITERIA_TEST;
1136 prop = matcherprop_new(criteria, NULL, 0, expr, 0);
1138 | MATCHER_NOT_TEST MATCHER_STRING
1142 matcher_is_fast = FALSE;
1143 criteria = MATCHCRITERIA_NOT_TEST;
1145 prop = matcherprop_new(criteria, NULL, 0, expr, 0);
1150 MATCHER_EXECUTE MATCHER_STRING
1153 gint action_type = 0;
1155 action_type = MATCHACTION_EXECUTE;
1157 action = filteringaction_new(action_type, 0, cmd, 0, 0, NULL);
1159 | MATCHER_MOVE MATCHER_STRING
1161 gchar *destination = NULL;
1162 gint action_type = 0;
1164 action_type = MATCHACTION_MOVE;
1166 action = filteringaction_new(action_type, 0, destination, 0, 0, NULL);
1168 | MATCHER_SET_TAG MATCHER_STRING
1170 gchar *destination = NULL;
1171 gint action_type = 0;
1173 action_type = MATCHACTION_SET_TAG;
1175 action = filteringaction_new(action_type, 0, destination, 0, 0, NULL);
1177 | MATCHER_UNSET_TAG MATCHER_STRING
1179 gchar *destination = NULL;
1180 gint action_type = 0;
1182 action_type = MATCHACTION_UNSET_TAG;
1184 action = filteringaction_new(action_type, 0, destination, 0, 0, NULL);
1186 | MATCHER_CLEAR_TAGS
1188 gint action_type = 0;
1190 action_type = MATCHACTION_CLEAR_TAGS;
1191 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1193 | MATCHER_COPY MATCHER_STRING
1195 gchar *destination = NULL;
1196 gint action_type = 0;
1198 action_type = MATCHACTION_COPY;
1200 action = filteringaction_new(action_type, 0, destination, 0, 0, NULL);
1204 gint action_type = 0;
1206 action_type = MATCHACTION_DELETE;
1207 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1211 gint action_type = 0;
1213 action_type = MATCHACTION_MARK;
1214 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1218 gint action_type = 0;
1220 action_type = MATCHACTION_UNMARK;
1221 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1225 gint action_type = 0;
1227 action_type = MATCHACTION_LOCK;
1228 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1232 gint action_type = 0;
1234 action_type = MATCHACTION_UNLOCK;
1235 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1237 | MATCHER_MARK_AS_READ
1239 gint action_type = 0;
1241 action_type = MATCHACTION_MARK_AS_READ;
1242 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1244 | MATCHER_MARK_AS_UNREAD
1246 gint action_type = 0;
1248 action_type = MATCHACTION_MARK_AS_UNREAD;
1249 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1251 | MATCHER_MARK_AS_SPAM
1253 gint action_type = 0;
1255 action_type = MATCHACTION_MARK_AS_SPAM;
1256 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1258 | MATCHER_MARK_AS_HAM
1260 gint action_type = 0;
1262 action_type = MATCHACTION_MARK_AS_HAM;
1263 action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL);
1265 | MATCHER_FORWARD MATCHER_INTEGER MATCHER_STRING
1267 gchar *destination = NULL;
1268 gint action_type = 0;
1269 gint account_id = 0;
1271 action_type = MATCHACTION_FORWARD;
1272 account_id = strtol($2, NULL, 10);
1274 action = filteringaction_new(action_type,
1275 account_id, destination, 0, 0, NULL);
1277 | MATCHER_FORWARD_AS_ATTACHMENT MATCHER_INTEGER MATCHER_STRING
1279 gchar *destination = NULL;
1280 gint action_type = 0;
1281 gint account_id = 0;
1283 action_type = MATCHACTION_FORWARD_AS_ATTACHMENT;
1284 account_id = strtol($2, NULL, 10);
1286 action = filteringaction_new(action_type,
1287 account_id, destination, 0, 0, NULL);
1289 | MATCHER_REDIRECT MATCHER_INTEGER MATCHER_STRING
1291 gchar *destination = NULL;
1292 gint action_type = 0;
1293 gint account_id = 0;
1295 action_type = MATCHACTION_REDIRECT;
1296 account_id = strtol($2, NULL, 10);
1298 action = filteringaction_new(action_type,
1299 account_id, destination, 0, 0, NULL);
1301 | MATCHER_COLOR MATCHER_INTEGER
1303 gint action_type = 0;
1306 action_type = MATCHACTION_COLOR;
1307 color = strtol($2, NULL, 10);
1308 action = filteringaction_new(action_type, 0, NULL, color, 0, NULL);
1310 | MATCHER_CHANGE_SCORE MATCHER_INTEGER
1314 score = strtol($2, NULL, 10);
1315 action = filteringaction_new(MATCHACTION_CHANGE_SCORE, 0,
1316 NULL, 0, score, NULL);
1318 /* backward compatibility */
1319 | MATCHER_SCORE MATCHER_INTEGER
1323 score = strtol($2, NULL, 10);
1324 action = filteringaction_new(MATCHACTION_CHANGE_SCORE, 0,
1325 NULL, 0, score, NULL);
1327 | MATCHER_SET_SCORE MATCHER_INTEGER
1331 score = strtol($2, NULL, 10);
1332 action = filteringaction_new(MATCHACTION_SET_SCORE, 0,
1333 NULL, 0, score, NULL);
1337 action = filteringaction_new(MATCHACTION_HIDE, 0, NULL, 0, 0, NULL);
1341 action = filteringaction_new(MATCHACTION_IGNORE, 0, NULL, 0, 0, NULL);
1345 action = filteringaction_new(MATCHACTION_WATCH, 0, NULL, 0, 0, NULL);
1347 | MATCHER_ADD_TO_ADDRESSBOOK MATCHER_STRING
1349 header = g_strdup($2);
1352 gchar *addressbook = NULL;
1353 gint action_type = 0;
1355 action_type = MATCHACTION_ADD_TO_ADDRESSBOOK;
1357 action = filteringaction_new(action_type, 0, addressbook, 0, 0, header);
1362 action = filteringaction_new(MATCHACTION_STOP, 0, NULL, 0, 0, NULL);