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 have the capability
53 bool module_provides( const module_t
*m
, const char *cap
)
55 if (unlikely(m
->psz_capability
== NULL
))
57 return !strcmp( m
->psz_capability
, cap
);
61 * Get the internal name of a module
64 * \return the module name
66 const char *module_get_object( const module_t
*m
)
68 if (unlikely(m
->i_shortcuts
== 0))
70 return m
->pp_shortcuts
[0];
74 * Get the human-friendly name of a module.
77 * \param long_name TRUE to have the long name of the module
78 * \return the short or long name of the module
80 const char *module_get_name( const module_t
*m
, bool long_name
)
82 if( long_name
&& ( m
->psz_longname
!= NULL
) )
83 return m
->psz_longname
;
85 if (m
->psz_shortname
!= NULL
)
86 return m
->psz_shortname
;
87 return module_get_object (m
);
91 * Get the help for a module
96 const char *module_get_help( const module_t
*m
)
102 * Get the capability for a module
104 * \param m the module
105 * return the capability
107 const char *module_get_capability( const module_t
*m
)
109 return m
->psz_capability
;
113 * Get the score for a module
115 * \param m the module
116 * return the score for the capability
118 int module_get_score( const module_t
*m
)
124 * Translate a string using the module's text domain
126 * \param m the module
127 * \param str the American English ASCII string to localize
128 * \return the gettext-translated string
130 const char *module_gettext (const module_t
*m
, const char *str
)
132 if (m
->parent
!= NULL
)
134 if (unlikely(str
== NULL
|| *str
== '\0'))
137 const char *domain
= m
->domain
;
138 return dgettext ((domain
!= NULL
) ? domain
: PACKAGE_NAME
, str
);
146 int module_start (vlc_object_t
*obj
, const module_t
*m
)
148 int (*activate
) (vlc_object_t
*) = m
->pf_activate
;
150 return (activate
!= NULL
) ? activate (obj
) : VLC_SUCCESS
;
154 void module_stop (vlc_object_t
*obj
, const module_t
*m
)
156 void (*deactivate
) (vlc_object_t
*) = m
->pf_deactivate
;
158 if (deactivate
!= NULL
)
162 typedef struct module_list_t
169 static int modulecmp (const void *a
, const void *b
)
171 const module_list_t
*la
= a
, *lb
= b
;
172 /* Note that qsort() uses _ascending_ order,
173 * so the smallest module is the one with the biggest score. */
174 return lb
->i_score
- la
->i_score
;
177 #undef vlc_module_load
179 * Finds and instantiates the best module of a certain type.
180 * All candidates modules having the specified capability and name will be
181 * sorted in decreasing order of priority. Then the probe callback will be
182 * invoked for each module, until it succeeds (returns 0), or all candidate
183 * module failed to initialize.
185 * The probe callback first parameter is the address of the module entry point.
186 * Further parameters are passed as an argument list; it corresponds to the
187 * variable arguments passed to this function. This scheme is meant to
188 * support arbitrary prototypes for the module entry point.
190 * \param p_this VLC object
191 * \param psz_capability capability, i.e. class of module
192 * \param psz_name name name of the module asked, if any
193 * \param b_strict if true, do not fallback to plugin with a different name
194 * but the same capability
195 * \param probe module probe callback
196 * \return the module or NULL in case of a failure
198 module_t
*vlc_module_load(vlc_object_t
*p_this
, const char *psz_capability
,
199 const char *psz_name
, bool b_strict
,
200 vlc_activate_t probe
, ...)
202 module_list_t
*p_list
;
205 char *psz_shortcuts
= NULL
, *psz_var
= NULL
, *psz_alias
= NULL
;
206 bool b_force_backup
= p_this
->b_force
;
208 /* Deal with variables */
209 if( psz_name
&& psz_name
[0] == '$' )
211 psz_name
= psz_var
= var_CreateGetString( p_this
, psz_name
+ 1 );
214 /* Count how many different shortcuts were asked for */
215 if( psz_name
&& *psz_name
)
217 char *psz_parser
, *psz_last_shortcut
;
219 /* If the user wants none, give him none. */
220 if( !strcmp( psz_name
, "none" ) )
227 psz_parser
= psz_shortcuts
= psz_last_shortcut
= strdup( psz_name
);
229 while( ( psz_parser
= strchr( psz_parser
, ',' ) ) )
233 psz_last_shortcut
= ++psz_parser
;
236 /* Check if the user wants to override the "strict" mode */
237 if( psz_last_shortcut
)
239 if( !strcmp(psz_last_shortcut
, "none") )
244 else if( !strcmp(psz_last_shortcut
, "any") )
252 /* Sort the modules and test them */
254 module_t
**p_all
= module_list_get (&count
);
255 p_list
= malloc( count
* sizeof( module_list_t
) );
257 /* Parse the module list for capabilities and probe each of them */
259 for (size_t i
= 0; (p_module
= p_all
[i
]) != NULL
; i
++)
261 int i_shortcut_bonus
= 0;
263 /* Test that this module can do what we need */
264 if( !module_provides( p_module
, psz_capability
) )
267 /* If we required a shortcut, check this plugin provides it. */
268 if( i_shortcuts
> 0 )
270 const char *name
= psz_shortcuts
;
272 for( unsigned i_short
= i_shortcuts
; i_short
> 0; i_short
-- )
274 for( unsigned i
= 0; i
< p_module
->i_shortcuts
; i
++ )
277 if( ( c
= strchr( name
, '@' ) )
278 ? !strncasecmp( name
, p_module
->pp_shortcuts
[i
],
280 : !strcasecmp( name
, p_module
->pp_shortcuts
[i
] ) )
285 i_shortcut_bonus
= i_short
* 10000;
290 /* Go to the next shortcut... This is so lame! */
291 name
+= strlen( name
) + 1;
294 /* If we are in "strict" mode and we couldn't
295 * find the module in the list of provided shortcuts,
296 * then kick the bastard out of here!!! */
301 /* Trash <= 0 scored plugins (they can only be selected by shortcut) */
302 if( p_module
->i_score
<= 0 )
306 /* Store this new module */
307 p_list
[count
].p_module
= p_module
;
308 p_list
[count
].i_score
= p_module
->i_score
+ i_shortcut_bonus
;
309 p_list
[count
].b_force
= i_shortcut_bonus
&& b_strict
;
313 /* We can release the list, interesting modules are held */
314 module_list_free (p_all
);
316 /* Sort candidates by descending score */
317 qsort (p_list
, count
, sizeof (p_list
[0]), modulecmp
);
318 msg_Dbg( p_this
, "looking for %s module: %zu candidate%s", psz_capability
,
319 count
, count
== 1 ? "" : "s" );
321 /* Parse the linked list and use the first successful module */
324 va_start(args
, probe
);
327 for (size_t i
= 0; (i
< count
) && (p_module
== NULL
); i
++)
329 module_t
*p_cand
= p_list
[i
].p_module
;
331 if (module_Map (p_this
, p_cand
))
333 p_this
->b_force
= p_list
[i
].b_force
;
337 if (likely(p_cand
->pf_activate
!= NULL
))
342 ret
= probe(p_cand
->pf_activate
, ap
);
356 /* good module, but aborted */
359 default: /* bad module */
366 p_this
->b_force
= b_force_backup
;
368 if( p_module
!= NULL
)
370 msg_Dbg( p_this
, "using %s module \"%s\"",
371 psz_capability
, module_get_object(p_module
) );
372 vlc_object_set_name( p_this
, psz_alias
? psz_alias
373 : module_get_object(p_module
) );
375 else if( count
== 0 )
376 msg_Dbg( p_this
, "no %s module matched \"%s\"",
377 psz_capability
, (psz_name
&& *psz_name
) ? psz_name
: "any" );
379 msg_Dbg( p_this
, "no %s module matching \"%s\" could be loaded",
380 psz_capability
, (psz_name
&& *psz_name
) ? psz_name
: "any" );
382 free( psz_shortcuts
);
385 /* Don't forget that the module is still locked */
391 * Deinstantiates a module.
392 * \param module the module pointer as returned by vlc_module_load()
393 * \param deinit deactivation callback
395 void vlc_module_unload(module_t
*module
, vlc_deactivate_t deinit
, ...)
397 if (module
->pf_deactivate
!= NULL
)
401 va_start(ap
, deinit
);
402 deinit(module
->pf_deactivate
, ap
);
408 static int generic_start(void *func
, va_list ap
)
410 vlc_object_t
*obj
= va_arg(ap
, vlc_object_t
*);
411 int (*activate
)(vlc_object_t
*) = func
;
413 return activate(obj
);
416 static void generic_stop(void *func
, va_list ap
)
418 vlc_object_t
*obj
= va_arg(ap
, vlc_object_t
*);
419 void (*deactivate
)(vlc_object_t
*) = func
;
425 module_t
*module_need(vlc_object_t
*obj
, const char *cap
, const char *name
,
428 return vlc_module_load(obj
, cap
, name
, strict
, generic_start
, obj
);
432 void module_unneed(vlc_object_t
*obj
, module_t
*module
)
434 msg_Dbg(obj
, "removing module \"%s\"", module_get_object(module
));
435 vlc_module_unload(module
, generic_stop
, obj
);
439 * Get a pointer to a module_t given it's name.
441 * \param name the name of the module
442 * \return a pointer to the module or NULL in case of a failure
444 module_t
*module_find (const char *name
)
446 module_t
**list
, *module
;
448 assert (name
!= NULL
);
449 list
= module_list_get (NULL
);
453 for (size_t i
= 0; (module
= list
[i
]) != NULL
; i
++)
455 if (unlikely(module
->i_shortcuts
== 0))
457 if (!strcmp (module
->pp_shortcuts
[0], name
))
460 module_list_free (list
);
465 * Tell if a module exists and release it in thic case
467 * \param psz_name th name of the module
468 * \return TRUE if the module exists
470 bool module_exists (const char * psz_name
)
472 return module_find (psz_name
) != NULL
;
476 * Get a pointer to a module_t that matches a shortcut.
477 * This is a temporary hack for SD. Do not re-use (generally multiple modules
478 * can have the same shortcut, so this is *broken* - use module_need()!).
480 * \param psz_shortcut shortcut of the module
481 * \param psz_cap capability of the module
482 * \return a pointer to the module or NULL in case of a failure
484 module_t
*module_find_by_shortcut (const char *psz_shortcut
)
486 module_t
**list
, *module
;
488 list
= module_list_get (NULL
);
492 for (size_t i
= 0; (module
= list
[i
]) != NULL
; i
++)
493 for (size_t j
= 0; j
< module
->i_shortcuts
; j
++)
494 if (!strcmp (module
->pp_shortcuts
[j
], psz_shortcut
))
497 module_list_free (list
);
502 * Get the configuration of a module
504 * \param module the module
505 * \param psize the size of the configuration returned
506 * \return the configuration as an array
508 module_config_t
*module_config_get( const module_t
*module
, unsigned *restrict psize
)
511 unsigned size
= module
->confsize
;
512 module_config_t
*config
= malloc( size
* sizeof( *config
) );
514 assert( psize
!= NULL
);
520 for( i
= 0, j
= 0; i
< size
; i
++ )
522 const module_config_t
*item
= module
->p_config
+ i
;
523 if( item
->b_internal
/* internal option */
524 || item
->b_removed
/* removed option */ )
527 memcpy( config
+ j
, item
, sizeof( *config
) );
536 * Release the configuration
538 * \param the configuration
541 void module_config_free( module_config_t
*config
)