diff --git a/Utilities/bin_patch.cpp b/Utilities/bin_patch.cpp index e83e886b35..a0d4b198b1 100644 --- a/Utilities/bin_patch.cpp +++ b/Utilities/bin_patch.cpp @@ -144,8 +144,8 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st if (version != patch_engine_version) { - append_log_message(log_messages, fmt::format("Error: File version %s does not match patch engine target version %s (file: %s)", version, patch_engine_version, path)); - patch_log.error("File version %s does not match patch engine target version %s (file: %s)", version, patch_engine_version, path); + append_log_message(log_messages, fmt::format("Error: File version %s does not match patch engine target version %s (location: %s, file: %s)", version, patch_engine_version, get_yaml_node_location(version_node), path)); + patch_log.error("File version %s does not match patch engine target version %s (location: %s, file: %s)", version, patch_engine_version, get_yaml_node_location(version_node), path); return false; } @@ -168,16 +168,16 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st if (const auto yml_type = pair.second.Type(); yml_type != YAML::NodeType::Map) { - append_log_message(log_messages, fmt::format("Error: Skipping key %s: expected Map, found %s", main_key, yml_type)); - patch_log.error("Skipping key %s: expected Map, found %s (file: %s)", main_key, yml_type, path); + append_log_message(log_messages, fmt::format("Error: Skipping key %s: expected Map, found %s (location: %s)", main_key, yml_type, get_yaml_node_location(pair.second))); + patch_log.error("Skipping key %s: expected Map, found %s (location: %s, file: %s)", main_key, yml_type, get_yaml_node_location(pair.second), path); is_valid = false; continue; } if (main_key.empty()) { - append_log_message(log_messages, "Error: Skipping empty key"); - patch_log.error("Skipping empty key (file: %s)", path); + append_log_message(log_messages, fmt::format("Error: Skipping empty key (location: %s)", get_yaml_node_location(pair.second))); + patch_log.error("Skipping empty key (location: %s, file: %s)", get_yaml_node_location(pair.second), path); is_valid = false; continue; } @@ -203,8 +203,8 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st if (const auto yml_type = patches_entry.second.Type(); yml_type != YAML::NodeType::Map) { - append_log_message(log_messages, fmt::format("Error: Skipping Patch key %s: expected Map, found %s (key: %s)", description, yml_type, main_key)); - patch_log.error("Skipping Patch key %s: expected Map, found %s (key: %s, file: %s)", description, yml_type, main_key, path); + append_log_message(log_messages, fmt::format("Error: Skipping Patch key %s: expected Map, found %s (key: %s, location: %s)", description, yml_type, main_key, get_yaml_node_location(patches_entry.second))); + patch_log.error("Skipping Patch key %s: expected Map, found %s (key: %s, location: %s, file: %s)", description, yml_type, main_key, get_yaml_node_location(patches_entry.second), path); is_valid = false; continue; } @@ -219,8 +219,8 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st { if (const auto yml_type = games_node.Type(); yml_type != YAML::NodeType::Map) { - append_log_message(log_messages, fmt::format("Error: Skipping Games key: expected Map, found %s (patch: %s, key: %s)", yml_type, description, main_key)); - patch_log.error("Skipping Games key: expected Map, found %s (patch: %s, key: %s, file: %s)", yml_type, description, main_key, path); + append_log_message(log_messages, fmt::format("Error: Skipping Games key: expected Map, found %s (patch: %s, key: %s, location: %s)", yml_type, description, main_key, get_yaml_node_location(games_node))); + patch_log.error("Skipping Games key: expected Map, found %s (patch: %s, key: %s, location: %s, file: %s)", yml_type, description, main_key, get_yaml_node_location(games_node), path); is_valid = false; continue; } @@ -231,16 +231,16 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st if (title.empty()) { - append_log_message(log_messages, fmt::format("Error: Empty game title (key: %s, file: %s)", main_key, path)); - patch_log.error("Empty game title (key: %s, file: %s)", main_key, path); + append_log_message(log_messages, fmt::format("Error: Empty game title (key: %s, location: %s, file: %s)", main_key, get_yaml_node_location(game_node), path)); + patch_log.error("Empty game title (key: %s, location: %s, file: %s)", main_key, get_yaml_node_location(game_node), path); is_valid = false; continue; } if (const auto yml_type = game_node.second.Type(); yml_type != YAML::NodeType::Map) { - append_log_message(log_messages, fmt::format("Error: Skipping game %s: expected Map, found %s (patch: %s, key: %s)", title, yml_type, description, main_key)); - patch_log.error("Skipping game %s: expected Map, found %s (patch: %s, key: %s, file: %s)", title, yml_type, description, main_key, path); + append_log_message(log_messages, fmt::format("Error: Skipping game %s: expected Map, found %s (patch: %s, key: %s, location: %s)", title, yml_type, description, main_key, get_yaml_node_location(game_node))); + patch_log.error("Skipping game %s: expected Map, found %s (patch: %s, key: %s, location: %s, file: %s)", title, yml_type, description, main_key, get_yaml_node_location(game_node), path); is_valid = false; continue; } @@ -253,8 +253,8 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st if (serial.empty()) { - append_log_message(log_messages, fmt::format("Error: Using empty serial (title: %s, patch: %s, key: %s)", title, description, main_key)); - patch_log.error("Using empty serial (title: %s, patch: %s, key: %s, file: %s)", title, description, main_key, path); + append_log_message(log_messages, fmt::format("Error: Using empty serial (title: %s, patch: %s, key: %s, location: %s)", title, description, main_key, get_yaml_node_location(serial_node))); + patch_log.error("Using empty serial (title: %s, patch: %s, key: %s, location: %s, file: %s)", title, description, main_key, get_yaml_node_location(serial_node), path); is_valid = false; continue; } @@ -262,24 +262,24 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st { if (!title_is_all_key) { - append_log_message(log_messages, fmt::format("Error: Using '%s' as serial is not allowed for titles other than '%s' (title: %s, patch: %s, key: %s)", patch_key::all, patch_key::all, title, description, main_key)); - patch_log.error("Error: Using '%s' as serial is not allowed for titles other than '%s' (title: %s, patch: %s, key: %s, file: %s)", patch_key::all, patch_key::all, title, description, main_key, path); + append_log_message(log_messages, fmt::format("Error: Using '%s' as serial is not allowed for titles other than '%s' (title: %s, patch: %s, key: %s, location: %s)", patch_key::all, patch_key::all, title, description, main_key, get_yaml_node_location(serial_node))); + patch_log.error("Error: Using '%s' as serial is not allowed for titles other than '%s' (title: %s, patch: %s, key: %s, location: %s, file: %s)", patch_key::all, patch_key::all, title, description, main_key, get_yaml_node_location(serial_node), path); is_valid = false; continue; } } else if (title_is_all_key) { - append_log_message(log_messages, fmt::format("Error: Only '%s' is allowed as serial if the title is '%s' (serial: %s, patch: %s, key: %s)", patch_key::all, patch_key::all, serial, description, main_key)); - patch_log.error("Error: Only '%s' is allowed as serial if the title is '%s' (serial: %s, patch: %s, key: %s, file: %s)", patch_key::all, patch_key::all, serial, description, main_key, path); + append_log_message(log_messages, fmt::format("Error: Only '%s' is allowed as serial if the title is '%s' (serial: %s, patch: %s, key: %s, location: %s)", patch_key::all, patch_key::all, serial, description, main_key, get_yaml_node_location(serial_node))); + patch_log.error("Error: Only '%s' is allowed as serial if the title is '%s' (serial: %s, patch: %s, key: %s, location: %s, file: %s)", patch_key::all, patch_key::all, serial, description, main_key, get_yaml_node_location(serial_node), path); is_valid = false; continue; } if (const auto yml_type = serial_node.second.Type(); yml_type != YAML::NodeType::Sequence) { - append_log_message(log_messages, fmt::format("Error: Skipping %s: expected Sequence, found %s (title: %s, patch: %s, key: %s)", serial, title, yml_type, description, main_key)); - patch_log.error("Skipping %s: expected Sequence, found %s (title: %s, patch: %s, key: %s, file: %s)", serial, title, yml_type, description, main_key, path); + append_log_message(log_messages, fmt::format("Error: Skipping %s: expected Sequence, found %s (title: %s, patch: %s, key: %s, location: %s)", serial, title, yml_type, description, main_key, get_yaml_node_location(serial_node))); + patch_log.error("Skipping %s: expected Sequence, found %s (title: %s, patch: %s, key: %s, location: %s, file: %s)", serial, title, yml_type, description, main_key, get_yaml_node_location(serial_node), path); is_valid = false; continue; } @@ -298,8 +298,8 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st if (app_versions.empty()) { - append_log_message(log_messages, fmt::format("Error: Skipping %s: empty Sequence (title: %s, patch: %s, key: %s)", serial, title, description, main_key)); - patch_log.error("Skipping %s: empty Sequence (title: %s, patch: %s, key: %s, file: %s)", serial, title, description, main_key, path); + append_log_message(log_messages, fmt::format("Error: Skipping %s: empty Sequence (title: %s, patch: %s, key: %s, location: %s)", serial, title, description, main_key, get_yaml_node_location(serial_node))); + patch_log.error("Skipping %s: empty Sequence (title: %s, patch: %s, key: %s, location: %s, file: %s)", serial, title, description, main_key, get_yaml_node_location(serial_node), path); is_valid = false; } else @@ -332,8 +332,8 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st } else { - append_log_message(log_messages, fmt::format("Error: Skipping sequenced Note (patch: %s, key: %s)", description, main_key)); - patch_log.error("Skipping sequenced Note (patch: %s, key: %s, file: %s)", description, main_key, path); + append_log_message(log_messages, fmt::format("Error: Skipping sequenced Note (patch: %s, key: %s, location: %s)", description, main_key, get_yaml_node_location(note))); + patch_log.error("Skipping sequenced Note (patch: %s, key: %s, location: %s, file: %s)", description, main_key, get_yaml_node_location(note), path); is_valid = false; } } @@ -361,7 +361,7 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st if (container.patch_info_map.find(description) != container.patch_info_map.end()) { bool ok; - const auto existing_version = container.patch_info_map[description].patch_version; + const std::string& existing_version = container.patch_info_map[description].patch_version; const bool version_is_bigger = utils::compare_versions(info.patch_version, existing_version, ok) > 0; if (!ok || !version_is_bigger) @@ -410,13 +410,13 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie { if (!node || !node.IsSequence()) { - append_log_message(log_messages, fmt::format("Skipping invalid patch node %s. (key: %s)", info.description, info.hash)); - patch_log.error("Skipping invalid patch node %s. (key: %s)", info.description, info.hash); + append_log_message(log_messages, fmt::format("Skipping invalid patch node %s. (key: %s, location: %s)", info.description, info.hash, get_yaml_node_location(node))); + patch_log.error("Skipping invalid patch node %s. (key: %s, location: %s)", info.description, info.hash, get_yaml_node_location(node)); return false; } const auto type_node = node[0]; - auto addr_node = node[1]; + const auto addr_node = node[1]; const auto value_node = node[2]; const auto type = get_patch_type(type_node); @@ -424,8 +424,8 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie if (type == patch_type::invalid) { const auto type_str = type_node && type_node.IsScalar() ? type_node.Scalar() : ""; - append_log_message(log_messages, fmt::format("Skipping patch node %s: type '%s' is invalid. (key: %s)", info.description, type_str, info.hash)); - patch_log.error("Skipping patch node %s: type '%s' is invalid. (key: %s)", info.description, type_str, info.hash); + append_log_message(log_messages, fmt::format("Skipping patch node %s: type '%s' is invalid. (key: %s, location: %s)", info.description, type_str, info.hash, get_yaml_node_location(node))); + patch_log.error("Skipping patch node %s: type '%s' is invalid. (key: %s, location: %s)", info.description, type_str, info.hash, get_yaml_node_location(node)); return false; } @@ -436,8 +436,8 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie // Check if the anchor was resolved. if (const auto yml_type = addr_node.Type(); yml_type != YAML::NodeType::Sequence) { - append_log_message(log_messages, fmt::format("Skipping sequence: expected Sequence, found %s (key: %s)", yml_type, info.hash)); - patch_log.error("Skipping sequence: expected Sequence, found %s (key: %s)", yml_type, info.hash); + append_log_message(log_messages, fmt::format("Skipping sequence: expected Sequence, found %s (key: %s, location: %s)", yml_type, info.hash, get_yaml_node_location(node))); + patch_log.error("Skipping sequence: expected Sequence, found %s (key: %s, location: %s)", yml_type, info.hash, get_yaml_node_location(node)); return false; } @@ -488,8 +488,8 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie if (!error_message.empty()) { - error_message = fmt::format("Skipping patch data entry: [ %s, 0x%.8x, %s ] (key: %s) %s", - p_data.type, p_data.offset, p_data.original_value.empty() ? "?" : p_data.original_value, info.hash, error_message); + error_message = fmt::format("Skipping patch data entry: [ %s, 0x%.8x, %s ] (key: %s, location: %s) %s", + p_data.type, p_data.offset, p_data.original_value.empty() ? "?" : p_data.original_value, info.hash, get_yaml_node_location(node), error_message); append_log_message(log_messages, error_message); patch_log.error("%s", error_message); return false; @@ -504,15 +504,15 @@ bool patch_engine::read_patch_node(patch_info& info, YAML::Node node, const YAML { if (!node) { - append_log_message(log_messages, fmt::format("Skipping invalid patch node %s. (key: %s)", info.description, info.hash)); - patch_log.error("Skipping invalid patch node %s. (key: %s)", info.description, info.hash); + append_log_message(log_messages, fmt::format("Skipping invalid patch node %s. (key: %s, location: %s)", info.description, info.hash, get_yaml_node_location(node))); + patch_log.error("Skipping invalid patch node %s. (key: %s, location: %s)", info.description, info.hash, get_yaml_node_location(node)); return false; } if (const auto yml_type = node.Type(); yml_type != YAML::NodeType::Sequence) { - append_log_message(log_messages, fmt::format("Skipping patch node %s: expected Sequence, found %s (key: %s)", info.description, yml_type, info.hash)); - patch_log.error("Skipping patch node %s: expected Sequence, found %s (key: %s)", info.description, yml_type, info.hash); + append_log_message(log_messages, fmt::format("Skipping patch node %s: expected Sequence, found %s (key: %s, location: %s)", info.description, yml_type, info.hash, get_yaml_node_location(node))); + patch_log.error("Skipping patch node %s: expected Sequence, found %s (key: %s, location: %s)", info.description, yml_type, info.hash, get_yaml_node_location(node)); return false; } diff --git a/rpcs3/Emu/vfs_config.cpp b/rpcs3/Emu/vfs_config.cpp index cf030d55a2..6a0cb00c52 100644 --- a/rpcs3/Emu/vfs_config.cpp +++ b/rpcs3/Emu/vfs_config.cpp @@ -2,7 +2,6 @@ #include "vfs_config.h" #include "Utilities/StrUtil.h" #include "Utilities/StrFmt.h" -#include "util/yaml.hpp" LOG_CHANNEL(vfs_log, "VFS"); diff --git a/rpcs3/rpcs3qt/config_adapter.cpp b/rpcs3/rpcs3qt/config_adapter.cpp index 1ff8b6a82e..2b5581cf0f 100644 --- a/rpcs3/rpcs3qt/config_adapter.cpp +++ b/rpcs3/rpcs3qt/config_adapter.cpp @@ -36,7 +36,7 @@ namespace cfg_adapter if (!node || !node.IsMap()) { - cfg_log.fatal("Node error. A cfg_location does not match its cfg::node"); + cfg_log.fatal("Node error. A cfg_location does not match its cfg::node (location: %s)", get_yaml_node_location(node)); return YAML::Node(); } diff --git a/rpcs3/util/yaml.cpp b/rpcs3/util/yaml.cpp index d3886c16ef..ea52140e2d 100644 --- a/rpcs3/util/yaml.cpp +++ b/rpcs3/util/yaml.cpp @@ -59,6 +59,23 @@ T get_yaml_node_value(YAML::Node node, std::string& error_message) return {}; } +std::string get_yaml_node_location(YAML::Node node) +{ + try + { + const auto mark = node.Mark(); + + if (mark.is_null()) + return "unknown"; + + return fmt::format("line %d, column %d", mark.line, mark.column); // Don't need the pos. It's not really useful. + } + catch (const std::exception& e) + { + return e.what(); + } +} + template u32 get_yaml_node_value(YAML::Node, std::string&); template u64 get_yaml_node_value(YAML::Node, std::string&); template f64 get_yaml_node_value(YAML::Node, std::string&); diff --git a/rpcs3/util/yaml.hpp b/rpcs3/util/yaml.hpp index 8ac66357d9..98c43a33af 100644 --- a/rpcs3/util/yaml.hpp +++ b/rpcs3/util/yaml.hpp @@ -25,3 +25,6 @@ std::pair yaml_load(const std::string& from); // Use try/catch in YAML::Node::as() instead of YAML::Node::as(fallback) in order to get an error message template T get_yaml_node_value(YAML::Node node, std::string& error_message); + +// Get the location of the node in the document +std::string get_yaml_node_location(YAML::Node node);