summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2016-01-04 22:59:59 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2016-01-04 23:14:38 +0100
commite9b39a1ef74f9a3b15de54896ae612637ddc3956 (patch)
treea8eaa847d2963083fcd7af2b66d466a83394c866
parenta227060383b4c61dd54cffba16ef26f1757e004b (diff)
downloadxK-e9b39a1ef74f9a3b15de54896ae612637ddc3956.tar.gz
xK-e9b39a1ef74f9a3b15de54896ae612637ddc3956.tar.xz
xK-e9b39a1ef74f9a3b15de54896ae612637ddc3956.zip
degesch: Lua: allow arbitrary userdata properties
-rw-r--r--degesch.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/degesch.c b/degesch.c
index b66114b..5d1186c 100644
--- a/degesch.c
+++ b/degesch.c
@@ -8173,8 +8173,38 @@ lua_plugin_property_get (lua_State *L)
return 1;
}
- return luaL_error (L, "%s: %s",
- "no such method or property", property_name);
+ // Or we look for a property set by the user (__gc cannot be overriden)
+ if (lua_getuservalue (L, 1) != LUA_TTABLE)
+ lua_pushnil (L);
+ else
+ lua_getfield (L, -1, property_name);
+ return 1;
+}
+
+static int
+lua_plugin_property_set (lua_State *L)
+{
+ luaL_checktype (L, 1, LUA_TUSERDATA);
+ const char *property_name = luaL_checkstring (L, 2);
+ luaL_checkany (L, 3);
+
+ // We use the associated value to store user-defined properties
+ int type = lua_getuservalue (L, 1);
+ if (type == LUA_TNIL)
+ {
+ lua_pop (L, 1);
+ lua_newtable (L);
+ lua_pushvalue (L, -1);
+ lua_setuservalue (L, 1);
+ }
+ else if (type != LUA_TTABLE)
+ return luaL_error (L, "associated value is not a table");
+
+ // Beware that we do not check for conflicts here;
+ // if Lua code writes a conflicting field, it is effectively ignored
+ lua_pushvalue (L, 3);
+ lua_setfield (L, -2, property_name);
+ return 0;
}
static void
@@ -8186,6 +8216,9 @@ lua_plugin_create_meta (lua_State *L, const char *name, luaL_Reg *fns)
// Emulate properties for convenience
lua_pushcfunction (L, lua_plugin_property_get);
lua_setfield (L, -2, "__index");
+ lua_pushcfunction (L, lua_plugin_property_set);
+ lua_setfield (L, -2, "__newindex");
+
lua_pop (L, 1);
}