/** Convert a Lua table to a list of widget nodes. * \param L The Lua VM state. * \param widgets The linked list of widget node. */ static void luaA_table2widgets(lua_State *L, widget_node_array_t *widgets) { if(lua_istable(L, -1)) { lua_pushnil(L); while(luaA_next(L, -2)) luaA_table2widgets(L, widgets); /* remove the table */ lua_pop(L, 1); } else { widget_t *widget = luaA_toudata(L, -1, &widget_class); if(widget) { widget_node_t w; p_clear(&w, 1); w.widget = luaA_object_ref(L, -1); widget_node_array_append(widgets, w); } else lua_pop(L, 1); /* remove value */ } }
/** Browse a table pushed on top of the index, and put all its table and * sub-table into an array. * \param L The Lua VM state. * \param elems The elements array. * \return False if we encounter an elements already in list. */ static bool luaA_isloop_check(lua_State *L, cptr_array_t *elems) { if(lua_istable(L, -1)) { const void *object = lua_topointer(L, -1); /* Check that the object table is not already in the list */ for(int i = 0; i < elems->len; i++) if(elems->tab[i] == object) return false; /* push the table in the elements list */ cptr_array_append(elems, object); /* look every object in the "table" */ lua_pushnil(L); while(luaA_next(L, -2)) { if(!luaA_isloop_check(L, elems)) { /* remove key and value */ lua_pop(L, 2); return false; } /* remove value, keep key for next iteration */ lua_pop(L, 1); } } return true; }
static void luaB_next (void) { Hash *a = gethash(1); TObject *k = luaA_Address(luaL_nonnullarg(2)); int i = (ttype(k) == LUA_T_NIL) ? 0 : luaH_pos(a, k)+1; if (luaA_next(a, i) == 0) lua_pushnil(); }
int lua_next (lua_Object o, int i) { TObject *t = Address(o); if (ttype(t) != LUA_T_ARRAY) lua_error("API error - object is not a table in `lua_next'"); i = luaA_next(avalue(t), i); top2LC((i==0) ? 0 : 2); return i; }
/** Look for an item: table, function, etc. * \param L The Lua VM state. * \param item The pointer item. */ bool luaA_hasitem(lua_State *L, const void *item) { lua_pushnil(L); while(luaA_next(L, -2)) { if(lua_topointer(L, -1) == item) { /* remove value and key */ lua_pop(L, 2); return true; } if(lua_istable(L, -1)) if(luaA_hasitem(L, item)) { /* remove key and value */ lua_pop(L, 2); return true; } /* remove value */ lua_pop(L, 1); } return false; }