mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Filter: Use common initializer for undefined variables and eattrs.
Undefined paths and clists should use typed f_val with empty adata instead of just void f_val. Use common initializer to handle both variables and eattrs.
This commit is contained in:
parent
7395b97daf
commit
a3dc26455d
@ -244,23 +244,6 @@ f_new_lc_item(u32 f1, u32 t1, u32 f2, u32 t2, u32 f3, u32 t3)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct f_inst *
|
|
||||||
f_const_empty(enum f_type t)
|
|
||||||
{
|
|
||||||
switch (t) {
|
|
||||||
case T_PATH:
|
|
||||||
case T_CLIST:
|
|
||||||
case T_ECLIST:
|
|
||||||
case T_LCLIST:
|
|
||||||
return f_new_inst(FI_CONSTANT, (struct f_val) {
|
|
||||||
.type = t,
|
|
||||||
.val.ad = &null_adata,
|
|
||||||
});
|
|
||||||
default:
|
|
||||||
return f_new_inst(FI_CONSTANT, (struct f_val) {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove all new lines and doubled whitespaces
|
* Remove all new lines and doubled whitespaces
|
||||||
* and convert all tabulators to spaces
|
* and convert all tabulators to spaces
|
||||||
@ -914,11 +897,12 @@ term:
|
|||||||
|
|
||||||
| term_dot_method
|
| term_dot_method
|
||||||
|
|
||||||
| '+' EMPTY '+' { $$ = f_const_empty(T_PATH); }
|
| '+' EMPTY '+' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_PATH)); }
|
||||||
| '-' EMPTY '-' { $$ = f_const_empty(T_CLIST); }
|
| '-' EMPTY '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_CLIST)); }
|
||||||
| '-' '-' EMPTY '-' '-' { $$ = f_const_empty(T_ECLIST); }
|
| '-' '-' EMPTY '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_ECLIST)); }
|
||||||
| '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_const_empty(T_LCLIST); }
|
| '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_LCLIST)); }
|
||||||
| PREPEND '(' term ',' term ')' { $$ = f_dispatch_method_x("prepend", $3->type, $3, $5); }
|
|
||||||
|
| PREPEND '(' term ',' term ')' { $$ = f_dispatch_method_x("prepend", $3->type, $3, $5); }
|
||||||
| ADD '(' term ',' term ')' { $$ = f_dispatch_method_x("add", $3->type, $3, $5); }
|
| ADD '(' term ',' term ')' { $$ = f_dispatch_method_x("add", $3->type, $3, $5); }
|
||||||
| DELETE '(' term ',' term ')' { $$ = f_dispatch_method_x("delete", $3->type, $3, $5); }
|
| DELETE '(' term ',' term ')' { $$ = f_dispatch_method_x("delete", $3->type, $3, $5); }
|
||||||
| FILTER '(' term ',' term ')' { $$ = f_dispatch_method_x("filter", $3->type, $3, $5); }
|
| FILTER '(' term ',' term ')' { $$ = f_dispatch_method_x("filter", $3->type, $3, $5); }
|
||||||
|
@ -318,14 +318,32 @@ const struct adata *lclist_filter(struct linpool *pool, const struct adata *list
|
|||||||
|
|
||||||
|
|
||||||
/* Special undef value for paths and clists */
|
/* Special undef value for paths and clists */
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
undef_value(struct f_val v)
|
val_is_undefined(struct f_val v)
|
||||||
{
|
{
|
||||||
return ((v.type == T_PATH) || (v.type == T_CLIST) ||
|
return ((v.type == T_PATH) || (v.type == T_CLIST) ||
|
||||||
(v.type == T_ECLIST) || (v.type == T_LCLIST)) &&
|
(v.type == T_ECLIST) || (v.type == T_LCLIST)) &&
|
||||||
(v.val.ad == &null_adata);
|
(v.val.ad == &null_adata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct f_val
|
||||||
|
val_empty(enum f_type t)
|
||||||
|
{
|
||||||
|
switch (t)
|
||||||
|
{
|
||||||
|
case T_PATH:
|
||||||
|
case T_CLIST:
|
||||||
|
case T_ECLIST:
|
||||||
|
case T_LCLIST:
|
||||||
|
return (struct f_val) { .type = t, .val.ad = &null_adata };
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (struct f_val) { };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern const struct f_val f_const_empty_prefix_set;
|
extern const struct f_val f_const_empty_prefix_set;
|
||||||
|
|
||||||
enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres);
|
enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres);
|
||||||
|
@ -493,7 +493,7 @@
|
|||||||
|
|
||||||
INST(FI_DEFINED, 1, 1) {
|
INST(FI_DEFINED, 1, 1) {
|
||||||
ARG_ANY(1);
|
ARG_ANY(1);
|
||||||
RESULT(T_BOOL, i, (v1.type != T_VOID) && !undef_value(v1));
|
RESULT(T_BOOL, i, (v1.type != T_VOID) && !val_is_undefined(v1));
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD_R(T_NET, type, T_ENUM_NETTYPE, i, v1.val.net->type);
|
METHOD_R(T_NET, type, T_ENUM_NETTYPE, i, v1.val.net->type);
|
||||||
@ -519,7 +519,7 @@
|
|||||||
|
|
||||||
/* New variable is always the last on stack */
|
/* New variable is always the last on stack */
|
||||||
uint pos = curline.vbase + sym->offset;
|
uint pos = curline.vbase + sym->offset;
|
||||||
fstk->vstk[pos] = (struct f_val) { };
|
fstk->vstk[pos] = val_empty(sym->class & 0xff);
|
||||||
fstk->vcnt = pos + 1;
|
fstk->vcnt = pos + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,32 +806,7 @@
|
|||||||
eattr *e = ea_find(*fs->eattrs, da.ea_code);
|
eattr *e = ea_find(*fs->eattrs, da.ea_code);
|
||||||
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
/* A special case: undefined as_path looks like empty as_path */
|
RESULT_VAL(val_empty(da.f_type));
|
||||||
if (da.type == EAF_TYPE_AS_PATH) {
|
|
||||||
RESULT_(T_PATH, ad, &null_adata);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The same special case for int_set */
|
|
||||||
if (da.type == EAF_TYPE_INT_SET) {
|
|
||||||
RESULT_(T_CLIST, ad, &null_adata);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The same special case for ec_set */
|
|
||||||
if (da.type == EAF_TYPE_EC_SET) {
|
|
||||||
RESULT_(T_ECLIST, ad, &null_adata);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The same special case for lc_set */
|
|
||||||
if (da.type == EAF_TYPE_LC_SET) {
|
|
||||||
RESULT_(T_LCLIST, ad, &null_adata);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Undefined value */
|
|
||||||
RESULT_VOID;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user