--- 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 <[email protected]> + * + * 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
