Merge pull request #3515 from Winvoker/fix/progress-stub-call-whitespace
fix(progress): match stub calls across whitespace
This commit is contained in:
commit
c5da8233a5
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## Library counts
|
||||
|
||||
The scanner reads `APS5_VABI` function definitions under `core/libs/prx/<library>/`, excluding `tests` subdirectories and their descendants. Test callbacks do not contribute to library counts. A definition is pending when its body calls `NotImplemented_nid_no_patch`, directly or through a recognized local stub wrapper. Other definitions are counted as implemented. Braces inside string literals, character literals and comments do not delimit bodies. These counts describe declared functions, not every firmware export, verified ABI compatibility or playable games. Silent behavior and unverified assumptions remain in [Technical debt](TechnicalDebt.md).
|
||||
The scanner reads `APS5_VABI` function definitions under `core/libs/prx/<library>/`, excluding `tests` subdirectories and their descendants. Test callbacks do not contribute to library counts. A definition is pending when its body calls `NotImplemented_nid_no_patch`, directly or through a recognized local stub wrapper. Call matching uses complete identifiers and accepts whitespace or comments before `(`. Other definitions are counted as implemented. Braces inside string literals, character literals and comments do not delimit bodies. These counts describe declared functions, not every firmware export, verified ABI compatibility or playable games. Silent behavior and unverified assumptions remain in [Technical debt](TechnicalDebt.md).
|
||||
|
||||
A library with no scanned definitions can include a sibling library's source builder. The scanner recognizes literal `include(${CMAKE_CURRENT_SOURCE_DIR}/../<library>/<file>.cmake)` references, including quoted paths. It does not evaluate arbitrary CMake expressions. It also recognizes a top-level `.cpp` that includes another library's source with `#include "prx/<library>/<file>.cpp"`.
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ ISA = Path(__file__).resolve().parent / "rdna_isa.txt"
|
|||
SOURCE = f'https://github.com/{os.environ.get("GITHUB_REPOSITORY", "boykopovar/AnyPS5")}/blob/main'
|
||||
DEFINITION = re.compile(r"\bAPS5_VABI\s+(\w+)\s*\([^;{]*\)\s*(?:noexcept\s*)?(?:try\s*)?\{")
|
||||
STUB = "NotImplemented_nid_no_patch"
|
||||
CALL = re.compile(r"\b(\w+)\s*\(")
|
||||
CMAKE_SHARED = re.compile(r'^\s*include\(\s*"?\$\{CMAKE_CURRENT_SOURCE_DIR\}/\.\./([\w.-]+)/[\w.-]+\.cmake"?\s*\)', re.M)
|
||||
SOURCE_SHARED = re.compile(r'^\s*#\s*include\s*"prx/([\w.-]+)/[\w./-]+\.cpp"', re.M)
|
||||
STUB_WRAPPER = re.compile(r"\bstatic\s+(?:\[\[noreturn\]\]\s+)?[\w:<>,\s*&]+?\s+(\w+)\s*\([^;{]*\)\s*\{")
|
||||
|
|
@ -91,10 +92,11 @@ def body_end(text, start):
|
|||
|
||||
|
||||
def stub_calls(text):
|
||||
calls = [STUB]
|
||||
calls = {STUB}
|
||||
for match in STUB_WRAPPER.finditer(text):
|
||||
if STUB in text[match.end() - 1:body_end(text, match.end() - 1)]:
|
||||
calls.append(match.group(1) + "(")
|
||||
body = text[match.end() - 1:body_end(text, match.end() - 1)]
|
||||
if any(call.group(1) == STUB for call in CALL.finditer(body)):
|
||||
calls.add(match.group(1))
|
||||
return calls
|
||||
|
||||
|
||||
|
|
@ -156,7 +158,7 @@ def scan_library(path):
|
|||
if name.endswith("_nid_no_patch"):
|
||||
continue
|
||||
body = text[match.end() - 1:body_end(text, match.end() - 1)]
|
||||
if any(call in body for call in calls):
|
||||
if any(call.group(1) in calls for call in CALL.finditer(body)):
|
||||
todo.add(name)
|
||||
continue
|
||||
done.add(name)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,30 @@ class ProgressTests(unittest.TestCase):
|
|||
self.assertEqual(group["done_names"], [])
|
||||
self.assertEqual(group["todo_names"], ["sceExampleSupportFormat"])
|
||||
|
||||
def test_stub_wrapper_calls_allow_whitespace(self):
|
||||
for separator in ("", " ", "\t", "\n", " /* separator */ "):
|
||||
with self.subTest(separator=separator), tempfile.TemporaryDirectory() as directory:
|
||||
library = Path(directory) / "libSceExample"
|
||||
library.mkdir()
|
||||
(library / "Export.cpp").write_text(
|
||||
"static int Unsupported() { NotImplemented_nid_no_patch(__func__); return 0; }\n"
|
||||
f"int APS5_VABI Pending() {{ return Unsupported{separator}(); }}\n")
|
||||
group = progress.scan_library(library)
|
||||
self.assertEqual(group["done_names"], [])
|
||||
self.assertEqual(group["todo_names"], ["Pending"])
|
||||
|
||||
def test_stub_wrapper_names_match_whole_identifiers(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
library = Path(directory) / "libSceExample"
|
||||
library.mkdir()
|
||||
(library / "Export.cpp").write_text(
|
||||
"static int Unsupported() { NotImplemented_nid_no_patch(__func__); return 0; }\n"
|
||||
"static int NotUnsupported(int value) { return value * 2; }\n"
|
||||
"int APS5_VABI Ready(int value) { return NotUnsupported(value); }\n")
|
||||
group = progress.scan_library(library)
|
||||
self.assertEqual(group["done_names"], ["Ready"])
|
||||
self.assertEqual(group["todo_names"], [])
|
||||
|
||||
def test_braces_in_literals_and_comments_do_not_delimit_bodies(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
library = Path(directory) / "libSceExample"
|
||||
|
|
|
|||
Loading…
Reference in New Issue