From 3d693f8b8bc40a9840e2279a149af665dfa62f6e Mon Sep 17 00:00:00 2001 From: Antoine Cellerier Date: Sat, 13 Feb 2010 14:14:04 +0100 Subject: [PATCH] Setup lua module search path For example, if runing script /lua/intf/script.lua, the following paths will be added: /lua/modules/?.lua /lua/intf/modules/?.lua /lua/modules/?.lua /lua/intf/modules/?.lua If runing script /lua/intf/script.lua, the following paths will be added: /lua/modules/?.lua /lua/intf/modules/?.lua --- modules/misc/lua/demux.c | 9 +++- modules/misc/lua/extension.c | 7 +++ modules/misc/lua/intf.c | 21 ++------ modules/misc/lua/meta.c | 22 ++++++-- modules/misc/lua/vlc.c | 97 ++++++++++++++++++++++++++++++++++++ modules/misc/lua/vlc.h | 3 ++ 6 files changed, 136 insertions(+), 23 deletions(-) diff --git a/modules/misc/lua/demux.c b/modules/misc/lua/demux.c index 29d80139c9..66a750157c 100644 --- a/modules/misc/lua/demux.c +++ b/modules/misc/lua/demux.c @@ -147,6 +147,14 @@ static int probe_luascript( vlc_object_t *p_this, const char * psz_filename, lua_pop( L, 1 ); + /* Setup the module search path */ + if( vlclua_add_modules_path( p_demux, L, psz_filename ) ) + { + msg_Warn( p_demux, "Error while setting the module search path for %s", + psz_filename ); + goto error; + } + /* Load and run the script(s) */ if( luaL_dofile( L, psz_filename ) ) { @@ -197,7 +205,6 @@ error: int Import_LuaPlaylist( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; - lua_State *L; int ret; p_demux->p_sys = (demux_sys_t*)malloc( sizeof( demux_sys_t ) ); diff --git a/modules/misc/lua/extension.c b/modules/misc/lua/extension.c index c82d11a0f7..139f5f674a 100644 --- a/modules/misc/lua/extension.c +++ b/modules/misc/lua/extension.c @@ -742,6 +742,13 @@ static lua_State* GetLuaState( extensions_manager_t *p_mgr, lua_pushcfunction( L, vlclua_extension_deactivate ); lua_setfield( L, -2, "deactivate" ); + /* Setup the module search path */ + if( vlclua_add_modules_path( p_mgr, L, p_ext->psz_name ) ) + { + msg_Warn( p_mgr, "Error while setting the module search path for %s", p_ext->psz_name ); + return NULL; + } + /* Load and run the script(s) */ if( luaL_dofile( L, p_ext->psz_name ) != 0 ) { diff --git a/modules/misc/lua/intf.c b/modules/misc/lua/intf.c index fd5583205a..6ee073e077 100644 --- a/modules/misc/lua/intf.c +++ b/modules/misc/lua/intf.c @@ -201,28 +201,13 @@ int Open_LuaIntf( vlc_object_t *p_this ) /* clean up */ lua_pop( L, 1 ); - /* */ /* Setup the module search path */ + if( vlclua_add_modules_path( p_intf, L, p_sys->psz_filename ) ) { - char *psz_command; - char *psz_char = strrchr(p_sys->psz_filename,DIR_SEP_CHAR); - *psz_char = '\0'; - /* FIXME: don't use luaL_dostring */ - if( asprintf( &psz_command, - "package.path = [[%s"DIR_SEP"modules"DIR_SEP"?.lua;]]..package.path", - p_sys->psz_filename ) < 0 ) - { + msg_Warn( p_intf, "Error while setting the module search path for %s", + p_sys->psz_filename ); goto error; } - *psz_char = DIR_SEP_CHAR; - if( luaL_dostring( L, psz_command ) ) - { - free( psz_command ); - goto error; - } - free( psz_command ); - } - /* */ psz_config = var_CreateGetString( p_intf, "lua-config" ); if( psz_config && *psz_config ) diff --git a/modules/misc/lua/meta.c b/modules/misc/lua/meta.c index 23220ca2b7..f2b619d90e 100644 --- a/modules/misc/lua/meta.c +++ b/modules/misc/lua/meta.c @@ -51,7 +51,7 @@ *****************************************************************************/ static const luaL_Reg p_reg[] = { { NULL, NULL } }; -static lua_State * init( vlc_object_t *p_this, input_item_t * p_item ) +static lua_State * init( vlc_object_t *p_this, input_item_t * p_item, const char *psz_filename ) { lua_State * L = luaL_newstate(); if( !L ) @@ -76,6 +76,14 @@ static lua_State * init( vlc_object_t *p_this, input_item_t * p_item ) lua_pushlightuserdata( L, p_this ); lua_setfield( L, -2, "private" ); + if( vlclua_add_modules_path( p_this, L, psz_filename ) ) + { + msg_Warn( p_this, "Error while setting the module search path for %s", + psz_filename ); + lua_close( L ); + return NULL; + } + return L; } @@ -131,7 +139,9 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename, input_item_t * p_item = user_data; int s; - lua_State *L = init( p_this, p_item ); + lua_State *L = init( p_this, p_item, psz_filename ); + if( !L ) + return VLC_EGENERIC; int i_ret = run(p_this, psz_filename, L, "fetch_art"); if(i_ret != VLC_SUCCESS) @@ -178,7 +188,9 @@ static int read_meta( vlc_object_t *p_this, const char * psz_filename, void * user_data ) { input_item_t * p_item = user_data; - lua_State *L = init( p_this, p_item ); + lua_State *L = init( p_this, p_item, psz_filename ); + if( !L ) + return VLC_EGENERIC; int i_ret = run(p_this, psz_filename, L, "read_meta"); if(i_ret != VLC_SUCCESS) @@ -201,7 +213,9 @@ static int fetch_meta( vlc_object_t *p_this, const char * psz_filename, void * user_data ) { input_item_t * p_item = user_data; - lua_State *L = init( p_this, p_item ); + lua_State *L = init( p_this, p_item, psz_filename ); + if( !L ) + return VLC_EGENERIC; int ret = run(p_this, psz_filename, L, "fetch_meta"); lua_close( L ); diff --git a/modules/misc/lua/vlc.c b/modules/misc/lua/vlc.c index 5e82328c5b..57d65cbba2 100644 --- a/modules/misc/lua/vlc.c +++ b/modules/misc/lua/vlc.c @@ -660,3 +660,100 @@ error: vlclua_dir_list_free( ppsz_dir_list ); return VLC_ENOMEM; } + +static int vlclua_add_modules_path_inner( lua_State *L, const char *psz_path ) +{ + /* FIXME: don't use luaL_dostring */ + char *psz_command = NULL; + if( asprintf( &psz_command, + "package.path =[[%s"DIR_SEP"modules"DIR_SEP"?.lua;]]..package.path", + psz_path ) < 0 ) + { + return 1; + } + + if( luaL_dostring( L, psz_command ) ) + { + free( psz_command ); + return 1; + } + free( psz_command ); + + return 0; +} + +int __vlclua_add_modules_path( vlc_object_t *obj, lua_State *L, const char *psz_filename ) +{ + /* Setup the module search path: + * * "The script's directory"/modules + * * "The script's parent directory"/modules + * * and so on for all the next directories in the directory list + */ + + char *psz_path = strdup( psz_filename ); + if( !psz_path ) + return 1; + + char *psz_char = strrchr( psz_path, DIR_SEP_CHAR ); + if( !psz_char ) + { + free( psz_path ); + return 1; + } + *psz_char = '\0'; + + /* psz_path now holds the file's directory */ + psz_char = strrchr( psz_path, DIR_SEP_CHAR ); + if( !psz_char ) + { + free( psz_path ); + return 1; + } + *psz_char = '\0'; + + /* psz_path now holds the file's parent directory */ + if( vlclua_add_modules_path_inner( L, psz_path ) ) + { + free( psz_path ); + return 1; + } + *psz_char = DIR_SEP_CHAR; + + /* psz_path now holds the file's directory */ + if( vlclua_add_modules_path_inner( L, psz_path ) ) + { + free( psz_path ); + return 1; + } + + char *ppsz_dir_list[] = { NULL, NULL, NULL, NULL }; + vlclua_dir_list( obj, psz_char+1/* gruik? */, ppsz_dir_list ); + char **ppsz_dir = ppsz_dir_list; + + for( ; *ppsz_dir && strcmp( *ppsz_dir, psz_path ); ppsz_dir++ ); + free( psz_path ); + + for( ; *ppsz_dir; ppsz_dir++ ) + { + psz_path = *ppsz_dir; + psz_char = strrchr( psz_path, DIR_SEP_CHAR ); + if( !psz_char ) + goto exit; + + *psz_char = '\0'; + if( vlclua_add_modules_path_inner( L, psz_path ) ) + goto exit; + *psz_char = DIR_SEP_CHAR; + + if( vlclua_add_modules_path_inner( L, psz_path ) ) + goto exit; + } + + vlclua_dir_list_free( ppsz_dir_list ); + return 0; + + exit: + vlclua_dir_list_free( ppsz_dir_list ); + return 1; +} + diff --git a/modules/misc/lua/vlc.h b/modules/misc/lua/vlc.h index cb71d98b30..7bca326a19 100644 --- a/modules/misc/lua/vlc.h +++ b/modules/misc/lua/vlc.h @@ -124,6 +124,9 @@ int __vlclua_playlist_add_internal( vlc_object_t *, lua_State *, playlist_t *, input_item_t *, bool ); #define vlclua_playlist_add_internal(a,b,c,d,e) __vlclua_playlist_add_internal(VLC_OBJECT(a),b,c,d,e) +int __vlclua_add_modules_path( vlc_object_t *, lua_State *, const char *psz_filename ); +#define vlclua_add_modules_path( a, b, c ) __vlclua_add_modules_path(VLC_OBJECT(a), b, c) + /** * Per-interface private state */ -- 2.39.2