Fixes and improvement
authorMyhailo Danylenko <isbear@ukrpost.net>
Mon, 23 Feb 2009 04:05:05 +0200
changeset 1 7d87d323c889
parent 0 65cbecad22b4
child 2 a88a395e6868
Fixes and improvement * style changed * documentation * various fixes * unregistering commands (see TODO)
CMakeLists.txt
TODO
config.h.in
docgen.pl
main.c
--- a/CMakeLists.txt	Sun Feb 22 23:14:24 2009 +0200
+++ b/CMakeLists.txt	Mon Feb 23 04:05:05 2009 +0200
@@ -4,7 +4,7 @@
 
 ## User options
 option(DEBUG "Enable debugging output" ON)
-option(MCABBER_INCLUDE_DIR "Path to mcabber include files" "/home/isbear/src/mcabber/hglm/mcabber/src")
+set(MCABBER_INCLUDE_DIR "/home/isbear/src/mcabber/hglm/mcabber/src" CACHE FILEPATH "Path to mcabber headers")
 
 ## Define targets
 add_library(mcabber-lua MODULE main.c util.c)
@@ -38,19 +38,20 @@
 find_package(PkgConfig REQUIRED)
 pkg_check_modules(GLIB REQUIRED glib-2.0)
 pkg_check_modules(GMODULE REQUIRED gmodule-2.0)
-#find_package(Perl)
+pkg_check_modules(LM REQUIRED loudmouth-1.0)
+find_package(Perl)
 
 ## Set up compiler
 configure_file(config.h.in config.h)
-include_directories(SYSTEM ${LUA_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS} ${GMODULE_INCLUDE_DIRS})
+include_directories(SYSTEM ${LUA_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS} ${GMODULE_INCLUDE_DIRS} ${LM_INCLUDE_DIRS})
 target_link_libraries(mcabber-lua ${LUA_LIBRARIES} ${GLIB_LIBRARIES} ${GMODULE_LIBRARIES})
 include_directories(${mcabber-lua_SOURCE_DIR} ${mcabber-lua_BINARY_DIR} ${MCABBER_INCLUDE_DIR})
 
 ## Extra targets
-#if(PERL_FOUND)
-#	add_custom_command(OUTPUT ${lua-lm_BINARY_DIR}/loudmouth.html COMMAND ${PERL_EXECUTABLE} ${lua-lm_SOURCE_DIR}/docgen.pl ${lua-lm_SOURCES} > ${lua-lm_BINARY_DIR}/loudmouth.html DEPENDS ${lua-lm_SOURCE_DIR}/docgen.pl ${lua-lm_SOURCES} WORKING_DIRECTORY ${lua-lm_SOURCE_DIR})
-#	add_custom_target(doc ALL DEPENDS ${lua-lm_BINARY_DIR}/loudmouth.html)
-#endif()
+if(PERL_FOUND)
+	add_custom_command(OUTPUT ${mcabber-lua_BINARY_DIR}/mcabber-lua.html COMMAND ${PERL_EXECUTABLE} ${mcabber-lua_SOURCE_DIR}/docgen.pl ${mcabber-lua_SOURCES} > ${mcabber-lua_BINARY_DIR}/mcabber-lua.html DEPENDS ${mcabber-lua_SOURCE_DIR}/docgen.pl ${mcabber-lua_SOURCES} WORKING_DIRECTORY ${mcabber-lua_SOURCE_DIR})
+	add_custom_target(doc ALL DEPENDS ${mcabber-lua_BINARY_DIR}/mcabber-lua.html)
+endif()
 #add_custom_target(test COMMAND env "LUA_PATH=${lua-lm_SOURCE_DIR}/?.lua;${LUA_PATH}" "LUA_CPATH=${lua-lm_SOURCE_DIR}/?.so;${lua-lm_BINARY_DIR}/?.so;${LUA_CPATH}" lua ${lua-lm_SOURCE_DIR}/test.lua DEPENDS loudmouth VERBATIM)
 #add_custom_target(test1 COMMAND env "LUA_PATH=${lua-lm_SOURCE_DIR}/?.lua;${LUA_PATH}" "LUA_CPATH=${lua-lm_SOURCE_DIR}/?.so;${lua-lm_BINARY_DIR}/?.so;${LUA_CPATH}" lua ${lua-lm_BINARY_DIR}/test.lua DEPENDS loudmouth VERBATIM)
 
@@ -58,9 +59,9 @@
 install(TARGETS mcabber-lua DESTINATION lib/mcabber)
 #install(FILES lm.lua DESTINATION share/lua/5.1)
 #install(FILES test.lua DESTINATION share/doc/${CPACK_PACKAGE_NAME}/examples)
-#if(PERL_FOUND)
-#	install(FILES ${lua-lm_BINARY_DIR}/loudmouth.html DESTINATION share/doc/${CPACK_PACKAGE_NAME})
-#endif()
+if(PERL_FOUND)
+	install(FILES ${mcabber-lua_BINARY_DIR}/mcabber-lua.html DESTINATION share/doc/${CPACK_PACKAGE_NAME})
+endif()
 install(FILES README DESTINATION share/doc/${CPACK_PACKAGE_NAME})
 install(FILES TODO DESTINATION share/doc/${CPACK_PACKAGE_NAME})
 install(FILES COPYING DESTINATION share/doc/${CPACK_PACKAGE_NAME})
--- a/TODO	Sun Feb 22 23:14:24 2009 +0200
+++ b/TODO	Mon Feb 23 04:05:05 2009 +0200
@@ -1,8 +1,8 @@
 
