~ubuntu-branches/ubuntu/intrepid/irssi/intrepid-updates

« back to all changes in this revision

Viewing changes to src/core/modules.c

  • Committer: Bazaar Package Importer
  • Author(s): David Pashley
  • Date: 2005-12-10 21:25:51 UTC
  • Revision ID: james.westby@ubuntu.com-20051210212551-5qwm108g7inyu2f2
Tags: upstream-0.8.10
ImportĀ upstreamĀ versionĀ 0.8.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 modules.c : irssi
 
3
 
 
4
    Copyright (C) 1999-2001 Timo Sirainen
 
5
 
 
6
    This program is free software; you can redistribute it and/or modify
 
7
    it under the terms of the GNU General Public License as published by
 
8
    the Free Software Foundation; either version 2 of the License, or
 
9
    (at your option) any later version.
 
10
 
 
11
    This program is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with this program; if not, write to the Free Software
 
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
*/
 
20
 
 
21
#include "module.h"
 
22
#include "modules.h"
 
23
#include "signals.h"
 
24
 
 
25
GSList *modules;
 
26
 
 
27
static GHashTable *uniqids, *uniqstrids;
 
28
static GHashTable *idlookup, *stridlookup;
 
29
static int next_uniq_id;
 
30
 
 
31
void *module_check_cast(void *object, int type_pos, const char *id)
 
32
{
 
33
        return object == NULL || module_find_id(id,
 
34
                G_STRUCT_MEMBER(int, object, type_pos)) == -1 ? NULL : object;
 
35
}
 
36
 
 
37
void *module_check_cast_module(void *object, int type_pos,
 
38
                               const char *module, const char *id)
 
39
{
 
40
        const char *str;
 
41
 
 
42
        if (object == NULL)
 
43
                return NULL;
 
44
 
 
45
        str = module_find_id_str(module,
 
46
                                 G_STRUCT_MEMBER(int, object, type_pos));
 
47
        return str == NULL || strcmp(str, id) != 0 ? NULL : object;
 
48
}
 
49
 
 
50
/* return unique number across all modules for `id' */
 
51
int module_get_uniq_id(const char *module, int id)
 
52
{
 
53
        GHashTable *ids;
 
54
        gpointer origkey, uniqid, idp;
 
55
        int ret;
 
56
 
 
57
        g_return_val_if_fail(module != NULL, -1);
 
58
 
 
59
        ids = g_hash_table_lookup(idlookup, module);
 
60
        if (ids == NULL) {
 
61
                /* new module */
 
62
                ids = g_hash_table_new((GHashFunc) g_direct_hash,
 
63
                                       (GCompareFunc) g_direct_equal);
 
64
                g_hash_table_insert(idlookup, g_strdup(module), ids);
 
65
        }
 
66
 
 
67
        idp = GINT_TO_POINTER(id);
 
68
        if (!g_hash_table_lookup_extended(ids, idp, &origkey, &uniqid)) {
 
69
                /* not found */
 
70
                ret = next_uniq_id++;
 
71
                g_hash_table_insert(ids, idp, GINT_TO_POINTER(ret));
 
72
                g_hash_table_insert(uniqids, GINT_TO_POINTER(ret), idp);
 
73
        } else {
 
74
                ret = GPOINTER_TO_INT(uniqid);
 
75
        }
 
76
 
 
77
        return ret;
 
78
}
 
79
 
 
80
/* return unique number across all modules for `id' */
 
81
int module_get_uniq_id_str(const char *module, const char *id)
 
