libamxp  1.4.0
Patterns C Implementation
amxp_expression_main.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"
#include "amxp_expr.tab.h"

Go to the source code of this file.

Data Structures

struct  _amxp_expr_vfunc
 
struct  _amxp_expr_bfunc
 
struct  _amxp_regexp
 

Macros

#define _GNU_SOURCE
 
#define REGEXP_STORE_SIZE   40
 

Typedefs

typedef struct _amxp_expr_vfunc amxp_expr_vfunc_t
 
typedef struct _amxp_expr_bfunc amxp_expr_bfunc_t
 
typedef struct _amxp_regexp amxp_regexp_t
 

Functions

static void amxp_regexp_clean (amxc_llist_it_t *it)
 
static amxp_regexp_tamxp_regexp_get (const char *regexp_str)
 
static CONSTRUCTOR void amxp_regexp_store_init (void)
 
static DESTRUCTOR void amxp_regexp_store_cleanup (void)
 
static void amxp_expr_vfunc_hit_free (UNUSED const char *key, amxc_htable_it_t *it)
 
static void amxp_expr_bfunc_hit_free (UNUSED const char *key, amxc_htable_it_t *it)
 
static ssize_t amxp_expr_string_reader (amxp_expr_t *expr, void *buf, size_t max_size)
 
static bool amxp_expr_match_regexp (amxp_expr_t *expr, amxc_var_t *lvalue, amxc_var_t *rvalue)
 
static bool amxp_expr_string_check (const char *lstr, size_t llength, const char *rstr, size_t rlength, amxp_expr_comp_t comperator)
 
static bool amxp_expr_string_head_tail_check (amxc_var_t *lvalue, amxc_var_t *rvalue, amxp_expr_comp_t comperator)
 
static bool amxp_expr_in_list (amxc_var_t *lvalue, amxc_var_t *rvalue)
 
static bool amxp_expr_in_string (amxc_var_t *lvalue, amxc_var_t *rvalue)
 
static bool amxp_expr_equals_ignorecase (amxc_var_t *lvalue, amxc_var_t *rvalue)
 
static bool amxp_expr_is_simple_type (amxc_var_t *value)
 
static bool amxp_expr_are_simple_types (amxc_var_t *lvalue, amxc_var_t *rvalue)
 
static bool amxp_expr_in (amxp_expr_t *expr, amxc_var_t *lvalue, amxc_var_t *rvalue)
 
static bool amxp_expr_comperator (int result, amxp_expr_comp_t type)
 
static amxp_expr_status_t _value_first_of (UNUSED amxp_expr_t *expr, amxc_var_t *args, amxc_var_t *ret)
 
static bool _bool_is_empty (UNUSED amxp_expr_t *expr, amxc_var_t *args)
 
static bool _bool_contains (amxp_expr_t *expr, amxc_var_t *args)
 
static bool amxp_expr_is_safe_value (const char *string)
 
static amxp_expr_status_t amxp_expr_parse (amxp_expr_t *expr)
 
void amxp_expr_msg (amxp_expr_t *expr, const char *format,...)
 
int amxp_expr_printf (const char *format,...)
 
bool amxp_expr_compare (amxp_expr_t *expr, amxc_var_t *lvalue, amxc_var_t *rvalue, amxp_expr_comp_t comperator)
 
amxp_expr_status_t amxp_expr_call_value_func (amxp_expr_t *expr, const char *func, amxc_var_t *args, amxc_var_t *ret)
 
bool amxp_expr_call_bool_func (amxp_expr_t *expr, const char *func, amxc_var_t *args)
 
amxp_expr_status_t amxp_expr_get_field (amxp_expr_t *expr, amxc_var_t *value, const char *path)
 
amxp_expr_status_t amxp_expr_new (amxp_expr_t **expr, const char *expression)
 Allocates and initializes an expression. More...
 
void amxp_expr_delete (amxp_expr_t **expr)
 Deletes a previously allocated expression structure. More...
 
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...
 
