]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: sample: pass an empty list instead of a null for fetch args
authorWilly Tarreau <w@1wt.eu>
Fri, 19 Oct 2012 17:49:09 +0000 (19:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 19 Oct 2012 17:49:09 +0000 (19:49 +0200)
ACL and sample fetches use args list and it is really not convenient to
check for null args everywhere. Now for empty args we pass a constant
list of end of lists. It will allow us to remove many useless checks.

include/proto/arg.h
src/acl.c
src/arg.c
src/haproxy.c
src/sample.c

index 68eb379db9fba3da974a4f392171e19411ec78b9..8e0a81b075f50fbba33db1c79072ca10c78d12c7 100644 (file)
 #define ARG7(m, t1, t2, t3, t4, t5, t6, t7) \
        (ARG6(m, t1, t2, t3, t4, t5, t6) + (ARGT_##t7 << 28))
 
+/* This dummy arg list may be used by default when no arg is found, it helps
+ * parsers by removing pointer checks.
+ */
+extern struct arg empty_arg_list[8];
+
 int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
                  char **err_msg, const char **err_ptr, int *err_arg);
 
index ba7c1f0ea1a0f8b8262e6664a5f6600602c9e68b..f220394d9606492e76c852c986a66aa5abd5af9c 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -1224,7 +1224,8 @@ static struct acl_expr *prune_acl_expr(struct acl_expr *expr)
                arg++;
        }
 
-       free(expr->args);
+       if (expr->args != empty_arg_list)
+               free(expr->args);
        expr->kw->use_cnt--;
        return expr;
 }
@@ -1352,6 +1353,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
        aclkw->use_cnt++;
        LIST_INIT(&expr->patterns);
        expr->pattern_tree = EB_ROOT_UNIQUE;
+       expr->args = empty_arg_list;
 
        arg = strchr(args[0], '(');
        if (aclkw->arg_mask) {
@@ -1380,6 +1382,9 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
                                goto out_free_expr;
                        }
 
+                       if (!expr->args)
+                               expr->args = empty_arg_list;
+
                        if (aclkw->val_args && !aclkw->val_args(expr->args, err)) {
                                /* invalid keyword argument, error must have been
                                 * set by val_args().
@@ -2030,10 +2035,8 @@ acl_find_targets(struct proxy *p)
 
        list_for_each_entry(acl, &p->acl, list) {
                list_for_each_entry(expr, &acl->expr, list) {
-                       for (arg = expr->args; arg; arg++) {
-                               if (arg->type == ARGT_STOP)
-                                       break;
-                               else if (!arg->unresolved)
+                       for (arg = expr->args; arg && arg->type != ARGT_STOP; arg++) {
+                               if (!arg->unresolved)
                                        continue;
                                else if (arg->type == ARGT_SRV) {
                                        struct proxy *px;
index 187540d53ed181945a27455e3eadb2a5ad0554c1..f113ba3033a58fdeaa48f9aded7bd1a822037a8c 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -36,6 +36,11 @@ static const char *arg_type_names[ARGT_NBTYPES] = {
        /* Unassigned types must never happen. Better crash during parsing if they do. */
 };
 
+/* This dummy arg list may be used by default when no arg is found, it helps
+ * parsers by removing pointer checks.
+ */
+struct arg empty_arg_list[8] = { };
+
 /* This function builds an argument list from a config line. It returns the
  * number of arguments found, or <0 in case of any error. Everything needed
  * it automatically allocated. A pointer to an error message might be returned
index 6c80f6b10c4918d1a11a73e6e24964f045cecf5c..f296f716f40bdc72db3b690a124db27141e77424 100644 (file)
@@ -73,6 +73,7 @@
 
 #include <proto/auth.h>
 #include <proto/acl.h>
+#include <proto/arg.h>
 #include <proto/backend.h>
 #include <proto/channel.h>
 #include <proto/checks.h>
@@ -818,7 +819,8 @@ static void deinit_sample_arg(struct arg *p)
                p++;
        }
 
-       free(p_back);
+       if (p_back != empty_arg_list)
+               free(p_back);
 }
 
 static void deinit_stick_rules(struct list *rules)
index 3e0c96501a8847674adaefe59677d2ebbe44ac1c..3eef4c3342833c72a6c925b8b5a37669075cdcce 100644 (file)
@@ -320,6 +320,7 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, char *err, int err_s
 
        LIST_INIT(&(expr->conv_exprs));
        expr->fetch = fetch;
+       expr->arg_p = empty_arg_list;
 
        if (end != endw) {
                char *err_msg = NULL;
@@ -344,6 +345,9 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, char *err, int err_s
                        goto out_error;
                }
 
+               if (!expr->arg_p)
+                       expr->arg_p = empty_arg_list;
+
                if (fetch->val_args && !fetch->val_args(expr->arg_p, &err_msg)) {
                        p = my_strndup(str[*idx], endw - str[*idx]);
                        if (p) {
@@ -436,6 +440,9 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, char *err, int err_s
                                goto out_error;
                        }
 
+                       if (!conv_expr->arg_p)
+                               conv_expr->arg_p = empty_arg_list;
+
                        if (conv->val_args && !conv->val_args(conv_expr->arg_p, &err_msg)) {
                                p = my_strndup(str[*idx], endw - str[*idx]);
                                if (p) {