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