compiling, working, but still ugly module code modules
authorTero Marttila <terom@fixme.fi>
Sun, 15 Mar 2009 23:01:12 +0200
branchmodules
changeset 56 942370000450
parent 55 6f7f6ae729d0
child 57 ce1accba5fc7
compiling, working, but still ugly module code
Makefile
src/error.c
src/error.h
src/irc_log.c
src/irc_log.h
src/module.c
src/module.h
src/nexus.c
--- a/Makefile	Sun Mar 15 01:17:22 2009 +0200
+++ b/Makefile	Sun Mar 15 23:01:12 2009 +0200
@@ -34,12 +34,12 @@
 # modules
 module_objs = $(patsubst src/%.c,obj/%.o,$(wildcard src/$(1)/*.c))
 
-CORE_OBJS = obj/error.o obj/log.o obj/chain.o
+CORE_OBJS = obj/error.o obj/log.o
 SOCK_OBJS = obj/sock.o obj/sock_tcp.o
 SOCK_TEST_OBJS = obj/sock_test.o
 SOCK_GNUTLS_OBJS = obj/sock_gnutls.o
 LINEPROTO_OBJS = obj/line_proto.o
-IRC_OBJS = obj/irc_line.o obj/irc_conn.o obj/irc_net.o obj/irc_chan.o obj/irc_cmd.o obj/irc_proto.o obj/irc_client.o
+IRC_OBJS = obj/irc_line.o obj/irc_conn.o obj/irc_net.o obj/irc_chan.o obj/chain.o obj/irc_cmd.o obj/irc_proto.o obj/irc_client.o
 NEXUS_OBJS = obj/signals.o obj/module.o
 IRC_LOG_OBJS = obj/irc_log.o
 
@@ -54,11 +54,11 @@
 
 bin/test: ${CORE_OBJS} ${SOCK_OBJS} ${SOCK_GNUTLS_OBJS} ${SOCK_TEST_OBJS} ${LINEPROTO_OBJS} ${IRC_OBJS}
 
-modules/irc_log.so: ${CORE_OBJS} ${IRC_OBJS}
+modules/irc_log.so: ${CORE_OBJS}
 
 # computed
-CFLAGS = ${MODE_CFLAGS} ${FIXED_CFLAGS} ${LIBEVENT_CFLAGS} ${GNUTLS_CFLAGS} ${EVSQL_CFLAGS}
-LDFLAGS = ${LIBEVENT_LDFLAGS} ${GNUTLS_LDFLAGS} ${EVSQL_LDFLAGS}
+CFLAGS = ${MODE_CFLAGS} ${FIXED_CFLAGS} ${LIBEVENT_CFLAGS} ${GNUTLS_CFLAGS} ${EVSQL_CFLAGS} -fpic 
+LDFLAGS = ${LIBEVENT_LDFLAGS} ${GNUTLS_LDFLAGS} ${EVSQL_LDFLAGS} -Wl,--export-dynamic
 
 # XXX: is this valid?
 CPPFLAGS = ${CFLAGS}
@@ -92,13 +92,13 @@
 
 # XXX: removed $(CPPFLAGS) 
 obj/%.o : src/%.c
-	$(CC) -fpic -c $(CFLAGS) $< -o $@
+	$(CC) -c $(CFLAGS) $< -o $@
 
 bin/% : obj/%.o
 	$(CC) $(LDFLAGS) $+ $(LOADLIBES) $(LDLIBS) -o $@
 
 modules/%.so : obj/%.o
-	$(CC) -shared -Wl,-soname,$(basename %@) -o $@ $+ -lc
+	$(CC) -shared -Wl,-soname,$(notdir $@) -o $@ $+ -lc
 
 # documentation
 DOXYGEN_PATH = /usr/bin/doxygen
--- a/src/error.c	Sun Mar 15 01:17:22 2009 +0200
+++ b/src/error.c	Sun Mar 15 23:01:12 2009 +0200
@@ -51,6 +51,7 @@
     {   ERR_MODULE_OPEN,                    "module dlopen() failed",                   ERR_EXTRA_NONE      },
     {   ERR_MODULE_NAME,                    "invalid module name",                      ERR_EXTRA_NONE      },
     {   ERR_MODULE_INIT_FUNC,               "invalid module init func",                 ERR_EXTRA_NONE      },
+    {   ERR_MODULE_CONF,                    "module_conf",                              ERR_EXTRA_STR       },
     {   _ERR_INVALID,                       NULL,                                       0                   }
 };
 
@@ -132,6 +133,11 @@
                 snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gnutls_strerror(err->extra));
                 break;
             
+            case ERR_EXTRA_STR:
+                // static error message string
+                snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, err->extra_str);
+                break;
+
             default:
                 // ???
                 snprintf(msg, ERROR_MSG_MAXLEN, "%s: %#.8x", desc->name, err->extra);
--- a/src/error.h	Sun Mar 15 01:17:22 2009 +0200
+++ b/src/error.h	Sun Mar 15 23:01:12 2009 +0200
@@ -29,6 +29,9 @@
 
     /** GnuTLS, using gnutls_strerror() */
     ERR_EXTRA_GNUTLS,
+
+    /** Static error message string */
+    ERR_EXTRA_STR,
 };
 
 /**
@@ -47,10 +50,10 @@
     ERR_GETADDRINFO,
     ERR_GETADDRINFO_EMPTY, 
     
-    /** @see enum sock_error_code*/
+    /** @see sock_error_code*/
     _ERR_SOCK       = 0x000300,
 
-    /** @see enum sock_gnutls_error_code */
+    /** @see sock_gnutls_error_code */
     _ERR_GNUTLS     = 0x000400,
 
     /** Libevent errors */
@@ -78,7 +81,7 @@
     _ERR_IRC_NET    = 0x000900,
     ERR_IRC_NET_QUIT_STATE,
 
-    /** modul errors */
+    /** @see module_error_code */
     _ERR_MODULE     = 0x000a00,
 };
 
