diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-10-02 19:36:46 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-10-02 19:36:46 +0100 |
commit | f51cef1bd7b1814a94991a5646dac900bdba3b95 (patch) | |
tree | 120d1b74b444c259e09feea6a00e5678130ce844 /src | |
parent | 4fe7fd34d97a6b18bbdc4a8aafb425e1cc7a8674 (diff) | |
download | rspamd-f51cef1bd7b1814a94991a5646dac900bdba3b95.tar.gz rspamd-f51cef1bd7b1814a94991a5646dac900bdba3b95.zip |
Load RCL object from lua.
Diffstat (limited to 'src')
-rw-r--r-- | src/lua/lua_common.h | 2 | ||||
-rw-r--r-- | src/lua/lua_rcl.c | 87 |
2 files changed, 86 insertions, 3 deletions
diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h index 7416297f7..526c20f6f 100644 --- a/src/lua/lua_common.h +++ b/src/lua/lua_common.h @@ -114,7 +114,7 @@ gint lua_rcl_obj_push (lua_State *L, rspamd_cl_object_t *obj); * @param L * @return */ -rspamd_cl_object_t * lua_rcl_obj_get (lua_State *L); +rspamd_cl_object_t * lua_rcl_obj_get (lua_State *L, gint idx); /** * Open libraries functions diff --git a/src/lua/lua_rcl.c b/src/lua/lua_rcl.c index 1dc17bde5..91f1fff79 100644 --- a/src/lua/lua_rcl.c +++ b/src/lua/lua_rcl.c @@ -30,6 +30,8 @@ static gint lua_rcl_obj_push_array (lua_State *L, rspamd_cl_object_t *obj); static gint lua_rcl_obj_push_simple (lua_State *L, rspamd_cl_object_t *obj); +static void lua_rcl_table_get (lua_State *L, rspamd_cl_object_t *top, gint idx); +static void lua_rcl_elt_get (lua_State *L, rspamd_cl_object_t *top, gint idx); /** * Push a single element of an object to lua @@ -148,12 +150,84 @@ lua_rcl_obj_push (lua_State *L, rspamd_cl_object_t *obj) } /** + * Parse lua table into object top + * @param L + * @param top + * @param idx + */ +static void +lua_rcl_table_get (lua_State *L, rspamd_cl_object_t *top, gint idx) +{ + rspamd_cl_object_t *obj; + gsize keylen; + const gchar *k; + + /* Table iterate */ + lua_pushvalue (L, idx); + lua_pushnil (L); + while (lua_next (L, -2) != 0) { + /* copy key to avoid modifications */ + lua_pushvalue (L, -2); + obj = rspamd_cl_object_new (); + if (obj != NULL) { + k = lua_tolstring (L, -1, &keylen); + obj->key = g_malloc (keylen + 1); + memcpy (obj->key, k, keylen); + obj->key[keylen] = '\0'; + HASH_ADD_KEYPTR (hh, top->value.ov, obj->key, keylen, obj); + lua_rcl_elt_get (L, obj, -2); + } + + lua_pop (L, 2); + } + lua_pop (L, 1); +} + +/** + * Get a single element from lua to object obj + * @param L + * @param obj + * @param idx + */ +static void +lua_rcl_elt_get (lua_State *L, rspamd_cl_object_t *obj, gint idx) +{ + gint type; + + type = lua_type (L, idx); + + switch (type) { + case LUA_TFUNCTION: + lua_pushvalue (L, idx); + obj->type = RSPAMD_CL_USERDATA; + obj->value.ud = GINT_TO_POINTER (luaL_ref (L, LUA_REGISTRYINDEX)); + break; + case LUA_TSTRING: + obj->type = RSPAMD_CL_STRING; + obj->value.sv = g_strdup (lua_tostring (L, idx)); + break; + case LUA_TNUMBER: + obj->type = RSPAMD_CL_FLOAT; + obj->value.dv = lua_tonumber (L, idx); + break; + case LUA_TBOOLEAN: + obj->type = RSPAMD_CL_BOOLEAN; + obj->value.iv = lua_toboolean (L, idx); + break; + case LUA_TTABLE: + obj->type = RSPAMD_CL_OBJECT; + lua_rcl_table_get (L, obj, idx); + break; + } +} + +/** * Extract rcl object from lua object * @param L * @return */ rspamd_cl_object_t * -lua_rcl_obj_get (lua_State *L) +lua_rcl_obj_get (lua_State *L, gint idx) { rspamd_cl_object_t *obj; gint t; @@ -161,7 +235,16 @@ lua_rcl_obj_get (lua_State *L) obj = rspamd_cl_object_new (); if (obj != NULL) { - t = lua_type (L, 1); + t = lua_type (L, idx); + switch (t) { + case LUA_TTABLE: + /* We assume all tables as objects, not arrays */ + lua_rcl_table_get (L, obj, idx); + break; + default: + lua_rcl_elt_get (L, obj, idx); + break; + } } return obj; |