Merge pull request #4575 from MiniRML/fix/progress-raw-string-literals

fix(progress): ignore C++ raw-string contents
This commit is contained in:
Adrià 2026-10-13 17:19:23 +02:00 committed by GitHub
commit 5a76fd716f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 5 deletions

View File

@ -1,4 +1,5 @@
import argparse
import importlib.util
import json
import os
import re
@ -6,6 +7,11 @@ import sys
from html import escape
from pathlib import Path
tokenizer_spec = importlib.util.spec_from_file_location("anyps5_cpp_tokenizer", Path(__file__).with_name("nid_names.py"))
tokenizer = importlib.util.module_from_spec(tokenizer_spec)
tokenizer_spec.loader.exec_module(tokenizer)
CPP_TOKEN = tokenizer.CPP_TOKEN
ROOT = Path(__file__).resolve().parent.parent
PRX = ROOT / "core" / "libs" / "prx"
OPCODES = ROOT / "core" / "shader" / "recompiler" / "RdnaDecoder" / "include" / "RdnaDecoder" / "RdnaOpcode.hpp"
@ -20,7 +26,6 @@ STUB_WRAPPER = re.compile(
r"^[ \t]*(?:static\s+)?(?:\[\[noreturn\]\]\s+)?(?:(?!APS5_VABI)[\w:<>,\s*&])+?[\s*&]"
r"(?!(?:if|while|for|switch|catch|return|else)\b)(\w+)\s*\([^;{]*\)\s*"
r"(?:const\s*)?(?:noexcept\s*)?(?:->\s*[\w:<>*&\s]+?)?\{", re.M)
NON_CODE = re.compile(r'"(?:\\.|[^"\\\n])*"|\'(?:\\.|[^\'\\\n])*\'|//[^\n]*|/\*.*?\*/', re.S)
DISCARD = re.compile(r"\(void\)\s*\w+\s*;")
EMPTY_RETURN = re.compile(r"return\s*;")
CONST_RETURN = re.compile(r"return\s+(?:[+-]?\s*(?:0[xX][0-9a-fA-F]+|\d+)[uUlL]*|\w+|\"(?:\\.|[^\"\\])*\")\s*;")
@ -73,14 +78,15 @@ DONE_COLOR, TODO_COLOR, BORDER, TEXT = "#2ea043", "#6e7681", "#0d1117", "#ffffff
def blank(match):
if match.group(0).startswith(('"', "'")):
if match.group("code") is not None:
return match.group()
if match.group("comment") is None:
return "LITERAL"
return re.sub(r"[^\n]", " ", match.group(0))
return re.sub(r"[^\n]", " ", match.group())
def code(text):
return NON_CODE.sub(blank, text)
return CPP_TOKEN.sub(blank, text.replace("\\\n", "").replace("\\\r\n", ""))
def body_end(text, start):
depth = 0

View File

@ -9,6 +9,30 @@ import progress
class ProgressTests(unittest.TestCase):
def test_raw_string_example_does_not_declare_an_export(self):
source = 'const char* example = R"help(\nint APS5_VABI Fake() { return 0; }\n)help";\n'
source += 'int APS5_VABI Real() { return 7; }\n'
with tempfile.TemporaryDirectory() as directory:
library = Path(directory) / "libSceExample"
library.mkdir()
(library / "Export.cpp").write_text(source, encoding="utf-8")
group = progress.scan_library(library)
self.assertEqual(group["done_names"], ["Real"])
self.assertEqual(group["todo_names"], [])
def test_stub_marker_inside_raw_literals_does_not_mark_implementation_as_stub(self):
for prefix in ("", "u8", "u", "U", "L"):
source = ('int APS5_VABI Ready(int value) {\n'
'auto message = ' + prefix + 'R"help(\n"quoted" NotImplemented_nid_no_patch(); } {\n)help";\n'
'return value + 1;\n}\n')
with self.subTest(prefix=prefix), tempfile.TemporaryDirectory() as directory:
library = Path(directory) / "libSceExample"
library.mkdir()
(library / "Export.cpp").write_text(source, encoding="utf-8")
group = progress.scan_library(library)
self.assertEqual(group["done_names"], ["Ready"])
self.assertEqual(group["todo_names"], [])
def test_nonvoid_stub_wrappers_keep_callers_unimplemented(self):
with tempfile.TemporaryDirectory() as directory:
library = Path(directory) / "libSceExample"