Message have node methods
authorMyhailo Danylenko <isbear@ukrpost.net>
Sat, 21 Feb 2009 12:43:51 +0200
changeset 7 5db1448eb857
parent 6 90073cbb535d
child 8 951f92c66821
Message have node methods
CMakeLists.txt
TODO
lm.c
lm.lua
lm_message.c
lm_message_node.c
lm_message_node.h
lm_types.c
lm_types.h
--- a/CMakeLists.txt	Fri Feb 20 23:07:43 2009 +0200
+++ b/CMakeLists.txt	Sat Feb 21 12:43:51 2009 +0200
@@ -52,7 +52,7 @@
 
 ## Extra targets
 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_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()
 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)
--- a/TODO	Fri Feb 20 23:07:43 2009 +0200
+++ b/TODO	Sat Feb 21 12:43:51 2009 +0200
@@ -1,4 +1,5 @@
 
 Verify refcounts of lm objects. Need a decent test script for that.
 Some additional lua functions?
+Path node/message method to traverse path and return nil or node
 
--- a/lm.c	Fri Feb 20 23:07:43 2009 +0200
+++ b/lm.c	Sat Feb 21 12:43:51 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);
--- a/lm.lua	Fri Feb 20 23:07:43 2009 +0200
+++ b/lm.lua	Sat Feb 21 12:43:51 2009 +0200
@@ -1,5 +1,5 @@
 
-lm = require 'loudmouth'
+require 'loudmouth'
 
 -- argument is a table with keys,
 -- corresponding to method names.
@@ -149,7 +149,7 @@
 
 		return c
 	else
-		error ( "at least server name parameter required" )
+		error "at least server name parameter required"
 	end
 end
 
@@ -222,7 +222,7 @@
 	end
 	a.to = nil
 	a.mtype = nil
-	lm.message_node.fill ( m:node(), a )
+	lm.message_node.fill ( m, a )
 	return m
 end
 
@@ -244,17 +244,16 @@
 -- There are NO WAY to get a list of node attributes,
 -- except brute force...
 function lm.message.parse ( message )
-	local node = message:node ()
 	local mtype, subtype = message:type ()
 	if subtype then
 		mtype = mtype .. '-' .. subtype
 	end
 	local r = { mtype = mtype }
-	local value = node:value ()
+	local value = message:value ()
 	if value then
 		r[1] = value
 	end
-	lm.message_node.parse ( node, r )
+	lm.message_node.parse ( message, r )
 	return r
 end
 
--- a/lm_message.c	Fri Feb 20 23:07:43 2009 +0200
+++ b/lm_message.c	Sat Feb 21 12:43:51 2009 +0200
@@ -6,6 +6,7 @@
 #include "config.h"
 #include "util.h"
 #include "lm_types.h"
+#include "lm_message_node.h"
 
 /// lm.message
 /// Module, representing individual message.
@@ -104,9 +105,6 @@
 	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
@@ -143,11 +141,23 @@
 };
 
 static const luaL_Reg llm_message_reg_m[] = {
-	{ "node",    llm_message_node    },
-	{ "type",    llm_message_kind    },
-	{ "pointer", llm_message_pointer },
-	{ "__gc",    llm_message_gc      },
-	{ NULL,      NULL                },
+	{ "node",       llm_message_node            },
+	{ "type",       llm_message_kind            },
+	// These methods are common for message and message node
+	{ "next",       llm_message_node_next       },
+	{ "prev",       llm_message_node_prev       },
+	{ "children",   llm_message_node_children   },
+	{ "parent",     llm_message_node_parent     },
+	{ "value",      llm_message_node_value      },
+	{ "child",      llm_message_node_child      },
+	{ "find_child", llm_message_node_find_child },
+	{ "attribute",  llm_message_node_attribute  },
+	{ "raw",        llm_message_node_raw        },
+	{ "xml",        llm_message_node_xml        },
+	// End common methods
+	{ "pointer",    llm_message_pointer         },
+	{ "__gc",       llm_message_gc              },
+	{ NULL,         NULL                        },
 };
 
 int luaopen_lm_message (lua_State *L)
--- a/lm_message_node.c	Fri Feb 20 23:07:43 2009 +0200
+++ b/lm_message_node.c	Sat Feb 21 12:43:51 2009 +0200
@@ -24,22 +24,22 @@
 /// message_node:name
 /// Gets a name of message node.
 /// R: string
