diff options
author | Hadriel Kaplan <hadrielk@yahoo.com> | 2014-03-26 19:12:04 -0400 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2014-03-27 05:03:39 +0000 |
commit | f3fe29f0fccaebaa7b7bb5db86604b241a1fa749 (patch) | |
tree | f2bb75112d459024c436b80bcae3dec27f72f2ae /epan | |
parent | 09055f18a567fc4b8a28d9271b71cf19ef95277a (diff) |
Add paths to Lua package.path so require works for user scripts
This adds the global and personal plugins directories to the
package.path setting in Lua, so doing 'require' will work
properly.
Change-Id: Iec33bc60cd7d41aa122da456db91d4ccc3085f82
Reviewed-on: https://code.wireshark.org/review/841
Reviewed-by: Hadriel Kaplan <hadrielk@yahoo.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/wslua/init_wslua.c | 24 | ||||
-rw-r--r-- | epan/wslua/template-init.lua | 43 |
2 files changed, 64 insertions, 3 deletions
diff --git a/epan/wslua/init_wslua.c b/epan/wslua/init_wslua.c index fb1e2e15c7..9c2cefeaa2 100644 --- a/epan/wslua/init_wslua.c +++ b/epan/wslua/init_wslua.c @@ -413,8 +413,12 @@ static int lua_script_push_args(const int script_num) { #define FILE_NAME_KEY "__FILE__" #define DIR_NAME_KEY "__DIR__" +#define DIR_SEP_NAME_KEY "__DIR_SEPARATOR__" /* assumes a loaded chunk's function is on top of stack */ static void set_file_environment(const gchar* filename, const gchar* dirname) { + const char* path; + char* personal = get_plugins_pers_dir(); + lua_newtable(L); /* environment for script (index 3) */ lua_pushstring(L, filename); /* tell the script about its filename */ @@ -423,14 +427,28 @@ static void set_file_environment(const gchar* filename, const gchar* dirname) { lua_pushstring(L, dirname); /* tell the script about its dirname */ lua_setfield(L, -2, DIR_NAME_KEY); /* make it accessible at __DIR__ */ - lua_newtable(L); /* metatable */ + lua_pushstring(L, G_DIR_SEPARATOR_S); /* tell the script the directory separator */ + lua_setfield(L, -2, DIR_SEP_NAME_KEY); /* make it accessible at __DIR__ */ + + lua_newtable(L); /* new metatable */ #if LUA_VERSION_NUM >= 502 lua_pushglobaltable(L); #else lua_pushvalue(L, LUA_GLOBALSINDEX); #endif - lua_setfield(L, -2, "__index"); /* __index points to global environment */ + /* prepend the directory name to _G.package.path */ + lua_getfield(L, -1, "package"); /* get the package table from the global table */ + lua_getfield(L, -1, "path"); /* get the path field from the package table */ + path = luaL_checkstring(L, -1); /* get the path string */ + lua_pop(L, 1); /* pop the path string */ + /* prepend the various paths */ + lua_pushfstring(L, "%s" G_DIR_SEPARATOR_S "?.lua;%s" G_DIR_SEPARATOR_S "?.lua;%s" G_DIR_SEPARATOR_S "?.lua;%s", + dirname, personal, get_plugin_dir(), path); + lua_setfield(L, -2, "path"); /* set the new string to be the path field of the package table */ + lua_setfield(L, -2, "package"); /* set the package table to be the package field of the global */ + + lua_setfield(L, -2, "__index"); /* make metatable's __index point to global table */ lua_setmetatable(L, -2); /* pop metatable, set it as metatable of environment */ @@ -439,6 +457,8 @@ static void set_file_environment(const gchar* filename, const gchar* dirname) { #else lua_setfenv(L, -2); /* pop environment and set it as the func's environment */ #endif + + g_free(personal); } /* If file_count > 0 then it's a command-line-added user script, and the count diff --git a/epan/wslua/template-init.lua b/epan/wslua/template-init.lua index 2f99159b07..806593739e 100644 --- a/epan/wslua/template-init.lua +++ b/epan/wslua/template-init.lua @@ -64,12 +64,53 @@ function typeof(obj) return mt and mt.__typeof or obj.__typeof or type(obj) end --- the following function is since 1.11.3 +-- the following function checks if a file exists +-- since 1.11.3 function file_exists(name) local f = io.open(name,"r") if f ~= nil then io.close(f) return true else return false end end +-- the following function prepends the given directory name to +-- the package.path, so that a 'require "foo"' will work if 'foo' +-- is in the directory name given to this function. For example, +-- if your Lua file will do a 'require "foo"' and the foo.lua +-- file is in a local directory (local to your script) named 'bar', +-- then call this function before doing your 'require', by doing +-- package.prepend_path("bar") +-- and that will let Wireshark's Lua find the file "bar/foo.lua" +-- when you later do 'require "foo"' +-- +-- Because this function resides here in init.lua, it does not +-- have the same environment as your script, so it has to get it +-- using the debug library, which is why the code appears so +-- cumbersome. +-- +-- since 1.11.3 +function package.prepend_path(name) + local debug = require "debug" + -- get the function calling this package.prepend_path function + local dt = debug.getinfo(2, "f") + if not dt then + error("could not retrieve debug info table") + end + -- get its upvalue + local _, val = debug.getupvalue(dt.func, 1) + if not val or type(val) ~= 'table' then + error("No calling function upvalue or it is not a table") + end + -- get the __DIR__ field in its upvalue table + local dir = val["__DIR__"] + -- get the platform-specific directory separator character + local sep = package.config:sub(1,1) + -- prepend the dir and given name to path + if dir and dir:len() > 0 then + package.path = dir .. sep .. name .. sep .. "?.lua;" .. package.path + end + -- also prepend just the name as a directory + package.path = name .. sep .. "?.lua;" .. package.path +end + -- %WTAP_ENCAPS% -- %WTAP_FILETYPES% |