Transform flagcmp expression to a relational with binop on the left hand side, ie. relational / \ binop value / \ payload mask Add list_expr_to_binop() to make this transformation. Goal is two-fold: - Allow -o/--optimize to pick up on this representation. - Remove the flagcmp expression in a follow up patch. This prepare for the removal of the flagcmp expression added by: c3d57114f119 ("parser_bison: add shortcut syntax for matching flags without binary operations") Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- include/expression.h | 1 + src/expression.c | 23 +++++++++++++++++++++++ src/parser_bison.y | 22 ++++++++++++++++++---- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/include/expression.h b/include/expression.h index 8472748621ef..818d7a7dc74b 100644 --- a/include/expression.h +++ b/include/expression.h @@ -519,6 +519,7 @@ extern void list_splice_sorted(struct list_head *list, struct list_head *head); extern struct expr *concat_expr_alloc(const struct location *loc); extern struct expr *list_expr_alloc(const struct location *loc); +struct expr *list_expr_to_binop(struct expr *expr); extern struct expr *set_expr_alloc(const struct location *loc, const struct set *set); diff --git a/src/expression.c b/src/expression.c index 156a66eb37f0..2a30d5af92a4 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1263,6 +1263,29 @@ struct expr *list_expr_alloc(const struct location *loc) return compound_expr_alloc(loc, EXPR_LIST); } +/* list is assumed to have two items at least, otherwise extend this! */ +struct expr *list_expr_to_binop(struct expr *expr) +{ + struct expr *first, *last, *i; + + first = list_first_entry(&expr->expressions, struct expr, list); + i = first; + + list_for_each_entry_continue(i, &expr->expressions, list) { + if (first) { + last = binop_expr_alloc(&expr->location, OP_OR, first, i); + first = NULL; + } else { + last = binop_expr_alloc(&expr->location, OP_OR, i, last); + } + } + /* zap list expressions, they have been moved to binop expression. */ + init_list_head(&expr->expressions); + expr_free(expr); + + return last; +} + static const char *calculate_delim(const struct expr *expr, int *count, struct output_ctx *octx) { diff --git a/src/parser_bison.y b/src/parser_bison.y index 5760ba479fc9..4b2b51d4275c 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -4917,19 +4917,33 @@ relational_expr : expr /* implicit */ rhs_expr } | expr /* implicit */ basic_rhs_expr SLASH list_rhs_expr { - $$ = flagcmp_expr_alloc(&@$, OP_EQ, $1, $4, $2); + struct expr *mask = list_expr_to_binop($4); + struct expr *binop = binop_expr_alloc(&@$, OP_AND, $1, mask); + + $$ = relational_expr_alloc(&@$, OP_IMPLICIT, binop, $2); } | expr /* implicit */ list_rhs_expr SLASH list_rhs_expr { - $$ = flagcmp_expr_alloc(&@$, OP_EQ, $1, $4, $2); + struct expr *value = list_expr_to_binop($2); + struct expr *mask = list_expr_to_binop($4); + struct expr *binop = binop_expr_alloc(&@$, OP_AND, $1, mask); + + $$ = relational_expr_alloc(&@$, OP_IMPLICIT, binop, value); } | expr relational_op basic_rhs_expr SLASH list_rhs_expr { - $$ = flagcmp_expr_alloc(&@$, $2, $1, $5, $3); + struct expr *mask = list_expr_to_binop($5); + struct expr *binop = binop_expr_alloc(&@$, OP_AND, $1, mask); + + $$ = relational_expr_alloc(&@$, $2, binop, $3); } | expr relational_op list_rhs_expr SLASH list_rhs_expr { - $$ = flagcmp_expr_alloc(&@$, $2, $1, $5, $3); + struct expr *value = list_expr_to_binop($3); + struct expr *mask = list_expr_to_binop($5); + struct expr *binop = binop_expr_alloc(&@$, OP_AND, $1, mask); + + $$ = relational_expr_alloc(&@$, $2, binop, value); } | expr relational_op rhs_expr { -- 2.30.2