libamxp  1.4.0
Patterns C Implementation
amxp_expression_node.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <amxc/amxc.h>
#include "amxp_expr_priv.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

static void amxp_expr_node_clean_args (amxc_llist_it_t *it)
 
static void amxp_expr_node_build_args (amxp_expr_t *expr, amxc_var_t *value, amxc_llist_t *args)
 
static const char * amxp_expr_compop2string (amxp_expr_comp_t op)
 
void amxp_expr_node_new (amxp_expr_node_t **node, amxp_expr_node_type_t type)
 
void amxp_expr_node_delete (amxp_expr_node_t **node)
 
void amxp_expr_node_push (amxc_lstack_t *stack, amxp_expr_node_t *node)
 
amxp_expr_node_tamxp_expr_node_pop (amxc_lstack_t *stack)
 
void amxp_expr_node_set_left (amxp_expr_node_t *node, amxp_expr_node_t *left)
 
void amxp_expr_node_set_right (amxp_expr_node_t *node, amxp_expr_node_t *right)
 
void amxp_expr_node_set_value (amxp_expr_node_t *node, amxc_var_t *value)
 
void amxp_expr_node_set_function (amxp_expr_node_t *node, char *func_name)
 
void amxp_expr_node_set_field (amxp_expr_node_t *node, char *field)
 
void amxp_expr_node_set_compop (amxp_expr_node_t *node, amxp_expr_comp_t comop)
 
void amxp_expr_node_add_value (amxp_expr_node_t *node, amxp_expr_node_t *value)
 
amxp_expr_node_tamxp_expr_get_node (amxp_expr_t *expr)
 
amxc_var_t * amxp_expr_node_get_value (amxp_expr_t *expr, amxp_expr_node_t *node)
 
bool amxp_expr_node_eval (amxp_expr_t *expr, amxp_expr_node_t *node)
 
void amxp_expr_node_dump (amxp_expr_t *expr, amxp_expr_node_t *node, uint32_t level, uint32_t parent_id)
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxp_expression_node.c.

Function Documentation

◆ amxp_expr_compop2string()

static const char* amxp_expr_compop2string ( amxp_expr_comp_t  op)
static

Definition at line 80 of file amxp_expression_node.c.

80  {
81  const char* string[] = {
82  "==",
83  "!=",
84  "\\<",
85  "\\>",
86  "\\<=",
87  "\\>=",
88  "matches",
89  "starts with",
90  "in",
91  "~=",
92  "^=",
93  "ends with"
94  };
95 
96  return string[op];
97 }

◆ amxp_expr_get_node()

amxp_expr_node_t* amxp_expr_get_node ( amxp_expr_t expr)

Definition at line 189 of file amxp_expression_node.c.

189  {
190  amxp_expr_node_t* node = NULL;
191  amxc_llist_it_t* it = amxc_llist_get_first(&expr->nodes);
192  when_null(it, exit);
193 
194  node = amxc_container_of(it, amxp_expr_node_t, it);
195 
196 exit:
197  return node;
198 }
amxc_lstack_t nodes

◆ amxp_expr_node_add_value()

void amxp_expr_node_add_value ( amxp_expr_node_t node,
amxp_expr_node_t value 
)

Definition at line 185 of file amxp_expression_node.c.

185  {
186  amxc_llist_append(&node->right.args, &value->it);
187 }
amxc_llist_t args
amxc_llist_it_t it
union _amxp_expr_node::@1 right

◆ amxp_expr_node_build_args()

static void amxp_expr_node_build_args ( amxp_expr_t expr,
amxc_var_t *  value,
amxc_llist_t *  args 
)
static

Definition at line 70 of file amxp_expression_node.c.

70  {
71  amxc_var_set_type(value, AMXC_VAR_ID_LIST);
72  amxc_llist_for_each(it, args) {
73  amxp_expr_node_t* value_node = amxc_container_of(it, amxp_expr_node_t, it);
74  amxc_var_t* v = amxp_expr_node_get_value(expr, value_node);
75  amxc_var_set_index(value, -1, v, AMXC_VAR_FLAG_DEFAULT);
77  }
78 }
amxc_var_t * amxp_expr_node_get_value(amxp_expr_t *expr, amxp_expr_node_t *node)
@ amxp_expr_status_ok
amxp_expr_status_t status

◆ amxp_expr_node_clean_args()

static void amxp_expr_node_clean_args ( amxc_llist_it_t *  it)
static

Definition at line 65 of file amxp_expression_node.c.