-improve global print to work on other types. or improve types :)
+print should allow other types to be printed
 finish roster list information
-implement dopath() thing instead of main.config_file()
 settings list?
 non-setting settings?
-...
+set package searching paths?
+register commands inside of lua object too, then unregister them on exit
 
--- a/config.h.in	Sun Feb 22 23:14:24 2009 +0200
+++ b/config.h.in	Mon Feb 23 04:05:05 2009 +0200
@@ -5,6 +5,9 @@
 // define this to enable debugging output
 #cmakedefine DEBUG
 
+// hack for mcabber headers
+#define MODULES_ENABLE
+
 #ifdef DEBUG
 #  include <stdio.h>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docgen.pl	Mon Feb 23 04:05:05 2009 +0200
@@ -0,0 +1,108 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+my %docs;
+my @tags;
+my $inside;
+my $harvest;
+my @values;
+
+foreach my $file (@ARGV) {
+	if ( not open SOURCE, '<', $file ) {
+		print STDERR "Cannot open $file\n";
+		next;
+	}
+
+	my $chunk = 0;
+
+	while (<SOURCE>) {
+		if ( $inside ) {
+			if ( not /^\/\/\// ) {
+				$inside = 0;
+				$chunk++;
+			} elsif ( /^\/\/\/ G:/ ) {
+				$inside = 0;
+				$harvest = 'V: ' . substr ( $_, 6 );
+			} else {
+				push @{$docs{$file}[$chunk]}, substr ( $_, 4 );
+			}
+		} elsif ( $harvest ) {
+			if ( /\{\s*NULL.*\}/ ) {
+				push @{$docs{$file}[$chunk]}, $harvest . ' ' . join ( ', ', @values );
+				$harvest = undef;
+				@values  = ();
+				$chunk++;
+			} elsif ( /\{\s*"(.+)".*\}/ ) {
+				push @values, $1;
+			}
+		} else {
+			next if not /^\/\/\//;
+
+			$inside = 1;
+			my $tag = substr $_, 4;
+			chomp $tag;
+			push @{$docs{$file}[$chunk]}, $tag;
+			# hack to allow twoword objects be written in text with spaces
+			# now it matches "lm message" instead of "lm message node" -.-
+			# and even if tag list will be reverse sorted by length,
+			# it will produce nested links...
+			# well, that all is now solved, but in not too impressive way..
+			$tag =~ s/_/./g;
+			push @tags, $tag;
+		}
+	}
+	
+	close SOURCE;
+}
+
+print <<HEADER
+<html>
+<head><title>lua-loudmouth docs</title></head>
+<body>
+HEADER
+;
+
+@tags = reverse sort { length $a <=> length $b } @tags;
+# TODO preserve original order
+foreach my $file ( sort keys %docs ) {
+	print "<hr>";
+	foreach my $chunk ( @{$docs{$file}} ) {
+		my $head = shift @$chunk;
+		my $tag  = $head;
+		my $list = undef;
+		$tag =~ s/_/./g;
+		print "<a name='$tag'></a><h2>$head</h2><p>";
+		foreach ( @$chunk ) {
+			s/^A: /<br\/>Arguments: /;
+			s/^R: /<br\/>Return values: /;
+			s/^V: /<br\/>Values: /;
+			if ( $list ) {
+				if ( /^\* / ) {
+					s/^\* /<\/li><li>/;
+				} else {
+					s/^/<\/li><\/ul> /;
+					$list = undef;
+				}
+			} elsif ( /^\* / ) {
+				s/^\* /<ul><li>/;
+				$list = 1;
+			}
+			foreach my $tag ( @tags ) {
+				# TODO quotemeta required, but for now
+				# this bug is rather desired...
+				#s/\b$tag\b/<a href="#$tag">$&<\/a>/g;
+				s/(.)\b($tag)\b/ if ( $1 eq '#' or $1 eq '>' ) { "$1$2" } else { "$1<a href='#$tag'>$2<\/a>" } /ge;
+			}
+			print $_;
+		}
+		print "</li></ul>" if $list;
+		print "</p>"
+	}
+	print "<hr>";
+}
+
+print "</body></html>"
+
+# The end
--- a/main.c	Sun Feb 22 23:14:24 2009 +0200
+++ b/main.c	Mon Feb 23 04:05:05 2009 +0200
@@ -4,41 +4,41 @@
 #include <lua.h>
 #include <lauxlib.h>
 #include <lualib.h>
-#include <stdio.h>       // popen, pclose, fileno
+#include <stdio.h>
+#include <stdlib.h>    // getenv
 
-#include "logprint.h"    // scr_LogPrint
-#include "screen.h"      // scr_Beep, scr_WriteIncomingMessage
-#include "hbuf.h"        // HBB_PREFIX_INFO
-#include "commands.h"    // process_command
-#include "xmpp.h"        // xmpp_getstatus, xmpp_getstatusmsg, lconnection
-#include "roster.h"      // imstatus2char, foreach_buddy, buddy_*, current_buddy, BUDDATA, ROSTER_TYPE_*
-#include "utils.h"       // from_utf8
-#include "lua_util.h"    // mcabber_config_file, string2enum
-#include "hooks.h"
-#include "settings.h"
+#include "util.h"
+#include "logprint.h"  // scr_LogPrint
+#include "screen.h"    // scr_Beep, scr_WriteIncomingMessage
+#include "hbuf.h"      // HBB_PREFIX_INFO
+#include "commands.h"  // process_command, cmd_add, cmd_del
+#include "xmpp.h"      // xmpp_getstatus, xmpp_getstatusmsg, lconnection, xmpp_add_feature, xmpp_del_feature
+#include "roster.h"    // imstatus2char, foreach_buddy, buddy_*, current_buddy, BUDDATA, ROSTER_TYPE_*
+#include "utils.h"     // from_utf8, jidtodisp
+#include "hooks.h"     // hk_add_handler, hk_del_handler
+#include "settings.h"  // settings_set, settings_del, settings_get
 
 
-lua_State *lua = NULL;    // global lua state object
+// global lua state object, necessary for uninitialization function
+static lua_State *lua = NULL;
 
