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