65  {
66  amxp_expr_node_t* node = amxc_container_of(it, amxp_expr_node_t, it);
67  amxp_expr_node_delete(&node);
68 }
void amxp_expr_node_delete(amxp_expr_node_t **node)

◆ amxp_expr_node_delete()

void amxp_expr_node_delete ( amxp_expr_node_t **  node)

Definition at line 104 of file amxp_expression_node.c.

104  {
105  when_null(node, exit);
106  when_null(*node, exit);
107 
108  amxc_llist_it_take(&(*node)->it);
109  switch((*node)->type) {
111  case amxp_expr_and:
112  case amxp_expr_or:
113  amxp_expr_node_delete(&(*node)->left.node);
114  amxp_expr_node_delete(&(*node)->right.node);
115  break;
116  case amxp_expr_not:
117  amxp_expr_node_delete(&(*node)->left.node);
118  break;
119  case amxp_expr_value:
120  if((amxc_var_type_of((*node)->left.value) == AMXC_VAR_ID_LIST) ||
121  ((*node)->left.value == NULL)) {
122  amxc_llist_clean(&(*node)->right.args, amxp_expr_node_clean_args);
123  }
124  amxc_var_delete(&(*node)->left.value);
125  break;
127  case amxp_expr_bool_func:
128  free((*node)->left.func_name);
129  (*node)->left.func_name = NULL;
130  amxc_var_delete(&(*node)->value);
131  amxc_llist_clean(&(*node)->right.args, amxp_expr_node_clean_args);
132  break;
133  case amxp_expr_field:
134  free((*node)->left.field);
135  amxc_var_delete(&(*node)->value);
136  break;
137  }
138  free(*node);
139  *node = NULL;
140 exit:
141  return;
142 }
@ amxp_expr_value
@ amxp_expr_bool_func
@ amxp_expr_or
@ amxp_expr_not
@ amxp_expr_compare_oper
@ amxp_expr_value_func
@ amxp_expr_field
@ amxp_expr_and
static void amxp_expr_node_clean_args(amxc_llist_it_t *it)

◆ amxp_expr_node_dump()

void amxp_expr_node_dump ( amxp_expr_t expr,
amxp_expr_node_t node,
uint32_t  level,
uint32_t  parent_id 
)

Definition at line 322 of file amxp_expression_node.c.

322  {
323  static uint32_t id = 0;
324  uint32_t current_id = 0;
325 
326  when_null(node, exit);
327 
328  if(level == 0) {
329  amxc_string_t expr_txt;
330  amxc_string_init(&expr_txt, 0);
331  amxc_string_setf(&expr_txt, "%s", expr->expression);
332  amxc_string_replace(&expr_txt, "\"", "\\\"", UINT32_MAX);
333  printf("digraph D {\n");
334  printf("graph [ordering=\"out\"];\n");
335  printf("label = \"%s\";\n", amxc_string_get(&expr_txt, 0));
336  printf("labelloc = \"t\";\n");
337  id = 1;
338  parent_id = 0;
339  amxc_string_clean(&expr_txt);
340  } else {
341  id++;
342  }
343 
344  current_id = id;
345 
346  printf("node_%d", current_id);
347  switch(node->type) {
349  printf("[shape=\"record\" label=\"{COMPARE|%s}\"];\n", amxp_expr_compop2string(node->compare));
350  amxp_expr_node_dump(expr, node->left.node, level + 1, current_id);
351  amxp_expr_node_dump(expr, node->right.node, level + 1, current_id);
352  break;
353  case amxp_expr_and:
354  printf("[shape=\"box\" label=\"AND\"];\n");
355  amxp_expr_node_dump(expr, node->left.node, level + 1, current_id);
356  amxp_expr_node_dump(expr, node->right.node, level + 1, current_id);
357  break;
358  case amxp_expr_or:
359  printf("[shape=\"box\" label=\"OR\"];\n");
360  amxp_expr_node_dump(expr, node->left.node, level + 1, current_id);
361  amxp_expr_node_dump(expr, node->right.node, level + 1, current_id);
362  break;
363  case amxp_expr_not:
364  printf("[shape=\"box\" label=\"NOT\"];\n");
365  amxp_expr_node_dump(expr, node->left.node, level + 1, current_id);
366  break;
367  case amxp_expr_value: {
368  char* value = amxc_var_dyncast(cstring_t, node->left.value);
369  printf("[shape=\"record\" label=\"{VALUE|%s}\"];\n", value);
370  free(value);
371  }
372  break;
374  printf("[shape=\"record\" label=\"{VALUE FUNCTION|%s}\"];\n", node->left.func_name);
375  break;
376  case amxp_expr_bool_func:
377  printf("[shape=\"record\" label=\"{BOOL FUNCTION|%s}\"];\n", node->left.func_name);
378  break;
379  case amxp_expr_field:
380  printf("[shape=\"record\" label=\"{FIELD|%s}\"];\n", node->left.field);
381  break;
382  }
383 
384  if(parent_id != 0) {
385  printf("node_%d -> node_%d;\n", parent_id, current_id);
386  }
387 
388  if(level == 0) {
389  printf("}\n");
390  }
391 
392 exit:
393  return;
394 }
static const char * amxp_expr_compop2string(amxp_expr_comp_t op)
void amxp_expr_node_dump(amxp_expr_t *expr, amxp_expr_node_t *node, uint32_t level, uint32_t parent_id)
union _amxp_expr_node::@0 left
amxp_expr_node_t * node
amxp_expr_comp_t compare
amxp_expr_node_type_t type
amxc_var_t * value
char * expression

