--- 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... */