145 lines
4.3 KiB
C++
145 lines
4.3 KiB
C++
|
|
#include <fstream>
|
||
|
|
#include <vector>
|
||
|
|
#include <iostream>
|
||
|
|
#include <string>
|
||
|
|
#include <memory_resource>
|
||
|
|
#include <stack>
|
||
|
|
#include <optional>
|
||
|
|
#include <sstream>
|
||
|
|
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<pmr::string> args;
|
||
|
|
MacroData() :args(&pool) {}
|
||
|
|
MacroData(const pmr::vector<pmr::string>& args):args(args) {}
|
||
|
|
};
|
||
|
|
pmr::vector<pmr::string> parseArgs(std::string_view& str) {
|
||
|
|
pmr::vector<pmr::string> args(&pool);
|
||
|
|
std::stack<char> 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<MacroData> 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<MacroData>{};
|
||
|
|
}
|
||
|
|
// 读取文件并返回每一行内容
|
||
|
|
pmr::vector<MacroData> readFile(const char* file_path) {
|
||
|
|
pmr::vector<MacroData> 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<MacroData>& 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<MacroData>& 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;
|
||
|
|
}
|