]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: acl: cleanup some of the redundancy and spaghetti after last fix
authorWilly Tarreau <w@1wt.eu>
Fri, 29 Aug 2014 17:09:48 +0000 (19:09 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 29 Aug 2014 17:13:32 +0000 (19:13 +0200)
This code aims at clearing up the ACL parsing code a bit to make it
more obvious what happens in the case of an ACL keyword and what happens
in the case of a sample expression. Variables prev_type and cur_type were
merged, and ACL keyword processing functions are checked only once.

This patch could be backported into 1.5 after the previous patch, in order
to keep the code more maintainable.

src/acl.c

index 3e04874f2a7d9b8d7b114eb57f6e48c979e6af87..8f3fd9eaa7468be4c9291f949064c58c1dc6d6d9 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -145,7 +145,6 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
        const char *begw;
        const char *endw;
        const char *endt;
-       unsigned long prev_type;
        int cur_type;
        int nbargs;
        int operator = STD_OP_EQ;
@@ -231,11 +230,9 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
                /* look for the begining of the converters list. Those directly attached
                 * to the ACL keyword are found just after <arg> which points to the comma.
                 * If we find any converter, then we don't use the ACL keyword's match
-                * anymore but the one related to the converter's output type, so we'll
-                * kill the ACL kw to avoid any future reference to it (since in fact we'll
-                * only be using it as a sample fetch function).
+                * anymore but the one related to the converter's output type.
                 */
-               prev_type = smp->fetch->out_type;
+               cur_type = smp->fetch->out_type;
                while (*arg) {
                        struct sample_conv *conv;
                        struct sample_conv_expr *conv_expr;
@@ -294,13 +291,13 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
                        }
 
                        /* If impossible type conversion */
-                       if (!sample_casts[prev_type][conv->in_type]) {
+                       if (!sample_casts[cur_type][conv->in_type]) {
                                memprintf(err, "ACL keyword '%s' : conv method '%s' cannot be applied.",
                                          aclkw->kw, ckw);
                                goto out_free_smp;
                        }
 
-                       prev_type = conv->out_type;
+                       cur_type = conv->out_type;
                        conv_expr = calloc(1, sizeof(struct sample_conv_expr));
                        if (!conv_expr)
                                goto out_free_smp;
@@ -353,15 +350,9 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
                        memprintf(err, "%s in ACL expression '%s'", *err, *args);
                        goto out_return;
                }
-               prev_type = smp_expr_output_type(smp);
+               cur_type = smp_expr_output_type(smp);
        }
 
-       /* From now on, prev_type is the expression's output type.
-        * Stop relying on ACL keyword if a converter is used.
-        */
-       if (acl_conv_found)
-               aclkw = NULL;
-
        expr = (struct acl_expr *)calloc(1, sizeof(*expr));
        if (!expr) {
                memprintf(err, "out of memory when parsing ACL expression");
@@ -370,38 +361,26 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
 
        pattern_init_head(&expr->pat);
 
-       expr->kw = aclkw ? aclkw->kw : smp->fetch->kw;
-       expr->pat.parse = aclkw ? aclkw->parse : NULL;
-       expr->pat.index = aclkw ? aclkw->index : NULL;
-       expr->pat.match = aclkw ? aclkw->match : NULL;
-       expr->pat.delete = aclkw ? aclkw->delete : NULL;
-       expr->pat.prune = aclkw ? aclkw->prune : NULL;
-       expr->pat.expect_type = prev_type;
-       expr->smp = smp;
-       smp = NULL;
-
-       /* Fill NULL pointers with values provided by the pattern.c arrays */
-       if (aclkw) {
-               if (!expr->pat.parse)
-                       expr->pat.parse = pat_parse_fcts[aclkw->match_type];
-
-               if (!expr->pat.index)
-                       expr->pat.index = pat_index_fcts[aclkw->match_type];
-
-               if (!expr->pat.match)
-                       expr->pat.match = pat_match_fcts[aclkw->match_type];
-
-               if (!expr->pat.delete)
-                       expr->pat.delete = pat_delete_fcts[aclkw->match_type];
-
-               if (!expr->pat.prune)
-                       expr->pat.prune = pat_prune_fcts[aclkw->match_type];
+       expr->pat.expect_type = cur_type;
+       expr->smp             = smp;
+       expr->kw              = smp->fetch->kw;
+       smp = NULL; /* don't free it anymore */
+
+       if (aclkw && !acl_conv_found) {
+               expr->kw = aclkw->kw;
+               expr->pat.parse  = aclkw->parse  ? aclkw->parse  : pat_parse_fcts[aclkw->match_type];
+               expr->pat.index  = aclkw->index  ? aclkw->index  : pat_index_fcts[aclkw->match_type];
+               expr->pat.match  = aclkw->match  ? aclkw->match  : pat_match_fcts[aclkw->match_type];
+               expr->pat.delete = aclkw->delete ? aclkw->delete : pat_delete_fcts[aclkw->match_type];
+               expr->pat.prune  = aclkw->prune  ? aclkw->prune  : pat_prune_fcts[aclkw->match_type];
        }
 
        if (!expr->pat.parse) {
-               /* some types can be automatically converted */
-
-               switch (prev_type) {
+               /* Parse/index/match functions depend on the expression type,
+                * so we have to map them now. Some types can be automatically
+                * converted.
+                */
+               switch (cur_type) {
                case SMP_T_BOOL:
                        expr->pat.parse = pat_parse_fcts[PAT_MATCH_BOOL];
                        expr->pat.index = pat_index_fcts[PAT_MATCH_BOOL];
@@ -440,7 +419,6 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
        }
 
        /* Additional check to protect against common mistakes */
-       cur_type = smp_expr_output_type(expr->smp);
        if (expr->pat.parse && cur_type != SMP_T_BOOL && !*args[1]) {
                Warning("parsing acl keyword '%s' :\n"
                        "  no pattern to match against were provided, so this ACL will never match.\n"