summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/rule.h1
-rw-r--r--src/parser_bison.y22
-rw-r--r--src/rule.c15
-rw-r--r--src/scanner.l2
4 files changed, 40 insertions, 0 deletions
diff --git a/include/rule.h b/include/rule.h
index d9c172dd..531222ce 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -82,6 +82,7 @@ struct symbol {
extern void symbol_bind(struct scope *scope, const char *identifier,
struct expr *expr);
+extern int symbol_unbind(struct scope *scope, const char *identifier);
extern struct symbol *symbol_lookup(const struct scope *scope,
const char *identifier);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index ec8b0dd8..df672b1e 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -185,6 +185,8 @@ int nft_lex(void *, void *, void *);
%token INCLUDE "include"
%token DEFINE "define"
+%token REDEFINE "redefine"
+%token UNDEFINE "undefine"
%token FIB "fib"
@@ -763,6 +765,26 @@ common_block : INCLUDE QUOTED_STRING stmt_separator
symbol_bind(scope, $2, $4);
xfree($2);
}
+ | REDEFINE identifier '=' initializer_expr stmt_separator
+ {
+ struct scope *scope = current_scope(state);
+
+ /* ignore missing identifier */
+ symbol_unbind(scope, $2);
+ symbol_bind(scope, $2, $4);
+ xfree($2);
+ }
+ | UNDEFINE identifier stmt_separator
+ {
+ struct scope *scope = current_scope(state);
+
+ if (symbol_unbind(scope, $2) < 0) {
+ erec_queue(error(&@2, "undefined symbol '%s'", $2),
+ state->msgs);
+ YYERROR;
+ }
+ xfree($2);
+ }
| error stmt_separator
{
if (++state->nerrs == nft->parser_max_errors)
diff --git a/src/rule.c b/src/rule.c
index c7b4b498..5b7219e8 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -485,6 +485,21 @@ void symbol_bind(struct scope *scope, const char *identifier, struct expr *expr)
list_add_tail(&sym->list, &scope->symbols);
}
+int symbol_unbind(struct scope *scope, const char *identifier)
+{
+ struct symbol *sym;
+
+ sym = symbol_lookup(scope, identifier);
+ if (!sym)
+ return -1;
+
+ list_del(&sym->list);
+ xfree(sym->identifier);
+ expr_free(sym->expr);
+ xfree(sym);
+ return 0;
+}
+
struct symbol *symbol_lookup(const struct scope *scope, const char *identifier)
{
struct symbol *sym;
diff --git a/src/scanner.l b/src/scanner.l
index c3992a78..05c70afe 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -233,6 +233,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"include" { return INCLUDE; }
"define" { return DEFINE; }
+"redefine" { return REDEFINE; }
+"undefine" { return UNDEFINE; }
"describe" { return DESCRIBE; }