◆ amxp_expr_node_eval()

bool amxp_expr_node_eval ( amxp_expr_t expr,
amxp_expr_node_t node 
)

Definition at line 247 of file amxp_expression_node.c.

247  {
248  bool result = true;
249  when_null(node, exit);
250 
251  switch(node->type) {
252  case amxp_expr_and: {
253  bool right = false;
254  bool left = amxp_expr_node_eval(expr, node->left.node);
255  if(!left) {
256  result = left;
257  } else {
258  right = amxp_expr_node_eval(expr, node->right.node);
259  result = (left && right);
260  }
261  }
262  break;
263  case amxp_expr_or: {
264  bool right = false;
265  bool left = amxp_expr_node_eval(expr, node->left.node);
266  if(left) {
267  result = left;
268  } else {
269  right = amxp_expr_node_eval(expr, node->right.node);
270  result = (left || right);
271  }
272  }
273  break;
274  case amxp_expr_not:
275  result = !amxp_expr_node_eval(expr, node->left.node);
276  break;
277  case amxp_expr_compare_oper: {
278  amxc_var_t* left_value = amxp_expr_node_get_value(expr, node->left.node);
279  amxc_var_t* right_value = amxp_expr_node_get_value(expr, node->right.node);
280  if(!amxc_var_is_null(left_value) && !amxc_var_is_null(right_value)) {
281  result = amxp_expr_compare(expr, left_value, right_value, node->compare);
282  } else {
283  result = false;
284  }
285  }
286  break;
287  case amxp_expr_value:
288  if(amxc_var_type_of(node->left.value) != AMXC_VAR_ID_BOOL) {
290  result = false;
291  } else {
292  result = amxc_var_constcast(bool, node->left.value);
293  }
294  break;
295  case amxp_expr_field:
296  if(node->value == NULL) {
297  amxc_var_new(&node->value);
298  }
299  amxp_expr_get_field(expr, node->value, node->left.field);
300  if(expr->status != amxp_expr_status_ok) {
301  result = false;
302  } else {
303  result = amxc_var_constcast(bool, node->value);
304  }
305  break;
306  case amxp_expr_bool_func: {
307  amxc_var_t args;
308  amxc_var_init(&args);
309  amxp_expr_node_build_args(expr, &args, &node->right.args);
310  result = amxp_expr_call_bool_func(expr, node->left.func_name, &args);
311  amxc_llist_clean(&args.data.vl, NULL);
312  }
313  break;
314  default:
315  break;
316  }
317 
318 exit:
319  return result;
320 }
PRIVATE void PRIVATE int PRIVATE bool amxp_expr_compare(amxp_expr_t *expr, amxc_var_t *lvalue, amxc_var_t *rvalue, amxp_expr_comp_t comperator)
PRIVATE amxp_expr_status_t amxp_expr_get_field(amxp_expr_t *expr, amxc_var_t *var, const char *path)
PRIVATE bool amxp_expr_call_bool_func(amxp_expr_t *expr, const char *func, amxc_var_t *args)
bool amxp_expr_node_eval(amxp_expr_t *expr, amxp_expr_node_t *node)
static void amxp_expr_node_build_args(amxp_expr_t *expr, amxc_var_t *value, amxc_llist_t *args)
@ amxp_expr_status_invalid_value

◆ amxp_expr_node_get_value()

amxc_var_t* amxp_expr_node_get_value ( amxp_expr_t expr,
amxp_expr_node_t node 
)