@@ -102,9 +105,14 @@
 struct error_info {
     /** The base error code */
     err_t code;
+    
+    union {
+        /** Additional detail info, usually some third-party error code, as defined by the code's ERR_EXTRA_* */
+        int extra;
 
-    /** Additional detail info, usually some third-party error code, as defined by the code's ERR_EXTRA_* */
-    int extra;
+        /** Additional info, stored as a pointer to a static string (note how dangerous this is) */
+        const char *extra_str;
+    };
 };
 
 /**
@@ -153,6 +161,13 @@
 #define _SET_ERROR_ERRNO(err_info_ptr, err_code) _SET_ERROR_EXTRA(err_info_ptr, err_code, errno);
 #define SET_ERROR_ERRNO(err_info_ptr, err_code) SET_ERROR_EXTRA(err_info_ptr, err_code, errno);
 
+/** 
+ * Set error_info.code to err_code, and .extra_str to str. The given string pointer should remain valid while the error
+ * is being handled down-stack.
+ */
+#define _SET_ERROR_STR(err_info_ptr, err_code, err_str) (err_info_ptr)->code = (err_code); (err_info_ptr)->extra_str = (err_str)
+#define SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); } while(0)
+
 /** Set error_info from another error_info. Evaluates to the new error_info */
 #define SET_ERROR_INFO(err_info_ptr, from_ptr) (*err_info_ptr = *from_ptr)
 
@@ -161,6 +176,7 @@
 #define RETURN_SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) do { _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra); return (err_code); } while (0)
 #define RETURN_SET_ERROR_ERRNO(err_info_ptr, err_code) do { _SET_ERROR_ERRNO(err_info_ptr, err_code); return (err_code); } while (0)
 #define RETURN_SET_ERROR_INFO(err_info_ptr, from_ptr) do { SET_ERROR_INFO(err_info_ptr, from_ptr); return (from_ptr->code); } while (0)
+#define RETURN_SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); return (err_code); } while (0)
 
 /** 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)
--- a/src/irc_log.c	Sun Mar 15 01:17:22 2009 +0200
+++ b/src/irc_log.c	Sun Mar 15 23:01:12 2009 +0200
@@ -11,6 +11,9 @@
  * The core irc_log state
  */
 static struct irc_log_ctx {
+    /** The nexus this module is loaded for */
+    struct nexus *nexus;
+
     /** The database connection */
     struct evsql *db;
 
@@ -40,40 +43,43 @@
     // XXX: static pointer
     ctx = &_ctx;
 
+    // initialize
+    memset(ctx, 0, sizeof(*ctx));
+
+    // store
+    ctx->nexus = modules->nexus;
+
     // ok
     return ctx;
 }
 
