#include #include #include #include #include #include #include #include namespace pmr { using std::pmr::monotonic_buffer_resource; using std::pmr::vector; using std::pmr::string; } pmr::monotonic_buffer_resource pool; const char* MODULE_DEPENDENCY = "MODULE_DEPENDENCY"; const char* IMPLEMENT_DYNAMIC_MODULE = "IMPLEMENT_DYNAMIC_MODULE"; const char* IMPLEMENT_STATIC_MODULE = "IMPLEMENT_STATIC_MODULE"; std::string_view module_macro[] = { MODULE_DEPENDENCY , IMPLEMENT_DYNAMIC_MODULE , IMPLEMENT_STATIC_MODULE }; struct MacroData{ const char* macro{nullptr}; pmr::vector args; MacroData() :args(&pool) {} MacroData(const pmr::vector& args):args(args) {} }; pmr::vector parseArgs(std::string_view& str) { pmr::vector args(&pool); std::stack stack; enum EParseState { EEmpty, EBody, }; EParseState state = EEmpty; int n = 0; char segment[1024]; for (char c : str) { switch (state) { case EEmpty: { if (c == ' ' || c == '\t') break; state = EBody; if (c == '(' && stack.empty()) { stack.push(c); break; } } case EBody: { if (c == '(' || c == '{' || c == '[' || (c == '"' && stack.top() != '"')) { stack.push(c); }else{ char t = stack.top(); if ((t == '(' && c == ')') || (t == '[' && c == ']') || (t == '{' && c == '}') || (t == '"' && c == '"')) { stack.pop(); } } if (stack.empty()) { std::string_view view(segment, n); args.push_back(pmr::string(view, &pool)); return args; } if (c == ',' && stack.size() == 1) { std::string_view view(segment, n); args.push_back(pmr::string(view, &pool)); n = 0; state = EEmpty; } else { segment[n++] = c; } break; } default: break; } } return args; } std::optional parseLine(std::string_view line) { for (auto macro : module_macro) { size_t pos = line.find(macro); if (pos != std::string_view::npos) { line = line.substr(pos + macro.size()); MacroData md{ parseArgs(line) }; md.macro = macro.data(); std::cout << line << std::endl; return md; } } return std::optional{}; } // 读取文件并返回每一行内容 pmr::vector readFile(const char* file_path) { pmr::vector lines(&pool); std::ifstream file(file_path); if (!file.is_open()) { //std::cerr << "Failed to open file: " << file_path << std::endl; return lines; } std::string line; while (std::getline(file, line)) { std::string_view line_view(line); if (auto md = parseLine(line_view)) { lines.push_back(md.value()); } } file.close(); return lines; } void writeFile(const char* file_path, std::string_view data) { std::ofstream file(file_path, 0); file.write(data.data(), data.size()); file.close(); } void genLua(const char* file_path, const pmr::vector& mdList) { std::ostringstream oss; oss << "{\n"; for (auto& md : mdList) { if (md.macro == MODULE_DEPENDENCY) { oss << "\t{"; for (auto& args : md.args) { if (args[0] != '{') { oss << '"' << args << "\", "; } else { oss << args; } } oss << "},\n"; } } oss << '}'; writeFile(file_path, oss.str()); } void genPlugin(const char* file_path, const pmr::vector& mdList) { } int main() { const char* file_path = R"(F:\engine\zengine\engine\modules\render\vulkan\include\vulkan\module.h)"; auto mdList = readFile(file_path); genLua(R"(F:\engine\zengine\build\.gens\vulkan\windows\xmake.lua)", mdList); genPlugin(R"(F:\engine\zengine\build\.gens\vulkan\windows\xmake.lua)", mdList); return 0; }