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 (unlikely(str
== NULL
|| *str
== '\0'))
133 const char *domain
= m
->plugin
->textdomain
;
134 return dgettext ((domain
!= NULL
) ? domain
: PACKAGE_NAME
, str
);
142 int module_start (vlc_object_t
*obj
, const module_t
*m
)
144 int (*activate
) (vlc_object_t
*) = m
->pf_activate
;
146 return (activate
!= NULL
) ? activate (obj
) : VLC_SUCCESS
;
150 void module_stop (vlc_object_t
*obj
, const module_t
*m
)
152 void (*deactivate
) (vlc_object_t
*) = m
->pf_deactivate
;
154 if (deactivate
!= NULL
)
158 static bool module_match_name (const module_t
*m
, const char *name
)
160 /* Plugins with zero score must be matched explicitly. */
161 if (!strcasecmp ("any", name
))
162 return m
->i_score
> 0;
164 for (unsigned i
= 0; i
< m
->i_shortcuts
; i
++)
165 if (!strcasecmp (m
->pp_shortcuts
[i
], name
))
170 static int module_load (vlc_object_t
*obj
, module_t
*m
,
171 vlc_activate_t init
, va_list args
)
173 int ret
= VLC_SUCCESS
;
175 if (module_Map(obj
, m
->plugin
))
178 if (m
->pf_activate
!= NULL
)
183 ret
= init (m
->pf_activate
, ap
);
187 if (ret
!= VLC_SUCCESS
)
188 vlc_objres_clear(obj
);
193 #undef vlc_module_load
195 * Finds and instantiates the best module of a certain type.
196 * All candidates modules having the specified capability and name will be
197 * sorted in decreasing order of priority. Then the probe callback will be
198 * invoked for each module, until it succeeds (returns 0), or all candidate
199 * module failed to initialize.
201 * The probe callback first parameter is the address of the module entry point.
202 * Further parameters are passed as an argument list; it corresponds to the
203 * variable arguments passed to this function. This scheme is meant to
204 * support arbitrary prototypes for the module entry point.
206 * \param obj VLC object
207 * \param capability capability, i.e. class of module
208 * \param name name of the module asked, if any
209 * \param strict if true, do not fallback to plugin with a different name
210 * but the same capability
211 * \param probe module probe callback
212 * \return the module or NULL in case of a failure
214 module_t
*vlc_module_load(vlc_object_t
*obj
, const char *capability
,
215 const char *name
, bool strict
,
216 vlc_activate_t probe
, ...)
220 if (name
== NULL
|| name
[0] == '\0')
223 /* Deal with variables */
226 var
= var_InheritString (obj
, name
+ 1);
227 name
= (var
!= NULL
) ? var
: "any";
230 /* Find matching modules */
232 ssize_t total
= module_list_cap (&mods
, capability
);
234 msg_Dbg (obj
, "looking for %s module matching \"%s\": %zd candidates",
235 capability
, name
, total
);
238 module_list_free (mods
);
239 msg_Dbg (obj
, "no %s modules", capability
);
243 module_t
*module
= NULL
;
244 const bool b_force_backup
= obj
->obj
.force
; /* FIXME: remove this */
247 va_start(args
, probe
);
251 size_t slen
= strcspn (name
, ",");
253 if (likely(slen
< sizeof (buf
)))
255 memcpy(buf
, name
, slen
);
259 name
+= strspn (name
, ",");
260 if (unlikely(slen
>= sizeof (buf
)))
263 const char *shortcut
= buf
;
264 assert (shortcut
!= NULL
);
266 if (!strcasecmp ("none", shortcut
))
269 obj
->obj
.force
= strict
&& strcasecmp ("any", shortcut
);
270 for (ssize_t i
= 0; i
< total
; i
++)
272 module_t
*cand
= mods
[i
];
274 continue; // module failed in previous iteration
275 if (!module_match_name (cand
, shortcut
))
277 mods
[i
] = NULL
; // only try each module once at most...
279 int ret
= module_load (obj
, cand
, probe
, args
);
291 /* None of the shortcuts matched, fall back to any module */
294 obj
->obj
.force
= false;
295 for (ssize_t i
= 0; i
< total
; i
++)
297 module_t
*cand
= mods
[i
];
298 if (cand
== NULL
|| module_get_score (cand
) <= 0)
301 int ret
= module_load (obj
, cand
, probe
, args
);
314 obj
->obj
.force
= b_force_backup
;
315 module_list_free (mods
);
320 msg_Dbg (obj
, "using %s module \"%s\"", capability
,
321 module_get_object (module
));
322 vlc_object_set_name (obj
, module_get_object (module
));
325 msg_Dbg (obj
, "no %s modules matched", capability
);
329 #undef vlc_module_unload
331 * Deinstantiates a module.
332 * \param module the module pointer as returned by vlc_module_load()
333 * \param deinit deactivation callback
335 void vlc_module_unload(vlc_object_t
*obj
, module_t
*module
,
336 vlc_deactivate_t deinit
, ...)
338 if (module
->pf_deactivate
!= NULL
)
342 va_start(ap
, deinit
);
343 deinit(module
->pf_deactivate
, ap
);
347 vlc_objres_clear(obj
);
351 static int generic_start(void *func
, va_list ap
)
353 vlc_object_t
*obj
= va_arg(ap
, vlc_object_t
*);
354 int (*activate
)(vlc_object_t
*) = func
;
356 return activate(obj
);
359 static void generic_stop(void *func
, va_list ap
)
361 vlc_object_t
*obj
= va_arg(ap
, vlc_object_t
*);
362 void (*deactivate
)(vlc_object_t
*) = func
;
368 module_t
*module_need(vlc_object_t
*obj
, const char *cap
, const char *name
,
371 return vlc_module_load(obj
, cap
, name
, strict
, generic_start
, obj
);
375 void module_unneed(vlc_object_t
*obj
, module_t
*module
)
377 msg_Dbg(obj
, "removing module \"%s\"", module_get_object(module
));
378 vlc_module_unload(obj
, module
, generic_stop
, obj
);
382 * Get a pointer to a module_t given it's name.
384 * \param name the name of the module
385 * \return a pointer to the module or NULL in case of a failure
387 module_t
*module_find (const char *name
)
390 module_t
**list
= module_list_get (&count
);
392 assert (name
!= NULL
);
394 for (size_t i
= 0; i
< count
; i
++)
396 module_t
*module
= list
[i
];
398 if (unlikely(module
->i_shortcuts
== 0))
400 if (!strcmp (module
->pp_shortcuts
[0], name
))
402 module_list_free (list
);
406 module_list_free (list
);
411 * Tell if a module exists
413 * \param psz_name th name of the module
414 * \return TRUE if the module exists
416 bool module_exists (const char * psz_name
)
418 return module_find (psz_name
) != NULL
;
422 * Get the configuration of a module
424 * \param module the module
425 * \param psize the size of the configuration returned
426 * \return the configuration as an array
428 module_config_t
*module_config_get( const module_t
*module
, unsigned *restrict psize
)
430 const vlc_plugin_t
*plugin
= module
->plugin
;
432 if (plugin
->module
!= module
)
433 { /* For backward compatibility, pretend non-first modules have no
434 * configuration items. */
440 size_t size
= plugin
->conf
.size
;
441 module_config_t
*config
= malloc( size
* sizeof( *config
) );
443 assert( psize
!= NULL
);
449 for( i
= 0, j
= 0; i
< size
; i
++ )
451 const module_config_t
*item
= plugin
->conf
.items
+ i
;
452 if( item
->b_internal
/* internal option */
453 || item
->b_removed
/* removed option */ )
456 memcpy( config
+ j
, item
, sizeof( *config
) );
465 * Release the configuration
467 * \param the configuration
470 void module_config_free( module_config_t
*config
)