# HG changeset patch # User Myhailo Danylenko # Date 1235164063 -7200 # Node ID 90073cbb535df176d21428f15d1ddef4c1d56674 # Parent e617c9cf6dd35df03d6ea707d038db6dd4b9a770 Logging and chained methods diff -r e617c9cf6dd3 -r 90073cbb535d CMakeLists.txt --- a/CMakeLists.txt Mon Feb 16 01:32:12 2009 +0200 +++ b/CMakeLists.txt Fri Feb 20 23:07:43 2009 +0200 @@ -3,12 +3,11 @@ project(lua-lm C) ## User options -option(DEBUG "Enable debugging output" OFF) +option(DEBUG "Enable debugging output" ON) ## Define targets add_library(loudmouth MODULE util.c lm_types.c lm_proxy.c lm_ssl.c lm_connection.c lm_message.c lm_message_node.c lm_message_handler.c lm.c) get_target_property(lua-lm_SOURCES loudmouth SOURCES) -configure_file(config.h.in config.h) ## Packaging information set(CPACK_PACKAGE_NAME liblua5.1-loudmouth) @@ -38,23 +37,34 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(GLIB REQUIRED glib-2.0) pkg_check_modules(LM REQUIRED loudmouth-1.0) +include(CheckFunctionExists) +set(CMAKE_REQUIRED_INCLUDES ${LM_INCLUDE_DIRS}) +set(CMAKE_REQUIRED_LIBRARIES ${LM_LIBRARIES}) +check_function_exists(lm_connection_get_keep_alive_rate HAVE_LM_CONNECTION_GET_KEEP_ALIVE_RATE) +find_package(Perl) ## Set up compiler +configure_file(config.h.in config.h) include_directories(SYSTEM ${LUA_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS} ${LM_INCLUDE_DIRS}) target_link_libraries(loudmouth ${LUA_LIBRARIES} ${GLIB_LIBRARIES} ${LM_LIBRARIES}) include_directories(${lua-lm_SOURCE_DIR} ${lua-lm_BINARY_DIR}) set_target_properties(loudmouth PROPERTIES PREFIX "") ## Extra targets -add_custom_command(OUTPUT ${lua-lm_BINARY_DIR}/loudmouth.html COMMAND ${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) +if(PERL_FOUND) + add_custom_command(OUTPUT ${lua-lm_BINARY_DIR}/loudmouth.html COMMAND ${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() 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) ## Set up installer install(TARGETS loudmouth DESTINATION lib/lua/5.1) install(FILES lm.lua DESTINATION share/lua/5.1) install(FILES test.lua DESTINATION share/doc/${CPACK_PACKAGE_NAME}/examples) -install(FILES ${lua-lm_BINARY_DIR}/loudmouth.html DESTINATION share/doc/${CPACK_PACKAGE_NAME}) +if(PERL_FOUND) + install(FILES ${lua-lm_BINARY_DIR}/loudmouth.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}) diff -r e617c9cf6dd3 -r 90073cbb535d README --- a/README Mon Feb 16 01:32:12 2009 +0200 +++ b/README Fri Feb 20 23:07:43 2009 +0200 @@ -1,18 +1,22 @@ This is a lua 5.1 interface for loudmouth jabber client library. -To install it, you need glib and loudmouth headers and libraries. -Edit Makefile, set PREFIX, SOLIBDIR, LUALIBDIR, then run -make -make install + +To install it, you need lua, glib and loudmouth headers and libraries, +cmake and perl (optional, for documentation). Then do +$ cd build +$ cmake .. +$ make +# make install -Optionally you can generate and install api documentation (for now -there are no lua convenience interface documentation, only for low-level -interface, implemented in c, see example in test.lua). You will need a -perl interpreter for that. Edit Makefile, set DOCDIR, then run -make doc -make doc-install +Debian users can instead of make install do +$ make package +# dpkg -i liblua5.1-*.deb -This code underlies terms of GNU GPL v3 or later. +Also you can be interested in running +$ make edit_cache +before doing make to configure some project settings. + +This code underlies terms of GNU GPL v2 or later. I will be happy to get feedback, patches, suggestions, etc. diff -r e617c9cf6dd3 -r 90073cbb535d TODO --- a/TODO Mon Feb 16 01:32:12 2009 +0200 +++ b/TODO Fri Feb 20 23:07:43 2009 +0200 @@ -1,5 +1,4 @@ -* Add debugging output and verify refcounts of lm objects. Need a decent test script for that... -* How to report errors in callbacks? We cannot use lua_error, it can be even outside of any lua pcalled environment. -* Some additional lua functions? +Verify refcounts of lm objects. Need a decent test script for that. +Some additional lua functions? diff -r e617c9cf6dd3 -r 90073cbb535d config.h.in --- a/config.h.in Mon Feb 16 01:32:12 2009 +0200 +++ b/config.h.in Fri Feb 20 23:07:43 2009 +0200 @@ -5,11 +5,25 @@ // define this to enable debugging output #cmakedefine DEBUG +// define this, if your loudmouth have lm_connection_get_keep_alive_rate () +#cmakedefine HAVE_LM_CONNECTION_GET_KEEP_ALIVE_RATE + #ifdef DEBUG -#include -#define D(FORMAT...) { fprintf ( stderr, FORMAT ); } +# include + +# ifndef LLM_LOG_PREFIX +# define LLM_LOG_PREFIX ( "lua-lm" ) +# endif + +# define D(FORMAT...) { g_log (LLM_LOG_PREFIX, G_LOG_LEVEL_DEBUG, FORMAT); } +# define I(FORMAT...) { g_log (LLM_LOG_PREFIX, G_LOG_LEVEL_INFO, FORMAT); } +# define W(FORMAT...) { g_log (LLM_LOG_PREFIX, G_LOG_LEVEL_WARNING, FORMAT); } +# define E(FORMAT...) { g_log (LLM_LOG_PREFIX, G_LOG_LEVEL_ERROR, FORMAT); } #else -#define D(FORMAT...) { /* FORMAT */ } +# define D(FORMAT...) { /* FORMAT */ } +# define I(FORMAT...) { /* FORMAT */ } +# define W(FORMAT...) { /* FORMAT */ } +# define E(FORMAT...) { /* FORMAT */ } #endif #endif diff -r e617c9cf6dd3 -r 90073cbb535d lm.c --- a/lm.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm.c Fri Feb 20 23:07:43 2009 +0200 @@ -21,8 +21,8 @@ lua_rawset (L, LUA_REGISTRYINDEX); // 0 lua_createtable (L, 6, 0); - lua_pushvalue (L, -1); - lua_setglobal (L, "lm"); +// lua_pushvalue (L, -1); +// lua_setglobal (L, "lm"); luaopen_lm_message_node (L); luaopen_lm_message (L); diff -r e617c9cf6dd3 -r 90073cbb535d lm.lua --- a/lm.lua Mon Feb 16 01:32:12 2009 +0200 +++ b/lm.lua Fri Feb 20 23:07:43 2009 +0200 @@ -1,11 +1,11 @@ -require ( 'loudmouth' ) +lm = require 'loudmouth' -- argument is a table with keys, -- corresponding to method names. function lm.proxy.create ( a ) if type ( a ) ~= "table" then - error ( "arguments should be in a table" ) + error "arguments should be in a table" end local p = lm.proxy.new () if a.server then @@ -31,7 +31,7 @@ function lm.ssl.create ( a ) if not lm.ssl.supported () then -- XXX - -- error ( "ssl is not supported by your loudmouth library" ) + -- error "ssl is not supported by your loudmouth library" return nil end local fp, cb @@ -44,7 +44,7 @@ elseif st == "string" then fp = a elseif st ~= "nil" then - error ( "unexpected type of argument" ) + error "unexpected type of argument" end if fp then if cb then @@ -80,7 +80,7 @@ elseif at == "table" then local server = a.server if not server then - error ( "server name parameter required" ) + error "server name parameter required" end -- create connection object @@ -208,10 +208,10 @@ --]] function lm.message.create ( a ) if type ( a ) ~= "table" then - error ( "table expected as argument" ) + error "table expected as argument" end if not a.mtype or not a.to then - error ( "you must specify message type and destination" ) + error "you must specify message type and destination" end local mtype, subtype = a.mtype:match ( "(.-)%-(.+)" ) local m @@ -267,7 +267,7 @@ -- resource function lm.connect ( a ) if type ( a ) ~= "table" then - error ( "table expected as argument" ) + error "table expected as argument" end if a.ssl then if a.ssl.validate and not a.ssl.callback then diff -r e617c9cf6dd3 -r 90073cbb535d lm_connection.c --- a/lm_connection.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm_connection.c Fri Feb 20 23:07:43 2009 +0200 @@ -4,6 +4,7 @@ #include // GDestroyNotify, GMainContext #include +#include "config.h" #include "util.h" #include "lm_types.h" #include "lm_message.h" @@ -62,16 +63,15 @@ { const char *server = luaL_checkstring (L, 1); LmConnection *connection; - if (lua_gettop (L) < 2) { + if (lua_gettop (L) < 2) connection = lm_connection_new (server); - lua_pop (L, 1); - } else { + else { luaL_argcheck (L, lua_islightuserdata (L, 2), 2, "glib main context lightuserdata expected"); connection = lm_connection_new_with_context (server, (GMainContext *) lua_touserdata (L, 2)); - lua_pop (L, 2); } llm_connection_bless (L, connection); lm_connection_unref (connection); + D ("Connection %X created", (int) connection); return 1; } @@ -84,7 +84,6 @@ { luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "loudmouth connection lightuserdata expected"); llm_connection_bless (L, (LmConnection *) lua_touserdata (L, 1)); - lua_remove (L, -2); return 1; } @@ -99,37 +98,41 @@ // XXX lm_connection_unref (connection); lua_pushboolean (cb->L, success); if (lua_pcall (cb->L, 2, 0, 0)) { - // XXX lua_error (cb->L); + E ("Connection callback error: %s", lua_tostring (cb->L, -1)); lua_pop (cb->L, 1); - return; } } /// connection:open /// Opens connection to the server and then calls callback function. /// A: connection callback function -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_open (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); llm_callback_t *cb; luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected"); + GError *err; cb = luaL_malloc (L, sizeof (llm_callback_t)); cb->reference = luaL_ref (L, LUA_REGISTRYINDEX); cb->L = L; - lua_pushboolean (L, lm_connection_open (object->connection, - (LmResultFunction)llm_connection_callback, cb, - (GDestroyNotify)llm_callback_destroy, NULL)); - lua_remove (L, -2); - return 1; + if (lm_connection_open (object->connection, (LmResultFunction) llm_connection_callback, + cb, (GDestroyNotify) llm_callback_destroy, &err)) + return 1; + else { + lua_pushnil (L); + lua_pushstring (L, err->message); + W ("Connection opening failed"); + return 2; + } } /// connection:authenticate /// Tries to authenticate against opened connection, then calls callback function. /// A: string (username), string (password), string (resource), connection callback function -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_authenticate (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); @@ -138,72 +141,72 @@ const char *resource = luaL_checkstring (L, 4); llm_callback_t *cb; int status; + GError *err = NULL; luaL_argcheck (L, lua_isfunction (L, 5), 5, "function expected"); cb = luaL_malloc (L, sizeof (llm_callback_t)); cb->reference = luaL_ref (L, LUA_REGISTRYINDEX); cb->L = L; - status = lm_connection_authenticate (object->connection, username, password, resource, - (LmResultFunction)llm_connection_callback, cb, - (GDestroyNotify)llm_callback_destroy, NULL); - lua_pop (L, 4); - lua_pushboolean (L, status); - return 1; + if (lm_connection_authenticate (object->connection, username, password, resource, + (LmResultFunction) llm_connection_callback, cb, + (GDestroyNotify) llm_callback_destroy, &err)) { + lua_pop (L, 3); + return 1; + } else { + lua_pushnil (L); + lua_pushstring (L, err->message); + W ("Connection authentication failed: %s", err->message); + return 2; + } } /// connection:port /// Gets or sets server port to connect. /// A: integer (optional) -/// R: integer (when called with no args) +/// R: integer (when called with no args) or lm connection object static int llm_connection_port (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set lm_connection_set_port (object->connection, luaL_checkint (L, 2)); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get lua_pushnumber (L, lm_connection_get_port (object->connection)); - lua_remove (L, -2); - return 1; } + return 1; } /// connection:server /// Gets or sets server to connect to. /// A: string (optional, server name) -/// R: string (when called with no args) +/// R: string (when called with no args) or lm connection object static int llm_connection_server (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set lm_connection_set_server (object->connection, luaL_checkstring (L, 2)); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get lua_pushstring (L, lm_connection_get_server (object->connection)); - lua_remove (L, -2); - return 1; } + return 1; } /// connection:jid /// Gets or sets jid for connection. /// A: string (optional) -/// R: string (when called with no args) +/// R: string (when called with no args) or lm connection object static int llm_connection_jid (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set lm_connection_set_jid (object->connection, luaL_checkstring (L, 2)); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get lua_pushstring (L, lm_connection_get_jid (object->connection)); - lua_remove (L, -2); - return 1; } + return 1; } /// connection:keep_alive_rate @@ -211,39 +214,38 @@ /// Note, that on some platforms there is no get function even in /// loudmouth versions, that should have it according to documentation. /// integer (optional, seconds) -/// integer (when called with no args) +/// integer (when called with no args) or lm connection object or nil, string (error message, when get function is not available in loudmouth) static int llm_connection_keep_alive_rate (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set lm_connection_set_keep_alive_rate (object->connection, luaL_checkint (L, 2)); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); + return 1; } else { // Get #ifdef HAVE_LM_CONNECTION_GET_KEEP_ALIVE_RATE lua_pushnumber (L, lm_connection_get_keep_alive_rate (object->connection)); - lua_remove (L, -2); + return 1; #else - lua_pop (L, 1); - lua_pushstring (L, "Sorry, your loudmouth have no get_keep_alive_rate"); - lua_error (L); + E ("Sorry, your loudmouth have no get_keep_alive_rate ()"); + lua_pushnil (L); + lua_pushstring (L, "Sorry, your loudmouth have no get_keep_alive_rate ()"); + return 2; #endif - return 1; } } /// connection:proxy /// Gets or sets proxy server for connection. /// A: lm proxy object (optional) -/// R: lm proxy object or nil (when called with no args) +/// R: lm proxy object or nil (when called with no args) or lm connection object static int llm_connection_proxy (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set llm_proxy_t *proxy = luaL_checklm_proxy (L, 2); lm_connection_set_proxy (object->connection, proxy->proxy); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get LmProxy *proxy = lm_connection_get_proxy (object->connection); lua_pop (L, 1); @@ -252,22 +254,21 @@ // XXX lm_proxy_unref (proxy); } else lua_pushnil (L); - return 1; } + return 1; } /// connection:ssl /// Gets or sets ssl object for connection. /// A: lm ssl object (optional) -/// R: lm ssl object or nil (when called with no args) +/// R: lm ssl object or nil (when called with no args) or lm connection object static int llm_connection_ssl (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set llm_ssl_t *ssl = luaL_checklm_ssl (L, 2); lm_connection_set_ssl (object->connection, ssl->ssl); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get LmSSL *ssl = lm_connection_get_ssl (object->connection); lua_pop (L, 1); @@ -276,19 +277,25 @@ // XXX lm_ssl_unref (ssl); } else lua_pushnil (L); - return 1; } + return 1; } /// connection:close /// Close connection. -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_close (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); - lua_pushboolean (L, lm_connection_close (object->connection, NULL)); - lua_remove (L, -2); - return 1; + GError *err = NULL; + if (lm_connection_close (object->connection, &err)) + return 1; + else { + W ("Connection close failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:status @@ -298,7 +305,6 @@ { llm_connection_t *connection = luaL_checklm_connection (L, 1); luaL_pushenum (L, lm_connection_get_state (connection->connection), llm_connection_state); - lua_remove (L, -2); return 1; } @@ -307,14 +313,15 @@ /// receiving of response to that message. /// Handler function can be either message handler object or just a function. /// A: lm message object, message handler callback function or lm message handler object (optional) -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_send (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); llm_message_t *message = luaL_checklm_message (L, 2); int status; + GError *err = NULL; if (lua_gettop (L) < 3) // Send - status = lm_connection_send (object->connection, message->message, NULL); + status = lm_connection_send (object->connection, message->message, &err); else if (lua_isfunction (L, 3)) { // Send w/reply, func llm_callback_t *cb = luaL_malloc (L, sizeof (llm_callback_t)); LmMessageHandler *handler; @@ -325,31 +332,43 @@ (LmHandleMessageFunction)llm_message_handler_callback, cb, (GDestroyNotify)llm_callback_destroy); status = lm_connection_send_with_reply (object->connection, - message->message, handler, NULL); + message->message, handler, &err); lm_message_handler_unref (handler); } else { // Send w/reply, handler llm_message_handler_t *handler = luaL_checklm_message_handler (L, 3); status = lm_connection_send_with_reply (object->connection, message->message, - handler->message_handler, NULL); + handler->message_handler, &err); lua_pop (L, 1); }; - lua_pop (L, 2); - lua_pushboolean (L, status); - return 1; + lua_pop (L, 1); + if (status) + return 1; + else { + W ("Message sending failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:send_raw /// Sends arbitrary string to opened connection. /// A: string -/// R: boolean (status) +/// R: lm connection object or nil, string (error message) static int llm_connection_send_raw (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); const char *string = luaL_checkstring (L, 2); - int status = lm_connection_send_raw (object->connection, string, NULL); - lua_pop (L, 2); - lua_pushboolean (L, status); - return 1; + GError *err = NULL; + if (lm_connection_send_raw (object->connection, string, NULL)) { + lua_pop (L, 1); + return 1; + } else { + W ("Raw message sending failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:handler @@ -358,6 +377,7 @@ /// Handler function can be specified as plain function or message handler object. /// Though, you can unregister only a message handler object. /// A: message handler callback function or lm message handler object, message type, handler priority (optional) +/// R: lm connection object static int llm_connection_handler (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); @@ -393,7 +413,7 @@ type); } lua_pop (L, 2); - return 0; + return 1; } /// disconnect callback function @@ -406,15 +426,15 @@ // XXX lm_connection_unref (connection); luaL_pushenum (cb->L, reason, llm_disconnect_reason); if (lua_pcall (cb->L, 2, 0, 0)) { - // XXX lua_error (cb->L); + E ("Disconnect callback error: %s", lua_tostring (cb->L, -1)); lua_pop (cb->L, 1); - return; } } /// connection:ondisconnect /// Sets callback, that will be called on connection disconnect. /// A: disconnect callback function +/// R: lm connection object static int llm_connection_ondisconnect (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); @@ -428,56 +448,69 @@ lm_connection_set_disconnect_function (object->connection, (LmDisconnectFunction)llm_disconnect_callback, cb, (GDestroyNotify)llm_callback_destroy); - lua_pop (L, 1); - return 0; + return 1; } /// connection:open_wait /// Synchronous open call, that will block until connection will be opened. -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_open_wait (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); - lua_pushboolean (L, lm_connection_open_and_block (object->connection, NULL)); - lua_remove (L, -2); - return 1; + GError *err = NULL; + if (lm_connection_open_and_block (object->connection, &err)) + return 1; + else { + W ("Synchronous connection opening failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:authenticate_wait /// Synchronous authentication call, that will wait until the end of authentication. /// A: string (username), string (password), string (resource) -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_authenticate_wait (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); const char *username = luaL_checkstring (L, 2); const char *password = luaL_checkstring (L, 3); const char *resource = luaL_checkstring (L, 4); - int status = lm_connection_authenticate_and_block (object->connection, username, - password, resource, NULL); - lua_pop (L, 4); - lua_pushboolean (L, status); - return 1; + GError *err = NULL; + if (lm_connection_authenticate_and_block (object->connection, username, + password, resource, &err)) + return 1; + else { + W ("Synchronous authentication failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:send_wait /// Synchronous call, that will send message and wait for reply to it. /// A: lm message object -/// R: lm message object or nil +/// R: lm message object or nil, string (error message) static int llm_connection_send_wait (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); llm_message_t *message = luaL_checklm_message (L, 2); + GError *err = NULL; LmMessage *new = lm_connection_send_with_reply_and_block (object->connection, - message->message, NULL); - lua_pop (L, 2); - if (!new) + message->message, &err); + if (!new) { + W ("Synchronous message sending failed: %s", err->message); lua_pushnil (L); - else { + lua_pushstring (L, err->message); + return 2; + } else { llm_message_bless (L, new); lm_message_unref (new); // XXX + return 1; } - return 1; } /// connection:pointer @@ -494,8 +527,8 @@ static int llm_connection_gc (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); + D ("Connection %X gc called", (int) object); lm_connection_unref (object->connection); - lua_pop (L, 1); return 0; } diff -r e617c9cf6dd3 -r 90073cbb535d lm_message.c --- a/lm_message.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm_message.c Fri Feb 20 23:07:43 2009 +0200 @@ -3,6 +3,7 @@ #include #include +#include "config.h" #include "util.h" #include "lm_types.h" @@ -31,6 +32,8 @@ { "stream:stream", LM_MESSAGE_TYPE_STREAM }, { "stream:error", LM_MESSAGE_TYPE_STREAM_ERROR }, { "stream:features", LM_MESSAGE_TYPE_STREAM_FEATURES }, + { "stream_error", LM_MESSAGE_TYPE_STREAM_ERROR }, + { "stream_features", LM_MESSAGE_TYPE_STREAM_FEATURES }, { NULL, 0 }, }; @@ -67,15 +70,14 @@ const char *to = luaL_checkstring (L, 1); int type = luaL_checkenum (L, 2, llm_message_type); LmMessage *message; - if (lua_gettop (L) > 2) { + if (lua_gettop (L) > 2) message = lm_message_new_with_sub_type (to, type, luaL_checkenum (L, 3, llm_message_sub_type)); - lua_pop (L, 1); - } else + else message = lm_message_new (to, type); - lua_pop (L, 2); llm_message_bless (L, message); lm_message_unref (message); + D ("Message %X created", (int) message); return 1; } @@ -87,7 +89,6 @@ { luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "lm message lightuserdata expected"); llm_message_bless (L, lua_touserdata (L, 1)); - lua_remove (L, -2); return 1; } @@ -100,10 +101,12 @@ LmMessageNode *node = lm_message_get_node (object->message); llm_message_node_bless (L, node); // XXX lm_message_node_unref (node); - lua_remove (L, -2); return 1; } +// XXX: add node methods here to allow omitting of :node(): element +// BTW, we can jus adapt node methods to work on messages too and register them here also + /// message:type /// Returns two strings: message type and message sub type. /// R: message type, message sub type @@ -112,7 +115,6 @@ llm_message_t *object = luaL_checklm_message (L, 1); luaL_pushenum (L, lm_message_get_type (object->message), llm_message_type); luaL_pushenum (L, lm_message_get_sub_type (object->message), llm_message_sub_type); - lua_remove (L, -3); return 2; } @@ -123,15 +125,14 @@ { llm_message_t *object = luaL_checklm_message (L, 1); lua_pushlightuserdata (L, object->message); - lua_remove (L, -2); return 1; } static int llm_message_gc (lua_State *L) { - llm_message_t *object = luaL_checklm_message (L, 1); - lm_message_unref (object->message); - lua_pop (L, 1); + llm_message_t *message = luaL_checklm_message (L, 1); + D ("Message %X gc called", (int) message); + lm_message_unref (message->message); return 0; } diff -r e617c9cf6dd3 -r 90073cbb535d lm_message_handler.c --- a/lm_message_handler.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm_message_handler.c Fri Feb 20 23:07:43 2009 +0200 @@ -4,6 +4,7 @@ #include #include +#include "config.h" #include "lm_types.h" #include "util.h" @@ -25,7 +26,7 @@ llm_message_bless (cb->L, message); // XXX lm_message_unref (message); if (lua_pcall (cb->L, 2, 1, 0)) { - // XXX lua_error (cb->L); + E ("Message handler callback error: %s", lua_tostring (cb->L, -1)); lua_pop (cb->L, 1); return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; } @@ -55,6 +56,7 @@ cb, (GDestroyNotify)llm_callback_destroy); llm_message_handler_bless (L, handler); lm_message_handler_unref (handler); // XXX + D ("Message handler %X created", (int) handler); return 1; } @@ -66,18 +68,18 @@ { luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "loudmouth message handler pointer expected"); llm_message_handler_bless (L, lua_touserdata (L, 1)); - lua_remove (L, -2); return 1; } +// XXX: merge with next? /// message_handler:invalidate /// Invalidates handler. +/// R: lm message handler object static int llm_message_handler_invalidate (lua_State *L) { llm_message_handler_t *object = luaL_checklm_message_handler (L, 1); lm_message_handler_invalidate (object->message_handler); - lua_pop (L, 1); - return 0; + return 1; } /// message_handler:valid @@ -87,7 +89,6 @@ { llm_message_handler_t *object = luaL_checklm_message_handler (L, 1); lua_pushboolean (L, lm_message_handler_is_valid (object->message_handler)); - lua_remove (L, -2); return 1; } @@ -98,15 +99,14 @@ { llm_message_handler_t *object = luaL_checklm_message_handler (L, 1); lua_pushlightuserdata (L, object->message_handler); - lua_remove (L, -2); return 1; } static int llm_message_handler_gc (lua_State *L) { llm_message_handler_t *object = luaL_checklm_message_handler (L, 1); + D ("Message handler %X gc called", (int) object); lm_message_handler_unref (object->message_handler); - lua_pop (L, 1); return 0; } diff -r e617c9cf6dd3 -r 90073cbb535d lm_message_node.c --- a/lm_message_node.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm_message_node.c Fri Feb 20 23:07:43 2009 +0200 @@ -3,6 +3,7 @@ #include #include +#include "config.h" #include "lm_types.h" /// lm.message_node @@ -17,7 +18,6 @@ { luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "loudmouth message node lightuserdata expected"); llm_message_node_bless (L, lua_touserdata (L, 1)); - lua_remove (L, -2); return 1; } @@ -28,7 +28,6 @@ { llm_message_node_t *object = luaL_checklm_message_node (L, 1); lua_pushstring (L, object->message_node->name); - lua_remove (L, -2); return 1; } @@ -43,7 +42,6 @@ llm_message_node_bless (L, node); else lua_pushnil (L); - lua_remove (L, -2); return 1; } @@ -58,7 +56,6 @@ llm_message_node_bless (L, node); else lua_pushnil (L); - lua_remove (L, -2); return 1; } @@ -73,7 +70,6 @@ llm_message_node_bless (L, node); else lua_pushnil (L); - lua_remove (L, -2); return 1; } @@ -88,27 +84,23 @@ llm_message_node_bless (L, node); else lua_pushnil (L); - lua_remove (L, -2); return 1; } /// message_node:value /// Gets or sets a value of message node. /// A: string (optional value) -/// R: string (if called without arguments) +/// R: string (if called without arguments) or lm message node object static int llm_message_node_value (lua_State *L) { llm_message_node_t *object = luaL_checklm_message_node (L, 1); if (lua_gettop (L) > 1) { // Set const char *value = luaL_checkstring (L, 2); lm_message_node_set_value (object->message_node, value); - lua_pop (L, 2); - return 0; - } else { // Get + lua_pop (L, 1); + } else // Get lua_pushstring (L, lm_message_node_get_value (object->message_node)); - lua_remove (L, -2); - return 1; - } + return 1; } /// message_node:child @@ -121,11 +113,10 @@ const char *name = luaL_checkstring (L, 2); LmMessageNode *child; - if (lua_gettop (L) > 2) { // Add + if (lua_gettop (L) > 2) // Add child = lm_message_node_add_child (object->message_node, name, luaL_checkstring (L, 3)); - lua_pop (L, 1); - } else { // Get + else { // Get child = lm_message_node_get_child (object->message_node, name); if (!child) { lua_pushnil (L); @@ -134,8 +125,6 @@ } llm_message_node_bless (L, child); // XXX lm_message_node_unref (child); - lua_remove (L, -2); - lua_remove (L, -2); return 1; } @@ -156,8 +145,6 @@ llm_message_node_bless (L, child); // XXX lm_message_node_unref (child); } - lua_remove (L, -2); - lua_remove (L, -2); return 1; } @@ -165,40 +152,33 @@ /// Gets or sets raw mode flag for node. /// When set, value of node will not be escaped. /// A: boolean (optional) -/// V: boolean (if called with no apguments) +/// V: boolean (if called with no apguments) or lm message node object static int llm_message_node_raw (lua_State *L) { llm_message_node_t *object = luaL_checklm_message_node (L, 1); if (lua_gettop (L) > 1) { // Set luaL_checktype (L, 2, LUA_TBOOLEAN); lm_message_node_set_raw_mode (object->message_node, lua_toboolean (L, 2)); - lua_pop (L, 2); - return 0; - } else { // Get + lua_pop (L, 1); + } else // Get lua_pushboolean (L, lm_message_node_get_raw_mode (object->message_node)); - lua_remove (L, -2); - return 1; - } + return 1; } /// message_node:attribute /// Gets or sets value of node attribute with a given name. /// A: string (name), string (optional value) -/// R: string (when called with one aprgument) +/// R: string (when called with one aprgument) or lm message node object static int llm_message_node_attribute (lua_State *L) { llm_message_node_t *object = luaL_checklm_message_node (L, 1); const char *name = luaL_checkstring (L, 2); if (lua_gettop (L) > 2) { // Set lm_message_node_set_attribute (object->message_node, name, luaL_checkstring (L, 3)); - lua_pop (L, 3); - return 0; - } else { // Get + lua_pop (L, 2); + } else // Get lua_pushstring (L, lm_message_node_get_attribute (object->message_node, name)); - lua_remove (L, -2); - lua_remove (L, -2); - return 1; - } + return 1; } /// message_node:xml @@ -208,7 +188,6 @@ { llm_message_node_t *object = luaL_checklm_message_node (L, 1); lua_pushstring (L, lm_message_node_to_string (object->message_node)); - lua_remove (L, -2); return 1; } @@ -219,15 +198,14 @@ { llm_message_node_t *object = luaL_checklm_message_node (L, 1); lua_pushlightuserdata (L, object->message_node); - lua_remove (L, -2); return 1; } static int llm_message_node_gc (lua_State *L) { llm_message_node_t *object = luaL_checklm_message_node (L, 1); + D ("Message node %X gc called", (int) object); lm_message_node_unref (object->message_node); - lua_pop (L, 1); return 0; } diff -r e617c9cf6dd3 -r 90073cbb535d lm_proxy.c --- a/lm_proxy.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm_proxy.c Fri Feb 20 23:07:43 2009 +0200 @@ -4,6 +4,7 @@ #include #include +#include "config.h" #include "util.h" #include "lm_types.h" @@ -30,15 +31,13 @@ { int type = luaL_checkenum (L, 1, llm_proxy_type); LmProxy *proxy; - if (lua_gettop (L) > 0) { + if (lua_gettop (L) > 0) proxy = lm_proxy_new_with_server (type, luaL_checkstring (L, 2), luaL_checkint (L, 3)); - lua_pop (L, 3); - } else { + else proxy = lm_proxy_new (type); - lua_pop (L, 1); - } llm_proxy_bless (L, proxy); lm_proxy_unref (proxy); // XXX + D ("Proxy %X created", (int) proxy); return 1; } @@ -50,98 +49,82 @@ { luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "lm proxy lightuserdata expected"); llm_proxy_bless (L, lua_touserdata (L, 1)); - lua_remove (L, -2); return 1; } /// proxy:type /// Gets or sets proxy server type. /// A: proxy type (optional) -/// R: proxy type (when called with no args) +/// R: proxy type (when called with no args) or lm proxy object static int llm_proxy_kind (lua_State *L) { llm_proxy_t *proxy = luaL_checklm_proxy (L, 1); if (lua_gettop (L) > 1) { // Set lm_proxy_set_type (proxy->proxy, luaL_checkenum (L, 2, llm_proxy_type)); - lua_pop (L, 2); - return 0; - } else { // Get + lua_pop (L, 1); + } else // Get luaL_pushenum (L, lm_proxy_get_type (proxy->proxy), llm_proxy_type); - lua_remove (L, -2); - return 1; - } + return 1; } /// proxy:server /// Gets or sets proxy server name. /// A: string (optional) -/// R: string (when called with no args) +/// R: string (when called with no args) or lm proxy object static int llm_proxy_server (lua_State *L) { llm_proxy_t *object = luaL_checklm_proxy (L, 1); if (lua_gettop (L) > 1) { // Set lm_proxy_set_server (object->proxy, luaL_checkstring (L, 2)); - lua_pop (L, 2); - return 0; - } else { // Get + lua_pop (L, 1); + } else // Get lua_pushstring (L, lm_proxy_get_server (object->proxy)); - lua_remove (L, -2); - return 1; - } + return 1; } /// proxy:port /// Gets or sets proxy server port. /// A: integer (optional) -/// R: integer (when called with no args) +/// R: integer (when called with no args) or lm proxy object static int llm_proxy_port (lua_State *L) { llm_proxy_t *object = luaL_checklm_proxy (L, 1); if (lua_gettop (L) > 1) { // Set lm_proxy_set_port (object->proxy, luaL_checkint (L, 2)); - lua_pop (L, 2); - return 0; - } else { // Get + lua_pop (L, 1); + } else // Get lua_pushnumber (L, lm_proxy_get_port (object->proxy)); - lua_remove (L, -2); - return 1; - } + return 1; } /// proxy:username /// Gets or sets username to authenticate to proxy server with. /// A: string (optional) -/// R: string (when called with no args) +/// R: string (when called with no args) or lm proxy object static int llm_proxy_username (lua_State *L) { llm_proxy_t *object = luaL_checklm_proxy (L, 1); if (lua_gettop (L) > 1) { // Set lm_proxy_set_username (object->proxy, luaL_checkstring (L, 2)); - lua_pop (L, 2); - return 0; - } else { // Get + lua_pop (L, 1); + } else // Get lua_pushstring (L, lm_proxy_get_username (object->proxy)); - lua_remove (L, -2); - return 1; - } + return 1; } /// proxy:password /// Gets or sets password to authenticate to proxy server with. /// A: string (optional) -/// R: string (when called with no args) +/// R: string (when called with no args) or lm proxy object static int llm_proxy_password (lua_State *L) { llm_proxy_t *object = luaL_checklm_proxy (L, 1); if (lua_gettop (L) > 1) { // Set lm_proxy_set_password (object->proxy, luaL_checkstring (L, 2)); - lua_pop (L, 2); - return 0; - } else { // Get + lua_pop (L, 1); + } else // Get lua_pushstring (L, lm_proxy_get_password (object->proxy)); - lua_remove (L, -2); - return 1; - } + return 1; } /// proxy:pointer @@ -151,15 +134,14 @@ { llm_proxy_t *object = luaL_checklm_proxy (L, 1); lua_pushlightuserdata (L, object->proxy); - lua_remove (L, -2); return 1; } static int llm_proxy_gc (lua_State *L) { llm_proxy_t *object = luaL_checklm_proxy (L, 1); + D ("Proxy %X gc called", (int) object); lm_proxy_unref (object->proxy); - lua_pop (L, 1); return 0; } diff -r e617c9cf6dd3 -r 90073cbb535d lm_ssl.c --- a/lm_ssl.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm_ssl.c Fri Feb 20 23:07:43 2009 +0200 @@ -5,6 +5,7 @@ #include #include +#include "config.h" #include "util.h" #include "lm_types.h" @@ -40,7 +41,7 @@ // XXX lm_ssl_unref (ssl); luaL_pushenum (cb->L, status, llm_ssl_status); if (lua_pcall (cb->L, 2, 0, 0)) { - // XXX lua_error (cb->L); + E ("SSL callback error: %s", lua_tostring (cb->L, -1)); lua_pop (cb->L, 1); return LM_SSL_RESPONSE_CONTINUE; } @@ -82,7 +83,6 @@ if (lua_objlen (L, 1) > 46) string2fingerprint (fingerprint, buffer); ssl = lm_ssl_new (buffer, NULL, NULL, NULL); - lua_pop (L, 1); } else { llm_callback_t *cb; gchar buffer[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; @@ -101,10 +101,10 @@ ssl = lm_ssl_new ((args > 1) ? buffer : NULL, (LmSSLFunction)llm_ssl_callback, cb, (GDestroyNotify)llm_callback_destroy); - lua_pop (L, 1); } llm_ssl_bless (L, ssl); lm_ssl_unref (ssl); // XXX + D ("SSL %X created", (int) ssl); return 1; } @@ -116,7 +116,6 @@ { luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "lm ssl lightuserdata expected"); llm_ssl_bless (L, lua_touserdata (L, 1)); - lua_remove (L, -2); return 1; } @@ -149,7 +148,6 @@ fingerprint[12], fingerprint[13], fingerprint[14], fingerprint[15]); lua_pushlstring (L, buffer, 47); } - lua_remove (L, -2); return 1; } @@ -160,15 +158,14 @@ { llm_ssl_t *object = luaL_checklm_ssl (L, 1); lua_pushlightuserdata (L, object->ssl); - lua_remove (L, -2); return 1; } static int llm_ssl_gc (lua_State *L) { llm_ssl_t *object = luaL_checklm_ssl (L, 1); + D ("SSL %X gc called", (int) object); lm_ssl_unref (object->ssl); - lua_pop (L, 1); return 0; } diff -r e617c9cf6dd3 -r 90073cbb535d lm_types.c --- a/lm_types.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm_types.c Fri Feb 20 23:07:43 2009 +0200 @@ -3,11 +3,13 @@ #include #include // lm_*ref +#include "config.h" #include "lm_types.h" #include "util.h" void llm_callback_destroy (llm_callback_t *cb) { + D ("Destroying callback %X", (int) cb); luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference); luaL_free (cb->L, cb); } @@ -31,6 +33,7 @@ if (!lua_isnil (L, -1)) { /* 2 object */ \ lua_remove (L, -2); /* 1 object */ \ object = lua_touserdata (L, -1); \ + D ("Existing " #WHAT " object %X requested", (int) object); \ return object; \ } \ /* 2 nil */ \ @@ -44,6 +47,7 @@ lua_remove (L, -2); /* 1 object */ \ object->WHAT = WHAT; \ lm_##WHAT##_ref (WHAT); \ + D ("New " #WHAT " object %X blessed", (int) object); \ return object; \ } diff -r e617c9cf6dd3 -r 90073cbb535d util.h --- a/util.h Mon Feb 16 01:32:12 2009 +0200 +++ b/util.h Fri Feb 20 23:07:43 2009 +0200 @@ -9,6 +9,8 @@ #define enum_value_t int #endif +#define lua_pushconststring(L, STRING) { lua_pushlstring (L, STRING, sizeof(STRING)); } + // Array of string2eunm_t's must be ended with pair { NULL, fallback_value } typedef struct { const char *string;