source: filter.c @ 1b9d3cc

release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 1b9d3cc was 23fddad, checked in by Karl Ramm <kcr@1ts.org>, 13 years ago
refactor & rename filter creation & storage management filter_init_fromstring -> filter_new_fromstring filter_init -> filter_new filter_free -> filter_delete Every time owl_filter_init and owl_filter_init_fromstring were called, there was a call to malloc right above them; Conversely, after every owl_filter_free there needed to be a call to owl_free (and sometimes there wasn't).
  • Property mode set to 100644
File size: 5.9 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
[8fa9562]166void owl_filter_set_fgcolor(owl_filter *f, int color)
[e187445]167{
[8fa9562]168  f->fgcolor=color;
[7d4fbcd]169}
170
[4542047]171int owl_filter_get_fgcolor(const owl_filter *f)
[e187445]172{
[8fa9562]173  return(f->fgcolor);
174}
175
176void owl_filter_set_bgcolor(owl_filter *f, int color)
177{
178  f->bgcolor=color;
179}
180
[4542047]181int owl_filter_get_bgcolor(const owl_filter *f)
[8fa9562]182{
183  return(f->bgcolor);
[7d4fbcd]184}
185
[e187445]186void owl_filter_set_cachedmsgid(owl_filter *f, int cachedmsgid)
187{
[59cf91c]188  f->cachedmsgid=cachedmsgid;
189}
190
[4542047]191int owl_filter_get_cachedmsgid(const owl_filter *f)
[e187445]192{
[59cf91c]193  return(f->cachedmsgid);
194}
195
[15b34fd]196/* return 1 if the message matches the given filter, otherwise
197 * return 0.
198 */
[4542047]199int owl_filter_message_match(const owl_filter *f, const owl_message *m)
[e187445]200{
[ad15610]201  int ret;
[cb769bb]202  if(!f->root) return 0;
[ad15610]203  ret = owl_filterelement_match(f->root, m);
[cb769bb]204  return ret;
[7d4fbcd]205}
206
207
[4542047]208char* owl_filter_print(const owl_filter *f)
[e187445]209{
[cdc6ff1]210  GString *out = g_string_new("");
[446aa2b]211
[8fa9562]212  if (f->fgcolor!=OWL_COLOR_DEFAULT) {
[0504f63]213    g_string_append(out, "-c ");
[c2c5c77]214    if (f->fgcolor < 8) {
[0504f63]215      g_string_append(out, owl_util_color_to_string(f->fgcolor));
[c2c5c77]216    }
217    else {
[0504f63]218      g_string_append_printf(out, "%i",f->fgcolor);
[c2c5c77]219    }
[0504f63]220    g_string_append(out, " ");
[8fa9562]221  }
222  if (f->bgcolor!=OWL_COLOR_DEFAULT) {
[0504f63]223    g_string_append(out, "-b ");
[c2c5c77]224    if (f->bgcolor < 8) {
[0504f63]225      g_string_append(out, owl_util_color_to_string(f->bgcolor));
[c2c5c77]226    }
227    else {
[0504f63]228      g_string_append_printf(out, "%i",f->fgcolor);
[c2c5c77]229    }
[0504f63]230    g_string_append(out, " ");
231  }
232  if(f->root) {
233    owl_filterelement_print(f->root, out);
234    g_string_append(out, "\n");
[446aa2b]235  }
[0504f63]236
237  return g_string_free(out, 0);
[7d4fbcd]238}
239
[40458b9]240/* Return 1 if the filters 'a' and 'b' are equivalent, 0 otherwise */
[4542047]241int owl_filter_equiv(const owl_filter *a, const owl_filter *b)
[e187445]242{
[0504f63]243  char *buffa, *buffb;
244  int ret;
[7d4fbcd]245
[0504f63]246  buffa = owl_filter_print(a);
247  buffb = owl_filter_print(b);
[7d4fbcd]248
[0504f63]249  ret = !strcmp(buffa, buffb);
[cdc6ff1]250  ret = ret && !strcmp(owl_filter_get_name(a),
251                       owl_filter_get_name(b));
[0504f63]252
253  owl_free(buffa);
254  owl_free(buffb);
255
256  return ret;
[7d4fbcd]257}
258
[cb769bb]259
[4542047]260int owl_filter_is_toodeep(const owl_filter *f)
[40458b9]261{
[cb769bb]262  return owl_filterelement_is_toodeep(f, f->root);
[40458b9]263}
264
[23fddad]265void owl_filter_delete(owl_filter *f)
[40458b9]266{
[23fddad]267  if (f == NULL)
268    return;
269  if (f->root) {
[cb769bb]270    owl_filterelement_free(f->root);
271    owl_free(f->root);
[40458b9]272  }
[23fddad]273  if (f->name)
274    owl_free(f->name);
275  owl_free(f);
[cb769bb]276}
Note: See TracBrowser for help on using the repository browser.