]> git.sesse.net Git - vlc/blobdiff - src/modules/entry.c
raop: handle VLC_ADD_LIBS
[vlc] / src / modules / entry.c
index c67362085b96ba6378e716f0dfac49c229b11546..60543db4312883ceb5866b2a3ece0ffe43ce35c7 100644 (file)
 #include "config/configuration.h"
 #include "libvlc.h"
 
-static void vlc_module_destruct (gc_object_t *obj)
+static char *strdup_null (const char *str)
 {
-    module_t *module = vlc_priv (obj, module_t);
-
-    free (module->pp_shortcuts);
-    free (module);
+    return (str != NULL) ? strdup (str) : NULL;
 }
 
-module_t *vlc_module_create (void)
+module_t *vlc_module_create (module_t *parent)
 {
     module_t *module = malloc (sizeof (*module));
     if (module == NULL)
         return NULL;
 
-    module->next = NULL;
+    /* TODO: replace module/submodules with plugin/modules */
+    if (parent == NULL)
+    {
+        module->next = NULL;
+        module->parent = NULL;
+    }
+    else
+    {
+        module->next = parent->submodule;
+        parent->submodule = module;
+        parent->submodule_count++;
+        module->parent = parent;
+    }
+
     module->submodule = NULL;
-    module->parent = NULL;
     module->submodule_count = 0;
-    vlc_gc_init (module, vlc_module_destruct);
 
     module->psz_shortname = NULL;
     module->psz_longname = NULL;
@@ -60,8 +68,9 @@ module_t *vlc_module_create (void)
     module->pp_shortcuts = NULL;
     module->i_shortcuts = 0;
     module->psz_capability = NULL;
-    module->i_score = 1;
-    module->b_unloadable = true;
+    module->i_score = (parent != NULL) ? parent->i_score : 1;
+    module->b_loaded = false;
+    module->b_unloadable = parent == NULL;
     module->pf_activate = NULL;
     module->pf_deactivate = NULL;
     module->p_config = NULL;
@@ -71,60 +80,35 @@ module_t *vlc_module_create (void)
     /*module->handle = garbage */
     module->psz_filename = NULL;
     module->domain = NULL;
-    module->b_builtin = false;
-    module->b_loaded = false;
     return module;
 }
 
-
-static void vlc_submodule_destruct (gc_object_t *obj)
+/**
+ * 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)
 {
-    module_t *module = vlc_priv (obj, module_t);
-
-    free (module->pp_shortcuts);
-    free (module);
-}
+    assert (!module->b_loaded || !module->b_unloadable);
 
-module_t *vlc_submodule_create (module_t *module)
-{
-    assert (module != NULL);
+    for (module_t *m = module->submodule, *next; m != NULL; m = next)
+    {
+        next = m->next;
+        vlc_module_destroy (m);
+    }
 
-    module_t *submodule = malloc (sizeof (*submodule));
-    if (unlikely(submodule == NULL))
-        return NULL;
+    config_Free (module->p_config, module->confsize);
 
-    /* TODO: replace module/submodules with plugin/modules */
-    vlc_gc_init (submodule, vlc_submodule_destruct);
-
-    submodule->next = module->submodule;
-    module->submodule = submodule;
-    module->submodule_count++;
-    submodule->parent = module;
-    submodule->submodule = NULL;
-    submodule->submodule_count = 0;
-
-    submodule->pp_shortcuts = xmalloc (sizeof (char **));
-    submodule->pp_shortcuts[0] = module->pp_shortcuts[0]; /* object name */
-    submodule->i_shortcuts = 1;
-
-    submodule->psz_shortname = module->psz_shortname;
-    submodule->psz_longname = module->psz_longname;
-    submodule->psz_help = NULL;
-    submodule->psz_capability = module->psz_capability;
-    submodule->i_score = module->i_score;
-    submodule->b_builtin = false;
-    submodule->b_loaded = false;
-    submodule->b_unloadable = false;
-    submodule->pf_activate = NULL;
-    submodule->pf_deactivate = NULL;
-    submodule->p_config = NULL;
-    submodule->confsize = 0;
-    submodule->i_config_items = 0;
-    submodule->i_bool_items = 0;
-    /*submodule->handle = unused*/
-    /*submodule->psz_filename unused */
-    submodule->domain = NULL;
-    return submodule;
+    free (module->domain);
+    free (module->psz_filename);
+    for (unsigned i = 0; i < module->i_shortcuts; i++)
+        free (module->pp_shortcuts[i]);
+    free (module->pp_shortcuts);
+    free (module->psz_capability);
+    free (module->psz_help);
+    free (module->psz_longname);
+    free (module->psz_shortname);
+    free (module);
 }
 
 static module_config_t *vlc_config_create (module_t *module, int type)
