mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-03-21 22:07:03 +00:00
Filters: allowing to return any number of values
This commit is contained in:
parent
df5a08e7c7
commit
ba91f4c831
@ -160,7 +160,7 @@ static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
|
|||||||
* TWOARGS macro to get both of them evaluated.
|
* TWOARGS macro to get both of them evaluated.
|
||||||
*/
|
*/
|
||||||
static enum filter_return
|
static enum filter_return
|
||||||
interpret(struct filter_state *fs, const struct f_line *line, uint argc, const struct f_val *argv, struct f_val *val)
|
interpret(struct filter_state *fs, const struct f_line *line, uint argc, const struct f_val *argv, uint resc, struct f_val *resv)
|
||||||
{
|
{
|
||||||
/* Check of appropriate number of arguments */
|
/* Check of appropriate number of arguments */
|
||||||
ASSERT(line->args == argc);
|
ASSERT(line->args == argc);
|
||||||
@ -225,21 +225,14 @@ interpret(struct filter_state *fs, const struct f_line *line, uint argc, const s
|
|||||||
fstk->ecnt--;
|
fstk->ecnt--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstk->vcnt == 0) {
|
if (fstk->vcnt != resc)
|
||||||
if (val) {
|
{
|
||||||
log_rl(&rl_runtime_err, L_ERR "filters: No value left on stack");
|
log_rl(&rl_runtime_err, L_ERR "Filter expected to leave %d values on stack but %d left instead", resc, fstk->vcnt);
|
||||||
return F_ERROR;
|
return F_ERROR;
|
||||||
}
|
|
||||||
return F_NOP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val && (fstk->vcnt == 1)) {
|
memcpy(resv, fstk->vstk, sizeof(struct f_val) * resc);
|
||||||
*val = fstk->vstk[0];
|
return F_NOP;
|
||||||
return F_NOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_rl(&rl_runtime_err, L_ERR "Too many items left on stack: %u", fstk->vcnt);
|
|
||||||
return F_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -296,7 +289,7 @@ f_run_args(const struct filter *filter, struct rte **rte, struct linpool *tmp_po
|
|||||||
LOG_BUFFER_INIT(filter_state.buf);
|
LOG_BUFFER_INIT(filter_state.buf);
|
||||||
|
|
||||||
/* Run the interpreter itself */
|
/* Run the interpreter itself */
|
||||||
enum filter_return fret = interpret(&filter_state, filter->root, argc, argv, NULL);
|
enum filter_return fret = interpret(&filter_state, filter->root, argc, argv, 0, NULL);
|
||||||
|
|
||||||
if (filter_state.old_rta) {
|
if (filter_state.old_rta) {
|
||||||
/*
|
/*
|
||||||
@ -348,7 +341,7 @@ f_run_args(const struct filter *filter, struct rte **rte, struct linpool *tmp_po
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
enum filter_return
|
enum filter_return
|
||||||
f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, struct f_val *pres)
|
f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, uint resc, struct f_val *resv)
|
||||||
{
|
{
|
||||||
filter_state = (struct filter_state) {
|
filter_state = (struct filter_state) {
|
||||||
.stack = &filter_stack,
|
.stack = &filter_stack,
|
||||||
@ -358,14 +351,14 @@ f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool
|
|||||||
|
|
||||||
LOG_BUFFER_INIT(filter_state.buf);
|
LOG_BUFFER_INIT(filter_state.buf);
|
||||||
|
|
||||||
return interpret(&filter_state, expr, argc, argv, pres);
|
return interpret(&filter_state, expr, argc, argv, resc, resv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* f_eval - get a value of a term
|
* f_eval - get a value of a term
|
||||||
* @expr: filter line containing the term
|
* @expr: filter line containing the term
|
||||||
* @tmp_pool: long data may get allocated from this pool
|
* @tmp_pool: long data may get allocated from this pool
|
||||||
* @pres: here the output will be stored
|
* @pres: here the output will be stored if requested
|
||||||
*/
|
*/
|
||||||
enum filter_return
|
enum filter_return
|
||||||
f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
|
f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
|
||||||
@ -377,7 +370,7 @@ f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
|
|||||||
|
|
||||||
LOG_BUFFER_INIT(filter_state.buf);
|
LOG_BUFFER_INIT(filter_state.buf);
|
||||||
|
|
||||||
enum filter_return fret = interpret(&filter_state, expr, 0, NULL, pres);
|
enum filter_return fret = interpret(&filter_state, expr, 0, NULL, !!pres, pres);
|
||||||
return fret;
|
return fret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ struct rte;
|
|||||||
|
|
||||||
enum filter_return f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags);
|
enum filter_return f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags);
|
||||||
enum filter_return f_run_args(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, int flags);
|
enum filter_return f_run_args(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, int flags);
|
||||||
enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, struct f_val *pres);
|
enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, uint resc, struct f_val *resv);
|
||||||
enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
|
enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
|
||||||
|
|
||||||
struct f_val cf_eval(const struct f_inst *inst, int type);
|
struct f_val cf_eval(const struct f_inst *inst, int type);
|
||||||
|
@ -113,7 +113,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
|
|||||||
net_copy(e->net->n.addr, r->net);
|
net_copy(e->net->n.addr, r->net);
|
||||||
|
|
||||||
/* Evaluate the filter */
|
/* Evaluate the filter */
|
||||||
f_eval_rte(r->cmds, &e, static_lp, 0, NULL, NULL);
|
f_eval_rte(r->cmds, &e, static_lp, 0, NULL, 0, NULL);
|
||||||
|
|
||||||
/* Remove the temporary node */
|
/* Remove the temporary node */
|
||||||
e->net = NULL;
|
e->net = NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user