+// caller sould g_free result
 char *mcabber_config_filename (const char *file)
 {
-  char *home = getenv("HOME");
-  if (!home)
-    return NULL;
-  return g_strconcat (home, "/.mcabber/", file ? file : "", NULL);
+	const char *home = getenv ("HOME");
+	if (!home)
+		return NULL;
+	return g_strconcat (home, "/.mcabber/", file ? file : "", NULL);
 }
 
 /// print
-/// Prints it's arguments to log with default priority.
-/// A: message, message...
+/// Prints its arguments to log with default priority.
+/// A: string/number, ...
 static int lua_global_print (lua_State *L)
 {
-  const char *message;
-  lua_concat (L, lua_gettop (L));
-  message = lua_tostring (L, -1);
-  scr_LogPrint (LPRINT_LOGNORM, message);
-  lua_pop (L, 1);
-  return 0;
+	lua_concat (L, lua_gettop (L));
+	scr_LogPrint (LPRINT_LOGNORM, lua_tostring (L, -1));
+	return 0;
 }
 
 /// dopath
@@ -46,47 +46,62 @@
 /// A: string (filename, without ".lua")
 static int lua_global_dopath (lua_State *L)
 {
- // const char *name = luaL_checkstring (L, 1);
-  // FIXME
-  return 0;
+	const char *name = luaL_checkstring (L, 1);
+	size_t      size = lua_objlen (L, 1);
+	char       *path;
+	if (!strncmp (name + size - 4, ".lua", 4))
+		path = mcabber_config_filename (name);
+	else {
+		char *fname = g_strconcat (name, ".lua", NULL);
+		path = mcabber_config_filename (fname);
+		g_free (fname);
+	}
+
+	if (luaL_loadfile (L, path))
+		scr_LogPrint (LPRINT_LOGNORM, "lua: Unable to compile file %s: %s", path, lua_tostring (L, -1));
+	else if (lua_pcall (lua, 0, LUA_MULTRET, 0))
+		scr_LogPrint(LPRINT_LOGNORM, "lua: Runtime error in file %s: %s", path, lua_tostring (L, -1));
+
+	g_free (path);
+	return 0;
 }
 
 /// main.config_file
 /// Adds mcabber default config location path to config file name.
-/// Note: not sure, that this function will stay alive long.
+/// Note: deprecated, use dopath.
 /// A: string (filename)
 /// R: string (full path)
 static int lua_main_config_file (lua_State *L)
 {
-  char *home = mcabber_config_filename (lua_isstring (L, 1) ?
-                                        lua_tostring (L, 1) : NULL);
-  lua_pop (L, 1);
-  if (!home) {
-    lua_pushstring (L, "Cannot find home dir!");
-    lua_error (L);
-  }
-  lua_pushstring (L, home);
-  g_free (home); // XXX
-  return 1;
+	char *home = mcabber_config_filename (luaL_checkstring (L, 1));
+	if (!home) {
+		lua_pushstring (L, "Cannot find home dir!");
+		lua_error (L);
+	}
+	lua_pushstring (L, home);
+	g_free (home);
+	return 1;
 }
 
 /// log print type
-/// V: normal, log, debug, notutf8, lognorm
+/// G:
 static const string2enum_t lua_lprint[] = {
-  { "normal",  LPRINT_NORMAL  },
-  { "log",     LPRINT_LOG     },
-  { "debug",   LPRINT_DEBUG   },
-  { "notutf0", LPRINT_NOTUTF8 },
-  { NULL,      0              },
+	{ "normal",  LPRINT_NORMAL  },
+	{ "log",     LPRINT_LOG     },
+	{ "debug",   LPRINT_DEBUG   },
+	{ "notutf0", LPRINT_NOTUTF8 },
+	{ NULL,      0              },
 };
 
+/// roster type
+/// G:
 static const string2enum_t lua_roster_type[] = {
-  { "user",    ROSTER_TYPE_USER    },
-  { "group",   ROSTER_TYPE_GROUP   },
-  { "agent",   ROSTER_TYPE_AGENT   },
-  { "room",    ROSTER_TYPE_ROOM    },
-  { "special", ROSTER_TYPE_SPECIAL },
-  { NULL,      0                   },
+	{ "user",    ROSTER_TYPE_USER    },
+	{ "group",   ROSTER_TYPE_GROUP   },
+	{ "agent",   ROSTER_TYPE_AGENT   },
+	{ "room",    ROSTER_TYPE_ROOM    },
+	{ "special", ROSTER_TYPE_SPECIAL },
+	{ NULL,      0                   },
 };
 
 /// main.log
@@ -94,12 +109,10 @@
 /// A: log print type, message, message...
 static int lua_main_log (lua_State *L)
 {
-  const char *message;
-  int type = luaL_checkenum_multi (L, 1, lua_lprint);
-  lua_concat (L, lua_gettop (L) - 1);
-  message = lua_tostring (L, -1);
-  scr_LogPrint (type, message);
-  return 0;
+	int type = luaL_checkenum_multi (L, 1, lua_lprint);
+	lua_concat (L, lua_gettop (L) - 1);
+	scr_LogPrint (type, lua_tostring (L, -1));
+	return 0;
 }
 
 /// main.option
