--- 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?