diff --git a/doc/configuration.txt b/doc/configuration.txt index b128718cd..ccb77a511 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 ee9fbbede..b154cb258 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 ac83b30ba..2dffe7b41 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; }