From a66a76f9c9b1888a1c3aea8b917083c2db789aa1 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Mon, 13 Sep 2021 23:40:01 -0400 Subject: [PATCH 01/20] Added in searcher. --- data/core/start.lua | 1 + src/api/system.c | 98 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/data/core/start.lua b/data/core/start.lua index 71050057..7fab5b37 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -19,3 +19,4 @@ package.path = DATADIR .. '/?.lua;' .. package.path package.path = DATADIR .. '/?/init.lua;' .. package.path package.path = USERDIR .. '/?.lua;' .. package.path package.path = USERDIR .. '/?/init.lua;' .. package.path +package.searchers[3] = system.searcher_plugin diff --git a/src/api/system.c b/src/api/system.c index 2f1bf763..dbcdbc3e 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -638,6 +638,103 @@ static int f_set_window_opacity(lua_State *L) { } + +typedef struct { + const char* symbol; + void* address; +} lua_function_node; + +#define P(FUNC) { "lua_" #FUNC, (void*)(lua_##FUNC) } +static void* api_require(const char* symbol) { + static lua_function_node nodes[] = { + P(absindex), P(arith), P(atpanic), P(callk), P(checkstack), + P(close), P(compare), P(concat), P(copy), P(createtable), P(dump), + P(error), P(gc), P(getallocf), P(getctx), P(getfield), P(getglobal), + P(gethook), P(gethookcount), P(gethookmask), P(getinfo), P(getlocal), + P(getmetatable), P(getstack), P(gettable), P(gettop), P(getupvalue), + P(getuservalue), P(insert), P(isnumber), + P(isstring), P(isuserdata), P(len), P(load), + P(newstate), P(newthread), P(newuserdata), P(next), + P(pcallk), P(pushboolean), P(pushcclosure), + P(pushfstring), P(pushinteger), P(pushlightuserdata), + P(pushlstring), P(pushnil), P(pushnumber), P(pushstring), + P(pushthread), P(pushunsigned), P(pushvalue), P(pushvfstring), P(rawequal), + P(rawget), P(rawgeti), P(rawgetp), P(rawlen), P(rawset), P(rawseti), + P(rawsetp), P(remove), P(replace), P(resume), P(setallocf), + P(setfield), P(setglobal), P(sethook), P(setlocal), P(setmetatable), + P(settable), P(settop), P(setupvalue), P(setuservalue), P(status), + P(tocfunction), P(tointegerx), P(tolstring), P(toboolean), + P(tonumberx), P(topointer), P(tothread), + P(tounsignedx), P(touserdata), P(type), P(typename), P(upvalueid), + P(upvaluejoin), P(version), P(xmove), P(yieldk) + }; + for (int i = 0; i < sizeof(nodes) / sizeof(lua_function_node); ++i) { + if (strcmp(nodes[i].symbol, symbol) == 0) + return nodes[i].address; + } + return NULL; +} + +static int loader_plugin(lua_State* L) { + size_t sname, modlen, pathlen; + char buffer[512] = "lua_open_"; + const char* modname = luaL_checklstring(L, -2, &modlen); + const char* path = luaL_checklstring(L, -1, &pathlen); + void* library = SDL_LoadObject(path); + if (modlen == 0 || !library) + return luaL_error(L, "Unable to load %s: %s", modname, SDL_GetError()); + for (sname = modlen - 1; sname > 0 && modname[sname] != '.'; --sname); + strncat(buffer, &modname[sname], modlen - sname + 1); + int (*entrypoint)(lua_State* L, void*) = SDL_LoadFunction(library, buffer); + if (!entrypoint) { + return luaL_error(L, "Unable to load %s: Can't find entrypoint. Requires a \ + function defined as int %s(lua_State* L, void* (*symbol)(const char*))", + path, buffer); + } + lua_pushlightuserdata(L, library); + lua_setfield(L, LUA_REGISTRYINDEX, modname); + if (entrypoint(L, api_require) == 0) + return luaL_error(L, "Unable to load %s: Your entrypoint must return at\ + least one argument."); + return 1; +} + +#if _WIN32 + #define PATH_SEPARATOR '\\' +#else + #define PATH_SEPARATOR '/' +#endif +static int f_searcher_plugin(lua_State *L) { + size_t len, cpath_len, cpath_idx = 0, cpath_q = 0; + const char* modname = luaL_checklstring(L, -1, &len); + lua_getglobal(L, "package"); + lua_getfield(L, -1, "cpath"); + const char* cpath = luaL_checklstring(L, -1, &cpath_len); + char lib[8192]; + for (size_t i = 0; i <= cpath_len; ++i) { + if (i == cpath_len || cpath[i] == ';') { + if (cpath_q) { + size_t offset = cpath_q - cpath_idx; + strncpy(lib, &cpath[cpath_idx], offset); + for (size_t j = 0; j < len && j < sizeof(lib) - 1; ++j) + lib[offset++] = modname[j] != '.' ? modname[j] : PATH_SEPARATOR; + lib[offset++] = '\0'; + struct stat s; + if (!stat(lib, &s)) { + lua_pushcfunction(L, loader_plugin); + lua_pushlstring(L, lib, offset); + return 2; + } + } + cpath_idx = i + 1; + cpath_q = 0; + } else if (cpath[i] == '?') { + cpath_q = i; + } + } + return 0; +} + static const luaL_Reg lib[] = { { "poll_event", f_poll_event }, { "wait_event", f_wait_event }, @@ -664,6 +761,7 @@ static const luaL_Reg lib[] = { { "exec", f_exec }, { "fuzzy_match", f_fuzzy_match }, { "set_window_opacity", f_set_window_opacity }, + { "searcher_plugin", f_searcher_plugin }, { NULL, NULL } }; From e9f48ce949e8f283a4c45cb15fe238e52837fb32 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Tue, 14 Sep 2021 00:13:30 -0400 Subject: [PATCH 02/20] Added in sample plugin and tested things out. Works. --- build_plugin.sh | 1 + data/core/init.lua | 3 ++- data/core/start.lua | 1 + sample_plugin.c | 14 ++++++++++++++ src/api/system.c | 21 ++++++++++++++------- src/main.c | 6 +++++- 6 files changed, 37 insertions(+), 9 deletions(-) create mode 100755 build_plugin.sh create mode 100644 sample_plugin.c diff --git a/build_plugin.sh b/build_plugin.sh new file mode 100755 index 00000000..b270caf7 --- /dev/null +++ b/build_plugin.sh @@ -0,0 +1 @@ +gcc sample_plugin.c -shared -o data/plugins/sample.so diff --git a/data/core/init.lua b/data/core/init.lua index af291767..1cb98979 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -426,6 +426,8 @@ function core.init() NagView = require "core.nagview" DocView = require "core.docview" Doc = require "core.doc" + local PluginTest = require "plugins.sample" + print(PluginTest.example) if PATHSEP == '\\' then USERDIR = common.normalize_path(USERDIR) @@ -675,7 +677,6 @@ local function check_plugin_version(filename) return true, version_match end - function core.load_plugins() local no_errors = true local refused_list = { diff --git a/data/core/start.lua b/data/core/start.lua index 7fab5b37..b9360d4b 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -19,4 +19,5 @@ package.path = DATADIR .. '/?.lua;' .. package.path package.path = DATADIR .. '/?/init.lua;' .. package.path package.path = USERDIR .. '/?.lua;' .. package.path package.path = USERDIR .. '/?/init.lua;' .. package.path +package.cpath = DATADIR .. '/?.' .. (MACOS and 'lib' or (WINDOWS and 'dll' or 'so')) .. ';' .. package.cpath package.searchers[3] = system.searcher_plugin diff --git a/sample_plugin.c b/sample_plugin.c new file mode 100644 index 00000000..8cd58bc3 --- /dev/null +++ b/sample_plugin.c @@ -0,0 +1,14 @@ + +typedef struct lua_State lua_State; +#define SYMBOL(NAME, RTYPE, ...) RTYPE (*lua_##NAME)(lua_State*, __VA_ARGS__) = (RTYPE (*)(lua_State*, __VA_ARGS__))symbol("lua_" #NAME); + +int lua_open_sample(lua_State* L, void* (*symbol(const char*))) { + SYMBOL(createtable, void, int, int); + SYMBOL(setfield, void, int, const char*); + SYMBOL(pushstring, const char*, const char*); + + lua_createtable(L, 0, 0); + lua_pushstring(L, "value"); + lua_setfield(L, -2, "example"); + return 1; +} diff --git a/src/api/system.c b/src/api/system.c index dbcdbc3e..791d839f 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -684,12 +684,12 @@ static int loader_plugin(lua_State* L) { if (modlen == 0 || !library) return luaL_error(L, "Unable to load %s: %s", modname, SDL_GetError()); for (sname = modlen - 1; sname > 0 && modname[sname] != '.'; --sname); - strncat(buffer, &modname[sname], modlen - sname + 1); + strcat(buffer, &modname[sname+1]); int (*entrypoint)(lua_State* L, void*) = SDL_LoadFunction(library, buffer); if (!entrypoint) { - return luaL_error(L, "Unable to load %s: Can't find entrypoint. Requires a \ - function defined as int %s(lua_State* L, void* (*symbol)(const char*))", - path, buffer); + return luaL_error(L, "Unable to load %s: Can't find entrypoint. Requires a " + "function defined as int %s(lua_State* L, void* (*symbol)(const char*))", + modname, buffer); } lua_pushlightuserdata(L, library); lua_setfield(L, LUA_REGISTRYINDEX, modname); @@ -701,7 +701,13 @@ static int loader_plugin(lua_State* L) { #if _WIN32 #define PATH_SEPARATOR '\\' -#else + #define DYNAMIC_SUFFIX "dll" +#else + #if __APPLE__ + #define DYNAMIC_SUFFIX "lib" + #else + #define DYNAMIC_SUFFIX "so" + #endif #define PATH_SEPARATOR '/' #endif static int f_searcher_plugin(lua_State *L) { @@ -716,13 +722,14 @@ static int f_searcher_plugin(lua_State *L) { if (cpath_q) { size_t offset = cpath_q - cpath_idx; strncpy(lib, &cpath[cpath_idx], offset); - for (size_t j = 0; j < len && j < sizeof(lib) - 1; ++j) + for (size_t j = 0; j < len && j < sizeof(lib) - 3; ++j) lib[offset++] = modname[j] != '.' ? modname[j] : PATH_SEPARATOR; lib[offset++] = '\0'; + strcat(lib, "." DYNAMIC_SUFFIX); struct stat s; if (!stat(lib, &s)) { lua_pushcfunction(L, loader_plugin); - lua_pushlstring(L, lib, offset); + lua_pushstring(L, lib); return 2; } } diff --git a/src/main.c b/src/main.c index 470f0b5e..3e99c735 100644 --- a/src/main.c +++ b/src/main.c @@ -139,13 +139,17 @@ init_lua: lua_pushstring(L, exename); lua_setglobal(L, "EXEFILE"); -#ifdef __APPLE__ lua_pushboolean(L, true); +#ifdef __APPLE__ lua_setglobal(L, "MACOS"); enable_momentum_scroll(); #ifdef MACOS_USE_BUNDLE set_macos_bundle_resources(L); #endif +#elsif _WIN32 + lua_setglobal(L, "WINDOWS"); +#else + lua_setglobal(L, "LINUX"); #endif const char *init_lite_code = \ From 377ce1cd06abd5ba50386920732ac62d8e6b2637 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 16 Sep 2021 12:37:17 -0400 Subject: [PATCH 03/20] Moved things around, fixed a few things up. --- build_plugin.sh | 2 +- data/core/start.lua | 16 ++- generate_header.sh | 17 +++ lite_plugin_api.h | 300 ++++++++++++++++++++++++++++++++++++++++++++ sample_plugin.c | 8 +- src/api/system.c | 46 +------ 6 files changed, 336 insertions(+), 53 deletions(-) create mode 100755 generate_header.sh create mode 100644 lite_plugin_api.h diff --git a/build_plugin.sh b/build_plugin.sh index b270caf7..437f9b58 100755 --- a/build_plugin.sh +++ b/build_plugin.sh @@ -1 +1 @@ -gcc sample_plugin.c -shared -o data/plugins/sample.so +gcc -g sample_plugin.c -shared -o data/plugins/sample.so diff --git a/data/core/start.lua b/data/core/start.lua index b9360d4b..7658d6c7 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -19,5 +19,17 @@ package.path = DATADIR .. '/?.lua;' .. package.path package.path = DATADIR .. '/?/init.lua;' .. package.path package.path = USERDIR .. '/?.lua;' .. package.path package.path = USERDIR .. '/?/init.lua;' .. package.path -package.cpath = DATADIR .. '/?.' .. (MACOS and 'lib' or (WINDOWS and 'dll' or 'so')) .. ';' .. package.cpath -package.searchers[3] = system.searcher_plugin + +local dynamic_suffix = MACOS and 'lib' or (WINDOWS and 'dll' or 'so') +package.cpath = DATADIR .. '/?.' .. dynamic_suffix .. ';' .. package.cpath +package.searchers[3] = function(modname) + local s,e = 0 + repeat + e = package.cpath:find(";", s) or #package.cpath + local path = package.cpath:sub(s, e - 1):gsub("?", modname:gsub("%.", "/")) + if system.get_file_info(path) then + return system.load_native_plugin, path + end + s = e + 1 + until s > #package.cpath +end diff --git a/generate_header.sh b/generate_header.sh new file mode 100755 index 00000000..fb03e712 --- /dev/null +++ b/generate_header.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# Takes lua folder, outputs a header file that includes all the necessary macros for writing a lite plugin. +# Takes a minimal approach, and strips out problematic functions. Should be good enough for most purposes. + +echo "// This file was automatically generated by generate_header.sh. Do not modify directly." +echo "#include " +echo "typedef struct lua_State lua_State; typedef double lua_Number; typedef int (*lua_CFunction)(lua_State*); typedef ptrdiff_t lua_Integer;" +echo "typedef unsigned long lua_Unsigned; typedef struct luaL_Buffer luaL_Buffer; typedef struct luaL_Reg luaL_Reg; typedef struct lua_Debug lua_Debug;" +echo "typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);" +echo "typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);" +echo "typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);" +grep -h "^LUA\(LIB\)*_API" $1/*.h | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^/static /" +grep -h "#define luaL*_" $1/*.h | grep -v "\\\s*$" | grep -v "\(assert\|lock\)" | grep -v "\(asm\|int32\)" | grep -v "#define lua_number2integer(i,n)\s*lua_number2int(i, n)" +echo "#define IMPORT_SYMBOL(name, ret, ...) name = (ret (*)(__VA_ARGS__))symbol(#name)" +echo "static void lite_init_plugin(void* (*symbol(const char*))) {" +grep -h "^LUA\(LIB\)*_API" $1/*.h | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^\([^)]*\)(\*\(lua\w*\))\s*(/\tIMPORT_SYMBOL(\2, \1,/" +echo "}" diff --git a/lite_plugin_api.h b/lite_plugin_api.h new file mode 100644 index 00000000..b6c03204 --- /dev/null +++ b/lite_plugin_api.h @@ -0,0 +1,300 @@ +// This file was automatically generated by generate_header.sh. Do not modify directly. +#include +typedef struct lua_State lua_State; typedef double lua_Number; typedef int (*lua_CFunction)(lua_State*); typedef ptrdiff_t lua_Integer; +typedef unsigned long lua_Unsigned; typedef struct luaL_Buffer luaL_Buffer; typedef struct luaL_Reg luaL_Reg; typedef struct lua_Debug lua_Debug; +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); +static void (*luaL_checkversion_) (lua_State *L, lua_Number ver); +static int (*luaL_getmetafield) (lua_State *L, int obj, const char *e); +static int (*luaL_callmeta) (lua_State *L, int obj, const char *e); +static const char *(*luaL_tolstring) (lua_State *L, int idx, size_t *len); +static int (*luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +static lua_Number (*luaL_checknumber) (lua_State *L, int numArg); +static lua_Number (*luaL_optnumber) (lua_State *L, int nArg, lua_Number def); +static lua_Integer (*luaL_checkinteger) (lua_State *L, int numArg); +static lua_Unsigned (*luaL_checkunsigned) (lua_State *L, int numArg); +static void (*luaL_checkstack) (lua_State *L, int sz, const char *msg); +static void (*luaL_checktype) (lua_State *L, int narg, int t); +static void (*luaL_checkany) (lua_State *L, int narg); +static int (*luaL_newmetatable) (lua_State *L, const char *tname); +static void (*luaL_setmetatable) (lua_State *L, const char *tname); +static void *(*luaL_testudata) (lua_State *L, int ud, const char *tname); +static void *(*luaL_checkudata) (lua_State *L, int ud, const char *tname); +static void (*luaL_where) (lua_State *L, int lvl); +static int (*luaL_error) (lua_State *L, const char *fmt, ...); +static int (*luaL_fileresult) (lua_State *L, int stat, const char *fname); +static int (*luaL_execresult) (lua_State *L, int stat); +static int (*luaL_ref) (lua_State *L, int t); +static void (*luaL_unref) (lua_State *L, int t, int ref); +static int (*luaL_loadstring) (lua_State *L, const char *s); +static lua_State *(*luaL_newstate) (void); +static int (*luaL_len) (lua_State *L, int idx); +static void (*luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); +static int (*luaL_getsubtable) (lua_State *L, int idx, const char *fname); +static void (*luaL_buffinit) (lua_State *L, luaL_Buffer *B); +static char *(*luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); +static void (*luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +static void (*luaL_addstring) (luaL_Buffer *B, const char *s); +static void (*luaL_addvalue) (luaL_Buffer *B); +static void (*luaL_pushresult) (luaL_Buffer *B); +static void (*luaL_pushresultsize) (luaL_Buffer *B, size_t sz); +static char *(*luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); +static lua_State *(*lua_newstate) (lua_Alloc f, void *ud); +static void (*lua_close) (lua_State *L); +static lua_State *(*lua_newthread) (lua_State *L); +static lua_CFunction (*lua_atpanic) (lua_State *L, lua_CFunction panicf); +static const lua_Number *(*lua_version) (lua_State *L); +static int (*lua_absindex) (lua_State *L, int idx); +static int (*lua_gettop) (lua_State *L); +static void (*lua_settop) (lua_State *L, int idx); +static void (*lua_pushvalue) (lua_State *L, int idx); +static void (*lua_remove) (lua_State *L, int idx); +static void (*lua_insert) (lua_State *L, int idx); +static void (*lua_replace) (lua_State *L, int idx); +static void (*lua_copy) (lua_State *L, int fromidx, int toidx); +static int (*lua_checkstack) (lua_State *L, int sz); +static void (*lua_xmove) (lua_State *from, lua_State *to, int n); +static int (*lua_isnumber) (lua_State *L, int idx); +static int (*lua_isstring) (lua_State *L, int idx); +static int (*lua_iscfunction) (lua_State *L, int idx); +static int (*lua_isuserdata) (lua_State *L, int idx); +static int (*lua_type) (lua_State *L, int idx); +static const char *(*lua_typename) (lua_State *L, int tp); +static lua_Number (*lua_tonumberx) (lua_State *L, int idx, int *isnum); +static lua_Integer (*lua_tointegerx) (lua_State *L, int idx, int *isnum); +static lua_Unsigned (*lua_tounsignedx) (lua_State *L, int idx, int *isnum); +static int (*lua_toboolean) (lua_State *L, int idx); +static const char *(*lua_tolstring) (lua_State *L, int idx, size_t *len); +static size_t (*lua_rawlen) (lua_State *L, int idx); +static lua_CFunction (*lua_tocfunction) (lua_State *L, int idx); +static void *(*lua_touserdata) (lua_State *L, int idx); +static lua_State *(*lua_tothread) (lua_State *L, int idx); +static const void *(*lua_topointer) (lua_State *L, int idx); +static void (*lua_arith) (lua_State *L, int op); +static int (*lua_rawequal) (lua_State *L, int idx1, int idx2); +static int (*lua_compare) (lua_State *L, int idx1, int idx2, int op); +static void (*lua_pushnil) (lua_State *L); +static void (*lua_pushnumber) (lua_State *L, lua_Number n); +static void (*lua_pushinteger) (lua_State *L, lua_Integer n); +static void (*lua_pushunsigned) (lua_State *L, lua_Unsigned n); +static const char *(*lua_pushlstring) (lua_State *L, const char *s, size_t l); +static const char *(*lua_pushstring) (lua_State *L, const char *s); +static const char *(*lua_pushfstring) (lua_State *L, const char *fmt, ...); +static void (*lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +static void (*lua_pushboolean) (lua_State *L, int b); +static void (*lua_pushlightuserdata) (lua_State *L, void *p); +static int (*lua_pushthread) (lua_State *L); +static void (*lua_getglobal) (lua_State *L, const char *var); +static void (*lua_gettable) (lua_State *L, int idx); +static void (*lua_getfield) (lua_State *L, int idx, const char *k); +static void (*lua_rawget) (lua_State *L, int idx); +static void (*lua_rawgeti) (lua_State *L, int idx, int n); +static void (*lua_rawgetp) (lua_State *L, int idx, const void *p); +static void (*lua_createtable) (lua_State *L, int narr, int nrec); +static void *(*lua_newuserdata) (lua_State *L, size_t sz); +static int (*lua_getmetatable) (lua_State *L, int objindex); +static void (*lua_getuservalue) (lua_State *L, int idx); +static void (*lua_setglobal) (lua_State *L, const char *var); +static void (*lua_settable) (lua_State *L, int idx); +static void (*lua_setfield) (lua_State *L, int idx, const char *k); +static void (*lua_rawset) (lua_State *L, int idx); +static void (*lua_rawseti) (lua_State *L, int idx, int n); +static void (*lua_rawsetp) (lua_State *L, int idx, const void *p); +static int (*lua_setmetatable) (lua_State *L, int objindex); +static void (*lua_setuservalue) (lua_State *L, int idx); +static int (*lua_getctx) (lua_State *L, int *ctx); +static int (*lua_dump) (lua_State *L, lua_Writer writer, void *data); +static int (*lua_resume) (lua_State *L, lua_State *from, int narg); +static int (*lua_status) (lua_State *L); +static int (*lua_gc) (lua_State *L, int what, int data); +static int (*lua_error) (lua_State *L); +static int (*lua_next) (lua_State *L, int idx); +static void (*lua_concat) (lua_State *L, int n); +static void (*lua_len) (lua_State *L, int idx); +static lua_Alloc (*lua_getallocf) (lua_State *L, void **ud); +static void (*lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); +static int (*lua_getstack) (lua_State *L, int level, lua_Debug *ar); +static int (*lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); +static const char *(*lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); +static const char *(*lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); +static const char *(*lua_getupvalue) (lua_State *L, int funcindex, int n); +static const char *(*lua_setupvalue) (lua_State *L, int funcindex, int n); +static void *(*lua_upvalueid) (lua_State *L, int fidx, int n); +static int (*lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); +static lua_Hook (*lua_gethook) (lua_State *L); +static int (*lua_gethookmask) (lua_State *L); +static int (*lua_gethookcount) (lua_State *L); +static void (*luaL_openlibs) (lua_State *L); +#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) +#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) +#define luaL_addsize(B,s) ((B)->n += (s)) +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) +#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) +#define lua_number2int(i,n) ((i)=(int)(n)) +#define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) +#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) +#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol) +#define lua_h +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) +#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) +#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) +#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) +#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) +#define lua_pop(L,n) lua_settop(L, -(n)-1) +#define lua_newtable(L) lua_createtable(L, 0, 0) +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) +#define lua_strlen(L,i) lua_rawlen(L, (i)) +#define lua_objlen(L,i) lua_rawlen(L, (i)) +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define lua_str2number(s,p) strtod((s), (p)) +#define lua_strx2number(s,p) strtod((s), (p)) +#define IMPORT_SYMBOL(name, ret, ...) name = (ret (*)(__VA_ARGS__))symbol(#name) +static void lite_init_plugin(void* (*symbol(const char*))) { + IMPORT_SYMBOL(luaL_checkversion_, void ,lua_State *L, lua_Number ver); + IMPORT_SYMBOL(luaL_getmetafield, int ,lua_State *L, int obj, const char *e); + IMPORT_SYMBOL(luaL_callmeta, int ,lua_State *L, int obj, const char *e); + IMPORT_SYMBOL(luaL_tolstring, const char *,lua_State *L, int idx, size_t *len); + IMPORT_SYMBOL(luaL_argerror, int ,lua_State *L, int numarg, const char *extramsg); + IMPORT_SYMBOL(luaL_checknumber, lua_Number ,lua_State *L, int numArg); + IMPORT_SYMBOL(luaL_optnumber, lua_Number ,lua_State *L, int nArg, lua_Number def); + IMPORT_SYMBOL(luaL_checkinteger, lua_Integer ,lua_State *L, int numArg); + IMPORT_SYMBOL(luaL_checkunsigned, lua_Unsigned ,lua_State *L, int numArg); + IMPORT_SYMBOL(luaL_checkstack, void ,lua_State *L, int sz, const char *msg); + IMPORT_SYMBOL(luaL_checktype, void ,lua_State *L, int narg, int t); + IMPORT_SYMBOL(luaL_checkany, void ,lua_State *L, int narg); + IMPORT_SYMBOL(luaL_newmetatable, int ,lua_State *L, const char *tname); + IMPORT_SYMBOL(luaL_setmetatable, void ,lua_State *L, const char *tname); + IMPORT_SYMBOL(luaL_testudata, void *,lua_State *L, int ud, const char *tname); + IMPORT_SYMBOL(luaL_checkudata, void *,lua_State *L, int ud, const char *tname); + IMPORT_SYMBOL(luaL_where, void ,lua_State *L, int lvl); + IMPORT_SYMBOL(luaL_error, int ,lua_State *L, const char *fmt, ...); + IMPORT_SYMBOL(luaL_fileresult, int ,lua_State *L, int stat, const char *fname); + IMPORT_SYMBOL(luaL_execresult, int ,lua_State *L, int stat); + IMPORT_SYMBOL(luaL_ref, int ,lua_State *L, int t); + IMPORT_SYMBOL(luaL_unref, void ,lua_State *L, int t, int ref); + IMPORT_SYMBOL(luaL_loadstring, int ,lua_State *L, const char *s); + IMPORT_SYMBOL(luaL_newstate, lua_State *,void); + IMPORT_SYMBOL(luaL_len, int ,lua_State *L, int idx); + IMPORT_SYMBOL(luaL_setfuncs, void ,lua_State *L, const luaL_Reg *l, int nup); + IMPORT_SYMBOL(luaL_getsubtable, int ,lua_State *L, int idx, const char *fname); + IMPORT_SYMBOL(luaL_buffinit, void ,lua_State *L, luaL_Buffer *B); + IMPORT_SYMBOL(luaL_prepbuffsize, char *,luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(luaL_addlstring, void ,luaL_Buffer *B, const char *s, size_t l); + IMPORT_SYMBOL(luaL_addstring, void ,luaL_Buffer *B, const char *s); + IMPORT_SYMBOL(luaL_addvalue, void ,luaL_Buffer *B); + IMPORT_SYMBOL(luaL_pushresult, void ,luaL_Buffer *B); + IMPORT_SYMBOL(luaL_pushresultsize, void ,luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(luaL_buffinitsize, char *,lua_State *L, luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(lua_newstate, lua_State *,lua_Alloc f, void *ud); + IMPORT_SYMBOL(lua_close, void ,lua_State *L); + IMPORT_SYMBOL(lua_newthread, lua_State *,lua_State *L); + IMPORT_SYMBOL(lua_atpanic, lua_CFunction ,lua_State *L, lua_CFunction panicf); + IMPORT_SYMBOL(lua_version, const lua_Number *,lua_State *L); + IMPORT_SYMBOL(lua_absindex, int ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_gettop, int ,lua_State *L); + IMPORT_SYMBOL(lua_settop, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_pushvalue, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_remove, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_insert, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_replace, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_copy, void ,lua_State *L, int fromidx, int toidx); + IMPORT_SYMBOL(lua_checkstack, int ,lua_State *L, int sz); + IMPORT_SYMBOL(lua_xmove, void ,lua_State *from, lua_State *to, int n); + IMPORT_SYMBOL(lua_isnumber, int ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_isstring, int ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_iscfunction, int ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_isuserdata, int ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_type, int ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_typename, const char *,lua_State *L, int tp); + IMPORT_SYMBOL(lua_tonumberx, lua_Number ,lua_State *L, int idx, int *isnum); + IMPORT_SYMBOL(lua_tointegerx, lua_Integer ,lua_State *L, int idx, int *isnum); + IMPORT_SYMBOL(lua_tounsignedx, lua_Unsigned ,lua_State *L, int idx, int *isnum); + IMPORT_SYMBOL(lua_toboolean, int ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_tolstring, const char *,lua_State *L, int idx, size_t *len); + IMPORT_SYMBOL(lua_rawlen, size_t ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_tocfunction, lua_CFunction ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_touserdata, void *,lua_State *L, int idx); + IMPORT_SYMBOL(lua_tothread, lua_State *,lua_State *L, int idx); + IMPORT_SYMBOL(lua_topointer, const void *,lua_State *L, int idx); + IMPORT_SYMBOL(lua_arith, void ,lua_State *L, int op); + IMPORT_SYMBOL(lua_rawequal, int ,lua_State *L, int idx1, int idx2); + IMPORT_SYMBOL(lua_compare, int ,lua_State *L, int idx1, int idx2, int op); + IMPORT_SYMBOL(lua_pushnil, void ,lua_State *L); + IMPORT_SYMBOL(lua_pushnumber, void ,lua_State *L, lua_Number n); + IMPORT_SYMBOL(lua_pushinteger, void ,lua_State *L, lua_Integer n); + IMPORT_SYMBOL(lua_pushunsigned, void ,lua_State *L, lua_Unsigned n); + IMPORT_SYMBOL(lua_pushlstring, const char *,lua_State *L, const char *s, size_t l); + IMPORT_SYMBOL(lua_pushstring, const char *,lua_State *L, const char *s); + IMPORT_SYMBOL(lua_pushfstring, const char *,lua_State *L, const char *fmt, ...); + IMPORT_SYMBOL(lua_pushcclosure, void ,lua_State *L, lua_CFunction fn, int n); + IMPORT_SYMBOL(lua_pushboolean, void ,lua_State *L, int b); + IMPORT_SYMBOL(lua_pushlightuserdata, void ,lua_State *L, void *p); + IMPORT_SYMBOL(lua_pushthread, int ,lua_State *L); + IMPORT_SYMBOL(lua_getglobal, void ,lua_State *L, const char *var); + IMPORT_SYMBOL(lua_gettable, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_getfield, void ,lua_State *L, int idx, const char *k); + IMPORT_SYMBOL(lua_rawget, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_rawgeti, void ,lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_rawgetp, void ,lua_State *L, int idx, const void *p); + IMPORT_SYMBOL(lua_createtable, void ,lua_State *L, int narr, int nrec); + IMPORT_SYMBOL(lua_newuserdata, void *,lua_State *L, size_t sz); + IMPORT_SYMBOL(lua_getmetatable, int ,lua_State *L, int objindex); + IMPORT_SYMBOL(lua_getuservalue, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_setglobal, void ,lua_State *L, const char *var); + IMPORT_SYMBOL(lua_settable, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_setfield, void ,lua_State *L, int idx, const char *k); + IMPORT_SYMBOL(lua_rawset, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_rawseti, void ,lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_rawsetp, void ,lua_State *L, int idx, const void *p); + IMPORT_SYMBOL(lua_setmetatable, int ,lua_State *L, int objindex); + IMPORT_SYMBOL(lua_setuservalue, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_getctx, int ,lua_State *L, int *ctx); + IMPORT_SYMBOL(lua_dump, int ,lua_State *L, lua_Writer writer, void *data); + IMPORT_SYMBOL(lua_resume, int ,lua_State *L, lua_State *from, int narg); + IMPORT_SYMBOL(lua_status, int ,lua_State *L); + IMPORT_SYMBOL(lua_gc, int ,lua_State *L, int what, int data); + IMPORT_SYMBOL(lua_error, int ,lua_State *L); + IMPORT_SYMBOL(lua_next, int ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_concat, void ,lua_State *L, int n); + IMPORT_SYMBOL(lua_len, void ,lua_State *L, int idx); + IMPORT_SYMBOL(lua_getallocf, lua_Alloc ,lua_State *L, void **ud); + IMPORT_SYMBOL(lua_setallocf, void ,lua_State *L, lua_Alloc f, void *ud); + IMPORT_SYMBOL(lua_getstack, int ,lua_State *L, int level, lua_Debug *ar); + IMPORT_SYMBOL(lua_getinfo, int ,lua_State *L, const char *what, lua_Debug *ar); + IMPORT_SYMBOL(lua_getlocal, const char *,lua_State *L, const lua_Debug *ar, int n); + IMPORT_SYMBOL(lua_setlocal, const char *,lua_State *L, const lua_Debug *ar, int n); + IMPORT_SYMBOL(lua_getupvalue, const char *,lua_State *L, int funcindex, int n); + IMPORT_SYMBOL(lua_setupvalue, const char *,lua_State *L, int funcindex, int n); + IMPORT_SYMBOL(lua_upvalueid, void *,lua_State *L, int fidx, int n); + IMPORT_SYMBOL(lua_sethook, int ,lua_State *L, lua_Hook func, int mask, int count); + IMPORT_SYMBOL(lua_gethook, lua_Hook ,lua_State *L); + IMPORT_SYMBOL(lua_gethookmask, int ,lua_State *L); + IMPORT_SYMBOL(lua_gethookcount, int ,lua_State *L); + IMPORT_SYMBOL(luaL_openlibs, void ,lua_State *L); +} diff --git a/sample_plugin.c b/sample_plugin.c index 8cd58bc3..96e021c9 100644 --- a/sample_plugin.c +++ b/sample_plugin.c @@ -1,12 +1,8 @@ -typedef struct lua_State lua_State; -#define SYMBOL(NAME, RTYPE, ...) RTYPE (*lua_##NAME)(lua_State*, __VA_ARGS__) = (RTYPE (*)(lua_State*, __VA_ARGS__))symbol("lua_" #NAME); +#include "lite_plugin_api.h" int lua_open_sample(lua_State* L, void* (*symbol(const char*))) { - SYMBOL(createtable, void, int, int); - SYMBOL(setfield, void, int, const char*); - SYMBOL(pushstring, const char*, const char*); - + lite_init_plugin(symbol); lua_createtable(L, 0, 0); lua_pushstring(L, "value"); lua_setfield(L, -2, "example"); diff --git a/src/api/system.c b/src/api/system.c index 791d839f..78b3e700 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -675,7 +675,7 @@ static void* api_require(const char* symbol) { return NULL; } -static int loader_plugin(lua_State* L) { +static int f_load_native_plugin(lua_State* L) { size_t sname, modlen, pathlen; char buffer[512] = "lua_open_"; const char* modname = luaL_checklstring(L, -2, &modlen); @@ -699,48 +699,6 @@ static int loader_plugin(lua_State* L) { return 1; } -#if _WIN32 - #define PATH_SEPARATOR '\\' - #define DYNAMIC_SUFFIX "dll" -#else - #if __APPLE__ - #define DYNAMIC_SUFFIX "lib" - #else - #define DYNAMIC_SUFFIX "so" - #endif - #define PATH_SEPARATOR '/' -#endif -static int f_searcher_plugin(lua_State *L) { - size_t len, cpath_len, cpath_idx = 0, cpath_q = 0; - const char* modname = luaL_checklstring(L, -1, &len); - lua_getglobal(L, "package"); - lua_getfield(L, -1, "cpath"); - const char* cpath = luaL_checklstring(L, -1, &cpath_len); - char lib[8192]; - for (size_t i = 0; i <= cpath_len; ++i) { - if (i == cpath_len || cpath[i] == ';') { - if (cpath_q) { - size_t offset = cpath_q - cpath_idx; - strncpy(lib, &cpath[cpath_idx], offset); - for (size_t j = 0; j < len && j < sizeof(lib) - 3; ++j) - lib[offset++] = modname[j] != '.' ? modname[j] : PATH_SEPARATOR; - lib[offset++] = '\0'; - strcat(lib, "." DYNAMIC_SUFFIX); - struct stat s; - if (!stat(lib, &s)) { - lua_pushcfunction(L, loader_plugin); - lua_pushstring(L, lib); - return 2; - } - } - cpath_idx = i + 1; - cpath_q = 0; - } else if (cpath[i] == '?') { - cpath_q = i; - } - } - return 0; -} static const luaL_Reg lib[] = { { "poll_event", f_poll_event }, @@ -768,7 +726,7 @@ static const luaL_Reg lib[] = { { "exec", f_exec }, { "fuzzy_match", f_fuzzy_match }, { "set_window_opacity", f_set_window_opacity }, - { "searcher_plugin", f_searcher_plugin }, + { "load_native_plugin", f_load_native_plugin }, { NULL, NULL } }; From 29875540978d9f898db17e993414bb67194ea15d Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 16 Sep 2021 15:47:12 -0400 Subject: [PATCH 04/20] Moving things into final positions. --- build_plugin.sh | 1 - data/core/init.lua | 2 -- data/core/start.lua | 1 + generate_header.sh | 17 ---------- .../lite_xl_plugin_api.h | 33 ++++++++++++++++--- sample_plugin.c | 10 ------ 6 files changed, 29 insertions(+), 35 deletions(-) delete mode 100755 build_plugin.sh delete mode 100755 generate_header.sh rename lite_plugin_api.h => resources/lite_xl_plugin_api.h (91%) delete mode 100644 sample_plugin.c diff --git a/build_plugin.sh b/build_plugin.sh deleted file mode 100755 index 437f9b58..00000000 --- a/build_plugin.sh +++ /dev/null @@ -1 +0,0 @@ -gcc -g sample_plugin.c -shared -o data/plugins/sample.so diff --git a/data/core/init.lua b/data/core/init.lua index 1cb98979..e05d5c2b 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -426,8 +426,6 @@ function core.init() NagView = require "core.nagview" DocView = require "core.docview" Doc = require "core.doc" - local PluginTest = require "plugins.sample" - print(PluginTest.example) if PATHSEP == '\\' then USERDIR = common.normalize_path(USERDIR) diff --git a/data/core/start.lua b/data/core/start.lua index 7658d6c7..0bbaadee 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -22,6 +22,7 @@ package.path = USERDIR .. '/?/init.lua;' .. package.path local dynamic_suffix = MACOS and 'lib' or (WINDOWS and 'dll' or 'so') package.cpath = DATADIR .. '/?.' .. dynamic_suffix .. ';' .. package.cpath +package.cpath = USERDIR .. '/?.' .. dynamic_suffix .. ';' .. package.cpath package.searchers[3] = function(modname) local s,e = 0 repeat diff --git a/generate_header.sh b/generate_header.sh deleted file mode 100755 index fb03e712..00000000 --- a/generate_header.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# Takes lua folder, outputs a header file that includes all the necessary macros for writing a lite plugin. -# Takes a minimal approach, and strips out problematic functions. Should be good enough for most purposes. - -echo "// This file was automatically generated by generate_header.sh. Do not modify directly." -echo "#include " -echo "typedef struct lua_State lua_State; typedef double lua_Number; typedef int (*lua_CFunction)(lua_State*); typedef ptrdiff_t lua_Integer;" -echo "typedef unsigned long lua_Unsigned; typedef struct luaL_Buffer luaL_Buffer; typedef struct luaL_Reg luaL_Reg; typedef struct lua_Debug lua_Debug;" -echo "typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);" -echo "typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);" -echo "typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);" -grep -h "^LUA\(LIB\)*_API" $1/*.h | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^/static /" -grep -h "#define luaL*_" $1/*.h | grep -v "\\\s*$" | grep -v "\(assert\|lock\)" | grep -v "\(asm\|int32\)" | grep -v "#define lua_number2integer(i,n)\s*lua_number2int(i, n)" -echo "#define IMPORT_SYMBOL(name, ret, ...) name = (ret (*)(__VA_ARGS__))symbol(#name)" -echo "static void lite_init_plugin(void* (*symbol(const char*))) {" -grep -h "^LUA\(LIB\)*_API" $1/*.h | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^\([^)]*\)(\*\(lua\w*\))\s*(/\tIMPORT_SYMBOL(\2, \1,/" -echo "}" diff --git a/lite_plugin_api.h b/resources/lite_xl_plugin_api.h similarity index 91% rename from lite_plugin_api.h rename to resources/lite_xl_plugin_api.h index b6c03204..7ac9c5e8 100644 --- a/lite_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -1,4 +1,30 @@ -// This file was automatically generated by generate_header.sh. Do not modify directly. +#ifndef LITE_XL_PLUGIN_API +#define LITE_XL_PLUGIN_API +/* This file was automatically generated by the below code. Do not modify directly. +#!/bin/sh +# Takes lua folder, outputs a header file that includes all the necessary macros for writing a lite plugin. +# Takes a minimal approach, and strips out problematic functions. Should be good enough for most purposes. + +echo "#ifndef LITE_XL_PLUGIN_API" +echo "#define LITE_XL_PLUGIN_API" +echo "/* This file was automatically generated by the below code. Do not modify directly." +cat $0 +echo "*""/" +echo "#include " +echo "typedef struct lua_State lua_State; typedef double lua_Number; typedef int (*lua_CFunction)(lua_State*); typedef ptrdiff_t lua_Integer;" +echo "typedef unsigned long lua_Unsigned; typedef struct luaL_Buffer luaL_Buffer; typedef struct luaL_Reg luaL_Reg; typedef struct lua_Debug lua_Debug;" +echo "typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);" +echo "typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);" +echo "typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);" +LUA_HEADERS=`pkg-config --cflags lua5.2 | sed 's/^-I//' | sed 's/$/\/*.h/'` +grep -h "^LUA\(LIB\)*_API" $LUA_HEADERS | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^/static /" +grep -h "#define luaL*_" $LUA_HEADERS | grep -v "\\\s*$" | grep -v "\(assert\|lock\)" | grep -v "\(asm\|int32\)" | grep -v "#define lua_number2integer(i,n)\s*lua_number2int(i, n)" +echo "#define IMPORT_SYMBOL(name, ret, ...) name = (ret (*)(__VA_ARGS__))symbol(#name)" +echo "static void lite_init_plugin(void* (*symbol(const char*))) {" +grep -h "^LUA\(LIB\)*_API" $LUA_HEADERS | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^\([^)]*\)(\*\(lua\w*\))\s*(/\tIMPORT_SYMBOL(\2, \1,/" +echo "}" +echo "#endif" +*/ #include typedef struct lua_State lua_State; typedef double lua_Number; typedef int (*lua_CFunction)(lua_State*); typedef ptrdiff_t lua_Integer; typedef unsigned long lua_Unsigned; typedef struct luaL_Buffer luaL_Buffer; typedef struct luaL_Reg luaL_Reg; typedef struct lua_Debug lua_Debug; @@ -142,10 +168,6 @@ static void (*luaL_openlibs) (lua_State *L); #define luaL_addsize(B,s) ((B)->n += (s)) #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) -#define lua_number2int(i,n) ((i)=(int)(n)) -#define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) -#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) -#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol) #define lua_h #define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) #define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) @@ -298,3 +320,4 @@ static void lite_init_plugin(void* (*symbol(const char*))) { IMPORT_SYMBOL(lua_gethookcount, int ,lua_State *L); IMPORT_SYMBOL(luaL_openlibs, void ,lua_State *L); } +#endif diff --git a/sample_plugin.c b/sample_plugin.c deleted file mode 100644 index 96e021c9..00000000 --- a/sample_plugin.c +++ /dev/null @@ -1,10 +0,0 @@ - -#include "lite_plugin_api.h" - -int lua_open_sample(lua_State* L, void* (*symbol(const char*))) { - lite_init_plugin(symbol); - lua_createtable(L, 0, 0); - lua_pushstring(L, "value"); - lua_setfield(L, -2, "example"); - return 1; -} From 03b467d9d98ef0e7d9c369b92c7b5a49a0d462cf Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 16 Sep 2021 16:08:21 -0400 Subject: [PATCH 05/20] Cleaned up, added utility API. --- resources/lite_xl_plugin_api.h | 6 ++-- src/api/system.c | 62 +++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h index 7ac9c5e8..bd2d3dba 100644 --- a/resources/lite_xl_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -20,7 +20,8 @@ LUA_HEADERS=`pkg-config --cflags lua5.2 | sed 's/^-I//' | sed 's/$/\/*.h/'` grep -h "^LUA\(LIB\)*_API" $LUA_HEADERS | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^/static /" grep -h "#define luaL*_" $LUA_HEADERS | grep -v "\\\s*$" | grep -v "\(assert\|lock\)" | grep -v "\(asm\|int32\)" | grep -v "#define lua_number2integer(i,n)\s*lua_number2int(i, n)" echo "#define IMPORT_SYMBOL(name, ret, ...) name = (ret (*)(__VA_ARGS__))symbol(#name)" -echo "static void lite_init_plugin(void* (*symbol(const char*))) {" +echo "static void lite_xl_plugin_init(void* XL) {" +echo "\tvoid* (*symbol)(const char*) = (void* (*)(const char*))XL;" grep -h "^LUA\(LIB\)*_API" $LUA_HEADERS | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^\([^)]*\)(\*\(lua\w*\))\s*(/\tIMPORT_SYMBOL(\2, \1,/" echo "}" echo "#endif" @@ -197,7 +198,8 @@ static void (*luaL_openlibs) (lua_State *L); #define lua_str2number(s,p) strtod((s), (p)) #define lua_strx2number(s,p) strtod((s), (p)) #define IMPORT_SYMBOL(name, ret, ...) name = (ret (*)(__VA_ARGS__))symbol(#name) -static void lite_init_plugin(void* (*symbol(const char*))) { +static void lite_xl_plugin_init(void* XL) { + void* (*symbol)(const char*) = (void* (*)(const char*))XL; IMPORT_SYMBOL(luaL_checkversion_, void ,lua_State *L, lua_Number ver); IMPORT_SYMBOL(luaL_getmetafield, int ,lua_State *L, int obj, const char *e); IMPORT_SYMBOL(luaL_callmeta, int ,lua_State *L, int obj, const char *e); diff --git a/src/api/system.c b/src/api/system.c index 78b3e700..01cf72a7 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -645,6 +645,7 @@ typedef struct { } lua_function_node; #define P(FUNC) { "lua_" #FUNC, (void*)(lua_##FUNC) } +#define U(FUNC) { "luaL_" #FUNC, (void*)(luaL_##FUNC) } static void* api_require(const char* symbol) { static lua_function_node nodes[] = { P(absindex), P(arith), P(atpanic), P(callk), P(checkstack), @@ -652,21 +653,26 @@ static void* api_require(const char* symbol) { P(error), P(gc), P(getallocf), P(getctx), P(getfield), P(getglobal), P(gethook), P(gethookcount), P(gethookmask), P(getinfo), P(getlocal), P(getmetatable), P(getstack), P(gettable), P(gettop), P(getupvalue), - P(getuservalue), P(insert), P(isnumber), - P(isstring), P(isuserdata), P(len), P(load), - P(newstate), P(newthread), P(newuserdata), P(next), - P(pcallk), P(pushboolean), P(pushcclosure), - P(pushfstring), P(pushinteger), P(pushlightuserdata), - P(pushlstring), P(pushnil), P(pushnumber), P(pushstring), - P(pushthread), P(pushunsigned), P(pushvalue), P(pushvfstring), P(rawequal), - P(rawget), P(rawgeti), P(rawgetp), P(rawlen), P(rawset), P(rawseti), - P(rawsetp), P(remove), P(replace), P(resume), P(setallocf), - P(setfield), P(setglobal), P(sethook), P(setlocal), P(setmetatable), - P(settable), P(settop), P(setupvalue), P(setuservalue), P(status), - P(tocfunction), P(tointegerx), P(tolstring), P(toboolean), - P(tonumberx), P(topointer), P(tothread), - P(tounsignedx), P(touserdata), P(type), P(typename), P(upvalueid), - P(upvaluejoin), P(version), P(xmove), P(yieldk) + P(getuservalue), P(insert), P(isnumber), P(isstring), P(isuserdata), + P(len), P(load), P(newstate), P(newthread), P(newuserdata), P(next), + P(pcallk), P(pushboolean), P(pushcclosure), P(pushfstring), P(pushinteger), + P(pushlightuserdata), P(pushlstring), P(pushnil), P(pushnumber), + P(pushstring), P(pushthread), P(pushunsigned), P(pushvalue), + P(pushvfstring), P(rawequal), P(rawget), P(rawgeti), P(rawgetp), P(rawlen), + P(rawset), P(rawseti), P(rawsetp), P(remove), P(replace), P(resume), + P(setallocf), P(setfield), P(setglobal), P(sethook), P(setlocal), + P(setmetatable), P(settable), P(settop), P(setupvalue), P(setuservalue), + P(status), P(tocfunction), P(tointegerx), P(tolstring), P(toboolean), + P(tonumberx), P(topointer), P(tothread), P(tounsignedx), P(touserdata), + P(type), P(typename), P(upvalueid), P(upvaluejoin), P(version), P(xmove), + P(yieldk), U(checkversion_), U(getmetafield), U(callmeta), U(tolstring), + U(argerror), U(checknumber), U(optnumber), U(checkinteger), + U(checkunsigned), U(checkstack), U(checktype), U(checkany), + U(newmetatable), U(setmetatable), U(testudata), U(checkudata), U(where), + U(error), U(fileresult), U(execresult), U(ref), U(unref), U(loadstring), + U(newstate), U(len), U(setfuncs), U(getsubtable), U(buffinit), + U(prepbuffsize), U(addlstring), U(addstring), U(addvalue), U(pushresult), + U(pushresultsize), U(buffinitsize) }; for (int i = 0; i < sizeof(nodes) / sizeof(lua_function_node); ++i) { if (strcmp(nodes[i].symbol, symbol) == 0) @@ -676,26 +682,26 @@ static void* api_require(const char* symbol) { } static int f_load_native_plugin(lua_State* L) { - size_t sname, modlen, pathlen; - char buffer[512] = "lua_open_"; - const char* modname = luaL_checklstring(L, -2, &modlen); + size_t sname, namelen, pathlen; + char olib[512]; + const char* name = luaL_checklstring(L, -2, &namelen); const char* path = luaL_checklstring(L, -1, &pathlen); void* library = SDL_LoadObject(path); - if (modlen == 0 || !library) - return luaL_error(L, "Unable to load %s: %s", modname, SDL_GetError()); - for (sname = modlen - 1; sname > 0 && modname[sname] != '.'; --sname); - strcat(buffer, &modname[sname+1]); - int (*entrypoint)(lua_State* L, void*) = SDL_LoadFunction(library, buffer); + if (name == 0 || !library) + return luaL_error(L, "Unable to load %s: %s", name, SDL_GetError()); + for (sname = namelen - 1; sname > 0 && name[sname] != '.'; --sname); + snprintf(olib, sizeof(olib), "lua_open_%s", &name[sname+1]); olib[511] = 0; + int (*entrypoint)(lua_State* L, void*) = SDL_LoadFunction(library, olib); if (!entrypoint) { return luaL_error(L, "Unable to load %s: Can't find entrypoint. Requires a " - "function defined as int %s(lua_State* L, void* (*symbol)(const char*))", - modname, buffer); + "function defined as int %s(lua_State* L, void* XL)", + name, olib); } lua_pushlightuserdata(L, library); - lua_setfield(L, LUA_REGISTRYINDEX, modname); + lua_setfield(L, LUA_REGISTRYINDEX, name); if (entrypoint(L, api_require) == 0) - return luaL_error(L, "Unable to load %s: Your entrypoint must return at\ - least one argument."); + return luaL_error(L, "Unable to load %s: Your entrypoint must return at " + " least one value.", name); return 1; } From 801b7dd0d9ce3addb1855a014b792e8feae3d14b Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 16 Sep 2021 16:22:33 -0400 Subject: [PATCH 06/20] Added some comments. --- resources/lite_xl_plugin_api.h | 41 +++++++++++++++++++++++++++++----- src/api/system.c | 4 ++-- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h index bd2d3dba..ba9b053f 100644 --- a/resources/lite_xl_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -1,13 +1,44 @@ #ifndef LITE_XL_PLUGIN_API #define LITE_XL_PLUGIN_API -/* This file was automatically generated by the below code. Do not modify directly. -#!/bin/sh -# Takes lua folder, outputs a header file that includes all the necessary macros for writing a lite plugin. -# Takes a minimal approach, and strips out problematic functions. Should be good enough for most purposes. +/* +The lite_xl plugin API is quite simple. Any shared library can be a plugin file, so long +as it has an entrypoint that looks like the following, where xxxxx is the plugin name: +#include "lite_xl_plugin_api.h" + +int lua_open_xxxxx(lua_State* L, void* XL) { + lite_xl_plugin_init(XL); + ... + return 1; +} + +In linux, to compile this file, you'd do: 'gcc -o xxxxx.so -shared xxxxx.c'. Simple! +Due to the way the API is structured, you *should not* link or include lua libraries. + +This file was automatically generated by the below code. Do NOT MODIFY DIRECTLY. + + +#!/bin/sh echo "#ifndef LITE_XL_PLUGIN_API" echo "#define LITE_XL_PLUGIN_API" -echo "/* This file was automatically generated by the below code. Do not modify directly." +echo "/* " +echo "The lite_xl plugin API is quite simple. Any shared library can be a plugin file, so long" +echo "as it has an entrypoint that looks like the following, where xxxxx is the plugin name:" +echo +echo '#include "lite_xl_plugin_api.h"' +echo +echo "int lua_open_xxxxx(lua_State* L, void* XL) {" +echo " lite_xl_plugin_init(XL);" +echo " ..." +echo " return 1;" +echo "}" +echo +echo "In linux, to compile this file, you'd do: 'gcc -o xxxxx.so -shared xxxxx.c'. Simple!" +echo "Due to the way the API is structured, you *should not* link or include lua libraries." +echo +echo "This file was automatically generated by the below code. Do NOT MODIFY DIRECTLY." +echo +echo cat $0 echo "*""/" echo "#include " diff --git a/src/api/system.c b/src/api/system.c index 01cf72a7..e5ec18cd 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -637,8 +637,8 @@ static int f_set_window_opacity(lua_State *L) { return 1; } - - +// Symbol table for native plugin loading. Allows for a statically +// bound lua library to be used by native plugins. typedef struct { const char* symbol; void* address; From 10c3c9d4cf14cd1fdf5f2db97b1473c3f7d5a4db Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 16 Sep 2021 16:24:07 -0400 Subject: [PATCH 07/20] Undid deletion. --- data/core/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/data/core/init.lua b/data/core/init.lua index e05d5c2b..af291767 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -675,6 +675,7 @@ local function check_plugin_version(filename) return true, version_match end + function core.load_plugins() local no_errors = true local refused_list = { From 1721b8f1c9859f037bef49480c24430805c2e521 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 16 Sep 2021 16:28:02 -0400 Subject: [PATCH 08/20] Should be elif. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 3e99c735..4b15ef34 100644 --- a/src/main.c +++ b/src/main.c @@ -146,7 +146,7 @@ init_lua: #ifdef MACOS_USE_BUNDLE set_macos_bundle_resources(L); #endif -#elsif _WIN32 +#elif _WIN32 lua_setglobal(L, "WINDOWS"); #else lua_setglobal(L, "LINUX"); From fbc11c00eb2c422a0347a8c1c92d533c212c4ad4 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 16 Sep 2021 16:55:33 -0400 Subject: [PATCH 09/20] Split entrypoints in half. --- resources/lite_xl_plugin_api.h | 4 ++-- src/api/system.c | 30 +++++++++++++++++++----------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h index ba9b053f..08e22137 100644 --- a/resources/lite_xl_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -6,7 +6,7 @@ as it has an entrypoint that looks like the following, where xxxxx is the plugin #include "lite_xl_plugin_api.h" -int lua_open_xxxxx(lua_State* L, void* XL) { +int lua_open_lite_xl_xxxxx(lua_State* L, void* XL) { lite_xl_plugin_init(XL); ... return 1; @@ -27,7 +27,7 @@ echo "as it has an entrypoint that looks like the following, where xxxxx is the echo echo '#include "lite_xl_plugin_api.h"' echo -echo "int lua_open_xxxxx(lua_State* L, void* XL) {" +echo "int lua_open_lite_xl_xxxxx(lua_State* L, void* XL) {" echo " lite_xl_plugin_init(XL);" echo " ..." echo " return 1;" diff --git a/src/api/system.c b/src/api/system.c index e5ec18cd..47709344 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -683,26 +683,34 @@ static void* api_require(const char* symbol) { static int f_load_native_plugin(lua_State* L) { size_t sname, namelen, pathlen; - char olib[512]; + int results; + char olib[512]; olib[sizeof(olib)-1] = 0; const char* name = luaL_checklstring(L, -2, &namelen); const char* path = luaL_checklstring(L, -1, &pathlen); void* library = SDL_LoadObject(path); if (name == 0 || !library) return luaL_error(L, "Unable to load %s: %s", name, SDL_GetError()); - for (sname = namelen - 1; sname > 0 && name[sname] != '.'; --sname); - snprintf(olib, sizeof(olib), "lua_open_%s", &name[sname+1]); olib[511] = 0; - int (*entrypoint)(lua_State* L, void*) = SDL_LoadFunction(library, olib); - if (!entrypoint) { - return luaL_error(L, "Unable to load %s: Can't find entrypoint. Requires a " - "function defined as int %s(lua_State* L, void* XL)", - name, olib); - } lua_pushlightuserdata(L, library); lua_setfield(L, LUA_REGISTRYINDEX, name); - if (entrypoint(L, api_require) == 0) + for (sname = namelen - 1; sname > 0 && name[sname] != '.'; --sname); + snprintf(olib, sizeof(olib), "lua_open_lite_xl_%s", &name[sname+1]); + int (*ext_entrypoint)(lua_State* L, void*) = SDL_LoadFunction(library, olib); + if (!ext_entrypoint) { + snprintf(olib, sizeof(olib), "lua_open_%s", &name[sname+1]); + int (*entrypoint)(lua_State* L) = SDL_LoadFunction(library, olib); + if (!entrypoint) { + return luaL_error(L, "Unable to load %s: Can't find entrypoint. Requires a " + "function defined as int lua_open_lite_xl_%s(lua_State* L, void* XL)", + name, &name[sname+1]); + } + results = entrypoint(L); + } else { + results = ext_entrypoint(L, api_require); + } + if (!results) return luaL_error(L, "Unable to load %s: Your entrypoint must return at " " least one value.", name); - return 1; + return results; } From 3ca127793af09eb30d01085c3572addcf9fdcafc Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Mon, 20 Sep 2021 23:33:12 -0400 Subject: [PATCH 10/20] Incorporated some suggestions, and some functions. --- data/core/start.lua | 15 ++++----------- resources/lite_xl_plugin_api.h | 4 ++++ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/data/core/start.lua b/data/core/start.lua index 0bbaadee..2b340d5d 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -21,16 +21,9 @@ package.path = USERDIR .. '/?.lua;' .. package.path package.path = USERDIR .. '/?/init.lua;' .. package.path local dynamic_suffix = MACOS and 'lib' or (WINDOWS and 'dll' or 'so') -package.cpath = DATADIR .. '/?.' .. dynamic_suffix .. ';' .. package.cpath -package.cpath = USERDIR .. '/?.' .. dynamic_suffix .. ';' .. package.cpath +package.cpath = DATADIR .. '/?.' .. dynamic_suffix .. ";" .. USERDIR .. '/?.' .. dynamic_suffix package.searchers[3] = function(modname) - local s,e = 0 - repeat - e = package.cpath:find(";", s) or #package.cpath - local path = package.cpath:sub(s, e - 1):gsub("?", modname:gsub("%.", "/")) - if system.get_file_info(path) then - return system.load_native_plugin, path - end - s = e + 1 - until s > #package.cpath + local path = package.searchpath(modname, package.cpath) + if not path then return nil end + return system.load_native_plugin, path end diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h index 08e22137..44c1b4d3 100644 --- a/resources/lite_xl_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -50,6 +50,8 @@ echo "typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* u LUA_HEADERS=`pkg-config --cflags lua5.2 | sed 's/^-I//' | sed 's/$/\/*.h/'` grep -h "^LUA\(LIB\)*_API" $LUA_HEADERS | sed "s/LUA\(LIB\)*_API //" | sed "s/(lua/(*lua/" | grep -v ",\s*$" | sed "s/^/static /" grep -h "#define luaL*_" $LUA_HEADERS | grep -v "\\\s*$" | grep -v "\(assert\|lock\)" | grep -v "\(asm\|int32\)" | grep -v "#define lua_number2integer(i,n)\s*lua_number2int(i, n)" +echo "#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)" +echo "#define lua_pushglobaltable(L) lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)" echo "#define IMPORT_SYMBOL(name, ret, ...) name = (ret (*)(__VA_ARGS__))symbol(#name)" echo "static void lite_xl_plugin_init(void* XL) {" echo "\tvoid* (*symbol)(const char*) = (void* (*)(const char*))XL;" @@ -228,6 +230,8 @@ static void (*luaL_openlibs) (lua_State *L); #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) #define lua_str2number(s,p) strtod((s), (p)) #define lua_strx2number(s,p) strtod((s), (p)) +#define lua_pushliteral(L, s) lua_pushlstring(L, s, (sizeof(s)/sizeof(char))-1) +#define lua_pushglobaltable(L) lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) #define IMPORT_SYMBOL(name, ret, ...) name = (ret (*)(__VA_ARGS__))symbol(#name) static void lite_xl_plugin_init(void* XL) { void* (*symbol)(const char*) = (void* (*)(const char*))XL; From c01c5a23b087a5926803911514a06a488bb58de9 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Mon, 20 Sep 2021 23:38:10 -0400 Subject: [PATCH 11/20] Added in plugin table. --- src/api/system.c | 4 +++- src/main.c | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/api/system.c b/src/api/system.c index 47709344..e35e4558 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -690,8 +690,10 @@ static int f_load_native_plugin(lua_State* L) { void* library = SDL_LoadObject(path); if (name == 0 || !library) return luaL_error(L, "Unable to load %s: %s", name, SDL_GetError()); + lua_getfield(L, LUA_REGISTRYINDEX, "native_plugins"); lua_pushlightuserdata(L, library); - lua_setfield(L, LUA_REGISTRYINDEX, name); + lua_setfield(L, -2, name); + lua_pop(L, 1); for (sname = namelen - 1; sname > 0 && name[sname] != '.'; --sname); snprintf(olib, sizeof(olib), "lua_open_lite_xl_%s", &name[sname+1]); int (*ext_entrypoint)(lua_State* L, void*) = SDL_LoadFunction(library, olib); diff --git a/src/main.c b/src/main.c index 4b15ef34..4a95a76b 100644 --- a/src/main.c +++ b/src/main.c @@ -152,6 +152,9 @@ init_lua: lua_setglobal(L, "LINUX"); #endif + lua_newtable(L); + lua_setfield(L, LUA_REGISTRYINDEX, "native_plugins"); + const char *init_lite_code = \ "local core\n" "xpcall(function()\n" From e13529444fcbbef190a98fd909e9a87929289f4b Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Mon, 20 Sep 2021 23:42:39 -0400 Subject: [PATCH 12/20] Less C code, and more namespacing is better. --- data/core/start.lua | 1 + src/api/system.c | 3 ++- src/main.c | 3 --- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/data/core/start.lua b/data/core/start.lua index 2b340d5d..a84b4faa 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -22,6 +22,7 @@ package.path = USERDIR .. '/?/init.lua;' .. package.path local dynamic_suffix = MACOS and 'lib' or (WINDOWS and 'dll' or 'so') package.cpath = DATADIR .. '/?.' .. dynamic_suffix .. ";" .. USERDIR .. '/?.' .. dynamic_suffix +package.native_plugins = {} package.searchers[3] = function(modname) local path = package.searchpath(modname, package.cpath) if not path then return nil end diff --git a/src/api/system.c b/src/api/system.c index e35e4558..68d25ae9 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -690,7 +690,8 @@ static int f_load_native_plugin(lua_State* L) { void* library = SDL_LoadObject(path); if (name == 0 || !library) return luaL_error(L, "Unable to load %s: %s", name, SDL_GetError()); - lua_getfield(L, LUA_REGISTRYINDEX, "native_plugins"); + lua_getglobal(L, "package"); + lua_getfield(L, -1, "native_plugins"); lua_pushlightuserdata(L, library); lua_setfield(L, -2, name); lua_pop(L, 1); diff --git a/src/main.c b/src/main.c index 4a95a76b..4b15ef34 100644 --- a/src/main.c +++ b/src/main.c @@ -152,9 +152,6 @@ init_lua: lua_setglobal(L, "LINUX"); #endif - lua_newtable(L); - lua_setfield(L, LUA_REGISTRYINDEX, "native_plugins"); - const char *init_lite_code = \ "local core\n" "xpcall(function()\n" From 713ef787c2963d2b4f2e474b320f1f0adcb3582c Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Mon, 20 Sep 2021 23:50:06 -0400 Subject: [PATCH 13/20] Removed extra macros, used PLATFORM. Also removed MACOS, as it's redundant C code that's already encapsulated within PLATFORM. --- data/core/keymap.lua | 2 +- data/core/start.lua | 2 +- src/main.c | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/data/core/keymap.lua b/data/core/keymap.lua index 50eadec6..7f7c0fe2 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -5,7 +5,7 @@ keymap.modkeys = {} keymap.map = {} keymap.reverse_map = {} -local macos = rawget(_G, "MACOS") +local macos = PLATFORM == "Mac OS X" -- Thanks to mathewmariani, taken from his lite-macos github repository. local modkeys_os = require("core.modkeys-" .. (macos and "macos" or "generic")) diff --git a/data/core/start.lua b/data/core/start.lua index a84b4faa..0311774d 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -20,7 +20,7 @@ package.path = DATADIR .. '/?/init.lua;' .. package.path package.path = USERDIR .. '/?.lua;' .. package.path package.path = USERDIR .. '/?/init.lua;' .. package.path -local dynamic_suffix = MACOS and 'lib' or (WINDOWS and 'dll' or 'so') +local dynamic_suffix = PLATFORM == "Mac OS X" and 'lib' or (PLATFORM == "Windows" and 'dll' or 'so') package.cpath = DATADIR .. '/?.' .. dynamic_suffix .. ";" .. USERDIR .. '/?.' .. dynamic_suffix package.native_plugins = {} package.searchers[3] = function(modname) diff --git a/src/main.c b/src/main.c index 4b15ef34..ac97e698 100644 --- a/src/main.c +++ b/src/main.c @@ -141,15 +141,10 @@ init_lua: lua_pushboolean(L, true); #ifdef __APPLE__ - lua_setglobal(L, "MACOS"); enable_momentum_scroll(); #ifdef MACOS_USE_BUNDLE set_macos_bundle_resources(L); #endif -#elif _WIN32 - lua_setglobal(L, "WINDOWS"); -#else - lua_setglobal(L, "LINUX"); #endif const char *init_lite_code = \ From 5ffe4eae909fe6694a8eec8f04b864acb4c93d36 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Mon, 20 Sep 2021 23:54:52 -0400 Subject: [PATCH 14/20] Removed extra boolean. --- src/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.c b/src/main.c index ac97e698..ee9c68fe 100644 --- a/src/main.c +++ b/src/main.c @@ -139,7 +139,6 @@ init_lua: lua_pushstring(L, exename); lua_setglobal(L, "EXEFILE"); - lua_pushboolean(L, true); #ifdef __APPLE__ enable_momentum_scroll(); #ifdef MACOS_USE_BUNDLE From b8da46e10ea3fa002c28ab2445b41f058af006e6 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 22 Sep 2021 17:24:22 -0400 Subject: [PATCH 15/20] Removed searchers[4]. --- data/core/start.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/core/start.lua b/data/core/start.lua index 0311774d..9c2e64e4 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -23,8 +23,8 @@ package.path = USERDIR .. '/?/init.lua;' .. package.path local dynamic_suffix = PLATFORM == "Mac OS X" and 'lib' or (PLATFORM == "Windows" and 'dll' or 'so') package.cpath = DATADIR .. '/?.' .. dynamic_suffix .. ";" .. USERDIR .. '/?.' .. dynamic_suffix package.native_plugins = {} -package.searchers[3] = function(modname) +package.searchers = { package.seachers[1], package.searchers[2], function(modname) local path = package.searchpath(modname, package.cpath) if not path then return nil end return system.load_native_plugin, path -end +end } From 466464d8a4f3ca815cc9eb0d94a97a4b5e40b978 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 22 Sep 2021 17:25:16 -0400 Subject: [PATCH 16/20] Mispelling. --- data/core/start.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/core/start.lua b/data/core/start.lua index 9c2e64e4..330c42f5 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -23,7 +23,7 @@ package.path = USERDIR .. '/?/init.lua;' .. package.path local dynamic_suffix = PLATFORM == "Mac OS X" and 'lib' or (PLATFORM == "Windows" and 'dll' or 'so') package.cpath = DATADIR .. '/?.' .. dynamic_suffix .. ";" .. USERDIR .. '/?.' .. dynamic_suffix package.native_plugins = {} -package.searchers = { package.seachers[1], package.searchers[2], function(modname) +package.searchers = { package.searchers[1], package.searchers[2], function(modname) local path = package.searchpath(modname, package.cpath) if not path then return nil end return system.load_native_plugin, path From 27fe185ed44b89a2c36b2036ec5f27da995e632f Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sat, 25 Sep 2021 10:31:15 +0800 Subject: [PATCH 17/20] fix unable to load any native library something went wrong in snprintf that it skips the first character of the library name. Not only that, the signature is actually luaopen and not lua_open. --- src/api/system.c | 49 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/api/system.c b/src/api/system.c index 0cd64271..bcd1b997 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -695,39 +695,40 @@ static void* api_require(const char* symbol) { return NULL; } -static int f_load_native_plugin(lua_State* L) { - size_t sname, namelen, pathlen; - int results; - char olib[512]; olib[sizeof(olib)-1] = 0; - const char* name = luaL_checklstring(L, -2, &namelen); - const char* path = luaL_checklstring(L, -1, &pathlen); - void* library = SDL_LoadObject(path); - if (name == 0 || !library) +static int f_load_native_plugin(lua_State *L) { + char entrypoint_name[512]; entrypoint_name[sizeof(entrypoint_name) - 1] = '\0'; + int result; + + const char *name = luaL_checkstring(L, 1); + const char *path = luaL_checkstring(L, 2); + void *library = SDL_LoadObject(path); + if (!library) return luaL_error(L, "Unable to load %s: %s", name, SDL_GetError()); + lua_getglobal(L, "package"); lua_getfield(L, -1, "native_plugins"); lua_pushlightuserdata(L, library); lua_setfield(L, -2, name); lua_pop(L, 1); - for (sname = namelen - 1; sname > 0 && name[sname] != '.'; --sname); - snprintf(olib, sizeof(olib), "lua_open_lite_xl_%s", &name[sname+1]); - int (*ext_entrypoint)(lua_State* L, void*) = SDL_LoadFunction(library, olib); + + const char *basename = strrchr(name, '.'); + basename = !basename ? name : basename + 1; + snprintf(entrypoint_name, sizeof(entrypoint_name), "luaopen_lite_xl_%s", basename); + int (*ext_entrypoint) (lua_State *L, void*) = SDL_LoadFunction(library, entrypoint_name); if (!ext_entrypoint) { - snprintf(olib, sizeof(olib), "lua_open_%s", &name[sname+1]); - int (*entrypoint)(lua_State* L) = SDL_LoadFunction(library, olib); - if (!entrypoint) { - return luaL_error(L, "Unable to load %s: Can't find entrypoint. Requires a " - "function defined as int lua_open_lite_xl_%s(lua_State* L, void* XL)", - name, &name[sname+1]); - } - results = entrypoint(L); + snprintf(entrypoint_name, sizeof(entrypoint_name), "luaopen_%s", basename); + int (*entrypoint)(lua_State *L) = SDL_LoadFunction(library, entrypoint_name); + if (!entrypoint) + return luaL_error(L, "Unable to load %s: Can't find %s(lua_State *L, void *XL)", name, entrypoint_name); + result = entrypoint(L); } else { - results = ext_entrypoint(L, api_require); + result = ext_entrypoint(L, api_require); } - if (!results) - return luaL_error(L, "Unable to load %s: Your entrypoint must return at " - " least one value.", name); - return results; + + if (!result) + return luaL_error(L, "Unable to load %s: entrypoint must return a value", name); + + return result; } From 84622a0009deb57dec47ebedaada846ffb2bf7fe Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 26 Sep 2021 10:18:13 -0400 Subject: [PATCH 18/20] Potentially fixing issue with cache not invalidating on restart. (#548) --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index 6275be74..a7147e76 100644 --- a/src/main.c +++ b/src/main.c @@ -184,6 +184,7 @@ init_lua: lua_pcall(L, 0, 1, 0); if (lua_toboolean(L, -1)) { lua_close(L); + rencache_invalidate(); goto init_lua; } From 8f8af19cbe480cef85c2fdc24f06b4d4cc37077f Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 26 Sep 2021 10:21:57 -0400 Subject: [PATCH 19/20] Rearranged DPI calc so that on calc failure, returns 1. (#547) --- src/main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index a7147e76..4eb1ec03 100644 --- a/src/main.c +++ b/src/main.c @@ -18,13 +18,12 @@ SDL_Window *window; static double get_scale(void) { -#ifdef __APPLE__ - return 1.0; -#else - float dpi = 96.0; - SDL_GetDisplayDPI(0, NULL, &dpi, NULL); - return dpi / 96.0; +#ifndef __APPLE__ + float dpi; + if (SDL_GetDisplayDPI(0, NULL, &dpi, NULL) == 0) + return dpi / 96.0; #endif + return 1.0; } From 86bf023c90ffcb5d806c190d2bb3de43839fa58e Mon Sep 17 00:00:00 2001 From: Not-a-web-Developer <47886897+Not-a-web-Developer@users.noreply.github.com> Date: Mon, 27 Sep 2021 19:29:25 +0530 Subject: [PATCH 20/20] fixed the build link in readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 73204c57..71f856a1 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ See the [licenses] file for details on licenses used by the required dependencie [screenshot-dark]: https://user-images.githubusercontent.com/433545/111063905-66943980-84b1-11eb-9040-3876f1133b20.png [lite]: https://github.com/rxi/lite [website]: https://lite-xl.github.io -[build]: https://lite-xl.github.io/en/build +[build]: https://lite-xl.github.io/en/documentation/build/ [Get Lite XL]: https://github.com/franko/lite-xl/releases/latest [Get plugins]: https://github.com/franko/lite-plugins [Get color themes]: https://github.com/rxi/lite-colors