amxp_expr_status_t amxp_expr_buildf_new (amxp_expr_t **expr, const char *expr_fmt,...)
 
amxp_expr_status_t amxp_expr_init (amxp_expr_t *expr, const char *expression)
 Initializes an expression structure. More...
 
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_buildf (amxp_expr_t *expr, const char *expr_fmt,...)
 
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...
 
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...
 
 CONSTRUCTOR_LVL (101)
 
 DESTRUCTOR_LVL (101)
 

Variables

static amxc_htable_t value_funcs
 
static amxc_htable_t bool_funcs
 
static amxc_htable_t regexp_store
 
static amxc_llist_t regexp_store_list
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxp_expression_main.c.

◆ REGEXP_STORE_SIZE

#define REGEXP_STORE_SIZE   40

Definition at line 73 of file amxp_expression_main.c.

Typedef Documentation

◆ amxp_expr_bfunc_t

◆ amxp_expr_vfunc_t

◆ amxp_regexp_t

typedef struct _amxp_regexp amxp_regexp_t

Function Documentation

◆ _bool_contains()

static bool _bool_contains ( amxp_expr_t expr,
amxc_var_t *  args 
)
static

Definition at line 412 of file amxp_expression_main.c.

413  {
414  bool retval = false;
415  amxc_var_t* data = (amxc_var_t*) expr->priv;
416  const char* path = NULL;
417  amxc_var_t field_value;
419 
420  amxc_var_init(&field_value);
421  when_null(data, exit);
422  when_null(expr->get_field, exit);
423 
424  amxc_var_for_each(field_var, args) {
425  if(amxc_var_type_of(field_var) != AMXC_VAR_ID_CSTRING) {
426  // ignore invalid field paths - field paths must be strings
427  continue;
428  }
429  path = amxc_var_constcast(cstring_t, field_var);
430  status = expr->get_field(expr, &field_value, path, expr->priv);
431  retval = (status == amxp_expr_status_ok);
432  if(retval) {
433  // found one, we can stop
434  break;
435  }
436  }
437 
438 exit:
439  amxc_var_clean(&field_value);
440  return retval;
441 }
enum _expr_status amxp_expr_status_t
Expression status/error codes.
@ amxp_expr_status_ok
amxp_expr_get_field_t get_field
static amxc_string_t path

◆ _bool_is_empty()

static bool _bool_is_empty ( UNUSED amxp_expr_t expr,
amxc_var_t *  args 
)
static

Definition at line 389 of file amxp_expression_main.c.

390  {
391  bool retval = false;
392  amxc_llist_it_t* it = amxc_llist_get_first(&args->data.vl);
393  amxc_var_t* data = amxc_var_from_llist_it(it);
394 
395  if(amxc_var_is_null(data)) {
396  retval = true;
397  }
398 
399  if((amxc_var_type_of(data) == AMXC_VAR_ID_LIST) &&
400  amxc_llist_is_empty(&data->data.vl)) {
401  retval = true;
402  }
403 
404  if((amxc_var_type_of(data) == AMXC_VAR_ID_HTABLE) &&
405  amxc_htable_is_empty(&data->data.vm)) {
406  retval = true;
407  }
408 
409  return retval;
410 }

◆ _value_first_of()

static amxp_expr_status_t _value_first_of ( UNUSED amxp_expr_t expr,
amxc_var_t *  args,
amxc_var_t *  ret 
)
static

Definition at line 367 of file amxp_expression_main.c.

369  {
371  amxc_var_t* data = NULL;
372  amxc_llist_for_each(it, (&args->data.vl)) {
373  data = amxc_var_from_llist_it(it);
374  if(!amxc_var_is_null(data)) {
375  break;
376  }
377  data = NULL;
378  }
379 
380  when_null(data, exit);
381  amxc_var_copy(ret, data);
382 
383  status = amxp_expr_status_ok;
384 
385 exit:
386  return status;
387 }
@ amxp_expr_status_invalid_value