@@ -110,23 +123,23 @@
 /// R: string (value, optional)
 static int lua_main_option (lua_State *L)
 {
-  const char *name = luaL_checkstring (L, 1);
-  if (lua_gettop (L) > 1) { // Set
-    if (lua_type (L, 2) == LUA_TNIL)
-      settings_del (SETTINGS_TYPE_OPTION, name);
-    else {
-      const char *value = luaL_checkstring (L, 2);
-      settings_set (SETTINGS_TYPE_OPTION, name, value);
-    }
-    return 0;
-  } else {
-    const char *value = settings_get (SETTINGS_TYPE_OPTION, name);
-    if (value)
-      lua_pushstring (L, value);
-    else
-      lua_pushnil (L);
-    return 1;
-  }
+	const char *name = luaL_checkstring (L, 1);
+	if (lua_gettop (L) > 1) { // Set
+		if (lua_type (L, 2) == LUA_TNIL) // Unset
+			settings_del (SETTINGS_TYPE_OPTION, name);
+		else { // Set
+			const char *value = luaL_checkstring (L, 2);
+			settings_set (SETTINGS_TYPE_OPTION, name, value);
+		}
+		return 0;
+	} else { // Get
+		const char *value = settings_get (SETTINGS_TYPE_OPTION, name);
+		if (value)
+			lua_pushstring (L, value);
+		else
+			lua_pushnil (L);
+		return 1;
+	}
 }
 
 /// main.connection
@@ -135,60 +148,74 @@
 /// R: lightuserdata
 static int lua_main_connection (lua_State *L)
 {
-  lua_pushlightuserdata (L, lconnection);
-  return 1;
+	lua_pushlightuserdata (L, lconnection);
+	return 1;
 }
 
-// Well, for now
-// I cannot get how
-// To use caps.
-
 /// 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;
+	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;
+	xmpp_del_feature (luaL_checkstring (L, 1));
+	return 0;
 }
 
 typedef struct {
-  int reference;
-  lua_State *L;
+	int        reference;
+	lua_State *L;
 } lua_command_callback_t;
 
 /// command function
-/// A: argument string
+/// 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);
-  }
+	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;
+	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
@@ -196,19 +223,18 @@
 /// A: string (jid), string (message)
 static int lua_main_print_info (lua_State *L)
 {
-  char *to = jidtodisp (luaL_checkstring (L, 1));
-  const char *message = luaL_checkstring (L, 2);
-  scr_WriteIncomingMessage (to, message, 0, HBB_PREFIX_INFO, 0);
-  g_free (to);
-  return 0;
+	char *to = jidtodisp (luaL_checkstring (L, 1));
+	scr_WriteIncomingMessage (to, luaL_checkstring (L, 2), 0, HBB_PREFIX_INFO, 0);
+	g_free (to);
+	return 0;
 }
 
 /// main.beep
 /// Beeps with system speaker.
 static int lua_main_beep (lua_State *L)
 {
-  scr_Beep ();
-  return 0;
+	scr_Beep ();
+	return 0;
 }
 
 /// main.run
@@ -216,29 +242,28 @@
 /// A: string
 static int lua_main_run (lua_State *L)
 {
-  const char *command = luaL_checkstring (L, 1);
-  process_command (command, TRUE);
-  return 0;
+	process_command (luaL_checkstring (L, 1), TRUE);
+	return 0;
 }
 
 /// main.status
 /// Returns your current status.
-/// R: char (status letter), string (status message)
+/// R: string (status letter), string (status message)
 static int lua_main_status (lua_State *L)
 {
-  char *sm = from_utf8 (xmpp_getstatusmsg ());
-  lua_pushlstring (L, &imstatus2char[xmpp_getstatus ()], 1);
-  lua_pushstring  (L, sm);
-  g_free (sm);
-  return 2;
+	char *sm = from_utf8 (xmpp_getstatusmsg ());
+	lua_pushlstring (L, &imstatus2char[xmpp_getstatus ()], 1);
+	lua_pushstring (L, sm);
+	g_free (sm);
+	return 2;
 }
 
-// expects table on top!
+// expects table on top
 static void lua_rosterlist_callback (gpointer buddy, lua_State *L)
 {
-  lua_pushnumber (L, lua_objlen (L, -1) + 1);
-  lua_pushstring (L, buddy_getjid (buddy));
-  lua_settable (L, -3);
+	lua_pushnumber (L, lua_objlen (L, -1) + 1);
+	lua_pushstring (L, buddy_getjid (buddy));
+	lua_settable (L, -3);
 }
 
 /// main.roster
@@ -246,9 +271,9 @@
 /// R: table
 static int lua_main_roster (lua_State *L)
 {
-  lua_newtable (L);
-  foreach_buddy (ROSTER_TYPE_USER|ROSTER_TYPE_AGENT|ROSTER_TYPE_ROOM, (void (*) (gpointer buddy, void *data))lua_rosterlist_callback, L);
-  return 1;
+	lua_newtable (L);
+	foreach_buddy (ROSTER_TYPE_USER|ROSTER_TYPE_AGENT|ROSTER_TYPE_ROOM, (void (*) (gpointer buddy, void *data))lua_rosterlist_callback, L);
+	return 1;
 }
 
 /// main.current_buddy
