mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-12 16:37:20 +00:00
MINOR: cfgcond: support terms made of parenthesis around expressions
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.
This commit is contained in:
parent
ca81887599
commit
316ea7ede5
@ -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
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user