libamxp  1.4.0
Patterns C Implementation
amxp_expression_var.c File Reference
#include <sys/resource.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <regex.h>
#include <amxc/amxc.h>
#include <amxc/amxc_macros.h>
#include "amxp_expr_priv.h"

Go to the source code of this file.

Data Structures

struct  _var_collector
 

Macros

#define _GNU_SOURCE
 

Typedefs

typedef struct _var_collector var_collector_t
 

Functions

static void var_collector_it_free (amxc_llist_it_t *it)
 
static var_collector_tvar_collector_new (const char *path, const amxc_var_t *var, amxc_llist_t *vars)
 
static void var_path_add (amxc_string_t *path, const char *name, uint32_t index)
 
static void var_update_entry (var_collector_t *c, const char *token)
 
static void var_add_filtered_entry (amxc_var_t *item, const char *base_path, const char *token, amxp_expr_t *expr, amxc_llist_t *new_entries, const char *name, uint32_t index)
 
static void var_update_filtered_list (var_collector_t *current, amxc_llist_t *new_entries, const char *token)
 
static void var_update_filtered_table (var_collector_t *current, amxc_llist_t *new_entries, const char *token)
 
static void var_update_filtered (var_collector_t *current, amxc_llist_t *new_entries, const char *token)
 
static void var_update_collection (amxc_llist_t *vars, amxc_string_t *part)
 
static void var_collect (amxc_llist_t *vars, amxc_llist_t *parts)
 
static int var_build_parts (amxc_llist_t *parts, const char *path)
 
bool amxp_expr_eval_var (amxp_expr_t *expr, const amxc_var_t *const data, amxp_expr_status_t *status)
 Evaluates an expression against a composite variant. More...
 
amxp_expr_status_t amxp_expr_get_field_var (UNUSED amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)
 
int amxp_expr_find_var_paths (const amxc_var_t *const var, amxc_llist_t *paths, const char *path)
 Search matching variant paths in a composite variant. More...
 
int amxp_expr_find_var_values (const amxc_var_t *const var, amxc_htable_t *values, const char *path)
 Search matching variant paths in a composite variant. More...
 
amxc_var_t * amxp_expr_find_var (const amxc_var_t *const var, const char *path)
 Search a matching variant and returns a pointer to that variant. More...
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxp_expression_var.c.

Typedef Documentation

◆ var_collector_t

Function Documentation

◆ amxp_expr_get_field_var()

amxp_expr_status_t amxp_expr_get_field_var ( UNUSED amxp_expr_t expr,
amxc_var_t *  value,
const char *  path,
void *  priv 
)

Definition at line 328 of file amxp_expression_var.c.

331  {
333  amxc_var_t* data = (amxc_var_t*) priv;
334  amxc_var_t* field = NULL;
335 
336  if(path && (path[0] == '.')) {
337  field = amxc_var_get_path(data, path + 1, AMXC_VAR_FLAG_DEFAULT);
338  } else {
339  field = amxc_var_get_path(data, path, AMXC_VAR_FLAG_DEFAULT);
340  }
341  if(amxc_var_copy(value, field) == 0) {
342  status = amxp_expr_status_ok;
343  }
344 
345  return status;
346 }
enum _expr_status amxp_expr_status_t
Expression status/error codes.
@ amxp_expr_status_unknown_error
@ amxp_expr_status_ok
static amxc_string_t path

◆ var_add_filtered_entry()

static void var_add_filtered_entry ( amxc_var_t *  item,
const char *  base_path,
const char *  token,
amxp_expr_t expr,
amxc_llist_t *  new_entries,
const char *  name,
uint32_t  index 
)
static

Definition at line 133 of file amxp_expression_var.c.

139  {
140  var_collector_t* nc = NULL;
141 
142  if(token[0] == '*') {
143  nc = var_collector_new(base_path, item, new_entries);
144  var_path_add(nc->path, name, index);
145  } else {
146  if(amxp_expr_eval_var(expr, item, NULL)) {
147  nc = var_collector_new(base_path, item, new_entries);
148  var_path_add(nc->path, name, index);
149  }
150  }
151 }
static var_collector_t * var_collector_new(const char *path, const amxc_var_t *var, amxc_llist_t *vars)
static void var_path_add(amxc_string_t *path, const char *name, uint32_t index)
bool amxp_expr_eval_var(amxp_expr_t *expr, const amxc_var_t *const data, amxp_expr_status_t *status)
Evaluates an expression against a composite variant.
amxc_string_t * path

◆ var_build_parts()

static int var_build_parts ( amxc_llist_t *  parts,
const char *  path 
)
static

Definition at line 292 of file amxp_expression_var.c.