Definition at line 200 of file amxp_expression_node.c.

200  {
201  amxc_var_t* value = NULL;
202  switch(node->type) {
203  case amxp_expr_value:
204  if((node->left.value == NULL) ||
205  (amxc_var_type_of(node->left.value) == AMXC_VAR_ID_LIST)) {
206  if(node->left.value == NULL) {
207  amxc_var_new(&node->left.value);
208  }
209  value = node->left.value;
210  amxc_llist_clean(&value->data.vl, NULL);
211  amxp_expr_node_build_args(expr, value, &node->right.args);
212  } else {
213  value = node->left.value;
214  }
215  break;
216  case amxp_expr_field:
217  if(node->value == NULL) {
218  amxc_var_new(&node->value);
219  }
220  amxp_expr_get_field(expr, node->value, node->left.field);
221  if(expr->status == amxp_expr_status_ok) {
222  value = node->value;
223  } else {
224  amxc_var_set_type(node->value, AMXC_VAR_ID_NULL);
225  value = node->value;
226  }
227  break;
228  case amxp_expr_value_func: {
229  amxc_var_t args;
230  amxc_var_init(&args);
231  amxp_expr_node_build_args(expr, &args, &node->right.args);
232  if(node->value == NULL) {
233  amxc_var_new(&node->value);
234  }
235  amxp_expr_call_value_func(expr, node->left.func_name, &args, node->value);
236  amxc_llist_clean(&args.data.vl, NULL);
237  value = node->value;
238  }
239  break;
240  default:
241  break;
242  }
243 
244  return value;
245 }
PRIVATE amxp_expr_status_t amxp_expr_call_value_func(amxp_expr_t *expr, const char *func, amxc_var_t *args, amxc_var_t *ret)

◆ amxp_expr_node_new()

void amxp_expr_node_new ( amxp_expr_node_t **  node,
amxp_expr_node_type_t  type 
)

Definition at line 99 of file amxp_expression_node.c.

99  {
100  *node = (amxp_expr_node_t*) calloc(1, sizeof(amxp_expr_node_t));
101  (*node)->type = type;
102 }

◆ amxp_expr_node_pop()

amxp_expr_node_t* amxp_expr_node_pop ( amxc_lstack_t *  stack)

Definition at line 148 of file amxp_expression_node.c.

148  {
149  amxp_expr_node_t* node = NULL;
150  amxc_lstack_it_t* it = amxc_lstack_pop(stack);
151 
152  when_null(it, exit);
153  node = amxc_container_of(it, amxp_expr_node_t, it);
154 
155 exit:
156  return node;
157 }

◆ amxp_expr_node_push()

void amxp_expr_node_push ( amxc_lstack_t *  stack,
amxp_expr_node_t node 
)

Definition at line 144 of file amxp_expression_node.c.

144  {
145  amxc_lstack_push(stack, &node->it);
146 }

◆ amxp_expr_node_set_compop()

void amxp_expr_node_set_compop ( amxp_expr_node_t node,
amxp_expr_comp_t  comop 
)

Definition at line 181 of file amxp_expression_node.c.

181  {
182  node->compare = comop;
183 }

◆ amxp_expr_node_set_field()

void amxp_expr_node_set_field ( amxp_expr_node_t node,
char *  field 
)

Definition at line 177 of file amxp_expression_node.c.

177  {
178  node->left.field = field;
179 }

◆ amxp_expr_node_set_function()

void amxp_expr_node_set_function ( amxp_expr_node_t node,
char *  func_name 
)

Definition at line 173 of file amxp_expression_node.c.

173  {
174  node->left.func_name = func_name;
175 }

◆ amxp_expr_node_set_left()

void amxp_expr_node_set_left ( amxp_expr_node_t node,
amxp_expr_node_t left 
)

Definition at line 159 of file amxp_expression_node.c.

159  {
160  node->left.node = left;
161  amxc_llist_it_take(&left->it);
162 }

◆ amxp_expr_node_set_right()

void amxp_expr_node_set_right ( amxp_expr_node_t node,
amxp_expr_node_t right 
)

Definition at line 164 of file amxp_expression_node.c.

164  {
165  node->right.node = right;
166  amxc_llist_it_take(&right->it);
167 }

◆ amxp_expr_node_set_value()

void amxp_expr_node_set_value ( amxp_expr_node_t node,
amxc_var_t *  value 
)

Definition at line 169 of file amxp_expression_node.c.

169  {
170  node->left.value = value;
171 }