]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cfgcond: support terms made of parenthesis around expressions
authorWilly Tarreau <w@1wt.eu>
Fri, 16 Jul 2021 12:56:59 +0000 (14:56 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 16 Jul 2021 17:18:41 +0000 (19:18 +0200)
Now it's possible to form a term using parenthesis around an expression.
This will soon allow to build more complex expressions. For now they're
still pretty limited but parenthesis do work.

doc/configuration.txt
include/haproxy/cfgcond-t.h
src/cfgcond.c

index a66350fd11d15a1d65ee18e662502196398d07bc..1b42a3c39b643d312ce3d8b4252626d3203c5db0 100644 (file)
@@ -811,6 +811,7 @@ expression made of any combination of:
   - the integer zero ('0'), always returns "false"
   - a non-nul integer (e.g. '1'), always returns "true".
   - a predicate optionally followed by argument(s) in parenthesis.
+  - a condition placed between a pair of parenthesis '(' and ')'
   - a question mark ('!') preceeding any of the non-empty elements above, and
     which will negate its status.
   - expressions combined with a logical AND ('&&'), which will be evaluated
@@ -861,7 +862,7 @@ Example:
      .endif
    .endif
 
-   .if streq("$WITH_SSL",yes) && feature(OPENSSL)
+   .if feature(OPENSSL) && (streq("$WITH_SSL",yes) || streq("$SSL_ONLY",yes))
           bind :443 ssl crt ...
    .endif
 
index f4f2796f07d87268597f7cec80f06f1d927d0d76..bb196123457fa8a19389e376080bce6f40fc12cf 100644 (file)
@@ -58,6 +58,7 @@ enum cfg_cond_term_type {
        CCTT_FALSE,
        CCTT_TRUE,
        CCTT_PRED,
+       CCTT_PAREN, // '(' EXPR ')'
 };
 
 /* keyword for a condition predicate */
@@ -74,6 +75,7 @@ struct cfg_cond_term {
        int neg;                      // 0: direct result; 1: negate
        union {
                const struct cond_pred_kw *pred; // predicate (function)
+               struct cfg_cond_expr *expr;      // expression for CCTT_PAREN
        };
 };
 
index a96832ff2f0e98e7b303e0ba1d91ac77f51eeb53..fd03196a7c853536298d91966952ea34dd24c9af 100644 (file)
@@ -51,6 +51,9 @@ void cfg_free_cond_term(struct cfg_cond_term **term)
        if (!term || !*term)
                return;
 
+       if ((*term)->type == CCTT_PAREN)
+               cfg_free_cond_expr(&(*term)->expr);
+
        free_args((*term)->args);
        free((*term)->args);
        ha_free(term);
@@ -104,6 +107,32 @@ int cfg_parse_cond_term(const char **text, struct cfg_cond_term **term, char **e
                return 1;
        }
 
+       /* Try to parse '(' EXPR ')' */
+       if (*in == '(') {
+               int ret;
+
+               t->type = CCTT_PAREN;
+               t->args = NULL;
+
+               do { in++; } while (*in == ' ' || *in == '\t');
+               ret = cfg_parse_cond_expr(&in, &t->expr, err, errptr);
+               if (ret == -1)
+                       goto fail2;
+               if (ret == 0)
+                       goto fail0;
+
+               /* find the closing ')' */
+               while (*in == ' ' || *in == '\t')
+                       in++;
+               if (*in != ')') {
+                       memprintf(err, "expected ')' after conditional expression '%s'", *text);
+                       goto fail1;
+               }
+               do { in++; } while (*in == ' ' || *in == '\t');
+               *text = in;
+               return 1;
+       }
+
        /* below we'll likely all make_arg_list() so we must return only via
         * the <done> label which frees the arg list.
         */
@@ -123,6 +152,7 @@ int cfg_parse_cond_term(const char **text, struct cfg_cond_term **term, char **e
                return 1;
        }
 
+ fail0:
        memprintf(err, "unparsable conditional expression '%s'", *text);
  fail1:
        if (errptr)
@@ -196,6 +226,9 @@ int cfg_eval_cond_term(const struct cfg_cond_term *term, char **err)
                        break;
                }
        }
+       else if (term->type == CCTT_PAREN) {
+               ret = cfg_eval_cond_expr(term->expr, err);
+       }
        else {
                memprintf(err, "internal error: unhandled condition term type %d", (int)term->type);
        }