mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-14 17:37:46 +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"
|
- the integer zero ('0'), always returns "false"
|
||||||
- a non-nul integer (e.g. '1'), always returns "true".
|
- a non-nul integer (e.g. '1'), always returns "true".
|
||||||
- a predicate optionally followed by argument(s) in parenthesis.
|
- 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
|
- a question mark ('!') preceeding any of the non-empty elements above, and
|
||||||
which will negate its status.
|
which will negate its status.
|
||||||
- expressions combined with a logical AND ('&&'), which will be evaluated
|
- expressions combined with a logical AND ('&&'), which will be evaluated
|
||||||
@ -861,7 +862,7 @@ Example:
|
|||||||
.endif
|
.endif
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if streq("$WITH_SSL",yes) && feature(OPENSSL)
|
.if feature(OPENSSL) && (streq("$WITH_SSL",yes) || streq("$SSL_ONLY",yes))
|
||||||
bind :443 ssl crt ...
|
bind :443 ssl crt ...
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ enum cfg_cond_term_type {
|
|||||||
CCTT_FALSE,
|
CCTT_FALSE,
|
||||||
CCTT_TRUE,
|
CCTT_TRUE,
|
||||||
CCTT_PRED,
|
CCTT_PRED,
|
||||||
|
CCTT_PAREN, // '(' EXPR ')'
|
||||||
};
|
};
|
||||||
|
|
||||||
/* keyword for a condition predicate */
|
/* keyword for a condition predicate */
|
||||||
@ -74,6 +75,7 @@ struct cfg_cond_term {
|
|||||||
int neg; // 0: direct result; 1: negate
|
int neg; // 0: direct result; 1: negate
|
||||||
union {
|
union {
|
||||||
const struct cond_pred_kw *pred; // predicate (function)
|
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)
|
if (!term || !*term)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ((*term)->type == CCTT_PAREN)
|
||||||
|
cfg_free_cond_expr(&(*term)->expr);
|
||||||
|
|
||||||
free_args((*term)->args);
|
free_args((*term)->args);
|
||||||
free((*term)->args);
|
free((*term)->args);
|
||||||
ha_free(term);
|
ha_free(term);
|
||||||
@ -104,6 +107,32 @@ int cfg_parse_cond_term(const char **text, struct cfg_cond_term **term, char **e
|
|||||||
return 1;
|
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
|
/* below we'll likely all make_arg_list() so we must return only via
|
||||||
* the <done> label which frees the arg list.
|
* 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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fail0:
|
||||||
memprintf(err, "unparsable conditional expression '%s'", *text);
|
memprintf(err, "unparsable conditional expression '%s'", *text);
|
||||||
fail1:
|
fail1:
|
||||||
if (errptr)
|
if (errptr)
|
||||||
@ -196,6 +226,9 @@ int cfg_eval_cond_term(const struct cfg_cond_term *term, char **err)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (term->type == CCTT_PAREN) {
|
||||||
|
ret = cfg_eval_cond_expr(term->expr, err);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
memprintf(err, "internal error: unhandled condition term type %d", (int)term->type);
|
memprintf(err, "internal error: unhandled condition term type %d", (int)term->type);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user