zengine/engine/tools/make_plugin/src/main.cpp

151 lines
4.6 KiB
C++
Raw Normal View History

2024-07-20 18:04:19 +08:00
#include <fstream>
#include <vector>
#include <iostream>
#include <string>
#include <memory_resource>
#include <stack>
#include <optional>
#include <sstream>
2024-07-22 09:05:42 +08:00
#include "yyjson.h"
2024-07-20 18:04:19 +08:00
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) {
2024-07-22 09:05:42 +08:00
yyjson_read_err err = {};
std::pmr::string json{"{a=1}"};
yyjson_doc* _document = yyjson_read_opts(
(char*)json.data(), json.size(),
0, nullptr, &err);
auto obj = yyjson_doc_get_root((yyjson_doc*)_document);
2024-07-20 18:04:19 +08:00
}
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;
}