◆ amxp_expr_are_simple_types()

static bool amxp_expr_are_simple_types ( amxc_var_t *  lvalue,
amxc_var_t *  rvalue 
)
static

Definition at line 297 of file amxp_expression_main.c.

298  {
299  return (amxp_expr_is_simple_type(lvalue) &&
300  amxp_expr_is_simple_type(rvalue));
301 }
static bool amxp_expr_is_simple_type(amxc_var_t *value)

◆ amxp_expr_bfunc_hit_free()

static void amxp_expr_bfunc_hit_free ( UNUSED const char *  key,
amxc_htable_it_t *  it 
)
static

Definition at line 129 of file amxp_expression_main.c.

130  {
131  amxp_expr_bfunc_t* bfn = amxc_htable_it_get_data(it, amxp_expr_bfunc_t, hit);
132  free(bfn);
133 }

◆ amxp_expr_buildf()

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

Definition at line 755 of file amxp_expression_main.c.

757  {
758  va_list args;
760  va_start(args, expr_fmt);
761  retval = amxp_expr_vbuildf(expr, expr_fmt, args);
762  va_end(args);
763  return retval;
764 }
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
@ amxp_expr_status_unknown_error

◆ amxp_expr_buildf_new()

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

Definition at line 685 of file amxp_expression_main.c.

687  {
688  va_list args;
690  va_start(args, expr_fmt);
691  retval = amxp_expr_vbuildf_new(expr, expr_fmt, args);
692  va_end(args);
693  return retval;
694 }
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

◆ amxp_expr_call_bool_func()

bool amxp_expr_call_bool_func ( amxp_expr_t expr,
const char *  func,
amxc_var_t *  args 
)

Definition at line 586 of file amxp_expression_main.c.

588  {
589  int retval = false;
590  amxc_htable_it_t* it = amxc_htable_get(&bool_funcs, func);
591  amxp_expr_bfunc_t* fn = amxc_htable_it_get_data(it, amxp_expr_bfunc_t, hit);
592 
594  when_null(it, exit);
595  expr->status = amxp_expr_status_ok;
596  if(expr->verify) {
597  retval = true;
598  } else {
599  retval = fn->fn(expr, args);
600  }
601 
602 exit:
603  return retval;
604 }
static amxc_htable_t bool_funcs
@ amxp_expr_status_function_not_found
amxp_expr_bool_func_t fn
amxp_expr_status_t status

◆ amxp_expr_call_value_func()

amxp_expr_status_t amxp_expr_call_value_func ( amxp_expr_t expr,
const char *  func,
amxc_var_t *  args,
amxc_var_t *  ret 
)

Definition at line 567 of file amxp_expression_main.c.

570  {
571  amxc_htable_it_t* it = amxc_htable_get(&value_funcs, func);
572  amxp_expr_vfunc_t* fn = amxc_htable_it_get_data(it, amxp_expr_vfunc_t, hit);
573 
575  when_null(it, exit);
576  if(expr->verify) {
577  expr->status = amxp_expr_status_ok;
578  } else {
579  expr->status = fn->fn(expr, args, ret);
580  }
581 
582 exit:
583  return expr->status;
584 }
static amxc_htable_t value_funcs
amxp_expr_value_func_t fn

◆ amxp_expr_compare()

bool amxp_expr_compare ( amxp_expr_t expr,
amxc_var_t *  lvalue,
amxc_var_t *  rvalue,
amxp_expr_comp_t  comperator 
)

Definition at line 519 of file amxp_expression_main.c.

