]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cfgcond: support negating conditional expressions
authorWilly Tarreau <w@1wt.eu>
Fri, 16 Jul 2021 11:56:54 +0000 (13:56 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 16 Jul 2021 17:18:41 +0000 (19:18 +0200)
Now preceeding a config condition term with "!" will simply negate it.
Example:

   .if !feature(OPENSSL)
       .alert "SSL support is mandatory"
   .endif

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

index b128718cddac84291148038f706668af6609f14a..ccb77a511f2ad8e3746a3041d646dfe2dbbbf2b6 100644 (file)
@@ -811,6 +811,8 @@ The conditions are currently limited to:
   - 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 question mark ('!') preceeding any of the non-empty elements above, and
+    which will negate its status.
 
 The list of currently supported predicates is the following:
 
@@ -856,6 +858,10 @@ Example:
        profiling.memory on
    .endif
 
+   .if !feature(OPENSSL)
+       .alert "SSL support is mandatory"
+   .endif
+
 Four other directives are provided to report some status:
 
   - .diag "message"    : emit this message only when in diagnostic mode (-dD)
index ee9fbbede8cb89652d94e43c361732566cb380f3..b154cb2582b14b9fa85c6a2fce20571059a91a0c 100644 (file)
@@ -71,6 +71,7 @@ struct cond_pred_kw {
 struct cfg_cond_term {
        enum cfg_cond_term_type type; // CCTT_*
        struct arg *args;             // arguments for predicates
+       int neg;                      // 0: direct result; 1: negate
        union {
                const struct cond_pred_kw *pred; // predicate (function)
        };
index ac83b30baa1347fb664d3848287241b4797e0917..2dffe7b415a61ec9305716d4e33a6b21ddd8616d 100644 (file)
@@ -65,6 +65,7 @@ int cfg_parse_cond_term(const char **text, struct cfg_cond_term *term, char **er
 
        term->type = CCTT_NONE;
        term->args = NULL;
+       term->neg  = 0;
 
        while (*in == ' ' || *in == '\t')
                in++;
@@ -72,6 +73,12 @@ int cfg_parse_cond_term(const char **text, struct cfg_cond_term *term, char **er
        if (!*in) /* empty term does not parse */
                return 0;
 
+       /* !<term> negates the term. White spaces permitted */
+       while (*in == '!') {
+               term->neg = !term->neg;
+               do { in++; } while (*in == ' ' || *in == '\t');
+       }
+
        val = strtol(in, &end, 0);
        if (end != in) {
                term->type = val ? CCTT_TRUE : CCTT_FALSE;
@@ -173,6 +180,9 @@ int cfg_eval_cond_term(const struct cfg_cond_term *term, char **err)
        else {
                memprintf(err, "internal error: unhandled condition term type %d", (int)term->type);
        }
+
+       if (ret >= 0 && term->neg)
+               ret = !ret;
        return ret;
 }