diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cb4fb85c..53577c535 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,8 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/tools/hw-oracle/test_hw_oracle.py) add_test(NAME pr_overlap_exports COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pr_overlap_exports.py) + add_test(NAME pr_overlap_wrapped_exports COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pr_overlap_wrapped_exports.py) add_test(NAME nid_database_cache COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_nid_names.py) endif() diff --git a/tools/pr_overlap.py b/tools/pr_overlap.py index e84ee058d..82aa9b527 100644 --- a/tools/pr_overlap.py +++ b/tools/pr_overlap.py @@ -70,9 +70,18 @@ def commit(tree): def exports(diff): found = set() - for line in diff.splitlines(): + lines = diff.splitlines() + for i, line in enumerate(lines): m = EXPORT.match(line) - if m and not m.group(1).endswith("_nid_no_patch") and not line.rstrip().endswith(";"): + if not m or m.group(1).endswith("_nid_no_patch"): + continue + text = line[1:] + for nxt in lines[i + 1:]: + if ";" in text or "{" in text or not nxt.startswith("+") or nxt.startswith("+++"): + break + text += nxt[1:] + semi, brace = text.find(";"), text.find("{") + if semi < 0 or 0 <= brace < semi: found.add(m.group(1)) return found diff --git a/tools/tests/test_pr_overlap_wrapped_exports.py b/tools/tests/test_pr_overlap_wrapped_exports.py new file mode 100644 index 000000000..96dbd2232 --- /dev/null +++ b/tools/tests/test_pr_overlap_wrapped_exports.py @@ -0,0 +1,28 @@ +import sys +import unittest +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) +import pr_overlap + +DECL = "+int APS5_VABI sceFooBar(int a,\n+ int b);\n" + + +class WrappedExportTests(unittest.TestCase): + def test_wrapped_declaration_is_not_export(self): + self.assertEqual(pr_overlap.exports(DECL), set()) + + def test_wrapped_definition_is_export(self): + diff = "+int APS5_VABI sceFooBar(int a,\n+ int b) {\n+ return a + b;\n+}\n" + self.assertEqual(pr_overlap.exports(diff), {"sceFooBar"}) + + def test_declaration_then_definition_returns_only_definition(self): + diff = DECL + "+int APS5_VABI sceBaz(int a) { return a; }\n" + self.assertEqual(pr_overlap.exports(diff), {"sceBaz"}) + + def test_declaration_at_end_of_diff(self): + self.assertEqual(pr_overlap.exports("+int APS5_VABI sceFooBar(int a, int b);"), set()) + + +if __name__ == "__main__": + unittest.main()