522  {
523  int result = 0;
524  bool retval = false;
525 
526  if((comperator != amxp_expr_comp_in) &&
527  (comperator != amxp_expr_comp_starts_with) &&
528  (comperator != amxp_expr_comp_ends_with) &&
529  (comperator != amxp_expr_comp_contains)) {
530  if(!amxp_expr_are_simple_types(lvalue, rvalue)) {
532  goto exit;
533  }
534  }
535 
536  switch(comperator) {
538  retval = amxp_expr_match_regexp(expr, lvalue, rvalue);
539  break;
542  retval = amxp_expr_string_head_tail_check(lvalue, rvalue, comperator);
543  break;
544  case amxp_expr_comp_in:
545  retval = amxp_expr_in(expr, lvalue, rvalue);
546  break;
548  retval = amxp_expr_in(expr, rvalue, lvalue);
549  break;
551  retval = amxp_expr_equals_ignorecase(rvalue, lvalue);
552  break;
553  default:
554  amxc_var_compare(lvalue, rvalue, &result);
555  retval = amxp_expr_comperator(result, comperator);
556  break;
557  }
558 
559  if(expr->verify) {
560  retval = true;
561  }
562 
563 exit:
564  return retval;
565 }
@ amxp_expr_comp_ends_with
@ amxp_expr_comp_in
@ amxp_expr_comp_starts_with
@ amxp_expr_comp_matches
@ amxp_expr_comp_equals_ignorecase
@ amxp_expr_comp_contains
static bool amxp_expr_equals_ignorecase(amxc_var_t *lvalue, amxc_var_t *rvalue)
static bool amxp_expr_string_head_tail_check(amxc_var_t *lvalue, amxc_var_t *rvalue, amxp_expr_comp_t comperator)
static bool amxp_expr_in(amxp_expr_t *expr, amxc_var_t *lvalue, amxc_var_t *rvalue)
static bool amxp_expr_are_simple_types(amxc_var_t *lvalue, amxc_var_t *rvalue)
static bool amxp_expr_match_regexp(amxp_expr_t *expr, amxc_var_t *lvalue, amxc_var_t *rvalue)
static bool amxp_expr_comperator(int result, amxp_expr_comp_t type)

◆ amxp_expr_comperator()

static bool amxp_expr_comperator ( int  result,
amxp_expr_comp_t  type 
)
static

Definition at line 340 of file amxp_expression_main.c.

340  {
341  bool retval = false;
342  switch(type) {
344  retval = (result == 0);
345  break;
347  retval = (result != 0);
348  break;
350  retval = (result < 0);
351  break;
353  retval = (result > 0);
354  break;
356  retval = (result <= 0);
357  break;
359  retval = (result >= 0);
360  break;
361  default:
362  break;
363  }
364  return retval;
365 }
@ amxp_expr_comp_bigger_equal
@ amxp_expr_comp_lesser
@ amxp_expr_comp_equal
@ amxp_expr_comp_bigger
@ amxp_expr_comp_not_equal
@ amxp_expr_comp_lesser_equal

◆ amxp_expr_equals_ignorecase()

static bool amxp_expr_equals_ignorecase ( amxc_var_t *  lvalue,
amxc_var_t *  rvalue 
)
static

Definition at line 275 of file amxp_expression_main.c.

276  {
277  bool retval = false;
278  char* lvalue_str = NULL;
279  char* rvalue_str = NULL;
280 
281  lvalue_str = amxc_var_dyncast(cstring_t, lvalue);
282  rvalue_str = amxc_var_dyncast(cstring_t, rvalue);
283 
284  retval = 0 == strcasecmp(lvalue_str, rvalue_str);
285 
286  free(lvalue_str);
287  free(rvalue_str);
288 
289  return retval;
290 }

◆ amxp_expr_get_field()

amxp_expr_status_t amxp_expr_get_field ( amxp_expr_t expr,
amxc_var_t *  value,
const char *  path 
)

Definition at line 606 of file amxp_expression_main.c.

