From 16a2eadb66c26677dade15ac0bdc9578e8742fa9 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 27 Oct 2008 14:17:12 +0100 Subject: [PATCH] wibox: check for table loops Signed-off-by: Julien Danjou --- luaa.c | 33 +++++++++++++++++++++++++++++++++ luaa.h | 1 + wibox.c | 2 ++ 3 files changed, 36 insertions(+) diff --git a/luaa.c b/luaa.c index 8da05ef3..e2e6d4c4 100644 --- a/luaa.c +++ b/luaa.c @@ -531,6 +531,39 @@ luaA_hasitem(lua_State *L, const void *item) 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. * This table can use safely object as key. * \param L The Lua VM state. diff --git a/luaa.h b/luaa.h index 515cd89a..340dc5cb 100644 --- a/luaa.h +++ b/luaa.h @@ -345,6 +345,7 @@ int luaA_pushcolor(lua_State *, const xcolor_t *); bool luaA_hasitem(lua_State *, const void *); void luaA_table2wtable(lua_State *); int luaA_next(lua_State *, int); +bool luaA_isloop(lua_State *, int); #define hooks_property(c, prop) \ do { \ diff --git a/wibox.c b/wibox.c index 402ac163..8c4d0604 100644 --- a/wibox.c +++ b/wibox.c @@ -972,6 +972,8 @@ luaA_wibox_newindex(lua_State *L) } break; 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); /* recompute widget node list */ wibox_widgets_table_build(L, *wibox);