basic cli interface
[profile/ivi/pulseaudio.git] / src / module.c
1 #include <limits.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <assert.h>
5 #include <string.h>
6 #include <errno.h>
7
8 #include "module.h"
9 #include "strbuf.h"
10
11 struct module* module_load(struct core *c, const char *name, const char *argument) {
12     struct module *m = NULL;
13     int r;
14     
15     assert(c && name);
16
17     m = malloc(sizeof(struct module));
18     assert(m);
19
20     if (!(m->dl = lt_dlopenext(name)))
21         goto fail;
22
23     if (!(m->init = lt_dlsym(m->dl, "module_init")))
24         goto fail;
25
26     if (!(m->done = lt_dlsym(m->dl, "module_done")))
27         goto fail;
28     
29     m->name = strdup(name);
30     m->argument = argument ? strdup(argument) : NULL;
31     m->userdata = NULL;
32     m->core = c;
33
34     assert(m->init);
35     if (m->init(c, m) < 0)
36         goto fail;
37
38     if (!c->modules)
39         c->modules = idxset_new(NULL, NULL);
40     
41     assert(c->modules);
42     r = idxset_put(c->modules, m, &m->index);
43     assert(r >= 0 && m->index != IDXSET_INVALID);
44
45     fprintf(stderr, "module: loaded %u \"%s\" with argument \"%s\".\n", m->index, m->name, m->argument);
46     
47     return m;
48     
49 fail:
50     if (m) {
51         free(m->argument);
52         free(m->name);
53         
54         if (m->dl)
55             lt_dlclose(m->dl);
56
57         free(m);
58     }
59
60     return NULL;
61 }
62
63 static void module_free(struct module *m) {
64     assert(m && m->done && m->core);
65     m->done(m->core, m);
66
67     lt_dlclose(m->dl);
68     
69     fprintf(stderr, "module: unloaded %u \"%s\".\n", m->index, m->name);
70
71     free(m->name);
72     free(m->argument);
73     free(m);
74 }
75
76
77 void module_unload(struct core *c, struct module *m) {
78     assert(c && m);
79
80     assert(c->modules);
81     if (!(m = idxset_remove_by_data(c->modules, m, NULL)))
82         return;
83
84     module_free(m);
85 }
86
87 void module_unload_by_index(struct core *c, uint32_t index) {
88     struct module *m;
89     assert(c && index != IDXSET_INVALID);
90
91     assert(c->modules);
92     if (!(m = idxset_remove_by_index(c->modules, index)))
93         return;
94
95     module_free(m);
96 }
97
98 void free_callback(void *p, void *userdata) {
99     struct module *m = p;
100     assert(m);
101     module_free(m);
102 }
103
104 void module_unload_all(struct core *c) {
105     assert(c);
106
107     if (!c->modules)
108         return;
109
110     idxset_free(c->modules, free_callback, NULL);
111     c->modules = NULL;
112 }
113
114 char *module_list_to_string(struct core *c) {
115     struct strbuf *s;
116     struct module *m;
117     uint32_t index = IDXSET_INVALID;
118     assert(c);
119
120     s = strbuf_new();
121     assert(s);
122
123     strbuf_printf(s, "%u module(s) loaded.\n", idxset_ncontents(c->modules));
124     
125     for (m = idxset_first(c->modules, &index); m; m = idxset_next(c->modules, &index))
126         strbuf_printf(s, "    index: %u, name: <%s>, argument: <%s>\n", m->index, m->name, m->argument);
127     
128     return strbuf_tostring_free(s);
129 }