X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fentry.c;h=60543db4312883ceb5866b2a3ece0ffe43ce35c7;hb=ffce1e460279dab9e890ae6f28074fb5bffc70d9;hp=df7277bd5de06c00b510866bb28f74a18decf912;hpb=cafd2e02288005f71157bc74cf13b7d1d68fb808;p=vlc diff --git a/src/modules/entry.c b/src/modules/entry.c index df7277bd5d..60543db431 100644 --- a/src/modules/entry.c +++ b/src/modules/entry.c @@ -34,39 +34,43 @@ #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->psz_object_name); - free (module); + return (str != NULL) ? strdup (str) : NULL; } -static const char default_name[] = "unnamed"; - -module_t *vlc_module_create (vlc_object_t *obj) +module_t *vlc_module_create (module_t *parent) { module_t *module = malloc (sizeof (*module)); if (module == NULL) return NULL; - module->psz_object_name = strdup( default_name ); - 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 = (char*)default_name; + module->psz_longname = NULL; module->psz_help = NULL; module->pp_shortcuts = NULL; module->i_shortcuts = 0; - module->psz_capability = (char*)""; - module->i_score = 1; - module->b_unloadable = true; - module->b_submodule = false; + module->psz_capability = NULL; + 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; @@ -76,50 +80,35 @@ module_t *vlc_module_create (vlc_object_t *obj) /*module->handle = garbage */ module->psz_filename = NULL; module->domain = NULL; - module->b_builtin = false; - module->b_loaded = false; - - (void)obj; 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->psz_object_name); - 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 = calloc( 1, sizeof(*submodule) ); - if( !submodule ) - return NULL; + config_Free (module->p_config, module->confsize); - vlc_gc_init (submodule, vlc_submodule_destruct); - - submodule->next = module->submodule; - submodule->parent = module; - module->submodule = submodule; - module->submodule_count++; - - /* Muahahaha! Heritage! Polymorphism! Ugliness!! */ - submodule->pp_shortcuts = malloc( sizeof( char ** ) ); - submodule->pp_shortcuts[0] = module->pp_shortcuts[0]; /* object name */ - submodule->i_shortcuts = 1; - - submodule->psz_object_name = strdup( module->psz_object_name ); - submodule->psz_shortname = module->psz_shortname; - submodule->psz_longname = module->psz_longname; - submodule->psz_capability = module->psz_capability; - submodule->i_score = module->i_score; - submodule->b_submodule = true; - submodule->domain = module->domain; - 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) @@ -144,7 +133,7 @@ static module_config_t *vlc_config_create (module_t *module, int type) } tab[confsize].i_type = type; - if (type & CONFIG_ITEM) + if (CONFIG_ITEM(type)) { module->i_config_items++; if (type == CONFIG_ITEM_BOOL) @@ -156,22 +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; - typedef int(*int_fp_vlcobjectt)(vlc_object_t *) ; - typedef void(*void_fp_vlcobjectt)(vlc_object_t *); 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; } @@ -179,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; } @@ -189,9 +205,12 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) { unsigned i_shortcuts = va_arg (ap, unsigned); unsigned index = module->i_shortcuts; + /* The cache loader accept only a small number of shortcuts */ + assert(i_shortcuts + index <= MODULE_SHORTCUT_MAX); + const char *const *tab = va_arg (ap, const char *const *); - const char **pp = realloc (module->pp_shortcuts, - sizeof (pp[0]) * (index + i_shortcuts)); + char **pp = realloc (module->pp_shortcuts, + sizeof (pp[0]) * (index + i_shortcuts)); if (unlikely(pp == NULL)) { ret = -1; @@ -199,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: @@ -212,69 +234,77 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) break; case VLC_MODULE_CB_OPEN: - module->pf_activate = va_arg (ap, int_fp_vlcobjectt); + module->pf_activate = va_arg (ap, void *); break; case VLC_MODULE_CB_CLOSE: - module->pf_deactivate = va_arg (ap, void_fp_vlcobjectt); + module->pf_deactivate = va_arg (ap, void *); break; case VLC_MODULE_NO_UNLOAD: + assert (module->parent == NULL); module->b_unloadable = false; break; case VLC_MODULE_NAME: { const char *value = va_arg (ap, const char *); - free( module->psz_object_name ); - module->psz_object_name = strdup( value ); + + 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 == default_name) - 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: - module->psz_help = va_arg (ap, char *); + assert (module->parent == NULL); + assert (module->psz_help == NULL); + 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: { const char *name = va_arg (ap, const char *); - vlc_callback_t cb = va_arg (ap, vlc_callback_t); assert (name != NULL); item->psz_name = strdup (name); - item->pf_callback = cb; break; } case VLC_CONFIG_VALUE: { - if (IsConfigIntegerType (item->i_type)) + if (IsConfigIntegerType (item->i_type) + || !CONFIG_ITEM(item->i_type)) { - item->orig.i = item->saved.i = + item->orig.i = item->value.i = va_arg (ap, int64_t); } else if (IsConfigFloatType (item->i_type)) { - item->orig.f = item->saved.f = + item->orig.f = item->value.f = va_arg (ap, double); } else @@ -283,26 +313,22 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) const char *value = va_arg (ap, const char *); item->value.psz = value ? strdup (value) : NULL; item->orig.psz = value ? strdup (value) : NULL; - item->saved.psz = value ? strdup (value) : NULL; } break; } case VLC_CONFIG_RANGE: { - if (IsConfigIntegerType (item->i_type) - || item->i_type == CONFIG_ITEM_MODULE_LIST_CAT - || item->i_type == CONFIG_ITEM_MODULE_CAT) - { - 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; } @@ -314,14 +340,6 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) item->b_unsaveable = true; break; - case VLC_CONFIG_PERSISTENT: - item->b_autosave = true; - break; - - case VLC_CONFIG_RESTART: - item->b_restart = true; - break; - case VLC_CONFIG_PRIVATE: item->b_internal = true; break; @@ -341,13 +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 *); - item->psz_oldname = oldname ? strdup (oldname) : NULL; - break; - } - case VLC_CONFIG_SAFE: item->b_safe = true; break; @@ -457,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; +}