#include "vxheaven_parse.hpp" #include #include #include #include #include #include #include #include namespace vxorg { /// Wrapper for std::views::split. /// Make sure line outlives the vector. std::vector split_by(const std::string& string, char delim) { auto res = std::vector {}; for(auto word : std::views::split(string, delim)) { res.push_back(std::string_view(word)); } return res; } std::string get_sample_name(VxHeavenTree::Node* node) { if(node == nullptr) return ""; if(!node->data().is_sample) return node->data().name; std::string sample_name {}; std::vector parent_list {}; vxorg::VxHeavenTree::Node* parent = node->parent_node(); while(parent) { if(parent->data().name.empty()) break; parent_list.push_back(&parent->data()); parent = parent->parent_node(); } for(auto& item : std::views::reverse(parent_list)) { sample_name += std::format("{}.", item->name); } sample_name += node->data().name; return sample_name; } 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