| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545 |
- #include "luat_base.h"
- #include "luat_fs.h"
- #include "luat_malloc.h"
- #include "lundump.h"
- #include "luat_mock.h"
- #include "luat_luadb2.h"
- #include <stdlib.h>
- #define LUAT_LOG_TAG "fs"
- #include "luat_log.h"
- #include "dirent.h"
- extern int cmdline_argc;
- extern char **cmdline_argv;
- // luadb数据的上下文
- luat_luadb2_ctx_t luadb_ctx = {0};
- char *luadb_ptr;
- // 导出luadb数据的路径,默认是导出
- char luadb_dump_path[1024];
- // 脚本lua文件转luac时,是否删除调试信息,默认不删
- int cfg_luac_strip;
- int cfg_dump_luadb;
- int cfg_dump_report;
- int cfg_norun;
- void *check_file_path(const char *path);
- static int luat_cmd_load_luadb(const char *path);
- static int luat_cmd_load_luatools(const char *path);
- int luadb_do_report(luat_luadb2_ctx_t *ctx);
- static int is_opts(const char *key, const char *arg)
- {
- if (strlen(key) >= strlen(arg))
- {
- return 0;
- }
- return memcmp(key, arg, strlen(key)) == 0;
- }
- int luat_cmd_parse(int argc, char **argv)
- {
- if (cmdline_argc == 1)
- {
- return 0;
- }
- luat_luadb2_init(&luadb_ctx);
- for (size_t i = 1; i < (size_t)argc; i++)
- {
- const char *arg = argv[i];
- // 加载luadb文件镜像直接启动
- if (is_opts("--load_luadb=", arg))
- {
- if (luat_cmd_load_luadb(arg + strlen("--load_luadb=")))
- {
- LLOGE("加载luadb镜像失败");
- return -1;
- }
- continue;
- }
- if (is_opts("--ldb=", arg))
- {
- if (luat_cmd_load_luadb(arg + strlen("--ldb=")))
- {
- LLOGE("加载luadb镜像失败");
- return -1;
- }
- continue;
- }
- // 加载LuaTools项目文件直接启动
- if (is_opts("--load_luatools=", arg))
- {
- if (luat_cmd_load_luatools(arg + strlen("--load_luatools=")))
- {
- LLOGE("加载luatools项目文件失败");
- return -1;
- }
- continue;
- }
- if (is_opts("--llt=", arg))
- {
- if (luat_cmd_load_luatools(arg + strlen("--llt=")))
- {
- LLOGE("加载luatools项目文件失败");
- return -1;
- }
- continue;
- }
- // mock加载
- if (is_opts("--mlua=", arg))
- {
- if (luat_mock_init(arg + strlen("--mlua=")))
- {
- LLOGE("加载mock功能失败");
- return -1;
- }
- continue;
- }
- // 导出luadb文件
- if (is_opts("--dump_luadb=", arg))
- {
- memcpy(luadb_dump_path, arg + strlen("--dump_luadb="), strlen(arg) - strlen("--dump_luadb="));
- continue;
- }
-
- if (is_opts("--luac_strip=", arg))
- {
- if (!strcmp("--luac_strip=1", arg)) {
- cfg_luac_strip = 1;
- }
- else if (!strcmp("--luac_strip=0", arg)) {
- cfg_luac_strip = 0;
- }
- else if (!strcmp("--luac_strip=2", arg)) {
- cfg_luac_strip = 2;
- }
- continue;
- }
- if (is_opts("--luac_report=", arg))
- {
- // LLOGD("只导出luadb数据");
- if (!strcmp("--luac_report=1", arg)) {
- cfg_dump_report = 1;
- }
- continue;
- }
- // 是否导出luadb文件
- if (is_opts("--norun=", arg))
- {
- // LLOGD("只导出luadb数据");
- if (!strcmp("--norun=1", arg)) {
- cfg_norun = 1;
- }
- continue;
- }
- if (arg[0] == '-')
- {
- continue;
- }
- check_file_path(arg);
- }
- if (luadb_dump_path[0]) {
- LLOGD("导出luadb数据到 %s 大小 %d", luadb_dump_path, luadb_ctx.offset);
- FILE* f = fopen(luadb_dump_path, "wb+");
- if (f == NULL) {
- LLOGE("无法打开luadb导出路径 %s", luadb_dump_path);
- exit(1);
- }
- fwrite(luadb_ptr, 1, luadb_ctx.offset, f);
- fclose(f);
- }
- if (cfg_norun) {
- exit(0);
- }
- return 0;
- }
- static int luat_cmd_load_luadb(const char *path)
- {
- long len = 0;
- FILE *f = fopen(path, "rb");
- if (!f)
- {
- LLOGE("无法打开luadb镜像文件 %s", path);
- return -1;
- }
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- fseek(f, 0, SEEK_SET);
- char *ptr = luat_heap_malloc(len);
- if (ptr == NULL)
- {
- fclose(f);
- LLOGE("luadb镜像文件太大,内存放不下 %s", path);
- return -1;
- }
- fread(ptr, len, 1, f);
- fclose(f);
- luadb_ptr = ptr;
- // luadb_offset = len;
- return 0;
- }
- static int luat_cmd_load_luatools(const char *path)
- {
- long len = 0;
- FILE *f = fopen(path, "rb");
- if (!f)
- {
- LLOGE("无法打开luatools项目文件 %s", path);
- return -1;
- }
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- fseek(f, 0, SEEK_SET);
- char *ptr = luat_heap_malloc(len + 1);
- if (ptr == NULL)
- {
- fclose(f);
- LLOGE("luatools项目文件太大,内存放不下 %s", path);
- return -1;
- }
- fread(ptr, len, 1, f);
- fclose(f);
- ptr[len] = 0;
- char *ret = ptr;
- char dirline[512] = {0};
- char rpath[1024] = {0};
- size_t retlen = 0;
- while (ptr[0] != 0x00)
- {
- // LLOGD("ptr %c", ptr[0]);
- if (ptr[0] == '\r' || ptr[0] == '\n')
- {
- if (ret != ptr)
- {
- ptr[0] = 0x00;
- retlen = strlen(ret);
- // LLOGD("检索到的行 %s", ret);
- if (!strcmp("[info]", ret))
- {
- }
- else if (retlen > 5)
- {
- if (ret[0] == '[' && ret[retlen - 1] == ']')
- {
- LLOGD("目录行 %s", ret);
- memcpy(dirline, ret + 1, retlen - 2);
- dirline[retlen - 2] = 0x00;
- }
- else
- {
- if (dirline[0])
- {
- for (size_t i = 0; i < strlen(ret); i++)
- {
- if (ret[i] == ' ' || ret[i] == '=')
- {
- ret[i] = 0;
- memset(rpath, 0, 1024);
- memcpy(rpath, dirline, strlen(dirline));
- #ifdef LUA_USE_WINDOWS
- rpath[strlen(dirline)] = '\\';
- #else
- rpath[strlen(dirline)] = '/';
- #endif
- memcpy(rpath + strlen(rpath), ret, strlen(ret));
- LLOGI("加载文件 %s", rpath);
- if (check_file_path(rpath) == NULL)
- return -2;
- break;
- }
- }
- }
- }
- }
- }
- ret = ptr + 1;
- }
- ptr++;
- }
- return 0;
- }
- typedef struct luac_ctx
- {
- char *ptr;
- size_t len;
- } luac_ctx_t;
- luac_ctx_t* last_ctx = NULL;
- static int writer(lua_State *L, const void *p, size_t size, void *u)
- {
- UNUSED(L);
- // LLOGD("写入部分数据 %p %d", p, size);
- luac_ctx_t *ctx = (luac_ctx_t *)u;
- if (ctx->ptr == NULL)
- {
- ctx->ptr = luat_heap_malloc(size);
- ctx->len = size;
- memcpy(ctx->ptr, p, size);
- return 0;
- }
- char *ptr = luat_heap_realloc(ctx->ptr, ctx->len + size);
- if (ptr == NULL)
- {
- LLOGE("内存分配失败");
- return 1;
- }
- memcpy(ptr + ctx->len, p, size);
- ctx->ptr = ptr;
- ctx->len += size;
- return 0;
- }
- static int pmain(lua_State *L)
- {
- const char *name = luaL_checkstring(L, 1);
- size_t len = 0;
- const char *data = luaL_checklstring(L, 2, &len);
- int ret = luaL_loadbufferx(L, data, len, name, NULL);
- if (ret)
- {
- LLOGE("文件加载失败 %s %s", name, lua_tostring(L, -1));
- return 0;
- }
- // LLOGD("luac转换成功,开始转buff %s", name);
- luac_ctx_t *ctx = luat_heap_malloc(sizeof(luac_ctx_t));
- memset(ctx, 0, sizeof(luac_ctx_t));
- // LLOGD("getproto ");
- const Proto *f = getproto(L->top - 1);
- // LLOGD("Proto %p", f);
- if (cfg_luac_strip) {
- if (cfg_luac_strip == 1 && !strcmp("main.lua", name)) {
- ret = luaU_dump(L, f, writer, ctx, 0);
- }
- else {
- ret = luaU_dump(L, f, writer, ctx, 1);
- }
- }
- else {
- ret = luaU_dump(L, f, writer, ctx, 0);
- }
-
- // LLOGD("luaU_dump 执行完成");
- if (ret == 0)
- {
- // luadb_addfile(name, ctx->ptr, ctx->len);
- luat_luadb2_write(&luadb_ctx, name, ctx->ptr, ctx->len);
- luadb_ptr = luadb_ctx.dataptr;
- }
- lua_pushinteger(L, ret);
- luat_heap_free(ctx->ptr);
- luat_heap_free(ctx);
- return 1;
- }
- static int to_luac(const char *fullpath, const char *name, char *data, size_t len)
- {
- // LLOGD("检查语法并转换成luac %s 路径 %s", name, fullpath);
- lua_State *L = lua_newstate(luat_heap_alloc, NULL);
- // LLOGD("创建临时luavm");
- lua_pushcfunction(L, &pmain);
- lua_pushstring(L, name);
- lua_pushlstring(L, data, len);
- // LLOGD("准备执行luac转换");
- int ret = lua_pcall(L, 2, 1, 0);
- if (ret)
- {
- LLOGD("lua文件加载失败 %s %d", fullpath, ret);
- lua_close(L);
- return -1;
- }
- ret = luaL_checkinteger(L, -1);
- lua_close(L);
- return ret;
- }
- static int add_onefile(const char *path)
- {
- size_t len = 0;
- int ret = 0;
- // LLOGD("把%s当做main.lua运行", path);
- char tmpname[512] = {0};
- FILE *f = fopen(path, "rb");
- if (!f)
- {
- LLOGE("文件不存在 %s", path);
- return -1;
- }
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- fseek(f, 0, SEEK_SET);
- // void* fptr = luat_heap_malloc(len);
- char *tmp = luat_heap_malloc(len);
- if (tmp == NULL)
- {
- fclose(f);
- LLOGE("文件太大,内存放不下 %s", path);
- return -2;
- }
- fread(tmp, 1, len, f);
- fclose(f);
- for (size_t i = strlen(path); i > 0; i--)
- {
- if (path[i - 1] == '/' || path[i - 1] == '\\')
- {
- memcpy(tmpname, path + i, strlen(path) - 1);
- break;
- }
- }
- if (tmpname[0] == 0x00)
- {
- memcpy(tmpname, path, strlen(path));
- }
- if (!memcmp(path + strlen(path) - 4, ".lua", 4))
- {
- ret = to_luac(path, tmpname, tmp, len);
- }
- else
- {
- // ret = luadb_addfile(tmpname, tmp, len);
- ret = luat_luadb2_write(&luadb_ctx, tmpname, tmp, len);
- luadb_ptr = luadb_ctx.dataptr;
- }
- luat_heap_free(tmp);
- return ret;
- }
- void *check_file_path(const char *path)
- {
- if (strlen(path) < 4 || strlen(path) >= 512)
- {
- LLOGD("文件长度不对劲 %d %s", strlen(path), path);
- return NULL;
- }
- // 目录模式
- if (!memcmp(path + strlen(path) - 1, "/", 1) || !memcmp(path + strlen(path) - 1, "\\", 1))
- {
- DIR *dp;
- struct dirent *ep;
- // int index = 0;
- char buff[512] = {0};
- // LLOGD("加载目录 %s", path);
- #ifdef LUA_USE_WINDOWS
- memcpy(buff, path, strlen(path));
- #else
- memcpy(buff, path, strlen(path) - 1);
- #endif
- dp = opendir(buff);
- // LLOGD("目录打开 %p", dp);
- if (dp != NULL)
- {
- // LLOGD("开始遍历目录 %s", path);
- while ((ep = readdir(dp)) != NULL)
- {
- // LLOGD("文件/目录 %s %d", ep->d_name, ep->d_type);
- if (ep->d_type != DT_REG)
- {
- continue;
- }
- #ifdef LUA_USE_WINDOWS
- sprintf(buff, "%s\\%s", path, ep->d_name);
- #else
- sprintf(buff, "%s/%s", path, ep->d_name);
- #endif
- if (add_onefile(buff))
- {
- return NULL;
- }
- }
- // LLOGD("遍历结束");
- (void)closedir(dp);
- return luadb_ptr;
- }
- else
- {
- LLOGW("opendir file %s failed", path);
- return NULL;
- }
- }
- else
- {
- if (add_onefile(path))
- {
- return NULL;
- }
- return luadb_ptr;
- }
- // return NULL;
- }
- // 加载并分析文件
- int luat_cmd_load_and_analyse(const char *path)
- {
- size_t len = 0;
- int ret = 0;
- // LLOGD("把%s当做main.lua运行", path);
- char tmpname[512] = {0};
- FILE *f = fopen(path, "rb");
- if (!f)
- {
- LLOGE("文件不存在 %s", path);
- return -1;
- }
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- fseek(f, 0, SEEK_SET);
- // void* fptr = luat_heap_malloc(len);
- char *tmp = luat_heap_malloc(len);
- if (tmp == NULL)
- {
- fclose(f);
- LLOGE("文件太大,内存放不下 %s", path);
- return -2;
- }
- fread(tmp, 1, len, f);
- fclose(f);
- for (size_t i = strlen(path); i > 0; i--)
- {
- if (path[i - 1] == '/' || path[i - 1] == '\\')
- {
- memcpy(tmpname, path + i, strlen(path) - 1);
- break;
- }
- }
- if (tmpname[0] == 0x00)
- {
- memcpy(tmpname, path, strlen(path));
- }
- if (!memcmp(path + strlen(path) - 4, ".lua", 4))
- {
- ret = to_luac(path, tmpname, tmp, len);
- }
- else
- {
- // ret = luadb_addfile(tmpname, tmp, len);
- ret = luat_luadb2_write(&luadb_ctx, tmpname, tmp, len);
- luadb_ptr = luadb_ctx.dataptr;
- }
- luat_heap_free(tmp);
- return ret;
- }
|