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