source: filter.c @ 3cc4bfc

release-1.10release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 3cc4bfc was 3cc4bfc, checked in by David Benjamin <davidben@mit.edu>, 14 years ago
Add owl_filter_to_sv for exporting filters Currently just returns the name. Signed-off-by: David Benjamin <davidben@mit.edu>
  • Property mode set to 100644
File size: 6.0 KB
RevLine 
[7d4fbcd]1#include <string.h>
2#include "owl.h"
3
[23fddad]4owl_filter *owl_filter_new_fromstring(const char *name, const char *string)
[e187445]5{
[23fddad]6  owl_filter *f;
[7d4fbcd]7  char **argv;
[23fddad]8  int argc;
[7d4fbcd]9
[23fddad]10  argv = owl_parseline(string, &argc);
11  f = owl_filter_new(name, argc, strs(argv));
[1716fed]12  owl_parsefree(argv, argc);
[23fddad]13
14  return f;
[7d4fbcd]15}
16
[23fddad]17owl_filter *owl_filter_new(const char *name, int argc, const char *const *argv)
[e187445]18{
[23fddad]19  owl_filter *f;
20
21  f = owl_malloc(sizeof(owl_filter));
22
[7d4fbcd]23  f->name=owl_strdup(name);
[8fa9562]24  f->fgcolor=OWL_COLOR_DEFAULT;
25  f->bgcolor=OWL_COLOR_DEFAULT;
[59cf91c]26  f->cachedmsgid=-1;
[cb769bb]27
[7d4fbcd]28  /* first take arguments that have to come first */
29  /* set the color */
[8fa9562]30  while ( argc>=2 && ( !strcmp(argv[0], "-c") ||
31                       !strcmp(argv[0], "-b") ) ) {
[601733d]32    if (owl_util_string_to_color(argv[1])==OWL_COLOR_INVALID) {
[12c35df]33      owl_function_error("The color '%s' is not available, using default.", argv[1]);
34    } else {
[8fa9562]35      switch (argv[0][1]) {
36      case 'c':
37        f->fgcolor=owl_util_string_to_color(argv[1]);
38        break;
39      case 'b':
40        f->bgcolor=owl_util_string_to_color(argv[1]);
41        break;
42      }
[12c35df]43    }
[7d4fbcd]44    argc-=2;
45    argv+=2;
46  }
47
[23fddad]48  if (!(f->root = owl_filter_parse_expression(argc, argv, NULL))) {
49    owl_filter_delete(f);
50    return NULL;
51  }
[7d4fbcd]52
[cb769bb]53  /* Now check for recursion. */
[40458b9]54  if (owl_filter_is_toodeep(f)) {
[9711a6e]55    owl_function_error("Filter loop!");
[23fddad]56    owl_filter_delete(f);
57    return NULL;
[7d4fbcd]58  }
[cb769bb]59
[23fddad]60  return f;
[7d4fbcd]61}
62
[cb769bb]63
64/* A primitive expression is one without any toplevel ``and'' or ``or''s*/
65
[e19eb97]66static owl_filterelement * owl_filter_parse_primitive_expression(int argc, const char *const *argv, int *next)
[cb769bb]67{
[ad15610]68  owl_filterelement *fe, *op;
69  int i = 0, skip;
[cb769bb]70
[ad15610]71  if(!argc) return NULL;
[cb769bb]72
[ad15610]73  fe = owl_malloc(sizeof(owl_filterelement));
[cb769bb]74  owl_filterelement_create(fe);
75
76  if(!strcasecmp(argv[i], "(")) {
77    i++;
78    op = owl_filter_parse_expression(argc-i, argv+i, &skip);
79    if(!op) goto err;
80    i += skip;
[d791cdb]81    if(i >= argc) goto err;
[cb769bb]82    if(strcasecmp(argv[i++], ")")) goto err;
83    owl_filterelement_create_group(fe, op);
84  } else if(!strcasecmp(argv[i], "not")) {
85    i++;
86    op = owl_filter_parse_primitive_expression(argc-i, argv+i, &skip);
87    if(!op) goto err;
88    i += skip;
89    owl_filterelement_create_not(fe, op);
90  } else if(!strcasecmp(argv[i], "true")) {
91    i++;
92    owl_filterelement_create_true(fe);
93  } else if(!strcasecmp(argv[i], "false")) {
94    i++;
95    owl_filterelement_create_false(fe);
96  } else {
97    if(argc == 1) goto err;
98    if(!strcasecmp(*argv, "filter")) {
99      owl_filterelement_create_filter(fe, *(argv+1));
100    } else if(!strcasecmp(*argv, "perl")) {
101      owl_filterelement_create_perl(fe, *(argv+1));
102    } else {
[e6a4dd5]103      if(owl_filterelement_create_re(fe, *argv, *(argv+1))) {
104        goto err;
105      }
[cb769bb]106    }
107    i += 2;
108  }
109
110  if(next) {
111    *next = i;
112  } else if(i != argc) {
113    goto err;
114  }
115  return fe;
116err:
117  owl_filterelement_free(fe);
118  owl_free(fe);
119  return NULL;
120}
121
[e19eb97]122owl_filterelement * owl_filter_parse_expression(int argc, const char *const *argv, int *next)
[cb769bb]123{
124  int i = 0, skip;
[ad15610]125  owl_filterelement * op1 = NULL, * op2 = NULL, *tmp;
[cb769bb]126
127  op1 = owl_filter_parse_primitive_expression(argc-i, argv+i, &skip);
128  i += skip;
129  if(!op1) goto err;
130
131  while(i < argc) {
132    if(strcasecmp(argv[i], "and") &&
133       strcasecmp(argv[i], "or")) break;
134    op2 = owl_filter_parse_primitive_expression(argc-i-1, argv+i+1, &skip);
135    if(!op2) goto err;
[ad15610]136    tmp = owl_malloc(sizeof(owl_filterelement));
[cb769bb]137    if(!strcasecmp(argv[i], "and")) {
138      owl_filterelement_create_and(tmp, op1, op2);
139    } else {
140      owl_filterelement_create_or(tmp, op1, op2);
141    }
142    op1 = tmp;
143    op2 = NULL;
144    i += skip+1;
145  }
146
147  if(next) {
148    *next = i;
149  } else if(i != argc) {
150    goto err;
151  }
152  return op1;
153err:
154  if(op1) {
155    owl_filterelement_free(op1);
156    owl_free(op1);
157  }
158  return NULL;
159}
160
[4542047]161const char *owl_filter_get_name(const owl_filter *f)
[e187445]162{
[7d4fbcd]163  return(f->name);
164}
165
[3cc4bfc]166SV *owl_filter_to_sv(const owl_filter *f)
167{
168  return owl_new_sv(owl_filter_get_name(f));
169}
170
[8fa9562]171void owl_filter_set_fgcolor(owl_filter *f, int color)
[e187445]172{
[8fa9562]173  f->fgcolor=color;
[7d4fbcd]174}
175
[4542047]176int owl_filter_get_fgcolor(const owl_filter *f)
[e187445]177{
[8fa9562]178  return(f->fgcolor);
179}
180
181void owl_filter_set_bgcolor(owl_filter *f, int color)
182{
183  f->bgcolor=color;
184}
185
[4542047]186int owl_filter_get_bgcolor(const owl_filter *f)
[8fa9562]187{
188  return(f->bgcolor);
[7d4fbcd]189}
190
[e187445]191void owl_filter_set_cachedmsgid(owl_filter *f, int cachedmsgid)
192{
[59cf91c]193  f->cachedmsgid=cachedmsgid;
194}
195
[4542047]196int owl_filter_get_cachedmsgid(const owl_filter *f)
[e187445]197{
[59cf91c]198  return(f->cachedmsgid);
199}
200
[15b34fd]201/* return 1 if the message matches the given filter, otherwise
202 * return 0.
203 */
[4542047]204int owl_filter_message_match(const owl_filter *f, const owl_message *m)
[e187445]205{
[ad15610]206  int ret;
[cb769bb]207  if(!f->root) return 0;
[ad15610]208  ret = owl_filterelement_match(f->root, m);
[cb769bb]209  return ret;
[7d4fbcd]210}
211
212
[4542047]213char* owl_filter_print(const owl_filter *f)
[e187445]214{
[cdc6ff1]215  GString *out = g_string_new("");
[446aa2b]216
[8fa9562]217  if (f->fgcolor!=OWL_COLOR_DEFAULT) {
[0504f63]218    g_string_append(out, "-c ");
[c2c5c77]219    if (f->fgcolor < 8) {
[0504f63]220      g_string_append(out, owl_util_color_to_string(f->fgcolor));
[c2c5c77]221    }
222    else {
[0504f63]223      g_string_append_printf(out, "%i",f->fgcolor);
[c2c5c77]224    }
[0504f63]225    g_string_append(out, " ");
[8fa9562]226  }
227  if (f->bgcolor!=OWL_COLOR_DEFAULT) {
[0504f63]228    g_string_append(out, "-b ");
[c2c5c77]229    if (f->bgcolor < 8) {
[0504f63]230      g_string_append(out, owl_util_color_to_string(f->bgcolor));
[c2c5c77]231    }
232    else {
[0504f63]233      g_string_append_printf(out, "%i",f->fgcolor);
[c2c5c77]234    }
[0504f63]235    g_string_append(out, " ");
236  }
237  if(f->root) {
238    owl_filterelement_print(f->root, out);
239    g_string_append(out, "\n");
[446aa2b]240  }
[0504f63]241
242  return g_string_free(out, 0);
[7d4fbcd]243}
244
[40458b9]245/* Return 1 if the filters 'a' and 'b' are equivalent, 0 otherwise */
[4542047]246int owl_filter_equiv(const owl_filter *a, const owl_filter *b)
[e187445]247{
[0504f63]248  char *buffa, *buffb;
249  int ret;
[7d4fbcd]250
[0504f63]251  buffa = owl_filter_print(a);
252  buffb = owl_filter_print(b);
[7d4fbcd]253
[0504f63]254  ret = !strcmp(buffa, buffb);
[cdc6ff1]255  ret = ret && !strcmp(owl_filter_get_name(a),
256                       owl_filter_get_name(b));
[0504f63]257
258  owl_free(buffa);
259  owl_free(buffb);
260
261  return ret;
[7d4fbcd]262}
263
[cb769bb]264
[4542047]265int owl_filter_is_toodeep(const owl_filter *f)
[40458b9]266{
[cb769bb]267  return owl_filterelement_is_toodeep(f, f->root);
[40458b9]268}
269
[23fddad]270void owl_filter_delete(owl_filter *f)
[40458b9]271{
[23fddad]272  if (f == NULL)
273    return;
274  if (f->root) {
[cb769bb]275    owl_filterelement_free(f->root);
276    owl_free(f->root);
[40458b9]277  }
[23fddad]278  if (f->name)
279    owl_free(f->name);
280  owl_free(f);
[cb769bb]281}
Note: See TracBrowser for help on using the repository browser.