@@ -161,20 +145,44 @@ static module_config_t *vlc_config_create (module_t *module, int type)
 }
 
 
-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;
 
     va_start (ap, propid);
     switch (propid)
     {
-        case VLC_SUBMODULE_CREATE:
+        case VLC_MODULE_CREATE:
         {
-            module_t **pp = va_arg (ap, module_t **);
-            *pp = vlc_submodule_create (module);
-            if (*pp == NULL)
+            module = *pprimary;
+            module_t *submodule = vlc_module_create (module);
+            if (unlikely(submodule == NULL))
+            {
                 ret = -1;
+                break;
+            }
+
+            *(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]);
+            submodule->i_shortcuts = 1; /* object name */
+
+            submodule->psz_shortname = strdup_null (module->psz_shortname);
+            submodule->psz_longname = strdup_null (module->psz_longname);
+            submodule->psz_capability = strdup_null (module->psz_capability);
             break;
         }
 
@@ -182,9 +190,14 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
         {
             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;
         }
 
@@ -205,12 +218,15 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
             }
             module->pp_shortcuts = pp;
             module->i_shortcuts = index + i_shortcuts;
-            memcpy (pp + index, tab, sizeof (pp[0]) * i_shortcuts);
+            pp += index;
+            for (unsigned i = 0; i < i_shortcuts; i++)
+                pp[i] = strdup (tab[i]);
             break;
         }
 
         case VLC_MODULE_CAPABILITY:
-            module->psz_capability = va_arg (ap, char *);
+            free (module->psz_capability);
+            module->psz_capability = strdup (va_arg (ap, char *));
             break;
 
         case VLC_MODULE_SCORE:
@@ -226,6 +242,7 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
             break;
 
         case VLC_MODULE_NO_UNLOAD:
+            assert (module->parent == NULL);
             module->b_unloadable = false;
             break;
 
@@ -235,30 +252,36 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
 
             assert (module->i_shortcuts == 0);
             module->pp_shortcuts = malloc( sizeof( char ** ) );
-            module->pp_shortcuts[0] = (char*)value; /* dooh! */
+            module->pp_shortcuts[0] = strdup (value);
             module->i_shortcuts = 1;
 
-            if (module->psz_longname == NULL)
-                module->psz_longname = (char*)value; /* dooh! */
+            assert (module->psz_longname == NULL);
+            module->psz_longname = strdup (value);
             break;
         }
 
         case VLC_MODULE_SHORTNAME:
-            module->psz_shortname = va_arg (ap, char *);
+            assert (module->psz_shortname == NULL || module->parent != NULL);
+            free (module->psz_shortname);
+            module->psz_shortname = strdup (va_arg (ap, char *));
             break;
 
         case VLC_MODULE_DESCRIPTION:
-            module->psz_longname = va_arg (ap, char *);
+            // TODO: do not set this in VLC_MODULE_NAME
+            free (module->psz_longname);
+            module->psz_longname = strdup (va_arg (ap, char *));
             break;
 
         case VLC_MODULE_HELP:
             assert (module->parent == NULL);
             assert (module->psz_help == NULL);
-            module->psz_help = va_arg (ap, char *);
+            module->psz_help = strdup (va_arg (ap, char *));
             break;
 
         case VLC_MODULE_TEXTDOMAIN:
-            module->domain = va_arg (ap, char *);
+            assert (module->parent == NULL);
+            assert (module->domain == NULL);
+            module->domain = strdup (va_arg (ap, char *));
             break;
 
         case VLC_CONFIG_NAME:
@@ -296,18 +319,16 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
 
         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;
         }
 
@@ -338,14 +359,6 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
             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;
@@ -455,3 +468,19 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int 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;
+}