82
{
 
83
        GHashTable *ids;
 
84
        gpointer origkey, uniqid;
 
85
        int ret;
 
86
 
 
87
        g_return_val_if_fail(module != NULL, -1);
 
88
 
 
89
        ids = g_hash_table_lookup(stridlookup, module);
 
90
        if (ids == NULL) {
 
91
                /* new module */
 
92
                ids = g_hash_table_new((GHashFunc) g_str_hash,
 
93
                                       (GCompareFunc) g_str_equal);
 
94
                g_hash_table_insert(stridlookup, g_strdup(module), ids);
 
95
        }
 
96
 
 
97
        if (!g_hash_table_lookup_extended(ids, id, &origkey, &uniqid)) {
 
98
                /* not found */
 
99
                char *saveid;
 
100
 
 
101
                saveid = g_strdup(id);
 
102
                ret = next_uniq_id++;
 
103
                g_hash_table_insert(ids, saveid, GINT_TO_POINTER(ret));
 
104
                g_hash_table_insert(uniqstrids, GINT_TO_POINTER(ret), saveid);
 
105
        } else {
 
106
                ret = GPOINTER_TO_INT(uniqid);
 
107
        }
 
108
 
 
109
        return ret;
 
110
}
 
111
 
 
112
/* returns the original module specific id, -1 = not found */
 
113
int module_find_id(const char *module, int uniqid)
 
114
{
 
115
        GHashTable *idlist;
 
116
        gpointer origkey, id;
 
117
        int ret;
 
118
 
 
119
        g_return_val_if_fail(module != NULL, -1);
 
120
 
 
121
        if (!g_hash_table_lookup_extended(uniqids, GINT_TO_POINTER(uniqid),
 
122
                                          &origkey, &id))
 
123
                return -1;
 
124
 
 
125
        /* check that module matches */
 
126
        idlist = g_hash_table_lookup(idlookup, module);
 
127
        if (idlist == NULL)
 
128
                return -1;
 
129
 
 
130
        ret = GPOINTER_TO_INT(id);
 
131
        if (!g_hash_table_lookup_extended(idlist, id, &origkey, &id) ||
 
132
            GPOINTER_TO_INT(id) != uniqid)
 
133
                ret = -1;
 
134
 
 
135
        return ret;
 
136
}
 
137
 
 
138
/* returns the original module specific id, NULL = not found */
 
139
const char *module_find_id_str(const char *module, int uniqid)
 
140
{
 
141
        GHashTable *idlist;
 
142
        gpointer origkey, id;
 
143
        const char *ret;
 
144
 
 
145
        g_return_val_if_fail(module != NULL, NULL);
 
146
 
 
147
        if (!g_hash_table_lookup_extended(uniqstrids, GINT_TO_POINTER(uniqid),
 
148
                                          &origkey, &id))
 
149
                return NULL;
 
150
 
 
151
        /* check that module matches */
 
152
        idlist = g_hash_table_lookup(stridlookup, module);
 
153
        if (idlist == NULL)
 
154
                return NULL;
 
155
 
 
156
        ret = id;
 
157
        if (!g_hash_table_lookup_extended(idlist, id, &origkey, &id) ||
 
158
            GPOINTER_TO_INT(id) != uniqid)
 
159
                ret = NULL;
 
160
 
 
161
        return ret;
 
162
}
 
163
 
 
164
static void uniq_destroy(gpointer key, gpointer value)
 
165
{
 
166
        g_hash_table_remove(uniqids, value);
 
167
}
 
168
 
 
169
static void uniq_destroy_str(gpointer key, gpointer value)
 
170
{
 
171
        g_hash_table_remove(uniqstrids, value);
 
172
        g_free(key);
 
173
}
 
174
 
 
175
/* Destroy unique IDs from `module'. This function is automatically called
 
176
   when module is destroyed with module's name as the parameter. */
 
177
void module_uniq_destroy(const char *module)
 
178
{
 
179
        GHashTable *idlist;
 
180
        gpointer key, value;
 
181
 
 
182
        if (g_hash_table_lookup_extended(idlookup, module, &key, &value)) {
 
183
                idlist = value;
 
184
 
 
185
                g_hash_table_remove(idlookup, key);
 
186
                g_free(key);
 
187
 
 
188
                g_hash_table_foreach(idlist, (GHFunc) uniq_destroy, NULL);
 
189
                g_hash_table_destroy(idlist);
 
190
        }
 
191
 
 
192
        if (g_hash_table_lookup_extended(stridlookup, module, &key, &value)) {
 
193
                idlist = value;
 
194
 
 
195
                g_hash_table_remove(stridlookup, key);
 
196
                g_free(key);
 
197
 
 
198
                g_hash_table_foreach(idlist, (GHFunc) uniq_destroy_str, NULL);
 
199
                g_hash_table_destroy(idlist);
 
200
        }
 
201
}
 