608  {
610  amxp_expr_get_field_t fn = expr->get_field;
611 
612  amxc_var_clean(value);
613  if(expr->verify) {
614  amxc_var_set(bool, value, true);
615  retval = amxp_expr_status_ok;
616  goto exit;
617  }
618 
619  if(fn != NULL) {
620  retval = fn(expr, value, path, expr->priv);
621  }
622 
623  if(amxc_var_is_null(value)) {
625  amxp_expr_msg(expr, "Field not found - %s -", path);
626  }
627  expr->status = retval;
628 
629 exit:
630  return retval;
631 }
void amxp_expr_msg(amxp_expr_t *expr, const char *format,...)
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.
@ amxp_expr_status_field_not_found

◆ amxp_expr_in()

static bool amxp_expr_in ( amxp_expr_t expr,
amxc_var_t *  lvalue,
amxc_var_t *  rvalue 
)
static

Definition at line 303 of file amxp_expression_main.c.

305  {
306  int rtype = amxc_var_type_of(rvalue);
307  bool retval = false;
308 
309  if(!amxp_expr_is_simple_type(lvalue)) {
311  goto exit;
312  }
313 
314  switch(rtype) {
315  case AMXC_VAR_ID_LIST:
316  retval = amxp_expr_in_list(lvalue, rvalue);
317  break;
318  case AMXC_VAR_ID_CSTRING:
319  retval = amxp_expr_in_string(lvalue, rvalue);
320  break;
321  case AMXC_VAR_ID_SSV_STRING:
322  case AMXC_VAR_ID_CSV_STRING:
323  amxc_var_cast(rvalue, AMXC_VAR_ID_LIST);
324  retval = amxp_expr_in_list(lvalue, rvalue);
325  break;
326  case AMXC_VAR_ID_BOOL:
327  if(!expr->verify) {
329  }
330  break;
331  default:
333  break;
334  }
335 
336 exit:
337  return retval;
338 }
static bool amxp_expr_in_string(amxc_var_t *lvalue, amxc_var_t *rvalue)
static bool amxp_expr_in_list(amxc_var_t *lvalue, amxc_var_t *rvalue)

◆ amxp_expr_in_list()

static bool amxp_expr_in_list ( amxc_var_t *  lvalue,
amxc_var_t *  rvalue 
)
static

Definition at line 236 of file amxp_expression_main.c.

237  {
238  const amxc_llist_t* list = amxc_var_constcast(amxc_llist_t, rvalue);
239  int result = 0;
240  bool retval = false;
241 
242  amxc_llist_for_each(it, list) {
243  amxc_var_t* item = amxc_var_from_llist_it(it);
244  int amxc_rv = amxc_var_compare(lvalue, item, &result);
245  if((amxc_rv == 0) && (result == 0)) {
246  retval = true;
247  break;
248  }
249  }
250 
251  return retval;
252 }

◆ amxp_expr_in_string()

static bool amxp_expr_in_string ( amxc_var_t *  lvalue,
amxc_var_t *  rvalue 
)
static

Definition at line 254 of file amxp_expression_main.c.

255  {
256  const char* string = amxc_var_constcast(cstring_t, rvalue);
257  int rlength = strlen(string);
258  char* lstr = amxc_var_dyncast(cstring_t, lvalue);
259  int llength = strlen(lstr);
260  bool retval = false;
261 
262  if(llength <= rlength) {
263  for(int i = 0; i <= rlength - llength; i++) {
264  if(strncmp(lstr, string + i, llength) == 0) {
265  retval = true;
266  break;
267  }
268  }
269  }
270 
271  free(lstr);
272  return retval;
273 }

◆ amxp_expr_is_safe_value()

static bool amxp_expr_is_safe_value ( const char *  string)
static

Definition at line 443 of file amxp_expression_main.c.

443  {
444  if(string == NULL) {
445  return false;
446  }
447  for(const char* c = string; *c != '\0'; c++) {
448  bool is_whitelisted =
449  *c == ' '
450  || *c == '!'
451  || (*c >= '#' && *c <= '&')
452  || (*c >= '(' && *c <= '[')
453  || (*c >= ']' && *c <= '_')
454  || (*c >= 'a' && *c <= '~');
455  if(!is_whitelisted) {
456  return false;
457  }
458  }
459  return true;
460 }

