// SPDX-License-Identifier: GPL-3.0-or-later
#include "../libnetdata.h"
// ----------------------------------------------------------------------------
// data structures for storing the parsed expression in memory
typedef struct eval_value {
int type;
union {
NETDATA_DOUBLE number;
EVAL_VARIABLE *variable;
struct eval_node *expression;
};
} EVAL_VALUE;
typedef struct eval_node {
int id;
unsigned char operator;
int precedence;
int count;
EVAL_VALUE ops[];
} EVAL_NODE;
// these are used for EVAL_NODE.operator
// they are used as internal IDs to identify an operator
// THEY ARE NOT USED FOR PARSING OPERATORS LIKE THAT
#define EVAL_OPERATOR_NOP '\0'
#define EVAL_OPERATOR_EXPRESSION_OPEN '('
#define EVAL_OPERATOR_EXPRESSION_CLOSE ')'
#define EVAL_OPERATOR_NOT '!'
#define EVAL_OPERATOR_PLUS '+'
#define EVAL_OPERATOR_MINUS '-'
#define EVAL_OPERATOR_AND '&'
#define EVAL_OPERATOR_OR '|'
#define EVAL_OPERATOR_GREATER_THAN_OR_EQUAL 'G'
#define EVAL_OPERATOR_LESS_THAN_OR_EQUAL 'L'
#define EVAL_OPERATOR_NOT_EQUAL '~'
#define EVAL_OPERATOR_EQUAL '='
#define EVAL_OPERATOR_LESS '<'
#define EVAL_OPERATOR_GREATER '>'
#define EVAL_OPERATOR_MULTIPLY '*'
#define EVAL_OPERATOR_DIVIDE '/'
#define EVAL_OPERATOR_SIGN_PLUS 'P'
#define EVAL_OPERATOR_SIGN_MINUS 'M'
#define EVAL_OPERATOR_ABS 'A'
#define EVAL_OPERATOR_IF_THEN_ELSE '?'
// ----------------------------------------------------------------------------
// forward function definitions
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 NETDATA_DOUBLE eval_node(EVAL_EXPRESSION *exp, EVAL_NODE *op, int *error);
static inline void print_parsed_as_node(BUFFER *out, EVAL_NODE *op, int *error);
static inline void print_parsed_as_constant(BUFFER *out, NETDATA_DOUBLE n);
// ----------------------------------------------------------------------------
// evaluation of expressions
static inline NETDATA_DOUBLE eval_variable(EVAL_EXPRESSION *exp, EVAL_VARIABLE *v, int *error) {
static STRING
*this_string = NULL,
*now_string = NULL,
*after_string = NULL,
*before_string = NULL,
*status_string = NULL,
*removed_string = NULL,
*uninitialized_string = NULL,
*undefined_string = NULL,
*clear_string = NULL,
*warning_string = NULL,
*critical_string = NULL;
NETDATA_DOUBLE n;
if(unlikely(this_string == NULL)) {
this_string = string_strdupz("this");
now_string = string_strdupz("now");
after_string =