diff options
author | Timo Sirainen <cras@irssi.org> | 2001-08-14 00:41:59 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2001-08-14 00:41:59 +0000 |
commit | 803d8050164eaaefdd52fd4ae967c1e038b3c571 (patch) | |
tree | 615ff88add7d3682beebed692f41f5135c799713 /src/core/modules.c | |
parent | f584c1013c74a98bfb43b79280c4ee20b775970a (diff) | |
download | irssi-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.c | 219 |
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) |