add nexus_lua_error for unified LUA_ERR* -> ERR_LUA_* mapping, and lua configuration support
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config.lua Wed Apr 01 01:41:08 2009 +0300
@@ -0,0 +1,59 @@
+local conf = {
+ log_level = "DEBUG",
+
+ name = {
+ nickname = "SpBotDev",
+ username = "spbot-dev",
+ realname = "SpBot (development version)"
+ },
+
+ networks = {
+ PVLNet = {
+ hostname = "irc.fixme.fi",
+
+ channels = {
+ "#test"
+ }
+ },
+ },
+
+ modules = {
+ irc_log = {
+ path = "src/modules/mod_irc_log.so",
+
+ conf = {
+ db_info = "dbname=spbot",
+ channel = "PVLNet/#test",
+ }
+ }
+ },
+}
+
+-- apply general
+log_level(conf.log_level)
+
+-- apply conf_name
+client:set_defaults(conf.name.nickname, conf.name.username, conf.name.realname)
+
+-- apply conf_networks
+for network, settings in pairs(conf.networks) do
+ -- establish the irc_net
+ net = client:connect(network, settings.hostname)
+
+ -- join each channel
+ for i, channel in ipairs(settings.channels) do
+ net:join(channel)
+ end
+end
+
+-- apply conf_modules
+for name, settings in pairs(conf.modules) do
+ -- load the module
+ module = modules:load(name, settings.path)
+
+ -- apply confs
+ for key, value in pairs(settings.conf) do
+ module:conf(key, value)
+ end
+end
+
--- a/src/CMakeLists.txt Wed Apr 01 00:57:34 2009 +0300
+++ b/src/CMakeLists.txt Wed Apr 01 01:41:08 2009 +0300
@@ -12,7 +12,7 @@
set (CORE_SOURCES error.c log.c)
set (SOCK_SOURCES sock.c sock_tcp.c sock_gnutls.c sock_test.c line_proto.c)
set (IRC_SOURCES irc_line.c irc_conn.c irc_net.c irc_chan.c chain.c irc_cmd.c irc_proto.c irc_client.c irc_user.c irc_queue.c)
-set (LUA_SOURCES nexus_lua.c lua_objs.c)
+set (LUA_SOURCES nexus_lua.c lua_objs.c lua_config.c)
set (CONSOLE_SOURCES console.c lua_console.c)
set (NEXUS_SOURCES nexus.c ${CORE_SOURCES} ${SOCK_SOURCES} ${IRC_SOURCES} ${LUA_SOURCES} ${CONSOLE_SOURCES} signals.c module.c config.c)
--- a/src/error.c Wed Apr 01 00:57:34 2009 +0300
+++ b/src/error.c Wed Apr 01 01:41:08 2009 +0300
@@ -77,10 +77,11 @@
{ _ERR_INVALID, NULL, 0 }
}, _lua_error_desc[] = {
- { ERR_LUA_MEM, "lua: out of memory", ERR_EXTRA_NONE },
- { ERR_LUA_SYNTAX, "lua: syntax error", ERR_EXTRA_NONE },
- { ERR_LUA_RUN, "lua: runtime error", ERR_EXTRA_NONE },
- { ERR_LUA_ERR, "lua: error handling error", ERR_EXTRA_NONE },
+ { ERR_LUA_MEM, "lua: out of memory", ERR_EXTRA_STR },
+ { ERR_LUA_SYNTAX, "lua: syntax error", ERR_EXTRA_STR },
+ { ERR_LUA_RUN, "lua: runtime error", ERR_EXTRA_STR },
+ { ERR_LUA_ERR, "lua: error handling error", ERR_EXTRA_STR },
+ { ERR_LUA_FILE, "lua: error loading file", ERR_EXTRA_STR },
{ _ERR_INVALID, NULL, 0 }
};
--- a/src/error.h Wed Apr 01 00:57:34 2009 +0300
+++ b/src/error.h Wed Apr 01 01:41:08 2009 +0300
@@ -99,6 +99,7 @@
ERR_LUA_SYNTAX,
ERR_LUA_RUN,
ERR_LUA_ERR,
+ ERR_LUA_FILE,
/** irc_chan errors */
_ERR_IRC_CHAN = 0x000d00,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lua_config.c Wed Apr 01 01:41:08 2009 +0300
@@ -0,0 +1,16 @@
+#include "lua_config.h"
+
+#include <lua5.1/lauxlib.h>
+
+err_t lua_config_load (struct nexus_lua *lua, const char *path, struct error_info *err)
+{
+ // just use luaL_loadfile and translate the error code
+ if (nexus_lua_error(lua->st, luaL_loadfile(lua->st, path), err))
+ // XXX: pollute the stack
+ return ERROR_CODE(err);
+
+ // execute it
+ // XXX; error handler with debug info
+ return nexus_lua_error(lua->st, lua_pcall(lua->st, 0, 0, 0), err);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lua_config.h Wed Apr 01 01:41:08 2009 +0300
@@ -0,0 +1,19 @@
+#ifndef LUA_CONFIG_H
+#define LUA_CONFIG_H
+
+/**
+ * @file
+ *
+ * Read a lua configuration file into a nexus_lua state
+ */
+#include "error.h"
+#include "nexus_lua.h"
+
+/**
+ * Load a lua config file at the given path into the nexus's lua state.
+ *
+ * Path can also be given as NULL to load from stdin.
+ */
+err_t lua_config_load (struct nexus_lua *lua, const char *path, struct error_info *err);
+
+#endif /* LUA_CONFIG_H */
--- a/src/lua_console.c Wed Apr 01 00:57:34 2009 +0300
+++ b/src/lua_console.c Wed Apr 01 01:41:08 2009 +0300
@@ -30,31 +30,16 @@
error:
if (ret) {
- const char *error = lua_tostring(L, -1);
-
- switch (ret) {
- case LUA_ERRSYNTAX:
- log_error("syntax error: %s", error);
- break;
-
- case LUA_ERRRUN:
- log_error("runtime error: %s", error);
- break;
+ struct error_info err;
+
+ // build the error_info
+ nexus_lua_error(L, ret, &err);
- case LUA_ERRMEM:
- log_error("memory allocation error: %s", error);
- break;
-
- case LUA_ERRERR:
- log_error("error handling error: %s", error);
- break;
+ // log it
+ log_error("%s", error_msg(&err));
- default:
- log_error("unknown error: %s", error);
- break;
- };
-
- lua_pop(L, 1);
+ // pop it
+ lua_pop(L, -1);
}
}
--- a/src/lua_objs.c Wed Apr 01 00:57:34 2009 +0300
+++ b/src/lua_objs.c Wed Apr 01 01:41:08 2009 +0300
@@ -589,15 +589,9 @@
return 0;
}
-err_t lua_objs_init (struct nexus_lua *lua)
+err_t lua_objs_init (struct nexus_lua *lua, struct error_info *err)
{
// call in protected mode
- switch (lua_cpcall(lua->st, &_lua_objs_init, lua->nexus)) {
- case 0: return SUCCESS;
- case LUA_ERRRUN: return ERR_LUA_RUN;
- case LUA_ERRMEM: return ERR_LUA_MEM;
- case LUA_ERRERR: return ERR_LUA_ERR;
- default: return ERR_UNKNOWN;
- }
+ return nexus_lua_error(lua->st, lua_cpcall(lua->st, &_lua_objs_init, lua->nexus), err);
}
--- a/src/lua_objs.h Wed Apr 01 00:57:34 2009 +0300
+++ b/src/lua_objs.h Wed Apr 01 01:41:08 2009 +0300
@@ -11,6 +11,6 @@
/**
* Registers our lua runtime objects into the given lua state
*/
-err_t lua_objs_init (struct nexus_lua *lua);
+err_t lua_objs_init (struct nexus_lua *lua, struct error_info *err);
#endif /* LUA_OBJS_H */
--- a/src/nexus.c Wed Apr 01 00:57:34 2009 +0300
+++ b/src/nexus.c Wed Apr 01 01:41:08 2009 +0300
@@ -1,5 +1,5 @@
#include "nexus.h"
-#include "signals.h"
+#include "lua_config.h"
#include "log.h"
#include <stdlib.h>
@@ -16,15 +16,16 @@
OPT_HELP = 'h',
OPT_DEFAULTS = 'D',
OPT_NETWORK = 'n',
- OPT_CHANNEL = 'c',
OPT_MODULE = 'm',
- OPT_CONFIG = 'C',
+ OPT_CONF = 'C',
OPT_DEBUG = 'd',
+ OPT_CONFIG = 'c',
/** Options without short names */
_OPT_EXT_BEGIN = 0x00ff,
OPT_CONSOLE,
+ OPT_CHANNEL,
};
/**
@@ -36,13 +37,19 @@
{"network", 1, NULL, OPT_NETWORK },
{"channel", 1, NULL, OPT_CHANNEL },
{"module", 1, NULL, OPT_MODULE },
- {"config", 1, NULL, OPT_CONFIG },
+ {"conf", 1, NULL, OPT_CONF },
{"debug", 0, NULL, OPT_DEBUG },
{"console", 0, NULL, OPT_CONSOLE },
+ {"config", 1, NULL, OPT_CONFIG },
{0, 0, 0, 0 },
};
/**
+ * Short command-line option defintion
+ */
+const char *short_options = "hn:c:m:C:d";
+
+/**
* Display --help output on stdout.
*
* If nexus is given, --config options for loaded modules are also listed
@@ -54,10 +61,11 @@
printf(" --help / -h display this message\n");
printf(" --defaults / -D set the IRC client default info using '<nickname>:<username>:<realname>'\n");
printf(" --network / -n add an IRC network using '<name>:<hostname>[:<port>[:ssl]]' format\n");
- printf(" --channel / -c add an IRC channel using '<network>:<channel>' format\n");
+ printf(" --channel add an IRC channel using '<network>:<channel>' format\n");
printf(" --module / -m add a module using '<name>:<path>' format\n");
printf(" --config / -C add a module configuration option using '<mod_name>:<name>[:<value>]' format\n");
printf(" --debug / -d set logging level to DEBUG\n");
+ printf(" --config / -c load a Lua config file from '<path>'\n");
printf(" --console use the interactive console\n");
// dump loaded module configs
@@ -232,9 +240,9 @@
}
/**
- * Parse and apply a --config option, calling the module's conf func.
+ * Parse and apply a --conf option, calling the module's conf func.
*/
-static err_t apply_config (struct nexus *nexus, char *opt, struct error_info *err)
+static err_t apply_conf (struct nexus *nexus, char *opt, struct error_info *err)
{
struct module *module;
const char *module_name, *conf_name;
@@ -294,6 +302,16 @@
}
/**
+ * Load the lua config file from \a path
+ */
+static err_t apply_config (struct nexus *nexus, char *path, struct error_info *err)
+{
+ log_info("loading lua config from %s", path);
+
+ return lua_config_load(nexus->lua, path, err);
+}
+
+/**
* 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)
@@ -301,7 +319,7 @@
int opt, option_index;
// parse options
- while ((opt = getopt_long(argc, argv, "hn:c:m:C:", options, &option_index)) != -1) {
+ while ((opt = getopt_long(argc, argv, short_options, options, &option_index)) != -1) {
switch (opt) {
case OPT_HELP:
usage(nexus, argv[0]);
@@ -333,8 +351,8 @@
break;
- case OPT_CONFIG:
- if (apply_config(nexus, optarg, err))
+ case OPT_CONF:
+ if (apply_conf(nexus, optarg, err))
return ERROR_CODE(err);
break;
@@ -348,6 +366,12 @@
return ERROR_CODE(err);
break;
+
+ case OPT_CONFIG:
+ if (apply_config(nexus, optarg, err))
+ return ERROR_CODE(err);
+
+ break;
case '?':
usage(nexus, argv[0]);
--- a/src/nexus_lua.c Wed Apr 01 00:57:34 2009 +0300
+++ b/src/nexus_lua.c Wed Apr 01 01:41:08 2009 +0300
@@ -27,7 +27,7 @@
luaL_openlibs(lua->st);
// then our own things
- if ((ERROR_CODE(err) = lua_objs_init(lua)))
+ if (lua_objs_init(lua, err))
goto error;
// ok
@@ -48,3 +48,18 @@
free(lua);
}
+
+err_t nexus_lua_error (lua_State *L, int ret, struct error_info *err)
+{
+ const char *error = lua_tostring(L, -1);
+
+ switch (ret) {
+ case 0: RETURN_SET_ERROR(err, SUCCESS);
+ case LUA_ERRSYNTAX: RETURN_SET_ERROR_STR(err, ERR_LUA_SYNTAX, error);
+ case LUA_ERRRUN: RETURN_SET_ERROR_STR(err, ERR_LUA_RUN, error);
+ case LUA_ERRMEM: RETURN_SET_ERROR_STR(err, ERR_LUA_MEM, error);
+ case LUA_ERRERR: RETURN_SET_ERROR_STR(err, ERR_LUA_ERR, error);
+ case LUA_ERRFILE: RETURN_SET_ERROR_STR(err, ERR_LUA_FILE, error);
+ default: RETURN_SET_ERROR_EXTRA(err, ERR_UNKNOWN, ret);
+ };
+}
--- a/src/nexus_lua.h Wed Apr 01 00:57:34 2009 +0300
+++ b/src/nexus_lua.h Wed Apr 01 01:41:08 2009 +0300
@@ -31,4 +31,13 @@
*/
void nexus_lua_destroy (struct nexus_lua *lua);
+/**
+ * Handle a Lua error by converting the given error code into a ERR_LUA_* code, inspecting the error object at
+ * the top of the stack.
+ *
+ * Please note that the resulting error_info points into strings inside the lua stack - once you pop the error, the
+ * error_info might not be valid anymore.
+ */
+err_t nexus_lua_error (lua_State *L, int ret, struct error_info *err);
+
#endif /* NEXUS_LUA_H */