source: filter.c @ f661cee

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