94 lines
3.6 KiB
C++
94 lines
3.6 KiB
C++
#include "vxheaven_parse.hpp"
|
|
|
|
#include <format>
|
|
#include <fstream>
|
|
#include <optional>
|
|
#include <ranges>
|
|
#include <span>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
namespace vxorg {
|
|
|
|
/// Wrapper for std::views::split.
|
|
/// Make sure line outlives the vector.
|
|
std::vector<std::string_view> split_by(const std::string& string, char delim) {
|
|
auto res = std::vector<std::string_view> {};
|
|
for(auto word : std::views::split(string, delim)) {
|
|
res.push_back(std::string_view(word));
|
|
}
|
|
return res;
|
|
}
|
|
|
|
void parse_into_tree(VxHeavenTree& tree, std::istream& is) {
|
|
std::string line {};
|
|
while(std::getline(is, line)) {
|
|
auto split = split_by(line, '.');
|
|
|
|
VxHeavenTree::Node* type_leaf { nullptr };
|
|
VxHeavenTree::Node* platform_leaf { nullptr };
|
|
VxHeavenTree::Node* family_leaf { nullptr };
|
|
VxHeavenTree::Node* sample_leaf { nullptr };
|
|
|
|
if(auto* node = tree.root_node()->find_child([&](auto* node) { return node->data().name == split[0]; }); node == nullptr) {
|
|
// std::printf("making leaf for type %.*s\n", split[0].length(), split[0].data());
|
|
type_leaf = tree.create_leaf({ .name = std::string(split[0].data(), split[0].length()), .is_sample = false });
|
|
} else {
|
|
// std::printf("using existing leaf for type %.*s\n", split[0].length(), split[0].data());
|
|
type_leaf = node;
|
|
}
|
|
|
|
if(split.size() == 1) {
|
|
type_leaf->data().is_sample = true;
|
|
continue;
|
|
}
|
|
|
|
if(auto* n = type_leaf->find_child([&](auto* node) {
|
|
// auto matches = node->data().name == split[1];
|
|
// std::printf("trying to find %.*s in node %s's child %s: %s\n", split[1].length(), split[1].data(),
|
|
// type_leaf->data().name.c_str(), node->data().name.c_str(), matches ? "matches": "doesnt fucking match god damn it");
|
|
return node->data().name == split[1];
|
|
});
|
|
n == nullptr) {
|
|
// std::printf("making leaf for platform %s %.*s\n", type_leaf->data().name.c_str(), split[1].length(), split[1].data());
|
|
platform_leaf = type_leaf->create_leaf({ .name = std::string(split[1].data(), split[1].length()), .is_sample = false });
|
|
} else {
|
|
// std::printf("using existing leaf for platform %.*s\n", split[1].length(), split[1].data());
|
|
platform_leaf = n;
|
|
}
|
|
|
|
if(auto* n = platform_leaf->find_child([&](auto* node) { return node->data().name == split[2]; }); n == nullptr) {
|
|
// std::printf("making leaf for platform %s %.*s\n", type_leaf->data().name.c_str(), split[1].length(), split[1].data());
|
|
family_leaf = platform_leaf->create_leaf({ .name = std::string(split[2].data(), split[2].length()), .is_sample = false });
|
|
} else {
|
|
// std::printf("using existing leaf for platform %.*s\n", split[1].length(), split[1].data());
|
|
family_leaf = n;
|
|
}
|
|
|
|
// Handle famlies with a variantless sample inside of them
|
|
if(split.size() == 3) {
|
|
family_leaf->data().is_sample = true;
|
|
continue;
|
|
}
|
|
|
|
if(split.size() > 4) {
|
|
auto subvariants = std::span(split.data() + 4, split.size() - 4);
|
|
auto leaf = family_leaf;
|
|
|
|
for(auto& subvariant : subvariants) {
|
|
if(auto* node = leaf->find_child([&](auto* node) { return node->data().name == subvariant; }); node == nullptr) {
|
|
leaf = leaf->create_leaf({ .name = std::string(subvariant.data(), subvariant.length()), .is_sample = false });
|
|
}
|
|
}
|
|
|
|
leaf->data().is_sample = true;
|
|
} else {
|
|
auto subvariant = split[3];
|
|
if(auto* node = family_leaf->find_child([&](auto* node) { return node->data().name == subvariant; }); node == nullptr) {
|
|
family_leaf->create_leaf({ .name = std::string(subvariant.data(), subvariant.length()), .is_sample = true });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // namespace vxorg
|