From 4bbda72743d39df29dfc91e0f52be02b2d465f6d Mon Sep 17 00:00:00 2001 From: Ricardo Martincoski Date: Sun, 27 Nov 2022 10:07:18 -0300 Subject: [PATCH] utils/checkpackagelib: warn about redefined config Warn the developer in the case the same config is declared more than once in the same Config.in file. But take into account the conditional code that lets the config be visible and warn only when it is declared more than once in the same conditions. For instance, do not warn for: if BR2_PACKAGE_BUSYBOX config BR2_PACKAGE_BUSYBOX_SHOW_OTHERS endif if !BR2_PACKAGE_BUSYBOX # kconfig doesn't support else config BR2_PACKAGE_BUSYBOX_SHOW_OTHERS endif Signed-off-by: Ricardo Martincoski Signed-off-by: Peter Korsgaard --- utils/checkpackagelib/lib_config.py | 38 ++++++++++++ utils/checkpackagelib/test_lib_config.py | 78 ++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/utils/checkpackagelib/lib_config.py b/utils/checkpackagelib/lib_config.py index b05831f2c3..f26ca0d898 100644 --- a/utils/checkpackagelib/lib_config.py +++ b/utils/checkpackagelib/lib_config.py @@ -233,3 +233,41 @@ class Indent(_CheckFunction): return ["{}:{}: should not be indented" .format(self.filename, lineno), text] + + +class RedefinedConfig(_CheckFunction): + CONFIG = re.compile(r"^\s*(menu|)config\s+(BR2_\w+)\b") + IF = re.compile(r"^\s*if\s+([^#]*)\b") + ENDIF = re.compile(r"^\s*endif\b") + + def before(self): + self.configs = {} + self.conditional = [] + + def check_line(self, lineno, text): + if _empty_or_comment(text) or _part_of_help_text(text): + return + + m = self.IF.search(text) + if m is not None: + condition = m.group(1) + self.conditional.append(condition) + return + + m = self.ENDIF.search(text) + if m is not None: + self.conditional.pop() + return + + m = self.CONFIG.search(text) + if m is None: + return + config = m.group(2) + + key = (config, ' AND '.join(self.conditional)) + if key in self.configs.keys(): + previous_line = self.configs[key] + return ["{}:{}: config {} redeclared (previous line: {})" + .format(self.filename, lineno, config, previous_line), + text] + self.configs[key] = lineno diff --git a/utils/checkpackagelib/test_lib_config.py b/utils/checkpackagelib/test_lib_config.py index 91a549adf2..474d17105e 100644 --- a/utils/checkpackagelib/test_lib_config.py +++ b/utils/checkpackagelib/test_lib_config.py @@ -385,3 +385,81 @@ Indent = [ def test_Indent(testname, filename, string, expected): warnings = util.check_file(m.Indent, filename, string) assert warnings == expected + + +RedefinedConfig = [ + ('no redefinition', + 'any', + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'config BR2_PACKAGE_FOO_BAR\n' + 'bool "foo"\n', + []), + ('no conditional', + 'any', + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'config BR2_PACKAGE_BAR\n' + 'bool "bar"\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n', + [['any:5: config BR2_PACKAGE_FOO redeclared (previous line: 1)', + 'config BR2_PACKAGE_FOO\n']]), + ('three times', + 'any', + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n', + [['any:3: config BR2_PACKAGE_FOO redeclared (previous line: 1)', + 'config BR2_PACKAGE_FOO\n'], + ['any:5: config BR2_PACKAGE_FOO redeclared (previous line: 1)', + 'config BR2_PACKAGE_FOO\n']]), + ('same conditional', + 'any', + 'if BR2_PACKAGE_BAZ\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'config BR2_PACKAGE_BAR\n' + 'bool "bar"\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'endif\n', + [['any:6: config BR2_PACKAGE_FOO redeclared (previous line: 2)', + 'config BR2_PACKAGE_FOO\n']]), + ('equivalent conditional', + 'any', + 'if BR2_PACKAGE_BAZ\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'endif\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'if BR2_PACKAGE_BAZ\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'endif\n', + [['any:8: config BR2_PACKAGE_FOO redeclared (previous line: 2)', + 'config BR2_PACKAGE_FOO\n']]), + ('not equivalent conditional', + 'any', + 'if BR2_PACKAGE_BAZ\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'endif\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'if !BR2_PACKAGE_BAZ\n' + 'config BR2_PACKAGE_FOO\n' + 'bool "foo"\n' + 'endif\n', + []), + ] + + +@pytest.mark.parametrize('testname,filename,string,expected', RedefinedConfig) +def test_RedefinedConfig(testname, filename, string, expected): + warnings = util.check_file(m.RedefinedConfig, filename, string) + assert warnings == expected