static void strfilter_node__delete(struct strfilter_node *self) { if (self) { if (self->p && !is_operator(*self->p)) free((char *)self->p); strfilter_node__delete(self->l); strfilter_node__delete(self->r); free(self); } }
static void strfilter_node__delete(struct strfilter_node *node) { if (node) { if (node->p && !is_operator(*node->p)) zfree((char **)&node->p); strfilter_node__delete(node->l); strfilter_node__delete(node->r); free(node); } }
void strfilter__delete(struct strfilter *self) { if (self) { strfilter_node__delete(self->root); free(self); } }
void strfilter__delete(struct strfilter *filter) { if (filter) { strfilter_node__delete(filter->root); free(filter); } }
static int strfilter__append(struct strfilter *filter, bool _or, const char *rules, const char **err) { struct strfilter_node *right, *root; const char *ep = NULL; if (!filter || !rules) return -EINVAL; right = strfilter_node__new(rules, &ep); if (!right || *ep != '\0') { if (err) *err = ep; goto error; } root = strfilter_node__alloc(_or ? OP_or : OP_and, filter->root, right); if (!root) { ep = NULL; goto error; } filter->root = root; return 0; error: strfilter_node__delete(right); return ep ? -EINVAL : -ENOMEM; }
static struct strfilter_node *strfilter_node__new(const char *s, const char **ep) { struct strfilter_node root, *cur, *last_op; const char *e; if (!s) return NULL; memset(&root, 0, sizeof(root)); last_op = cur = &root; s = get_token(s, &e); while (*s != '\0' && *s != ')') { switch (*s) { case '&': /* */ if (!cur->r || !last_op->r) goto error; cur = strfilter_node__alloc(OP_and, last_op->r, NULL); if (!cur) goto nomem; last_op->r = cur; last_op = cur; break; case '|': /* */ if (!cur->r || !root.r) goto error; cur = strfilter_node__alloc(OP_or, root.r, NULL); if (!cur) goto nomem; root.r = cur; last_op = cur; break; case '!': /* */ if (cur->r) goto error; cur->r = strfilter_node__alloc(OP_not, NULL, NULL); if (!cur->r) goto nomem; cur = cur->r; break; case '(': /* */ if (cur->r) goto error; cur->r = strfilter_node__new(s + 1, &s); if (!s) goto nomem; if (!cur->r || *s != ')') goto error; e = s + 1; break; default: if (cur->r) goto error; cur->r = strfilter_node__alloc(NULL, NULL, NULL); if (!cur->r) goto nomem; cur->r->p = strndup(s, e - s); if (!cur->r->p) goto nomem; } s = get_token(e, &e); } if (!cur->r) goto error; *ep = s; return root.r; nomem: s = NULL; error: *ep = s; strfilter_node__delete(root.r); return NULL; }