diff -r b74185e1357a -r 8eb839fbabba src/lua_irc.c --- a/src/lua_irc.c Thu May 14 21:45:43 2009 +0300 +++ b/src/lua_irc.c Thu May 14 22:57:13 2009 +0300 @@ -172,37 +172,48 @@ } static struct lua_func lua_net_channels_func = LUA_FUNC(&lua_net_type, "channels", - "return a list of channel objects", + "Return an iterater over the network's channels", LUA_FUNC_ARG_END ); +static int lua_net_channels_iter (lua_State *L) +{ + int nargs = lua_gettop(L); + struct lua_net *lua_net = lua_arg_obj(L, nargs, 1, &lua_net_type, false); + struct lua_chan *lua_chan = lua_arg_obj(L, nargs, 2, &lua_chan_type, true); + struct irc_chan *chan_next; + + // get next item from current + if (lua_chan) + chan_next = TAILQ_NEXT(lua_chan->chan, net_channels); + else + chan_next = TAILQ_FIRST(&lua_net->net->channels); + + // push return value - next item + if (chan_next) + lua_chan_create(L, chan_next); + else + lua_pushnil(L); + + return 1; +} + static int lua_net_channels (lua_State *L) { struct lua_net *lua_net; - struct irc_chan *chan; - int i = 1; // parse args lua_args_parse(L, &lua_net_channels_func, (void *) &lua_net); - // create table to return - lua_newtable(L); - - // iter - TAILQ_FOREACH(chan, &lua_net->net->channels, net_channels) { - // push index - lua_pushinteger(L, i); + // push iter func + lua_pushcfunction(L, lua_net_channels_iter); - // push value as new lua_chan - lua_chan_create(L, chan); + // push invariant state - the lua_net + lua_pushvalue(L, 1); - // store in table - lua_settable(L, -3); - } - - // return table - return 1; + // return iter three-tuple + return 2; } static struct lua_method lua_net_methods[] = LUA_METHODS( @@ -335,37 +346,49 @@ } static struct lua_func lua_client_networks_func = LUA_FUNC(&lua_client_type, "channels", - "Build list of client's networks", + "Return an iterator over the client's networks", LUA_FUNC_ARG_END ); +static int lua_client_networks_iter (lua_State *L) +{ + int nargs = lua_gettop(L); + struct lua_client *lua_client = lua_arg_obj(L, nargs, 1, &lua_client_type, false); + struct lua_net *lua_net = lua_arg_obj(L, nargs, 2, &lua_net_type, true); + struct irc_net *net_next; + + if (lua_net) + // return next + net_next = TAILQ_NEXT(lua_net->net, client_networks); + else + // return first + net_next = TAILQ_FIRST(&lua_client->client->networks); + + // build and return next value + if (net_next) + lua_net_create(L, net_next); + else + lua_pushnil(L); + + return 1; +} + static int lua_client_networks (lua_State *L) { struct lua_client *lua_client; - struct irc_net *net; - int i = 1; // parse args lua_args_parse(L, &lua_client_networks_func, (void *) &lua_client); - // create new table - lua_newtable(L); - - // append each channel - TAILQ_FOREACH(net, &lua_client->client->networks, client_networks) { - // index - lua_pushinteger(L, i); + // push iter func + lua_pushcfunction(L, lua_client_networks_iter); - // push new lua_net - lua_net_create(L, net); + // push invariant state - the lua_client + lua_pushvalue(L, 1); - // store - lua_settable(L, -3); - } - - // ok, return the table - return 1; + // return three-tuple + return 2; } static struct lua_func lua_client_quit_func = LUA_FUNC(&lua_client_type, "quit",