mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-06-13 06:03:14 +00:00
Replace toml11 in RSPRecomp
This commit is contained in:
parent
8dd9af652c
commit
55d88413c7
5 changed files with 80 additions and 53 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -7,9 +7,6 @@
|
||||||
[submodule "lib/fmt"]
|
[submodule "lib/fmt"]
|
||||||
path = lib/fmt
|
path = lib/fmt
|
||||||
url = https://github.com/fmtlib/fmt
|
url = https://github.com/fmtlib/fmt
|
||||||
[submodule "lib/toml11"]
|
|
||||||
path = lib/toml11
|
|
||||||
url = https://github.com/ToruNiina/toml11
|
|
||||||
[submodule "lib/tomlplusplus"]
|
[submodule "lib/tomlplusplus"]
|
||||||
path = lib/tomlplusplus
|
path = lib/tomlplusplus
|
||||||
url = https://github.com/marzer/tomlplusplus
|
url = https://github.com/marzer/tomlplusplus
|
||||||
|
|
|
@ -81,11 +81,9 @@ target_link_libraries(N64Recomp fmt rabbitizer tomlplusplus::tomlplusplus)
|
||||||
project(RSPRecomp)
|
project(RSPRecomp)
|
||||||
add_executable(RSPRecomp)
|
add_executable(RSPRecomp)
|
||||||
|
|
||||||
target_include_directories(RSPRecomp PRIVATE
|
target_include_directories(RSPRecomp PRIVATE "${CMAKE_SOURCE_DIR}/include")
|
||||||
"${CMAKE_SOURCE_DIR}/include"
|
|
||||||
"${CMAKE_SOURCE_DIR}/lib/toml11")
|
|
||||||
|
|
||||||
target_link_libraries(RSPRecomp fmt rabbitizer)
|
target_link_libraries(RSPRecomp fmt rabbitizer tomlplusplus::tomlplusplus)
|
||||||
|
|
||||||
target_sources(RSPRecomp PRIVATE
|
target_sources(RSPRecomp PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/RSPRecomp/src/rsp_recomp.cpp)
|
${CMAKE_SOURCE_DIR}/RSPRecomp/src/rsp_recomp.cpp)
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "rabbitizer.hpp"
|
#include "rabbitizer.hpp"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "fmt/ostream.h"
|
#include "fmt/ostream.h"
|
||||||
#include "toml.hpp"
|
#include <toml++/toml.hpp>
|
||||||
|
|
||||||
using InstrId = rabbitizer::InstrId::UniqueId;
|
using InstrId = rabbitizer::InstrId::UniqueId;
|
||||||
using Cop0Reg = rabbitizer::Registers::Rsp::Cop0;
|
using Cop0Reg = rabbitizer::Registers::Rsp::Cop0;
|
||||||
|
@ -603,64 +604,97 @@ std::filesystem::path concat_if_not_empty(const std::filesystem::path& parent, c
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<T> toml_to_vec(const toml::value& branch_targets_data) {
|
std::vector<T> toml_to_vec(const toml::array* array) {
|
||||||
std::vector<T> ret;
|
std::vector<T> ret;
|
||||||
|
|
||||||
if (branch_targets_data.type() != toml::value_t::array) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the funcs array as an array type.
|
|
||||||
const std::vector<toml::value>& branch_targets_array = branch_targets_data.as_array();
|
|
||||||
|
|
||||||
// Reserve room for all the funcs in the map.
|
// Reserve room for all the funcs in the map.
|
||||||
ret.reserve(branch_targets_array.size());
|
ret.reserve(array->size());
|
||||||
for (const toml::value& cur_target_val : branch_targets_array) {
|
array->for_each([&ret](auto&& el) {
|
||||||
ret.push_back(cur_target_val.as_integer());
|
if constexpr (toml::is_integer<decltype(el)>) {
|
||||||
}
|
ret.push_back(*el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::unordered_set<T> toml_to_set(const toml::array* array) {
|
||||||
|
std::unordered_set<T> ret;
|
||||||
|
|
||||||
|
array->for_each([&ret](auto&& el) {
|
||||||
|
if constexpr (toml::is_integer<decltype(el)>) {
|
||||||
|
ret.insert(*el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool read_config(const std::filesystem::path& config_path, RSPRecompilerConfig& out) {
|
bool read_config(const std::filesystem::path& config_path, RSPRecompilerConfig& out) {
|
||||||
RSPRecompilerConfig ret{};
|
RSPRecompilerConfig ret{};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const toml::value config_data = toml::parse(config_path);
|
const toml::table config_data = toml::parse_file(config_path.u8string());
|
||||||
std::filesystem::path basedir = std::filesystem::path{ config_path }.parent_path();
|
std::filesystem::path basedir = std::filesystem::path{ config_path }.parent_path();
|
||||||
|
|
||||||
ret.text_offset = toml::find<uint32_t>(config_data, "text_offset");
|
std::optional<uint32_t> text_offset = config_data["text_offset"].value<uint32_t>();
|
||||||
ret.text_size = toml::find<uint32_t>(config_data, "text_size");
|
if (!text_offset.has_value()) {
|
||||||
ret.text_address = toml::find<uint32_t>(config_data, "text_address");
|
throw toml::parse_error("Missing text_offset in config file", {});
|
||||||
|
}
|
||||||
|
|
||||||
ret.rom_file_path = concat_if_not_empty(basedir, toml::find<std::string>(config_data, "rom_file_path"));
|
std::optional<uint32_t> text_size = config_data["text_size"].value<uint32_t>();
|
||||||
ret.output_file_path = concat_if_not_empty(basedir, toml::find<std::string>(config_data, "output_file_path"));
|
if (!text_size.has_value()) {
|
||||||
ret.output_function_name = toml::find<std::string>(config_data, "output_function_name");
|
throw toml::parse_error("Missing text_size in config file", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<uint32_t> text_address = config_data["text_address"].value<uint32_t>();
|
||||||
|
if (!text_address.has_value()) {
|
||||||
|
throw toml::parse_error("Missing text_address in config file", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> rom_file_path = config_data["rom_file_path"].value<std::string>();
|
||||||
|
if (rom_file_path.has_value()) {
|
||||||
|
ret.rom_file_path = concat_if_not_empty(basedir, rom_file_path.value());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw toml::parse_error("Missing rom_file_path in config file", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> output_file_path = config_data["output_file_path"].value<std::string>();
|
||||||
|
if (output_file_path.has_value()) {
|
||||||
|
ret.output_file_path = concat_if_not_empty(basedir, output_file_path.value());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw toml::parse_error("Missing output_file_path in config file", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> output_function_name = config_data["output_function_name"].value<std::string>();
|
||||||
|
if (output_function_name.has_value()) {
|
||||||
|
ret.output_function_name = output_function_name.value();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw toml::parse_error("Missing output_function_name in config file", {});
|
||||||
|
}
|
||||||
|
|
||||||
// Extra indirect branch targets (optional)
|
// Extra indirect branch targets (optional)
|
||||||
const toml::value& branch_targets_data = toml::find_or<toml::value>(config_data, "extra_indirect_branch_targets", toml::value{});
|
const toml::node_view branch_targets_data = config_data["extra_indirect_branch_targets"];
|
||||||
if (branch_targets_data.type() != toml::value_t::empty) {
|
if (branch_targets_data.is_array()) {
|
||||||
ret.extra_indirect_branch_targets = toml_to_vec<uint32_t>(branch_targets_data);
|
const toml::array* branch_targets_array = branch_targets_data.as_array();
|
||||||
}
|
ret.extra_indirect_branch_targets = toml_to_vec<uint32_t>(branch_targets_array);
|
||||||
|
}
|
||||||
|
|
||||||
// Unsupported_instructions (optional)
|
// Unsupported_instructions (optional)
|
||||||
const toml::value& unsupported_instructions_data = toml::find_or<toml::value>(config_data, "unsupported_instructions_data", toml::value{});
|
const toml::node_view unsupported_instructions_data = config_data["unsupported_instructions"];
|
||||||
if (unsupported_instructions_data.type() != toml::value_t::empty) {
|
if (unsupported_instructions_data.is_array()) {
|
||||||
ret.extra_indirect_branch_targets = toml_to_vec<uint32_t>(unsupported_instructions_data);
|
const toml::array* unsupported_instructions_array = unsupported_instructions_data.as_array();
|
||||||
}
|
ret.unsupported_instructions = toml_to_set<uint32_t>(unsupported_instructions_array);
|
||||||
}
|
}
|
||||||
catch (const toml::syntax_error& err) {
|
|
||||||
fmt::print(stderr, "Syntax error in config file on line {}, full error:\n{}\n", err.location().line(), err.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (const toml::type_error& err) {
|
|
||||||
fmt::print(stderr, "Incorrect type in config file on line {}, full error:\n{}\n", err.location().line(), err.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (const std::out_of_range& err) {
|
|
||||||
fmt::print(stderr, "Missing value in config file, full error:\n{}\n", err.what());
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
catch (const toml::parse_error& err) {
|
||||||
|
std::cerr << "Syntax error parsing toml: " << *err.source().path << " (" << err.source().begin << "):\n" << err.description() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
out = ret;
|
out = ret;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit d47fe788bcb08c9d0d2a73954a0dfaf512964fdc
|
|
|
@ -19,11 +19,11 @@ std::vector<RecompPort::ManualFunction> get_manual_funcs(const toml::array* manu
|
||||||
if (func_name.has_value() && section_name.has_value() && vram_in.has_value() && size.has_value()) {
|
if (func_name.has_value() && section_name.has_value() && vram_in.has_value() && size.has_value()) {
|
||||||
ret.emplace_back(func_name.value(), section_name.value(), vram_in.value(), size.value());
|
ret.emplace_back(func_name.value(), section_name.value(), vram_in.value(), size.value());
|
||||||
} else {
|
} else {
|
||||||
fmt::print(stderr, "Missing required value in manual_funcs array\n");
|
throw toml::parse_error("Missing required value in manual_funcs array", {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fmt::print(stderr, "Missing required value in manual_funcs array\n");
|
throw toml::parse_error("Missing required value in manual_funcs array", {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ RecompPort::Config::Config(const char* path) {
|
||||||
has_entrypoint = true;
|
has_entrypoint = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw toml::parse_error { "Invalid entrypoint", entrypoint_data.node()->source() };
|
throw toml::parse_error("Invalid entrypoint", entrypoint_data.node()->source());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -279,8 +279,7 @@ RecompPort::Config::Config(const char* path) {
|
||||||
output_func_path = concat_if_not_empty(basedir, output_func_path_opt.value());
|
output_func_path = concat_if_not_empty(basedir, output_func_path_opt.value());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fmt::print(stderr, "Missing value in config file:\n{}\n", "output_func_path");
|
throw toml::parse_error("Missing output_func_path in config file", {});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> relocatable_sections_path_opt = input_data["relocatable_sections_path"].value<std::string>();
|
std::optional<std::string> relocatable_sections_path_opt = input_data["relocatable_sections_path"].value<std::string>();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue