libamxp  1.4.0
Patterns C Implementation
Expressions

Logical expression parser and evaluator. More...

Typedefs

typedef enum _expr_status amxp_expr_status_t
 Expression status/error codes. More...
 
typedef ssize_t(* amxp_expr_reader_t) (amxp_expr_t *expr, void *buf, size_t max_size)
 Expression reader function. More...
 
typedef amxp_expr_status_t(* amxp_expr_get_field_t) (amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)
 Field fetcher function signature. More...
 
typedef amxp_expr_status_t(* amxp_expr_value_func_t) (amxp_expr_t *expr, amxc_var_t *args, amxc_var_t *ret)
 Callback function that can "calculate" a value. More...
 
typedef bool(* amxp_expr_bool_func_t) (amxp_expr_t *expr, amxc_var_t *args)
 Callback function that evaluates to true or false. More...
 

Enumerations

enum  _expr_status {
  amxp_expr_status_ok , amxp_expr_status_unknown_error , amxp_expr_status_syntax_error , amxp_expr_status_field_not_found ,
  amxp_expr_status_invalid_regexp , amxp_expr_status_invalid_value , amxp_expr_status_function_not_found
}
 Expression status/error codes. More...
 

Functions

amxp_expr_status_t amxp_expr_new (amxp_expr_t **expr, const char *expression)
 Allocates and initializes an expression. More...
 
