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