--- a/main.c Mon Feb 23 04:05:05 2009 +0200
+++ b/main.c Mon Feb 23 17:05:43 2009 +0200
@@ -6,6 +6,7 @@
#include <lualib.h>
#include <stdio.h>
#include <stdlib.h> // getenv
+#include <string.h> // strcmp
#include "util.h"
#include "logprint.h" // scr_LogPrint
@@ -152,72 +153,6 @@
return 1;
}
-/// main.add_feature
-/// Adds xmlns to disco#info features list.
-/// A: string (xmlns)
-static int lua_main_add_feature (lua_State *L)
-{
- xmpp_add_feature (luaL_checkstring (L, 1));
- return 0;
-}
-
-/// main.del_feature
-/// Removes xmlns from disco#info features list.
-/// A: stirng (xmlns)
-static int lua_main_del_feature (lua_State *L)
-{
- xmpp_del_feature (luaL_checkstring (L, 1));
- return 0;
-}
-
-typedef struct {
- int reference;
- lua_State *L;
-} lua_command_callback_t;
-
-/// command function
-/// Function to handle newly registered command.
-/// A: string (arguments)
-void lua_main_command_handler (char *args, lua_command_callback_t *cb)
-{
- lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
- lua_pushstring (cb->L, args);
- if (lua_pcall (cb->L, 1, 0, 0)) {
- scr_LogPrint (LPRINT_LOGNORM, "lua: Command execution error: %s", lua_tostring (cb->L, -1));
- lua_pop (cb->L, 1);
- }
-}
-
-/// main.add_command
-/// Associates mcabber command name with lua function.
-/// A: string (command name), command function
-static int lua_main_add_command (lua_State *L)
-{
- const char *name = luaL_checkstring (L, 1);
- lua_command_callback_t *cb;
- luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
-
- cb = luaL_malloc (L, sizeof (lua_command_callback_t));
- cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
- cb->L = L;
- cmd_add (name, "", 0, 0, (void (*) (char *p)) lua_main_command_handler, cb);
- return 0;
-}
-
-/// main.del_command
-/// Removes command from a list of commands.
-/// A: string (command name)
-static int lua_main_del_command (lua_State *L)
-{
- const char *name = luaL_checkstring (L, 1);
- lua_command_callback_t *cb = cmd_del (name);
- if (cb) {
- luaL_unref (L, LUA_REGISTRYINDEX, cb->reference);
- luaL_free (L, cb);
- }
- return 0;
-}
-
/// main.print_info
/// Prints a system message to buddy's window.
/// A: string (jid), string (message)
@@ -347,6 +282,94 @@
return 1;
}
+// XMPP DISCO FEATURES
+
+GSList *lua_added_features = NULL;
+
+/// main.add_feature
+/// Adds xmlns to disco#info features list.
+/// A: string (xmlns)
+static int lua_main_add_feature (lua_State *L)
+{
+ const char *xmlns = luaL_checkstring (L, 1);
+ xmpp_add_feature (xmlns);
+ lua_added_features = g_slist_prepend (lua_added_features, g_strdup (xmlns));
+ return 0;
+}
+
+/// main.del_feature
+/// Removes xmlns from disco#info features list.
+/// A: stirng (xmlns)
+static int lua_main_del_feature (lua_State *L)
+{
+ const char *xmlns = luaL_checkstring (L, 1);
+ GSList *el = g_slist_find_custom (lua_added_features, xmlns, (GCompareFunc) strcmp);
+ xmpp_del_feature (xmlns);
+ if (el) {
+ g_free (el->data);
+ lua_added_features = g_slist_delete_link (lua_added_features, el);
+ }
+ return 0;
+}
+
+// MCABBER COMMANDS
+
+typedef struct {
+ int reference;
+ lua_State *L;
+} lua_command_callback_t;
+
+static GSList *lua_added_commands = NULL;
+
+/// command function
+/// Function to handle newly registered command.
+/// A: string (arguments)
+void lua_main_command_handler (char *args, lua_command_callback_t *cb)
+{
+ lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
+ lua_pushstring (cb->L, args);
+ if (lua_pcall (cb->L, 1, 0, 0)) {
+ scr_LogPrint (LPRINT_LOGNORM, "lua: Command execution error: %s", lua_tostring (cb->L, -1));
+ lua_pop (cb->L, 1);
+ }
+}
+
+/// main.add_command
+/// Associates mcabber command name with lua function.
+/// A: string (command name), command function
+static int lua_main_add_command (lua_State *L)
+{
+ const char *name = luaL_checkstring (L, 1);
+ lua_command_callback_t *cb;
+ luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
+
+ cb = luaL_malloc (L, sizeof (lua_command_callback_t));
+ cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
+ cb->L = L;
+ cmd_add (name, "", 0, 0, (void (*) (char *p)) lua_main_command_handler, cb);
+ lua_added_commands = g_slist_prepend (lua_added_commands, g_strdup (name));
+ return 0;
+}
+
+/// main.del_command
+/// Removes command from a list of commands.
+/// A: string (command name)
+static int lua_main_del_command (lua_State *L)
+{
+ const char *name = luaL_checkstring (L, 1);
+ GSList *el = g_slist_find_custom (lua_added_commands, name, (GCompareFunc) strcmp);
+ lua_command_callback_t *cb = cmd_del (name);
+ if (cb) {
+ luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
+ luaL_free (cb->L, cb);
+ }
+ if (el) {
+ g_free (el->data);
+ lua_added_commands = g_slist_delete_link (lua_added_commands, el);
+ }
+ return 0;
+}
+
// TIMER
#define LUA_TIMER_PRIORITY ( G_PRIORITY_HIGH_IDLE )
@@ -595,6 +618,22 @@
return NULL;
}
+static void lua_features_destroy (char *xmlns, gpointer ignore)
+{
+ xmpp_del_feature (xmlns);
+ g_free (xmlns);
+}
+
+static void lua_commands_destroy (char *name, gpointer ignore)
+{
+ lua_command_callback_t *cb = cmd_del (name);
+ if (cb) {
+ luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
+ luaL_free (cb->L, cb);
+ }
+ g_free (name);
+}
+
void g_module_unload (GModule *module)
{
if (lua) {
@@ -605,9 +644,17 @@
scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook_quit: %s", lua_tostring (lua, -1));
lua_pop (lua, 1);
}
-
+
hk_del_handler ((hk_handler_t) lua_hook, lua);
+ g_slist_foreach (lua_added_features, (GFunc) lua_features_destroy, NULL);
+ g_slist_free (lua_added_features);
+ lua_added_features = NULL;
+
+ g_slist_foreach (lua_added_commands, (GFunc) lua_commands_destroy, NULL);
+ g_slist_free (lua_added_commands);
+ lua_added_commands = NULL;
+
lua_close (lua);
lua = NULL;
}