diff --git a/ps2xRecomp/include/ps2recomp/ps2_recompiler.h b/ps2xRecomp/include/ps2recomp/ps2_recompiler.h index b327ddad..10c9f5c2 100644 --- a/ps2xRecomp/include/ps2recomp/ps2_recompiler.h +++ b/ps2xRecomp/include/ps2recomp/ps2_recompiler.h @@ -40,6 +40,8 @@ namespace ps2recomp std::vector &functions, std::unordered_map> &decodedFunctions); + static std::string ClampFilenameLength(const std::string& baseName, const std::string& extension, std::size_t maxLength); + private: ConfigManager m_configManager; std::unique_ptr m_elfParser; @@ -70,6 +72,7 @@ namespace ps2recomp bool generateStubHeader(); bool writeToFile(const std::string &path, const std::string &content); std::filesystem::path getOutputPath(const Function &function) const; + static std::string clampFilenameLength(const std::string& baseName, const std::string& extension, std::size_t maxLength); std::string sanitizeFunctionName(const std::string &name) const; }; diff --git a/ps2xRecomp/src/lib/ps2_recompiler.cpp b/ps2xRecomp/src/lib/ps2_recompiler.cpp index a85cb2a9..01c50820 100644 --- a/ps2xRecomp/src/lib/ps2_recompiler.cpp +++ b/ps2xRecomp/src/lib/ps2_recompiler.cpp @@ -1451,11 +1451,46 @@ namespace ps2recomp } std::filesystem::path outputPath = m_config.outputPath; - outputPath /= safeName + ".cpp"; + outputPath /= clampFilenameLength(safeName, ".cpp", 100); return outputPath; } + std::string PS2Recompiler::clampFilenameLength(const std::string& baseName, const std::string& extension, std::size_t maxLength) + { + if (maxLength == 0) + { + std::cerr << "clampFilenameLength::maxLength must be greater than 0" << std::endl; + //Better go over the limit than create files with an empty path + return baseName + extension; + } + + if (baseName.size() + extension.size() <= maxLength) + return baseName + extension; + + std::string namePart = baseName; + std::string preservedSuffix; + + auto suffixPos = namePart.rfind("_0x"); + if (suffixPos != std::string::npos) + { + preservedSuffix = namePart.substr(suffixPos); + namePart = namePart.substr(0, suffixPos); + } + + std::size_t available = maxLength - extension.size() - preservedSuffix.size(); + + if (available == 0) + { + return preservedSuffix + extension; + } + + if (namePart.size() > available) + namePart = namePart.substr(0, available); + + return namePart + preservedSuffix + extension; + } + std::string PS2Recompiler::sanitizeFunctionName(const std::string &name) const { std::string sanitized = sanitizeIdentifierBody(name); @@ -1510,4 +1545,9 @@ namespace ps2recomp } return StubTarget::Unknown; } + + std::string PS2Recompiler::ClampFilenameLength(const std::string& baseName, const std::string& extension, std::size_t maxLength) + { + return clampFilenameLength(baseName, extension, maxLength); + } } diff --git a/ps2xTest/src/ps2_recompiler_tests.cpp b/ps2xTest/src/ps2_recompiler_tests.cpp index 575c647c..d2fece95 100644 --- a/ps2xTest/src/ps2_recompiler_tests.cpp +++ b/ps2xTest/src/ps2_recompiler_tests.cpp @@ -513,5 +513,14 @@ void register_ps2_recompiler_tests() std::error_code removeError; std::filesystem::remove(elfPath, removeError); - }); }); + }); + + tc.Run("respect max length for .cpp filenames", [](TestCase& t) { + + t.IsTrue(PS2Recompiler::ClampFilenameLength("ReallyLongFunctionNameReallyLongFunctionNameReallyLongFunctionName_0x12345678",".cpp",50).length() <= 50,"Function name must be max 50 characters"); + + t.IsTrue(PS2Recompiler::ClampFilenameLength("ReallyLongFunctionNameReallyLongFunctionNameReallyLongFunctionName_0x12345678", ".cpp", 50).rfind("0x12345678") != std::string::npos, "Function name must mantain the function address at the end, if present"); + + }); + }); }