◆ amxp_expr_is_simple_type()

static bool amxp_expr_is_simple_type ( amxc_var_t *  value)
static

Definition at line 292 of file amxp_expression_main.c.

292  {
293  int type = amxc_var_type_of(value);
294  return !(type == AMXC_VAR_ID_HTABLE || type == AMXC_VAR_ID_LIST);
295 }

◆ amxp_expr_match_regexp()

static bool amxp_expr_match_regexp ( amxp_expr_t expr,
amxc_var_t *  lvalue,
amxc_var_t *  rvalue 
)
static

Definition at line 145 of file amxp_expression_main.c.

147  {
148  bool retval = false;
149  amxp_regexp_t* regexp = NULL;
150  char* regexp_str = NULL;
151  char* value_str = NULL;
152 
153  regexp_str = amxc_var_dyncast(cstring_t, rvalue);
154  value_str = amxc_var_dyncast(cstring_t, lvalue);
155 
156  regexp = amxp_regexp_get(regexp_str);
157  if(regexp == NULL) {
158  regexp = (amxp_regexp_t*) calloc(1, sizeof(amxp_regexp_t));
159  when_null_status(regexp, exit, expr->status = amxp_expr_status_invalid_regexp);
160  if(regcomp(&regexp->regexp, regexp_str, REG_EXTENDED) != 0) {
162  free(regexp);
163  goto exit;
164  }
165  amxc_htable_insert(&regexp_store, regexp_str, &regexp->hit);
166  amxc_llist_append(&regexp_store_list, &regexp->lit);
167 
168  if(amxc_htable_size(&regexp_store) > REGEXP_STORE_SIZE) {
169  amxc_llist_it_t* it = amxc_llist_take_first(&regexp_store_list);
170  amxp_regexp_clean(it);
171  }
172  }
173 
174  if(regexec(&regexp->regexp, value_str, 0, NULL, 0) == 0) {
175  retval = true;
176  }
177 
178 exit:
179  free(regexp_str);
180  free(value_str);
181 
182  return retval;
183 }
static void amxp_regexp_clean(amxc_llist_it_t *it)
static amxc_htable_t regexp_store
static amxp_regexp_t * amxp_regexp_get(const char *regexp_str)
#define REGEXP_STORE_SIZE
static amxc_llist_t regexp_store_list
@ amxp_expr_status_invalid_regexp
amxc_llist_it_t lit
amxc_htable_it_t hit

◆ amxp_expr_msg()

void amxp_expr_msg ( amxp_expr_t expr,
const char *  format,
  ... 
)

Definition at line 504 of file amxp_expression_main.c.

504  {
505  va_list args;
506  va_start(args, format);
507  amxc_string_vsetf(&expr->msg, format, args);
508  va_end(args);
509 }
amxc_string_t msg

◆ amxp_expr_parse()

static amxp_expr_status_t amxp_expr_parse ( amxp_expr_t expr)
static

Definition at line 462 of file amxp_expression_main.c.

