vxorg/vxheaven_parse.cpp
Lily Tsuru af49206a16 Rewrite it in C++
rust people are going to be very mad at me now /j
2024-10-21 12:22:35 -04:00

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