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