amxp_expr_status_t amxp_expr_buildf_new (amxp_expr_t **expr, const char *expr_fmt,...) __attribute__((format(printf
 Allocates and initializes an expression with format-string and safety checks. More...
 
amxp_expr_status_t amxp_expr_status_t amxp_expr_vbuildf_new (amxp_expr_t **expr, const char *expr_fmt, va_list args)
 va_list version of amxp_expr_buildf_new More...
 
void amxp_expr_delete (amxp_expr_t **expr)
 Deletes a previously allocated expression structure. More...
 
amxp_expr_status_t amxp_expr_buildf (amxp_expr_t *expr, const char *expr_fmt,...) __attribute__((format(printf
 Initializes an expression structure. More...
 
amxp_expr_status_t amxp_expr_status_t amxp_expr_vbuildf (amxp_expr_t *expr, const char *expr_fmt, va_list args)
 va_list version of amxp_expr_buildf More...
 
amxp_expr_status_t amxp_expr_init (amxp_expr_t *expr, const char *expression)
 Initializes an expression structure. More...
 
void amxp_expr_clean (amxp_expr_t *expr)
 Clean-up the expression structure. More...
 
void amxp_expr_dump_tree (amxp_expr_t *expr)
 Dumps the binary tree in dot formatted text file to stdout. More...
 
bool amxp_expr_evaluate (amxp_expr_t *expr, amxp_expr_get_field_t fn, void *priv, amxp_expr_status_t *status)
 Evaluates an expression. More...
 
bool amxp_expr_eval (amxp_expr_t *expr, amxp_expr_status_t *status)
 Evaluates an expression. More...
 
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...
 
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...
 
amxp_expr_status_t amxp_expr_get_field_var (amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)
 Variant field fetcher implementation. More...
 
bool amxp_expr_eval_set (amxp_expr_t *expr, const amxc_set_t *const data, amxp_expr_status_t *status)
 Evaluates an expression against a set. More...
 
amxp_expr_status_t amxp_expr_get_field_set (amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)
 Flag field fetcher implementation for sets. More...
 
int amxp_expr_add_value_fn (const char *fn_name, amxp_expr_value_func_t fn)
 Adds a value calculation function. More...
 
int amxp_expr_add_bool_fn (const char *fn_name, amxp_expr_bool_func_t fn)
 Adds a boolean evaluation function. More...
 
const char * amxp_expr_get_string (amxp_expr_t *expr)
 Returns the string representation of the given expression. More...
 

Detailed Description

Logical expression parser and evaluator.

An logical expression evaluates to true or to false.

An expression can consist out of multiple expression parts, concatenated with a logical "OR" or logical "AND"

Syntax of an expression part

VALUE COMPARE OPERATOR VALUE

Each expression part has compare operator, a left value and a right value.

An VALUE can be:

Boolean values are case insensitive. There will be a match for true, True or even TrUe. The same comment applies to false.

The supported COMPARE OPERATORS are:

Supported logical operators:

Example
first_name in ['Tess', 'Olivia', 'Abraham'] && age < 25

Typedef Documentation

◆ amxp_expr_bool_func_t

typedef bool(* amxp_expr_bool_func_t) (amxp_expr_t *expr, amxc_var_t *args)

Callback function that evaluates to true or false.

Not all values can be expressed as a field or a constant, sometimes more complex operations are used. It is possible to define custom boolean method that evaluates the provided arguments and returns true or false.

Boolean functions can be used in any location in an expression when a logical expression is needed.

Parameters
exprpointer to the expression structure
argsvariant containing the arguments of the function
Returns
Returns true or false

Definition at line 240 of file amxp_expression.h.

◆ amxp_expr_get_field_t

typedef amxp_expr_status_t(* amxp_expr_get_field_t) (amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)

Field fetcher function signature.

An logical expression with only constant values is not very usefull.

A field fetcher function can be implemented and is used during the expression evaluation to get values for the fields used in the expression.

Depending on the situation or the specific problem a custom field fetcher is needed. When using libamxc variants as data, the field fetcher amxp_expr_get_field_var can be used.

Parameters
exprpointer to the expression structure
valuethe variant in which the value must be stored
paththe field
privthe private user data
Returns
An expression status, should be amxp_expr_status_ok when the value for the field was fetched correctly.

Definition at line 193 of file amxp_expression.h.

◆ amxp_expr_reader_t

typedef ssize_t(* amxp_expr_reader_t) (amxp_expr_t *expr, void *buf, size_t max_size)

Expression reader function.

A ringbuffer is used to store the expression and read from it during parsing of the expression.

Currently it is not possible to implement a custom reader function and set that function pointer.

Definition at line 166 of file amxp_expression.h.

◆ amxp_expr_status_t

Expression status/error codes.

◆ amxp_expr_value_func_t

typedef amxp_expr_status_t(* amxp_expr_value_func_t) (amxp_expr_t *expr, amxc_var_t *args, amxc_var_t *ret)

Callback function that can "calculate" a value.

Not all values can be expressed as a field or a constant, sometimes more complex operations are used. It is possible to define custom value calculation methods and register them using amxp_expr_add_value_fn.

Value functions can be used in any location in an expression where a value is needed.

Parameters
exprpointer to the expression structure
argsvariant containing the arguments of the function
retThe calculated value
Returns
An expression status, should be amxp_expr_status_ok when the value is calculated successfull.

Definition at line 218 of file amxp_expression.h.

Enumeration Type Documentation

◆ _expr_status

Expression status/error codes.

Enumerator
amxp_expr_status_ok 

No error, all ok

amxp_expr_status_unknown_error 

Unknown error

amxp_expr_status_syntax_error 

Expression has incorrect syntax

amxp_expr_status_field_not_found 

Value field is not found

amxp_expr_status_invalid_regexp 

Invalid regular expression provided (matches)

amxp_expr_status_invalid_value 

Invalid value provided

amxp_expr_status_function_not_found 

Function not found

Definition at line 144 of file amxp_expression.h.

144  {
enum _expr_status amxp_expr_status_t
Expression status/error codes.
@ amxp_expr_status_syntax_error
@ amxp_expr_status_invalid_value
@ amxp_expr_status_field_not_found
@ amxp_expr_status_unknown_error
@ amxp_expr_status_ok
@ amxp_expr_status_function_not_found
@ amxp_expr_status_invalid_regexp

Function Documentation

◆ amxp_expr_add_bool_fn()

int amxp_expr_add_bool_fn ( const char *  fn_name,
amxp_expr_bool_func_t  fn 
)

Adds a boolean evaluation function.

Adds a callback function with a given name to the possible boolean evaluation functions.

Parameters
fn_namename of the function with which it can be used in the expressions
fnthe function pointer and must match amxp_expr_bool_func_t signature
Returns
0 when the function is added, any other value otherwise

Definition at line 838 of file amxp_expression_main.c.

839  {
840  int retval = -1;
841  amxp_expr_bfunc_t* bfn = NULL;
842 
843  if(amxc_htable_capacity(&bool_funcs) == 0) {
844  amxc_htable_init(&bool_funcs, 5);
845  }
846 
847  when_true(amxc_htable_contains(&bool_funcs, fn_name), exit);
848  bfn = (amxp_expr_bfunc_t*) calloc(1, sizeof(amxp_expr_bfunc_t));
849  when_null(bfn, exit);
850  bfn->fn = fn;
851  retval = amxc_htable_insert(&bool_funcs, fn_name, &bfn->hit);
852 
853 exit:
854  return retval;
855 }
static amxc_htable_t bool_funcs
amxp_expr_bool_func_t fn
amxc_htable_it_t hit

◆ amxp_expr_add_value_fn()

int amxp_expr_add_value_fn ( const char *  fn_name,
amxp_expr_value_func_t  fn 
)

Adds a value calculation function.

Adds a callback function with a given name to the possible value calculation functions.

Parameters
fn_namename of the function with which it can be used in the expressions
fnthe function pointer and must match amxp_expr_value_func_t signature
Returns
0 when the function is added, any other value otherwise

Definition at line 820 of file amxp_expression_main.c.

821  {
822  int retval = -1;
823  amxp_expr_vfunc_t* vfn = NULL;
824 
825  if(amxc_htable_capacity(&value_funcs) == 0) {
826  amxc_htable_init(&value_funcs, 5);
827  }
828  when_true(amxc_htable_contains(&value_funcs, fn_name), exit);
829  vfn = (amxp_expr_vfunc_t*) calloc(1, sizeof(amxp_expr_vfunc_t));
830  when_null(vfn, exit);
831  vfn->fn = fn;
832  retval = amxc_htable_insert(&value_funcs, fn_name, &vfn->hit);
833 
834 exit:
835  return retval;
836 }
static amxc_htable_t value_funcs
amxp_expr_value_func_t fn
amxc_htable_it_t hit

◆ amxp_expr_buildf()

amxp_expr_status_t amxp_expr_buildf ( amxp_expr_t expr,
const char *  expr_fmt,
  ... 
)

Initializes an expression structure.

The same as amxp_expr_buildf_new but without new heap-allocation.

Note
Make sure that amxp_expr_clean (and not amxp_expr_delete) is called when the expression is not needed anymore. It is possible that the expression parser allocates memory at initialization time, which must be freed when the expression is not needed anymore.
Parameters
expra pointer to the location where the pointer to the new expression can be stored
expr_fmta string containing a logical expression with placeholders.
Returns
amxp_expr_status_ok if memory is allocated and the given expression is valid (syntax). When an error occurred the function will return any of the amxp_expr_status_t values

◆ amxp_expr_buildf_new()

amxp_expr_status_t amxp_expr_buildf_new ( amxp_expr_t **  expr,
const char *  expr_fmt,
  ... 
)

Allocates and initializes an expression with format-string and safety checks.

Allocates memory on the heap to store the expression data structure.

The provided expression format string and the replacement values are used to build the expression string. In the expression format string the nth placeholders is replaced with the nth replacement value in the variadic arguments (...).

The supported placeholders ('s', 'i', ...) are the ones supported by amxc_string_appendf_escape.

Example of a expression format string:

"password == '%s' and user == '%s'"

When the variadic arguments are:

["mypassword","admin"]

The expression string that is build will be:

"password == 'mypassword' and user == 'admin'"

Each value in the values variant is verified to avoid the expression, or the context of the expression, being interpreted in an unintended way.

Example of invalid values:

["mypassword' or true or '' = '", "admin"]

This would resolve into the following expression string:

"password == 'mypassword' or true or '' = '' and user == 'admin'"

Which is not the intention, so the first value is considered invalid and the expression build will fail.

The builded expression string is parsed and stored for later use. When the expression is invalid an error is returned and no memory is allocated.

Once an expression structure is available, it can be reused many times.

Note
The allocated memory must be freed when not used anymore, use amxp_expr_delete to free the memory
Parameters
expra pointer to the location where the pointer to the new expression can be stored
expr_fmta string containing a logical expression with placeholders.
Returns
amxp_expr_status_ok if memory is allocated and the given expression is valid (syntax). When an error occurred the function will return any of the amxp_expr_status_t values

◆ amxp_expr_clean()

void amxp_expr_clean ( amxp_expr_t expr)

Clean-up the expression structure.

Cleans up all internally allocated memory. After calling this function the expression data structure must be re-initialized before use.

Parameters
expra pointer to the expression structure

Definition at line 766 of file amxp_expression_main.c.

766  {
767  amxp_expr_node_t* node = NULL;
768  when_null(expr, exit);
769 
770  free(expr->expression);
771  expr->expression = NULL;
772 
773  node = amxp_expr_get_node(expr);
774  amxp_expr_node_delete(&node);
775  amxc_lstack_clean(&expr->nodes, NULL);
776  amxc_rbuffer_clean(&expr->rbuffer);
777  amxc_string_clean(&expr->msg);
778 
779 exit:
780  return;
781 }
PRIVATE amxp_expr_node_t * amxp_expr_get_node(amxp_expr_t *expr)
PRIVATE void amxp_expr_node_delete(amxp_expr_node_t **node)
char * expression
amxc_rbuffer_t rbuffer
amxc_string_t msg
amxc_lstack_t nodes

◆ amxp_expr_delete()

void amxp_expr_delete ( amxp_expr_t **  expr)

Deletes a previously allocated expression structure.

Frees memory previously allocated.

Parameters
expra pointer to the location where the pointer to the allocated expression

Definition at line 652 of file amxp_expression_main.c.

652  {
653  when_null(expr, exit);
654  when_null(*expr, exit);
655 
656  amxp_expr_clean(*expr);
657  free(*expr);
658  *expr = NULL;
659 
660 exit:
661  return;
662 }
void amxp_expr_clean(amxp_expr_t *expr)
Clean-up the expression structure.

◆ amxp_expr_dump_tree()

void amxp_expr_dump_tree ( amxp_expr_t expr)

Dumps the binary tree in dot formatted text file to stdout.

Using the output as input to the dot tool a graph can be created the represents the builded binary tree by the expression parser.

Parameters
expra pointer to the expression structure

Definition at line 783 of file amxp_expression_main.c.

783  {
784  amxp_expr_node_dump(expr, amxp_expr_get_node(expr), 0, 0);
785 }
PRIVATE void amxp_expr_node_dump(amxp_expr_t *expr, amxp_expr_node_t *node, uint32_t level, uint32_t parent_id)

◆ amxp_expr_eval()

bool amxp_expr_eval ( amxp_expr_t expr,
amxp_expr_status_t status 
)

Evaluates an expression.

Calls amxp_expr_evaluate without a field fetcher callback function.

Can only be used with expressions that don't contain any fields

Parameters
expra pointer to the expression structure
statuswill contain the status code,
Returns
  • true when the expression evaluates to true (status will be amxp_expr_status_ok)
  • false when the expression evaluates to false (status can be an error code)

Definition at line 816 of file amxp_expression_main.c.

816  {
817  return amxp_expr_evaluate(expr, NULL, NULL, status);
818 }
bool amxp_expr_evaluate(amxp_expr_t *expr, amxp_expr_get_field_t fn, void *priv, amxp_expr_status_t *status)
Evaluates an expression.

◆ amxp_expr_eval_set()

bool amxp_expr_eval_set ( amxp_expr_t expr,
const amxc_set_t *const  data,
amxp_expr_status_t status 
)

Evaluates an expression against a set.

Calls amxp_expr_evaluate with a field fetcher callback function (see amxp_expr_get_field_set) The values of the fields in the expression are flags that are or are not in the given set.

Parameters
expra pointer to the expression structure
dataa set
statuswill contain the status code,
Returns
  • true when the expression evaluates to true
  • false when the expression evaluates to false

Definition at line 59 of file amxp_expression_set.c.

61  {
62  bool rv = false;
63  when_null(data, exit);
64 
65  rv = amxp_expr_evaluate(expr, amxp_expr_get_field_set, (void*) data, status);
66 
67 exit:
68  return rv;
69 }
amxp_expr_status_t amxp_expr_get_field_set(UNUSED amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)

◆ amxp_expr_eval_var()

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.

Calls amxp_expr_evaluate with a field fetcher callback function (see amxp_expr_get_field_var) The values of the fields in the expression are fetched from the given variant.

Parameters
expra pointer to the expression structure
dataa variant
statuswill contain the status code,
Returns
  • true when the expression evaluates to true (status will be amxp_expr_status_ok)
  • false when the expression evaluates to false (status can be an error code)

Definition at line 315 of file amxp_expression_var.c.

317  {
318  bool rv = false;
319  when_null(data, exit);
320  when_true(amxc_var_type_of(data) != AMXC_VAR_ID_HTABLE, exit);
321 
322  rv = amxp_expr_evaluate(expr, amxp_expr_get_field_var, (void*) data, status);
323 
324 exit:
325  return rv;
326 }
amxp_expr_status_t amxp_expr_get_field_var(UNUSED amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)

◆ amxp_expr_evaluate()

bool amxp_expr_evaluate ( amxp_expr_t expr,
amxp_expr_get_field_t  fn,
void *  priv,
amxp_expr_status_t status 
)

Evaluates an expression.

If the expression provided (see amxp_expr_init or amxp_expr_new) contains fields, the field fetcher callback is called for each field encountered in the expression. The field fetcher callback function must return the value represented by the field.

How the field fetcher works depends on the implementation.

If no field fetcher callback is set and the expression contains fields, the expression will evaluate to false and the status code is set to amxp_expr_status_field_not_found.

Note
When an error occurs while evaluating the expression the return value will be false, check the status parameter to get the error code.
Parameters
expra pointer to the expression structure
fna field fetcher callback function.
privprivate data pointer, is passed as is to the field fetcher callback function
statuswill contain the status code,
Returns
  • true when the expression evaluates to true (status will be amxp_expr_status_ok)
  • false when the expression evaluates to false (status can be an error code)

Definition at line 787 of file amxp_expression_main.c.

790  {
791  bool rv = true;
792  amxp_expr_node_t* node = NULL;
793 
794  when_null_status(expr, exit, rv = false);
795 
796  expr->get_field = fn;
797  expr->priv = priv;
798 
799  node = amxp_expr_get_node(expr);
800  if(node == NULL) {
801  if(expr->status != amxp_expr_status_ok) {
802  rv = false;
803  }
804  } else {
805  rv = amxp_expr_node_eval(expr, node);
806  }
807 
808  if((status != NULL) && (expr != NULL)) {
809  *status = expr->status;
810  }
811 
812 exit:
813  return rv;
814 }
PRIVATE bool amxp_expr_node_eval(amxp_expr_t *expr, amxp_expr_node_t *node)
amxp_expr_get_field_t get_field
amxp_expr_status_t status

◆ amxp_expr_find_var()

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.

Using expressions or a wildcard '*' at the position of a list variant or a table variant the mathcing variants are filtered out. The expressions must be put between square brackets.

When multiple variants are matching the path, a NULL pointer is returned.

When multiple variants paths can match you can use amxp_expr_find_var_values or amxp_expr_find_var_paths instead.

Parameters
varthe composite variant
paththe variant path, it may contain wildcards or expressions
Returns
NULL when zero or more then one variants are matching, or a pointer to a variant is there is exactly one matching.

Definition at line 412 of file amxp_expression_var.c.

413  {
414  const amxc_var_t* retval = NULL;
415  int rv = 0;
416  var_collector_t* first = NULL;
417  amxc_llist_t parts;
418  amxc_llist_t vars;
419 
420  amxc_llist_init(&parts);
421  amxc_llist_init(&vars);
422 
423  when_null(var, exit);
424  when_str_empty(path, exit);
425 
426  rv = var_build_parts(&parts, path);
427  when_failed(rv, exit);
428 
429  var_collector_new("", var, &vars);
430  var_collect(&vars, &parts);
431 
432  if(amxc_llist_is_empty(&vars)) {
433  goto exit;
434  }
435 
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)) {
438  goto exit;
439  }
440 
441  retval = first->var;
442 
443 exit:
444  amxc_llist_clean(&parts, amxc_string_list_it_free);
445  amxc_llist_clean(&vars, var_collector_it_free);
446  return (amxc_var_t*) retval;
447 }
static int var_build_parts(amxc_llist_t *parts, const char *path)
static void var_collector_it_free(amxc_llist_it_t *it)
static var_collector_t * var_collector_new(const char *path, const amxc_var_t *var, amxc_llist_t *vars)
static void var_collect(amxc_llist_t *vars, amxc_llist_t *parts)
amxc_llist_it_t it
const amxc_var_t * var
static amxc_string_t path

◆ amxp_expr_find_var_paths()

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.

Using expressions or a wildcard '*' at the position of a list variant or a table variant the mathcing variants are filtered out. The expressions must be put between square brackets.

All matching variant paths are added to the linked list. The value of each matching variant can be fetched using the GET macros provided in libamxc

Example:

Data set in json notation

{
"00:01:02:03:44:f0": [
],
"94:83:c4:06:da:66": [
{
"Extender": true,
"MACAddress": "00:01:02:03:44:f0"
},
{
"Extender": false,
"MACAddress" : "00:00:55:3b:05",
}
]
}

Search path: "94:83:c4:06:da:66.[MACAddress == '00:01:02:03:44:f0'].Extender" Result: ["'94:83:c4:06:da:66'.0.'Extender'"]

Search path: "94:83:c4:06:da:66.*.Extender" Result: ["'94:83:c4:06:da:66'.0.'Extender'", "'94:83:c4:06:da:66'.1.'Extender'"]

Parameters
varthe composite variant
pathsa linked list that will be filled with all paths to the variants that match
paththe variant path, it may contain wildcards or expressions
Returns
0 when successfull, any other value indicates an error.

Definition at line 348 of file amxp_expression_var.c.

350  {
351  int retval = 0;
352  amxc_llist_t parts;
353  amxc_llist_t vars;
354 
355  amxc_llist_init(&parts);
356  amxc_llist_init(&vars);
357 
358  when_null(var, exit);
359  when_null(paths, exit);
360  when_str_empty(path, exit);
361 
362  retval = var_build_parts(&parts, path);
363  when_failed(retval, exit);
364  var_collector_new("", var, &vars);
365  var_collect(&vars, &parts);
366 
367  amxc_llist_for_each(it, &vars) {
368  var_collector_t* c = amxc_container_of(it, var_collector_t, it);
369  amxc_llist_append(paths, &c->path->it);
370  c->path = NULL;
371  }
372 
373 exit:
374  amxc_llist_clean(&parts, amxc_string_list_it_free);
375  amxc_llist_clean(&vars, var_collector_it_free);
376  return retval;
377 }
amxc_string_t * path

◆ amxp_expr_find_var_values()

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.

Using expressions or a wildcard '*' at the position of a list variant or a table variant the mathcing variants are filtered out. The expressions must be put between square brackets.

All matching variant paths are added to the hash table. The keys in the table are the matching variant paths, the values are copies of the mathcing variants.

Example:

Data set in json notation

{
"00:01:02:03:44:f0": [
],
"94:83:c4:06:da:66": [
{
"Extender": true,
"MACAddress": "00:01:02:03:44:f0"
},
{
"Extender": false,
"MACAddress" : "00:00:55:3b:05",
}
]
}

Search path: "94:83:c4:06:da:66.[MACAddress == '00:01:02:03:44:f0'].Extender" Result: {"'94:83:c4:06:da:66'.0.'Extender'" = true}

Search path: "94:83:c4:06:da:66.*.Extender" Result: {"'94:83:c4:06:da:66'.0.'Extender'" = true, "'94:83:c4:06:da:66'.1.'Extender'" = false }

Parameters
varthe composite variant
valuesa htable that will be filled with all paths and values of the variants that match the given path
paththe variant path, it may contain wildcards or expressions
Returns
0 when successfull, any other value indicates an error.

Definition at line 379 of file amxp_expression_var.c.

381  {
382  int retval = 0;
383  amxc_llist_t parts;
384  amxc_llist_t vars;
385 
386  amxc_llist_init(&parts);
387  amxc_llist_init(&vars);
388 
389  when_null(var, exit);
390  when_null(values, exit);
391  when_str_empty(path, exit);
392 
393  retval = var_build_parts(&parts, path);
394  when_failed(retval, exit);
395  var_collector_new("", var, &vars);
396  var_collect(&vars, &parts);
397 
398  amxc_llist_for_each(it, &vars) {
399  var_collector_t* c = amxc_container_of(it, var_collector_t, it);
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);
404  }
405 
406 exit:
407  amxc_llist_clean(&parts, amxc_string_list_it_free);
408  amxc_llist_clean(&vars, var_collector_it_free);
409  return retval;
410 }

◆ amxp_expr_get_field_set()

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

Flag field fetcher implementation for sets.

Used by amxp_expr_eval_set. This function should not be called directly.

Parameters
expra pointer to the expression structure
valuethe value of the field, filled by this function
paththe flag name
privthe private data as provided to amxp_expr_evaluate
Returns
The status code

◆ amxp_expr_get_field_var()

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

Variant field fetcher implementation.

Used by amxp_expr_eval_var. This function should not be called directly.

Parameters
expra pointer to the expression structure
valuethe value of the field, filled by this function
paththe field name
privthe private data as provided to amxp_expr_evaluate
Returns
The status code

◆ amxp_expr_get_string()

const char* amxp_expr_get_string ( amxp_expr_t expr)

Returns the string representation of the given expression.

Parameters
expra pointer to the expression structure
Returns
The string representation of the expression, or NULL if there is none.

Definition at line 857 of file amxp_expression_main.c.

857  {
858  return expr ? expr->expression : NULL;
859 }

◆ amxp_expr_init()

amxp_expr_status_t amxp_expr_init ( amxp_expr_t expr,
const char *  expression 
)

Initializes an expression structure.

The provided expression is parsed and stored for later use. When the expression is invalid an error is returned.

Once an expression structure is initialized, it can be reused many times.

Note
Make sure that amxp_expr_clean is called when the expression is not needed anymore. It is possible that the expression parser allocates memory at initialization time, which must be freed when the expression is not needed anymore.
Parameters
expra pointer to the expression structure
expressiona string containing a logical expression.
Returns
amxp_expr_status_ok if the given expression is valid (syntax). When an error occurred the function will return any of the amxp_expr_status_t values

Definition at line 696 of file amxp_expression_main.c.

697  {
699  when_null(expr, exit);
700 
701  expr->expression = NULL;
702  expr->status = amxp_expr_status_ok;
703  expr->verify = false;
704  expr->get_field = NULL;
705  amxc_rbuffer_init(&expr->rbuffer, 0);
706  amxc_string_init(&expr->msg, 0);
707  amxc_lstack_init(&expr->nodes);
708 
709  when_null(expression, exit);
710  expr->expression = strdup(expression);
711  when_null(expr->expression, exit);
712 
713  retval = amxp_expr_parse(expr);
714  if(retval == 0) {
715  expr->verify = true;
717  expr->verify = false;
718  retval = expr->status;
719  }
720 
721 exit:
722  if((retval != amxp_expr_status_ok) && (expr != NULL)) {
723  amxp_expr_node_t* node = amxp_expr_get_node(expr);
724  free(expr->expression);
725  expr->expression = NULL;
726  amxc_lqueue_clean(&expr->nodes, NULL);
727  amxp_expr_node_delete(&node);
728  }
729  return retval;
730 }
static amxp_expr_status_t amxp_expr_parse(amxp_expr_t *expr)

◆ amxp_expr_new()

amxp_expr_status_t amxp_expr_new ( amxp_expr_t **  expr,
const char *  expression 
)

Allocates and initializes an expression.

Allocates memory on the heap to store the expression data structure. The provided expression is parsed and stored for later use. When the expression is invalid an error is returned and no memory is allocated.

Once an expression structure is available, it can be reused many times.

Note
The allocated memory must be freed when not used anymore, use amxp_expr_delete to free the memory
Parameters
expra pointer to the location where the pointer to the new expression can be stored
expressiona string containing a logical expression.
Returns
amxp_expr_status_ok if memory is allocated and the given expression is valid (syntax). When an error occurred the function will return any of the amxp_expr_status_t values

Definition at line 633 of file amxp_expression_main.c.

633  {
635  when_null(expr, exit);
636  when_null(expression, exit);
637 
638  *expr = (amxp_expr_t*) calloc(1, sizeof(amxp_expr_t));
639  when_null((*expr), exit);
640 
641  retval = amxp_expr_init(*expr, expression);
642 
643 exit:
644  if((retval != 0) && (expr != NULL) && (*expr != NULL)) {
645  amxp_expr_clean(*expr);
646  free(*expr);
647  *expr = NULL;
648  }
649  return retval;
650 }
amxp_expr_status_t amxp_expr_init(amxp_expr_t *expr, const char *expression)
Initializes an expression structure.

◆ amxp_expr_vbuildf()

amxp_expr_status_t amxp_expr_status_t amxp_expr_vbuildf ( amxp_expr_t expr,
const char *  expr_fmt,
va_list  args 
)

va_list version of amxp_expr_buildf

Parameters
expra pointer to the location where the pointer to the new expression can be stored
expr_fmta string containing a logical expression with placeholders.
argsva list of arguments.
Returns
amxp_expr_status_ok if memory is allocated and the given expression is valid (syntax). When an error occurred the function will return any of the amxp_expr_status_t values

Definition at line 732 of file amxp_expression_main.c.

734  {
736  int status = -1;
737  amxc_string_t expression;
738 
739  amxc_string_init(&expression, 0);
740 
741  when_null(expr, exit);
742  when_null(expr_fmt, exit);
743 
744  memset(expr, 0, sizeof(amxp_expr_t));
745 
746  status = amxc_string_vappendf_checked(&expression, amxp_expr_is_safe_value, expr_fmt, args);
747  when_failed_status(status, exit, expr->status = amxp_expr_status_syntax_error);
748  retval = amxp_expr_init(expr, amxc_string_get(&expression, 0));
749 
750 exit:
751  amxc_string_clean(&expression);
752  return retval;
753 }
static bool amxp_expr_is_safe_value(const char *string)

◆ amxp_expr_vbuildf_new()

amxp_expr_status_t amxp_expr_status_t amxp_expr_vbuildf_new ( amxp_expr_t **  expr,
const char *  expr_fmt,
va_list  args 
)

va_list version of amxp_expr_buildf_new

Parameters
expra pointer to the location where the pointer to the new expression can be stored
expr_fmta string containing a logical expression with placeholders.
argsva list of arguments.
Returns
amxp_expr_status_ok if memory is allocated and the given expression is valid (syntax). When an error occurred the function will return any of the amxp_expr_status_t values

Definition at line 664 of file amxp_expression_main.c.

666  {
668  when_null(expr, exit);
669  when_null(expr_fmt, exit);
670 
671  *expr = (amxp_expr_t*) calloc(1, sizeof(amxp_expr_t));
672  when_null((*expr), exit);
673 
674  retval = amxp_expr_vbuildf(*expr, expr_fmt, args);
675 
676 exit:
677  if((retval != 0) && (expr != NULL) && (*expr != NULL)) {
678  amxp_expr_clean(*expr);
679  free(*expr);
680  *expr = NULL;
681  }
682  return retval;
683 }
amxp_expr_status_t amxp_expr_vbuildf(amxp_expr_t *expr, const char *expr_fmt, va_list args)
va_list version of amxp_expr_buildf