1 /*****************************************************************************
2 * modules.c : Builtin and plugin modules management functions
3 *****************************************************************************
4 * Copyright (C) 2001-2011 VLC authors and VideoLAN
7 * Authors: Sam Hocevar <sam@zoy.org>
8 * Ethan C. Baldridge <BaldridgeE@cadmus.com>
9 * Hans-Peter Jansen <hpj@urpla.net>
10 * Gildas Bazin <gbazin@videolan.org>
11 * RĂ©mi Denis-Courmont
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2.1 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
39 #include <vlc_common.h>
40 #include <vlc_modules.h>
42 #include "config/configuration.h"
43 #include "vlc_arrays.h"
44 #include "modules/modules.h"
47 * Checks whether a module implements a capability.
50 * \param cap the capability to check
51 * \return true if the module has the capability
53 bool module_provides (const module_t *m, const char *cap)
55 return !strcmp (module_get_capability (m), cap);
59 * Get the internal name of a module
62 * \return the module name
64 const char *module_get_object( const module_t *m )
66 if (unlikely(m->i_shortcuts == 0))
68 return m->pp_shortcuts[0];
72 * Get the human-friendly name of a module.
75 * \param long_name TRUE to have the long name of the module
76 * \return the short or long name of the module
78 const char *module_get_name( const module_t *m, bool long_name )
80 if( long_name && ( m->psz_longname != NULL) )
81 return m->psz_longname;
83 if (m->psz_shortname != NULL)
84 return m->psz_shortname;
85 return module_get_object (m);
89 * Get the help for a module
94 const char *module_get_help( const module_t *m )
100 * Gets the capability of a module
102 * \param m the module
103 * \return the capability, or "none" if unspecified
105 const char *module_get_capability (const module_t *m)
107 return (m->psz_capability != NULL) ? m->psz_capability : "none";
111 * Get the score for a module
113 * \param m the module
114 * return the score for the capability
116 int module_get_score( const module_t *m )
122 * Translate a string using the module's text domain
124 * \param m the module
125 * \param str the American English ASCII string to localize
126 * \return the gettext-translated string
128 const char *module_gettext (const module_t *m, const char *str)
130 if (m->parent != NULL)
132 if (unlikely(str == NULL || *str == '\0'))
135 const char *domain = m->domain;
136 return dgettext ((domain != NULL) ? domain : PACKAGE_NAME, str);
144 int module_start (vlc_object_t *obj, const module_t *m)
146 int (*activate) (vlc_object_t *) = m->pf_activate;
148 return (activate != NULL) ? activate (obj) : VLC_SUCCESS;
152 void module_stop (vlc_object_t *obj, const module_t *m)
154 void (*deactivate) (vlc_object_t *) = m->pf_deactivate;
156 if (deactivate != NULL)
160 static bool module_match_name (const module_t *m, const char *name)
162 /* Plugins with zero score must be matched explicitly. */
163 if (!strcasecmp ("any", name))
164 return m->i_score > 0;
166 for (unsigned i = 0; i < m->i_shortcuts; i++)
167 if (!strcasecmp (m->pp_shortcuts[i], name))
172 static int module_load (vlc_object_t *obj, module_t *m,
173 vlc_activate_t init, va_list args)
175 int ret = VLC_SUCCESS;
177 if (module_Map (obj, m))
180 if (m->pf_activate != NULL)
185 ret = init (m->pf_activate, ap);
191 #undef vlc_module_load
193 * Finds and instantiates the best module of a certain type.
194 * All candidates modules having the specified capability and name will be
195 * sorted in decreasing order of priority. Then the probe callback will be
196 * invoked for each module, until it succeeds (returns 0), or all candidate
197 * module failed to initialize.
199 * The probe callback first parameter is the address of the module entry point.
200 * Further parameters are passed as an argument list; it corresponds to the
201 * variable arguments passed to this function. This scheme is meant to
202 * support arbitrary prototypes for the module entry point.
204 * \param obj VLC object
205 * \param capability capability, i.e. class of module
206 * \param name name name of the module asked, if any
207 * \param strict if true, do not fallback to plugin with a different name
208 * but the same capability
209 * \param probe module probe callback
210 * \return the module or NULL in case of a failure
212 module_t *vlc_module_load(vlc_object_t *obj, const char *capability,
213 const char *name, bool strict,
214 vlc_activate_t probe, ...)
218 if (name == NULL || name[0] == '\0')
221 /* Deal with variables */
224 var = var_InheritString (obj, name + 1);
225 name = (var != NULL) ? var : "any";
228 /* Find matching modules */
230 ssize_t total = module_list_cap (&mods, capability);
232 msg_Dbg (obj, "looking for %s module matching \"%s\": %zd candidates",
233 capability, name, total);
236 module_list_free (mods);
237 msg_Dbg (obj, "no %s modules", capability);
241 module_t *module = NULL;
242 const bool b_force_backup = obj->b_force; /* FIXME: remove this */
245 va_start(args, probe);
249 size_t slen = strcspn (name, ",");
251 if (likely(slen < sizeof (buf)))
253 memcpy(buf, name, slen);
257 name += strspn (name, ",");
258 if (unlikely(slen >= sizeof (buf)))
261 const char *shortcut = buf;
262 assert (shortcut != NULL);
264 if (!strcasecmp ("none", shortcut))
267 obj->b_force = strict && strcasecmp ("any", shortcut);
268 for (ssize_t i = 0; i < total; i++)
270 module_t *cand = mods[i];
272 continue; // module failed in previous iteration
273 if (!module_match_name (cand, shortcut))
275 mods[i] = NULL; // only try each module once at most...
277 int ret = module_load (obj, cand, probe, args);
289 /* None of the shortcuts matched, fall back to any module */
292 obj->b_force = false;
293 for (ssize_t i = 0; i < total; i++)
295 module_t *cand = mods[i];
296 if (cand == NULL || module_get_score (cand) <= 0)
299 int ret = module_load (obj, cand, probe, args);
312 obj->b_force = b_force_backup;
313 module_list_free (mods);
318 msg_Dbg (obj, "using %s module \"%s\"", capability,
319 module_get_object (module));
320 vlc_object_set_name (obj, module_get_object (module));
323 msg_Dbg (obj, "no %s modules matched", capability);
329 * Deinstantiates a module.
330 * \param module the module pointer as returned by vlc_module_load()
331 * \param deinit deactivation callback
333 void vlc_module_unload(module_t *module, vlc_deactivate_t deinit, ...)
335 if (module->pf_deactivate != NULL)
339 va_start(ap, deinit);
340 deinit(module->pf_deactivate, ap);
346 static int generic_start(void *func, va_list ap)
348 vlc_object_t *obj = va_arg(ap, vlc_object_t *);
349 int (*activate)(vlc_object_t *) = func;
351 return activate(obj);
354 static void generic_stop(void *func, va_list ap)
356 vlc_object_t *obj = va_arg(ap, vlc_object_t *);
357 void (*deactivate)(vlc_object_t *) = func;
363 module_t *module_need(vlc_object_t *obj, const char *cap, const char *name,
366 return vlc_module_load(obj, cap, name, strict, generic_start, obj);
370 void module_unneed(vlc_object_t *obj, module_t *module)
372 msg_Dbg(obj, "removing module \"%s\"", module_get_object(module));
373 vlc_module_unload(module, generic_stop, obj);
377 * Get a pointer to a module_t given it's name.
379 * \param name the name of the module
380 * \return a pointer to the module or NULL in case of a failure
382 module_t *module_find (const char *name)
385 module_t **list = module_list_get (&count);
387 assert (name != NULL);
389 for (size_t i = 0; i < count; i++)
391 module_t *module = list[i];
393 if (unlikely(module->i_shortcuts == 0))
395 if (!strcmp (module->pp_shortcuts[0], name))
397 module_list_free (list);
401 module_list_free (list);
406 * Tell if a module exists and release it in thic case
408 * \param psz_name th name of the module
409 * \return TRUE if the module exists
411 bool module_exists (const char * psz_name)
413 return module_find (psz_name) != NULL;
417 * Get a pointer to a module_t that matches a shortcut.
418 * This is a temporary hack for SD. Do not re-use (generally multiple modules
419 * can have the same shortcut, so this is *broken* - use module_need()!).
421 * \param psz_shortcut shortcut of the module
422 * \param psz_cap capability of the module
423 * \return a pointer to the module or NULL in case of a failure
425 module_t *module_find_by_shortcut (const char *psz_shortcut)
428 module_t **list = module_list_get (&count);
430 for (size_t i = 0; i < count; i++)
432 module_t *module = list[count];
434 for (size_t j = 0; j < module->i_shortcuts; j++)
435 if (!strcmp (module->pp_shortcuts[j], psz_shortcut))
437 module_list_free (list);
441 module_list_free (list);
446 * Get the configuration of a module
448 * \param module the module
449 * \param psize the size of the configuration returned
450 * \return the configuration as an array
452 module_config_t *module_config_get( const module_t *module, unsigned *restrict psize )
455 unsigned size = module->confsize;
456 module_config_t *config = malloc( size * sizeof( *config ) );
458 assert( psize != NULL );
464 for( i = 0, j = 0; i < size; i++ )
466 const module_config_t *item = module->p_config + i;
467 if( item->b_internal /* internal option */
468 || item->b_removed /* removed option */ )
471 memcpy( config + j, item, sizeof( *config ) );
480 * Release the configuration
482 * \param the configuration
485 void module_config_free( module_config_t *config )