1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
m4_divert(-1)m4_dnl
#
# BIRD -- Construction of per-instruction structures
#
# (c) 2018 Maria Matejka <mq@jmq.cz>
#
# Can be freely distributed and used under the terms of the GNU GPL.
#
#
# Global Diversions:
# 4 enum fi_code
# 1 struct f_inst_FI_...
# 2 union in struct f_inst
# 3 constructors
#
# Per-inst Diversions:
# 11 content of struct f_inst_FI_...
# 12 constructor arguments
# 13 constructor body
# Flush the completed instruction
m4_define(FID_END, `m4_divert(-1)')
m4_dnl m4_debugmode(aceflqtx)
m4_define(FID_ZONE, `m4_divert($1) /* $2 for INST_NAME() */')
m4_define(FID_STRUCT, `FID_ZONE(1, Per-instruction structure)')
m4_define(FID_UNION, `FID_ZONE(2, Union member)')
m4_define(FID_NEW, `FID_ZONE(3, Constructor)')
m4_define(FID_ENUM, `FID_ZONE(4, Code enum)')
m4_define(FID_STRUCT_IN, `m4_divert(101)')
m4_define(FID_NEW_ARGS, `m4_divert(102)')
m4_define(FID_NEW_BODY, `m4_divert(103)')
m4_define(FID_ALL, `/* fidall */m4_ifdef([[FID_CURDIV]], [[m4_divert(FID_CURDIV)m4_undefine([[FID_CURDIV]])]])')
m4_define(FID_C, `m4_ifelse(TARGET, [[C]], FID_ALL, [[m4_define(FID_CURDIV, m4_divnum)m4_divert(-1)]])')
m4_define(FID_H, `m4_ifelse(TARGET, [[H]], FID_ALL, [[m4_define(FID_CURDIV, m4_divnum)m4_divert(-1)]])')
m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
FID_ENUM
INST_NAME(),
FID_STRUCT
struct f_inst_[[]]INST_NAME() {
m4_undivert(101)
};
FID_UNION
struct f_inst_[[]]INST_NAME() i_[[]]INST_NAME();
FID_NEW
struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code
m4_undivert(102)
)
FID_H ; FID_C
{
struct f_inst *what_ = cfg_allocz(sizeof(struct f_inst));
what_->fi_code = fi_code;
what_->lineno = ifs->lino;
what_->size = 1;
struct f_inst_[[]]INST_NAME() *what UNUSED = &(what_->i_[[]]INST_NAME());
m4_undivert(103)
return what_;
}
FID_ALL
FID_END
]])')
m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])')
m4_define(FID_MEMBER, `m4_dnl
FID_STRUCT_IN
$1 $2;
FID_NEW_ARGS
, $1 $2
FID_NEW_BODY
what->$2 = $2;
FID_END')
m4_define(ARG, `FID_MEMBER(const struct f_inst *, f$1)
FID_NEW_BODY
for (const struct f_inst *child = f$1; child; child = child->next) what_->size += child->size;
FID_END')
m4_define(ARG_ANY, `FID_MEMBER(const struct f_inst *, f$1)
FID_NEW_BODY
for (const struct f_inst *child = f$1; child; child = child->next) what_->size += child->size;
FID_END')
m4_define(LINE, `FID_MEMBER(const struct f_inst *, f$1)')
m4_define(LINEP, `FID_STRUCT_IN
const struct f_line *fl$1;
FID_END')
m4_define(SYMBOL, `FID_MEMBER(const struct symbol *, sym)')
m4_define(VALI, `FID_MEMBER(struct f_val, vali)')
m4_define(VALP, `FID_MEMBER(const struct f_val *, valp)')
m4_define(VAR, `m4_dnl
FID_STRUCT_IN
const struct f_val *valp;
const struct symbol *sym;
FID_NEW_ARGS
, const struct symbol *sym
FID_NEW_BODY
what->valp = (what->sym = sym)->def;
FID_END')
m4_define(FRET, `FID_MEMBER(enum filter_return, fret)')
m4_define(ECS, `FID_MEMBER(enum ec_subtype, ecs)')
m4_define(RTC, `FID_MEMBER(const struct rtable_config *, rtc)')
m4_define(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa)')
m4_define(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da)')
m4_define(COUNT, `FID_MEMBER(uint, count)')
m4_define(TREE, `FID_MEMBER(const struct f_tree *, tree)')
m4_define(STRING, `FID_MEMBER(const char *, s)')
m4_m4wrap(`
INST_FLUSH()
m4_divert(0)
FID_C
#include "nest/bird.h"
#include "filter/filter.h"
#include "filter/f-inst.h"
FID_H
/* Filter instruction codes */
enum f_instruction_code {
m4_undivert(4)
};
/* Per-instruction structures */
m4_undivert(1)
struct f_inst {
const struct f_inst *next; /* Next instruction */
enum f_instruction_code fi_code; /* Instruction code */
int size; /* How many instructions are underneath */
int lineno; /* Line number */
union {
m4_undivert(2)
};
};
FID_ALL
/* Instruction constructors */
m4_undivert(3)
')
m4_changequote([[,]])
|