MINOR: pattern: make the delete and prune functions more generic
authorWilly Tarreau <w@1wt.eu>
Mon, 2 Nov 2020 18:26:02 +0000 (19:26 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 5 Nov 2020 18:27:09 +0000 (19:27 +0100)
Now we have a single prune() function to act on an expression, and one
delete function for the lists and one for the trees. The presence of a
pointer in the lists is enough to warrant a free, and we rely on the
PAT_SF_REGFREE flag to decide whether to free using free() or regfree().

include/haproxy/pattern-t.h
include/haproxy/pattern.h
src/http_acl.c
src/pattern.c

index b5b4d0b..a4d29d5 100644 (file)
@@ -160,7 +160,7 @@ struct pattern {
                void *ptr;              /* any data */
                char *str;              /* any string  */
                struct my_regex *reg;   /* a compiled regex */
-       } ptr;                          /* indirect values, allocated */
+       } ptr;                          /* indirect values, allocated or NULL */
        int len;                        /* data length when required  */
        int sflags;                     /* flags relative to the storage method. */
        struct sample_data *data;       /* used to store a pointer to sample value associated
index 4055372..e9266f4 100644 (file)
@@ -83,11 +83,9 @@ int pat_idx_tree_pfx(struct pattern_expr *expr, struct pattern *pat, char **err)
  * never fails.
  *
  */
-void pat_del_list_val(struct pattern_expr *expr, struct pat_ref_elt *ref);
+void pat_del_list_gen(struct pattern_expr *expr, struct pat_ref_elt *ref);
 void pat_del_tree_ip(struct pattern_expr *expr, struct pat_ref_elt *ref);
-void pat_del_list_ptr(struct pattern_expr *expr, struct pat_ref_elt *ref);
 void pat_del_tree_str(struct pattern_expr *expr, struct pat_ref_elt *ref);
-void pat_del_list_reg(struct pattern_expr *expr, struct pat_ref_elt *ref);
 
 /*
  *
@@ -95,9 +93,7 @@ void pat_del_list_reg(struct pattern_expr *expr, struct pat_ref_elt *ref);
  * reset the tree and list root.
  *
  */
-void pat_prune_val(struct pattern_expr *expr);
-void pat_prune_ptr(struct pattern_expr *expr);
-void pat_prune_reg(struct pattern_expr *expr);
+void pat_prune_gen(struct pattern_expr *expr);
 
 /*
  *
index a81fb03..d4a0e46 100644 (file)
@@ -121,8 +121,8 @@ static struct acl_kw_list acl_kws = {ILH, {
         * and match method are related to the corresponding fetch methods. This
         * is very particular ACL declaration mode.
         */
-       { "http_auth_group", NULL,       PAT_MATCH_STR, NULL,  pat_idx_list_str, pat_del_list_ptr, NULL, pat_match_auth },
-       { "method",          NULL,       PAT_MATCH_STR, pat_parse_meth, pat_idx_list_str, pat_del_list_ptr, NULL, pat_match_meth },
+       { "http_auth_group", NULL,       PAT_MATCH_STR, NULL,  pat_idx_list_str, pat_del_list_gen, NULL, pat_match_auth },
+       { "method",          NULL,       PAT_MATCH_STR, pat_parse_meth, pat_idx_list_str, pat_del_list_gen, NULL, pat_match_meth },
 
        { "path",            "path",     PAT_MATCH_STR },
        { "path_beg",        "path",     PAT_MATCH_BEG },
