History

kconfig: Error out on duplicated kconfig inclusion

Let kconfig exit with error on duplicated Kconfig file inclusion. Repeated inclusion of Kbuild files are considered bad-practise with regard to maintenance; and Kconfig language is rich enough that there should be no need for that. If repeated inclusion of Kconfig files is detected, error out with messages like: Kconfig.inc1:4: error: repeated inclusion of Kconfig.inc3 Kconfig.inc2:3: note: location of first inclusion of Kconfig.inc3 While commit f094f8a1b273 ("kconfig: allow multiple inclusion of the same file") introduced detection of recursive inclusions of Kconfig files, it explicitly allowed repeated inclusions, unfortunately w/o reasoning.

Nicolas Schier committed 8 months ago

Commit 102d7121 parent 6de23f89 files · +55 −6Browse files

Unified · Split

9 files
  1. scripts/kconfig/lexer.l +2 −2
  2. scripts/kconfig/lkc.h +2 −1
  3. scripts/kconfig/tests/err_repeated_inc/Kconfig +3 −0
  4. scripts/kconfig/tests/err_repeated_inc/Kconfig.inc1 +4 −0
  5. scripts/kconfig/tests/err_repeated_inc/Kconfig.inc2 +3 −0
  6. scripts/kconfig/tests/err_repeated_inc/Kconfig.inc3 +1 −0
  7. scripts/kconfig/tests/err_repeated_inc/__init__.py +10 −0
  8. scripts/kconfig/tests/err_repeated_inc/expected_stderr +2 −0
  9. scripts/kconfig/util.c +28 −3
scripts/kconfig/lexer.l+2−2
@@ -402,7 +402,7 @@ void zconf_initscan(const char *name) · 401 unmodified lines
402402 exit(1);
403403 }
404404
405− cur_filename = file_lookup(name);
405+ cur_filename = file_lookup(name, NULL, 0);
406406 yylineno = 1;
407407 }
408408
@@ -443,7 +443,7 @@ void zconf_nextfile(const char *name) · 34 unmodified lines
443443 }
444444
445445 yylineno = 1;
446− cur_filename = file_lookup(name);
446+ cur_filename = file_lookup(name, cur_filename, cur_lineno);
447447 }
448448
449449 static void zconf_endfile(void)
scripts/kconfig/lkc.h+2−1
@@ -51,7 +51,8 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) · 50 unmodified lines
5151 }
5252
5353 /* util.c */
54−const char *file_lookup(const char *name);
54+const char *file_lookup(const char *name,
55+ const char *parent_name, int parent_lineno);
5556
5657 /* lexer.l */
5758 int yylex(void);
scripts/kconfig/tests/err_repeated_inc/Kconfig+3−0
@@ -0,0 +1,3 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+
3+source "Kconfig.inc1"
scripts/kconfig/tests/err_repeated_inc/Kconfig.inc1+4−0
@@ -0,0 +1,4 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+
3+source "Kconfig.inc2"
4+source "Kconfig.inc3"
scripts/kconfig/tests/err_repeated_inc/Kconfig.inc2+3−0
@@ -0,0 +1,3 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+
3+source "Kconfig.inc3"
scripts/kconfig/tests/err_repeated_inc/Kconfig.inc3+1−0
@@ -0,0 +1 @@
1+# SPDX-License-Identifier: GPL-2.0-only
scripts/kconfig/tests/err_repeated_inc/__init__.py+10−0
@@ -0,0 +1,10 @@
1+# SPDX-License-Identifier: GPL-2.0
2+"""
3+Detect repeated inclusion error.
4+
5+If repeated inclusion is detected, it should fail with error message.
6+"""
7+
8+def test(conf):
9+ assert conf.oldaskconfig() != 0
10+ assert conf.stderr_contains('expected_stderr')
scripts/kconfig/tests/err_repeated_inc/expected_stderr+2−0
@@ -0,0 +1,2 @@
1+Kconfig.inc1:4: error: Repeated inclusion of Kconfig.inc3
2+Kconfig.inc2:3: note: Location of first inclusion of Kconfig.inc3
scripts/kconfig/util.c+28−3
@@ -18,25 +18,50 @@ static HASHTABLE_DEFINE(file_hashtable, 1U << 11); · 17 unmodified lines
1818
1919 struct file {
2020 struct hlist_node node;
21+ struct {
22+ const char *name;
23+ int lineno;
24+ } parent;
2125 char name[];
2226 };
2327
28+static void die_duplicated_include(struct file *file,
29+ const char *parent, int lineno)
30+{
31+ fprintf(stderr,
32+ "%s:%d: error: repeated inclusion of %s\n"
33+ "%s:%d: note: location of first inclusion of %s\n",
34+ parent, lineno, file->name,
35+ file->parent.name, file->parent.lineno, file->name);
36+ exit(1);
37+}
38+
2439 /* file already present in list? If not add it */
25−const char *file_lookup(const char *name)
40+const char *file_lookup(const char *name,
41+ const char *parent_name, int parent_lineno)
2642 {
43+ const char *parent = NULL;
2744 struct file *file;
2845 size_t len;
2946 int hash = hash_str(name);
3047
48+ if (parent_name)
49+ parent = file_lookup(parent_name, NULL, 0);
50+
3151 hash_for_each_possible(file_hashtable, file, node, hash)
32− if (!strcmp(name, file->name))
33− return file->name;
52+ if (!strcmp(name, file->name)) {
53+ if (!parent_name)
54+ return file->name;
55+ die_duplicated_include(file, parent, parent_lineno);
56+ }
3457
3558 len = strlen(name);
3659 file = xmalloc(sizeof(*file) + len + 1);
3760 memset(file, 0, sizeof(*file));
3861 memcpy(file->name, name, len);
3962 file->name[len] = '\0';
63+ file->parent.name = parent;
64+ file->parent.lineno = parent_lineno;
4065
4166 hash_add(file_hashtable, &file->node, hash);
4267