@@ -256,30 +281,30 @@
 /// R: string
 static int lua_main_current_buddy (lua_State *L)
 {
-  lua_pushstring (L, buddy_getjid (BUDDATA (current_buddy)));
-  return 1;
+	lua_pushstring (L, buddy_getjid (BUDDATA (current_buddy)));
+	return 1;
 }
 
 typedef struct {
-  lua_State *L;
-  gpointer buddy;
+	lua_State *L;
+	gpointer   buddy;
 } lua_state_and_buddy_t; // :)
 
 // expects table on top!
 static void lua_buddy_resources_callback (gpointer resource, lua_state_and_buddy_t *d)
 {
-  lua_pushstring  (d->L, resource);
-  lua_createtable (d->L, 0, 3);
-  lua_pushstring  (d->L, "priority");
-  lua_pushnumber  (d->L, buddy_getresourceprio (d->buddy, resource));
-  lua_settable    (d->L, -3);
-  lua_pushstring  (d->L, "status");
-  lua_pushlstring (d->L, &imstatus2char[buddy_getstatus (d->buddy, resource)], 1);
-  lua_settable    (d->L, -3);
-  lua_pushstring  (d->L, "message");
-  lua_pushstring  (d->L, buddy_getstatusmsg (d->buddy, resource));
-  lua_settable    (d->L, -3);
-  lua_settable    (d->L, -3);
+	lua_pushstring (d->L, resource);
+	lua_createtable (d->L, 0, 3);
+	lua_pushstring (d->L, "priority");
+	lua_pushnumber (d->L, buddy_getresourceprio (d->buddy, resource));
+	lua_settable   (d->L, -3);
+	lua_pushstring  (d->L, "status");
+	lua_pushlstring (d->L, &imstatus2char[buddy_getstatus (d->buddy, resource)], 1);
+	lua_settable    (d->L, -3);
+	lua_pushstring (d->L, "message");
+	lua_pushstring (d->L, buddy_getstatusmsg (d->buddy, resource));
+	lua_settable   (d->L, -3);
+	lua_settable (d->L, -3);
 }
 
 /// main.buddy_info
@@ -292,37 +317,34 @@
 /// R: table
 static int lua_main_buddy_info (lua_State *L)
 {
-  char *jid = jidtodisp (luaL_checkstring (L, 1));
-  GSList *buddy = roster_find (jid, jidsearch,
-                          ROSTER_TYPE_USER|ROSTER_TYPE_AGENT|ROSTER_TYPE_ROOM);
-  lua_state_and_buddy_t snb;
-  g_free (jid);
+	char                  *jid   = jidtodisp (luaL_checkstring (L, 1));
+	GSList                *buddy = roster_find (jid, jidsearch, ROSTER_TYPE_USER|ROSTER_TYPE_AGENT|ROSTER_TYPE_ROOM);
+	lua_state_and_buddy_t  snb;
+	g_free (jid);
+
+	if (!buddy) {
+		lua_pushnil (L);
+		return 1;
+	}
 
-  if (!buddy) {
-    lua_pushnil (L);
-    return 1;
-  }
-  
-  lua_createtable (L, 0, 3);
-  lua_pushstring  (L, "type");
-  lua_pushstring  (L, enum2string (buddy_gettype (BUDDATA (buddy)),
-                                   lua_roster_type));
-  lua_settable    (L, -3);
-  lua_pushstring  (L, "name");
-  lua_pushstring  (L, buddy_getname (BUDDATA (buddy)));
-  lua_settable    (L, -3);
-  lua_pushstring  (L, "onserver");
-  lua_pushboolean (L, buddy_getonserverflag (BUDDATA (buddy)));
-  lua_settable    (L, -3);
-  lua_pushstring  (L, "resources");
-  lua_createtable (L, 0, 0);
-  snb.L     = L;
-  snb.buddy = BUDDATA (buddy);
-  g_slist_foreach (buddy_getresources (BUDDATA (buddy)),
-                   (GFunc)lua_buddy_resources_callback, &snb);
-  lua_settable    (L, -3);
-  
-  return 1;
+	lua_createtable (L, 0, 3);
+	lua_pushstring (L, "type");
+	luaL_pushenum  (L, buddy_gettype (BUDDATA (buddy)), lua_roster_type);
+	lua_settable   (L, -3);
+	lua_pushstring (L, "name");
+	lua_pushstring (L, buddy_getname (BUDDATA (buddy)));
+	lua_settable   (L, -3);
+	lua_pushstring  (L, "onserver");
+	lua_pushboolean (L, buddy_getonserverflag (BUDDATA (buddy)));
+	lua_settable    (L, -3);
+	lua_pushstring  (L, "resources");
+	lua_createtable (L, 0, 0);
+	snb.L     = L;
+	snb.buddy = BUDDATA (buddy);
+	g_slist_foreach (buddy_getresources (BUDDATA (buddy)), (GFunc) lua_buddy_resources_callback, &snb);
+	lua_settable    (L, -3);
+	
+	return 1;
 }
 
 // TIMER
@@ -330,14 +352,14 @@
 #define LUA_TIMER_PRIORITY ( G_PRIORITY_HIGH_IDLE )
 
 typedef struct {
-  int reference;
-  lua_State *L;
+	int        reference;
+	lua_State *L;
 } lua_timer_callback_t;
 
 static void lua_timer_callback_destroy (lua_timer_callback_t *cb)
 {
-  luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
-  luaL_free (cb->L, cb);
+	luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
+	luaL_free (cb->L, cb);
 }
 
 /// timer function
