all options are now fully implemented
authorTero Marttila <terom@fixme.fi>
Mon, 16 Mar 2009 01:14:36 +0200
changeset 66 ef8c9d7daf62
parent 65 d7508879ad01
child 67 aa94bf2b5f9b
all options are now fully implemented
src/irc_log.c
src/module.c
src/module.h
src/nexus.c
--- a/src/irc_log.c	Mon Mar 16 01:03:41 2009 +0200
+++ b/src/irc_log.c	Mon Mar 16 01:14:36 2009 +0200
@@ -74,14 +74,14 @@
            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) 
-            RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid '<network>/<channel>' value");
+            RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid '<network>:<channel>' value");
 
         // get the channel?
         if ((chan = irc_client_get_chan(ctx->nexus->client, network, channel)) == NULL)
@@ -92,8 +92,7 @@
             return ERROR_CODE(err);
 
     } else {
-        return -1;
-
+        RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown configuration option");
     }
 
     // ok
--- a/src/module.c	Mon Mar 16 01:03:41 2009 +0200
+++ b/src/module.c	Mon Mar 16 01:14:36 2009 +0200
@@ -94,6 +94,21 @@
     return ERROR_CODE(err);    
 }
 
+struct module* module_get (struct modules *modules, const char *name)
+{
+    struct module *module = NULL;
+
+    // look for it...
+    TAILQ_FOREACH(module, &modules->list, modules_list) {
+        if (strcasecmp(module->info.name, name) == 0)
+            // found it
+            return module;
+    }
+
+    // no such module
+    return NULL;
+}
+
 err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err)
 {
     // call the conf func
--- a/src/module.h	Mon Mar 16 01:03:41 2009 +0200
+++ b/src/module.h	Mon Mar 16 01:14:36 2009 +0200
@@ -46,7 +46,8 @@
      * 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
+     * The given value is either a NUL-terminated string value (which may be mutated, using e.g. strsep), or NULL if
+     * no value was given (flag option).
      *
      * @param ctx the module's context pointer as returned by init
      * @param name the name of the configuration setting
@@ -132,6 +133,15 @@
 err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err);
 
 /**
+ * Lookup a module by name
+ *
+ * @param modules the modules state
+ * @param name the module name to get
+ * @return the module struct, or NULL if not found
+ */
+struct module* module_get (struct modules *modules, const char *name);
+
+/**
  * Set a module configuration option
  */
 err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err);
--- a/src/nexus.c	Mon Mar 16 01:03:41 2009 +0200
+++ b/src/nexus.c	Mon Mar 16 01:14:36 2009 +0200
@@ -93,9 +93,9 @@
             RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "unrecognized flag for --network");
     }
 
+    // create the net
     log_info("add network '%s' at '%s:%s'", info.network, info.hostname, info.service);
 
-    // create the net
     if (irc_client_add_net(nexus->client, NULL, &info, err))
         return ERROR_CODE(err);
 
@@ -129,9 +129,9 @@
     if ((net = irc_client_get_net(nexus->client, network)) == NULL)
         RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "unknown network for --channel");
     
+    // add the channel
     log_info("add channel '%s' on network '%s'", info.channel, net->info.network);
 
-    // add the channel
     if (irc_net_add_chan(net, NULL, &info, err))
         return ERROR_CODE(err);
 
@@ -161,9 +161,9 @@
     if (opt)
         RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "trailing values for --channel");
     
+    // load it
     log_info("loading module '%s' from path '%s'", info.name, info.path);
 
-    // load it
     if (module_load(nexus->modules, &module, &info, err))
         return ERROR_CODE(err);
 
@@ -172,6 +172,39 @@
 }
 
 /**
+ * Parse and apply a --config option, calling the module's conf func.
+ */
+static err_t apply_config (struct nexus *nexus, char *opt, struct error_info *err)
+{
+    struct module *module;
+    const char *module_name, *conf_name;
+    char *conf_value;
+
+    // parse the required fields
+    if ((module_name = strsep(&opt, ":")) == NULL)
+        RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "missing <module> field for --config");
+
+    if ((conf_name = strsep(&opt, ":")) == NULL)
+        RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "missing <name> field for --config");
+
+    // value is the rest of the data, might be NULL
+    conf_value = opt;
+
+    // lookup the module
+    if ((module = module_get(nexus->modules, module_name)) == NULL)
+        RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "unknown module for --config");
+    
+    // do the config
+    log_info("applying module '%s' config name '%s' with value: %s", module->info.name, conf_name, conf_value);
+
+    if (module_conf(module, conf_name, conf_value, err))
+        return ERROR_CODE(err);
+
+    // ok
+    return SUCCESS;
+}
+
+/**
  * Parse arguments and apply them to the given nexus
  */
 static err_t parse_args (struct nexus *nexus, int argc, char **argv, struct error_info *err)
@@ -206,7 +239,10 @@
                 break;
 
             case OPT_CONFIG:
-                RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "option unimplemented");
+                if (apply_config(nexus, optarg, err))
+                    return ERROR_CODE(err);
+
+                break;
 
             case '?':
                 usage(argv[0]);