summaryrefslogtreecommitdiffstats
path: root/src/datatype.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2023-05-09 17:46:52 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2023-05-11 18:18:29 +0200
commit8d586177b843af5e77f10e3f0c532341648582d0 (patch)
tree6283fce979c399d335cfff8301eb2cafd8330ed0 /src/datatype.c
parent686ab8b6996e154592a5fc16bd1e15e661201b2a (diff)
datatype: misspell support with symbol table parser for error reporting
Some datatypes provide a symbol table that is parsed as an integer. Improve error reporting by using the misspell infrastructure, to provide a hint to the user, whenever possible. If base datatype, usually the integer datatype, fails to parse the symbol, then try a fuzzy match on the symbol table to provide a hint in case the user has mistype it. For instance: test.nft:3:11-14: Error: Could not parse Differentiated Services Code Point expression; did you you mean `cs0`? ip dscp ccs0 ^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/datatype.c')
-rw-r--r--src/datatype.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/src/datatype.c b/src/datatype.c
index 002ed46a..2cefd0f3 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -28,6 +28,7 @@
#include <erec.h>
#include <netlink.h>
#include <json.h>
+#include <misspell.h>
#include <netinet/ip_icmp.h>
@@ -141,6 +142,43 @@ struct error_record *symbol_parse(struct parse_ctx *ctx, const struct expr *sym,
sym->dtype->desc);
}
+static struct error_record *__symbol_parse_fuzzy(const struct expr *sym,
+ const struct symbol_table *tbl)
+{
+ const struct symbolic_constant *s;
+ struct string_misspell_state st;
+
+ string_misspell_init(&st);
+
+ for (s = tbl->symbols; s->identifier != NULL; s++) {
+ string_misspell_update(sym->identifier, s->identifier,
+ (void *)s->identifier, &st);
+ }
+
+ if (st.obj) {
+ return error(&sym->location,
+ "Could not parse %s expression; did you you mean `%s`?",
+ sym->dtype->desc, st.obj);
+ }
+
+ return NULL;
+}
+
+static struct error_record *symbol_parse_fuzzy(const struct expr *sym,
+ const struct symbol_table *tbl)
+{
+ struct error_record *erec;
+
+ if (!tbl)
+ return NULL;
+
+ erec = __symbol_parse_fuzzy(sym, tbl);
+ if (erec)
+ return erec;
+
+ return NULL;
+}
+
struct error_record *symbolic_constant_parse(struct parse_ctx *ctx,
const struct expr *sym,
const struct symbol_table *tbl,
@@ -163,8 +201,16 @@ struct error_record *symbolic_constant_parse(struct parse_ctx *ctx,
do {
if (dtype->basetype->parse) {
erec = dtype->basetype->parse(ctx, sym, res);
- if (erec != NULL)
- return erec;
+ if (erec != NULL) {
+ struct error_record *fuzzy_erec;
+
+ fuzzy_erec = symbol_parse_fuzzy(sym, tbl);
+ if (!fuzzy_erec)
+ return erec;
+
+ erec_destroy(erec);
+ return fuzzy_erec;
+ }
if (*res)
return NULL;
goto out;