diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-12-01 12:06:46 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-12-01 12:09:24 +0100 |
commit | be79e9c3467b324216688047c81315f0d3e51d24 (patch) | |
tree | 97616474615a0f1a0d44c42884f5e360ea8abd9d | |
parent | fa145fdf73d663eb69751800911cdd2853689dee (diff) |
src: introduce simple hints on incorrect identifier
# cat test.nft
define test = "1.2.3.4"
table ip x {
chain y {
ip saddr $text
}
}
# nft -f test.nft
test.nft:5:13-16: Error: unknown identifier 'text'; did you mean identifier ‘test’?
ip saddr $text
^^^^
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | include/rule.h | 2 | ||||
-rw-r--r-- | src/parser_bison.y | 12 | ||||
-rw-r--r-- | src/rule.c | 18 |
3 files changed, 30 insertions, 2 deletions
diff --git a/include/rule.h b/include/rule.h index 88fed62e..dc5e5b87 100644 --- a/include/rule.h +++ b/include/rule.h @@ -112,6 +112,8 @@ extern void symbol_bind(struct scope *scope, const char *identifier, extern int symbol_unbind(const struct scope *scope, const char *identifier); extern struct symbol *symbol_lookup(const struct scope *scope, const char *identifier); +struct symbol *symbol_lookup_fuzzy(const struct scope *scope, + const char *identifier); struct symbol *symbol_get(const struct scope *scope, const char *identifier); enum table_flags { diff --git a/src/parser_bison.y b/src/parser_bison.y index dfe30683..e73e1ecd 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -3078,8 +3078,16 @@ variable_expr : '$' identifier sym = symbol_get(scope, $2); if (!sym) { - erec_queue(error(&@2, "unknown identifier '%s'", $2), - state->msgs); + sym = symbol_lookup_fuzzy(scope, $2); + if (sym) { + erec_queue(error(&@2, "unknown identifier '%s'; " + "did you mean identifier ‘%s’?", + $2, sym->identifier), + state->msgs); + } else { + erec_queue(error(&@2, "unknown identifier '%s'", $2), + state->msgs); + } xfree($2); YYERROR; } @@ -692,6 +692,24 @@ struct symbol *symbol_lookup(const struct scope *scope, const char *identifier) return NULL; } +struct symbol *symbol_lookup_fuzzy(const struct scope *scope, + const char *identifier) +{ + struct string_misspell_state st; + struct symbol *sym; + + string_misspell_init(&st); + + while (scope != NULL) { + list_for_each_entry(sym, &scope->symbols, list) + string_misspell_update(sym->identifier, identifier, + sym, &st); + + scope = scope->parent; + } + return st.obj; +} + static const char * const chain_type_str_array[] = { "filter", "nat", |