X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fmodules.c;h=15feab162a7f0218125c9fea26adff7dee695acf;hb=d6aa3d36b8570833583b763b187979399b8c6b2a;hp=23e4bde234d2ce03559f2d78c09f3e54819f0d54;hpb=6d656addd5f9d7f47f64070200398ac96c7f547b;p=vlc diff --git a/src/modules/modules.c b/src/modules/modules.c index 23e4bde234..15feab162a 100644 --- a/src/modules/modules.c +++ b/src/modules/modules.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "libvlc.h" #include /* free(), strtol() */ @@ -49,35 +50,13 @@ #ifdef HAVE_UNISTD_H # include #endif - -#if !defined(HAVE_DYNAMIC_PLUGINS) - /* no support for plugins */ -#elif defined(HAVE_DL_DYLD) -# if defined(HAVE_MACH_O_DYLD_H) -# include -# endif -#elif defined(HAVE_DL_BEOS) -# if defined(HAVE_IMAGE_H) -# include -# endif -#elif defined(HAVE_DL_WINDOWS) -# include -#elif defined(HAVE_DL_DLOPEN) -# if defined(HAVE_DLFCN_H) /* Linux, BSD, Hurd */ -# include -# endif -# if defined(HAVE_SYS_DL_H) -# include -# endif -#elif defined(HAVE_DL_SHL_LOAD) -# if defined(HAVE_DL_H) -# include -# endif +#ifdef ENABLE_NLS +# include #endif #include "config/configuration.h" -#include "vlc_charset.h" +#include #include "vlc_arrays.h" #include "modules/modules.h" @@ -105,6 +84,7 @@ static void DupModule ( module_t * ); static void UndupModule ( module_t * ); #endif +#undef module_InitBank /** * Init bank * @@ -113,7 +93,7 @@ static void UndupModule ( module_t * ); * \param p_this vlc object structure * \return nothing */ -void __module_InitBank( vlc_object_t *p_this ) +void module_InitBank( vlc_object_t *p_this ) { module_bank_t *p_bank = NULL; @@ -189,8 +169,6 @@ void module_EndBank( vlc_object_t *p_this, bool b_plugins ) vlc_mutex_unlock( &module_lock ); #ifdef HAVE_DYNAMIC_PLUGINS - if( p_bank->b_cache ) - CacheSave( p_this, p_bank ); while( p_bank->i_loaded_cache-- ) { if( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] ) @@ -224,7 +202,7 @@ void module_EndBank( vlc_object_t *p_this, bool b_plugins ) * \param p_this vlc object structure * \return nothing */ -void module_LoadPlugins( vlc_object_t * p_this, bool b_cache_delete ) +void module_LoadPlugins( vlc_object_t * p_this ) { module_bank_t *p_bank = p_module_bank; @@ -237,8 +215,6 @@ void module_LoadPlugins( vlc_object_t * p_this, bool b_cache_delete ) msg_Dbg( p_this, "checking plugin modules" ); p_module_bank->b_cache = var_InheritBool( p_this, "plugins-cache" ); - if( p_module_bank->b_cache || b_cache_delete ) - CacheLoad( p_this, p_module_bank, b_cache_delete ); AllocateAllPlugins( p_this, p_module_bank ); config_UnsortConfig (); config_SortConfig (); @@ -318,6 +294,24 @@ int module_get_score( const module_t *m ) return m->i_score; } +/** + * Translate a string using the module's text domain + * + * \param m the module + * \param str the American English ASCII string to localize + * \return the gettext-translated string + */ +const char *module_gettext (const module_t *m, const char *str) +{ +#ifdef ENABLE_NLS + const char *domain = m->domain ? m->domain : PACKAGE_NAME; + return dgettext (domain, str); +#else + (void)m; + return str; +#endif +} + module_t *module_hold (module_t *m) { vlc_hold (&m->vlc_gc_data); @@ -329,6 +323,19 @@ void module_release (module_t *m) vlc_release (&m->vlc_gc_data); } +#undef module_start +int module_start (vlc_object_t *obj, module_t *m) +{ + return m->pf_activate ? (m->pf_activate (obj)) : VLC_SUCCESS; +} + +#undef module_stop +void module_stop (vlc_object_t *obj, module_t *m) +{ + if (m->pf_deactivate) + m->pf_deactivate (obj); +} + /** * Frees the flat list of VLC modules. * @param list list obtained by module_list_get() @@ -395,6 +402,7 @@ static int modulecmp (const void *a, const void *b) return lb->i_score - la->i_score; } +#undef module_need /** * module Need * @@ -407,8 +415,8 @@ static int modulecmp (const void *a, const void *b) * but the same capability * \return the module or NULL in case of a failure */ -module_t * __module_need( vlc_object_t *p_this, const char *psz_capability, - const char *psz_name, bool b_strict ) +module_t * module_need( vlc_object_t *p_this, const char *psz_capability, + const char *psz_name, bool b_strict ) { stats_TimerStart( p_this, "module_need()", STATS_TIMER_MODULE_NEED ); @@ -487,7 +495,7 @@ module_t * __module_need( vlc_object_t *p_this, const char *psz_capability, for( unsigned i_short = i_shortcuts; i_short > 0; i_short-- ) { - for( unsigned i = 0; p_module->pp_shortcuts[i]; i++ ) + for( unsigned i = 0; i < p_module->i_shortcuts; i++ ) { char *c; if( ( c = strchr( name, '@' ) ) @@ -560,10 +568,7 @@ found_shortcut: p_this->b_force = p_list[i].b_force; - int ret = VLC_SUCCESS; - if( p_cand->pf_activate ) - ret = p_cand->pf_activate( p_this ); - switch( ret ) + switch( module_start( p_this, p_cand ) ) { case VLC_SUCCESS: /* good module! */ @@ -596,30 +601,11 @@ found_shortcut: : p_module->psz_object_name ); } else if( count == 0 ) - { - if( !strcmp( psz_capability, "access_demux" ) - || !strcmp( psz_capability, "stream_filter" ) - || !strcmp( psz_capability, "vout_window" ) ) - { - msg_Dbg( p_this, "no %s module matched \"%s\"", - psz_capability, (psz_name && *psz_name) ? psz_name : "any" ); - } - else - { - msg_Err( p_this, "no %s module matched \"%s\"", + msg_Dbg( 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 ); + msg_Dbg( p_this, "no %s module matching \"%s\" could be loaded", + psz_capability, (psz_name && *psz_name) ? psz_name : "any" ); free( psz_shortcuts ); free( psz_var ); @@ -632,6 +618,7 @@ found_shortcut: return p_module; } +#undef module_unneed /** * Module unneed * @@ -641,16 +628,10 @@ found_shortcut: * \param p_module the module structure * \return nothing */ -void __module_unneed( vlc_object_t * p_this, module_t * p_module ) +void module_unneed( vlc_object_t * p_this, module_t * p_module ) { - /* Use the close method */ - if( p_module->pf_deactivate ) - { - p_module->pf_deactivate( p_this ); - } - msg_Dbg( p_this, "removing module \"%s\"", p_module->psz_object_name ); - + module_stop( p_this, p_module ); module_release( p_module ); } @@ -715,9 +696,7 @@ module_t *module_find_by_shortcut (const char *psz_shortcut) for (size_t i = 0; (module = list[i]) != NULL; i++) { - for (size_t j = 0; - (module->pp_shortcuts[j] != NULL) && (j < MODULE_SHORTCUT_MAX); - j++) + for (size_t j = 0; j < module->i_shortcuts; j++) { if (!strcmp (module->pp_shortcuts[j], psz_shortcut)) { @@ -754,7 +733,6 @@ module_config_t *module_config_get( const module_t *module, unsigned *restrict p { const module_config_t *item = module->p_config + i; if( item->b_internal /* internal option */ - || item->b_unsaveable /* non-modifiable option */ || item->b_removed /* removed option */ ) continue; @@ -840,17 +818,14 @@ static void AllocateAllPlugins( vlc_object_t *p_this, module_bank_t *p_bank ) int count,i; char * path; vlc_array_t *arraypaths = vlc_array_new(); + const bool b_reset = var_InheritBool( p_this, "reset-plugins-cache" ); /* Contruct the special search path for system that have a relocatable - * executable. Set it to /modules and /plugins. */ + * executable. Set it to /plugins. */ + assert( vlcpath ); - if( vlcpath && asprintf( &path, "%s" DIR_SEP "modules", vlcpath ) != -1 ) + if( asprintf( &path, "%s" DIR_SEP "plugins", vlcpath ) != -1 ) vlc_array_append( arraypaths, path ); - if( vlcpath && asprintf( &path, "%s" DIR_SEP "plugins", vlcpath ) != -1 ) - vlc_array_append( arraypaths, path ); -#ifndef WIN32 - vlc_array_append( arraypaths, strdup( PLUGIN_PATH ) ); -#endif /* If the user provided a plugin path, we add it to the list */ char *userpaths = var_InheritString( p_this, "plugin-path" ); @@ -870,11 +845,20 @@ static void AllocateAllPlugins( vlc_object_t *p_this, module_bank_t *p_bank ) if( !path ) continue; + size_t offset = p_module_bank->i_cache; + if( b_reset ) + CacheDelete( p_this, path ); + else + CacheLoad( p_this, p_module_bank, path ); + msg_Dbg( p_this, "recursively browsing `%s'", path ); /* Don't go deeper than 5 subdirectories */ AllocatePluginDir( p_this, p_bank, path, 5 ); + + CacheSave( p_this, path, p_module_bank->pp_cache + offset, + p_module_bank->i_cache - offset ); free( path ); } @@ -891,14 +875,14 @@ static void AllocatePluginDir( vlc_object_t *p_this, module_bank_t *p_bank, if( i_maxdepth == 0 ) return; - DIR *dh = utf8_opendir (psz_dir); + DIR *dh = vlc_opendir (psz_dir); if (dh == NULL) return; /* Parse the directory and try to load all files it contains. */ for (;;) { - char *file = utf8_readdir (dh), *path; + char *file = vlc_readdir (dh), *path; struct stat st; if (file == NULL) @@ -915,7 +899,7 @@ static void AllocatePluginDir( vlc_object_t *p_this, module_bank_t *p_bank, const int pathlen = asprintf (&path, "%s"DIR_SEP"%s", psz_dir, file); free (file); - if (pathlen == -1 || utf8_stat (path, &st)) + if (pathlen == -1 || vlc_stat (path, &st)) continue; if (S_ISDIR (st.st_mode)) @@ -923,10 +907,11 @@ static void AllocatePluginDir( vlc_object_t *p_this, module_bank_t *p_bank, AllocatePluginDir (p_this, p_bank, path, i_maxdepth - 1); else if (S_ISREG (st.st_mode) - && ((size_t)pathlen >= strlen (LIBEXT)) - && !strncasecmp (path + pathlen - strlen (LIBEXT), LIBEXT, - strlen (LIBEXT))) - /* ^^ We only load files ending with LIBEXT */ + && strncmp (path, "lib", 3) + && ((size_t)pathlen >= sizeof ("_plugin"LIBEXT)) + && !strncasecmp (path + pathlen - strlen ("_plugin"LIBEXT), + "_plugin"LIBEXT, strlen ("_plugni"LIBEXT))) + /* ^^ We only load files matching "lib*_plugin"LIBEXT */ AllocatePluginFile (p_this, p_bank, path, st.st_mtime, st.st_size); free (path); @@ -957,16 +942,16 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank, p_module = AllocatePlugin( p_this, psz_file ); } else - /* If junk dll, don't try to load it */ - if( p_cache_entry->b_junk ) - return -1; - else { module_config_t *p_item = NULL, *p_end = NULL; p_module = p_cache_entry->p_module; p_module->b_loaded = false; + /* If plugin-path contains duplicate entries... */ + if( p_module->next != NULL ) + return 0; /* already taken care of that one */ + /* For now we force loading if the module's config contains * callbacks or actions. * Could be optimized by adding an API call.*/ @@ -979,13 +964,14 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank, break; } } - if( p_module == p_cache_entry->p_module ) - p_cache_entry->b_used = true; } if( p_module == NULL ) return -1; + /* We have not already scanned and inserted this module */ + assert( p_module->next == NULL ); + /* Everything worked fine ! * The module is ready to be added to the list. */ p_module->b_builtin = false; @@ -994,6 +980,7 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank, p_module->psz_object_name, p_module->psz_longname ); */ p_module->next = p_bank->head; p_bank->head = p_module; + assert( p_module->next != NULL ); /* Insertion done */ if( !p_module_bank->b_cache ) return 0; @@ -1010,8 +997,6 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank, pp_cache[p_bank->i_cache]->psz_file = strdup( psz_file ); pp_cache[p_bank->i_cache]->i_time = i_file_time; pp_cache[p_bank->i_cache]->i_size = i_file_size; - pp_cache[p_bank->i_cache]->b_junk = p_module ? 0 : 1; - pp_cache[p_bank->i_cache]->b_used = true; pp_cache[p_bank->i_cache]->p_module = p_module; p_bank->pp_cache = pp_cache; p_bank->i_cache++; @@ -1072,12 +1057,9 @@ static module_t * AllocatePlugin( vlc_object_t * p_this, const char *psz_file ) *****************************************************************************/ static void DupModule( module_t *p_module ) { - char **pp_shortcut; - - for( pp_shortcut = p_module->pp_shortcuts ; *pp_shortcut ; pp_shortcut++ ) - { - *pp_shortcut = strdup( *pp_shortcut ); - } + char **pp_shortcuts = p_module->pp_shortcuts; + for( unsigned i = 0; i < p_module->i_shortcuts; i++ ) + pp_shortcuts[i] = strdup( p_module->pp_shortcuts[i] ); /* We strdup() these entries so that they are still valid when the * module is unloaded. */ @@ -1087,6 +1069,7 @@ static void DupModule( module_t *p_module ) p_module->psz_longname = strdup( p_module->psz_longname ); p_module->psz_help = p_module->psz_help ? strdup( p_module->psz_help ) : NULL; + p_module->domain = p_module->domain ? strdup( p_module->domain ) : NULL; for (module_t *subm = p_module->submodule; subm; subm = subm->next) DupModule (subm); @@ -1099,20 +1082,19 @@ static void DupModule( module_t *p_module ) *****************************************************************************/ static void UndupModule( module_t *p_module ) { - char **pp_shortcut; + char **pp_shortcuts = p_module->pp_shortcuts; for (module_t *subm = p_module->submodule; subm; subm = subm->next) UndupModule (subm); - for( pp_shortcut = p_module->pp_shortcuts ; *pp_shortcut ; pp_shortcut++ ) - { - free( *pp_shortcut ); - } + for( unsigned i = 0; i < p_module->i_shortcuts; i++ ) + free( pp_shortcuts[i] ); free( p_module->psz_capability ); FREENULL( p_module->psz_shortname ); free( p_module->psz_longname ); FREENULL( p_module->psz_help ); + free( p_module->domain ); } #endif /* HAVE_DYNAMIC_PLUGINS */