lm_message_node.c
changeset 39 c5a487f2fd7f
parent 38 34a2b880615c
child 45 1fcec4b012a7
--- a/lm_message_node.c	Sun Jul 03 22:17:16 2011 +0300
+++ b/lm_message_node.c	Tue Jul 05 04:17:47 2011 +0300
@@ -135,14 +135,57 @@
 	return 1;
 }
 
+static int children_iterator_lm_node (lua_State *L)
+{
+	const char    *name = lua_tostring (L, lua_upvalueindex (1));
+	LmMessageNode *node;
+	if (lua_type (L, 2) == LUA_TUSERDATA) {
+		node = luaL_checkLmMessageNode (L, 2);
+		node = node -> next;
+	} else {
+		node = luaL_checkLmMessageNode (L, 1);
+		node = node -> children;
+	}
+
+	if (name)
+		while (node && g_strcmp0 (node -> name, name))
+			node = node -> next;
+
+	if (node)
+		bless_lm_node (L, node);
+		// XXX lm_message_node_unref (child); // may be necessary on _get/_add'ed nodes
+	else
+		lua_pushnil (L);
+
+	return 1;
+}
+
+/// message_node:children
+/// Returns iterator over child nodes of given node. Optionally filters childs by name.
+/// A: string (name, optional)
+/// R: iterator function, lm message node object, nil
+int children_lm_node (lua_State *L)
+{
+	LmMessageNode *node  = luaL_checkLmMessageNode (L, 1);
+	
+	if (lua_type (L, 2) != LUA_TSTRING)
+		lua_pushnil (L);
+
+	lua_pushcclosure (L, children_iterator_lm_node, 1);
+	lua_pushvalue (L, 1);
+	lua_pushnil (L);
+	
+	return 3;
+}
+
 /// message_node:find_child
 /// Searches for node with a given name over all node subtree.
 /// A: string (name)
 /// R: lm message node object or nil
 int find_child_lm_node (lua_State *L)
 {
-	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
-	const char *name = luaL_checkstring (L, 2);
+	LmMessageNode *node  = luaL_checkLmMessageNode (L, 1);
+	const char    *name  = luaL_checkstring (L, 2);
 	LmMessageNode *child;
 
 	child = lm_message_node_get_child (node, name);
@@ -179,7 +222,7 @@
 int attribute_lm_node (lua_State *L)
 {
 	LmMessageNode *node = luaL_checkLmMessageNode (L, 1);
-	const char *name = luaL_checkstring (L, 2);
+	const char    *name = luaL_checkstring (L, 2);
 	if (lua_gettop (L) > 2) { // Set
 		lm_message_node_set_attribute (node, name, luaL_checkstring (L, 3));
 		lua_pop (L, 2);
@@ -249,6 +292,7 @@
 	{ "parent",     parent_lm_node     },
 	{ "value",      value_lm_node      },
 	{ "child",      child_lm_node      },
+	{ "children",   children_lm_node   },
 	{ "find_child", find_child_lm_node },
 	{ "attribute",  attribute_lm_node  },
 	{ "raw",        raw_lm_node        },