add 'Selective download'
[claws.git] / src / matcher_parser_parse.y
1 %{
2 #include "filtering.h"
3 #include "scoring.h"
4 #include "matcher.h"
5 #include "matcher_parser.h"
6 #include "matcher_parser_lex.h"
7 #include "intl.h"
8 #include <glib.h>
9 #include "defs.h"
10 #include "utils.h"
11
12 static gint error = 0;
13 static gint bool_op = 0;
14 static gint match_type = 0;
15 static gchar * header = NULL;
16
17 static MatcherProp * prop;
18
19 static GSList * matchers_list = NULL;
20
21 static MatcherList * cond;
22 static gint score = 0;
23 static FilteringAction * action = NULL;
24
25 static FilteringProp *  filtering;
26 static ScoringProp * scoring = NULL;
27
28 static GSList ** prefs_scoring = NULL;
29 static GSList ** prefs_filtering = NULL;
30
31 static int matcher_parser_dialog = 0;
32
33
34 /* ******************************************************************** */
35
36
37
38 void matcher_parser_start_parsing(FILE * f)
39 {
40         matcher_parserrestart(f);
41         matcher_parserparse();
42 }
43  
44 FilteringProp * matcher_parser_get_filtering(gchar * str)
45 {
46         void * bufstate;
47
48         /* bad coding to enable the sub-grammar matching
49            in yacc */
50         matcher_parserlineno = 1;
51         matcher_parser_dialog = 1;
52         bufstate = matcher_parser_scan_string(str);
53         if (matcher_parserparse() != 0)
54                 filtering = NULL;
55         matcher_parser_dialog = 0;
56         matcher_parser_delete_buffer(bufstate);
57         return filtering;
58 }
59
60 ScoringProp * matcher_parser_get_scoring(gchar * str)
61 {
62         void * bufstate;
63
64         /* bad coding to enable the sub-grammar matching
65            in yacc */
66         matcher_parserlineno = 1;
67         matcher_parser_dialog = 1;
68         bufstate = matcher_parser_scan_string(str);
69         if (matcher_parserparse() != 0)
70                 scoring = NULL;
71         matcher_parser_dialog = 0;
72         matcher_parser_delete_buffer(bufstate);
73         return scoring;
74 }
75
76 MatcherList * matcher_parser_get_cond(gchar * str)
77 {
78         void * bufstate;
79
80         /* bad coding to enable the sub-grammar matching
81            in yacc */
82         matcher_parserlineno = 1;
83         matcher_parser_dialog = 1;
84         bufstate = matcher_parser_scan_string(str);
85         matcher_parserparse();
86         matcher_parser_dialog = 0;
87         matcher_parser_delete_buffer(bufstate);
88         return cond;
89 }
90
91 MatcherProp * matcher_parser_get_prop(gchar * str)
92 {
93         MatcherList * list;
94         MatcherProp * prop;
95
96         matcher_parserlineno = 1;
97         list = matcher_parser_get_cond(str);
98         if (list == NULL)
99                 return NULL;
100
101         if (list->matchers == NULL)
102                 return NULL;
103
104         if (list->matchers->next != NULL)
105                 return NULL;
106
107         prop = list->matchers->data;
108
109         g_slist_free(list->matchers);
110         g_free(list);
111
112         return prop;
113 }
114
115 void matcher_parsererror(char * str)
116 {
117         GSList * l;
118
119         if (matchers_list) {
120                 for(l = matchers_list ; l != NULL ;
121                     l = g_slist_next(l))
122                         matcherprop_free((MatcherProp *)
123                                          l->data);
124                 g_slist_free(matchers_list);
125                 matchers_list = NULL;
126         }
127
128         g_warning(_("scoring / filtering parsing: %i: %s\n"),
129                   matcher_parserlineno, str);
130         error = 1;
131 }
132
133 int matcher_parserwrap(void)
134 {
135         return 1;
136 }
137 %}
138
139 %union {
140         char * str;
141         int value;
142 }
143
144 %token MATCHER_ALL MATCHER_UNREAD  MATCHER_NOT_UNREAD 
145 %token MATCHER_NEW  MATCHER_NOT_NEW  MATCHER_MARKED
146 %token MATCHER_NOT_MARKED  MATCHER_DELETED  MATCHER_NOT_DELETED
147 %token MATCHER_REPLIED  MATCHER_NOT_REPLIED  MATCHER_FORWARDED
148 %token MATCHER_NOT_FORWARDED  MATCHER_SUBJECT  MATCHER_NOT_SUBJECT
149 %token MATCHER_FROM  MATCHER_NOT_FROM  MATCHER_TO  MATCHER_NOT_TO
150 %token MATCHER_CC  MATCHER_NOT_CC  MATCHER_TO_OR_CC  MATCHER_NOT_TO_AND_NOT_CC
151 %token MATCHER_AGE_GREATER  MATCHER_AGE_LOWER  MATCHER_NEWSGROUPS
152 %token MATCHER_NOT_NEWSGROUPS  MATCHER_INREPLYTO  MATCHER_NOT_INREPLYTO
153 %token MATCHER_REFERENCES  MATCHER_NOT_REFERENCES  MATCHER_SCORE_GREATER
154 %token MATCHER_SCORE_LOWER  MATCHER_HEADER  MATCHER_NOT_HEADER
155 %token MATCHER_HEADERS_PART  MATCHER_NOT_HEADERS_PART  MATCHER_MESSAGE
156 %token MATCHER_NOT_MESSAGE  MATCHER_BODY_PART  MATCHER_NOT_BODY_PART
157 %token MATCHER_EXECUTE  MATCHER_NOT_EXECUTE  MATCHER_MATCHCASE  MATCHER_MATCH
158 %token MATCHER_REGEXPCASE  MATCHER_REGEXP  MATCHER_SCORE  MATCHER_MOVE
159 %token MATCHER_COPY  MATCHER_DELETE  MATCHER_MARK  MATCHER_UNMARK
160 %token MATCHER_MARK_AS_READ  MATCHER_MARK_AS_UNREAD  MATCHER_FORWARD
161 %token MATCHER_FORWARD_AS_ATTACHMENT  MATCHER_EOL  MATCHER_STRING  
162 %token MATCHER_OR MATCHER_AND  
163 %token MATCHER_COLOR MATCHER_SCORE_EQUAL MATCHER_BOUNCE MATCHER_DELETE_ON_SERVER
164
165 %start file
166
167 %token <str> MATCHER_STRING
168 %token <str> MATCHER_SECTION
169 %token <value> MATCHER_INTEGER
170
171 %%
172
173 file:
174 {
175         if (!matcher_parser_dialog) {
176                 prefs_scoring = &global_scoring;
177                 prefs_filtering = &global_processing;
178         }
179 }
180 file_line_list;
181
182 file_line_list:
183 file_line
184 file_line_list
185 | file_line
186 ;
187
188 file_line:
189 section_notification
190 | instruction
191 | error MATCHER_EOL
192 {
193         yyerrok;
194 };
195
196 section_notification:
197 MATCHER_SECTION MATCHER_EOL
198 {
199         gchar * folder = $1;
200         FolderItem * item = NULL;
201
202         if (!matcher_parser_dialog) {
203                 item = folder_find_item_from_identifier(folder);
204                 if (item == NULL) {
205                         prefs_scoring = &global_scoring;
206                         prefs_filtering = &global_processing;
207                 }
208                 else {
209                         prefs_scoring = &item->prefs->scoring;
210                         prefs_filtering = &item->prefs->processing;
211                 }
212         }
213 }
214 ;
215
216 instruction:
217 condition end_instr_opt
218 | MATCHER_EOL
219 ;
220
221 end_instr_opt:
222 filtering_or_scoring end_action
223 |
224 {
225         if (matcher_parser_dialog)
226                 YYACCEPT;
227         else {
228                 matcher_parsererror("parse error");
229                 YYERROR;
230         }
231 }
232 ;
233
234 end_action:
235 MATCHER_EOL
236 |
237 {
238         if (matcher_parser_dialog)
239                 YYACCEPT;
240         else {
241                 matcher_parsererror("parse error");
242                 YYERROR;
243         }
244 }
245 ;
246
247 filtering_or_scoring:
248 filtering_action
249 {
250         filtering = filteringprop_new(cond, action);
251         cond = NULL;
252         action = NULL;
253         if (!matcher_parser_dialog) {
254                 * prefs_filtering = g_slist_append(* prefs_filtering,
255                                                    filtering);
256                 filtering = NULL;
257         }
258 }
259 | scoring_rule
260 {
261         scoring = scoringprop_new(cond, score);
262         cond = NULL;
263         score = 0;
264         if (!matcher_parser_dialog) {
265                 * prefs_scoring = g_slist_append(* prefs_scoring, scoring);
266                 scoring = NULL;
267         }
268 }
269 ;
270
271 match_type:
272 MATCHER_MATCHCASE
273 {
274         match_type = MATCHTYPE_MATCHCASE;
275 }
276 | MATCHER_MATCH
277 {
278         match_type = MATCHTYPE_MATCH;
279 }
280 | MATCHER_REGEXPCASE
281 {
282         match_type = MATCHTYPE_REGEXPCASE;
283 }
284 | MATCHER_REGEXP
285 {
286         match_type = MATCHTYPE_REGEXP;
287 }
288 ;
289
290 condition:
291 condition_list
292 {
293         cond = matcherlist_new(matchers_list, (bool_op == MATCHERBOOL_AND));
294         matchers_list = NULL;
295 }
296 ;
297
298 condition_list:
299 condition_list bool_op one_condition
300 {
301         matchers_list = g_slist_append(matchers_list, prop);
302 }
303 | one_condition
304 {
305         matchers_list = NULL;
306         matchers_list = g_slist_append(matchers_list, prop);
307 }
308 ;
309
310 bool_op:
311 MATCHER_AND
312 {
313         bool_op = MATCHERBOOL_AND;
314 }
315 | MATCHER_OR
316 {
317         bool_op = MATCHERBOOL_OR;
318 }
319 ;
320
321 one_condition:
322 MATCHER_ALL
323 {
324         gint criteria = 0;
325
326         criteria = MATCHCRITERIA_ALL;
327         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
328 }
329 | MATCHER_UNREAD
330 {
331         gint criteria = 0;
332
333         criteria = MATCHCRITERIA_UNREAD;
334         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
335 }
336 | MATCHER_NOT_UNREAD 
337 {
338         gint criteria = 0;
339
340         criteria = MATCHCRITERIA_NOT_UNREAD;
341         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
342 }
343 | MATCHER_NEW
344 {
345         gint criteria = 0;
346
347         criteria = MATCHCRITERIA_NEW;
348         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
349 }
350 | MATCHER_NOT_NEW
351 {
352         gint criteria = 0;
353
354         criteria = MATCHCRITERIA_NOT_NEW;
355         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
356 }
357 | MATCHER_MARKED
358 {
359         gint criteria = 0;
360
361         criteria = MATCHCRITERIA_MARKED;
362         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
363 }
364 | MATCHER_NOT_MARKED
365 {
366         gint criteria = 0;
367
368         criteria = MATCHCRITERIA_NOT_MARKED;
369         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
370 }
371 | MATCHER_DELETED
372 {
373         gint criteria = 0;
374
375         criteria = MATCHCRITERIA_DELETED;
376         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
377 }
378 | MATCHER_NOT_DELETED
379 {
380         gint criteria = 0;
381
382         criteria = MATCHCRITERIA_NOT_DELETED;
383         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
384 }
385 | MATCHER_REPLIED
386 {
387         gint criteria = 0;
388
389         criteria = MATCHCRITERIA_REPLIED;
390         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
391 }
392 | MATCHER_NOT_REPLIED
393 {
394         gint criteria = 0;
395
396         criteria = MATCHCRITERIA_NOT_REPLIED;
397         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
398 }
399 | MATCHER_FORWARDED
400 {
401         gint criteria = 0;
402
403         criteria = MATCHCRITERIA_FORWARDED;
404         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
405 }
406 | MATCHER_NOT_FORWARDED
407 {
408         gint criteria = 0;
409
410         criteria = MATCHCRITERIA_NOT_FORWARDED;
411         prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
412 }
413 | MATCHER_SUBJECT match_type MATCHER_STRING
414 {
415         gint criteria = 0;
416         gchar * expr = NULL;
417
418         criteria = MATCHCRITERIA_SUBJECT;
419         expr = $3;
420         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
421 }
422 | MATCHER_NOT_SUBJECT match_type MATCHER_STRING
423 {
424         gint criteria = 0;
425         gchar * expr = NULL;
426
427         criteria = MATCHCRITERIA_NOT_SUBJECT;
428         expr = $3;
429         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
430 }
431 | MATCHER_FROM match_type MATCHER_STRING
432 {
433         gint criteria = 0;
434         gchar * expr = NULL;
435
436         criteria = MATCHCRITERIA_FROM;
437         expr = $3;
438         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
439 }
440 | MATCHER_NOT_FROM match_type MATCHER_STRING
441 {
442         gint criteria = 0;
443         gchar * expr = NULL;
444
445         criteria = MATCHCRITERIA_NOT_FROM;
446         expr = $3;
447         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
448 }
449 | MATCHER_TO match_type MATCHER_STRING
450 {
451         gint criteria = 0;
452         gchar * expr = NULL;
453
454         criteria = MATCHCRITERIA_TO;
455         expr = $3;
456         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
457 }
458 | MATCHER_NOT_TO match_type MATCHER_STRING
459 {
460         gint criteria = 0;
461         gchar * expr = NULL;
462
463         criteria = MATCHCRITERIA_NOT_TO;
464         expr = $3;
465         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
466 }
467 | MATCHER_CC match_type MATCHER_STRING
468 {
469         gint criteria = 0;
470         gchar * expr = NULL;
471
472         criteria = MATCHCRITERIA_CC;
473         expr = $3;
474         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
475 }
476 | MATCHER_NOT_CC match_type MATCHER_STRING
477 {
478         gint criteria = 0;
479         gchar * expr = NULL;
480
481         criteria = MATCHCRITERIA_NOT_CC;
482         expr = $3;
483         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
484 }
485 | MATCHER_TO_OR_CC match_type MATCHER_STRING
486 {
487         gint criteria = 0;
488         gchar * expr = NULL;
489
490         criteria = MATCHCRITERIA_TO_OR_CC;
491         expr = $3;
492         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
493 }
494 | MATCHER_NOT_TO_AND_NOT_CC match_type MATCHER_STRING
495 {
496         gint criteria = 0;
497         gchar * expr = NULL;
498
499         criteria = MATCHCRITERIA_NOT_TO_AND_NOT_CC;
500         expr = $3;
501         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
502 }
503 | MATCHER_AGE_GREATER MATCHER_INTEGER
504 {
505         gint criteria = 0;
506         gint value = 0;
507
508         criteria = MATCHCRITERIA_AGE_GREATER;
509         value = atoi($2);
510         prop = matcherprop_new(criteria, NULL, 0, NULL, value);
511 }
512 | MATCHER_AGE_LOWER MATCHER_INTEGER
513 {
514         gint criteria = 0;
515         gint value = 0;
516
517         criteria = MATCHCRITERIA_AGE_LOWER;
518         value = atoi($2);
519         prop = matcherprop_new(criteria, NULL, 0, NULL, value);
520 }
521 | MATCHER_NEWSGROUPS match_type MATCHER_STRING
522 {
523         gint criteria = 0;
524         gchar * expr = NULL;
525
526         criteria = MATCHCRITERIA_NEWSGROUPS;
527         expr = $3;
528         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
529 }
530 | MATCHER_NOT_NEWSGROUPS match_type MATCHER_STRING
531 {
532         gint criteria = 0;
533         gchar * expr = NULL;
534
535         criteria = MATCHCRITERIA_NOT_NEWSGROUPS;
536         expr = $3;
537         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
538 }
539 | MATCHER_INREPLYTO match_type MATCHER_STRING
540 {
541         gint criteria = 0;
542         gchar * expr = NULL;
543
544         criteria = MATCHCRITERIA_INREPLYTO;
545         expr = $3;
546         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
547 }
548 | MATCHER_NOT_INREPLYTO match_type MATCHER_STRING
549 {
550         gint criteria = 0;
551         gchar * expr = NULL;
552
553         criteria = MATCHCRITERIA_NOT_INREPLYTO;
554         expr = $3;
555         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
556 }
557 | MATCHER_REFERENCES match_type MATCHER_STRING
558 {
559         gint criteria = 0;
560         gchar * expr = NULL;
561
562         criteria = MATCHCRITERIA_REFERENCES;
563         expr = $3;
564         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
565 }
566 | MATCHER_NOT_REFERENCES match_type MATCHER_STRING
567 {
568         gint criteria = 0;
569         gchar * expr = NULL;
570
571         criteria = MATCHCRITERIA_NOT_REFERENCES;
572         expr = $3;
573         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
574 }
575 | MATCHER_SCORE_GREATER MATCHER_INTEGER
576 {
577         gint criteria = 0;
578         gint value = 0;
579
580         criteria = MATCHCRITERIA_SCORE_GREATER;
581         value = atoi($2);
582         prop = matcherprop_new(criteria, NULL, 0, NULL, value);
583 }
584 | MATCHER_SCORE_LOWER MATCHER_INTEGER
585 {
586         gint criteria = 0;
587         gint value = 0;
588
589         criteria = MATCHCRITERIA_SCORE_LOWER;
590         value = atoi($2);
591         prop = matcherprop_new(criteria, NULL, 0, NULL, value);
592 }
593 | MATCHER_SCORE_EQUAL MATCHER_INTEGER
594 {
595         gint criteria = 0;
596         gint value = 0;
597
598         criteria = MATCHCRITERIA_SCORE_EQUAL;
599         value = atoi($2);
600         prop = matcherprop_new(criteria, NULL, 0, NULL, value);
601 }
602 | MATCHER_HEADER MATCHER_STRING
603 {
604         header = g_strdup($2);
605 } match_type MATCHER_STRING
606 {
607         gint criteria = 0;
608         gchar * expr = NULL;
609
610         criteria = MATCHCRITERIA_HEADER;
611         expr = $2;
612         prop = matcherprop_new(criteria, header, match_type, expr, 0);
613         g_free(header);
614 }
615 | MATCHER_NOT_HEADER MATCHER_STRING
616 {
617         header = g_strdup($2);
618 } match_type MATCHER_STRING
619 {
620         gint criteria = 0;
621         gchar * expr = NULL;
622
623         criteria = MATCHCRITERIA_NOT_HEADER;
624         expr = $2;
625         prop = matcherprop_new(criteria, header, match_type, expr, 0);
626         g_free(header);
627 }
628 | MATCHER_HEADERS_PART match_type MATCHER_STRING
629 {
630         gint criteria = 0;
631         gchar * expr = NULL;
632
633         criteria = MATCHCRITERIA_HEADERS_PART;
634         expr = $3;
635         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
636 }
637 | MATCHER_NOT_HEADERS_PART match_type MATCHER_STRING
638 {
639         gint criteria = 0;
640         gchar * expr = NULL;
641
642         criteria = MATCHCRITERIA_NOT_HEADERS_PART;
643         expr = $3;
644         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
645 }
646 | MATCHER_MESSAGE match_type MATCHER_STRING
647 {
648         gint criteria = 0;
649         gchar * expr = NULL;
650
651         criteria = MATCHCRITERIA_MESSAGE;
652         expr = $3;
653         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
654 }
655 | MATCHER_NOT_MESSAGE match_type MATCHER_STRING
656 {
657         gint criteria = 0;
658         gchar * expr = NULL;
659
660         criteria = MATCHCRITERIA_NOT_MESSAGE;
661         expr = $3;
662         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
663 }
664 | MATCHER_BODY_PART match_type MATCHER_STRING
665 {
666         gint criteria = 0;
667         gchar * expr = NULL;
668
669         criteria = MATCHCRITERIA_BODY_PART;
670         expr = $3;
671         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
672 }
673 | MATCHER_NOT_BODY_PART match_type MATCHER_STRING
674 {
675         gint criteria = 0;
676         gchar * expr = NULL;
677
678         criteria = MATCHCRITERIA_NOT_BODY_PART;
679         expr = $3;
680         prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
681 }
682 | MATCHER_EXECUTE MATCHER_STRING
683 {
684         gint criteria = 0;
685         gchar * expr = NULL;
686
687         criteria = MATCHCRITERIA_EXECUTE;
688         expr = $2;
689         prop = matcherprop_new(criteria, NULL, 0, expr, 0);
690 }
691 | MATCHER_NOT_EXECUTE MATCHER_STRING
692 {
693         gint criteria = 0;
694         gchar * expr = NULL;
695
696         criteria = MATCHCRITERIA_NOT_EXECUTE;
697         expr = $2;
698         prop = matcherprop_new(criteria, NULL, 0, expr, 0);
699 }
700 ;
701
702 filtering_action:
703 MATCHER_EXECUTE MATCHER_STRING
704 {
705         gchar * cmd = NULL;
706         gint action_type = 0;
707
708         action_type = MATCHACTION_EXECUTE;
709         cmd = $2;
710         action = filteringaction_new(action_type, 0, cmd, 0);
711 }
712 | MATCHER_MOVE MATCHER_STRING
713 {
714         gchar * destination = NULL;
715         gint action_type = 0;
716
717         action_type = MATCHACTION_MOVE;
718         destination = $2;
719         action = filteringaction_new(action_type, 0, destination, 0);
720 }
721 | MATCHER_COPY MATCHER_STRING
722 {
723         gchar * destination = NULL;
724         gint action_type = 0;
725
726         action_type = MATCHACTION_COPY;
727         destination = $2;
728         action = filteringaction_new(action_type, 0, destination, 0);
729 }
730 | MATCHER_DELETE
731 {
732         gint action_type = 0;
733
734         action_type = MATCHACTION_DELETE;
735         action = filteringaction_new(action_type, 0, NULL, 0);
736 }
737 | MATCHER_MARK
738 {
739         gint action_type = 0;
740
741         action_type = MATCHACTION_MARK;
742         action = filteringaction_new(action_type, 0, NULL, 0);
743 }
744 | MATCHER_UNMARK
745 {
746         gint action_type = 0;
747
748         action_type = MATCHACTION_UNMARK;
749         action = filteringaction_new(action_type, 0, NULL, 0);
750 }
751 | MATCHER_MARK_AS_READ
752 {
753         gint action_type = 0;
754
755         action_type = MATCHACTION_MARK_AS_READ;
756         action = filteringaction_new(action_type, 0, NULL, 0);
757 }
758 | MATCHER_MARK_AS_UNREAD
759 {
760         gint action_type = 0;
761
762         action_type = MATCHACTION_MARK_AS_UNREAD;
763         action = filteringaction_new(action_type, 0, NULL, 0);
764 }
765 | MATCHER_FORWARD MATCHER_INTEGER MATCHER_STRING
766 {
767         gchar * destination = NULL;
768         gint action_type = 0;
769         gint account_id = 0;
770
771         action_type = MATCHACTION_FORWARD;
772         account_id = atoi($2);
773         destination = $3;
774         action = filteringaction_new(action_type, account_id, destination, 0);
775 }
776 | MATCHER_FORWARD_AS_ATTACHMENT MATCHER_INTEGER MATCHER_STRING
777 {
778         gchar * destination = NULL;
779         gint action_type = 0;
780         gint account_id = 0;
781
782         action_type = MATCHACTION_FORWARD_AS_ATTACHMENT;
783         account_id = atoi($2);
784         destination = $3;
785         action = filteringaction_new(action_type, account_id, destination, 0);
786 }
787 | MATCHER_BOUNCE MATCHER_INTEGER MATCHER_STRING
788 {
789         gchar * destination = NULL;
790         gint action_type = 0;
791         gint account_id = 0;
792
793         action_type = MATCHACTION_BOUNCE;
794         account_id = atoi($2);
795         destination = $3;
796         action = filteringaction_new(action_type, account_id, destination, 0);
797 }
798 | MATCHER_COLOR MATCHER_INTEGER
799 {
800         gint action_type = 0;
801         gint color = 0;
802
803         action_type = MATCHACTION_COLOR;
804         color = atoi($2);
805         action = filteringaction_new(action_type, 0, NULL, color);
806 }
807 | MATCHER_DELETE_ON_SERVER
808 {
809         gint action_type = 0;
810         action_type = MATCHACTION_DELETE_ON_SERVER;
811         action = filteringaction_new(action_type, 0, NULL, 0);
812 }
813 ;
814
815 scoring_rule:
816 MATCHER_SCORE MATCHER_INTEGER
817 {
818         score = atoi($2);
819 }
820 ;