summaryrefslogtreecommitdiff
path: root/src/core/modules.c
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2001-08-14 00:41:59 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2001-08-14 00:41:59 +0000
commit803d8050164eaaefdd52fd4ae967c1e038b3c571 (patch)
tree615ff88add7d3682beebed692f41f5135c799713 /src/core/modules.c
parentf584c1013c74a98bfb43b79280c4ee20b775970a (diff)
downloadirssi-803d8050164eaaefdd52fd4ae967c1e038b3c571.zip
Module loading updates - /LOAD shows now also the statically loaded modules.
You can't /LOAD the same module twice. Syntax changed to /LOAD <module> [<submodule>], /UNLOAD <module> [<submodule>]. NOTE: all modules now need to call register_module() in their init() function. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1748 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/core/modules.c')
-rw-r--r--src/core/modules.c219
1 files changed, 36 insertions, 183 deletions
diff --git a/src/core/modules.c b/src/core/modules.c
index f450f39d..dc373189 100644
--- a/src/core/modules.c
+++ b/src/core/modules.c
@@ -1,7 +1,7 @@
/*
modules.c : irssi
- Copyright (C) 1999-2000 Timo Sirainen
+ Copyright (C) 1999-2001 Timo Sirainen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,9 +22,6 @@
#include "modules.h"
#include "signals.h"
-#include "commands.h"
-#include "settings.h"
-
GSList *modules;
static GHashTable *uniqids, *uniqstrids;
@@ -201,206 +198,62 @@ void module_uniq_destroy(const char *module)
}
}
-MODULE_REC *module_find(const char *name)
+/* Register a new module. The `name' is the root module name, `submodule'
+ specifies the current module to be registered (eg. "perl", "fe").
+ The module is registered as statically loaded by default. */
+MODULE_FILE_REC *module_register_full(const char *name, const char *submodule,
+ const char *defined_module_name)
{
- GSList *tmp;
+ MODULE_REC *module;
+ MODULE_FILE_REC *file;
- for (tmp = modules; tmp != NULL; tmp = tmp->next) {
- MODULE_REC *rec = tmp->data;
+ module = module_find(name);
+ if (module == NULL) {
+ module = g_new0(MODULE_REC, 1);
+ module->name = g_strdup(name);
- if (g_strcasecmp(rec->name, name) == 0)
- return rec;
+ modules = g_slist_append(modules, module);
}
- return NULL;
-}
-
-#ifdef HAVE_GMODULE
-static char *module_get_name(const char *path, int *start, int *end)
-{
- const char *name;
- char *module_name, *ptr;
+ file = module_file_find(module, submodule);
+ if (file != NULL)
+ return file;
- name = NULL;
- if (g_path_is_absolute(path)) {
- name = strrchr(path, G_DIR_SEPARATOR);
- if (name != NULL) name++;
- }
+ file = g_new0(MODULE_FILE_REC, 1);
+ file->root = module;
+ file->name = g_strdup(submodule);
+ file->defined_module_name = g_strdup(defined_module_name);
- if (name == NULL)
- name = path;
-
- if (strncmp(name, "lib", 3) == 0)
- name += 3;
-
- module_name = g_strdup(name);
- ptr = strchr(module_name, '.');
- if (ptr != NULL) *ptr = '\0';
-
- *start = (int) (name-path);
- *end = *start + (ptr == NULL ? strlen(name) :
- (int) (ptr-module_name));
-
- return module_name;
+ module->files = g_slist_append(module->files, file);
+ return file;
}
-static GModule *module_open(const char *name)
+MODULE_REC *module_find(const char *name)
{
- struct stat statbuf;
- GModule *module;
- char *path, *str;
-
- if (g_path_is_absolute(name) ||
- (*name == '.' && name[1] == G_DIR_SEPARATOR))
- path = g_strdup(name);
- else {
- /* first try from home dir */
- str = g_strdup_printf("%s/modules", get_irssi_dir());
- path = g_module_build_path(str, name);
- g_free(str);
-
- if (stat(path, &statbuf) == 0) {
- module = g_module_open(path, (GModuleFlags) 0);
- g_free(path);
- return module;
- }
-
- /* module not found from home dir, try global module dir */
- g_free(path);
- path = g_module_build_path(MODULEDIR, name);
- }
-
- module = g_module_open(path, (GModuleFlags) 0);
- g_free(path);
- return module;
-}
-
-#define module_error(error, module, text) \
- signal_emit("module error", 3, GINT_TO_POINTER(error), module, text)
+ GSList *tmp;
-static int module_load_name(const char *path, const char *name, int silent)
-{
- void (*module_init) (void);
- GModule *gmodule;
- MODULE_REC *rec;
- char *initfunc;
-
- gmodule = module_open(path);
- if (gmodule == NULL) {
- if (!silent) {
- module_error(MODULE_ERROR_LOAD, name,
- g_module_error());
- }
- return FALSE;
- }
+ for (tmp = modules; tmp != NULL; tmp = tmp->next) {
+ MODULE_REC *rec = tmp->data;
- /* get the module's init() function */
- initfunc = g_strconcat(name, "_init", NULL);
- if (!g_module_symbol(gmodule, initfunc, (gpointer *) &module_init)) {
- if (!silent)
- module_error(MODULE_ERROR_INVALID, name, NULL);
- g_module_close(gmodule);
- g_free(initfunc);
- return FALSE;
+ if (g_strcasecmp(rec->name, name) == 0)
+ return rec;
}
- g_free(initfunc);
-
- rec = g_new0(MODULE_REC, 1);
- rec->name = g_strdup(name);
- rec->gmodule = gmodule;
- modules = g_slist_append(modules, rec);
- module_init();
- settings_check_module(name);
-
- signal_emit("module loaded", 1, rec);
- return TRUE;
+ return NULL;
}
-#endif
-/* Load module - automatically tries to load also the related non-core
- modules given in `prefixes' (like irc, fe, fe_text, ..) */
-int module_load(const char *path, char **prefixes)
+MODULE_FILE_REC *module_file_find(MODULE_REC *module, const char *name)
{
-#ifdef HAVE_GMODULE
- GString *realpath;
- char *name, *pname;
- int ret, start, end;
-
- g_return_val_if_fail(path != NULL, FALSE);
-
- if (!g_module_supported())
- return FALSE;
+ GSList *tmp;
- name = module_get_name(path, &start, &end);
- if (module_find(name)) {
- module_error(MODULE_ERROR_ALREADY_LOADED, name, NULL);
- g_free(name);
- return FALSE;
- }
+ for (tmp = module->files; tmp != NULL; tmp = tmp->next) {
+ MODULE_FILE_REC *rec = tmp->data;
- /* load "module_core" instead of "module" if it exists */
- realpath = g_string_new(path);
- g_string_insert(realpath, end, "_core");
-
- pname = g_strconcat(name, "_core", NULL);
- ret = module_load_name(realpath->str, pname, TRUE);
- g_free(pname);
-
- if (!ret) {
- /* load "module" - complain if it's not found */
- ret = module_load_name(path, name, FALSE);
- } else if (prefixes != NULL) {
- /* load all the "prefix modules", like the fe-common, irc,
- etc. part of the module */
- while (*prefixes != NULL) {
- g_string_assign(realpath, path);
- g_string_insert(realpath, start, "_");
- g_string_insert(realpath, start, *prefixes);
-
- pname = g_strconcat(*prefixes, "_", name, NULL);
- module_load_name(realpath->str, pname, TRUE);
- g_free(pname);
-
- prefixes++;
- }
+ if (strcmp(rec->name, name) == 0)
+ return rec;
}
- g_string_free(realpath, TRUE);
- g_free(name);
- return ret;
-#else
- return FALSE;
-#endif
-}
-
-void module_unload(MODULE_REC *module)
-{
-#ifdef HAVE_GMODULE
- void (*module_deinit) (void);
- char *deinitfunc;
-
- g_return_if_fail(module != NULL);
-
- modules = g_slist_remove(modules, module);
-
- signal_emit("module unloaded", 1, module);
-
- /* call the module's deinit() function */
- deinitfunc = g_strconcat(module->name, "_deinit", NULL);
- if (g_module_symbol(module->gmodule, deinitfunc,
- (gpointer *) &module_deinit))
- module_deinit();
- g_free(deinitfunc);
-
- settings_remove_module(module->name);
- commands_remove_module(module->name);
- signals_remove_module(module->name);
-
- g_module_close(module->gmodule);
- g_free(module->name);
- g_free(module);
-#endif
+ return NULL;
}
static void uniq_get_modules(char *key, void *value, GSList **list)