variables are now parsed into expressions
Costa Tsaousis committed
Aug 13, 2016 at 02:58 UTC
8cf883f0ddbb0e12b793232ca20ee2558b2c1147
2 files changed
+52
-7
src/eval.c
+50
-7
@@ -26,7 +26,6 @@ typedef struct eval_node {
26
// they are used as internal IDs to identify an operator
27
// THEY ARE NOT USED FOR PARSING OPERATORS LIKE THAT
28
#define EVAL_OPERATOR_NOP '\0'
29
-#define EVAL_OPERATOR_VALUE ':'
29
#define EVAL_OPERATOR_EXPRESSION_OPEN '('
30
#define EVAL_OPERATOR_EXPRESSION_CLOSE ')'
31
#define EVAL_OPERATOR_NOT '!'
@@ -181,7 +180,6 @@ static struct operator {
180
[EVAL_OPERATOR_SIGN_PLUS] = { "+", 6, 1, eval_sign_plus },
181
[EVAL_OPERATOR_SIGN_MINUS] = { "-", 6, 1, eval_sign_minus },
182
[EVAL_OPERATOR_NOP] = { NULL, 7, 1, eval_nop },
184
- [EVAL_OPERATOR_VALUE] = { NULL, 7, 1, eval_nop },
183
[EVAL_OPERATOR_EXPRESSION_OPEN] = { NULL, 7, 1, eval_nop },
184
185
// this should exist in our evaluation list
@@ -298,10 +296,20 @@ static inline int isoperatorterm_word(const char s) {
296
297
// what character can appear just after an operator symbol?
298
static inline int isoperatorterm_symbol(const char s) {
301
- if(isoperatorterm_word(s) || isalpha(s)) return 1;
299
+ if(isoperatorterm_word(s) || isalpha(s))
300
+ return 1;
301
+
302
return 0;
303
}
304
305
+// return 1 if the character should never appear in a variable
306
+static inline int isvariableterm(const char s) {
307
+ if(isalnum(s) || s == '.' || s == '_')
308
+ return 0;
309
+
310
+ return 1;
311
+}
312
+
313
// ----------------------------------------------------------------------------
314
// parse operators
315
@@ -513,6 +521,28 @@ static inline int parse_close_subexpression(const char **string) {
521
return 0;
522
}
523
524
+static inline int parse_variable(const char **string, char *buffer, size_t len) {
525
+ const char *s = *string;
526
+
527
+ // $
528
+ if(s[0] == '$') {
529
+ size_t i = 0;
530
+ s++;
531
+
532
+ while(*s && !isvariableterm(*s) && i < len)
533
+ buffer[i++] = *s++;
534
+
535
+ buffer[i] = '\0';
536
+
537
+ if(buffer[0]) {
538
+ *string = &s[0];
539
+ return 1;
540
+ }
541
+ }
542
+
543
+ return 0;
544
+}
545
+
546
static inline int parse_constant(const char **string, calculated_number *number) {
547
char *end = NULL;
548
calculated_number n = strtold(*string, &end);
@@ -604,7 +634,17 @@ static inline void eval_node_set_value_to_constant(EVAL_NODE *op, int pos, calcu
634
op->ops[pos].number = value;
635
}
636
637
+static inline void eval_node_set_value_to_variable(EVAL_NODE *op, int pos, const char *variable) {
638
+ if(pos >= op->count)
639
+ fatal("Invalid request to set position %d of OPERAND that has only %d values", pos + 1, op->count + 1);
640
+
641
+ op->ops[pos].type = EVAL_VALUE_VARIABLE;
642
+ op->ops[pos].variable = callocz(1, sizeof(EVAL_VARIABLE));
643
+ op->ops[pos].variable->name = strdupz(variable);
644
+}
645
+
646
static inline void eval_variable_free(EVAL_VARIABLE *v) {
647
+ freez(v->name);
648
freez(v);
649
}
650
@@ -649,6 +689,7 @@ static inline EVAL_NODE *parse_next_operand_given_its_operator(const char **stri
689
690
// parse a full operand, including its sign or other associative operator (e.g. NOT)
691
static inline EVAL_NODE *parse_one_full_operand(const char **string, int *error) {
692
+ char variable_buffer[EVAL_MAX_VARIABLE_NAME_LENGTH + 1];
693
EVAL_NODE *op1 = NULL;
694
calculated_number number;
695
@@ -686,12 +727,14 @@ static inline EVAL_NODE *parse_one_full_operand(const char **string, int *error)
727
}
728
}
729
}
689
-// else if(parse_variable(string)) {
690
-//
691
-// }
730
+ else if(parse_variable(string, variable_buffer, EVAL_MAX_VARIABLE_NAME_LENGTH)) {
731
+ op1 = eval_node_alloc(1);
732
+ op1->operator = EVAL_OPERATOR_NOP;
733
+ eval_node_set_value_to_variable(op1, 0, variable_buffer);
734
+ }
735
else if(parse_constant(string, &number)) {
736
op1 = eval_node_alloc(1);
694
- op1->operator = EVAL_OPERATOR_VALUE;
737
+ op1->operator = EVAL_OPERATOR_NOP;
738
eval_node_set_value_to_constant(op1, 0, number);
739
}
740
else if(**string)
src/eval.h
+2
@@ -1,6 +1,8 @@
1
#ifndef NETDATA_EVAL_H
2
#define NETDATA_EVAL_H
3
4
+#define EVAL_MAX_VARIABLE_NAME_LENGTH 300
5
+
6
typedef struct eval_variable {
7
char *name;
8
struct rrdvar *rrdvar;