static module_t * AllocatePlugin( vlc_object_t *, char * );
#endif
static int AllocateBuiltinModule( vlc_object_t *, int ( * ) ( module_t * ) );
-static int DeleteModule ( module_t * );
+static int DeleteModule ( module_t *, vlc_bool_t );
#ifdef HAVE_DYNAMIC_PLUGINS
static void DupModule ( module_t * );
static void UndupModule ( module_t * );
*****************************************************************************/
void __module_InitBank( vlc_object_t *p_this )
{
- module_bank_t *p_bank;
+ module_bank_t *p_bank = NULL;
vlc_value_t lockval;
var_Create( p_this->p_libvlc_global, "libvlc", VLC_VAR_MUTEX );
var_Destroy( p_this->p_libvlc_global, "libvlc" );
p_bank = vlc_object_create( p_this, sizeof(module_bank_t) );
+ if( !p_bank )
+ return;
p_bank->psz_object_name = "module bank";
p_bank->i_usage = 1;
p_bank->i_cache = p_bank->i_loaded_cache = 0;
vlc_object_attach( p_bank, p_this->p_libvlc_global );
module_LoadMain( p_this );
-
- return;
}
/*****************************************************************************
*****************************************************************************/
void __module_EndBank( vlc_object_t *p_this )
{
- module_t * p_next;
+ module_t * p_next = NULL;
vlc_value_t lockval;
var_Create( p_this->p_libvlc_global, "libvlc", VLC_VAR_MUTEX );
if( p_bank->b_cache ) CacheSave( p_this );
while( p_bank->i_loaded_cache-- )
{
- DeleteModule (p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->p_module);
- free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->psz_file );
- free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] );
+ if( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] )
+ {
+ DeleteModule( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->p_module, p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->b_used );
+ free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->psz_file );
+ free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] );
+ p_bank->pp_loaded_cache[p_bank->i_loaded_cache] = NULL;
+ }
}
if( p_bank->pp_loaded_cache )
+ {
free( p_bank->pp_loaded_cache );
-
+ p_bank->pp_loaded_cache = NULL;
+ }
while( p_bank->i_cache-- )
{
free( p_bank->pp_cache[p_bank->i_cache]->psz_file );
free( p_bank->pp_cache[p_bank->i_cache] );
+ p_bank->pp_cache[p_bank->i_cache] = NULL;
}
if( p_bank->pp_cache )
+ {
free( p_bank->pp_cache );
+ p_bank->pp_cache = NULL;
+ }
#undef p_bank
#endif
{
p_next = (module_t *)p_this->p_libvlc_global->p_module_bank->pp_children[0];
- if( DeleteModule( p_next ) )
+ if( DeleteModule( p_next, VLC_TRUE ) )
{
/* Module deletion failed */
msg_Err( p_this, "module \"%s\" can't be removed, trying harder",
module_t *p_module;
int i_shortcuts = 0;
- char *psz_shortcuts = NULL, *psz_var = NULL;
+ char *psz_shortcuts = NULL, *psz_var = NULL, *psz_alias = NULL;
vlc_bool_t b_force_backup = p_this->b_force;
if( i_shortcuts > 0 )
{
vlc_bool_t b_trash;
- int i_dummy, i_short = i_shortcuts;
- char *psz_name = psz_shortcuts;
+ const char *psz_name = psz_shortcuts;
/* Let's drop modules with a <= 0 score (unless they are
* explicitly requested) */
b_trash = p_module->i_score <= 0;
- while( i_short > 0 )
+ for( unsigned i_short = i_shortcuts; i_short > 0; i_short-- )
{
- for( i_dummy = 0; p_module->pp_shortcuts[i_dummy]; i_dummy++ )
+ for( unsigned i = 0; p_module->pp_shortcuts[i]; i++ )
{
- if( !strcasecmp( psz_name,
- p_module->pp_shortcuts[i_dummy] ) )
+ char *c;
+ if( ( c = strchr( psz_name, '@' ) )
+ ? !strncasecmp( psz_name, p_module->pp_shortcuts[i],
+ c-psz_name )
+ : !strcasecmp( psz_name, p_module->pp_shortcuts[i] ) )
{
/* Found it */
- b_trash = VLC_FALSE;
+ if( c && c[1] )
+ psz_alias = c+1;
i_shortcut_bonus = i_short * 10000;
- break;
+ goto found_shortcut;
}
}
- if( i_shortcut_bonus )
- {
- /* We found it... remember ? */
- break;
- }
-
/* Go to the next shortcut... This is so lame! */
- while( *psz_name )
- {
- psz_name++;
- }
- psz_name++;
- i_short--;
+ psz_name += strlen( psz_name ) + 1;
}
/* If we are in "strict" mode and we couldn't
* find the module in the list of provided shortcuts,
* then kick the bastard out of here!!! */
- if( i_short == 0 && b_strict )
- {
- b_trash = VLC_TRUE;
- }
-
- if( b_trash )
- {
+ if( b_strict )
continue;
- }
}
/* If we didn't require a shortcut, trash <= 0 scored plugins */
else if( p_module->i_score <= 0 )
continue;
}
+found_shortcut:
+
/* Special case: test if we requested a particular intf plugin */
if( !i_shortcuts && p_module->psz_program
&& !strcmp( psz_capability, "interface" )
{
#ifdef HAVE_DYNAMIC_PLUGINS
/* Make sure the module is loaded in mem */
- module_t *p_module = p_tmp->p_module->b_submodule ?
- (module_t *)p_tmp->p_module->p_parent : p_tmp->p_module;
+ module_t *p_module = p_tmp->p_module;
+ if( p_module->b_submodule )
+ p_module = (module_t *)p_module->p_parent;
+
if( !p_module->b_builtin && !p_module->b_loaded )
{
module_t *p_new_module =
{
CacheMerge( p_this, p_module, p_new_module );
vlc_object_attach( p_new_module, p_module );
- DeleteModule( p_new_module );
+ DeleteModule( p_new_module, VLC_TRUE );
}
}
#endif
{
msg_Err( p_this, "no %s module matched \"%s\"",
psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
+
+ msg_StackSet( VLC_EGENERIC, "no %s module matched \"%s\"",
+ psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
}
}
else if( psz_name != NULL && *psz_name )
msg_Warn( p_this, "no %s module matching \"%s\" could be loaded",
psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
}
+ else
+ msg_StackSet( VLC_EGENERIC, "no suitable %s module", psz_capability );
+
+ if( psz_alias && !p_this->psz_object_name )
+ /* This assumes that p_this is the object which will be using the
+ * module. That's not always the case ... but it is in most cases.
+ */
+ p_this->psz_object_name = strdup( psz_alias );
if( psz_shortcuts )
{
return;
}
+/*****************************************************************************
+ * module_Exists: tell if a module exists.
+ *****************************************************************************
+ * This function is a boolean function that tells if a module exist or not.
+ *****************************************************************************/
+
+vlc_bool_t __module_Exists( vlc_object_t *p_this, const char * psz_name )
+{
+ vlc_list_t *p_list;
+ int i;
+ p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+ for( i = 0 ; i < p_list->i_count; i++)
+ {
+ if (!strcmp(
+ ((module_t *) p_list->p_values[i].p_object)->psz_shortname ,
+ psz_name ) )
+ {
+ /* We can release the list, and return yes */
+ vlc_list_release( p_list ); return VLC_TRUE;
+ }
+ }
+ vlc_list_release( p_list ); return VLC_FALSE;
+}
+
+
/*****************************************************************************
* Following functions are local.
*****************************************************************************/
static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file,
int64_t i_file_time, int64_t i_file_size )
{
- module_t * p_module;
+ module_t * p_module = NULL;
module_cache_t *p_cache_entry = NULL;
/*
}
else
{
- module_config_t *p_item, *p_end;
+ module_config_t *p_item = NULL, *p_end = NULL;
p_module = p_cache_entry->p_module;
p_module->b_loaded = VLC_FALSE;
p_item < p_end; p_item++ )
{
if( p_item->pf_callback || p_item->i_action )
+ {
p_module = AllocatePlugin( p_this, psz_file );
+ break;
+ }
}
+ if( p_module == p_cache_entry->p_module )
+ p_cache_entry->b_used = VLC_TRUE;
}
}
p_module->psz_object_name, p_module->psz_longname ); */
vlc_object_attach( p_module, p_this->p_libvlc_global->p_module_bank );
- }
- if( !p_this->p_libvlc_global->p_module_bank->b_cache ) return 0;
+ if( !p_this->p_libvlc_global->p_module_bank->b_cache )
+ return 0;
- /* Add entry to cache */
+ /* Add entry to cache */
#define p_bank p_this->p_libvlc_global->p_module_bank
- p_bank->pp_cache =
- realloc( p_bank->pp_cache, (p_bank->i_cache + 1) * sizeof(void *) );
- p_bank->pp_cache[p_bank->i_cache] = malloc( sizeof(module_cache_t) );
- p_bank->pp_cache[p_bank->i_cache]->psz_file = strdup( psz_file );
- p_bank->pp_cache[p_bank->i_cache]->i_time = i_file_time;
- p_bank->pp_cache[p_bank->i_cache]->i_size = i_file_size;
- p_bank->pp_cache[p_bank->i_cache]->b_junk = p_module ? 0 : 1;
- p_bank->pp_cache[p_bank->i_cache]->p_module = p_module;
- p_bank->i_cache++;
+ p_bank->pp_cache =
+ realloc( p_bank->pp_cache, (p_bank->i_cache + 1) * sizeof(void *) );
+ p_bank->pp_cache[p_bank->i_cache] = malloc( sizeof(module_cache_t) );
+ if( !p_bank->pp_cache[p_bank->i_cache] )
+ return -1;
+ p_bank->pp_cache[p_bank->i_cache]->psz_file = strdup( psz_file );
+ p_bank->pp_cache[p_bank->i_cache]->i_time = i_file_time;
+ p_bank->pp_cache[p_bank->i_cache]->i_size = i_file_size;
+ p_bank->pp_cache[p_bank->i_cache]->b_junk = p_module ? 0 : 1;
+ p_bank->pp_cache[p_bank->i_cache]->b_used = VLC_TRUE;
+ p_bank->pp_cache[p_bank->i_cache]->p_module = p_module;
+ p_bank->i_cache++;
+ }
return p_module ? 0 : -1;
}
*****************************************************************************/
static module_t * AllocatePlugin( vlc_object_t * p_this, char * psz_file )
{
- module_t * p_module;
+ module_t * p_module = NULL;
module_handle_t handle;
- if( LoadModule( p_this, psz_file, &handle ) ) return NULL;
+ if( LoadModule( p_this, psz_file, &handle ) )
+ return NULL;
/* Now that we have successfully loaded the module, we can
* allocate a structure for it */
*****************************************************************************
* This function can only be called if the module isn't being used.
*****************************************************************************/
-static int DeleteModule( module_t * p_module )
+static int DeleteModule( module_t * p_module, vlc_bool_t b_detach )
{
- vlc_object_detach( p_module );
+ if( !p_module ) return VLC_EGENERIC;
+ if( b_detach )
+ vlc_object_detach( p_module );
/* We free the structures that we strdup()ed in Allocate*Module(). */
#ifdef HAVE_DYNAMIC_PLUGINS
config_Free( p_module );
vlc_object_destroy( p_module );
-
+ p_module = NULL;
return 0;
}
LOAD_IMMEDIATE( pp_cache[i]->i_time );
LOAD_IMMEDIATE( pp_cache[i]->i_size );
LOAD_IMMEDIATE( pp_cache[i]->b_junk );
+ pp_cache[i]->b_used = VLC_FALSE;
if( pp_cache[i]->b_junk ) continue;
}
/*****************************************************************************
- * FindPluginCache: finds the cache entry corresponding to a file
+ * CacheFind: finds the cache entry corresponding to a file
*****************************************************************************/
static module_cache_t *CacheFind( vlc_object_t *p_this, char *psz_file,
int64_t i_time, int64_t i_size )