* [LTP] [PATCH v2 1/2] lib: tst_bool_expr: Add support for strings
2020-11-12 15:47 [LTP] [PATCH v2 0/2] Add support for kconfig strings Cyril Hrubis
@ 2020-11-12 15:47 ` Cyril Hrubis
2020-11-12 15:47 ` [LTP] [PATCH v2 2/2] lib/tst_kconfig: Validate variables Cyril Hrubis
2020-11-18 10:22 ` [LTP] [PATCH v2 0/2] Add support for kconfig strings Richard Palethorpe
2 siblings, 0 replies; 5+ messages in thread
From: Cyril Hrubis @ 2020-11-12 15:47 UTC (permalink / raw)
To: ltp
There are cases where special characters, e.g. parentesis appear in the
value of a kernel config variable, so in order to be able to parse
boolean variables such as "CONFIG_DEFAULT_HOSTNAME=\"(none)\"" the
tokenizer must be able to parse strings.
The implementation is easy, when in string we do not split the input
into tokens.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
lib/newlib_tests/config01 | 1 +
lib/newlib_tests/config02 | 1 +
lib/newlib_tests/config03 | 1 +
lib/newlib_tests/config04 | 1 +
lib/newlib_tests/config05 | 1 +
lib/newlib_tests/test_kconfig.c | 1 +
lib/newlib_tests/tst_bool_expr.c | 3 +++
lib/tst_bool_expr.c | 7 +++++++
8 files changed, 16 insertions(+)
diff --git a/lib/newlib_tests/config01 b/lib/newlib_tests/config01
index 96d68d836..1d94d810a 100644
--- a/lib/newlib_tests/config01
+++ b/lib/newlib_tests/config01
@@ -2,3 +2,4 @@
CONFIG_MMU=y
CONFIG_EXT4_FS=m
CONFIG_PGTABLE_LEVELS=4
+CONFIG_DEFAULT_HOSTNAME="(none)"
diff --git a/lib/newlib_tests/config02 b/lib/newlib_tests/config02
index 2de45cff8..e1b0e8086 100644
--- a/lib/newlib_tests/config02
+++ b/lib/newlib_tests/config02
@@ -2,3 +2,4 @@
# CONFIG_MMU is not set
CONFIG_EXT4_FS=m
CONFIG_PGTABLE_LEVELS=4
+CONFIG_DEFAULT_HOSTNAME="(none)"
diff --git a/lib/newlib_tests/config03 b/lib/newlib_tests/config03
index 1a3b9e648..05c8e194a 100644
--- a/lib/newlib_tests/config03
+++ b/lib/newlib_tests/config03
@@ -2,3 +2,4 @@
CONFIG_MMU=y
CONFIG_EXT4_FS=m
CONFIG_PGTABLE_LEVELS=44
+CONFIG_DEFAULT_HOSTNAME="(none)"
diff --git a/lib/newlib_tests/config04 b/lib/newlib_tests/config04
index cce7051ae..da01579b6 100644
--- a/lib/newlib_tests/config04
+++ b/lib/newlib_tests/config04
@@ -2,3 +2,4 @@
CONFIG_MMU=y
CONFIG_EXT4_FS=y
CONFIG_PGTABLE_LEVELS=4
+CONFIG_DEFAULT_HOSTNAME="(none)"
diff --git a/lib/newlib_tests/config05 b/lib/newlib_tests/config05
index a9d7bab4d..490f94fa6 100644
--- a/lib/newlib_tests/config05
+++ b/lib/newlib_tests/config05
@@ -1,3 +1,4 @@
# Everything is wrong
CONFIG_EXT4_FS=y
CONFIG_PGTABLE_LEVELS=44
+CONFIG_DEFAULT_HOSTNAME=""
diff --git a/lib/newlib_tests/test_kconfig.c b/lib/newlib_tests/test_kconfig.c
index 1f659b95a..9280f07ca 100644
--- a/lib/newlib_tests/test_kconfig.c
+++ b/lib/newlib_tests/test_kconfig.c
@@ -16,6 +16,7 @@ static const char *kconfigs[] = {
"CONFIG_PGTABLE_LEVELS=4",
"CONFIG_MMU & CONFIG_EXT4_FS=m",
"CONFIG_EXT4_FS=m | CONFIG_MMU",
+ "CONFIG_DEFAULT_HOSTNAME=\"(none)\"",
NULL
};
diff --git a/lib/newlib_tests/tst_bool_expr.c b/lib/newlib_tests/tst_bool_expr.c
index f9bb1780d..8f0929d35 100644
--- a/lib/newlib_tests/tst_bool_expr.c
+++ b/lib/newlib_tests/tst_bool_expr.c
@@ -102,6 +102,9 @@ static void do_test(void)
do_eval_test("False & A", 1, 0, 0, 0);
do_eval_test("! Undefined", 0, 0, 0, -1);
+ do_eval_test("\"(none)\"", 0, 0, 0, -1);
+ do_eval_test("\"(none)\" & \" \"", 0, 0, 0, -1);
+
parse_fail("A!");
parse_fail("A &");
parse_fail("A B");
diff --git a/lib/tst_bool_expr.c b/lib/tst_bool_expr.c
index dd147cde3..387c38b91 100644
--- a/lib/tst_bool_expr.c
+++ b/lib/tst_bool_expr.c
@@ -81,6 +81,13 @@ static unsigned int tokenize(const char *expr, struct tst_expr_tok *last)
token_cnt += new_tok(&last, &expr[j], i - j);
j = i+1;
break;
+ case '"':
+ while (expr[i+1] != '"' && expr[i+1])
+ i++;
+
+ if (expr[i+1] == '"')
+ i++;
+ break;
default:
break;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [LTP] [PATCH v2 2/2] lib/tst_kconfig: Validate variables
2020-11-12 15:47 [LTP] [PATCH v2 0/2] Add support for kconfig strings Cyril Hrubis
2020-11-12 15:47 ` [LTP] [PATCH v2 1/2] lib: tst_bool_expr: Add support for strings Cyril Hrubis
@ 2020-11-12 15:47 ` Cyril Hrubis
2020-11-18 10:22 ` [LTP] [PATCH v2 0/2] Add support for kconfig strings Richard Palethorpe
2 siblings, 0 replies; 5+ messages in thread
From: Cyril Hrubis @ 2020-11-12 15:47 UTC (permalink / raw)
To: ltp
Add variable validation so that we catch typos even before we attempt to
evaluate the expressions.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
lib/newlib_tests/.gitignore | 1 +
lib/newlib_tests/test_kconfig02.c | 29 +++++++++
lib/tst_kconfig.c | 102 ++++++++++++++++++++++++++++++
3 files changed, 132 insertions(+)
create mode 100644 lib/newlib_tests/test_kconfig02.c
diff --git a/lib/newlib_tests/.gitignore b/lib/newlib_tests/.gitignore
index 89de61cf7..ac1d19be0 100644
--- a/lib/newlib_tests/.gitignore
+++ b/lib/newlib_tests/.gitignore
@@ -32,6 +32,7 @@ test_exec
test_exec_child
test_kconfig
test_kconfig01
+test_kconfig02
variant
test_guarded_buf
tst_bool_expr
diff --git a/lib/newlib_tests/test_kconfig02.c b/lib/newlib_tests/test_kconfig02.c
new file mode 100644
index 000000000..176929222
--- /dev/null
+++ b/lib/newlib_tests/test_kconfig02.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * Invalid boolean expression test.
+ */
+
+#include "tst_test.h"
+
+static void do_test(void)
+{
+ tst_res(TPASS, "Test passed!");
+}
+
+static const char *kconfigs[] = {
+ "\"CONFIG_FOO=val\"",
+ "CONFIG_a=1",
+ "CONFIG_FOO=",
+ "CONFIG_DEFAULT_HOSTNAME=\"(none",
+ "CONFIG_DEFAULT_HOSTNAME=\"(none)\"a",
+ "CONFIG_BROKEN=a\" | CONFIG_FOO",
+ "CONFIG_BROKEN=a=",
+ NULL
+};
+
+static struct tst_test test = {
+ .test_all = do_test,
+ .needs_kconfigs = kconfigs,
+};
diff --git a/lib/tst_kconfig.c b/lib/tst_kconfig.c
index 468f03a86..72830703c 100644
--- a/lib/tst_kconfig.c
+++ b/lib/tst_kconfig.c
@@ -224,6 +224,105 @@ static inline unsigned int get_len(const char* kconfig, unsigned int len)
return sep - kconfig;
}
+static void print_err(FILE *f, const struct tst_expr_tok *var,
+ size_t spaces, const char *err)
+{
+ size_t i;
+
+ for (i = 0; i < var->tok_len; i++)
+ fputc(var->tok[i], f);
+
+ fputc('\n', f);
+
+ while (spaces--)
+ fputc(' ', f);
+
+ fprintf(f, "^\n%s\n\n", err);
+}
+
+static int validate_var(const struct tst_expr_tok *var)
+{
+ size_t i = 7;
+
+ if (var->tok_len < 7 || strncmp(var->tok, "CONFIG_", 7)) {
+ print_err(stderr, var, 0, "Expected CONFIG_ prefix");
+ return 1;
+ }
+
+ while (var->tok[i]) {
+ char c;
+
+ if (i >= var->tok_len)
+ return 0;
+
+ c = var->tok[i];
+
+ if ((c >= 'A' && c <= 'Z') || c == '_') {
+ i++;
+ continue;
+ }
+
+ if (c == '=') {
+ i++;
+ break;
+ }
+
+ print_err(stderr, var, i, "Unexpected character in variable name");
+ return 1;
+ }
+
+ if (i >= var->tok_len) {
+ print_err(stderr, var, i, "Missing value");
+ return 1;
+ }
+
+ if (var->tok[i] == '"') {
+ do {
+ i++;
+ } while (i < var->tok_len && var->tok[i] != '"');
+
+ if (i < var->tok_len) {
+ print_err(stderr, var, i, "Garbage after a string");
+ return 1;
+ }
+
+ if (var->tok[i] != '"') {
+ print_err(stderr, var, i, "Untermianted string");
+ return 1;
+ }
+
+ return 0;
+ }
+
+ do {
+ i++;
+ } while (i < var->tok_len && isalnum(var->tok[i]));
+
+ if (i < var->tok_len) {
+ print_err(stderr, var, i, "Invalid character in variable value");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int validate_vars(struct tst_expr *const exprs[], unsigned int expr_cnt)
+{
+ unsigned int i;
+ const struct tst_expr_tok *j;
+ unsigned int ret = 0;
+
+ for (i = 0; i < expr_cnt; i++) {
+ for (j = exprs[i]->rpn; j; j = j->next) {
+ if (j->op == TST_OP_VAR)
+ ret |= validate_var(j);
+ }
+ }
+
+ return ret;
+}
+
+
static inline unsigned int get_var_cnt(struct tst_expr *const exprs[],
unsigned int expr_cnt)
{
@@ -372,6 +471,9 @@ void tst_kconfig_check(const char *const kconfigs[])
tst_brk(TBROK, "Invalid kconfig expression!");
}
+ if (validate_vars(exprs, expr_cnt))
+ tst_brk(TBROK, "Invalid kconfig variables!");
+
var_cnt = get_var_cnt(exprs, expr_cnt);
struct tst_kconfig_var vars[var_cnt];
--
2.26.2
^ permalink raw reply related [flat|nested] 5+ messages in thread