1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later 2*49cdfc7eSAndroid Build Coastguard Worker /* 3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2020 Cyril Hrubis <[email protected]> 4*49cdfc7eSAndroid Build Coastguard Worker */ 5*49cdfc7eSAndroid Build Coastguard Worker 6*49cdfc7eSAndroid Build Coastguard Worker #ifndef TST_BOOL_EXPR_H__ 7*49cdfc7eSAndroid Build Coastguard Worker #define TST_BOOL_EXPR_H__ 8*49cdfc7eSAndroid Build Coastguard Worker 9*49cdfc7eSAndroid Build Coastguard Worker enum tst_op { 10*49cdfc7eSAndroid Build Coastguard Worker TST_OP_NOT, 11*49cdfc7eSAndroid Build Coastguard Worker TST_OP_AND, 12*49cdfc7eSAndroid Build Coastguard Worker TST_OP_OR, 13*49cdfc7eSAndroid Build Coastguard Worker TST_OP_VAR, 14*49cdfc7eSAndroid Build Coastguard Worker /* Used only internally */ 15*49cdfc7eSAndroid Build Coastguard Worker TST_OP_LPAR, 16*49cdfc7eSAndroid Build Coastguard Worker TST_OP_RPAR, 17*49cdfc7eSAndroid Build Coastguard Worker }; 18*49cdfc7eSAndroid Build Coastguard Worker 19*49cdfc7eSAndroid Build Coastguard Worker struct tst_expr_tok { 20*49cdfc7eSAndroid Build Coastguard Worker enum tst_op op; 21*49cdfc7eSAndroid Build Coastguard Worker const char *tok; 22*49cdfc7eSAndroid Build Coastguard Worker size_t tok_len; 23*49cdfc7eSAndroid Build Coastguard Worker struct tst_expr_tok *next; 24*49cdfc7eSAndroid Build Coastguard Worker const void *priv; 25*49cdfc7eSAndroid Build Coastguard Worker }; 26*49cdfc7eSAndroid Build Coastguard Worker 27*49cdfc7eSAndroid Build Coastguard Worker struct tst_expr { 28*49cdfc7eSAndroid Build Coastguard Worker struct tst_expr_tok *rpn; 29*49cdfc7eSAndroid Build Coastguard Worker struct tst_expr_tok buf[]; 30*49cdfc7eSAndroid Build Coastguard Worker }; 31*49cdfc7eSAndroid Build Coastguard Worker 32*49cdfc7eSAndroid Build Coastguard Worker /* 33*49cdfc7eSAndroid Build Coastguard Worker * Parses an boolean expression and returns a simplified RPN version. 34*49cdfc7eSAndroid Build Coastguard Worker * 35*49cdfc7eSAndroid Build Coastguard Worker * If expression is not valid the call prints error into stderr and returns 36*49cdfc7eSAndroid Build Coastguard Worker * NULL. On success pointer to an expression is returned which can be evaluated 37*49cdfc7eSAndroid Build Coastguard Worker * by the tst_bool_expr_eval() function and has to be later freed by the 38*49cdfc7eSAndroid Build Coastguard Worker * caller. 39*49cdfc7eSAndroid Build Coastguard Worker * 40*49cdfc7eSAndroid Build Coastguard Worker * The boolean expression can consists of: 41*49cdfc7eSAndroid Build Coastguard Worker * 42*49cdfc7eSAndroid Build Coastguard Worker * - unary negation opeartion ! 43*49cdfc7eSAndroid Build Coastguard Worker * - two binary operations & and | 44*49cdfc7eSAndroid Build Coastguard Worker * - correct sequence of parentheses () 45*49cdfc7eSAndroid Build Coastguard Worker * - strings that are treated as boolean variables 46*49cdfc7eSAndroid Build Coastguard Worker * 47*49cdfc7eSAndroid Build Coastguard Worker * e.g. '(A | B) & C' or 'Variable_1 & Variable_2' are both a valid boolean 48*49cdfc7eSAndroid Build Coastguard Worker * expressions. 49*49cdfc7eSAndroid Build Coastguard Worker * 50*49cdfc7eSAndroid Build Coastguard Worker * @expr String containing a boolean expression to be parsed. 51*49cdfc7eSAndroid Build Coastguard Worker * @return Pointer to an RPN expression. 52*49cdfc7eSAndroid Build Coastguard Worker */ 53*49cdfc7eSAndroid Build Coastguard Worker struct tst_expr *tst_bool_expr_parse(const char *expr); 54*49cdfc7eSAndroid Build Coastguard Worker 55*49cdfc7eSAndroid Build Coastguard Worker /* 56*49cdfc7eSAndroid Build Coastguard Worker * Prints an string representation of the expression into a FILE. 57*49cdfc7eSAndroid Build Coastguard Worker * 58*49cdfc7eSAndroid Build Coastguard Worker * @param A FILE to print to. 59*49cdfc7eSAndroid Build Coastguard Worker * @expr An expression to print. 60*49cdfc7eSAndroid Build Coastguard Worker */ 61*49cdfc7eSAndroid Build Coastguard Worker void tst_bool_expr_print(FILE *f, struct tst_expr *expr); 62*49cdfc7eSAndroid Build Coastguard Worker 63*49cdfc7eSAndroid Build Coastguard Worker /* 64*49cdfc7eSAndroid Build Coastguard Worker * Evaluates an expression given a map for variables. 65*49cdfc7eSAndroid Build Coastguard Worker * 66*49cdfc7eSAndroid Build Coastguard Worker * The call will fail if: 67*49cdfc7eSAndroid Build Coastguard Worker * - map function returns -1 which indicates undefined variable 68*49cdfc7eSAndroid Build Coastguard Worker * - the eval function runs out of stack 69*49cdfc7eSAndroid Build Coastguard Worker * 70*49cdfc7eSAndroid Build Coastguard Worker * @param expr Boolean expression in RPN. 71*49cdfc7eSAndroid Build Coastguard Worker * @param map Mapping function for boolean variables. 72*49cdfc7eSAndroid Build Coastguard Worker * 73*49cdfc7eSAndroid Build Coastguard Worker * @return Returns 0 or 1 if expression was evaluated correctly and -1 on error. 74*49cdfc7eSAndroid Build Coastguard Worker */ 75*49cdfc7eSAndroid Build Coastguard Worker int tst_bool_expr_eval(struct tst_expr *expr, 76*49cdfc7eSAndroid Build Coastguard Worker int (*map)(struct tst_expr_tok *var)); 77*49cdfc7eSAndroid Build Coastguard Worker 78*49cdfc7eSAndroid Build Coastguard Worker /* 79*49cdfc7eSAndroid Build Coastguard Worker * Frees the memory allocated by the tst_bool_expr_parse(). 80*49cdfc7eSAndroid Build Coastguard Worker * 81*49cdfc7eSAndroid Build Coastguard Worker * @param Boolean expression. 82*49cdfc7eSAndroid Build Coastguard Worker */ 83*49cdfc7eSAndroid Build Coastguard Worker void tst_bool_expr_free(struct tst_expr *expr); 84*49cdfc7eSAndroid Build Coastguard Worker 85*49cdfc7eSAndroid Build Coastguard Worker #endif /* TST_BOOL_EXPR_H__ */ 86