summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHadriel Kaplan <hadrielk@yahoo.com>2014-03-26 19:12:04 -0400
committerAnders Broman <a.broman58@gmail.com>2014-03-27 05:03:39 +0000
commitf3fe29f0fccaebaa7b7bb5db86604b241a1fa749 (patch)
treef2bb75112d459024c436b80bcae3dec27f72f2ae
parent09055f18a567fc4b8a28d9271b71cf19ef95277a (diff)
downloadwireshark-f3fe29f0fccaebaa7b7bb5db86604b241a1fa749.tar.gz
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>
-rw-r--r--epan/wslua/init_wslua.c24
-rw-r--r--epan/wslua/template-init.lua43
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%