#include "macro-test-helpers.hpp" #include #include #include #include #include namespace advss::test { namespace { class LayoutParser { public: explicit LayoutParser(const std::string &layout) : _text(layout) {} std::deque> Parse() { std::deque> result; ParseList(result); return result; } private: std::vector> ParseList(std::deque> &out) { std::vector> items; SkipSpaces(); while (_pos < _text.size() && _text[_pos] != ']' && _text[_pos] != '}') { items.emplace_back(ParseItem(out)); SkipSpaces(); if (_pos < _text.size() && _text[_pos] == ',') { _pos++; } SkipSpaces(); } return items; } std::shared_ptr ParseItem(std::deque> &out) { std::string name; while (_pos < _text.size() && std::isalnum(static_cast(_text[_pos]))) { name += _text[_pos++]; } if (_pos >= _text.size() || (_text[_pos] != '[' && _text[_pos] != '{')) { auto macro = std::make_shared(name); out.emplace_back(macro); return macro; } const bool collapsed = _text[_pos] == '{'; _pos++; std::deque> descendants; auto children = ParseList(descendants); _pos++; auto group = Macro::CreateGroup(name, children); group->SetCollapsed(collapsed); out.emplace_back(group); out.insert(out.end(), descendants.begin(), descendants.end()); return group; } void SkipSpaces() { while (_pos < _text.size() && _text[_pos] == ' ') { _pos++; } } std::string _text; size_t _pos = 0; }; std::string describeChildren(const Macro *parent) { std::string result; for (const auto ¯o : GetTopLevelMacros()) { if (macro->Parent().get() != parent) { continue; } if (!result.empty()) { result += ", "; } result += macro->Name(); if (!macro->IsGroup()) { continue; } const bool collapsed = macro->IsCollapsed(); result += collapsed ? "{" : "["; result += describeChildren(macro.get()); result += collapsed ? "}" : "]"; } return result; } } // namespace void SetupMacros(const std::string &layout) { GetTopLevelMacros() = LayoutParser(layout).Parse(); } std::string DescribeMacros() { return describeChildren(nullptr); } std::shared_ptr GetMacro(const std::string &name) { return GetWeakMacroByName(name.c_str()).lock(); } } // namespace advss::test