index 5c83a5c..faf23ef 100644 (file)
@@ -80,37 +80,37 @@ int (*pat_index_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pattern *, ch
 };
 
 void (*pat_delete_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pat_ref_elt *) = {
-       [PAT_MATCH_FOUND] = pat_del_list_val,
-       [PAT_MATCH_BOOL]  = pat_del_list_val,
-       [PAT_MATCH_INT]   = pat_del_list_val,
+       [PAT_MATCH_FOUND] = pat_del_list_gen,
+       [PAT_MATCH_BOOL]  = pat_del_list_gen,
+       [PAT_MATCH_INT]   = pat_del_list_gen,
        [PAT_MATCH_IP]    = pat_del_tree_ip,
-       [PAT_MATCH_BIN]   = pat_del_list_ptr,
-       [PAT_MATCH_LEN]   = pat_del_list_val,
+       [PAT_MATCH_BIN]   = pat_del_list_gen,
+       [PAT_MATCH_LEN]   = pat_del_list_gen,
        [PAT_MATCH_STR]   = pat_del_tree_str,
        [PAT_MATCH_BEG]   = pat_del_tree_str,
-       [PAT_MATCH_SUB]   = pat_del_list_ptr,
-       [PAT_MATCH_DIR]   = pat_del_list_ptr,
-       [PAT_MATCH_DOM]   = pat_del_list_ptr,
-       [PAT_MATCH_END]   = pat_del_list_ptr,
-       [PAT_MATCH_REG]   = pat_del_list_reg,
-       [PAT_MATCH_REGM]  = pat_del_list_reg,
+       [PAT_MATCH_SUB]   = pat_del_list_gen,
+       [PAT_MATCH_DIR]   = pat_del_list_gen,
+       [PAT_MATCH_DOM]   = pat_del_list_gen,
+       [PAT_MATCH_END]   = pat_del_list_gen,
+       [PAT_MATCH_REG]   = pat_del_list_gen,
+       [PAT_MATCH_REGM]  = pat_del_list_gen,
 };
 
 void (*pat_prune_fcts[PAT_MATCH_NUM])(struct pattern_expr *) = {
-       [PAT_MATCH_FOUND] = pat_prune_val,
-       [PAT_MATCH_BOOL]  = pat_prune_val,
-       [PAT_MATCH_INT]   = pat_prune_val,
-       [PAT_MATCH_IP]    = pat_prune_val,
-       [PAT_MATCH_BIN]   = pat_prune_ptr,
-       [PAT_MATCH_LEN]   = pat_prune_val,
-       [PAT_MATCH_STR]   = pat_prune_ptr,
-       [PAT_MATCH_BEG]   = pat_prune_ptr,
-       [PAT_MATCH_SUB]   = pat_prune_ptr,
-       [PAT_MATCH_DIR]   = pat_prune_ptr,
-       [PAT_MATCH_DOM]   = pat_prune_ptr,
-       [PAT_MATCH_END]   = pat_prune_ptr,
-       [PAT_MATCH_REG]   = pat_prune_reg,
-       [PAT_MATCH_REGM]  = pat_prune_reg,
+       [PAT_MATCH_FOUND] = pat_prune_gen,
+       [PAT_MATCH_BOOL]  = pat_prune_gen,
+       [PAT_MATCH_INT]   = pat_prune_gen,
+       [PAT_MATCH_IP]    = pat_prune_gen,
+       [PAT_MATCH_BIN]   = pat_prune_gen,
+       [PAT_MATCH_LEN]   = pat_prune_gen,
+       [PAT_MATCH_STR]   = pat_prune_gen,
+       [PAT_MATCH_BEG]   = pat_prune_gen,
+       [PAT_MATCH_SUB]   = pat_prune_gen,
+       [PAT_MATCH_DIR]   = pat_prune_gen,
+       [PAT_MATCH_DOM]   = pat_prune_gen,
+       [PAT_MATCH_END]   = pat_prune_gen,
+       [PAT_MATCH_REG]   = pat_prune_gen,
+       [PAT_MATCH_REGM]  = pat_prune_gen,
 };
 
 struct pattern *(*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern_expr *, int) = {
@@ -1088,46 +1088,16 @@ void free_pattern_tree(struct eb_root *root)
        }
 }
 
-void pat_prune_val(struct pattern_expr *expr)
+void pat_prune_gen(struct pattern_expr *expr)
 {
        struct pattern_list *pat, *tmp;
 
        list_for_each_entry_safe(pat, tmp, &expr->patterns, list) {
                LIST_DEL(&pat->list);
-               free(pat->pat.data);
-               free(pat);
-       }
-
-       free_pattern_tree(&expr->pattern_tree);
-       free_pattern_tree(&expr->pattern_tree_2);
-       LIST_INIT(&expr->patterns);
-       expr->ref->revision = rdtsc();
-}
-
-void pat_prune_ptr(struct pattern_expr *expr)
-{
-       struct pattern_list *pat, *tmp;
-
-       list_for_each_entry_safe(pat, tmp, &expr->patterns, list) {
-               LIST_DEL(&pat->list);
-               free(pat->pat.ptr.ptr);
-               free(pat->pat.data);
-               free(pat);
-       }
-
-       free_pattern_tree(&expr->pattern_tree);
-       free_pattern_tree(&expr->pattern_tree_2);
-       LIST_INIT(&expr->patterns);
-       expr->ref->revision = rdtsc();
-}
-
-void pat_prune_reg(struct pattern_expr *expr)
-{
-       struct pattern_list *pat, *tmp;
-
-       list_for_each_entry_safe(pat, tmp, &expr->patterns, list) {
-               LIST_DEL(&pat->list);
-               regex_free(pat->pat.ptr.ptr);
+               if (pat->pat.sflags & PAT_SF_REGFREE)
+                       regex_free(pat->pat.ptr.ptr);
+               else
+                       free(pat->pat.ptr.ptr);
                free(pat->pat.data);
                free(pat);
        }
@@ -1418,7 +1388,7 @@ int pat_idx_tree_pfx(struct pattern_expr *expr, struct pattern *pat, char **err)
        return 1;
 }
 