202
 
 
203
/* Register a new module. The `name' is the root module name, `submodule'
 
204
   specifies the current module to be registered (eg. "perl", "fe").
 
205
   The module is registered as statically loaded by default. */
 
206
MODULE_FILE_REC *module_register_full(const char *name, const char *submodule,
 
207
                                      const char *defined_module_name)
 
208
{
 
209
        MODULE_REC *module;
 
210
        MODULE_FILE_REC *file;
 
211
 
 
212
        module = module_find(name);
 
213
        if (module == NULL) {
 
214
                module = g_new0(MODULE_REC, 1);
 
215
                module->name = g_strdup(name);
 
216
 
 
217
                modules = g_slist_append(modules, module);
 
218
        }
 
219
 
 
220
        file = module_file_find(module, submodule);
 
221
        if (file != NULL)
 
222
                return file;
 
223
 
 
224
        file = g_new0(MODULE_FILE_REC, 1);
 
225
        file->root = module;
 
226
        file->name = g_strdup(submodule);
 
227
        file->defined_module_name = g_strdup(defined_module_name);
 
228
 
 
229
        module->files = g_slist_append(module->files, file);
 
230
        return file;
 
231
}
 
232
 
 
233
MODULE_REC *module_find(const char *name)
 
234
{
 
235
        GSList *tmp;
 
236
 
 
237
        for (tmp = modules; tmp != NULL; tmp = tmp->next) {
 
238
                MODULE_REC *rec = tmp->data;
 
239
 
 
240
                if (g_strcasecmp(rec->name, name) == 0)
 
241
                        return rec;
 
242
        }
 
243
 
 
244
        return NULL;
 
245
}
 
246
 
 
247
MODULE_FILE_REC *module_file_find(MODULE_REC *module, const char *name)
 
248
{
 
249
        GSList *tmp;
 
250
 
 
251
        for (tmp = module->files; tmp != NULL; tmp = tmp->next) {
 
252
                MODULE_FILE_REC *rec = tmp->data;
 
253
 
 
254
                if (strcmp(rec->name, name) == 0)
 
255
                        return rec;
 
256
        }
 
257
 
 
258
        return NULL;
 
259
}
 
260
 
 
261
static void uniq_get_modules(char *key, void *value, GSList **list)
 
262
{
 
263
        *list = g_slist_append(*list, g_strdup(key));
 
264
}
 
265
 
 
266
void modules_init(void)
 
267
{
 
268
        modules = NULL;
 
269
 
 
270
        idlookup = g_hash_table_new((GHashFunc) g_str_hash,
 
271
                                    (GCompareFunc) g_str_equal);
 
272
        uniqids = g_hash_table_new((GHashFunc) g_direct_hash,
 
273
                                   (GCompareFunc) g_direct_equal);
 
274
 
 
275
        stridlookup = g_hash_table_new((GHashFunc) g_str_hash,
 
276
                                       (GCompareFunc) g_str_equal);
 
277
        uniqstrids = g_hash_table_new((GHashFunc) g_direct_hash,
 
278
                                      (GCompareFunc) g_direct_equal);
 
279
        next_uniq_id = 0;
 
280
}
 
281
 
 
282
void modules_deinit(void)
 
283
{
 
284
        GSList *list;
 
285
 
 
286
        list = NULL;
 
287
        g_hash_table_foreach(idlookup, (GHFunc) uniq_get_modules, &list);
 
288
        g_hash_table_foreach(stridlookup, (GHFunc) uniq_get_modules, &list);
 
289
 
 
290
        while (list != NULL) {
 
291
                module_uniq_destroy(list->data);
 
292
                g_free(list->data);
 
293
                list = g_slist_remove(list, list->data);
 
294
        }
 
295
 
 
296
        g_hash_table_destroy(idlookup);
 
297
        g_hash_table_destroy(stridlookup);
 
298
        g_hash_table_destroy(uniqids);
 
299
        g_hash_table_destroy(uniqstrids);
 
300
}