292  {
293  int retval = 0;
294  amxc_string_t search_path;
295  amxc_string_init(&search_path, 0);
296 
297  amxc_string_set(&search_path, path);
298  amxc_string_trim(&search_path, NULL);
299 
300  retval = amxc_string_split_to_llist(&search_path, parts, '.');
301  when_failed(retval, exit);
302  if((search_path.buffer != NULL) && (search_path.buffer[0] == '[')) {
303  amxc_string_t* fp = amxc_string_from_llist_it(amxc_llist_get_first(parts));
304  if((fp != NULL) && (fp->buffer != NULL) && (fp->buffer[0] != '[')) {
305  amxc_string_prepend(fp, "[", 1);
306  amxc_string_append(fp, "]", 1);
307  }
308  }
309 
310 exit:
311  amxc_string_clean(&search_path);
312  return retval;
313 }

◆ var_collect()

static void var_collect ( amxc_llist_t *  vars,
amxc_llist_t *  parts 
)
static

Definition at line 284 of file amxp_expression_var.c.

284  {
285  amxc_llist_for_each(it, parts) {
286  amxc_string_t* part = amxc_container_of(it, amxc_string_t, it);
287  var_update_collection(vars, part);
288  amxc_string_delete(&part);
289  }
290 }
static void var_update_collection(amxc_llist_t *vars, amxc_string_t *part)

◆ var_collector_it_free()

static void var_collector_it_free ( amxc_llist_it_t *  it)
static

Definition at line 78 of file amxp_expression_var.c.

78  {
79  var_collector_t* c = amxc_container_of(it, var_collector_t, it);
80  amxc_string_delete(&c->path);
81  free(c);
82 }

◆ var_collector_new()

static var_collector_t* var_collector_new ( const char *  path,
const amxc_var_t *  var,
amxc_llist_t *  vars 
)
static

Definition at line 84 of file amxp_expression_var.c.

86  {
87  var_collector_t* c = (var_collector_t*) calloc(1, sizeof(var_collector_t));
88  when_null(c, exit);
89  amxc_string_new(&c->path, 0);
90  amxc_string_setf(c->path, "%s", path);
91  c->var = var;
92 
93  amxc_llist_append(vars, &c->it);
94 
95 exit:
96  return c;
97 }
amxc_llist_it_t it
const amxc_var_t * var

◆ var_path_add()

static void var_path_add ( amxc_string_t *  path,
const char *  name,
uint32_t  index 
)
static

Definition at line 99 of file amxp_expression_var.c.

99  {
100  const char* sep = amxc_string_is_empty(path) ? "" : ".";
101  if(name != NULL) {
102  amxc_string_appendf(path, "%s'%s'", sep, name);
103  } else {
104  amxc_string_appendf(path, "%s%d", sep, index);
105  }
106 }

◆ var_update_collection()

static void var_update_collection ( amxc_llist_t *  vars,
amxc_string_t *  part 
)
static

Definition at line 253 of file amxp_expression_var.c.

253  {
254  size_t len = amxc_string_text_length(part);
255  uint32_t offset = 0;
256  char* token = amxc_string_take_buffer(part);
257  amxc_llist_t new_entries;
258  amxc_llist_init(&new_entries);
259 
260  if((token[0] == '\'') || (token[0] == '"') || (token[0] == '[')) {
261  token[len - 1] = 0;
262  offset = 1;
263  }
264 
265  amxc_llist_for_each(it1, vars) {
266  var_collector_t* c = amxc_container_of(it1, var_collector_t, it);
267 
268  if((token[0] == '*') || (token[0] == '[')) {
269  var_update_filtered(c, &new_entries, token);
270  } else {
271  var_update_entry(c, token + offset);
272  }
273 
274  c = NULL;
275  }
276 
277  amxc_llist_for_each(it2, &new_entries) {
278  amxc_llist_append(vars, it2);
279  }
280 
281  free(token);
282 }
static void var_update_filtered(var_collector_t *current, amxc_llist_t *new_entries, const char *token)
static void var_update_entry(var_collector_t *c, const char *token)

◆ var_update_entry()

static void var_update_entry ( var_collector_t c,
const char *  token 
)
static

Definition at line 108 of file amxp_expression_var.c.

108  {
109  int index = 0;
110  bool isindex = false;
111  char* endptr = NULL;
112  amxc_var_t* temp = NULL;
113 
114  index = strtol(token, &endptr, 0);
115  if(*endptr == 0) {
116  temp = amxc_var_get_index(c->var, index, AMXC_VAR_FLAG_DEFAULT);
117  }
118  if(temp == NULL) {
119  temp = amxc_var_get_key(c->var, token, AMXC_VAR_FLAG_DEFAULT);
120  } else {
121  isindex = true;
122  }
123 
124  if(temp != NULL) {
125  c->var = temp;
126  var_path_add(c->path, isindex ? NULL : token, index);
127  } else {
128  amxc_llist_it_take(&c->it);
130  }
131 }
static void var_collector_it_free(amxc_llist_it_t *it)

