ips stuffs2

This commit is contained in:
lizzie 2026-05-01 07:50:16 +00:00
parent 5736605795
commit 9a35739489
2 changed files with 47 additions and 33 deletions

View file

@ -7,6 +7,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <span> #include <span>
#include <cctype>
#include <ankerl/unordered_dense.h> #include <ankerl/unordered_dense.h>
#include "common/hex_util.h" #include "common/hex_util.h"
@ -146,43 +147,53 @@ static IPSwitchRecord EscapeStringSequences(std::string_view sv) {
return r; return r;
} }
[[nodiscard]] static inline std::array<u8, 32> ReadNSOBuildId(std::string_view const s) {
std::array<u8, 32> r{};
for (std::size_t i = 0; i < s.size(); ++i)
r[i / 2] |= Common::ToHexNibble(s[i]) << ((i % 2) * 4);
return r;
}
void IPSwitchCompiler::Parse() { void IPSwitchCompiler::Parse() {
const auto bytes = patch_text->ReadAllBytes(); auto const bytes = patch_text->ReadAllBytes();
std::stringstream s; std::vector<std::string> lines{};
s.write(reinterpret_cast<const char*>(bytes.data()), bytes.size()); for (auto it = bytes.cbegin(); it < bytes.cend(); ) {
auto const start = it;
std::vector<std::string> lines; auto end = start;
std::string sline{}; for (; end < bytes.cend() && *end != '\n' && *end != '\r'; ++end)
while (std::getline(s, sline)) { ;
// Remove a trailing \r it = end + 1; //prepare for next line
if (!sline.empty() && sline.back() == '\r') std::string_view const sline{
sline.pop_back(); reinterpret_cast<const char*>(bytes.data() + std::distance(bytes.cbegin(), start)),
size_t(std::distance(start, end))
// Remove comments };
std::string pp_str{}; if (sline.size() > 0) {
char has_comment = '\0'; auto p = sline.cbegin();
pp_str.resize(sline.size()); // skip space off line
for (size_t i = 0, j = 0; i < sline.size(); ) { for (; p < sline.cend() && std::isspace(*p); ++p)
if (sline[i] == '\"' || sline[i] == '\'') { ;
if (sline[i] == has_comment) { // now make a nominal preprocessed line: remove comments
has_comment = '\0'; char quote = '\0';
auto const sline_start = p;
for (; p < sline.cend(); ) {
if ((!quote && p + 1 < sline.cend() && p[0] == '/' && p[1] == '/')
|| (!quote && p[0] == '#')) {
break;
} else if (p[0] == '\"' || p[0] == '\'') {
quote = (p[0] == quote) ? '\0' : p[0];
++p;
} else if (p + 1 < sline.cend() && p[0] == '\\') {
p += 2;
} else { } else {
pp_str[j++] = sline[i++]; ++p;
has_comment = sline[i];
} }
} else if (sline[i] == '\\') {
pp_str[j++] = sline[i++];
pp_str[j++] = sline[i++];
} else if ((!has_comment && i + 1 < sline.size() && sline[i + 0] == '/' && sline[i + 1] == '/')
|| (!has_comment && sline[i] == '#')) {
pp_str.resize(j);
break;
} else {
pp_str[j++] = sline[i++];
} }
std::string pp_str(sline_start, p);
while (pp_str.size() > 0 && std::isspace(pp_str.back()))
pp_str.pop_back();
if (pp_str.size() > 0)
lines.push_back(pp_str);
} }
if (pp_str.size() > 0)
lines.push_back(std::move(pp_str));
} }
LOG_INFO(Loader, "IPSwitchCompiler: '{}'", patch_text->GetName()); LOG_INFO(Loader, "IPSwitchCompiler: '{}'", patch_text->GetName());
@ -196,7 +207,7 @@ void IPSwitchCompiler::Parse() {
// Force stop // Force stop
break; break;
} else if (StartsWith(line, "@nsobid-")) { // NSO Build ID Specifier } else if (StartsWith(line, "@nsobid-")) { // NSO Build ID Specifier
nso_build_id = Common::HexStringToArray<0x20>(line.substr(8)); nso_build_id = ReadNSOBuildId(line.substr(8));
} else if (StartsWith(line, "@enabled")) { } else if (StartsWith(line, "@enabled")) {
patches.push_back({{}, true}); //enabled patch patches.push_back({{}, true}); //enabled patch
} else if (StartsWith(line, "@disabled")) { } else if (StartsWith(line, "@disabled")) {

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later