-static int llm_message_node_name (lua_State *L)
+int llm_message_node_name (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
-	lua_pushstring (L, object->message_node->name);
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
+	lua_pushstring (L, node->name);
 	return 1;
 }
 
 /// message_node:next
 /// Gets next message node.
 /// R: lm message node object or nil
-static int llm_message_node_next (lua_State *L)
+int llm_message_node_next (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
-	LmMessageNode *node = object->message_node->next;
-	if (node)
-		llm_message_node_bless (L, node);
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
+	LmMessageNode *next = node->next;
+	if (next)
+		llm_message_node_bless (L, next);
 	else
 		lua_pushnil (L);
 	return 1;
@@ -48,12 +48,12 @@
 /// message_node:prev
 /// Gets previous message node.
 /// R: lm message node object or nil
-static int llm_message_node_prev (lua_State *L)
+int llm_message_node_prev (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
-	LmMessageNode *node = object->message_node->prev;
-	if (node)
-		llm_message_node_bless (L, node);
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
+	LmMessageNode *prev = node->prev;
+	if (prev)
+		llm_message_node_bless (L, prev);
 	else
 		lua_pushnil (L);
 	return 1;
@@ -62,12 +62,12 @@
 /// message_node:children
 /// Gets first child node (raw access used).
 /// R: lm message node object or nil
-static int llm_message_node_children (lua_State *L)
+int llm_message_node_children (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
-	LmMessageNode *node = object->message_node->children;
-	if (node)
-		llm_message_node_bless (L, node);
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
+	LmMessageNode *child = node->children;
+	if (child)
+		llm_message_node_bless (L, child);
 	else
 		lua_pushnil (L);
 	return 1;
@@ -76,12 +76,12 @@
 /// message_node:parent
 /// Gets parent message node.
 /// R: lm message node object or nil
-static int llm_message_node_parent (lua_State *L)
+int llm_message_node_parent (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
-	LmMessageNode *node = object->message_node->parent;
-	if (node)
-		llm_message_node_bless (L, node);
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
+	LmMessageNode *parent = node->parent;
+	if (parent)
+		llm_message_node_bless (L, parent);
 	else
 		lua_pushnil (L);
 	return 1;
@@ -91,15 +91,15 @@
 /// Gets or sets a value of message node.
 /// A: string (optional value)
 /// R: string (if called without arguments) or lm message node object
-static int llm_message_node_value (lua_State *L)
+int llm_message_node_value (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
 	if (lua_gettop (L) > 1) { // Set
 		const char *value = luaL_checkstring (L, 2);
-		lm_message_node_set_value (object->message_node, value);
+		lm_message_node_set_value (node, value);
 		lua_pop (L, 1);
 	} else // Get
-		lua_pushstring (L, lm_message_node_get_value (object->message_node));
+		lua_pushstring (L, lm_message_node_get_value (node));
 	return 1;
 }
 
@@ -107,17 +107,17 @@
 /// Gets or creates child node object with given name.
 /// A: string (name), string (optional value)
 /// R: lm message node object or nil
-static int llm_message_node_child (lua_State *L)
+int llm_message_node_child (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
 	const char *name = luaL_checkstring (L, 2);
 	LmMessageNode *child;
 
 	if (lua_gettop (L) > 2) // Add
-		child = lm_message_node_add_child (object->message_node, name,
+		child = lm_message_node_add_child (node, name,
 						   luaL_checkstring (L, 3));
 	else { // Get
-		child = lm_message_node_get_child (object->message_node, name);
+		child = lm_message_node_get_child (node, name);
 		if (!child) {
 			lua_pushnil (L);
 			return 1;
@@ -132,13 +132,13 @@
 /// Searches for node with a given name over all node subtree.
 /// A: string (name)
 /// R: lm message node object or nil
-static int llm_message_node_find_child (lua_State *L)
+int llm_message_node_find_child (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
 	const char *name = luaL_checkstring (L, 2);
 	LmMessageNode *child;
 
-	child = lm_message_node_get_child (object->message_node, name);
+	child = lm_message_node_get_child (node, name);
 	if (!child)
 		lua_pushnil (L);
 	else {
@@ -153,15 +153,15 @@
 /// When set, value of node will not be escaped.
 /// A: boolean (optional)
 /// V: boolean (if called with no apguments) or lm message node object
-static int llm_message_node_raw (lua_State *L)
+int llm_message_node_raw (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+	LmMessageNode *node = luaL_checkLmMessageNode (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));
+		lm_message_node_set_raw_mode (node, lua_toboolean (L, 2));
 		lua_pop (L, 1);
 	} else // Get
-		lua_pushboolean (L, lm_message_node_get_raw_mode (object->message_node));
+		lua_pushboolean (L, lm_message_node_get_raw_mode (node));
 	return 1;
 }
 
@@ -169,25 +169,25 @@
 /// Gets or sets value of node attribute with a given name.
 /// A: string (name), string (optional value)
 /// R: string (when called with one aprgument) or lm message node object
-static int llm_message_node_attribute (lua_State *L)
+int llm_message_node_attribute (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
+	LmMessageNode *node = luaL_checkLmMessageNode (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));
+		lm_message_node_set_attribute (node, name, luaL_checkstring (L, 3));
 		lua_pop (L, 2);
 	} else // Get
-		lua_pushstring (L, lm_message_node_get_attribute (object->message_node, name));
+		lua_pushstring (L, lm_message_node_get_attribute (node, name));
 	return 1;
 }
 
 /// message_node:xml
 /// Returns node representation in xml.
 /// R: string
-static int llm_message_node_xml (lua_State *L)
+int llm_message_node_xml (lua_State *L)
 {
-	llm_message_node_t *object = luaL_checklm_message_node (L, 1);
-	lua_pushstring (L, lm_message_node_to_string (object->message_node));
+	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
+	lua_pushstring (L, lm_message_node_to_string (node));
 	return 1;
 }
 
--- a/lm_message_node.h	Fri Feb 20 23:07:43 2009 +0200
+++ b/lm_message_node.h	Sat Feb 21 12:43:51 2009 +0200
@@ -4,6 +4,18 @@
 
 #include <lua.h>
 
+int llm_message_node_name (lua_State *L);
+int llm_message_node_next (lua_State *L);
+int llm_message_node_prev (lua_State *L);
+int llm_message_node_children (lua_State *L);
+int llm_message_node_parent (lua_State *L);
+int llm_message_node_value (lua_State *L);
+int llm_message_node_child (lua_State *L);
+int llm_message_node_find_child (lua_State *L);
+int llm_message_node_raw (lua_State *L);
+int llm_message_node_attribute (lua_State *L);
+int llm_message_node_xml (lua_State *L);
+
 int luaopen_lm_message_node (lua_State *L);
 
 #endif
--- a/lm_types.c	Fri Feb 20 23:07:43 2009 +0200
+++ b/lm_types.c	Sat Feb 21 12:43:51 2009 +0200
@@ -62,5 +62,23 @@
 LLM_DEFINE (proxy, LmProxy)
 LLM_DEFINE (ssl, LmSSL)
 
+LmMessageNode *luaL_checkLmMessageNode (lua_State *L, int index)
+{
+	void *object;
+	luaL_argcheck (L, lua_type (L, index) == LUA_TUSERDATA, index, "loudmouth message or message node expected");
+	object = lua_touserdata (L, index);
+	lua_getmetatable (L, index);
+	luaL_getmetatable (L, "loudmouth.message");
+	luaL_getmetatable (L, "loudmouth.message_node");
+	if (lua_rawequal (L, -2, -3)) // Message
+		object = (void *) lm_message_get_node (((llm_message_t *) object)->message);
+	else if (lua_rawequal (L, -1, -3)) // Node
+		object = (void *) (((llm_message_node_t *) object)->message_node);
+	else
+		luaL_argerror (L, index, "loudmouth message or message node expected");
+	lua_pop (L, 3);
+	return (LmMessageNode *) object;
+}
+
 #undef LLM_DEFINE
 
--- a/lm_types.h	Fri Feb 20 23:07:43 2009 +0200
+++ b/lm_types.h	Sat Feb 21 12:43:51 2009 +0200
@@ -31,6 +31,8 @@
 LLM_DECLARE (proxy, LmProxy)
 LLM_DECLARE (ssl, LmSSL)
 
+LmMessageNode *luaL_checkLmMessageNode (lua_State *L, int index);
+
 #undef LLM_DECLARE
 
 #endif