From cbaf6bd63025e0730b02f7bee21ba09ff0e01cb2 Mon Sep 17 00:00:00 2001 From: Vojtech Vilimek Date: Wed, 27 Jul 2022 13:21:47 +0200 Subject: [PATCH] TMP compiles but doesn't work --- conf/conf.h | 3 +++ filter/config.Y | 3 +++ filter/f-inst.c | 10 ++++++++- filter/filter.c | 2 +- proto/stats/config.Y | 20 ++++++++++++++---- proto/stats/stats-pub.h | 7 ++++++ proto/stats/stats.c | 47 +++++++++++++++++++++++++++++++++++++++++ proto/stats/stats.h | 45 +++++++++++++++++++++++++++++++++++++-- 8 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 proto/stats/stats-pub.h diff --git a/conf/conf.h b/conf/conf.h index d193155b..6907666b 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -109,6 +109,7 @@ void cfg_copy_list(list *dest, list *src, unsigned node_size); extern int (*cf_read_hook)(byte *buf, uint max, int fd); +struct stats_term_config; struct symbol { node n; /* In list of symbols in config */ struct symbol *next; @@ -125,6 +126,7 @@ struct symbol { struct f_val *val; /* For SYM_CONSTANT */ uint offset; /* For SYM_VARIABLE */ struct channel_config *ch_config; /* For SYM_COUNTER */ + struct stats_term_config *term; /* For SYM_COUNTER_TERM */ }; char name[0]; @@ -158,6 +160,7 @@ struct bytestring { #define SYM_TABLE 5 #define SYM_ATTRIBUTE 6 #define SYM_COUNTER 7 +#define SYM_COUNTER_TERM 8 #define SYM_VARIABLE 0x100 /* 0x100-0x1ff are variable types */ #define SYM_VARIABLE_RANGE SYM_VARIABLE ... (SYM_VARIABLE | 0xff) diff --git a/filter/config.Y b/filter/config.Y index 23b258cd..072ae622 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -761,6 +761,9 @@ symbol_value: symbol_known case SYM_COUNTER: $$ = f_new_inst(FI_COUNTER, $1); break; + case SYM_COUNTER_TERM: + $$ = f_new_inst(FI_COUNTER_TERM, $1); + break; default: cf_error("Can't get value of symbol %s", $1->name); } diff --git a/filter/f-inst.c b/filter/f-inst.c index a1e639f2..b0635db4 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -476,7 +476,15 @@ INST(FI_COUNTER, 0, 1) { SYMBOL; NEVER_CONSTANT; - RESULT(T_INT, i, get_stats_counter(sym)); + RESULT(T_INT, i, stats_get_counter(sym)); + } + + INST(FI_COUNTER_TERM, 0, 1) { + SYMBOL; + NEVER_CONSTANT; + + RESULT_TYPE(stats_get_type(sym->term)); + RESULT_VAL(stats_eval_term(sym->term)); } INST(FI_CONSTANT, 0, 1) { diff --git a/filter/filter.c b/filter/filter.c index 51fa0726..6d477b00 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -43,7 +43,7 @@ #include "filter/filter.h" #include "filter/f-inst.h" #include "filter/data.h" -#include "proto/stats/stats.h" /* provides function get_stats_counter() used in f-inst.c */ +#include "proto/stats/stats-pub.h" /* provides function get_stats_counter() used in f-inst.c */ /* Exception bits */ diff --git a/proto/stats/config.Y b/proto/stats/config.Y index 458e3ba5..970970d3 100644 --- a/proto/stats/config.Y +++ b/proto/stats/config.Y @@ -13,11 +13,12 @@ CF_HDR CF_DEFINES +#define STATS_CFG ((struct stats_config *) this_proto) #define STATS_CC ((struct stats_channel_config *) this_channel) CF_DECLS -CF_KEYWORDS(STATS, TABLE, MAX, GENERATION, SETTLE, TIME) +CF_KEYWORDS(STATS, TABLE, MAX, MIN, SETTLE, TIME) %type stats_channel_start @@ -28,6 +29,7 @@ proto: stats_proto '}' { this_channel = NULL; } ; stats_proto_start: proto_start STATS { this_proto = proto_config_new(&proto_stats, $1); + init_list(&STATS_CFG->terms); } proto_name ; @@ -39,10 +41,20 @@ stats_channel_opt_list: stats_opt: type symbol '=' term { - struct f_val val; - if (f_eval(f_linearize($4), &val) > F_RETURN) cf_error("Runtime error"); + + struct stats_term_config *tc = cfg_alloc(sizeof(struct stats_term_config)); + tc->code = (const struct f_line *) f_linearize($4); + tc->type = $1; + tc->name = $2->name; + + struct f_val val; + /* greater then F_RETURN, therefore 2 */ + if (f_eval(f_linearize($4), &val) > 2) cf_error("Runtime error"); if (val.type != $1) cf_error("The expresion does not match defined type"); - /* cf_define_symbol($2, SYM_VARIABLE | $1, val )*/ + + add_tail(&STATS_CFG->terms, (node *) tc); + + $2 = cf_define_symbol($2, SYM_COUNTER_TERM, term, tc); } | MIN SETTLE TIME expr_us { STATS_CC->min_settle_time = $4; } | MAX SETTLE TIME expr_us { STATS_CC->max_settle_time = $4; } diff --git a/proto/stats/stats-pub.h b/proto/stats/stats-pub.h new file mode 100644 index 00000000..7585c2eb --- /dev/null +++ b/proto/stats/stats-pub.h @@ -0,0 +1,7 @@ +#ifndef _BIRD_STATS_PUB_H_ +#define _BIRD_STATS_PUB_H_ + +extern int stats_get_counter(struct symbol *sym); +extern struct f_val stats_eval_term(struct stats_term_config *tc); +extern int stats_get_type(struct stats_term_config *tc); +#endif diff --git a/proto/stats/stats.c b/proto/stats/stats.c index 406bc226..253139d5 100644 --- a/proto/stats/stats.c +++ b/proto/stats/stats.c @@ -115,6 +115,16 @@ stats_start(struct proto *P) { log(L_INFO "stats_start() "); stats_configure_channels(P, P->cf); + + struct stats_term_config *tc; + WALK_LIST(tc, ((struct stats_config *) P->cf)->terms) + { + log(L_INFO "term %s", tc->name); + f_eval(tc->code, &tc->val); + log(L_INFO "content: %s, matches %s", val_dump(&tc->val), + tc->type == tc->val.type ? "yes" : "no"); + } + return PS_UP; } @@ -181,6 +191,9 @@ stats_show_proto_info(struct proto *P) cli_msg(-1006, " Settle time: %4u s", (*(sc->settle_timer->max_settle_time)) TO_S); } } + + cli_msg(-1006, " Terms:"); + cli_msg(-1006, "terms list: %p", ((struct stats_config *) p->c)->terms); } void @@ -252,6 +265,40 @@ stats_channel_shutdown(struct channel *C) c->pool = NULL; } +int +stats_get_counter(struct symbol *sym) +{ + if (sym->ch_config->channel) + return (int) ((struct stats_channel *) sym->ch_config->channel)->counter; + else + return 0; +} + +struct f_val +stats_eval_term(struct stats_term_config *tc) +{ + log(L_INFO "stats_eval_term() evaluating value of %s", + tc->name); + enum filter_return fret = f_eval(tc->code, &tc->val); + + if (fret > F_RETURN) + tc->val.type = T_VOID; + + if (tc->type != tc->val.type) + tc->val.type = T_VOID; + + log(L_INFO " stats_eval_term() returning %s", val_dump(&tc->val)); + return tc->val; +} + +int +stats_get_type(struct stats_term_config *tc) +{ + log(L_INFO "stats_get_type()"); + return tc->type; +} + + struct channel_class channel_stats = { .channel_size = sizeof(struct stats_channel), .config_size = sizeof(struct stats_channel_config), diff --git a/proto/stats/stats.h b/proto/stats/stats.h index ec5fbd12..f78df73c 100644 --- a/proto/stats/stats.h +++ b/proto/stats/stats.h @@ -10,11 +10,21 @@ #ifndef _BIRD_STATS_H_ #define _BIRD_STATS_H_ #include "lib/timer.h" +#include "filter/data.h" struct stats_channel; +struct stats_term_config { + node n; + const struct f_line *code; + struct f_val val; + int type; /* type declared in configuration */ + const char *name; +}; + struct stats_config { struct proto_config c; + list terms; /* list of counter terms */ }; struct stats_proto { @@ -37,13 +47,18 @@ struct stats_channel_config { btime max_settle_time; }; +int stats_get_counter(struct symbol *sym); +struct f_val stats_eval_term(struct stats_term_config *tc); +int stats_get_type(struct stats_term_config *tc); + +#if 0 /* * get_stats_counter() - extract last notified counter * for specific stats channel if it runs * */ -static inline int -get_stats_counter(struct symbol *sym) +inline int +stats_get_counter(struct symbol *sym) { if (sym->ch_config->channel) return (int) ((struct stats_channel *) sym->ch_config->channel)->counter; @@ -51,4 +66,30 @@ get_stats_counter(struct symbol *sym) return 0; } +/* + * stats_eval_term() - evaluate stats term + * + */ +inline struct f_val +stats_eval_term(struct stats_term_config *tc) +{ + enum filter_return fret = f_eval(tc->code, &tc->val); + + if (fret > F_RETURN) + tc->val.type = T_VOID; + + if (tc->type != tc->val.type) + tc->val.type = T_VOID; + + return tc->val; +} + +int +stats_get_type(struct stats_term_config *tc) +{ + return tc->type; +} + +#endif // if 0 + #endif