[vlc-commits] module_list_cap(): sorts modules for a certain capability

Rémi Denis-Courmont git at videolan.org
Fri Oct 12 18:04:14 CEST 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri Oct 12 18:39:38 2012 +0300| [a57b503d3466b6ffd7bee40f6f6b814722111951] | committer: Rémi Denis-Courmont

module_list_cap(): sorts modules for a certain capability

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a57b503d3466b6ffd7bee40f6f6b814722111951
---

 src/modules/bank.c    |   53 +++++++++++++++++++++++++++++++++++++++++++++++--
 src/modules/modules.h |    2 ++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/src/modules/bank.c b/src/modules/bank.c
index 9e182c6..cb2225d 100644
--- a/src/modules/bank.c
+++ b/src/modules/bank.c
@@ -216,8 +216,6 @@ void module_list_free (module_t **list)
  */
 module_t **module_list_get (size_t *n)
 {
-    /* TODO: this whole module lookup is quite inefficient */
-    /* Remove this and improve module_need */
     module_t **tab = NULL;
     size_t i = 0;
 
@@ -243,6 +241,57 @@ module_t **module_list_get (size_t *n)
     return tab;
 }
 
+static int modulecmp (const void *a, const void *b)
+{
+    const module_t *const *ma = a, *const *mb = b;
+    /* Note that qsort() uses _ascending_ order,
+     * so the smallest module is the one with the biggest score. */
+    return (*mb)->i_score - (*ma)->i_score;
+}
+
+/**
+ * Builds a sorted list of all VLC modules with a given capability.
+ * The list is sorted from the highest module score to the lowest.
+ * @param list pointer to the table of modules [OUT]
+ * @param cap capability of modules to look for
+ * @return the number of matching found, or -1 on error (*list is then NULL).
+ * @note *list must be freed with module_list_free().
+ */
+ssize_t module_list_cap (module_t ***restrict list, const char *cap)
+{
+    /* TODO: This is quite inefficient. List should be sorted by capability. */
+    ssize_t n = 0;
+
+    assert (list != NULL);
+
+    for (module_t *mod = modules.head; mod != NULL; mod = mod->next)
+    {
+         if (module_provides (mod, cap))
+             n++;
+         for (module_t *subm = mod->submodule; subm != NULL; subm = subm->next)
+             if (module_provides (subm, cap))
+                 n++;
+    }
+
+    module_t **tab = malloc (sizeof (*tab) * n);
+    *list = tab;
+    if (unlikely(tab == NULL))
+        return -1;
+
+    for (module_t *mod = modules.head; mod != NULL; mod = mod->next)
+    {
+         if (module_provides (mod, cap))
+             *(tab++)= mod;
+         for (module_t *subm = mod->submodule; subm != NULL; subm = subm->next)
+             if (module_provides (subm, cap))
+                 *(tab++) = subm;
+    }
+
+    assert (tab == *list + n);
+    qsort (*list, n, sizeof (*tab), modulecmp);
+    return n;
+}
+
 #ifdef HAVE_DYNAMIC_PLUGINS
 typedef enum { CACHE_USE, CACHE_RESET, CACHE_IGNORE } cache_mode_t;
 
diff --git a/src/modules/modules.h b/src/modules/modules.h
index a870560..bad964f 100644
--- a/src/modules/modules.h
+++ b/src/modules/modules.h
@@ -110,6 +110,8 @@ size_t module_LoadPlugins( vlc_object_t * );
 void module_EndBank (bool);
 int module_Map (vlc_object_t *, module_t *);
 
+ssize_t module_list_cap (module_t ***, const char *);
+
 int vlc_bindtextdomain (const char *);
 
 /* Low-level OS-dependent handler */



More information about the vlc-commits mailing list