int filter_rule_add(filter_t *filter, int include, const char *pattern) { filter_rule_t **rules = realloc(filter->rules, sizeof(filter_rule_t*)*(filter->rule_count+1)); if (!rules) { perror("out of memory"); return -1; } filter->rules = rules; filter_rule_t *rule = malloc(sizeof(filter_rule_t)); if (!rule) { perror("out of memory"); return -1; } rules[filter->rule_count] = rule; if (filter_rule_init(rule, include, pattern)) { fprintf(stderr, "filter_rule_init failed\n"); free(rule); return -1; } filter->rule_count++; if (_filter_match_add(filter->match, rule, 0)) { fprintf(stderr, "_filter_match_add failed\n"); filter_rule_free(rule); free(rule); return -1; } return 0; }
static void add_filter_rule(struct filter *filt, const char *expr, enum filter_rule_type type, const char *a_sym, int sym_re_p, const char *a_lib, int lib_re_p) { struct filter_rule *rule = malloc(sizeof(*rule)); struct filter_lib_matcher *matcher = malloc(sizeof(*matcher)); if (rule == NULL || matcher == NULL) { fprintf(stderr, "Rule near '%s' will be ignored: %s.\n", expr, strerror(errno)); fail: free(rule); free(matcher); return; } regex_t symbol_re; { /* Add ^ to the start of expression and $ to the end, so that * we match the whole symbol name. Let the user write the "*" * explicitly if they wish. */ char sym[strlen(a_sym) + 3]; sprintf(sym, "^%s$", a_sym); int status = (sym_re_p ? regcomp : globcomp) (&symbol_re, sym, 0); if (status != 0) { char buf[100]; regerror(status, &symbol_re, buf, sizeof buf); fprintf(stderr, "Rule near '%s' will be ignored: %s.\n", expr, buf); goto fail; } } if (compile_libname(expr, a_lib, lib_re_p, matcher) < 0) { regfree(&symbol_re); goto fail; } filter_rule_init(rule, type, matcher, symbol_re); filter_add_rule(filt, rule); }