0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

TMP compiles but doesn't work

This commit is contained in:
Vojtech Vilimek 2022-07-27 13:21:47 +02:00
parent 12f02619c4
commit cbaf6bd630
8 changed files with 129 additions and 8 deletions

View File

@ -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)

View File

@ -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);
}

View File

@ -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) {

View File

@ -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 */

View File

@ -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 <cc> 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; }

7
proto/stats/stats-pub.h Normal file
View File

@ -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

View File

@ -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),

View File

@ -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