-void pat_del_list_val(struct pattern_expr *expr, struct pat_ref_elt *ref)
+void pat_del_list_gen(struct pattern_expr *expr, struct pat_ref_elt *ref)
 {
        struct pattern_list *pat;
        struct pattern_list *safe;
@@ -1430,6 +1400,10 @@ void pat_del_list_val(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
                /* Delete and free entry. */
                LIST_DEL(&pat->list);
+               if (pat->pat.sflags & PAT_SF_REGFREE)
+                       regex_free(pat->pat.ptr.reg);
+               else
+                       free(pat->pat.ptr.ptr);
                free(pat->pat.data);
                free(pat);
        }
@@ -1459,7 +1433,7 @@ void pat_del_tree_ip(struct pattern_expr *expr, struct pat_ref_elt *ref)
        }
 
        /* Browse each node of the list for IPv4 addresses. */
-       pat_del_list_val(expr, ref);
+       pat_del_list_gen(expr, ref);
 
        /* browse each node of the tree for IPv6 addresses. */
        for (node = ebmb_first(&expr->pattern_tree_2), next_node = node ? ebmb_next(node) : NULL;
@@ -1480,25 +1454,6 @@ void pat_del_tree_ip(struct pattern_expr *expr, struct pat_ref_elt *ref)
        expr->ref->revision = rdtsc();
 }
 
-void pat_del_list_ptr(struct pattern_expr *expr, struct pat_ref_elt *ref)
-{
-       struct pattern_list *pat;
-       struct pattern_list *safe;
-
-       list_for_each_entry_safe(pat, safe, &expr->patterns, list) {
-               /* Check equality. */
-               if (pat->pat.ref != ref)
-                       continue;
-
-               /* Delete and free entry. */
-               LIST_DEL(&pat->list);
-               free(pat->pat.ptr.ptr);
-               free(pat->pat.data);
-               free(pat);
-       }
-       expr->ref->revision = rdtsc();
-}
-
 void pat_del_tree_str(struct pattern_expr *expr, struct pat_ref_elt *ref)
 {
        struct ebmb_node *node, *next_node;
@@ -1506,7 +1461,7 @@ void pat_del_tree_str(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
        /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
        if (expr->mflags & PAT_MF_IGNORE_CASE)
-               return pat_del_list_ptr(expr, ref);
+               return pat_del_list_gen(expr, ref);
 
        /* browse each node of the tree. */
        for (node = ebmb_first(&expr->pattern_tree), next_node = node ? ebmb_next(node) : NULL;
@@ -1527,25 +1482,6 @@ void pat_del_tree_str(struct pattern_expr *expr, struct pat_ref_elt *ref)
        expr->ref->revision = rdtsc();
 }
 
-void pat_del_list_reg(struct pattern_expr *expr, struct pat_ref_elt *ref)
-{
-       struct pattern_list *pat;
-       struct pattern_list *safe;
-
-       list_for_each_entry_safe(pat, safe, &expr->patterns, list) {
-               /* Check equality. */
-               if (pat->pat.ref != ref)
-                       continue;
-
-               /* Delete and free entry. */
-               LIST_DEL(&pat->list);
-               regex_free(pat->pat.ptr.ptr);
-               free(pat->pat.data);
-               free(pat);
-       }
-       expr->ref->revision = rdtsc();
-}
-
 void pattern_init_expr(struct pattern_expr *expr)
 {
        LIST_INIT(&expr->patterns);