# HG changeset patch # User Myhailo Danylenko # Date 1309828667 -10800 # Node ID c5a487f2fd7fc5772bc75479a71b1fa0e27907f7 # Parent 34a2b880615ccea435a7e580d08bce43806cc088 Add message/message_node children iterator method diff -r 34a2b880615c -r c5a487f2fd7f lm_message.c --- a/lm_message.c Sun Jul 03 22:17:16 2011 +0300 +++ b/lm_message.c Tue Jul 05 04:17:47 2011 +0300 @@ -30,7 +30,7 @@ /// Module, representing individual message. /// Message have a type and optionally a sub type. /// Message have a set common methods with message node, -/// these are name, next, prev, parent, value, child, +/// these are name, next, prev, parent, value, child, children, /// find_child, attribute, raw, xml and path. They just save /// you typing :node() each time and save memory for /// one node object. @@ -284,6 +284,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 }, diff -r 34a2b880615c -r c5a487f2fd7f lm_message_node.c --- 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 }, diff -r 34a2b880615c -r c5a487f2fd7f lm_message_node.h --- a/lm_message_node.h Sun Jul 03 22:17:16 2011 +0300 +++ b/lm_message_node.h Tue Jul 05 04:17:47 2011 +0300 @@ -27,6 +27,7 @@ int parent_lm_node (lua_State *L); int value_lm_node (lua_State *L); int child_lm_node (lua_State *L); +int children_lm_node (lua_State *L); int find_child_lm_node (lua_State *L); int raw_lm_node (lua_State *L); int attribute_lm_node (lua_State *L);