◆ var_update_filtered()

static void var_update_filtered ( var_collector_t current,
amxc_llist_t *  new_entries,
const char *  token 
)
static

Definition at line 232 of file amxp_expression_var.c.

234  {
235 
236  if((amxc_var_type_of(current->var) != AMXC_VAR_ID_HTABLE) &&
237  ( amxc_var_type_of(current->var) != AMXC_VAR_ID_LIST)) {
238  amxc_llist_it_take(&current->it);
240  goto exit;
241  }
242 
243  if(amxc_var_type_of(current->var) == AMXC_VAR_ID_LIST) {
244  var_update_filtered_list(current, new_entries, token);
245  } else {
246  var_update_filtered_table(current, new_entries, token);
247  }
248 
249 exit:
250  return;
251 }
static void var_update_filtered_table(var_collector_t *current, amxc_llist_t *new_entries, const char *token)
static void var_update_filtered_list(var_collector_t *current, amxc_llist_t *new_entries, const char *token)
static struct timeval current
Definition: amxp_timer.c:66

◆ var_update_filtered_list()

static void var_update_filtered_list ( var_collector_t current,
amxc_llist_t *  new_entries,
const char *  token 
)
static

Definition at line 153 of file amxp_expression_var.c.

155  {
156  const amxc_llist_t* items = amxc_var_constcast(amxc_llist_t, current->var);
157  const char* base = amxc_string_get(current->path, 0);
158  uint32_t index = 0;
159  amxp_expr_t expr;
160 
161  if(token[0] == '[') {
162  amxp_expr_init(&expr, token + 1);
163  }
164  amxc_llist_iterate(it, items) {
165  amxc_var_t* item = amxc_var_from_llist_it(it);
166  if(index != 0) {
167  var_add_filtered_entry(item, base, token, &expr, new_entries, NULL, index);
168  }
169  index++;
170  }
171 
172  if(token[0] == '*') {
173  var_path_add(current->path, NULL, 0);
174  current->var = amxc_var_get_index(current->var, 0, AMXC_VAR_FLAG_DEFAULT);
175  } else {
176  amxc_var_t* item = amxc_var_get_index(current->var, 0, AMXC_VAR_FLAG_DEFAULT);
177  if(!amxp_expr_eval_var(&expr, item, NULL)) {
178  amxc_llist_it_take(&current->it);
180  } else {
181  var_path_add(current->path, NULL, 0);
182  current->var = item;
183  }
184  }
185 
186  if(token[0] == '[') {
187  amxp_expr_clean(&expr);
188  }
189 }
static void var_add_filtered_entry(amxc_var_t *item, const char *base_path, const char *token, amxp_expr_t *expr, amxc_llist_t *new_entries, const char *name, uint32_t index)
static struct event_base * base
Definition: main.c:70
void amxp_expr_clean(amxp_expr_t *expr)
Clean-up the expression structure.
amxp_expr_status_t amxp_expr_init(amxp_expr_t *expr, const char *expression)
Initializes an expression structure.

◆ var_update_filtered_table()

static void var_update_filtered_table ( var_collector_t current,
amxc_llist_t *  new_entries,
const char *  token 
)
static

Definition at line 191 of file amxp_expression_var.c.

193  {
194  const amxc_htable_t* items = amxc_var_constcast(amxc_htable_t, current->var);
195  const char* first = NULL;
196  const char* base = amxc_string_get(current->path, 0);
197  amxp_expr_t expr;
198 
199  if(token[0] == '[') {
200  amxp_expr_init(&expr, token + 1);
201  }
202 
203  amxc_htable_iterate(it, items) {
204  const char* name = amxc_htable_it_get_key(it);
205  amxc_var_t* item = amxc_var_from_htable_it(it);
206  if(first != NULL) {
207  var_add_filtered_entry(item, base, token, &expr, new_entries, name, 0);
208  } else {
209  first = name;
210  }
211  }
212 
213  if(token[0] == '*') {
214  var_path_add(current->path, first, 0);
215  current->var = amxc_var_get_key(current->var, first, AMXC_VAR_FLAG_DEFAULT);
216  } else {
217  amxc_var_t* item = amxc_var_get_key(current->var, first, AMXC_VAR_FLAG_DEFAULT);
218  if(!amxp_expr_eval_var(&expr, item, NULL)) {
219  amxc_llist_it_take(&current->it);
221  } else {
222  var_path_add(current->path, first, 0);
223  current->var = item;
224  }
225  }
226 
227  if(token[0] == '[') {
228  amxp_expr_clean(&expr);
229  }
230 }