/*****************************************************************************
* entry.c : Callbacks for module entry point
*****************************************************************************
- * Copyright (C) 2007 the VideoLAN team
+ * Copyright (C) 2007 VLC authors and VideoLAN
* Copyright © 2007-2008 Rémi Denis-Courmont
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
return module;
}
+/**
+ * Destroys a plug-in.
+ * @warning If the plug-in is loaded in memory, the handle will be leaked.
+ */
void vlc_module_destroy (module_t *module)
{
+ assert (!module->b_loaded || !module->b_unloadable);
+
for (module_t *m = module->submodule, *next; m != NULL; m = next)
{
next = m->next;
}
-int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
+/**
+ * Callback for the plugin descriptor functions.
+ */
+static int vlc_plugin_setter (void *plugin, void *tgt, int propid, ...)
{
+ module_t **pprimary = plugin;
+ module_t *module = tgt;
+ module_config_t *item = tgt;
va_list ap;
int ret = 0;
{
case VLC_MODULE_CREATE:
{
- module_t **pp = va_arg (ap, module_t **);
+ module = *pprimary;
module_t *submodule = vlc_module_create (module);
-
if (unlikely(submodule == NULL))
{
ret = -1;
break;
}
- *pp = submodule;
- if (module == NULL)
+ *(va_arg (ap, module_t **)) = submodule;
+ if (*pprimary == NULL)
+ {
+ *pprimary = submodule;
break;
+ }
/* Inheritance. Ugly!! */
submodule->pp_shortcuts = xmalloc (sizeof (char **));
submodule->pp_shortcuts[0] = strdup_null (module->pp_shortcuts[0]);
{
int type = va_arg (ap, int);
module_config_t **pp = va_arg (ap, module_config_t **);
- *pp = vlc_config_create (module, type);
- if (*pp == NULL)
+
+ item = vlc_config_create (*pprimary, type);
+ if (unlikely(item == NULL))
+ {
ret = -1;
+ break;
+ }
+ *pp = item;
break;
}
case VLC_CONFIG_RANGE:
{
- if (IsConfigIntegerType (item->i_type)
- || !CONFIG_ITEM(item->i_type))
- {
- item->min.i = va_arg (ap, int64_t);
- item->max.i = va_arg (ap, int64_t);
- }
- else
if (IsConfigFloatType (item->i_type))
{
item->min.f = va_arg (ap, double);
item->max.f = va_arg (ap, double);
}
+ else
+ {
+ item->min.i = va_arg (ap, int64_t);
+ item->max.i = va_arg (ap, int64_t);
+ }
break;
}
item->i_short = va_arg (ap, int);
break;
- case VLC_CONFIG_OLDNAME:
- {
- const char *oldname = va_arg (ap, const char *);
- assert (item->psz_oldname == NULL);
- item->psz_oldname = oldname ? strdup (oldname) : NULL;
- break;
- }
-
case VLC_CONFIG_SAFE:
item->b_safe = true;
break;
{
size_t len = va_arg (ap, size_t);
+ assert (item->list_count == 0); /* cannot replace choices */
+ assert (item->list.psz_cb == NULL);
+ if (len == 0)
+ break; /* nothing to do */
/* Copy values */
if (IsConfigIntegerType (item->i_type))
{
const int *src = va_arg (ap, const int *);
- int *dst = malloc (sizeof (int) * (len + 1));
-
- if (dst != NULL)
- {
- memcpy (dst, src, sizeof (int) * len);
- dst[len] = 0;
- }
- item->pi_list = dst;
+ int *dst = xmalloc (sizeof (int) * len);
+
+ memcpy (dst, src, sizeof (int) * len);
+ item->list.i = dst;
}
else
if (IsConfigStringType (item->i_type))
{
const char *const *src = va_arg (ap, const char *const *);
- char **dst = malloc (sizeof (char *) * (len + 1));
-
- if (dst != NULL)
- {
- for (size_t i = 0; i < len; i++)
- dst[i] = src[i] ? strdup (src[i]) : NULL;
- dst[len] = NULL;
- }
- item->ppsz_list = dst;
+ char **dst = xmalloc (sizeof (char *) * len);
+
+ for (size_t i = 0; i < len; i++)
+ dst[i] = src[i] ? strdup (src[i]) : NULL;
+ item->list.psz = dst;
}
else
break;
/* Copy textual descriptions */
const char *const *text = va_arg (ap, const char *const *);
- if (text != NULL)
- {
- char **dtext = malloc (sizeof (char *) * (len + 1));
- if( dtext != NULL )
- {
- for (size_t i = 0; i < len; i++)
- dtext[i] = text[i] ? strdup (text[i]) : NULL;
- dtext[len] = NULL;
- }
- item->ppsz_list_text = dtext;
- }
- else
- item->ppsz_list_text = NULL;
-
- item->i_list = len;
- item->pf_update_list = va_arg (ap, vlc_callback_t);
+ char **dtext = xmalloc (sizeof (char *) * (len + 1));
+ for (size_t i = 0; i < len; i++)
+ dtext[i] = text[i] ? strdup (text[i]) : NULL;
+ item->list_text = dtext;
+ item->list_count = len;
break;
}
- case VLC_CONFIG_ADD_ACTION:
- {
- vlc_callback_t cb = va_arg (ap, vlc_callback_t), *tabcb;
- const char *name = va_arg (ap, const char *);
- char **tabtext;
-
- tabcb = realloc (item->ppf_action,
- (item->i_action + 2) * sizeof (cb));
- if (tabcb == NULL)
- break;
- item->ppf_action = tabcb;
- tabcb[item->i_action] = cb;
- tabcb[item->i_action + 1] = NULL;
-
- tabtext = realloc (item->ppsz_action_text,
- (item->i_action + 2) * sizeof (name));
- if (tabtext == NULL)
- break;
- item->ppsz_action_text = tabtext;
-
- if (name)
- tabtext[item->i_action] = strdup (name);
+ case VLC_CONFIG_LIST_CB:
+ if (IsConfigIntegerType (item->i_type))
+ item->list.i_cb = va_arg (ap, vlc_integer_list_cb);
else
- tabtext[item->i_action] = NULL;
- tabtext[item->i_action + 1] = NULL;
-
- item->i_action++;
+ if (IsConfigStringType (item->i_type))
+ item->list.psz_cb = va_arg (ap, vlc_string_list_cb);
+ else
+ break;
break;
- }
default:
fprintf (stderr, "LibVLC: unknown module property %d\n", propid);
va_end (ap);
return ret;
}
+
+/**
+ * Runs a plug-in descriptor. This loads the plug-in meta-data in memory.
+ */
+module_t *vlc_plugin_describe (vlc_plugin_cb entry)
+{
+ module_t *module = NULL;
+
+ if (entry (vlc_plugin_setter, &module) != 0)
+ {
+ if (module != NULL) /* partially initialized plug-in... */
+ vlc_module_destroy (module);
+ module = NULL;
+ }
+ return module;
+}