[RFC PATCH 08/20] add f_has_typed_symbols helper function
Asbjørn Sloth Tønnesen
ast at 2e8.dk
Mon Dec 30 17:56:34 CET 2019
---
filter/Makefile | 2 +-
filter/adapt.c | 31 +++++++++++++++++++++++++++++++
filter/decl.m4 | 44 ++++++++++++++++++++++++++++++++++++--------
filter/f-inst.c | 9 +++++++++
filter/filter.h | 3 +++
5 files changed, 80 insertions(+), 9 deletions(-)
create mode 100644 filter/adapt.c
diff --git a/filter/Makefile b/filter/Makefile
index c2062534..633960b2 100644
--- a/filter/Makefile
+++ b/filter/Makefile
@@ -1,4 +1,4 @@
-src := filter.c data.c f-util.c tree.c trie.c inst-gen.c
+src := filter.c data.c f-util.c tree.c trie.c inst-gen.c adapt.c
obj := $(src-o-files)
$(all-daemon)
$(cf-local)
diff --git a/filter/adapt.c b/filter/adapt.c
new file mode 100644
index 00000000..b1223169
--- /dev/null
+++ b/filter/adapt.c
@@ -0,0 +1,31 @@
+/*
+ * Filters: adaptation functions
+ *
+ * Copyright 1998 Pavel Machek <pavel at ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#undef LOCAL_DEBUG
+
+#include "lib/net.h"
+#include "filter/filter.h"
+#include "filter/f-inst.h"
+
+int
+filter_tree_has_typed_symbols(const struct f_tree *t)
+{
+ if (t == NULL)
+ return 0;
+
+ if (filter_tree_has_typed_symbols(t->left))
+ return 1;
+
+ if (filter_tree_has_typed_symbols(t->right))
+ return 1;
+
+ if (t->data && f_has_typed_symbols(t->data))
+ return 1;
+
+ return 0;
+}
diff --git a/filter/decl.m4 b/filter/decl.m4
index a78450a3..23024d35 100644
--- a/filter/decl.m4
+++ b/filter/decl.m4
@@ -40,6 +40,7 @@ m4_divert(-1)m4_dnl
# 106 comparator body
# 107 struct f_line_item content
# 108 interpreter body
+# 109 f_has_typed_symbls
#
# Here are macros to allow you to _divert to the right directions.
m4_define(FID_STRUCT_IN, `m4_divert(101)')
@@ -50,6 +51,7 @@ m4_define(FID_LINEARIZE_BODY, `m4_divert(105)')
m4_define(FID_SAME_BODY, `m4_divert(106)')
m4_define(FID_LINE_IN, `m4_divert(107)')
m4_define(FID_INTERPRET_BODY, `m4_divert(108)')
+m4_define(FID_HAS_TYPED_BODY, `m4_divert(109)')
# Sometimes you want slightly different code versions in different
# outputs.
@@ -206,6 +208,8 @@ FID_LINEARIZE_BODY()m4_dnl
item->fl$1 = f_linearize(whati->f$1);
FID_SAME_BODY()m4_dnl
if (!f_same(f1->fl$1, f2->fl$1)) return 0;
+FID_HAS_TYPED_BODY()m4_dnl
+if (f_has_typed_symbols(item->fl$1)) return 1;
FID_INTERPRET_EXEC()m4_dnl
do { if (whati->fl$1) {
LINEX_(whati->fl$1);
@@ -254,14 +258,15 @@ m4_define(ACCESS_RTE, `FID_HIC(,[[do { if (!fs->rte) runtime("No route to access
# into appropriate headers and structures and saves them into global
# diversions listed:
#
-# 4 enum fi_code
-# 5 enum fi_code to string
-# 6 dump line item
-# 7 dump line item callers
-# 8 linearize
-# 9 same (filter comparator)
-# 1 union in struct f_inst
-# 3 constructors + interpreter
+# 4 enum fi_code
+# 5 enum fi_code to string
+# 6 dump line item
+# 7 dump line item callers
+# 8 linearize
+# 9 same (filter comparator)
+# 10 f_has_typed_symbols
+# 1 union in struct f_inst
+# 3 constructors + interpreter
#
# These global diversions contain blocks of code that can be directly
# put into the final file, yet it still can't be written out now as
@@ -280,6 +285,7 @@ m4_define(FID_DUMP, `FID_ZONE(6, Dump line)')
m4_define(FID_DUMP_CALLER, `FID_ZONE(7, Dump line caller)')
m4_define(FID_LINEARIZE, `FID_ZONE(8, Linearize)')
m4_define(FID_SAME, `FID_ZONE(9, Comparison)')
+m4_define(FID_HAS_TYPED, `FID_ZONE(10, Has typed symbol)')
# This macro does all the code wrapping. See inline comments.
m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
@@ -367,6 +373,13 @@ m4_undivert(106)m4_dnl
#undef f2
break;
+FID_HAS_TYPED()m4_dnl This code checks if a f_line used typed symbols
+case INST_NAME():
+#define item (&(fl_item->i_]]INST_NAME()[[))
+m4_undivert(109)m4_dnl
+#undef item
+break;
+
m4_divert(-1)FID_FLUSH(101,200)m4_dnl And finally this flushes all the unused diversions
]])')
@@ -577,6 +590,21 @@ FID_WR_PUT(9)
return 1;
}
+/* Does this line refer to any typed symbols? */
+int
+f_has_typed_symbols(const struct f_line *fl)
+{
+ if (fl == NULL) return 0;
+
+ for (uint i=0; i<fl->len; i++) {
+ const struct f_line_item *fl_item = &fl->items[i];
+ switch (fl_item->fi_code) {
+FID_WR_PUT(10)
+ }
+ }
+ return 0;
+}
+
#if defined(__GNUC__) && __GNUC__ >= 6
#pragma GCC diagnostic pop
#endif
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 37fa0f39..46354aa2 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -443,6 +443,8 @@
NEVER_CONSTANT;
RESULT_TYPE(sym->class & 0xff);
+ FID_HAS_TYPED_BODY()
+ return 1;
FID_INTERPRET_BODY()
runtime("FI_TYPED_CONSTANT can't be interpreted", sym);
}
@@ -935,6 +937,9 @@
FID_SAME_BODY()
if (!(f1->sym->flags & SYM_FLAG_SAME))
return 0;
+ FID_HAS_TYPED_BODY()
+ if (item->sym->flags & SYM_FLAGS_TYPED)
+ return 1;
FID_INTERPRET_BODY()
/* Push the body on stack */
@@ -963,6 +968,10 @@
ARG_ANY(1);
FID_MEMBER(struct f_tree *, tree, [[!same_tree(f1->tree, f2->tree)]], "tree %p", item->tree);
+ FID_HAS_TYPED_BODY()
+ if (filter_tree_has_typed_symbols(item->tree))
+ return 1;
+ FID_INTERPRET_BODY()
const struct f_tree *t = find_tree(tree, &v1);
if (!t) {
diff --git a/filter/filter.h b/filter/filter.h
index 84b6b0be..7c4b0ae9 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -63,6 +63,9 @@ const char *filter_name(const struct filter *filter);
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_has_typed_symbols(const struct f_line *line);
+int filter_tree_has_typed_symbols(const struct f_tree *t);
+
void filter_commit(struct config *new, struct config *old);
void filters_dump_all(void);
--
2.24.0
More information about the Bird-users
mailing list