462  {
463  int yyparse_rv = 0;
464  int length = 0;
465  when_null(expr, exit);
466  when_null(expr->expression, exit);
467 
468  expr->status = amxp_expr_status_ok;
469  length = strlen(expr->expression);
470  if(length == 0) {
471  goto exit;
472  }
473  amxc_rbuffer_write(&expr->rbuffer,
474  expr->expression,
475  length);
476  if(expr->expression[length - 1] != ';') {
477  amxc_rbuffer_write(&expr->rbuffer, ";", 2);
478  }
479 
481  expr->status = amxp_expr_status_ok;
482 
483  amxp_expr_create_lex(expr);
484  yyparse_rv = yyparse(expr->scanner);
485  amxp_expr_destroy_lex(expr);
486 
487  if(yyparse_rv != 0) {
488  amxp_expr_node_t* node = NULL;
490  node = amxp_expr_node_pop(&expr->nodes);
491  while(node != NULL) {
492  amxp_expr_node_delete(&node);
493  node = amxp_expr_node_pop(&expr->nodes);
494  }
495  }
496 
497  amxc_rbuffer_clean(&expr->rbuffer);
498 
499 exit:
500  return expr->status;
501 }
PRIVATE void amxp_expr_create_lex(amxp_expr_t *expr)
PRIVATE void amxp_expr_node_delete(amxp_expr_node_t **node)
PRIVATE void amxp_expr_destroy_lex(amxp_expr_t *expr)
PRIVATE amxp_expr_node_t * amxp_expr_node_pop(amxc_lstack_t *stack)
static ssize_t amxp_expr_string_reader(amxp_expr_t *expr, void *buf, size_t max_size)
@ amxp_expr_status_syntax_error
char * expression
amxc_rbuffer_t rbuffer
amxp_expr_reader_t reader
amxc_lstack_t nodes

◆ amxp_expr_printf()

int amxp_expr_printf ( const char *  format,
  ... 
)

Definition at line 511 of file amxp_expression_main.c.

511  {
512  va_list args;
513  va_start(args, format);
514  vfprintf(stderr, format, args);
515  va_end(args);
516  return 0;
517 }

◆ amxp_expr_string_check()

static bool amxp_expr_string_check ( const char *  lstr,
size_t  llength,
const char *  rstr,
size_t  rlength,
amxp_expr_comp_t  comperator 
)
static

Definition at line 185 of file amxp_expression_main.c.

189  {
190  size_t offset = 0;
191  bool retval = false;
192 
193  when_true(rlength > llength, exit);
194 
195  if(comperator == amxp_expr_comp_starts_with) {
196  offset = 0;
197  } else {
198  offset = llength - rlength;
199  }
200  retval = strncmp(lstr + offset, rstr, rlength) == 0;
201 
202 exit:
203  return retval;
204 }

◆ amxp_expr_string_head_tail_check()

static bool amxp_expr_string_head_tail_check ( amxc_var_t *  lvalue,
amxc_var_t *  rvalue,
amxp_expr_comp_t  comperator 
)
static

Definition at line 206 of file amxp_expression_main.c.

208  {
209  bool retval = false;
210  char* lstr = amxc_var_dyncast(cstring_t, lvalue);
211  char* rstr = NULL;
212  size_t llength = strlen(lstr);
213 
214  if(amxc_var_type_of(rvalue) == AMXC_VAR_ID_LIST) {
215  amxc_var_for_each(var, rvalue) {
216  size_t rlength = 0;
217  rstr = amxc_var_dyncast(cstring_t, var);
218  rlength = strlen(rstr);
219  retval = amxp_expr_string_check(lstr, llength, rstr, rlength, comperator);
220  free(rstr);
221  if(retval) {
222  break;
223  }
224  }
225  } else {
226  size_t rlength = 0;
227  rstr = amxc_var_dyncast(cstring_t, rvalue);
228  rlength = strlen(rstr);
229  retval = amxp_expr_string_check(lstr, llength, rstr, rlength, comperator);
230  free(rstr);
231  }
232  free(lstr);
233  return retval;
234 }
static bool amxp_expr_string_check(const char *lstr, size_t llength, const char *rstr, size_t rlength, amxp_expr_comp_t comperator)

◆ amxp_expr_string_reader()

static ssize_t amxp_expr_string_reader ( amxp_expr_t expr,
void *  buf,
size_t  max_size 
)
static

Definition at line 135 of file amxp_expression_main.c.

137  {
138  ssize_t result = 0;
139  result = amxc_rbuffer_read(&expr->rbuffer, (char*) buf, max_size);
140  errno = 0;
141 
142  return result;
143 }

◆ amxp_expr_vfunc_hit_free()

static void amxp_expr_vfunc_hit_free ( UNUSED const char *  key,
amxc_htable_it_t *  it 
)
static

