--- a/lua.c Fri Oct 12 21:24:44 2012 +0300
+++ b/lua.c Sat Oct 13 20:57:03 2012 +0300
@@ -1403,6 +1403,55 @@
return ret;
}
+/// main.hook_run
+/// Runs handlers for given hook with supplied arguments.
+/// A: string (hook name), table (hook arguments)
+/// R: return enum field (hook handler result)
+static int lua_main_hook_run ( lua_State *L )
+{
+ const char * hook_name = luaL_checkstring ( L, 1 );
+ int num = 1;
+ hk_arg_t * args;
+ guint ret;
+ lua_settop ( L, 2 ); // 1 name, 2 args_in
+ luaL_argcheck ( L, lua_type ( L, 2 ) == LUA_TTABLE, 2, "table with hook arguments expected" );
+ // count fields, build temporary stringified table
+ lua_newtable ( L ); // 3 args
+ lua_pushnil ( L ); // 4 key
+ while ( lua_next ( L, 2 ) != 0 ) { // 5 value
+ int ktype = lua_type ( L, 4 );
+ if ( ktype == LUA_TSTRING || ktype == LUA_TNUMBER ) {
+ int vtype = lua_type ( L, 5 );
+ if ( vtype == LUA_TSTRING || vtype == LUA_TNUMBER ) {
+ lua_pushvalue ( L, 4 ); // 6 key copy
+ lua_pushvalue ( L, 5 ); // 7 value copy
+ lua_tostring ( L, 6 );
+ lua_tostring ( L, 7 );
+ lua_settable ( L, 3 ); // 5 value
+ num ++;
+ }
+ }
+ lua_pop ( L, 1 ); // 4 key
+ }
+ // alloc args, populate from temporary table
+ args = luaL_malloc ( L, num * sizeof ( hk_arg_t ) );
+ num = 0;
+ lua_pushnil ( L ); // 4 key
+ while ( lua_next ( L, 3 ) != 0 ) { // 5 value
+ ( args + num ) -> name = lua_tostring ( L, 4 );
+ ( args + num ) -> value = lua_tostring ( L, 5 );
+ num ++;
+ lua_pop ( L, 1 ); // 4 key
+ }
+ ( args + num ) -> name = NULL;
+ ( args + num ) -> value = NULL;
+ // run hook
+ ret = hk_run_handlers ( hook_name, args );
+ luaL_free ( L, args );
+ luaL_pushenum ( L, ret, lua_hook_handler_result );
+ return 1;
+}
+
/// main.hook
/// Installs hook handler, returns an object, that you need to keep until
/// hook handling is no more needed.
@@ -1681,6 +1730,7 @@
reg ( timer )
reg ( bgread )
reg ( hook )
+ reg ( hook_run )
reg ( add_guard )
reg ( del_guard )
{ NULL, NULL },