[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