# HG changeset patch # User Tero Marttila # Date 1237152177 -7200 # Node ID ce1accba5fc7494746e4d1d1767a5ad0c8dfa212 # Parent 94237000045071b7f98d46aa382423d670af0667 slight cleanup to move module funcs to a 'struct module_funcs' diff -r 942370000450 -r ce1accba5fc7 src/error.c --- a/src/error.c Sun Mar 15 23:01:12 2009 +0200 +++ b/src/error.c Sun Mar 15 23:22:57 2009 +0200 @@ -48,9 +48,9 @@ { ERR_INVALID_NICK_LENGTH, "Nickname is too long", ERR_EXTRA_NONE }, { _ERR_INVALID, NULL, 0 } }, _module_error_desc[] = { - { ERR_MODULE_OPEN, "module dlopen() failed", ERR_EXTRA_NONE }, + { ERR_MODULE_OPEN, "module dlopen() failed", ERR_EXTRA_STR }, { ERR_MODULE_NAME, "invalid module name", ERR_EXTRA_NONE }, - { ERR_MODULE_INIT_FUNC, "invalid module init func", ERR_EXTRA_NONE }, + { ERR_MODULE_INIT_FUNC, "invalid module init func", ERR_EXTRA_STR }, { ERR_MODULE_CONF, "module_conf", ERR_EXTRA_STR }, { _ERR_INVALID, NULL, 0 } }; diff -r 942370000450 -r ce1accba5fc7 src/error.h --- a/src/error.h Sun Mar 15 23:01:12 2009 +0200 +++ b/src/error.h Sun Mar 15 23:22:57 2009 +0200 @@ -181,5 +181,6 @@ /** Same as above, but also do a 'goto error' */ #define JUMP_SET_ERROR(err_info_ptr, err_code) do { SET_ERROR(err_info_ptr, err_code); goto error; } while (0) #define JUMP_SET_ERROR_INFO(err_info_ptr, from_ptr) do { SET_ERROR_INFO(err_info_ptr, from_ptr); goto error; } while (0) +#define JUMP_SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); goto error; } while (0) #endif diff -r 942370000450 -r ce1accba5fc7 src/irc_log.c --- a/src/irc_log.c Sun Mar 15 23:01:12 2009 +0200 +++ b/src/irc_log.c Sun Mar 15 23:22:57 2009 +0200 @@ -1,23 +1,27 @@ -#include "irc_log.h" +#include "module.h" +#include "irc_chan.h" +#include "error.h" #include "log.h" +#include #include +#include // XXX: fix this err_t crap #define LIB_ERR_H #include /** - * The core irc_log state + * The irc_log module state */ -static struct irc_log_ctx { +struct irc_log_ctx { /** The nexus this module is loaded for */ struct nexus *nexus; /** The database connection */ struct evsql *db; -} _ctx; +}; static void on_chan_msg (struct irc_chan *chan, const struct irc_nm *source, const char *message, void *arg) { @@ -33,27 +37,27 @@ .on_msg = on_chan_msg, }; -void* irc_log_init (struct modules *modules, struct error_info *err) +static err_t irc_log_init (struct nexus *nexus, void **ctx_ptr, struct error_info *err) { struct irc_log_ctx *ctx; - - (void) modules; - (void) err; - - // XXX: static pointer - ctx = &_ctx; + + // allocate + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) + return SET_ERROR(err, ERR_CALLOC); // initialize memset(ctx, 0, sizeof(*ctx)); // store - ctx->nexus = modules->nexus; + ctx->nexus = nexus; // ok - return ctx; + *ctx_ptr = ctx; + + return SET_ERROR(err, SUCCESS); } -err_t irc_log_conf (void *mod_ctx, const char *name, char *value, struct error_info *err) +static err_t irc_log_conf (void *mod_ctx, const char *name, char *value, struct error_info *err) { struct irc_log_ctx *ctx = mod_ctx; @@ -90,3 +94,10 @@ return SUCCESS; } +/** + * The module function table + */ +struct module_funcs irc_log_funcs = { + .init = &irc_log_init, + .conf = &irc_log_conf, +}; diff -r 942370000450 -r ce1accba5fc7 src/irc_log.h --- a/src/irc_log.h Sun Mar 15 23:01:12 2009 +0200 +++ b/src/irc_log.h Sun Mar 15 23:22:57 2009 +0200 @@ -1,27 +1,1 @@ -#ifndef IRC_LOG_H -#define IRC_LOG_H - -/** - * @file - * - * Module for logging IRC events to an SQL database - */ -#include "module.h" -#include "error.h" -#include "irc_chan.h" -#include -/** - * Initialize the irc_log module to use the given configuration - */ -void* irc_log_init (struct modules *modules, struct error_info *err); - -/** - * Set one of the config options: - * - * db_info - the database connection string - * channel - the '/' to log - */ -err_t irc_log_conf (void *mod_ctx, const char *name, char *value, struct error_info *err); - -#endif diff -r 942370000450 -r ce1accba5fc7 src/module.c --- a/src/module.c Sun Mar 15 23:01:12 2009 +0200 +++ b/src/module.c Sun Mar 15 23:22:57 2009 +0200 @@ -27,24 +27,22 @@ } /** - * Load the symbol named "_", + * Load the symbol named "_". */ static err_t module_symbol (struct module *module, void **sym, const char *suffix) { char sym_name[MODULE_SYMBOL_MAX]; // validate the length of the suffix + assert(strlen(module->info.name) <= MODULE_NAME_MAX); assert(strlen(suffix) <= MODULE_SUFFIX_MAX); // format sprintf(sym_name, "%s_%s", module->info.name, suffix); // load - if ((*sym = dlsym(module->handle, sym_name)) == NULL) { - log_error("dlsym(%s, %s) failed: %s", module->info.name, sym_name, dlerror()); - - return ERR_MODULE_SYM; - } + if ((*sym = dlsym(module->handle, sym_name)) == NULL) + return ERR_MODULE_SYM; // ok return SUCCESS; @@ -53,7 +51,6 @@ err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err) { struct module *module; - module_init_func_t init_func; // validate the module name if (strlen(info->name) > MODULE_NAME_MAX) @@ -65,29 +62,21 @@ // store module->info = *info; - module->modules = modules; // clear dlerrors (void) dlerror(); // load it - if ((module->handle = dlopen(info->path, RTLD_NOW)) == NULL) { - log_error("dlopen(%s) failed: %s", info->path, dlerror()); - - JUMP_SET_ERROR(err, ERR_MODULE_OPEN); - } + if ((module->handle = dlopen(info->path, RTLD_NOW)) == NULL) + JUMP_SET_ERROR_STR(err, ERR_MODULE_OPEN, dlerror()); - // load the init symbol - if ((ERROR_CODE(err) = module_symbol(module, (void *) &init_func, "init"))) - JUMP_SET_ERROR(err, ERR_MODULE_INIT_FUNC); + // load the funcs symbol + if ((ERROR_CODE(err) = module_symbol(module, (void **) &module->funcs, "funcs"))) + JUMP_SET_ERROR_STR(err, ERROR_CODE(err), dlerror()); - // call it - if ((module->ctx = init_func(modules, err)) == NULL) { - // ensure that this results in a valid error return code! - assert(ERROR_CODE(err)); - + // call the init func + if ((module->funcs->init(modules->nexus, &module->ctx, err))) goto error; - } // add to modules list TAILQ_INSERT_TAIL(&modules->list, module, modules_list); @@ -106,16 +95,6 @@ err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err) { - module_conf_func_t conf_func; - - // load the conf symbol - if ((ERROR_CODE(err) = module_symbol(module, (void *) &conf_func, "conf"))) - return ERROR_CODE(err); - - // call it - if (conf_func(module->ctx, name, value, err)) - return ERROR_CODE(err); - - // ok - return SUCCESS; + // call the conf func + return module->funcs->conf(module->ctx, name, value, err); } diff -r 942370000450 -r ce1accba5fc7 src/module.h --- a/src/module.h Sun Mar 15 23:01:12 2009 +0200 +++ b/src/module.h Sun Mar 15 23:22:57 2009 +0200 @@ -27,6 +27,36 @@ }; /** + * A module's behaviour is defined as a set of function pointers, which is dynamically resolved from the module DSO, + * using the _funcs symbol. + */ +struct module_funcs { + /** + * Initialize the module, returning an opaque context pointer that is stored in the module state, and supplied for + * subsequent calls. The supplied nexus arg can be used to access the global state. + * + * @param nexus a pointer to the nexus struct containing the global state + * @param ctx_ptr the context pointer should be returned via this + * @param err returned error info + */ + err_t (*init) (struct nexus *nexus, void **ctx_ptr, struct error_info *err); + + /** + * Set a configuration option with the given name and value, given by the user. Configuration settings are not + * regarded as unique-per-name, but rather, several invocations of 'conf' with the same name and different values + * could set up a multitude of things. + * + * XXX: make value a non-modifyable string + * + * @param ctx the module's context pointer as returned by init + * @param name the name of the configuration setting + * @param value the value of the configuration setting + * @param err returned error info + */ + err_t (*conf) (void *ctx, const char *name, char *value, struct error_info *err); +}; + +/** * A loaded module. */ struct module { @@ -36,12 +66,12 @@ /** The dlopen handle */ void *handle; + /** The resolved function table */ + struct module_funcs *funcs; + /** The module context object */ void *ctx; - /** Pointer back to the modules struct used to load this */ - struct modules *modules; - /** Our entry in the list of modules */ TAILQ_ENTRY(module) modules_list; }; @@ -70,24 +100,6 @@ ERR_MODULE_CONF, ///< value error in configuration data }; -/** - * Module initialization function type - * - * @param modules the module-loading context, containing the nexus - * @param err returned error info - * @return context pointer, or NULL on errors - */ -typedef void* (*module_init_func_t) (struct modules *modules, struct error_info *err); - -/** - * Module configuration function type - * - * @param ctx the module's context pointer - * @param name the name of the configuration setting - * @param value the value of the configuration setting - * @return error code - */ -typedef err_t (*module_conf_func_t) (void *ctx, const char *name, char *value, struct error_info *err); /** * Maximum length of a module name diff -r 942370000450 -r ce1accba5fc7 src/nexus.h --- a/src/nexus.h Sun Mar 15 23:01:12 2009 +0200 +++ b/src/nexus.h Sun Mar 15 23:22:57 2009 +0200 @@ -4,6 +4,9 @@ /** * A nexus is the central brain of the application; the place where the main() method is implemented */ + +struct nexus; + #include #include "module.h" #include "irc_client.h"