59 #include <sys/resource.h>
67 #include <amxc/amxc.h>
68 #include <amxc/amxc_macros.h>
74 const amxc_var_t*
var;
80 amxc_string_delete(&c->
path);
85 const amxc_var_t* var,
89 amxc_string_new(&c->
path, 0);
90 amxc_string_setf(c->
path,
"%s",
path);
93 amxc_llist_append(vars, &c->
it);
100 const char* sep = amxc_string_is_empty(
path) ?
"" :
".";
102 amxc_string_appendf(
path,
"%s'%s'", sep, name);
104 amxc_string_appendf(
path,
"%s%d", sep, index);
110 bool isindex =
false;
112 amxc_var_t* temp = NULL;
114 index = strtol(token, &endptr, 0);
116 temp = amxc_var_get_index(c->
var, index, AMXC_VAR_FLAG_DEFAULT);
119 temp = amxc_var_get_key(c->
var, token, AMXC_VAR_FLAG_DEFAULT);
128 amxc_llist_it_take(&c->
it);
134 const char* base_path,
137 amxc_llist_t* new_entries,
142 if(token[0] ==
'*') {
154 amxc_llist_t* new_entries,
156 const amxc_llist_t* items = amxc_var_constcast(amxc_llist_t,
current->var);
157 const char*
base = amxc_string_get(
current->path, 0);
161 if(token[0] ==
'[') {
164 amxc_llist_iterate(it, items) {
165 amxc_var_t* item = amxc_var_from_llist_it(it);
172 if(token[0] ==
'*') {
174 current->var = amxc_var_get_index(
current->var, 0, AMXC_VAR_FLAG_DEFAULT);
176 amxc_var_t* item = amxc_var_get_index(
current->var, 0, AMXC_VAR_FLAG_DEFAULT);
178 amxc_llist_it_take(&
current->it);
186 if(token[0] ==
'[') {
192 amxc_llist_t* new_entries,
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);
199 if(token[0] ==
'[') {
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);
213 if(token[0] ==
'*') {
215 current->var = amxc_var_get_key(
current->var, first, AMXC_VAR_FLAG_DEFAULT);
217 amxc_var_t* item = amxc_var_get_key(
current->var, first, AMXC_VAR_FLAG_DEFAULT);
219 amxc_llist_it_take(&
current->it);
227 if(token[0] ==
'[') {
233 amxc_llist_t* new_entries,
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);
243 if(amxc_var_type_of(
current->var) == AMXC_VAR_ID_LIST) {
254 size_t len = amxc_string_text_length(part);
256 char* token = amxc_string_take_buffer(part);
257 amxc_llist_t new_entries;
258 amxc_llist_init(&new_entries);
260 if((token[0] ==
'\'') || (token[0] ==
'"') || (token[0] ==
'[')) {
265 amxc_llist_for_each(it1, vars) {
268 if((token[0] ==
'*') || (token[0] ==
'[')) {
277 amxc_llist_for_each(it2, &new_entries) {
278 amxc_llist_append(vars, it2);
284 static void var_collect(amxc_llist_t* vars, amxc_llist_t* parts) {
285 amxc_llist_for_each(it, parts) {
286 amxc_string_t* part = amxc_container_of(it, amxc_string_t, it);
288 amxc_string_delete(&part);
294 amxc_string_t search_path;
295 amxc_string_init(&search_path, 0);
297 amxc_string_set(&search_path,
path);
298 amxc_string_trim(&search_path, NULL);
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);
311 amxc_string_clean(&search_path);
316 const amxc_var_t*
const data,
319 when_null(data, exit);
320 when_true(amxc_var_type_of(data) != AMXC_VAR_ID_HTABLE, exit);
333 amxc_var_t* data = (amxc_var_t*) priv;
334 amxc_var_t* field = NULL;
337 field = amxc_var_get_path(data,
path + 1, AMXC_VAR_FLAG_DEFAULT);
339 field = amxc_var_get_path(data,
path, AMXC_VAR_FLAG_DEFAULT);
341 if(amxc_var_copy(value, field) == 0) {
355 amxc_llist_init(&parts);
356 amxc_llist_init(&vars);
358 when_null(var, exit);
359 when_null(paths, exit);
360 when_str_empty(
path, exit);
363 when_failed(retval, exit);
367 amxc_llist_for_each(it, &vars) {
369 amxc_llist_append(paths, &c->
path->it);
374 amxc_llist_clean(&parts, amxc_string_list_it_free);
380 amxc_htable_t* values,
386 amxc_llist_init(&parts);
387 amxc_llist_init(&vars);
389 when_null(var, exit);
390 when_null(values, exit);
391 when_str_empty(
path, exit);
394 when_failed(retval, exit);
398 amxc_llist_for_each(it, &vars) {
400 amxc_var_t* value = NULL;
401 amxc_var_new(&value);
402 amxc_var_copy(value, c->
var);
403 amxc_htable_insert(values, amxc_string_get(c->
path, 0), &value->hit);
407 amxc_llist_clean(&parts, amxc_string_list_it_free);
414 const amxc_var_t* retval = NULL;
420 amxc_llist_init(&parts);
421 amxc_llist_init(&vars);
423 when_null(var, exit);
424 when_str_empty(
path, exit);
427 when_failed(rv, exit);
432 if(amxc_llist_is_empty(&vars)) {
436 first = amxc_container_of(amxc_llist_get_first(&vars),
var_collector_t, it);
437 if((first == NULL) || (amxc_llist_it_get_next(&first->
it) != NULL)) {
444 amxc_llist_clean(&parts, amxc_string_list_it_free);
446 return (amxc_var_t*) retval;
static void var_update_filtered_table(var_collector_t *current, amxc_llist_t *new_entries, const char *token)
static int var_build_parts(amxc_llist_t *parts, const char *path)
static void var_collector_it_free(amxc_llist_it_t *it)
static void var_update_filtered(var_collector_t *current, amxc_llist_t *new_entries, 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)
struct _var_collector var_collector_t
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)
static void var_update_filtered_list(var_collector_t *current, amxc_llist_t *new_entries, const char *token)
amxp_expr_status_t amxp_expr_get_field_var(UNUSED amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)
static void var_update_entry(var_collector_t *c, 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 struct timeval current
static struct event_base * base
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.
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.
void amxp_expr_clean(amxp_expr_t *expr)
Clean-up the expression structure.
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.
amxp_expr_status_t amxp_expr_init(amxp_expr_t *expr, const char *expression)
Initializes an expression structure.
bool amxp_expr_evaluate(amxp_expr_t *expr, amxp_expr_get_field_t fn, void *priv, amxp_expr_status_t *status)
Evaluates an expression.
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.
enum _expr_status amxp_expr_status_t
Expression status/error codes.
@ amxp_expr_status_unknown_error
static amxc_string_t path