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