slight cleanup to move module funcs to a 'struct module_funcs' modules
authorTero Marttila <terom@fixme.fi>
Sun, 15 Mar 2009 23:22:57 +0200
branchmodules
changeset 57 ce1accba5fc7
parent 56 942370000450
child 58 65bd90f94f4e
slight cleanup to move module funcs to a 'struct module_funcs'
src/error.c
src/error.h
src/irc_log.c
src/irc_log.h
src/module.c
src/module.h
src/nexus.h
--- 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                   }
 };
--- 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
--- 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 <stdlib.h>
 #include <string.h>
 
+#include <event2/event.h>
 // XXX: fix this err_t crap
 #define LIB_ERR_H
 #include <evsql.h>
 
 /**
- * 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,
+};
--- 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 <event2/event.h>
 
-/**
- * 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 '<network>/<channel>' to log
- */
-err_t irc_log_conf (void *mod_ctx, const char *name, char *value, struct error_info *err);
-
-#endif
--- 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 "<module>_<suffix>", 
+ * Load the symbol named "<module>_<suffix>".
  */ 
 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);
 }
--- 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 <mod_name>_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
--- 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 <event2/event.h>
 #include "module.h"
 #include "irc_client.h"