summaryrefslogtreecommitdiff
path: root/filter/f-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'filter/f-util.c')
-rw-r--r--filter/f-util.c98
1 files changed, 54 insertions, 44 deletions
diff --git a/filter/f-util.c b/filter/f-util.c
index 4f11a6d9..e94331b6 100644
--- a/filter/f-util.c
+++ b/filter/f-util.c
@@ -10,57 +10,15 @@
#include "nest/bird.h"
#include "conf/conf.h"
#include "filter/filter.h"
+#include "filter/f-inst-struct.h"
#include "lib/idm.h"
#include "nest/protocol.h"
#include "nest/route.h"
#define P(a,b) ((a<<8) | b)
-struct f_inst *
-f_new_inst(enum f_instruction_code fi_code)
-{
- struct f_inst * ret;
- ret = cfg_allocz(sizeof(struct f_inst));
- ret->fi_code = fi_code;
- ret->lineno = ifs->lino;
- return ret;
-}
-
-struct f_inst *
-f_new_inst_da(enum f_instruction_code fi_code, struct f_dynamic_attr da)
-{
- struct f_inst *ret = f_new_inst(fi_code);
- ret->da = da;
- return ret;
-}
-
-struct f_inst *
-f_new_inst_sa(enum f_instruction_code fi_code, struct f_static_attr sa)
-{
- struct f_inst *ret = f_new_inst(fi_code);
- ret->sa = sa;
- return ret;
-}
-
-/*
- * Generate set_dynamic( operation( get_dynamic(), argument ) )
- */
-struct f_inst *
-f_generate_complex(enum f_instruction_code fi_code, struct f_dynamic_attr da, struct f_inst *argument)
-{
- struct f_inst *set_dyn = f_new_inst_da(FI_EA_SET, da),
- *oper = f_new_inst(fi_code),
- *get_dyn = f_new_inst_da(FI_EA_GET, da);
-
- oper->a[0].p = get_dyn;
- oper->a[1].p = argument;
-
- set_dyn->a[0].p = oper;
- return set_dyn;
-}
-
static const char * const f_instruction_name_str[] = {
-#define F(c,a,b) \
+#define F(c,...) \
[c] = #c,
FI__LIST
#undef F
@@ -88,6 +46,58 @@ filter_name(struct filter *filter)
return filter->name;
}
+void f_inst_next(struct f_inst *first, const struct f_inst *append)
+{
+ first->next = append;
+}
+
+struct filter *f_new_where(const struct f_inst *where)
+{
+ struct f_inst acc = {
+ .fi_code = FI_PRINT_AND_DIE,
+ .lineno = ifs->lino,
+ .i_FI_PRINT_AND_DIE = { .fret = F_ACCEPT, },
+ };
+
+ struct f_inst rej = {
+ .fi_code = FI_PRINT_AND_DIE,
+ .lineno = ifs->lino,
+ .i_FI_PRINT_AND_DIE = { .fret = F_REJECT, },
+ };
+
+ struct f_inst i = {
+ .fi_code = FI_CONDITION,
+ .lineno = ifs->lino,
+ .i_FI_CONDITION = {
+ .f1 = where,
+ .f2 = &acc,
+ .f3 = &rej,
+ },
+ };
+
+ struct filter *f = cfg_alloc(sizeof(struct filter));
+ f->name = NULL;
+ f->root = f_postfixify(&i);
+ return f;
+}
+
+struct f_inst *f_clear_local_vars(struct f_inst *decls)
+{
+ /* Prepend instructions to clear local variables */
+ struct f_inst *head = NULL;
+
+ for (const struct f_inst *si = decls; si; si = si->next) {
+ struct f_inst *cur = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_VOID });
+ if (head)
+ f_inst_next(cur, head);
+ else
+ f_inst_next(cur, si);
+ head = cur; /* The first FI_CONSTANT put there */
+ }
+
+ return head;
+}
+
#define CA_KEY(n) n->name, n->fda.type
#define CA_NEXT(n) n->next
#define CA_EQ(na,ta,nb,tb) (!strcmp(na,nb) && (ta == tb))