mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
MINOR: config: centralize the ".if"/".elif" condition parser and evaluator
Instead of duplicating the condition evaluations, let's have a single function cfg_eval_condition() that returns true/false/error. It takes less code and will ease its extension.
This commit is contained in:
parent
71990e6bec
commit
6a2110c717
@ -1634,6 +1634,25 @@ static int cfg_parse_global_def_path(char **args, int section_type, struct proxy
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* evaluate a condition on a .if/.elif line. The condition is already tokenized
|
||||
* in <err>. Returns -1 on error (in which case err is filled with a message,
|
||||
* and only in this case), 0 if the condition is false, 1 if it's true.
|
||||
*/
|
||||
static int cfg_eval_condition(char **args, char **err)
|
||||
{
|
||||
char *end;
|
||||
long val;
|
||||
|
||||
if (!*args[0]) /* note: empty = false */
|
||||
return 0;
|
||||
|
||||
val = strtol(args[0], &end, 0);
|
||||
if (end && *end == '\0')
|
||||
return val != 0;
|
||||
|
||||
memprintf(err, "unparsable conditional expression '%s'.\n", args[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function reads and parses the configuration file given in the argument.
|
||||
@ -1848,6 +1867,9 @@ int readcfgfile(const char *file)
|
||||
/* check for config macros */
|
||||
if (*args[0] == '.') {
|
||||
if (strcmp(args[0], ".if") == 0) {
|
||||
char *errmsg = NULL;
|
||||
int cond;
|
||||
|
||||
nested_cond_lvl++;
|
||||
if (nested_cond_lvl >= MAXNESTEDCONDS) {
|
||||
ha_alert("parsing [%s:%d]: too many nested '.if', max is %d.\n", file, linenum, MAXNESTEDCONDS);
|
||||
@ -1862,20 +1884,28 @@ int readcfgfile(const char *file)
|
||||
nested_conds[nested_cond_lvl - 1] == NESTED_COND_ELIF_SKIP ||
|
||||
nested_conds[nested_cond_lvl - 1] == NESTED_COND_ELSE_DROP)) {
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_IF_SKIP;
|
||||
} else if (!*args[1] || *args[1] == '0') {
|
||||
/* empty = false */
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_IF_DROP;
|
||||
} else if (atoi(args[1]) != 0) {
|
||||
/* true */
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_IF_TAKE;
|
||||
} else {
|
||||
ha_alert("parsing [%s:%d]: unparsable conditional expression '%s'.\n", file, linenum, args[1]);
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
cond = cfg_eval_condition(args + 1, &errmsg);
|
||||
if (cond < 0) {
|
||||
ha_alert("parsing [%s:%d]: %s in '.if'\n", file, linenum, errmsg);
|
||||
free(errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL | ERR_ABORT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (cond)
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_IF_TAKE;
|
||||
else
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_IF_DROP;
|
||||
|
||||
goto next_line;
|
||||
}
|
||||
else if (strcmp(args[0], ".elif") == 0) {
|
||||
char *errmsg = NULL;
|
||||
int cond;
|
||||
|
||||
if (!nested_cond_lvl) {
|
||||
ha_alert("parsing [%s:%d]: lone '.elif' with no matching '.if'.\n", file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_FATAL | ERR_ABORT;
|
||||
@ -1894,17 +1924,22 @@ int readcfgfile(const char *file)
|
||||
nested_conds[nested_cond_lvl] == NESTED_COND_ELIF_TAKE ||
|
||||
nested_conds[nested_cond_lvl] == NESTED_COND_ELIF_SKIP) {
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_ELIF_SKIP;
|
||||
} else if (!*args[1] || *args[1] == '0') {
|
||||
/* empty = false */
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_ELIF_DROP;
|
||||
} else if (atoi(args[1]) != 0) {
|
||||
/* true */
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_ELIF_TAKE;
|
||||
} else {
|
||||
ha_alert("parsing [%s:%d]: unparsable conditional expression '%s'.\n", file, linenum, args[1]);
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
cond = cfg_eval_condition(args + 1, &errmsg);
|
||||
if (cond < 0) {
|
||||
ha_alert("parsing [%s:%d]: %s in '.elif'\n", file, linenum, errmsg);
|
||||
free(errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL | ERR_ABORT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (cond)
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_ELIF_TAKE;
|
||||
else
|
||||
nested_conds[nested_cond_lvl] = NESTED_COND_ELIF_DROP;
|
||||
|
||||
goto next_line;
|
||||
}
|
||||
else if (strcmp(args[0], ".else") == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user