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

Showing the changes to scripts (9 of 9 files). Show all

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
402 exit(1);402 exit(1);
403 }403 }
404 404
405 cur_filename = file_lookup(name);405 cur_filename = file_lookup(name, NULL, 0);
406 yylineno = 1;406 yylineno = 1;
407}407}
408 408
@@ -443,7 +443,7 @@ void zconf_nextfile(const char *name) · 34 unmodified lines
443 }443 }
444 444
445 yylineno = 1;445 yylineno = 1;
446 cur_filename = file_lookup(name);446 cur_filename = file_lookup(name, cur_filename, cur_lineno);
447}447}
448 448
449static void zconf_endfile(void)449static 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
51}51}
52 52
53/* util.c */53/* util.c */
54const char *file_lookup(const char *name);54const char *file_lookup(const char *name,
55 const char *parent_name, int parent_lineno);
55 56
56/* lexer.l */57/* lexer.l */
57int yylex(void);58int yylex(void);
scripts/kconfig/tests/err_repeated_inc/Kconfig+3−0
@@ -0,0 +1,3 @@
1# SPDX-License-Identifier: GPL-2.0-only
2
3source "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
3source "Kconfig.inc2"
4source "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
3source "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"""
3Detect repeated inclusion error.
4
5If repeated inclusion is detected, it should fail with error message.
6"""
7
8def 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 @@
1Kconfig.inc1:4: error: Repeated inclusion of Kconfig.inc3
2Kconfig.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
18 18
19struct file {19struct file {
20 struct hlist_node node;20 struct hlist_node node;
21 struct {
22 const char *name;
23 int lineno;
24 } parent;
21 char name[];25 char name[];
22};26};
23 27
28static 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
24/* file already present in list? If not add it */39/* file already present in list? If not add it */
25const char *file_lookup(const char *name)40const char *file_lookup(const char *name,
41 const char *parent_name, int parent_lineno)
26{42{
43 const char *parent = NULL;
27 struct file *file;44 struct file *file;
28 size_t len;45 size_t len;
29 int hash = hash_str(name);46 int hash = hash_str(name);
30 47
48 if (parent_name)
49 parent = file_lookup(parent_name, NULL, 0);
50
31 hash_for_each_possible(file_hashtable, file, node, hash)51 hash_for_each_possible(file_hashtable, file, node, hash)
32 if (!strcmp(name, file->name))52 if (!strcmp(name, file->name)) {
33 return file->name;53 if (!parent_name)
54 return file->name;
55 die_duplicated_include(file, parent, parent_lineno);
56 }
34 57
35 len = strlen(name);58 len = strlen(name);
36 file = xmalloc(sizeof(*file) + len + 1);59 file = xmalloc(sizeof(*file) + len + 1);
37 memset(file, 0, sizeof(*file));60 memset(file, 0, sizeof(*file));
38 memcpy(file->name, name, len);61 memcpy(file->name, name, len);
39 file->name[len] = '\0';62 file->name[len] = '\0';
63 file->parent.name = parent;
64 file->parent.lineno = parent_lineno;
40 65
41 hash_add(file_hashtable, &file->node, hash);66 hash_add(file_hashtable, &file->node, hash);
42 67