static void owl_global_delete_filter_ent(void *data) { owl_global_filter_ent *e = data; e->g->filterlist = g_list_remove(e->g->filterlist, e->f); owl_filter_delete(e->f); g_free(e); }
owl_filter *owl_filter_new(const char *name, int argc, const char *const *argv) { owl_filter *f; f = g_new(owl_filter, 1); f->name=g_strdup(name); f->fgcolor=OWL_COLOR_DEFAULT; f->bgcolor=OWL_COLOR_DEFAULT; /* first take arguments that have to come first */ /* set the color */ while ( argc>=2 && ( !strcmp(argv[0], "-c") || !strcmp(argv[0], "-b") ) ) { if (owl_util_string_to_color(argv[1])==OWL_COLOR_INVALID) { owl_function_error("The color '%s' is not available, using default.", argv[1]); } else { switch (argv[0][1]) { case 'c': f->fgcolor=owl_util_string_to_color(argv[1]); break; case 'b': f->bgcolor=owl_util_string_to_color(argv[1]); break; } } argc-=2; argv+=2; } if (!(f->root = owl_filter_parse_expression(argc, argv, NULL))) { owl_filter_delete(f); return NULL; } /* Now check for recursion. */ if (owl_filter_is_toodeep(f)) { owl_function_error("Filter loop!"); owl_filter_delete(f); return NULL; } return f; }
static int owl_filter_test_string(const char *filt, const owl_message *m, int shouldmatch) { owl_filter *f; int ok; int failed = 0; if ((f = owl_filter_new_fromstring("test-filter", filt)) == NULL) { printf("not ok can't parse %s\n", filt); failed = 1; goto out; } ok = owl_filter_message_match(f, m); if((shouldmatch && !ok) || (!shouldmatch && ok)) { printf("not ok match %s (got %d, expected %d)\n", filt, ok, shouldmatch); failed = 1; } out: owl_filter_delete(f); if(!failed) { printf("ok %s %s\n", shouldmatch ? "matches" : "doesn't match", filt); } return failed; }
int owl_filter_regtest(void) { int numfailed=0; owl_message m; owl_filter *f1, *f2, *f3, *f4, *f5; owl_dict_create(&g.filters); g.filterlist = NULL; owl_message_init(&m); owl_message_set_type_zephyr(&m); owl_message_set_direction_in(&m); owl_message_set_class(&m, "owl"); owl_message_set_instance(&m, "tester"); owl_message_set_sender(&m, "owl-user"); owl_message_set_recipient(&m, "joe"); owl_message_set_attribute(&m, "foo", "bar"); #define TEST_FILTER(f, e) do { \ numtests++; \ numfailed += owl_filter_test_string(f, &m, e); \ } while(0) TEST_FILTER("true", 1); TEST_FILTER("false", 0); TEST_FILTER("( true )", 1); TEST_FILTER("not false", 1); TEST_FILTER("( true ) or ( false )", 1); TEST_FILTER("true and false", 0); TEST_FILTER("( true or true ) or ( ( false ) )", 1); TEST_FILTER("class owl", 1); TEST_FILTER("class ^owl$", 1); TEST_FILTER("instance test", 1); TEST_FILTER("instance ^test$", 0); TEST_FILTER("instance ^tester$", 1); TEST_FILTER("foo bar", 1); TEST_FILTER("class owl and instance tester", 1); TEST_FILTER("type ^zephyr$ and direction ^in$ and ( class ^owl$ or instance ^owl$ )", 1); /* Order of operations and precedence */ TEST_FILTER("not true or false", 0); TEST_FILTER("true or true and false", 0); TEST_FILTER("true and true and false or true", 1); TEST_FILTER("false and false or true", 1); TEST_FILTER("true and false or false", 0); f1 = owl_filter_new_fromstring("f1", "class owl"); owl_global_add_filter(&g, f1); TEST_FILTER("filter f1", 1); owl_global_remove_filter(&g, "f1"); /* Test recursion prevention */ FAIL_UNLESS("self reference", (f2 = owl_filter_new_fromstring("test", "filter test")) == NULL); owl_filter_delete(f2); /* mutual recursion */ f3 = owl_filter_new_fromstring("f3", "filter f4"); owl_global_add_filter(&g, f3); FAIL_UNLESS("mutual recursion", (f4 = owl_filter_new_fromstring("f4", "filter f3")) == NULL); owl_global_remove_filter(&g, "f3"); owl_filter_delete(f4); /* support referencing a filter several times */ FAIL_UNLESS("DAG", (f5 = owl_filter_new_fromstring("dag", "filter f1 or filter f1")) != NULL); owl_filter_delete(f5); return 0; }