wibox: check for table loops

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-10-27 14:17:12 +01:00
parent a2f3790dce
commit 16a2eadb66
3 changed files with 36 additions and 0 deletions

33
luaa.c
View File

@ -531,6 +531,39 @@ luaA_hasitem(lua_State *L, const void *item)
return false; return false;
} }
/** Check if a table is a loop. When using table as direct acyclic digram,
* this is useful.
* \param L The Lua VM state.
* \param idx The index of the table in the stack
* \return True if the table loops.
*/
bool
luaA_isloop(lua_State *L, int idx)
{
if(lua_istable(L, idx))
{
lua_pushvalue(L, idx); /* push table on top */
if(luaA_hasitem(L, lua_topointer(L, -1)))
{
lua_pop(L, 1); /* remove pushed table */
return true;
}
lua_pushnil(L);
while(luaA_next(L, -2))
{
/* check for recursivity */
if(luaA_isloop(L, -1))
{
lua_pop(L, 2); /* remove key and value */
return true;
}
lua_pop(L, 1); /* remove value */
}
lua_pop(L, 1); /* remove pushed table */
}
return false;
}
/** Object table. /** Object table.
* This table can use safely object as key. * This table can use safely object as key.
* \param L The Lua VM state. * \param L The Lua VM state.

1
luaa.h
View File

@ -345,6 +345,7 @@ int luaA_pushcolor(lua_State *, const xcolor_t *);
bool luaA_hasitem(lua_State *, const void *); bool luaA_hasitem(lua_State *, const void *);
void luaA_table2wtable(lua_State *); void luaA_table2wtable(lua_State *);
int luaA_next(lua_State *, int); int luaA_next(lua_State *, int);
bool luaA_isloop(lua_State *, int);
#define hooks_property(c, prop) \ #define hooks_property(c, prop) \
do { \ do { \

View File

@ -972,6 +972,8 @@ luaA_wibox_newindex(lua_State *L)
} }
break; break;
case A_TK_WIDGETS: case A_TK_WIDGETS:
if(luaA_isloop(L, 3))
luaL_error(L, "table is looping, cannot use this as widget table");
luaA_register(L, 3, &(*wibox)->widgets_table); luaA_register(L, 3, &(*wibox)->widgets_table);
/* recompute widget node list */ /* recompute widget node list */
wibox_widgets_table_build(L, *wibox); wibox_widgets_table_build(L, *wibox);