-err_t irc_log_conf (struct module *module, const char *name, char *value)
+err_t irc_log_conf (void *mod_ctx, const char *name, char *value, struct error_info *err)
 {
-    struct irc_log_ctx *ctx = module->ctx;
-    struct nexus *nexus = module->modules->nexus;
-    err_t err;
+    struct irc_log_ctx *ctx = mod_ctx;
 
     if (strcmp(name, "db_info") == 0) {
         log_info("connect to database: %s", value);
 
-        if ((ctx->db = evsql_new_pq(nexus->ev_base, value, NULL, NULL)) == NULL)
+        if ((ctx->db = evsql_new_pq(ctx->nexus->ev_base, value, NULL, NULL)) == NULL)
            return ERR_EVSQL_NEW_PQ;
 
     } else if (strcmp(name, "channel") == 0) {
-        const char *network = strsep(&value, ":");
+        const char *network = strsep(&value, "/");
         const char *channel = value;
 
         struct irc_chan *chan;
         
         // kill missing tokens
         if (!network || !channel) 
-            // XXX: need to fix the error crap
-            return -1;
+            RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid '<network>/<channel>' value");
 
         // get the channel?
-        if ((chan = irc_client_get_chan(nexus->client, network, channel)) == NULL)
-            return -1;
+        if ((chan = irc_client_get_chan(ctx->nexus->client, network, channel)) == NULL)
+            RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown channel name");
 
         // add channel callbacks
-        if ((err = irc_chan_add_callbacks(chan, &_chan_callbacks, ctx)))
-            return err;
+        if ((ERROR_CODE(err) = irc_chan_add_callbacks(chan, &_chan_callbacks, ctx)))
+            return ERROR_CODE(err);
 
     } else {
         return -1;
--- a/src/irc_log.h	Sun Mar 15 01:17:22 2009 +0200
+++ b/src/irc_log.h	Sun Mar 15 23:01:12 2009 +0200
@@ -20,8 +20,8 @@
  * Set one of the config options:
  *
  *  db_info     - the database connection string
- *  channel     - the network:channel to log
+ *  channel     - the '<network>/<channel>' to log
  */
-err_t irc_log_conf (struct module *module, const char *name, char *value);
+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 01:17:22 2009 +0200
+++ b/src/module.c	Sun Mar 15 23:01:12 2009 +0200
@@ -82,8 +82,12 @@
         JUMP_SET_ERROR(err, ERR_MODULE_INIT_FUNC);
 
     // call it
-    if ((module->ctx = init_func(modules, err)))
+    if ((module->ctx = init_func(modules, err)) == NULL) {
+        // ensure that this results in a valid error return code!
+        assert(ERROR_CODE(err));
+
         goto error;
+    }
 
     // add to modules list
     TAILQ_INSERT_TAIL(&modules->list, module, modules_list);
@@ -100,18 +104,17 @@
     return ERROR_CODE(err);    
 }
 
-err_t module_conf (struct module *module, const char *name, char *value)
+err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err)
 {
     module_conf_func_t conf_func;
-    err_t err;
 
     // load the conf symbol
-    if ((err = module_symbol(module, (void *) &conf_func, "conf")))
-        return err;
+    if ((ERROR_CODE(err) = module_symbol(module, (void *) &conf_func, "conf")))
+        return ERROR_CODE(err);
 
     // call it
-    if ((err = conf_func(module, name, value)))
-        return err;
+    if (conf_func(module->ctx, name, value, err))
+        return ERROR_CODE(err);
 
     // ok
     return SUCCESS;
--- a/src/module.h	Sun Mar 15 01:17:22 2009 +0200
+++ b/src/module.h	Sun Mar 15 23:01:12 2009 +0200
@@ -67,6 +67,7 @@
     ERR_MODULE_NAME,        ///< invalid module_info.name
     ERR_MODULE_SYM,         ///< invalid symbol
     ERR_MODULE_INIT_FUNC,   ///< invalid module_init_func_t
+    ERR_MODULE_CONF,        ///< value error in configuration data
 };
 
 /**
@@ -86,7 +87,7 @@
  * @param value the value of the configuration setting
  * @return error code
  */
-typedef err_t (*module_conf_func_t) (struct module *module, const char *name, char *value);
+typedef err_t (*module_conf_func_t) (void *ctx, const char *name, char *value, struct error_info *err);
 
 /**
  * Maximum length of a module name
@@ -111,12 +112,12 @@
 /**
  * Load a new module
  */
-err_t module_load (struct modules *modules, struct module **module, const struct module_info *info, struct error_info *err);
+err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err);
 
 /**
  * Set a module configuration option
  */
-err_t module_conf (struct module *module, const char *name, char *value);
+err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err);
 
 /**
  * Unload a module
--- a/src/nexus.c	Sun Mar 15 01:17:22 2009 +0200
+++ b/src/nexus.c	Sun Mar 15 23:01:12 2009 +0200
@@ -181,18 +181,20 @@
 
         // get the channel
         if (log_chan_info.channel) {
+            char conf_channel[] = "default/#test";
+
             // create the channel
             if ((irc_net_add_chan(net, &log_chan_info)) == NULL)
                 FATAL("irc_net_add_chan");
 
             // configure it
             // XXX: hardcoded
-            if ((ERROR_CODE(&err) = module_conf(mod_irc_log, "channel", "default/#test")))
-                FATAL_ERROR(&err, "module_conf(irc_log, '%s', '%s)", "channel", "default/#test");
+            if (module_conf(mod_irc_log, "channel", conf_channel, &err))
+                FATAL_ERROR(&err, "module_conf(irc_log, '%s', '%s)", "channel", conf_channel);
         }
 
         // configure the databse info
-        if (log_db_info && (ERROR_CODE(&err) = module_conf(mod_irc_log, "db_info", log_db_info)))
+        if (log_db_info && module_conf(mod_irc_log, "db_info", log_db_info, &err))
             FATAL_ERROR(&err, "module_conf(irc_log, 'db_info', '%s')", log_db_info);
     }