@@ -345,17 +367,16 @@
 /// R: boolean
 static gboolean lua_timer_callback (lua_timer_callback_t *cb)
 {
-  int ret;
-  lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
-  if (lua_pcall (cb->L, 0, 1, 0)) {
-    scr_LogPrint (LPRINT_LOGNORM, "lua: Timer callback execution error: %s",
-                  lua_tostring (cb->L, -1));
-    lua_pop (cb->L, 1);
-    return FALSE;
-  }
-  ret = lua_toboolean (cb->L, -1);
-  lua_pop (cb->L, 1);
-  return ret;
+	int ret;
+	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
+	if (lua_pcall (cb->L, 0, 1, 0)) {
+		scr_LogPrint (LPRINT_LOGNORM, "lua: Timer callback execution error: %s", lua_tostring (cb->L, -1));
+		lua_pop (cb->L, 1);
+		return FALSE;
+	}
+	ret = lua_toboolean (cb->L, -1);
+	lua_pop (cb->L, 1);
+	return ret;
 }
 
 /// main.timer
@@ -363,18 +384,16 @@
 /// A: integer (interval, seconds), timer function
 static int lua_main_timer (lua_State *L)
 {
-  int interval = luaL_checkint (L, 1);
-  lua_timer_callback_t *cb;
-  luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
+	int                   interval = luaL_checkint (L, 1);
+	lua_timer_callback_t *cb;
+	luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
 
-  cb = luaL_malloc (L, sizeof (lua_timer_callback_t));
-  cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
-  cb->L         = L;
+	cb = luaL_malloc (L, sizeof (lua_timer_callback_t));
+	cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
+	cb->L         = L;
 
-  g_timeout_add_seconds_full (LUA_TIMER_PRIORITY, interval,
-                              (GSourceFunc)lua_timer_callback, cb,
-                              (GDestroyNotify)lua_timer_callback_destroy);
-  return 0;
+	g_timeout_add_seconds_full (LUA_TIMER_PRIORITY, interval, (GSourceFunc) lua_timer_callback, cb, (GDestroyNotify) lua_timer_callback_destroy);
+	return 0;
 }
 
 // BACKGROUND PIPE READING
@@ -382,18 +401,18 @@
 #define LUA_BGREAD_BUFFER ( 4096 )
 
 typedef struct {
-  lua_State *L;
-  FILE      *fd;
-  int        reference;
+	lua_State *L;
+	FILE      *fd;
+	int        reference;
 } lua_bgread_callback_t;
 
 static gchar lua_bgread_buffer[LUA_BGREAD_BUFFER];
 
 static void lua_bgread_callback_destroy (lua_bgread_callback_t *cb)
 {
-  luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
-  pclose (cb->fd);
-  luaL_free (cb->L, cb);
+	luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
+	pclose (cb->fd);
+	luaL_free (cb->L, cb);
 }
 
 /// background reading function
@@ -401,205 +420,196 @@
 /// A: string (data) or nil (eof)
 /// R: boolean (false if reading should be terminated)
 static gboolean
-lua_bgread_callback (GIOChannel *source, GIOCondition condition,
-                     lua_bgread_callback_t *cb)
+lua_bgread_callback (GIOChannel *source, GIOCondition condition, lua_bgread_callback_t *cb)
 {
-  int ret = TRUE;
+	int ret = TRUE;
 
-  if (condition | G_IO_IN) { // data
-    while (TRUE) {
-      gsize read = 0;
-      g_io_channel_read_chars(source, lua_bgread_buffer, LUA_BGREAD_BUFFER,
-                              &read, NULL);
-      if (!read) // exausted
-        break;
+	if (condition | G_IO_IN) { // data
+		while (TRUE) {
+			gsize read = 0;
+			g_io_channel_read_chars (source, lua_bgread_buffer, LUA_BGREAD_BUFFER, &read, NULL);
+			if (!read) // exausted
+				break;
 
-      lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
-      lua_pushlstring (cb->L, lua_bgread_buffer, read);
-      if (lua_pcall (cb->L, 1, 1, 0)) {
-        scr_LogPrint (LPRINT_LOGNORM,
-                      "lua: Bgread callback execution error: %s",
-                      lua_tostring (cb->L, -1));
-        lua_pop (cb->L, 1);
-        return FALSE;
-      }
-      ret = lua_toboolean (cb->L, -1);
-      lua_pop (cb->L, 1);
-      if (!ret) // enough
-        return FALSE;
-    }
-  }
+			lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
+			lua_pushlstring (cb->L, lua_bgread_buffer, read);
+			if (lua_pcall (cb->L, 1, 1, 0)) {
+				scr_LogPrint (LPRINT_LOGNORM, "lua: Bgread callback execution error: %s", lua_tostring (cb->L, -1));
+				lua_pop (cb->L, 1);
+				return FALSE;
+			}
+			ret = lua_toboolean (cb->L, -1);
+			lua_pop (cb->L, 1);
+			if (!ret) // enough
+				return FALSE;
+		}
+	}
 
-  if (condition & ~G_IO_IN) { // err or hup
-    lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
-    lua_pushnil (cb->L);
-    if (lua_pcall (cb->L, 1, 1, 0)) {
-      scr_LogPrint (LPRINT_LOGNORM, "lua: Bgread callback execution error: %s",
-                    lua_tostring (cb->L, -1));
-      lua_pop (cb->L, 1);
-      return FALSE;
-    }
-    ret = lua_toboolean (cb->L, -1);
-    lua_pop (cb->L, 1);
-  }
+	if (condition & ~G_IO_IN) { // err or hup
+		lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
+		lua_pushnil (cb->L);
+		if (lua_pcall (cb->L, 1, 1, 0)) {
+			scr_LogPrint (LPRINT_LOGNORM, "lua: Bgread callback execution error: %s", lua_tostring (cb->L, -1));
+			lua_pop (cb->L, 1);
+			return FALSE;
+		}
+		ret = lua_toboolean (cb->L, -1);
+		lua_pop (cb->L, 1);
+	}
 
-  return ret;
+	return ret;
 }
 
 /// main.bgread
