X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmisc%2Flua%2Fintf.c;h=3074355caedd70c182f95caab7facbd12059c4bf;hb=80303c27c6d6b1fd9899a158ebd798c4d8ae17bc;hp=2b0b38651b6176f3fc47b96709f470af1331c3ce;hpb=5eea1626ff7256bfa96de800770342880ad60e33;p=vlc diff --git a/modules/misc/lua/intf.c b/modules/misc/lua/intf.c index 2b0b38651b..3074355cae 100644 --- a/modules/misc/lua/intf.c +++ b/modules/misc/lua/intf.c @@ -50,22 +50,18 @@ /***************************************************************************** * Prototypes *****************************************************************************/ -struct intf_sys_t -{ - char *psz_filename; - lua_State *L; -}; +static void *Run( void * ); -static void Run( intf_thread_t *p_intf ); +static const char * const ppsz_intf_options[] = { "intf", "config", NULL }; /***************************************************************************** * *****************************************************************************/ -static char *FindFile( const char *psz_name ) +static char *FindFile( vlc_object_t *p_this, const char *psz_name ) { char *ppsz_dir_list[] = { NULL, NULL, NULL, NULL }; char **ppsz_dir; - vlclua_dir_list( "intf", ppsz_dir_list ); + vlclua_dir_list( p_this, "intf", ppsz_dir_list ); for( ppsz_dir = ppsz_dir_list; *ppsz_dir; ppsz_dir++ ) { char *psz_filename; @@ -73,16 +69,19 @@ static char *FindFile( const char *psz_name ) if( asprintf( &psz_filename, "%s"DIR_SEP"%s.lua", *ppsz_dir, psz_name ) < 0 ) { + vlclua_dir_list_free( ppsz_dir_list ); return NULL; } fp = fopen( psz_filename, "r" ); if( fp ) { fclose( fp ); + vlclua_dir_list_free( ppsz_dir_list ); return psz_filename; } free( psz_filename ); } + vlclua_dir_list_free( ppsz_dir_list ); return NULL; } @@ -94,22 +93,22 @@ static inline void luaL_register_submodule( lua_State *L, const char *psz_name, lua_setfield( L, -2, psz_name ); } -static struct +static const struct { const char *psz_shortcut; const char *psz_name; } pp_shortcuts[] = { { "luarc", "rc" }, - /* { "rc", "rc" }, */ + { "rc", "rc" }, { "luahotkeys", "hotkeys" }, /* { "hotkeys", "hotkeys" }, */ { "luatelnet", "telnet" }, - /* { "telnet", "telnet" }, */ + { "telnet", "telnet" }, { "luahttp", "http" }, - /* { "http", "http" }, */ + { "http", "http" }, { NULL, NULL } }; -static bool WordInList( const char *psz_list, const char *psz_word ) +static const char *WordInList( const char *psz_list, const char *psz_word ) { const char *psz_str = strstr( psz_list, psz_word ); int i_len = strlen( psz_word ); @@ -119,30 +118,43 @@ static bool WordInList( const char *psz_list, const char *psz_word ) /* it doesn't start in middle of a word */ /* it doest end in middle of a word */ && ( psz_str[i_len] == '\0' || psz_str[i_len] == ',' ) ) - return true; + return psz_str; psz_str = strstr( psz_str, psz_word ); } - return false; + return NULL; } -static const char *GetModuleName( intf_thread_t *p_intf ) +static char *GetModuleName( intf_thread_t *p_intf ) { int i; const char *psz_intf; - if( *p_intf->psz_intf == '$' ) + /*if( *p_intf->psz_intf == '$' ) psz_intf = var_GetString( p_intf, p_intf->psz_intf+1 ); - else + else*/ psz_intf = p_intf->psz_intf; + + int i_candidate = -1; + const char *psz_candidate = NULL; for( i = 0; pp_shortcuts[i].psz_name; i++ ) { - if( WordInList( psz_intf, pp_shortcuts[i].psz_shortcut ) ) - return pp_shortcuts[i].psz_name; + const char *psz_match; + if( ( psz_match = WordInList( psz_intf, pp_shortcuts[i].psz_shortcut ) ) ) + { + if( !psz_candidate || psz_match < psz_candidate ) + { + psz_candidate = psz_match; + i_candidate = i; + } + } } - return config_GetPsz( p_intf, "lua-intf" ); + if( i_candidate >= 0 ) + return strdup( pp_shortcuts[i_candidate].psz_name ); + + return var_CreateGetString( p_intf, "lua-intf" ); } -static luaL_Reg p_reg[] = { { NULL, NULL } }; +static const luaL_Reg p_reg[] = { { NULL, NULL } }; int Open_LuaIntf( vlc_object_t *p_this ) { @@ -150,22 +162,32 @@ int Open_LuaIntf( vlc_object_t *p_this ) intf_sys_t *p_sys; lua_State *L; - const char *psz_name = GetModuleName( p_intf ); - const char *psz_config; + config_ChainParse( p_intf, "lua-", ppsz_intf_options, p_intf->p_cfg ); + char *psz_name = NULL; + + if( !p_intf->b_force ) + psz_name = strdup( "rc" ); + else + psz_name = GetModuleName( p_intf ); + + if( !psz_name ) psz_name = strdup( "dummy" ); + + char *psz_config; bool b_config_set = false; - if( !psz_name ) psz_name = "dummy"; - p_intf->p_sys = (intf_sys_t*)malloc( sizeof(intf_sys_t*) ); + p_intf->p_sys = (intf_sys_t*)malloc( sizeof(intf_sys_t) ); if( !p_intf->p_sys ) { + free( psz_name ); return VLC_ENOMEM; } p_sys = p_intf->p_sys; - p_sys->psz_filename = FindFile( psz_name ); + p_sys->psz_filename = FindFile( p_this, psz_name ); if( !p_sys->psz_filename ) { msg_Err( p_intf, "Couldn't find lua interface script \"%s\".", psz_name ); + free( psz_name ); free( p_sys ); return VLC_EGENERIC; } @@ -175,6 +197,8 @@ int Open_LuaIntf( vlc_object_t *p_this ) if( !L ) { msg_Err( p_intf, "Could not create new Lua State" ); + free( p_sys->psz_filename ); + free( psz_name ); free( p_sys ); return VLC_EGENERIC; } @@ -207,6 +231,7 @@ int Open_LuaIntf( vlc_object_t *p_this ) luaopen_video( L ); luaopen_vlm( L ); luaopen_volume( L ); + luaopen_gettext( L ); /* clean up */ lua_pop( L, 1 ); @@ -219,16 +244,28 @@ int Open_LuaIntf( vlc_object_t *p_this ) *psz_char = '\0'; /* FIXME: don't use luaL_dostring */ if( asprintf( &psz_command, - "package.path = \"%s"DIR_SEP"modules"DIR_SEP"?.lua;\"..package.path", + "package.path = [[%s"DIR_SEP"modules"DIR_SEP"?.lua;]]..package.path", p_sys->psz_filename ) < 0 ) + { + free( p_sys->psz_filename ); + free( psz_name ); + free( p_sys ); return VLC_EGENERIC; + } *psz_char = DIR_SEP_CHAR; if( luaL_dostring( L, psz_command ) ) + { + free( psz_command ); + free( p_sys->psz_filename ); + free( psz_name ); + free( p_sys ); return VLC_EGENERIC; } + free( psz_command ); + } /* */ - psz_config = config_GetPsz( p_intf, "lua-config" ); + psz_config = var_CreateGetString( p_intf, "lua-config" ); if( psz_config && *psz_config ) { char *psz_buffer; @@ -250,6 +287,8 @@ int Open_LuaIntf( vlc_object_t *p_this ) } } } + free( psz_config ); + if( b_config_set == false ) { lua_newtable( L ); @@ -258,8 +297,19 @@ int Open_LuaIntf( vlc_object_t *p_this ) p_sys->L = L; - p_intf->pf_run = Run; - p_intf->psz_header = strdup( psz_name ); /* Do I need to clean that up myself in Close_LuaIntf? */ + p_intf->psz_header = psz_name; + /* ^^ Do I need to clean that up myself in Close_LuaIntf? */ + + vlc_mutex_init( &p_sys->lock ); + vlc_cond_init( &p_sys->wait ); + p_sys->exiting = false; + + if( vlc_clone( &p_sys->thread, Run, p_intf, VLC_THREAD_PRIORITY_LOW ) ) + { + p_sys->exiting = true; + Close_LuaIntf( p_this ); + return VLC_ENOMEM; + } return VLC_SUCCESS; } @@ -267,23 +317,38 @@ int Open_LuaIntf( vlc_object_t *p_this ) void Close_LuaIntf( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t*)p_this; + intf_sys_t *p_sys = p_intf->p_sys; + + vlc_cancel( p_sys->thread ); + + if( !p_sys->exiting ) /* <- Read-only here and in thread: no locking */ + { + vlc_mutex_lock( &p_sys->lock ); + p_sys->exiting = true; + vlc_cond_signal( &p_sys->wait ); + vlc_mutex_unlock( &p_sys->lock ); + vlc_join( p_sys->thread, NULL ); + } + vlc_cond_destroy( &p_sys->wait ); + vlc_mutex_destroy( &p_sys->lock ); - lua_close( p_intf->p_sys->L ); - free( p_intf->p_sys ); + lua_close( p_sys->L ); + + free( p_sys->psz_filename ); + free( p_sys ); } -static void Run( intf_thread_t *p_intf ) +static void *Run( void *data ) { - lua_State *L = p_intf->p_sys->L; + intf_thread_t *p_intf = data; + intf_sys_t *p_sys = p_intf->p_sys; + lua_State *L = p_sys->L; - if( luaL_dofile( L, p_intf->p_sys->psz_filename ) ) + if( luaL_dofile( L, p_sys->psz_filename ) ) { - msg_Err( p_intf, "Error loading script %s: %s", - p_intf->p_sys->psz_filename, + msg_Err( p_intf, "Error loading script %s: %s", p_sys->psz_filename, lua_tostring( L, lua_gettop( L ) ) ); lua_pop( L, 1 ); - p_intf->b_die = true; - return; } - p_intf->b_die = true; + return NULL; }