summaryrefslogtreecommitdiffstats
path: root/filter/f-util.c
diff options
context:
space:
mode:
authorPavel Machek <pavel@ucw.cz>1999-03-08 21:30:06 +0100
committerPavel Machek <pavel@ucw.cz>1999-03-08 21:30:06 +0100
commitb7005824453583d1459b49c5a424b50e2ea9a2c8 (patch)
tree23579261136bbf4a67a5a50789bebb46bce1e7e5 /filter/f-util.c
parent111213f0b66cff8f562f7d9117c9080a9882129e (diff)
downloadbird-b7005824453583d1459b49c5a424b50e2ea9a2c8.tar
bird-b7005824453583d1459b49c5a424b50e2ea9a2c8.zip
Filters are now a tiny bit stronger (if is actually working ;-)
Diffstat (limited to 'filter/f-util.c')
-rw-r--r--filter/f-util.c85
1 files changed, 67 insertions, 18 deletions
diff --git a/filter/f-util.c b/filter/f-util.c
index 66bf5f1..ba74804 100644
--- a/filter/f-util.c
+++ b/filter/f-util.c
@@ -21,33 +21,73 @@
#include "conf/conf.h"
#include "filter/filter.h"
-struct f_instruction *last_func = NULL;
+struct f_inst *last_func = NULL;
-static void
-interpret(struct f_instruction *what)
+#define runtime die
+
+static struct f_val
+interpret(struct f_inst *what)
{
struct symbol *sym;
+ struct f_val v1, v2, res;
+
+ res.type = T_VOID;
if (!what)
- return;
+ return res;
+
switch(what->code) {
case ',':
interpret(what->arg1);
interpret(what->arg2);
break;
+ case '+':
+ v1 = interpret(what->arg1);
+ v2 = interpret(what->arg2);
+ if (v1.type != v2.type)
+ runtime( "Can not operate with values of incompatible types" );
+
+ switch (res.type = v1.type) {
+ case T_VOID: runtime( "Can not operate with values of type void" );
+ case T_INT: res.val.i = v1.val.i + v2.val.i; break;
+ default: runtime( "Usage of unknown type" );
+ }
+ break;
case '=':
+ v1 = interpret(what->arg2);
sym = what->arg1;
- sym->aux = (int) what->arg2;
+ switch (res.type = v1.type) {
+ case T_VOID: runtime( "Can not assign void values" );
+ case T_INT:
+ if (sym->class != SYM_VARIABLE_INT)
+ runtime( "Variable of bad type" );
+ sym->aux = v1.val.i;
+ break;
+ }
+ break;
+ case 'c':
+ res.type = T_INT;
+ res.val.i = (int) what->arg1;
+ break;
+ case 'i':
+ res.type = T_INT;
+ res.val.i = * ((int *) what->arg1);
break;
case 'p':
- sym = what->arg1;
- switch(sym->class) {
- case SYM_VARIABLE_INT:
- printf( "Printing: %d\n", sym->aux );
- break;
- default:
- printf( "Unknown type passed to print\n" );
- break;
+ v1 = interpret(what->arg1);
+ printf( "Printing: " );
+ switch (v1.type) {
+ case T_VOID: printf( "(void)" ); break;
+ case T_INT: printf( "%d", v1.val.i ); break;
+ default: runtime( "Print of variable of unknown type" );
}
+ printf( "\n" );
+ break;
+ case '?':
+ v1 = interpret(what->arg1);
+ if (v1.type != T_INT)
+ runtime( "If requires integer expression" );
+ if (v1.val.i)
+ res = interpret(what->arg2);
break;
case 'D':
printf( "DEBUGGING PRINT\n" );
@@ -55,8 +95,17 @@ interpret(struct f_instruction *what)
case '0':
printf( "No operation\n" );
break;
+ case 'd':
+ printf( "Puts: %s\n", what->arg1 );
+ break;
+ case '!':
+ die( "Filter asked me to die" );
+ default:
+ die( "Unknown insruction %d(%c)", what->code, what->code & 0xff);
}
- interpret(what->next);
+ if (what->next)
+ return interpret(what->next);
+ return res;
}
void
@@ -69,11 +118,11 @@ filters_postconfig(void)
}
}
-struct f_instruction *
+struct f_inst *
f_new_inst(void)
{
- struct f_instruction * ret;
- ret = cfg_alloc(sizeof(struct f_instruction));
+ struct f_inst * ret;
+ ret = cfg_alloc(sizeof(struct f_inst));
ret->code = 0;
ret->arg1 = ret->arg2 = ret->next = NULL;
return ret;
@@ -82,7 +131,7 @@ f_new_inst(void)
int
f_run(struct symbol *filter, struct rte *rtein, struct rte **rteout)
{
- struct f_instruction *inst;
+ struct f_inst *inst;
debug( "Running filter `%s'...", filter->name );
inst = filter->def;