Skip to content
This repository has been archived by the owner on Aug 4, 2023. It is now read-only.

Commit

Permalink
Add modname + file:line info to node not found warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
xforce committed Sep 15, 2019
1 parent 06a7de8 commit a3c5236
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 37 deletions.
2 changes: 2 additions & 0 deletions libs/external-file-loader/include/mod.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ template <> struct hash<fs::path> {
class Mod
{
public:
Mod() = default;
explicit Mod(const fs::path &root);

std::string Name() const;
bool HasFile(const fs::path &file) const;
void ForEachFile(std::function<void(const fs::path &, const fs::path &)>) const;
fs::path Path() const;

private:
fs::path root_path;
Expand Down
1 change: 1 addition & 0 deletions libs/external-file-loader/include/mod_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class ModManager
void CollectPatchableFiles();
void StartWatchingFiles();
void WaitModsReady() const;
Mod& GetModContainingFile(const fs::path& file);

// Cache system stuff
// This should be moved into it's own class
Expand Down
5 changes: 5 additions & 0 deletions libs/external-file-loader/src/mod.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ void Mod::ForEachFile(std::function<void(const fs::path&, const fs::path&)> fn)
fn(game_path, file_path);
});
}

fs::path Mod::Path() const
{
return root_path;
}
15 changes: 14 additions & 1 deletion libs/external-file-loader/src/mod_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@ void ModManager::WaitModsReady() const
this->mods_ready_cv_.wait(lk, [this] { return this->mods_ready_.load(); });
}

Mod& ModManager::GetModContainingFile(const fs::path& file)
{
for (auto& mod : mods_) {
if (file.lexically_normal().generic_string().find(mod.Path().lexically_normal().generic_string()) == 0) {
return mod;
}
}
static Mod null_mod;
assert(false);
return null_mod;
}

void ModManager::ReadCache()
{
const auto cache_directory = ModManager::GetCacheDirectory();
Expand Down Expand Up @@ -421,7 +433,8 @@ void ModManager::GameFilesReady()
// Cache miss
auto operations = XmlOperation::GetXmlOperationsFromFile(on_disk_file);
for (auto&& operation : operations) {
operation.Apply(game_xml, on_disk_file);
auto &mod = GetModContainingFile(on_disk_file);
operation.Apply(game_xml, mod.Name(), game_path, on_disk_file);
}

struct xml_string_writer : pugi::xml_writer {
Expand Down
4 changes: 3 additions & 1 deletion libs/xml-operations/include/xml_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class XmlOperation
{
return path_;
}
void Apply(std::shared_ptr<pugi::xml_document> doc, fs::path mod_path = {});
void Apply(std::shared_ptr<pugi::xml_document> doc, std::string mod_name = "",
fs::path game_path = {}, fs::path mod_path = {});
static std::vector<XmlOperation> GetXmlOperations(std::shared_ptr<pugi::xml_document> doc);
static std::vector<XmlOperation> GetXmlOperationsFromFile(fs::path path);

Expand All @@ -40,6 +41,7 @@ class XmlOperation
std::string guid_;
std::optional<pugi::xml_object_range<pugi::xml_node_iterator>> nodes_;
std::shared_ptr<pugi::xml_document> doc_;
pugi::xml_node node_;

/*static inline std::string to_string(xmlChar *str)
{
Expand Down
78 changes: 43 additions & 35 deletions libs/xml-operations/src/xml_operations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,45 @@

#include <cstdio>

using offset_data_t = std::vector<ptrdiff_t>;

namespace {
static bool build_offset_data(offset_data_t &result, const char *file)
{
FILE *f = fopen(file, "rb");
if (!f)
return false;

ptrdiff_t offset = 0;

char buffer[1024];
size_t size;

while ((size = fread(buffer, 1, sizeof(buffer), f)) > 0) {
for (size_t i = 0; i < size; ++i)
if (buffer[i] == '\n')
result.push_back(offset + i);

offset += size;
}

fclose(f);

return true;
}

static std::pair<size_t, size_t> get_location(const offset_data_t &data, ptrdiff_t offset)
{
offset_data_t::const_iterator it = std::lower_bound(data.begin(), data.end(), offset);
size_t index = it - data.begin();

return std::make_pair(1 + index, index == 0 ? offset + 1 : offset - data[index - 1]);
}
}

XmlOperation::XmlOperation(std::shared_ptr<pugi::xml_document> doc, pugi::xml_node node)
{
node_ = node;
doc_ = doc;
ReadType(node);
ReadPath(node);
Expand All @@ -18,6 +55,7 @@ XmlOperation::XmlOperation(std::shared_ptr<pugi::xml_document> doc, pugi::xml_no
XmlOperation::XmlOperation(std::shared_ptr<pugi::xml_document> doc, pugi::xml_node node,
std::string guid)
{
node_ = node;
doc_ = doc;
guid_ = guid;
ReadPath(node, guid);
Expand Down Expand Up @@ -110,7 +148,7 @@ std::optional<pugi::xml_node> FindAsset(std::shared_ptr<pugi::xml_document> doc,
return FindAsset(guid, doc->root());
}

void XmlOperation::Apply(std::shared_ptr<pugi::xml_document> doc, fs::path mod_path)
void XmlOperation::Apply(std::shared_ptr<pugi::xml_document> doc, std::string mod_name, fs::path game_path, fs::path mod_path)
{
try {
spdlog::debug("Looking up {}", path_);
Expand All @@ -137,7 +175,10 @@ void XmlOperation::Apply(std::shared_ptr<pugi::xml_document> doc, fs::path mod_p
results = doc->select_nodes(GetPath().c_str());
}
if (results.empty()) {
spdlog::warn("No matching node for Path {}", GetPath());
offset_data_t offset_data;
build_offset_data(offset_data, mod_path.string().c_str());
auto [line, column]= get_location(offset_data, node_.offset_debug());
spdlog::warn("No matching node for Path {} in {} ({}:{})", GetPath(), mod_name, game_path.string(), line);
return;
}
spdlog::debug("Looking finished {}", path_);
Expand Down Expand Up @@ -206,39 +247,6 @@ std::vector<XmlOperation> XmlOperation::GetXmlOperations(std::shared_ptr<pugi::x
return mod_operations;
}

using offset_data_t = std::vector<ptrdiff_t>;
static bool build_offset_data(offset_data_t &result, const char *file)
{
FILE *f = fopen(file, "rb");
if (!f)
return false;

ptrdiff_t offset = 0;

char buffer[1024];
size_t size;

while ((size = fread(buffer, 1, sizeof(buffer), f)) > 0) {
for (size_t i = 0; i < size; ++i)
if (buffer[i] == '\n')
result.push_back(offset + i);

offset += size;
}

fclose(f);

return true;
}

static std::pair<size_t, size_t> get_location(const offset_data_t &data, ptrdiff_t offset)
{
offset_data_t::const_iterator it = std::lower_bound(data.begin(), data.end(), offset);
size_t index = it - data.begin();

return std::make_pair(1 + index, index == 0 ? offset + 1 : offset - data[index - 1]);
}

std::vector<XmlOperation> XmlOperation::GetXmlOperationsFromFile(fs::path path)
{
std::shared_ptr<pugi::xml_document> doc = std::make_shared<pugi::xml_document>();
Expand Down

0 comments on commit a3c5236

Please sign in to comment.