From bd6af3cfd8f43bdc852190da383ccb179687f486 Mon Sep 17 00:00:00 2001 From: taynpg Date: Thu, 13 Feb 2025 10:41:24 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9A=E6=B7=BB=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=94=9F=E6=88=90=E5=AE=9A=E4=B9=89=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .luarc.json | 3 + .vscode/settings.json | 74 ++++++++++++++++++++ CMakeLists.txt | 8 +-- def_fen.bat | 3 + fs/fs.lua | 3 +- fs/lib.cxx | 7 ++ gendef/CMakeLists.txt | 10 +++ gendef/main.cxx | 155 ++++++++++++++++++++++++++++++++++++++++++ main.cpp | 7 -- 9 files changed, 257 insertions(+), 13 deletions(-) create mode 100644 .luarc.json create mode 100644 def_fen.bat create mode 100644 gendef/CMakeLists.txt create mode 100644 gendef/main.cxx delete mode 100644 main.cpp diff --git a/.luarc.json b/.luarc.json new file mode 100644 index 0000000..42f45f5 --- /dev/null +++ b/.luarc.json @@ -0,0 +1,3 @@ +{ + "workspace.library": ["./build/bin/Debug/def", "./build/bin/Release/def"] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index ddca288..84ab78f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,5 +32,79 @@ "ja": true, "zh-hant": true, "zh-hans": true + }, + "files.associations": { + "filesystem": "cpp", + "algorithm": "cpp", + "atomic": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "forward_list": "cpp", + "fstream": "cpp", + "functional": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "locale": "cpp", + "map": "cpp", + "memory": "cpp", + "mutex": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "regex": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "utility": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xmemory0": "cpp", + "xstddef": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp", + "bit": "cpp", + "compare": "cpp", + "concepts": "cpp", + "format": "cpp", + "stop_token": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 4668a02..e8f4151 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16) -project(elua LANGUAGES CXX) +project(exlua LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -12,9 +12,9 @@ message(STATUS "System: ${CMAKE_SYSTEM_NAME}") message(STATUS "Compiler CXX ID: ${CMAKE_CXX_COMPILER_ID}") # Set output directories -set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/) +set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib/) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/) add_subdirectory(lua) add_subdirectory(fs) -add_executable(elua main.cpp) \ No newline at end of file +add_subdirectory(gendef) \ No newline at end of file diff --git a/def_fen.bat b/def_fen.bat new file mode 100644 index 0000000..69a7cc9 --- /dev/null +++ b/def_fen.bat @@ -0,0 +1,3 @@ +@echo off +.\build\bin\gendef.exe .\fs\lib.cxx lua_fs .\build\defs +pause diff --git a/fs/fs.lua b/fs/fs.lua index 1b64b6a..81fbe4d 100644 --- a/fs/fs.lua +++ b/fs/fs.lua @@ -1,6 +1,5 @@ -- 加载模块 -local fs = require "lua_fs" - +local fs = require("lua_fs") print(fs.file_exists("D:\\download")) local files = fs.get_dir_files("D:\\download") if files then diff --git a/fs/lib.cxx b/fs/lib.cxx index ba0ac38..ce963a4 100644 --- a/fs/lib.cxx +++ b/fs/lib.cxx @@ -16,6 +16,9 @@ int file_exists(lua_State* L) return 1; } +/// @brief 文件是否是一个常规文件 +/// @param path 文件路径 +/// @return int is_regular_file(lua_State* L) { const char* path = luaL_checkstring(L, 1); @@ -24,6 +27,10 @@ int is_regular_file(lua_State* L) return 1; } +/// @brief 复制文件 +/// @param source 源文件(string) +/// @param destination 目标文件(string) +/// @return bool int copy_file(lua_State* L) { const char* source = luaL_checkstring(L, 1); diff --git a/gendef/CMakeLists.txt b/gendef/CMakeLists.txt new file mode 100644 index 0000000..f5a3ddf --- /dev/null +++ b/gendef/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.16) + +project(gendef LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 17) + +if(MSVC) +add_compile_options("/source-charset:utf-8") +endif() + +add_executable(gendef main.cxx) \ No newline at end of file diff --git a/gendef/main.cxx b/gendef/main.cxx new file mode 100644 index 0000000..3148e00 --- /dev/null +++ b/gendef/main.cxx @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; + +std::string to_full(const std::string& path) +{ + fs::path base; + if (fs::path(path).is_relative()) { + base = fs::current_path(); + base.append(path); + } else { + base = fs::path(path); + } + fs::path ret = fs::absolute(base); + return ret.string(); +} + +struct LuaFunction { + std::string name; + std::string brief; + std::vector> params; + std::string returnType; +}; + +// 解析 C++ 代码并提取函数信息 +std::vector parse_cpp(const std::string& cpp_code) +{ + std::vector functions; + std::regex func_regex(R"(///\s*@brief\s*(.*))"); + std::regex param_regex(R"(///\s*@param\s*(\w+)\s*(.*))"); + std::regex return_regex(R"(///\s*@return\s*(.*))"); + std::regex name_regex(R"(\bint\s+(\w+)\s*\()"); + + LuaFunction current; + bool inFunction = false; + + std::istringstream stream(cpp_code); + std::string line; + while (std::getline(stream, line)) { + std::smatch match; + + if (std::regex_search(line, match, func_regex)) { + current.brief = match[1].str(); + inFunction = true; + } else if (std::regex_search(line, match, param_regex)) { + current.params.emplace_back(match[1].str(), match[2].str()); + } else if (std::regex_search(line, match, return_regex)) { + current.returnType = match[1].str().empty() ? "boolean" : match[1].str(); + } else if (std::regex_search(line, match, name_regex)) { + current.name = match[1].str(); + } else if (inFunction && line.find("}") != std::string::npos) { + functions.push_back(current); + current = LuaFunction(); + inFunction = false; + } + } + return functions; +} + +// 生成 Lua 绑定文件 +void generate_lua_file(const std::vector& functions, const std::string& filename, const std::string& mod_name) +{ + std::ofstream out(filename); + if (!out) { + std::cerr << "can't create file: " << filename << std::endl; + return; + } + + std::string mod_call = mod_name + "_call"; + std::string mod_call_p = mod_name + "_call."; + + out << "---@meta\n"; + out << "local " << mod_call << " = require(\"" << mod_name << "\")\n\n"; + out << "local M = {}\n\n"; + + for (const auto& func : functions) { + out << "--- " << func.brief << "\n"; + for (const auto& param : func.params) { + out << "--- @param " << param.first << " " << param.second << "\n"; + } + out << "--- @return " << func.returnType << "\n"; + out << "function M." << func.name << "("; + for (size_t i = 0; i < func.params.size(); ++i) { + out << func.params[i].first; + if (i < func.params.size() - 1) + out << ", "; + } + out << ")\n return " << mod_call_p << func.name << "("; + for (size_t i = 0; i < func.params.size(); ++i) { + out << func.params[i].first; + if (i < func.params.size() - 1) + out << ", "; + } + out << ")\nend\n\n"; + } + + out << "return M\n"; + out.close(); + std::cout << "Lua file gen success: " << filename << std::endl; +} + +// 主函数 +int main(int argc, char* argv[]) +{ + if (argc < 4) { + std::cout << "arg1: cxx file.\n"; + std::cout << "arg2: module name.\n"; + std::cout << "arg3: out dir.\n"; + return -1; + } + + std::string arg_file(argv[1]); + std::string arg_mod(argv[2]); + std::string arg_out(argv[3]); + + arg_file = to_full(arg_file); + arg_out = to_full(arg_out); + std::string out_file = fs::path(arg_out).append(arg_mod + ".lua").string(); + + std::cout << "file: " << arg_file << std::endl; + std::cout << "mod: " << arg_mod << std::endl; + std::cout << "out: " << arg_out << std::endl; + + if (!fs::exists(arg_file)) { + std::cerr << "file not found: " << arg_file << std::endl; + return -2; + } + try { + if (!fs::exists(arg_out)) { + fs::create_directories(arg_out); + } + } catch (const std::exception& e) { + std::cerr << "create dir auto failed: " << e.what() << '\n'; + return -3; + } + + std::string s; + std::ifstream in(arg_file); + if (!in.is_open()) { + std::cerr << "open file failed: " << arg_file << std::endl; + return -1; + } + std::istreambuf_iterator iterf(in); + std::istreambuf_iterator iter; + std::string content(iterf, iter); + std::vector functions = parse_cpp(content); + generate_lua_file(functions, out_file, arg_mod); + return 0; +} diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 157fa26..0000000 --- a/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int main() -{ - std::cout << "Done" << std::endl; - return 0; -} \ No newline at end of file