-/// Runs specified command and passes it's output to given function.
+/// Runs specified command and passes its output to a given function.
 /// A: string (command), background reading function
 static int lua_main_bgread (lua_State *L)
 {
-  const char *command = luaL_checkstring (L, 1);
-  lua_bgread_callback_t *cb;
-  FILE *fd;
-  GIOChannel *channel;
-  const char *charset = NULL;
-  luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
+	const char            *command = luaL_checkstring (L, 1);
+	lua_bgread_callback_t *cb;
+	FILE                  *fd;
+	GIOChannel            *channel;
+	const char            *charset = NULL;
+	luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
 
-  fd = popen (command, "r");
-  if (!fd) {
-    lua_pushstring (L, "Error opening pipe");
-    lua_error (L);
-  }
+	fd = popen (command, "r");
+	if (!fd) {
+		lua_pushstring (L, "Error opening pipe");
+		lua_error (L);
+	}
 
-  channel = g_io_channel_unix_new (fileno (fd));
-// We, most likely, need this,
-// But we cannot use this,
-// It will block.
-//if (!g_get_charset (&charset))
-  g_io_channel_set_encoding (channel, charset, NULL);
-  g_io_channel_set_buffered (channel, FALSE);
-  g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
-  g_io_channel_set_close_on_unref (channel, TRUE);
+	channel = g_io_channel_unix_new (fileno (fd));
+	// We, most likely, need this,
+	// But we cannot use this,
+	// It will block.
+	//if (!g_get_charset (&charset))
+	g_io_channel_set_encoding (channel, charset, NULL);
+	g_io_channel_set_buffered (channel, FALSE);
+	g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
+	g_io_channel_set_close_on_unref (channel, TRUE);
 
-  cb = luaL_malloc (L, sizeof (lua_bgread_callback_t));
-  cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
-  cb->L         = L;
-  cb->fd        = fd;
+	cb = luaL_malloc (L, sizeof (lua_bgread_callback_t));
+	cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
+	cb->L         = L;
+	cb->fd        = fd;
 
-  g_io_add_watch_full (channel, G_PRIORITY_HIGH_IDLE,
-                       G_IO_IN|G_IO_HUP|G_IO_ERR,
-                       (GIOFunc)lua_bgread_callback, cb,
-                       (GDestroyNotify)lua_bgread_callback_destroy);
-  return 0;
+	g_io_add_watch_full (channel, G_PRIORITY_HIGH_IDLE, G_IO_IN|G_IO_HUP|G_IO_ERR, (GIOFunc) lua_bgread_callback, cb, (GDestroyNotify) lua_bgread_callback_destroy);
+	return 0;
 }
 
 // MAIN INITIALIZATION CODE
 
