From d8c0f516ba0c5b16492fc170ef5a8ccd33918ca9 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Wed, 30 Sep 2009 11:55:43 +0200 Subject: [PATCH] luaclass: implement object checking Signed-off-by: Julien Danjou --- common/luaclass.c | 4 ++ common/luaclass.h | 6 ++- image.c | 2 +- objects/button.c | 2 +- objects/client.c | 94 +++++++++++++++++++++++------------------------ objects/client.h | 2 - objects/key.c | 2 +- objects/tag.c | 4 +- objects/timer.c | 2 +- objects/wibox.c | 2 +- objects/widget.c | 2 +- 11 files changed, 63 insertions(+), 59 deletions(-) diff --git a/common/luaclass.c b/common/luaclass.c index 85f115aa2..7209d59b2 100644 --- a/common/luaclass.c +++ b/common/luaclass.c @@ -71,6 +71,8 @@ luaA_checkudata(lua_State *L, int ud, lua_class_t *class) void *p = luaA_toudata(L, ud, class); if(!p) luaL_typerror(L, ud, class->name); + else if(class->checker && !class->checker(p)) + luaL_error(L, "invalid object"); return p; } @@ -155,6 +157,7 @@ void luaA_class_setup(lua_State *L, lua_class_t *class, const char *name, lua_class_allocator_t allocator, + lua_class_checker_t checker, lua_class_propfunc_t index_miss_property, lua_class_propfunc_t newindex_miss_property, const struct luaL_reg methods[], @@ -181,6 +184,7 @@ luaA_class_setup(lua_State *L, lua_class_t *class, class->name = name; class->index_miss_property = index_miss_property; class->newindex_miss_property = newindex_miss_property; + class->checker = checker; lua_class_array_append(&luaA_classes, class); } diff --git a/common/luaclass.h b/common/luaclass.h index e8856ba05..4d59d0d4f 100644 --- a/common/luaclass.h +++ b/common/luaclass.h @@ -44,6 +44,8 @@ typedef lua_object_t *(*lua_class_allocator_t)(lua_State *); typedef int (*lua_class_propfunc_t)(lua_State *, lua_object_t *); +typedef bool (*lua_class_checker_t)(lua_object_t *); + typedef struct { /** Class name */ @@ -58,6 +60,8 @@ typedef struct lua_class_propfunc_t index_miss_property; /** Function to call when a indexing an unknown property */ lua_class_propfunc_t newindex_miss_property; + /** Function to call to check if an object is valid */ + lua_class_checker_t checker; } lua_class_t; const char * luaA_typename(lua_State *, int); @@ -68,7 +72,7 @@ void luaA_class_remove_signal(lua_State *, lua_class_t *, const char *, int); void luaA_class_emit_signal(lua_State *, lua_class_t *, const char *, int); void luaA_openlib(lua_State *, const char *, const struct luaL_reg[], const struct luaL_reg[]); -void luaA_class_setup(lua_State *, lua_class_t *, const char *, lua_class_allocator_t, +void luaA_class_setup(lua_State *, lua_class_t *, const char *, lua_class_allocator_t, lua_class_checker_t, lua_class_propfunc_t, lua_class_propfunc_t, const struct luaL_reg[], const struct luaL_reg[]); diff --git a/image.c b/image.c index d4d8c6082..9a2cf4315 100644 --- a/image.c +++ b/image.c @@ -810,7 +810,7 @@ image_class_setup(lua_State *L) { NULL, NULL } }; - luaA_class_setup(L, &image_class, "image", (lua_class_allocator_t) image_new, + luaA_class_setup(L, &image_class, "image", (lua_class_allocator_t) image_new, NULL, luaA_class_index_miss_property, luaA_class_newindex_miss_property, image_methods, image_meta); luaA_class_add_property(&image_class, A_TK_WIDTH, diff --git a/objects/button.c b/objects/button.c index 94cf8cf58..443a2be08 100644 --- a/objects/button.c +++ b/objects/button.c @@ -114,7 +114,7 @@ button_class_setup(lua_State *L) { NULL, NULL } }; - luaA_class_setup(L, &button_class, "button", (lua_class_allocator_t) button_new, + luaA_class_setup(L, &button_class, "button", (lua_class_allocator_t) button_new, NULL, luaA_class_index_miss_property, luaA_class_newindex_miss_property, button_methods, button_meta); luaA_class_add_property(&button_class, A_TK_BUTTON, diff --git a/objects/client.c b/objects/client.c index 0234d1ab5..e7d1ab4c5 100644 --- a/objects/client.c +++ b/objects/client.c @@ -34,15 +34,6 @@ #include "common/atoms.h" #include "common/xutil.h" -client_t * -luaA_client_checkudata(lua_State *L, int ud) -{ - client_t *c = luaA_checkudata(L, ud, &client_class); - if(c->invalid) - luaL_error(L, "client is invalid\n"); - return c; -} - /** Collect a client. * \param L The Lua VM state. * \return The number of element pushed on stack. @@ -72,7 +63,7 @@ luaA_client_gc(lua_State *L) void client_set_opacity(lua_State *L, int cidx, double opacity) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->opacity != opacity) { @@ -90,7 +81,7 @@ client_set_opacity(lua_State *L, int cidx, double opacity) void client_set_urgent(lua_State *L, int cidx, bool urgent) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->urgent != urgent) { @@ -118,7 +109,7 @@ client_set_urgent(lua_State *L, int cidx, bool urgent) void client_set_group_window(lua_State *L, int cidx, xcb_window_t window) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->group_window != window) { @@ -130,7 +121,7 @@ client_set_group_window(lua_State *L, int cidx, xcb_window_t window) void client_set_type(lua_State *L, int cidx, window_type_t type) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->type != type) { @@ -142,7 +133,7 @@ client_set_type(lua_State *L, int cidx, window_type_t type) void client_set_pid(lua_State *L, int cidx, uint32_t pid) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->pid != pid) { @@ -154,7 +145,7 @@ client_set_pid(lua_State *L, int cidx, uint32_t pid) void client_set_icon_name(lua_State *L, int cidx, char *icon_name) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); p_delete(&c->icon_name); c->icon_name = icon_name; luaA_object_emit_signal(L, cidx, "property::icon_name", 0); @@ -163,7 +154,7 @@ client_set_icon_name(lua_State *L, int cidx, char *icon_name) void client_set_alt_icon_name(lua_State *L, int cidx, char *icon_name) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); p_delete(&c->alt_icon_name); c->alt_icon_name = icon_name; luaA_object_emit_signal(L, cidx, "property::icon_name", 0); @@ -172,7 +163,7 @@ client_set_alt_icon_name(lua_State *L, int cidx, char *icon_name) void client_set_role(lua_State *L, int cidx, char *role) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); p_delete(&c->role); c->role = role; luaA_object_emit_signal(L, cidx, "property::role", 0); @@ -181,7 +172,7 @@ client_set_role(lua_State *L, int cidx, char *role) void client_set_machine(lua_State *L, int cidx, char *machine) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); p_delete(&c->machine); c->machine = machine; luaA_object_emit_signal(L, cidx, "property::machine", 0); @@ -190,7 +181,7 @@ client_set_machine(lua_State *L, int cidx, char *machine) void client_set_class_instance(lua_State *L, int cidx, const char *class, const char *instance) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); p_delete(&c->class); p_delete(&c->instance); c->class = a_strdup(class); @@ -202,7 +193,7 @@ client_set_class_instance(lua_State *L, int cidx, const char *class, const char void client_set_transient_for(lua_State *L, int cidx, client_t *transient_for) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->transient_for != transient_for) { @@ -214,7 +205,7 @@ client_set_transient_for(lua_State *L, int cidx, client_t *transient_for) void client_set_name(lua_State *L, int cidx, char *name) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); p_delete(&c->name); c->name = name; luaA_object_emit_signal(L, cidx, "property::name", 0); @@ -223,7 +214,7 @@ client_set_name(lua_State *L, int cidx, char *name) void client_set_alt_name(lua_State *L, int cidx, char *name) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); p_delete(&c->alt_name); c->alt_name = name; luaA_object_emit_signal(L, cidx, "property::name", 0); @@ -895,7 +886,7 @@ client_resize(client_t *c, area_t geometry, bool hints) void client_set_minimized(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->minimized != s) { @@ -920,7 +911,7 @@ client_set_minimized(lua_State *L, int cidx, bool s) void client_set_sticky(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->sticky != s) { @@ -939,7 +930,7 @@ client_set_sticky(lua_State *L, int cidx, bool s) void client_set_fullscreen(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->fullscreen != s) { @@ -983,7 +974,7 @@ client_set_fullscreen(lua_State *L, int cidx, bool s) void client_set_maximized_horizontal(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->maximized_horizontal != s) { @@ -1022,7 +1013,7 @@ client_set_maximized_horizontal(lua_State *L, int cidx, bool s) void client_set_maximized_vertical(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->maximized_vertical != s) { @@ -1061,7 +1052,7 @@ client_set_maximized_vertical(lua_State *L, int cidx, bool s) void client_set_above(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->above != s) { @@ -1087,7 +1078,7 @@ client_set_above(lua_State *L, int cidx, bool s) void client_set_below(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->below != s) { @@ -1113,7 +1104,7 @@ client_set_below(lua_State *L, int cidx, bool s) void client_set_modal(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->modal != s) { @@ -1132,7 +1123,7 @@ client_set_modal(lua_State *L, int cidx, bool s) void client_set_ontop(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->ontop != s) { @@ -1157,7 +1148,7 @@ client_set_ontop(lua_State *L, int cidx, bool s) void client_set_skip_taskbar(lua_State *L, int cidx, bool s) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); if(c->skip_taskbar != s) { @@ -1306,7 +1297,7 @@ luaA_client_get(lua_State *L) static int luaA_client_isvisible(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); lua_pushboolean(L, client_isvisible(c, c->screen)); return 1; } @@ -1319,7 +1310,7 @@ luaA_client_isvisible(lua_State *L) void client_set_border_width(lua_State *L, int cidx, int width) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); uint32_t w = width; if(width > 0 && (c->type == WINDOW_TYPE_DOCK @@ -1357,7 +1348,7 @@ client_set_border_width(lua_State *L, int cidx, int width) void client_set_icon(lua_State *L, int cidx, int iidx) { - client_t *c = luaA_client_checkudata(L, cidx); + client_t *c = luaA_checkudata(L, cidx, &client_class); /* convert index to absolute */ cidx = luaA_absindex(L, cidx); iidx = luaA_absindex(L, iidx); @@ -1376,7 +1367,7 @@ client_set_icon(lua_State *L, int cidx, int iidx) static int luaA_client_kill(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); client_kill(c); return 0; } @@ -1390,8 +1381,8 @@ luaA_client_kill(lua_State *L) static int luaA_client_swap(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); - client_t *swap = luaA_client_checkudata(L, 2); + client_t *c = luaA_checkudata(L, 1, &client_class); + client_t *swap = luaA_checkudata(L, 2, &client_class); if(c != swap) { @@ -1424,7 +1415,7 @@ luaA_client_swap(lua_State *L) static int luaA_client_tags(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); tag_array_t *tags = &c->screen->tags; int j = 0; @@ -1458,7 +1449,7 @@ luaA_client_tags(lua_State *L) static int luaA_client_raise(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); client_raise(c); return 0; } @@ -1471,7 +1462,7 @@ luaA_client_raise(lua_State *L) static int luaA_client_lower(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); stack_client_push(c); @@ -1493,7 +1484,7 @@ luaA_client_lower(lua_State *L) static int luaA_client_redraw(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); xcb_unmap_window(globalconf.connection, c->window); xcb_map_window(globalconf.connection, c->window); @@ -1519,7 +1510,7 @@ luaA_client_redraw(lua_State *L) static int luaA_client_unmanage(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); client_unmanage(c); return 0; } @@ -1534,7 +1525,7 @@ luaA_client_unmanage(lua_State *L) static int luaA_client_geometry(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); if(lua_gettop(L) == 2 && !lua_isnil(L, 2)) { @@ -1570,7 +1561,7 @@ luaA_client_geometry(lua_State *L) static int luaA_client_struts(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); if(lua_gettop(L) == 2) { @@ -2006,7 +1997,7 @@ luaA_client_get_size_hints(lua_State *L, client_t *c) static int luaA_client_buttons(lua_State *L) { - client_t *client = luaA_client_checkudata(L, 1); + client_t *client = luaA_checkudata(L, 1, &client_class); button_array_t *buttons = &client->buttons; if(lua_gettop(L) == 2) @@ -2030,7 +2021,7 @@ luaA_client_buttons(lua_State *L) static int luaA_client_keys(lua_State *L) { - client_t *c = luaA_client_checkudata(L, 1); + client_t *c = luaA_checkudata(L, 1, &client_class); key_array_t *keys = &c->keys; if(lua_gettop(L) == 2) @@ -2078,7 +2069,7 @@ luaA_client_module_newindex(lua_State *L) switch(a_tokenize(buf, len)) { case A_TK_FOCUS: - c = luaA_client_checkudata(L, 3); + c = luaA_checkudata(L, 3, &client_class); client_focus(c); break; default: @@ -2088,6 +2079,12 @@ luaA_client_module_newindex(lua_State *L) return 0; } +static bool +client_checker(client_t *c) +{ + return !c->invalid; +} + void client_class_setup(lua_State *L) { @@ -2121,6 +2118,7 @@ client_class_setup(lua_State *L) }; luaA_class_setup(L, &client_class, "client", (lua_class_allocator_t) client_new, + (lua_class_checker_t) client_checker, luaA_class_index_miss_property, luaA_class_newindex_miss_property, client_methods, client_meta); luaA_class_add_property(&client_class, A_TK_NAME, diff --git a/objects/client.h b/objects/client.h index 03fdce66f..d8abe30e9 100644 --- a/objects/client.h +++ b/objects/client.h @@ -149,8 +149,6 @@ struct client_t double opacity; }; -client_t * luaA_client_checkudata(lua_State *, int); - ARRAY_FUNCS(client_t *, client, DO_NOTHING) /** Client class */ diff --git a/objects/key.c b/objects/key.c index 24cbd503e..a64d561fe 100644 --- a/objects/key.c +++ b/objects/key.c @@ -1126,7 +1126,7 @@ key_class_setup(lua_State *L) { NULL, NULL }, }; - luaA_class_setup(L, &key_class, "key", (lua_class_allocator_t) key_new, + luaA_class_setup(L, &key_class, "key", (lua_class_allocator_t) key_new, NULL, luaA_class_index_miss_property, luaA_class_newindex_miss_property, key_methods, key_meta); luaA_class_add_property(&key_class, A_TK_KEY, diff --git a/objects/tag.c b/objects/tag.c index dc81b7437..902329198 100644 --- a/objects/tag.c +++ b/objects/tag.c @@ -312,7 +312,7 @@ luaA_tag_clients(lua_State *L) lua_pushnil(L); while(lua_next(L, 2)) { - client_t *c = luaA_client_checkudata(L, -1); + client_t *c = luaA_checkudata(L, -1, &client_class); /* push tag on top of the stack */ lua_pushvalue(L, 1); tag_client(c); @@ -419,7 +419,7 @@ tag_class_setup(lua_State *L) { NULL, NULL }, }; - luaA_class_setup(L, &tag_class, "tag", (lua_class_allocator_t) tag_new, + luaA_class_setup(L, &tag_class, "tag", (lua_class_allocator_t) tag_new, NULL, luaA_class_index_miss_property, luaA_class_newindex_miss_property, tag_methods, tag_meta); luaA_class_add_property(&tag_class, A_TK_NAME, diff --git a/objects/timer.c b/objects/timer.c index 0ba3579fd..b8f2bbafe 100644 --- a/objects/timer.c +++ b/objects/timer.c @@ -122,7 +122,7 @@ timer_class_setup(lua_State *L) { NULL, NULL }, }; - luaA_class_setup(L, &timer_class, "timer", (lua_class_allocator_t) timer_new, + luaA_class_setup(L, &timer_class, "timer", (lua_class_allocator_t) timer_new, NULL, luaA_class_index_miss_property, luaA_class_newindex_miss_property, timer_methods, timer_meta); luaA_class_add_property(&timer_class, A_TK_TIMEOUT, diff --git a/objects/wibox.c b/objects/wibox.c index 4676f67cb..90db40fe3 100644 --- a/objects/wibox.c +++ b/objects/wibox.c @@ -1348,7 +1348,7 @@ wibox_class_setup(lua_State *L) { NULL, NULL }, }; - luaA_class_setup(L, &wibox_class, "wibox", (lua_class_allocator_t) wibox_new, + luaA_class_setup(L, &wibox_class, "wibox", (lua_class_allocator_t) wibox_new, NULL, luaA_class_index_miss_property, luaA_class_newindex_miss_property, wibox_methods, wibox_meta); luaA_class_add_property(&wibox_class, A_TK_WIDGETS, diff --git a/objects/widget.c b/objects/widget.c index 73f971351..9506951c8 100644 --- a/objects/widget.c +++ b/objects/widget.c @@ -581,7 +581,7 @@ widget_class_setup(lua_State *L) { NULL, NULL } }; - luaA_class_setup(L, &widget_class, "widget", (lua_class_allocator_t) widget_new, + luaA_class_setup(L, &widget_class, "widget", (lua_class_allocator_t) widget_new, NULL, NULL, NULL, widget_methods, widget_meta); luaA_class_add_property(&widget_class, A_TK_VISIBLE,