mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Filter: Use more generic approach for intra-config expressions
Replace f_eval_int() function with a type-generic variant: cf_eval(). Implement similar fuction: cf_eval_int() via inline call to cf_eval().
This commit is contained in:
parent
fc3547880a
commit
0dbcc92726
@ -155,14 +155,14 @@ conf: definition ;
|
|||||||
definition:
|
definition:
|
||||||
DEFINE symbol '=' term ';' {
|
DEFINE symbol '=' term ';' {
|
||||||
struct f_val *val = cfg_allocz(sizeof(struct f_val));
|
struct f_val *val = cfg_allocz(sizeof(struct f_val));
|
||||||
if (f_eval(f_linearize($4, 1), cfg_mem, val) > F_RETURN) cf_error("Runtime error");
|
*val = cf_eval($4, T_VOID);
|
||||||
cf_define_symbol($2, SYM_CONSTANT | val->type, val, val);
|
cf_define_symbol($2, SYM_CONSTANT | val->type, val, val);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
expr:
|
expr:
|
||||||
NUM
|
NUM
|
||||||
| '(' term ')' { $$ = f_eval_int(f_linearize($2, 1)); }
|
| '(' term ')' { $$ = cf_eval_int($2); }
|
||||||
| CF_SYM_KNOWN {
|
| CF_SYM_KNOWN {
|
||||||
if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number constant expected");
|
if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number constant expected");
|
||||||
$$ = SYM_VAL($1).i; }
|
$$ = SYM_VAL($1).i; }
|
||||||
|
@ -358,7 +358,7 @@ filter_def:
|
|||||||
|
|
||||||
conf: filter_eval ;
|
conf: filter_eval ;
|
||||||
filter_eval:
|
filter_eval:
|
||||||
EVAL term { f_eval_int(f_linearize($2, 1)); }
|
EVAL term { cf_eval_int($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
conf: custom_attr ;
|
conf: custom_attr ;
|
||||||
@ -573,7 +573,7 @@ set_atom:
|
|||||||
| VPN_RD { $$.type = T_RD; $$.val.ec = $1; }
|
| VPN_RD { $$.type = T_RD; $$.val.ec = $1; }
|
||||||
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
|
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
|
||||||
| '(' term ')' {
|
| '(' term ')' {
|
||||||
if (f_eval(f_linearize($2, 1), cfg_mem, &($$)) > F_RETURN) cf_error("Runtime error");
|
$$ = cf_eval($2, T_VOID);
|
||||||
if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
|
if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
|
||||||
}
|
}
|
||||||
| CF_SYM_KNOWN {
|
| CF_SYM_KNOWN {
|
||||||
@ -585,13 +585,13 @@ set_atom:
|
|||||||
|
|
||||||
switch_atom:
|
switch_atom:
|
||||||
NUM { $$.type = T_INT; $$.val.i = $1; }
|
NUM { $$.type = T_INT; $$.val.i = $1; }
|
||||||
| '(' term ')' { $$.type = T_INT; $$.val.i = f_eval_int(f_linearize($2, 1)); }
|
| '(' term ')' { $$ = cf_eval($2, T_INT); }
|
||||||
| fipa { $$ = $1; }
|
| fipa { $$ = $1; }
|
||||||
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
|
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
cnum:
|
cnum:
|
||||||
term { $$ = f_eval_int(f_linearize($1, 1)); }
|
term { $$ = cf_eval_int($1); }
|
||||||
|
|
||||||
pair_item:
|
pair_item:
|
||||||
'(' cnum ',' cnum ')' { $$ = f_new_pair_item($2, $2, $4, $4); }
|
'(' cnum ',' cnum ')' { $$ = f_new_pair_item($2, $2, $4, $4); }
|
||||||
|
@ -373,30 +373,22 @@ f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* f_eval_int - get an integer value of a term
|
* cf_eval - evaluate a value of a term and check its type
|
||||||
* Called internally from the config parser, uses its internal memory pool
|
* Called internally from the config parser, uses its internal memory pool
|
||||||
* for allocations. Do not call in other cases.
|
* for allocations. Do not call in other cases.
|
||||||
*/
|
*/
|
||||||
uint
|
struct f_val
|
||||||
f_eval_int(const struct f_line *expr)
|
cf_eval(const struct f_inst *inst, int type)
|
||||||
{
|
{
|
||||||
/* Called independently in parse-time to eval expressions */
|
|
||||||
filter_state = (struct filter_state) {
|
|
||||||
.stack = &filter_stack,
|
|
||||||
.pool = cfg_mem,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct f_val val;
|
struct f_val val;
|
||||||
|
|
||||||
LOG_BUFFER_INIT(filter_state.buf);
|
if (f_eval(f_linearize(inst, 1), cfg_mem, &val) > F_RETURN)
|
||||||
|
|
||||||
if (interpret(&filter_state, expr, &val) > F_RETURN)
|
|
||||||
cf_error("Runtime error while evaluating expression; see log for details");
|
cf_error("Runtime error while evaluating expression; see log for details");
|
||||||
|
|
||||||
if (val.type != T_INT)
|
if (type != T_VOID && val.type != type)
|
||||||
cf_error("Integer expression expected");
|
cf_error("Expression of type %s expected", f_type_name(type));
|
||||||
|
|
||||||
return val.val.i;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "lib/macro.h"
|
#include "lib/macro.h"
|
||||||
#include "nest/route.h"
|
#include "nest/route.h"
|
||||||
#include "nest/attrs.h"
|
#include "nest/attrs.h"
|
||||||
|
#include "filter/data.h"
|
||||||
|
|
||||||
/* Possible return values of filter execution */
|
/* Possible return values of filter execution */
|
||||||
enum filter_return {
|
enum filter_return {
|
||||||
@ -40,9 +41,8 @@ static inline const char *filter_return_str(const enum filter_return fret) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct f_val;
|
|
||||||
|
|
||||||
/* The filter encapsulating structure to be pointed-to from outside */
|
/* The filter encapsulating structure to be pointed-to from outside */
|
||||||
|
struct f_inst;
|
||||||
struct f_line;
|
struct f_line;
|
||||||
struct filter {
|
struct filter {
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
@ -53,9 +53,11 @@ struct rte;
|
|||||||
|
|
||||||
enum filter_return f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags);
|
enum filter_return f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags);
|
||||||
enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool);
|
enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool);
|
||||||
uint f_eval_int(const struct f_line *expr);
|
|
||||||
enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
|
enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
|
||||||
|
|
||||||
|
struct f_val cf_eval(const struct f_inst *inst, int type);
|
||||||
|
static inline uint cf_eval_int(const struct f_inst *inst) { return cf_eval(inst, T_INT).val.i; };
|
||||||
|
|
||||||
const char *filter_name(const struct filter *filter);
|
const char *filter_name(const struct filter *filter);
|
||||||
int filter_same(const struct filter *new, const struct filter *old);
|
int filter_same(const struct filter *new, const struct filter *old);
|
||||||
int f_same(const struct f_line *f1, const struct f_line *f2);
|
int f_same(const struct f_line *f1, const struct f_line *f2);
|
||||||
|
@ -167,7 +167,7 @@ rtrid:
|
|||||||
|
|
||||||
idval:
|
idval:
|
||||||
NUM { $$ = $1; }
|
NUM { $$ = $1; }
|
||||||
| '(' term ')' { $$ = f_eval_int(f_linearize($2, 1)); }
|
| '(' term ')' { $$ = cf_eval_int($2); }
|
||||||
| IP4 { $$ = ip4_to_u32($1); }
|
| IP4 { $$ = ip4_to_u32($1); }
|
||||||
| CF_SYM_KNOWN {
|
| CF_SYM_KNOWN {
|
||||||
if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD))
|
if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD))
|
||||||
|
Loading…
Reference in New Issue
Block a user