Definition at line 123 of file amxp_expression_main.c.

124  {
125  amxp_expr_vfunc_t* vfn = amxc_htable_it_get_data(it, amxp_expr_vfunc_t, hit);
126  free(vfn);
127 }

◆ amxp_regexp_clean()

static void amxp_regexp_clean ( amxc_llist_it_t *  it)
static

Definition at line 95 of file amxp_expression_main.c.

95  {
96  amxp_regexp_t* amxp_regexp = (amxp_regexp_t*) amxc_container_of(it, amxp_regexp_t, lit);
97  amxc_htable_it_clean(&amxp_regexp->hit, NULL);
98  regfree(&amxp_regexp->regexp);
99  free(amxp_regexp);
100 }

◆ amxp_regexp_get()

static amxp_regexp_t* amxp_regexp_get ( const char *  regexp_str)
static

Definition at line 102 of file amxp_expression_main.c.

102  {
103  amxp_regexp_t* regexp = NULL;
104  amxc_htable_it_t* it = amxc_htable_get(&regexp_store, regexp_str);
105  if(it != NULL) {
106  regexp = amxc_container_of(it, amxp_regexp_t, hit);
107  amxc_llist_append(&regexp_store_list, &regexp->lit);
108  }
109 
110  return regexp;
111 }

◆ amxp_regexp_store_cleanup()

static DESTRUCTOR void amxp_regexp_store_cleanup ( void  )
static

Definition at line 118 of file amxp_expression_main.c.

118  {
119  amxc_llist_clean(&regexp_store_list, amxp_regexp_clean);
120  amxc_htable_clean(&regexp_store, NULL);
121 }

◆ amxp_regexp_store_init()

static CONSTRUCTOR void amxp_regexp_store_init ( void  )
static

Definition at line 113 of file amxp_expression_main.c.

113  {
114  amxc_llist_init(&regexp_store_list);
115  amxc_htable_init(&regexp_store, REGEXP_STORE_SIZE);
116 }

◆ CONSTRUCTOR_LVL()

CONSTRUCTOR_LVL ( 101  )

Definition at line 861 of file amxp_expression_main.c.

861  {
862  amxp_expr_add_value_fn("first_existing", _value_first_of);
865 }
static bool _bool_contains(amxp_expr_t *expr, amxc_var_t *args)
static amxp_expr_status_t _value_first_of(UNUSED amxp_expr_t *expr, amxc_var_t *args, amxc_var_t *ret)
static bool _bool_is_empty(UNUSED amxp_expr_t *expr, amxc_var_t *args)
int amxp_expr_add_value_fn(const char *fn_name, amxp_expr_value_func_t fn)
Adds a value calculation function.
int amxp_expr_add_bool_fn(const char *fn_name, amxp_expr_bool_func_t fn)
Adds a boolean evaluation function.

◆ DESTRUCTOR_LVL()

DESTRUCTOR_LVL ( 101  )

Definition at line 867 of file amxp_expression_main.c.

867  {
868  amxc_htable_clean(&value_funcs, amxp_expr_vfunc_hit_free);
869  amxc_htable_clean(&bool_funcs, amxp_expr_bfunc_hit_free);
870 }
static void amxp_expr_bfunc_hit_free(UNUSED const char *key, amxc_htable_it_t *it)
static void amxp_expr_vfunc_hit_free(UNUSED const char *key, amxc_htable_it_t *it)

Variable Documentation

◆ bool_funcs

amxc_htable_t bool_funcs
static

Definition at line 91 of file amxp_expression_main.c.

◆ regexp_store

amxc_htable_t regexp_store
static

Definition at line 92 of file amxp_expression_main.c.

◆ regexp_store_list

amxc_llist_t regexp_store_list
static

Definition at line 93 of file amxp_expression_main.c.

◆ value_funcs

amxc_htable_t value_funcs
static

Definition at line 90 of file amxp_expression_main.c.