summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@tsaousis.gr>2016-08-11 01:11:40 +0300
committerCosta Tsaousis <costa@tsaousis.gr>2016-08-11 01:11:40 +0300
commit69f67772dbb538726a90dfb6e8a9450cae580695 (patch)
tree555653145410196e23572d79ff8a57365108070a /src
parent3f52dca264fee6721813bd662811e020b62e6748 (diff)
various renames to make the code more readable
Diffstat (limited to 'src')
-rw-r--r--src/eval.c219
-rw-r--r--src/eval.h15
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