From 55d88413c7fe847859801f129eacbaf471003af1 Mon Sep 17 00:00:00 2001 From: dcvz Date: Wed, 15 May 2024 10:20:49 +0200 Subject: [PATCH] Replace toml11 in RSPRecomp --- .gitmodules | 3 - CMakeLists.txt | 6 +- RSPRecomp/src/rsp_recomp.cpp | 114 +++++++++++++++++++++++------------ lib/toml11 | 1 - src/config.cpp | 9 ++- 5 files changed, 80 insertions(+), 53 deletions(-) delete mode 160000 lib/toml11 diff --git a/.gitmodules b/.gitmodules index 86a551c..2d7b930 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "lib/fmt"] path = lib/fmt url = https://github.com/fmtlib/fmt -[submodule "lib/toml11"] - path = lib/toml11 - url = https://github.com/ToruNiina/toml11 [submodule "lib/tomlplusplus"] path = lib/tomlplusplus url = https://github.com/marzer/tomlplusplus diff --git a/CMakeLists.txt b/CMakeLists.txt index 264990e..20d83b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,11 +81,9 @@ target_link_libraries(N64Recomp fmt rabbitizer tomlplusplus::tomlplusplus) project(RSPRecomp) add_executable(RSPRecomp) -target_include_directories(RSPRecomp PRIVATE - "${CMAKE_SOURCE_DIR}/include" - "${CMAKE_SOURCE_DIR}/lib/toml11") +target_include_directories(RSPRecomp PRIVATE "${CMAKE_SOURCE_DIR}/include") -target_link_libraries(RSPRecomp fmt rabbitizer) +target_link_libraries(RSPRecomp fmt rabbitizer tomlplusplus::tomlplusplus) target_sources(RSPRecomp PRIVATE ${CMAKE_SOURCE_DIR}/RSPRecomp/src/rsp_recomp.cpp) diff --git a/RSPRecomp/src/rsp_recomp.cpp b/RSPRecomp/src/rsp_recomp.cpp index dc59325..b52cf96 100644 --- a/RSPRecomp/src/rsp_recomp.cpp +++ b/RSPRecomp/src/rsp_recomp.cpp @@ -5,11 +5,12 @@ #include #include #include +#include #include #include "rabbitizer.hpp" #include "fmt/format.h" #include "fmt/ostream.h" -#include "toml.hpp" +#include using InstrId = rabbitizer::InstrId::UniqueId; using Cop0Reg = rabbitizer::Registers::Rsp::Cop0; @@ -603,64 +604,97 @@ std::filesystem::path concat_if_not_empty(const std::filesystem::path& parent, c } template -std::vector toml_to_vec(const toml::value& branch_targets_data) { +std::vector toml_to_vec(const toml::array* array) { std::vector ret; - if (branch_targets_data.type() != toml::value_t::array) { - return ret; - } - - // Get the funcs array as an array type. - const std::vector& branch_targets_array = branch_targets_data.as_array(); - // Reserve room for all the funcs in the map. - ret.reserve(branch_targets_array.size()); - for (const toml::value& cur_target_val : branch_targets_array) { - ret.push_back(cur_target_val.as_integer()); - } + ret.reserve(array->size()); + array->for_each([&ret](auto&& el) { + if constexpr (toml::is_integer) { + ret.push_back(*el); + } + }); return ret; } +template +std::unordered_set toml_to_set(const toml::array* array) { + std::unordered_set ret; + + array->for_each([&ret](auto&& el) { + if constexpr (toml::is_integer) { + ret.insert(*el); + } + }); + + return ret; +} + bool read_config(const std::filesystem::path& config_path, RSPRecompilerConfig& out) { RSPRecompilerConfig ret{}; 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(); - ret.text_offset = toml::find(config_data, "text_offset"); - ret.text_size = toml::find(config_data, "text_size"); - ret.text_address = toml::find(config_data, "text_address"); + std::optional text_offset = config_data["text_offset"].value(); + if (!text_offset.has_value()) { + throw toml::parse_error("Missing text_offset in config file", {}); + } - ret.rom_file_path = concat_if_not_empty(basedir, toml::find(config_data, "rom_file_path")); - ret.output_file_path = concat_if_not_empty(basedir, toml::find(config_data, "output_file_path")); - ret.output_function_name = toml::find(config_data, "output_function_name"); + std::optional text_size = config_data["text_size"].value(); + if (!text_size.has_value()) { + throw toml::parse_error("Missing text_size in config file", {}); + } + + std::optional text_address = config_data["text_address"].value(); + if (!text_address.has_value()) { + throw toml::parse_error("Missing text_address in config file", {}); + } + + std::optional rom_file_path = config_data["rom_file_path"].value(); + 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 output_file_path = config_data["output_file_path"].value(); + 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 output_function_name = config_data["output_function_name"].value(); + 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) - const toml::value& branch_targets_data = toml::find_or(config_data, "extra_indirect_branch_targets", toml::value{}); - if (branch_targets_data.type() != toml::value_t::empty) { - ret.extra_indirect_branch_targets = toml_to_vec(branch_targets_data); - } + const toml::node_view branch_targets_data = config_data["extra_indirect_branch_targets"]; + if (branch_targets_data.is_array()) { + const toml::array* branch_targets_array = branch_targets_data.as_array(); + ret.extra_indirect_branch_targets = toml_to_vec(branch_targets_array); + } // Unsupported_instructions (optional) - const toml::value& unsupported_instructions_data = toml::find_or(config_data, "unsupported_instructions_data", toml::value{}); - if (unsupported_instructions_data.type() != toml::value_t::empty) { - ret.extra_indirect_branch_targets = toml_to_vec(unsupported_instructions_data); - } - } - 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; + const toml::node_view unsupported_instructions_data = config_data["unsupported_instructions"]; + if (unsupported_instructions_data.is_array()) { + const toml::array* unsupported_instructions_array = unsupported_instructions_data.as_array(); + ret.unsupported_instructions = toml_to_set(unsupported_instructions_array); + } } + 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; return true; diff --git a/lib/toml11 b/lib/toml11 deleted file mode 160000 index d47fe78..0000000 --- a/lib/toml11 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d47fe788bcb08c9d0d2a73954a0dfaf512964fdc diff --git a/src/config.cpp b/src/config.cpp index 4fb2a3f..b8e6748 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -19,11 +19,11 @@ std::vector get_manual_funcs(const toml::array* manu 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()); } else { - fmt::print(stderr, "Missing required value in manual_funcs array\n"); + throw toml::parse_error("Missing required value in manual_funcs array", {}); } } 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; } else { - throw toml::parse_error { "Invalid entrypoint", entrypoint_data.node()->source() }; + throw toml::parse_error("Invalid entrypoint", entrypoint_data.node()->source()); } } else { @@ -279,8 +279,7 @@ RecompPort::Config::Config(const char* path) { output_func_path = concat_if_not_empty(basedir, output_func_path_opt.value()); } else { - fmt::print(stderr, "Missing value in config file:\n{}\n", "output_func_path"); - return; + throw toml::parse_error("Missing output_func_path in config file", {}); } std::optional relocatable_sections_path_opt = input_data["relocatable_sections_path"].value();