]> git.ipfire.org Git - thirdparty/bird.git/blame - filter/f-inst.h
Filter: The for loop uses the method system for type dispatch
[thirdparty/bird.git] / filter / f-inst.h
CommitLineData
9b46748d
MM
1/*
2 * BIRD Internet Routing Daemon -- Filter instructions
3 *
8bdb05ed 4 * (c) 1999 Pavel Machek <pavel@ucw.cz>
9b46748d
MM
5 * (c) 2018--2019 Maria Matejka <mq@jmq.cz>
6 *
7 * Can be freely distributed and used under the terms of the GNU GPL.
e1ac6f1e
MM
8 *
9 * Filter interpreter data structures and internal API.
0da06b71 10 * See filter/f-inst.c for documentation.
9b46748d
MM
11 */
12
8bdb05ed
MM
13#ifndef _BIRD_F_INST_H_
14#define _BIRD_F_INST_H_
15
4f082dfa
MM
16#include "nest/bird.h"
17#include "conf/conf.h"
8bdb05ed 18#include "filter/filter.h"
4f082dfa 19#include "filter/data.h"
d06a875b 20#include "lib/buffer.h"
ff2ca10c 21#include "lib/flowspec.h"
fc354788 22#include "lib/string.h"
8bdb05ed 23
ea4f55e3
MM
24/* Flags for instructions */
25enum f_instruction_flags {
26bc4f99 26 FIF_RECURSIVE = 1, /* FI_CALL: function is directly recursive */
ea4f55e3
MM
27} PACKED;
28
4f082dfa 29/* Include generated filter instruction declarations */
87bd7cd7 30#include "filter/inst-gen.h"
8bdb05ed 31
4f082dfa 32#define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__)
9b46748d
MM
33
34/* Convert the instruction back to the enum name */
87512e97
OZ
35const char *f_instruction_name_(enum f_instruction_code fi);
36static inline const char *f_instruction_name(enum f_instruction_code fi)
37{ return f_instruction_name_(fi) + 3; }
9b46748d 38
93d6096c
OZ
39struct f_arg {
40 struct symbol *arg;
41 struct f_arg *next;
42};
43
8bdb05ed 44/* Filter structures for execution */
8bdb05ed
MM
45/* Line of instructions to be unconditionally executed one after another */
46struct f_line {
47 uint len; /* Line length */
f249d0b8 48 u8 args; /* Function: Args required */
96d757c1 49 u8 vars;
a2527ee5 50 u8 results; /* Results left on stack: cmd -> 0, term -> 1 */
062ff656 51 u8 return_type; /* Type which the function returns */
93d6096c 52 struct f_arg *arg_list;
8bdb05ed
MM
53 struct f_line_item items[0]; /* The items themselves */
54};
9b46748d 55
8bdb05ed 56/* Convert the f_inst infix tree to the f_line structures */
a2527ee5
OZ
57struct f_line *f_linearize_concat(const struct f_inst * const inst[], uint count, uint results);
58static inline struct f_line *f_linearize(const struct f_inst *root, uint results)
59{ return f_linearize_concat(&root, 1, results); }
8bdb05ed 60
ea4f55e3
MM
61void f_dump_line(const struct f_line *, uint indent);
62
d06a875b
OZ
63
64/* Recursive iteration over filter instructions */
65
66struct filter_iterator {
67 BUFFER_(const struct f_line *) lines;
68};
69
70void f_add_lines(const struct f_line_item *what, struct filter_iterator *fit);
71
72#define FILTER_ITERATE_INIT(fit, filter, pool) \
73 ({ \
74 BUFFER_INIT((fit)->lines, (pool), 32); \
75 BUFFER_PUSH((fit)->lines) = (filter)->root; \
76 })
77
78#define FILTER_ITERATE(fit, fi) ({ \
79 const struct f_line *fl_; \
80 while (!BUFFER_EMPTY((fit)->lines)) \
81 { \
82 BUFFER_POP((fit)->lines); \
83 fl_ = (fit)->lines.data[(fit)->lines.used]; \
84 for (uint i_ = 0; i_ < fl_->len; i_++) \
85 { \
86 const struct f_line_item *fi = &fl_->items[i_]; \
87 f_add_lines(fi, (fit));
88
89#define FILTER_ITERATE_END } } })
90
91#define FILTER_ITERATE_CLEANUP(fit) \
92 ({ \
93 mb_free((fit)->lines.data); \
94 memset((fit), 0, sizeof(struct filter_iterator)); \
95 })
96
97
63f49457 98struct filter *f_new_where(struct f_inst *);
21faa54e
MM
99struct f_inst *f_for_cycle(struct symbol *var, struct f_inst *term, struct f_inst *block);
100
78976974
MM
101static inline struct f_dynamic_attr f_new_dynamic_attr(u8 type, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */
102{ return (struct f_dynamic_attr) { .type = type, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */
103static inline struct f_dynamic_attr f_new_dynamic_attr_bit(u8 bit, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */
104{ return (struct f_dynamic_attr) { .type = EAF_TYPE_BITFIELD, .bit = bit, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */
8bdb05ed
MM
105static inline struct f_static_attr f_new_static_attr(int f_type, int code, int readonly)
106{ return (struct f_static_attr) { .f_type = f_type, .sa_code = code, .readonly = readonly }; }
8bdb05ed
MM
107
108/* Hook for call bt_assert() function in configuration */
109extern void (*bt_assert_hook)(int result, const struct f_line_item *assert);
110
111/* Bird Tests */
112struct f_bt_test_suite {
113 node n; /* Node in config->tests */
0b39b1cb
MM
114 const struct f_line *fn; /* Root of function */
115 const struct f_line *cmp; /* Compare to this function */
8bdb05ed
MM
116 const char *fn_name; /* Name of test */
117 const char *dsc; /* Description */
132529ce 118 int result; /* Desired result */
9b46748d
MM
119};
120
8bdb05ed 121#endif