From: Willy Tarreau Date: Fri, 16 Jul 2021 11:56:54 +0000 (+0200) Subject: MINOR: cfgcond: support negating conditional expressions X-Git-Tag: v2.5-dev2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ca56d3d28bbd69b1201eda51fcf724fd3a44f62a;p=thirdparty%2Fhaproxy.git MINOR: cfgcond: support negating conditional expressions Now preceeding a config condition term with "!" will simply negate it. Example: .if !feature(OPENSSL) .alert "SSL support is mandatory" .endif --- diff --git a/doc/configuration.txt b/doc/configuration.txt index b128718cdd..ccb77a511f 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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) diff --git a/include/haproxy/cfgcond-t.h b/include/haproxy/cfgcond-t.h index ee9fbbede8..b154cb2582 100644 --- a/include/haproxy/cfgcond-t.h +++ b/include/haproxy/cfgcond-t.h @@ -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) }; diff --git a/src/cfgcond.c b/src/cfgcond.c index ac83b30baa..2dffe7b415 100644 --- a/src/cfgcond.c +++ b/src/cfgcond.c @@ -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; + /* ! 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; }