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 = \