fix up lua_module_conf/config_* enough so that logwatch_conf_filter works
authorTero Marttila <terom@fixme.fi>
Sat, 11 Apr 2009 01:54:33 +0300
changeset 124 f18d69425c4f
parent 123 dc80e4599fb8
child 125 5c70fb2d6793
fix up lua_module_conf/config_* enough so that logwatch_conf_filter works
src/config.c
src/lua_objs.c
src/modules/logwatch.c
src/modules/logwatch_filter.c
--- a/src/config.c	Fri Apr 10 22:46:05 2009 +0300
+++ b/src/config.c	Sat Apr 11 01:54:33 2009 +0300
@@ -81,7 +81,7 @@
         
         case CONFIG_USER:
             // fail
-            return SET_ERROR_STR(err, ERR_CONFIG_TYPE, "user type can't be parsed");
+            RETURN_SET_ERROR_STR(err, ERR_CONFIG_TYPE, "user type can't be parsed");
 
         default:
             NOT_REACHED();
@@ -107,33 +107,30 @@
     return config_parse_param(param, nexus, value, raw_value, err);
 }
 
-err_t config_check_param (const struct config_param *param, const struct config_value *value, struct error_info *err)
-{
-    // no value given?
-    if (!value || !value->type)
-        RETURN_SET_ERROR_STR(err, ERR_CONFIG_REQUIRED, param->name);
-
-    // wrong type?
-    if (param->type != value->type)
-        // XXX: info about type names
-        return SET_ERROR(err, ERR_CONFIG_TYPE);
-
-    // ok
-    return SUCCESS;
-}
-
 err_t config_apply_opt (const struct config_option *option, void *ctx, const struct config_value values[], struct error_info *err)
 {
     const struct config_param *param;
     const struct config_value *value;
 
     // handle each param
-    for (param = option->params, value = values; param->name && param->type; param++, value++) {
-        // check the given value
-        if (config_check_param(param, value, err))
-            goto error;
-        
-        if (param->is_handler) {
+    for (param = option->params, value = values; param->name && param->type; param++) {
+        // no value given, or value given as NULL?
+        if (!value->type || value->type == CONFIG_NULL) {
+            if (param->optional) {
+                // optional, so just ignore the value 
+                
+            } else {
+                // required
+                JUMP_SET_ERROR_STR(err, ERR_CONFIG_REQUIRED, param->name);
+
+            }
+
+        } else if (param->type != value->type) {
+            // invalid type, XXX: also report correct type name?
+            JUMP_SET_ERROR(err, ERR_CONFIG_TYPE);
+
+        } else if (param->is_handler) {
+            // only applicable for non-optional args
             err_t tmp;
             
             // invoke the handler
@@ -147,6 +144,10 @@
             if (tmp)
                 goto error;
         }
+        
+        // the values list is NULL-terminated, and optional params can be left off
+        if (value->type)
+            value++;
     }
 
     // the option's handler?
@@ -212,14 +213,28 @@
     return config_apply_opt(option, ctx, value, err);
 }
 
+/**
+ * Look up an option's param by name, returning NULL if not found
+ */
+static const struct config_param* config_get_param (const struct config_option *option, const char *name)
+{
+    const struct config_param *param;
+
+    for (param = option->params; param->name && param->type; param++)
+        if (strcmp(param->name, name) == 0)
+            return param;
+    
+    // not found
+    return NULL;
+}
+
 const struct config_value* config_get_value (const struct config_option *option, const struct config_value values[], const char *name)
 {
     const struct config_param *param;
     const struct config_value *value;
-
-    // handle each param
+    
+    // go through the (param, value) pairs
     for (param = option->params, value = values; param->name && param->type && value->type; param++, value++) {
-        // matches?
         if (strcmp(param->name, name) == 0) {
             // not NULL?
             if (value->type != CONFIG_NULL)
--- a/src/lua_objs.c	Fri Apr 10 22:46:05 2009 +0300
+++ b/src/lua_objs.c	Sat Apr 11 01:54:33 2009 +0300
@@ -107,10 +107,12 @@
 {
     struct lua_module *lua_module = lua_obj_get_obj(L, __func__, "spbot.module");
     const struct config_option *option;
+    struct error_info err;
+    bool is_err = true;
+
+    // the list of given config values, and temporary storage for string values
     struct config_value values[CONFIG_VALUES_MAX], *value = values;
     char *value_bufs[CONFIG_VALUES_MAX], **value_buf = value_bufs;
-    struct error_info err;
-    bool is_err = true;
 
     // number of arguments given
     int nargs = lua_gettop(L), argidx = 2;
@@ -133,16 +135,23 @@
     int maxargs = config_params_count(option);
 
     // too many arguments?
-    if (nargs > maxargs)
-        return luaL_error(L, "lua_module_conf: too many arguments (>%d) given (%d)", maxargs, nargs - 3);
+    if (nargs - argidx > maxargs)
+        return luaL_error(L, "lua_module_conf: too many arguments (>%d) given (%d)", maxargs, nargs - argidx);
     
     // the current param
     const struct config_param *param = option->params;
 
-    // apply each given argument
+    // apply each given argument to the correct param, storing it in value
     for (; argidx <= nargs; argidx++, value++, param++) {
-        // the config value
+        // the given config value
         switch (lua_type(L, argidx)) {
+            case LUA_TNONE:
+            case LUA_TNIL:
+                // no value
+                value->type = CONFIG_NULL;
+
+                break;
+
             case LUA_TSTRING: {
                 // string arg
                 const char *arg_str = lua_tostring(L, argidx);
--- a/src/modules/logwatch.c	Fri Apr 10 22:46:05 2009 +0300
+++ b/src/modules/logwatch.c	Sat Apr 11 01:54:33 2009 +0300
@@ -97,9 +97,8 @@
     CONFIG_OPT_STRING(  "source_fifo",  logwatch_conf_source_fifo, "<path>",           "read lines from the fifo at the given path"    ),
 
     CONFIG_OPT(         "filter",       logwatch_conf_filter, 
-        "filter lines (from source, if given), using the given regular expression pattern (if given), "
-        "format output using the given format expression (if given), and finally send the filtered/formatted lines "
-        "to the given channel",
+        "filter lines from source (or all), using the given regular expression (or all lines), and format output "
+        "using the given format expression (or pass through directly), and finally send the output to the given channel",
 
         CONFIG_PARAM(       "name",    CONFIG_STRING,      "filter name",                              false   ),
         CONFIG_PARAM_USER(  "source",  "logwatch_source",  "optional logwatch_source to use",          true    ),
--- a/src/modules/logwatch_filter.c	Fri Apr 10 22:46:05 2009 +0300
+++ b/src/modules/logwatch_filter.c	Sat Apr 11 01:54:33 2009 +0300
@@ -23,7 +23,7 @@
     
     // compile the regexp
     // XXX: any flags?
-    if (pattern && (filter->regexp = pcre_compile(pattern, 0, &err_msg, &err_offset, NULL)))
+    if (pattern && (filter->regexp = pcre_compile(pattern, 0, &err_msg, &err_offset, NULL)) == NULL)
         JUMP_SET_ERROR_STR(err, ERR_PCRE_COMPILE, err_msg);
 
     // format?