diff options
author | Costa Tsaousis <costa@tsaousis.gr> | 2016-08-11 01:11:40 +0300 |
---|---|---|
committer | Costa Tsaousis <costa@tsaousis.gr> | 2016-08-11 01:11:40 +0300 |
commit | 69f67772dbb538726a90dfb6e8a9450cae580695 (patch) | |
tree | 555653145410196e23572d79ff8a57365108070a /src | |
parent | 3f52dca264fee6721813bd662811e020b62e6748 (diff) |
various renames to make the code more readable
Diffstat (limited to 'src')
-rw-r--r-- | src/eval.c | 219 | ||||
-rw-r--r-- | src/eval.h | 15 |
2 files changed, 118 insertions, 116 deletions
diff --git a/src/eval.c b/src/eval.c index ff121b5ceb..93d768cf78 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1,11 +1,10 @@ #include "common.h" // forward definitions -static inline void operand_free(EVAL_OPERAND *op); -static inline EVAL_OPERAND *parse_operand(const char **string, int *error); -static inline EVAL_OPERAND *parse_operand1(const char **string, int *error); -static inline calculated_number eval_operand(EVAL_OPERAND *op, int *error); - +static inline void eval_node_free(EVAL_NODE *op); +static inline EVAL_NODE *parse_full_expression(const char **string, int *error); +static inline EVAL_NODE *parse_one_full_operand(const char **string, int *error); +static inline calculated_number eval_node(EVAL_NODE *op, int *error); static inline void skip_spaces(const char **string) { const char *s = *string; @@ -217,7 +216,7 @@ static inline int parse_close_subexpression(const char **string) { return 0; } -static inline int parse_literal(const char **string, calculated_number *number) { +static inline int parse_constant(const char **string, calculated_number *number) { char *end = NULL; calculated_number n = strtold(*string, &end); if(unlikely(!end || *string == end || isnan(n) || isinf(n))) { @@ -225,7 +224,6 @@ static inline int parse_literal(const char **string, calculated_number *number) return 0; } *number = n; - *string = end; return 1; } @@ -251,7 +249,7 @@ static inline int parse_not(const char **string) { } static struct operator_parser { - char id; + unsigned char id; int (*parse)(const char **); } operator_parsers[] = { // the order in this list is important! @@ -272,13 +270,13 @@ static struct operator_parser { { EVAL_OPERATOR_MULTIPLY, parse_multiply }, { EVAL_OPERATOR_DIVIDE, parse_divide }, - /* we should not put + /* we should not put in this list the following: * * - NOT * - ( * - ) * - * in this list + * these are handled in code */ { EVAL_OPERATOR_NOP, NULL } @@ -306,7 +304,7 @@ static inline calculated_number eval_value(EVAL_VALUE *v, int *error) { switch(v->type) { case EVAL_VALUE_EXPRESSION: - n = eval_operand(v->expression, error); + n = eval_node(v->expression, error); break; case EVAL_VALUE_NUMBER: @@ -325,52 +323,52 @@ static inline calculated_number eval_value(EVAL_VALUE *v, int *error) { return eval_check_number(n, error); } -calculated_number eval_and(EVAL_OPERAND *op, int *error) { +calculated_number eval_and(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) && eval_value(&op->ops[1], error); } -calculated_number eval_or(EVAL_OPERAND *op, int *error) { +calculated_number eval_or(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) || eval_value(&op->ops[1], error); } -calculated_number eval_greater_than_or_equal(EVAL_OPERAND *op, int *error) { +calculated_number eval_greater_than_or_equal(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) >= eval_value(&op->ops[1], error); } -calculated_number eval_less_than_or_equal(EVAL_OPERAND *op, int *error) { +calculated_number eval_less_than_or_equal(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) <= eval_value(&op->ops[1], error); } -calculated_number eval_not_equal(EVAL_OPERAND *op, int *error) { +calculated_number eval_not_equal(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) != eval_value(&op->ops[1], error); } -calculated_number eval_equal(EVAL_OPERAND *op, int *error) { +calculated_number eval_equal(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) == eval_value(&op->ops[1], error); } -calculated_number eval_less(EVAL_OPERAND *op, int *error) { +calculated_number eval_less(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) < eval_value(&op->ops[1], error); } -calculated_number eval_greater(EVAL_OPERAND *op, int *error) { +calculated_number eval_greater(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) > eval_value(&op->ops[1], error); } -calculated_number eval_plus(EVAL_OPERAND *op, int *error) { +calculated_number eval_plus(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) + eval_value(&op->ops[1], error); } -calculated_number eval_minus(EVAL_OPERAND *op, int *error) { +calculated_number eval_minus(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) - eval_value(&op->ops[1], error); } -calculated_number eval_multiply(EVAL_OPERAND *op, int *error) { +calculated_number eval_multiply(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) * eval_value(&op->ops[1], error); } -calculated_number eval_divide(EVAL_OPERAND *op, int *error) { +calculated_number eval_divide(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error) / eval_value(&op->ops[1], error); } -calculated_number eval_nop(EVAL_OPERAND *op, int *error) { +calculated_number eval_nop(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error); } -calculated_number eval_not(EVAL_OPERAND *op, int *error) { +calculated_number eval_not(EVAL_NODE *op, int *error) { return !eval_value(&op->ops[0], error); } -calculated_number eval_sign_plus(EVAL_OPERAND *op, int *error) { +calculated_number eval_sign_plus(EVAL_NODE *op, int *error) { return eval_value(&op->ops[0], error); } -calculated_number eval_sign_minus(EVAL_OPERAND *op, int *error) { +calculated_number eval_sign_minus(EVAL_NODE *op, int *error) { return -eval_value(&op->ops[0], error); } @@ -378,7 +376,7 @@ static struct operator { const char *print_as; char precedence; char parameters; - calculated_number (*eval)(EVAL_OPERAND *op, int *error); + calculated_number (*eval)(EVAL_NODE *op, int *error); } operators[256] = { // this is a random access array // we always access it with a known EVAL_OPERATOR_X @@ -408,7 +406,7 @@ static struct operator { #define eval_precedence(operator) (operators[(unsigned char)(operator)].precedence) -static inline calculated_number eval_operand(EVAL_OPERAND *op, int *error) { +static inline calculated_number eval_node(EVAL_NODE *op, int *error) { if(unlikely(op->count != operators[op->operator].parameters)) { *error = EVAL_ERROR_INVALID_NUMBER_OF_OPERANDS; return 0; @@ -421,7 +419,7 @@ static inline calculated_number eval_operand(EVAL_OPERAND *op, int *error) { // ---------------------------------------------------------------------------- -static inline char parse_operator(const char **string, int *precedence) { +static inline unsigned char parse_operator(const char **string, int *precedence) { skip_spaces(string); int i; @@ -434,11 +432,10 @@ static inline char parse_operator(const char **string, int *precedence) { return EVAL_OPERATOR_NOP; } - -static inline EVAL_OPERAND *operand_alloc(int count) { +static inline EVAL_NODE *eval_node_alloc(int count) { static int id = 1; - EVAL_OPERAND *op = calloc(1, sizeof(EVAL_OPERAND) + (sizeof(EVAL_VALUE) * count)); + EVAL_NODE *op = calloc(1, sizeof(EVAL_NODE) + (sizeof(EVAL_VALUE) * count)); if(!op) fatal("Cannot allocate memory for OPERAND with %d slots", count); op->id = id++; @@ -448,7 +445,7 @@ static inline EVAL_OPERAND *operand_alloc(int count) { return op; } -static inline void operand_set_value_operand(EVAL_OPERAND *op, int pos, EVAL_OPERAND *value) { +static inline void eval_node_set_value_to_node(EVAL_NODE *op, int pos, EVAL_NODE *value) { if(pos >= op->count) fatal("Invalid request to set position %d of OPERAND that has only %d values", pos + 1, op->count + 1); @@ -456,7 +453,7 @@ static inline void operand_set_value_operand(EVAL_OPERAND *op, int pos, EVAL_OPE op->ops[pos].expression = value; } -static inline void operand_set_value_literal(EVAL_OPERAND *op, int pos, calculated_number value) { +static inline void node_set_value_to_constant(EVAL_NODE *op, int pos, calculated_number value) { if(pos >= op->count) fatal("Invalid request to set position %d of OPERAND that has only %d values", pos + 1, op->count + 1); @@ -471,19 +468,19 @@ static inline void variable_free(VARIABLE *v) { static inline void value_free(EVAL_VALUE *v) { switch(v->type) { case EVAL_VALUE_EXPRESSION: - operand_free(v->expression); + eval_node_free(v->expression); break; - case EVAL_VALUE_VARIABLE: - variable_free(v->variable); - break; +// case EVAL_VALUE_VARIABLE: +// variable_free(v->variable); +// break; default: break; } } -static inline void operand_free(EVAL_OPERAND *op) { +static inline void eval_node_free(EVAL_NODE *op) { if(op->count) { int i; for(i = op->count - 1; i >= 0 ;i--) @@ -493,18 +490,18 @@ static inline void operand_free(EVAL_OPERAND *op) { free(op); } -static inline EVAL_OPERAND *parse_operand_with_operator(const char **string, char type, int *error) { - EVAL_OPERAND *sub = parse_operand1(string, error); +static inline EVAL_NODE *parse_next_operand_given_its_operator(const char **string, unsigned char operator_type, int *error) { + EVAL_NODE *sub = parse_one_full_operand(string, error); if(!sub) return NULL; - EVAL_OPERAND *op = operand_alloc(1); - op->operator = type; - operand_set_value_operand(op, 0, sub); + EVAL_NODE *op = eval_node_alloc(1); + op->operator = operator_type; + eval_node_set_value_to_node(op, 0, sub); return op; } -static inline EVAL_OPERAND *parse_operand1(const char **string, int *error) { - EVAL_OPERAND *op1 = NULL; +static inline EVAL_NODE *parse_one_full_operand(const char **string, int *error) { + EVAL_NODE *op1 = NULL; calculated_number number; *error = EVAL_ERROR_OK; @@ -516,27 +513,27 @@ static inline EVAL_OPERAND *parse_operand1(const char **string, int *error) { } if(parse_not(string)) { - op1 = parse_operand_with_operator(string, EVAL_OPERATOR_NOT, error); + op1 = parse_next_operand_given_its_operator(string, EVAL_OPERATOR_NOT, error); op1->precedence = eval_precedence(EVAL_OPERATOR_NOT); } else if(parse_plus(string)) { - op1 = parse_operand_with_operator(string, EVAL_OPERATOR_SIGN_PLUS, error); + op1 = parse_next_operand_given_its_operator(string, EVAL_OPERATOR_SIGN_PLUS, error); op1->precedence = eval_precedence(EVAL_OPERATOR_SIGN_PLUS); } else if(parse_minus(string)) { - op1 = parse_operand_with_operator(string, EVAL_OPERATOR_SIGN_MINUS, error); + op1 = parse_next_operand_given_its_operator(string, EVAL_OPERATOR_SIGN_MINUS, error); op1->precedence = eval_precedence(EVAL_OPERATOR_SIGN_MINUS); } else if(parse_open_subexpression(string)) { - EVAL_OPERAND *sub = parse_operand(string, error); + EVAL_NODE *sub = parse_full_expression(string, error); if(sub) { - op1 = operand_alloc(1); + op1 = eval_node_alloc(1); op1->operator = EVAL_OPERATOR_EXPRESSION_OPEN; op1->precedence = eval_precedence(EVAL_OPERATOR_EXPRESSION_OPEN); - operand_set_value_operand(op1, 0, sub); + eval_node_set_value_to_node(op1, 0, sub); if(!parse_close_subexpression(string)) { *error = EVAL_ERROR_MISSING_CLOSE_SUBEXPRESSION; - operand_free(op1); + eval_node_free(op1); return NULL; } } @@ -544,10 +541,10 @@ static inline EVAL_OPERAND *parse_operand1(const char **string, int *error) { // else if(parse_variable(string)) { // // } - else if(parse_literal(string, &number)) { - op1 = operand_alloc(1); + else if(parse_constant(string, &number)) { + op1 = eval_node_alloc(1); op1->operator = EVAL_OPERATOR_VALUE; - operand_set_value_literal(op1, 0, number); + node_set_value_to_constant(op1, 0, number); } else if(*string) *error = EVAL_ERROR_UNKNOWN_OPERAND; @@ -557,41 +554,42 @@ static inline EVAL_OPERAND *parse_operand1(const char **string, int *error) { return op1; } -static inline EVAL_OPERAND *parse_operand_rest(const char **string, int *error, EVAL_OPERAND *op1) { - EVAL_OPERAND *op2 = NULL; - char operator; +static inline EVAL_NODE *parse_rest_of_expression(const char **string, int *error, EVAL_NODE *op1) { + EVAL_NODE *op2 = NULL; + unsigned char operator; int precedence; operator = parse_operator(string, &precedence); skip_spaces(string); if(operator != EVAL_OPERATOR_NOP) { - op2 = parse_operand1(string, error); + op2 = parse_one_full_operand(string, error); if(!op2) { - operand_free(op1); + // error is already reported + eval_node_free(op1); return NULL; } - EVAL_OPERAND *op = operand_alloc(2); + EVAL_NODE *op = eval_node_alloc(2); op->operator = operator; op->precedence = precedence; - operand_set_value_operand(op, 0, op1); - operand_set_value_operand(op, 1, op2); + eval_node_set_value_to_node(op, 0, op1); + eval_node_set_value_to_node(op, 1, op2); if(op->precedence > op1->precedence && op1->count == 2 && op1->operator != '(' && op1->ops[1].type == EVAL_VALUE_EXPRESSION) { - operand_set_value_operand(op, 0, op1->ops[1].expression); + eval_node_set_value_to_node(op, 0, op1->ops[1].expression); op1->ops[1].expression = op; op = op1; } - return parse_operand_rest(string, error, op); + return parse_rest_of_expression(string, error, op); } else if(**string == EVAL_OPERATOR_EXPRESSION_CLOSE) { ; } else if(**string) { - if(op1) operand_free(op1); + if(op1) eval_node_free(op1); op1 = NULL; *error = EVAL_ERROR_MISSING_OPERATOR; } @@ -599,19 +597,58 @@ static inline EVAL_OPERAND *parse_operand_rest(const char **string, int *error, return op1; } -static inline EVAL_OPERAND *parse_operand(const char **string, int *error) { - EVAL_OPERAND *op1 = NULL; +static inline EVAL_NODE *parse_full_expression(const char **string, int *error) { + EVAL_NODE *op1 = NULL; - op1 = parse_operand1(string, error); + op1 = parse_one_full_operand(string, error); if(!op1) { *error = EVAL_ERROR_MISSING_OPERAND; return NULL; } - return parse_operand_rest(string, error, op1); + return parse_rest_of_expression(string, error, op1); +} + +// ---------------------------------------------------------------------------- +// public API + +EVAL_NODE *expression_parse(const char *string, const char **failed_at, int *error) { + const char *s; + int err = EVAL_ERROR_OK; + unsigned long pos = 0; + + s = string; + EVAL_NODE *op = parse_full_expression(&s, &err); + + if (failed_at) *failed_at = s; + if (error) *error = err; + + if(!op) { + pos = s - string + 1; + error("failed to parse expression '%s': %s at character %lu (i.e.: '%s').", string, expression_strerror(err), pos, s); + } + + return op; +} + +calculated_number expression_evaluate(EVAL_NODE *expression, int *error) { + int err = EVAL_ERROR_OK; + calculated_number ret = eval_node(expression, &err); + + if(err != EVAL_ERROR_OK) { + error("Failed to execute expression with error %d (%s)", err, expression_strerror(err)); + if(error) *error = err; + return 0; + } + + return ret; +} + +void expression_free(EVAL_NODE *op) { + if(op) eval_node_free(op); } -const char *eval_error(int error) { +const char *expression_strerror(int error) { switch(error) { case EVAL_ERROR_OK: return "success"; @@ -644,39 +681,3 @@ const char *eval_error(int error) { return "unknown error"; } } - -EVAL_OPERAND *parse_expression(const char *string, const char **failed_at, int *error) { - const char *s; - int err = EVAL_ERROR_OK; - unsigned long pos = 0; - - s = string; - EVAL_OPERAND *op = parse_operand(&s, &err); - - if (failed_at) *failed_at = s; - if (error) *error = err; - - if(!op) { - pos = s - string + 1; - error("failed to parse expression '%s': %s at character %lu (i.e.: '%s').", string, eval_error(err), pos, s); - } - - return op; -} - -calculated_number evaluate_expression(EVAL_OPERAND *expression, int *error) { - int err = EVAL_ERROR_OK; - calculated_number ret = eval_operand(expression, &err); - - if(err != EVAL_ERROR_OK) { - error("Failed to execute expression with error %d (%s)", err, eval_error(err)); - if(error) *error = err; - return 0; - } - - return ret; -} - -void free_expression(EVAL_OPERAND *op) { - if(op) operand_free(op); -} diff --git a/src/eval.h b/src/eval.h index 157abc63bd..a645b31b07 100644 --- a/src/eval.h +++ b/src/eval.h @@ -12,7 +12,7 @@ typedef struct variable { #define EVAL_VALUE_VARIABLE 2 #define EVAL_VALUE_EXPRESSION 3 -// these are used for EVAL_OPERAND.operator +// these are used for EVAL_NODE.operator #define EVAL_OPERATOR_NOP '\0' #define EVAL_OPERATOR_VALUE ':' #define EVAL_OPERATOR_EXPRESSION_OPEN '(' @@ -53,21 +53,22 @@ typedef struct eval_value { union { calculated_number number; VARIABLE *variable; - struct eval_operand *expression; + struct eval_node *expression; }; } EVAL_VALUE; -typedef struct eval_operand { +typedef struct eval_node { int id; unsigned char operator; int precedence; int count; EVAL_VALUE ops[]; -} EVAL_OPERAND; +} EVAL_NODE; -extern EVAL_OPERAND *parse_expression(const char *string, const char **failed_at, int *error); -extern calculated_number evaluate_expression(EVAL_OPERAND *expression, int *error); -extern void free_expression(EVAL_OPERAND *op); +extern EVAL_NODE *expression_parse(const char *string, const char **failed_at, int *error); +extern calculated_number expression_evaluate(EVAL_NODE *expression, int *error); +extern void expression_free(EVAL_NODE *op); +extern const char *expression_strerror(int error); #endif //NETDATA_EVAL_H |