--- a/lua.c Sat May 19 23:44:25 2012 +0300
+++ b/lua.c Sun May 20 06:24:50 2012 +0300
@@ -1499,18 +1499,9 @@
lua_pop (L, 1);
}
-#if 0
// OPTION GUARDS
-GSList *lua_installed_guards = NULL;
-
-typedef struct {
- lua_State *L; // lua environment for handler use
- int nameref; // reference to key name string
- int cbref; // reference to guard function
-// int objref; // self_reference to object
- guint hid; // hook id for object destruction
-} lua_guard_t;
+#define MLUA_GUARD_REGISTRY "mcabber_guards"
/// guard function
/// Function to be called, when option changes it's value.
@@ -1519,115 +1510,92 @@
/// R: string (value to save in hash table)
static gchar *lua_guard_cb (const gchar *key, const gchar *value)
{
- lua_guard_t *cb = ;// FIXME
- lua_State *L = cb -> L;
+ lua_State *L = lua; // FIXME
- if (cb -> cbref == LUA_NOREF)
- return g_strdup (value);
-
- lua_rawgeti (L, LUA_REGISTRYINDEX, cb -> cbref);
- if (!lua_isfunction (L, -1)) {
- lua_pop (L, 1);
- return g_strdup (value);
+ lua_getfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY ); // +1
+ lua_getfield ( L, -1, key ); // +2
+ if ( ! lua_isfunction ( L, -1 ) ) {
+ lua_pop ( L, 2 );
+ return g_strdup ( value );
}
- lua_pushstring (L, key);
- lua_psuhstring (L, value);
+ lua_pushstring ( L, key ); // +3
+ lua_pushstring ( L, value ); // +4
- if (lua_pcall (L, 2, 1, 0)) {
- scr_log_print (LPRINT_NORMAL, "lua: Error in hook handler: %s", lua_tostring (L, -1));
- lua_pop (L, 1);
- return g_strdup (value);
+ if ( lua_pcall ( L, 2, 1, 0 ) ) { // +2
+ scr_log_print ( LPRINT_NORMAL, "lua: Error in hook handler: %s", lua_tostring ( L, -1 ) );
+ lua_pop ( L, 2 );
+ return g_strdup ( value );
+ } else {
+ gchar *result = g_strdup ( lua_tostring ( L, -1 ) );
+ lua_pop ( L, 2 );
+ return result;
}
-
- return g_strdup (lua_tostring (L, -1));
}
-/// main.guard
-/// Installs option guard for given option. Returns guard object, that
-/// should be kept around as long, as guard is needed.
-/// A: string (option name), guard function
-/// R: userdata (guard object)
-static int lua_main_guard (lua_State *L)
+/// main.add_guard
+/// Installs option guard for given option.
+/// A: string ( option name ), guard function
+/// R: boolean ( success )
+static int lua_main_add_guard ( lua_State *L )
{
- const char *name = luaL_checkstring (L, 1);
- int priority = G_PRIORITY_DEFAULT;
- lua_guard_t *cb;
+ const char *name = luaL_checkstring ( L, 1 );
+ luaL_argcheck ( L, lua_isfunction (L, 2), 2, "function expected" );
+ lua_settop ( L, 2 );
- luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
-
- cb = lua_newuserdata (L, sizeof (lua_guard_t));
- luaL_getmetatable (L, "mcabber.guard");
- lua_setmetatable (L, -2);
-
- lua_pushvalue (L, 1);
- cb -> nameref = luaL_ref (L, LUA_REGISTRYINDEX);
- lua_pushvalue (L, 2);
- cb -> cbref = luaL_ref (L, LUA_REGISTRYINDEX);
- cb -> L = L;
-
- settings_set_guard (name, lua_guard_cb)
+ if ( settings_set_guard ( name, lua_guard_cb ) ) {
+ lua_getfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY );
+ lua_pushvalue ( L, 2 );
+ lua_setfield ( L, 3, name );
+ lua_pushboolean ( L, 1 );
+ } else
+ lua_pushboolean ( L, 0 );
return 1;
}
-static void lua_mcabber_unregister_guard (lua_State *L, lua_guard_t *cb)
-{
- const char *name;
-
- if (cb -> nameref == LUA_NOREF)
- return;
-
- lua_rawgeti (L, LUA_REGISTRYINDEX, cb -> nameref);
- name = lua_tostring (L, -1);
- if (name) {
- settings_del_guard (name);
- luaL_unref (L, LUA_REGISTRYINDEX, cb -> nameref);
- cb -> nameref = LUA_NOREF;
- }
-
- lua_pop (L, 1);
-}
-
-/// guard:del
-/// Unregisters given option guard from mcabber. Object will be destroyed later.
-static int lua_mcabber_guard_del (lua_State *L)
+/// main.del_guard
+/// Removes option guard from given option.
+/// By default, lua will refuse to remove guards, not installed
+/// by lua. Still, you can force guard removal.
+/// A: string ( option name ), boolean ( force removal )
+/// R: boolean ( success )
+static int lua_main_del_guard ( lua_State *L )
{
- lua_guard_t *cb = luaL_checkudata (L, 1, "mcabber.guard");
- luaL_argcheck (L, cb != NULL, 1, "mcabber guard object expected");
- lua_mcabber_unregister_guard (L, cb);
- return 0;
-}
+ const char *name = luaL_checkstring ( L, 1 );
+ lua_settop ( L, 2 );
+
+ lua_getfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY );
+ lua_getfield ( L, 3, name );
-static int lua_mcabber_guard_gc (lua_State *L)
-{
- lua_hook_t *cb = luaL_checkudata (L, 1, "mcabber.guard");
- luaL_argcheck (L, cb != NULL, 1, "mcabber guard object expected");
- lua_mcabber_unregister_guard (L, cb);
- if (cb -> cbref != LUA_NOREF)
- luaL_unref (L, LUA_REGISTRYINDEX, cb -> cbref);
- return 0;
+ if ( ! lua_isnil ( L, 4 ) || lua_toboolean ( L, 2 ) ) {
+ settings_del_guard ( name );
+ lua_pushnil ( L );
+ lua_setfield ( L, 3, name );
+ lua_pushboolean ( L, 1 );
+ } else
+ lua_pushboolean ( L, 0 );
+
+ return 1;
}
-static const luaL_Reg lua_mcabber_hook_reg_m[] = {
- { "del", lua_mcabber_guard_del },
- { "__gc", lua_mcabber_guard_gc },
- { NULL, NULL },
-};
-
static void lua_guard_init (lua_State *L)
{
- luaL_newmetatable (L, "mcabber.guard");
- lua_pushvalue (L, -1);
- lua_setfield (L, -2, "__index");
- luaL_register (L, NULL, lua_mcabber_guard_reg_m);
- lua_pop (L, 1);
+ lua_createtable ( L, 0, 0 );
+ lua_setfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY );
}
static void lua_guard_uninit (lua_State *L)
{
+ lua_getfield ( L, LUA_REGISTRYINDEX, MLUA_GUARD_REGISTRY );
+ lua_pushnil ( L );
+ while ( lua_next ( L, -2 ) ) {
+ const char *key = lua_tostring ( L, -2 );
+ settings_del_guard ( key );
+ lua_pop ( L, 1 );
+ }
+ lua_pop ( L, 1 );
}
-#endif
// MAIN INITIALIZATION CODE
@@ -1719,6 +1687,8 @@
reg ( timer )
reg ( bgread )
reg ( hook )
+ reg ( add_guard )
+ reg ( del_guard )
{ NULL, NULL },
};
#undef reg
@@ -1776,6 +1746,7 @@
lua_hook_init (lua);
lua_command_init (lua);
+ lua_guard_init (lua);
{
char *initfile = expand_filename (settings_opt_get ("lua_init_filename"));
@@ -1803,7 +1774,7 @@
}
}
-static void lua_events_cancel (gpointer data, gpointer ignore)
+static void lua_events_destroy ( gpointer data )
{
lua_event_callback_t *cb = data;
const char *evid;
@@ -1812,38 +1783,29 @@
lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->evid);
evid = lua_tostring (cb ->L, -1);
evs_callback (evid, EVS_CONTEXT_CANCEL, "Module unloading");
+ evs_del (evid); // XXX before these were two different runs. is there some reason for that?
}
-static void lua_events_destroy (gpointer data, gpointer ignore)
+static void lua_bgreads_destroy ( gpointer data )
{
- lua_event_callback_t *cb = data;
- const char *evid;
- if (cb->evid == LUA_NOREF)
- return;
- lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->evid);
- evid = lua_tostring (cb ->L, -1);
- evs_del (evid);
+ g_source_remove ( ( gulong ) data );
}
-static void lua_bgreads_destroy (guint source, gpointer ignore)
+static void lua_timers_destroy ( gpointer data )
{
- g_source_remove (source);
+ g_source_remove ( ( gulong ) data );
}
-static void lua_timers_destroy (guint source, gpointer ignore)
+static void lua_features_destroy ( gpointer data )
{
- g_source_remove (source);
-}
-
-static void lua_features_destroy (char *xmlns, gpointer ignore)
-{
+ gchar *xmlns = data;
xmpp_del_feature (xmlns);
g_free (xmlns);
}
-static void lua_categories_destroy (guint id, gpointer ignore)
+static void lua_categories_destroy ( gpointer data )
{
- compl_del_category (id);
+ compl_del_category ( ( gulong ) data );
}
void mlua_uninit (void)
@@ -1856,23 +1818,17 @@
// hook handlers and commands will be unregistered upon objects destruction
- g_slist_foreach (lua_bgreads, (GFunc) lua_bgreads_destroy, NULL);
- g_slist_free (lua_bgreads);
+ lua_guard_uninit ( lua );
+
+ g_slist_free_full ( lua_bgreads, lua_bgreads_destroy );
lua_bgreads = NULL;
- g_slist_foreach (lua_timers, (GFunc) lua_timers_destroy, NULL);
- g_slist_free (lua_timers);
+ g_slist_free_full ( lua_timers, lua_timers_destroy );
lua_timers = NULL;
- g_slist_foreach (lua_events, (GFunc) lua_events_cancel, NULL);
- g_slist_foreach (lua_events, (GFunc) lua_events_destroy, NULL);
- g_slist_free (lua_events);
+ g_slist_free_full ( lua_events, lua_events_destroy );
lua_events = NULL;
- g_slist_foreach (lua_added_features, (GFunc) lua_features_destroy, NULL);
- g_slist_free (lua_added_features);
- lua_added_features = NULL;
-
#ifdef MCABBER_API_HAVE_CMD_ID
cmd_del (lua_cmdid);
lua_cmdid = NULL;
@@ -1883,8 +1839,10 @@
lua_close (lua);
lua = NULL;
- g_slist_foreach (lua_added_categories, (GFunc) lua_categories_destroy, NULL);
- g_slist_free (lua_added_categories);
+ g_slist_free_full ( lua_added_features, lua_features_destroy );
+ lua_added_features = NULL;
+
+ g_slist_free_full ( lua_added_categories, lua_categories_destroy );
lua_added_categories = NULL;
#ifdef LLM_LOG_HANDLER