#pragma once #include #include #include #include #include #include namespace Hsdbg { enum class PpKind : uint8_t { Identifier, Number, String, Char, Punct, }; struct PpToken { PpKind kind = PpKind::Identifier; std::string text; std::vector hide; }; struct MacroDef { std::string name; bool function_like = false; bool variadic = false; std::vector params; std::vector body; }; class MacroTable { public: auto clear() -> void; auto build(const std::vector& lines, const std::filesystem::path& base_dir) -> void; auto find(std::string_view name) const -> const MacroDef*; auto empty() const -> bool { return m_macros.empty(); } auto size() const -> size_t { return m_macros.size(); } auto revision() const -> uint64_t { return m_revision; } private: auto scan_lines(const std::vector& lines, const std::filesystem::path& base_dir, int depth, std::vector& seen) -> void; auto scan_path(const std::filesystem::path& path, int depth, std::vector& seen) -> void; std::unordered_map m_macros; uint64_t m_revision = 0; }; struct MacroExpansion { std::vector levels; std::vector> expanded; auto fully_expanded() const -> bool { return m_reached_fixpoint; } bool m_reached_fixpoint = true; }; auto expand_stages(const MacroTable& table, std::string_view input, int max_levels = 64) -> MacroExpansion; }