-static void *lua_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
-  if (nsize == 0) {
-    g_free (ptr);
-    return NULL;
-  } else
-    return g_realloc (ptr, nsize);
-}
+#define LUA_HOOK_NAME ( "hook_handler" )
 
 static void lua_hook (hk_arg_t *args, lua_State *L)
 {
-  hk_arg_t *arg = args;
-  lua_getglobal (lua, "hook_handler");
-  if (!lua_isfunction (lua, -1)) {
-    lua_pop (lua, 1);
-    return;
-  }
-  lua_newtable (L);
-  while (arg->name != NULL) {
-    lua_pushstring (L, arg->name);
-    lua_pushstring (L, arg->value);
-    lua_settable (L, -3);
-    arg++;
-  }
-  if (lua_pcall (lua, 1, 0, 0)) {
-    scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook_handler: %s",
-                  lua_tostring (lua, -1));
-    lua_pop (lua, 1);
-  }
+	hk_arg_t *arg = args;
+	lua_getglobal (lua, LUA_HOOK_NAME);
+	if (!lua_isfunction (lua, -1)) {
+		lua_pop (lua, 1);
+		return;
+	}
+	lua_newtable (L);
+	while (arg->name != NULL) {
+		lua_pushstring (L, arg->name);
+		lua_pushstring (L, arg->value);
+		lua_settable (L, -3);
+		arg++;
+	}
+	if (lua_pcall (lua, 1, 0, 0)) {
+		scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook_handler: %s", lua_tostring (lua, -1));
+		lua_pop (lua, 1);
+	}
+}
+
+static void *lua_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
+	if (nsize == 0) {
+		g_free (ptr);
+		return NULL;
+	} else
+		return g_realloc (ptr, nsize);
 }
 
 static const luaL_Reg lua_reg_main[] = {
-  { "config_file",   lua_main_config_file   },
-  { "connection",    lua_main_connection    },
-  { "log",           lua_main_log           },
-  { "option",        lua_main_option        },
-  { "add_feature",   lua_main_add_feature   },
-  { "del_feature",   lua_main_del_feature   },
-  { "add_command",   lua_main_add_command   },
-  { "print_info",    lua_main_print_info    },
-  { "beep",          lua_main_beep          },
-  { "run",           lua_main_run           },
-  { "status",        lua_main_status        },
-  { "roster",        lua_main_roster        },
-  { "current_buddy", lua_main_current_buddy },
-  { "buddy_info",    lua_main_buddy_info    },
-  { "timer",         lua_main_timer         },
-  { "bgread",        lua_main_bgread        },
-  { NULL,            NULL                   }, // end
+	{ "config_file",   lua_main_config_file   },
+	{ "connection",    lua_main_connection    },
+	{ "log",           lua_main_log           },
+	{ "option",        lua_main_option        },
+	{ "add_feature",   lua_main_add_feature   },
+	{ "del_feature",   lua_main_del_feature   },
+	{ "add_command",   lua_main_add_command   },
+	{ "del_command",   lua_main_del_command   },
+	{ "print_info",    lua_main_print_info    },
+	{ "beep",          lua_main_beep          },
+	{ "run",           lua_main_run           },
+	{ "status",        lua_main_status        },
+	{ "roster",        lua_main_roster        },
+	{ "current_buddy", lua_main_current_buddy },
+	{ "buddy_info",    lua_main_buddy_info    },
+	{ "timer",         lua_main_timer         },
+	{ "bgread",        lua_main_bgread        },
+	{ NULL,            NULL                   },
 };
 
 const gchar *g_module_check_init (GModule *module)
 {
-  char *initfile;
+	char *initfile;
 
-  lua = lua_newstate(lua_alloc, NULL);
-  if (!lua) {
-    scr_LogPrint(LPRINT_LOGNORM, "lua: Initialization error");
-    return;
-  }
+	lua = lua_newstate (lua_alloc, NULL);
+	if (!lua) {
+		scr_LogPrint (LPRINT_LOGNORM, "lua: Initialization error");
+		return "Lua initialization error";
+	}
 
-  luaL_openlibs(lua);
+	luaL_openlibs (lua);
 
-  luaL_register(lua, "main", lua_reg_main);
-  lua_pop (lua, 1);
-// lua_register(lua, "dopath", lua_global_dopath);
-  lua_register(lua, "print", lua_global_print);
-  
-  initfile = mcabber_config_filename ("mcabberrc.lua");
-  if (!initfile)
-    scr_LogPrint(LPRINT_LOGNORM, "lua: Cannot determine config file name");
-  else {
-    int err = luaL_loadfile(lua, initfile);
-    if (err)
-      scr_LogPrint(LPRINT_LOGNORM, "lua: Unable to compile rc file (%d)", err);
-    else if (lua_pcall(lua, 0, LUA_MULTRET, 0)) {
-      scr_LogPrint(LPRINT_LOGNORM, "lua: Runtime error in rc file: %s",
-          lua_tostring(lua, -1));
-      lua_pop (lua, 1);
-    } else
-      scr_LogPrint(LPRINT_LOGNORM, "Loaded mcabberrc.lua");
-    g_free(initfile); // XXX
-  }
+	luaL_register (lua, "main", lua_reg_main);
+	lua_pop (lua, 1); // XXX
+	lua_register (lua, "dopath", lua_global_dopath);
+	lua_register (lua, "print",  lua_global_print );
+	
+	initfile = mcabber_config_filename ("mcabberrc.lua");
+	if (!initfile)
+		scr_LogPrint (LPRINT_LOGNORM, "lua: Cannot determine config file name");
+	else {
+		if (luaL_loadfile(lua, initfile)) {
+			scr_LogPrint (LPRINT_LOGNORM, "lua: Unable to compile rc file: %s", lua_tostring (lua, -1));
+			lua_pop (lua, 1);
+		} else if (lua_pcall (lua, 0, LUA_MULTRET, 0)) {
+			scr_LogPrint (LPRINT_LOGNORM, "lua: Runtime error in rc file: %s", lua_tostring(lua, -1));
+			lua_pop (lua, 1);
+		} else
+			scr_LogPrint (LPRINT_LOGNORM, "Loaded mcabberrc.lua");
+		g_free (initfile);
+	}
 
-  hk_add_handler ((hk_handler_t) lua_hook, lua);
+	hk_add_handler ((hk_handler_t) lua_hook, lua);
 
-  lua_getglobal (lua, "hook_start");
-  if (!lua_isfunction (lua, -1))
-    lua_pop (lua, 1);
-  else if (lua_pcall (lua, 0, 0, 0)) {
-    scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook_start: %s",
-                  lua_tostring (lua, -1));
-    lua_pop (lua, 1);
-  }
+	lua_getglobal (lua, "hook_start");
+	if (!lua_isfunction (lua, -1))
+		lua_pop (lua, 1);
+	else if (lua_pcall (lua, 0, 0, 0)) {
+		scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook_start: %s", lua_tostring (lua, -1));
+		lua_pop (lua, 1);
+	}
+	return NULL;
 }
 
 void g_module_unload (GModule *module)
 {
-  if (lua) {
-    lua_getglobal (lua, "hook_quit");
-    if (!lua_isfunction (lua, -1))
-      lua_pop (lua, 1);
-    else if (lua_pcall (lua, 0, 0, 0)) {
-      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);
+	if (lua) {
+		lua_getglobal (lua, "hook_quit");
+		if (!lua_isfunction (lua, -1))
+			lua_pop (lua, 1);
+		else if (lua_pcall (lua, 0, 0, 0)) {
+			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);
 
-    lua_close (lua);
-    lua = NULL;
-  }
+		lua_close (lua);
+		lua = NULL;
+	}
 }
 
-/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */