diff options
Diffstat (limited to 'lua/lua_ucl.c')
-rw-r--r-- | lua/lua_ucl.c | 85 |
1 files changed, 60 insertions, 25 deletions
diff --git a/lua/lua_ucl.c b/lua/lua_ucl.c index b6162b432f59a..bf80810d3e073 100644 --- a/lua/lua_ucl.c +++ b/lua/lua_ucl.c @@ -29,6 +29,7 @@ #include "ucl_internal.h" #include "lua_ucl.h" #include <strings.h> +#include <zconf.h> /*** * @module ucl @@ -149,14 +150,14 @@ ucl_object_lua_push_object (lua_State *L, const ucl_object_t *obj, } /* Optimize allocation by preallocation of table */ - while (ucl_iterate_object (obj, &it, true) != NULL) { + while (ucl_object_iterate (obj, &it, true) != NULL) { nelt ++; } lua_createtable (L, 0, nelt); it = NULL; - while ((cur = ucl_iterate_object (obj, &it, true)) != NULL) { + while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) { ucl_object_lua_push_element (L, ucl_object_key (cur), cur); } @@ -421,9 +422,7 @@ ucl_object_lua_fromelt (lua_State *L, int idx) fd->idx = luaL_ref (L, LUA_REGISTRYINDEX); obj = ucl_object_new_userdata (lua_ucl_userdata_dtor, - lua_ucl_userdata_emitter); - obj->type = UCL_USERDATA; - obj->value.ud = (void *)fd; + lua_ucl_userdata_emitter, (void *)fd); } } } @@ -514,6 +513,17 @@ lua_ucl_object_get (lua_State *L, int index) return *((ucl_object_t **) luaL_checkudata(L, index, OBJECT_META)); } +static void +lua_ucl_push_opaque (lua_State *L, ucl_object_t *obj) +{ + ucl_object_t **pobj; + + pobj = lua_newuserdata (L, sizeof (*pobj)); + *pobj = obj; + luaL_getmetatable (L, OBJECT_META); + lua_setmetatable (L, -2); +} + /*** * @method parser:parse_file(name) * Parse UCL object from file. @@ -629,17 +639,14 @@ static int lua_ucl_parser_get_object_wrapped (lua_State *L) { struct ucl_parser *parser; - ucl_object_t *obj, **pobj; + ucl_object_t *obj; int ret = 1; parser = lua_ucl_parser_get (L, 1); obj = ucl_parser_get_object (parser); if (obj != NULL) { - pobj = lua_newuserdata (L, sizeof (*pobj)); - *pobj = obj; - luaL_getmetatable (L, OBJECT_META); - lua_setmetatable (L, -2); + lua_ucl_push_opaque (L, obj); } else { lua_pushnil (L); @@ -806,19 +813,21 @@ lua_ucl_object_tostring (lua_State *L) } /*** - * @method object:validate(schema, path) + * @method object:validate(schema[, path[, ext_refs]]) * Validates the given ucl object using schema object represented as another * opaque ucl object. You can also specify path in the form `#/path/def` to * specify the specific schema element to perform validation. * * @param {ucl.object} schema schema object * @param {string} path optional path for validation procedure - * @return {result,err} two values: boolean result and the corresponding error + * @return {result,err} two values: boolean result and the corresponding + * error, if `ext_refs` are also specified, then they are returned as opaque + * ucl object as {result,err,ext_refs} */ static int lua_ucl_object_validate (lua_State *L) { - ucl_object_t *obj, *schema; + ucl_object_t *obj, *schema, *ext_refs = NULL; const ucl_object_t *schema_elt; bool res = false; struct ucl_schema_error err; @@ -828,15 +837,30 @@ lua_ucl_object_validate (lua_State *L) schema = lua_ucl_object_get (L, 2); if (schema && obj && ucl_object_type (schema) == UCL_OBJECT) { - if (lua_gettop (L) > 2 && lua_type (L, 3) == LUA_TSTRING) { - path = lua_tostring (L, 3); - if (path[0] == '#') { - path ++; + if (lua_gettop (L) > 2) { + if (lua_type (L, 3) == LUA_TSTRING) { + path = lua_tostring (L, 3); + if (path[0] == '#') { + path++; + } + } + else if (lua_type (L, 3) == LUA_TUSERDATA || lua_type (L, 3) == + LUA_TTABLE) { + /* External refs */ + ext_refs = lua_ucl_object_get (L, 3); + } + + if (lua_gettop (L) > 3) { + if (lua_type (L, 4) == LUA_TUSERDATA || lua_type (L, 4) == + LUA_TTABLE) { + /* External refs */ + ext_refs = lua_ucl_object_get (L, 4); + } } } if (path) { - schema_elt = ucl_lookup_path_char (schema, path, '/'); + schema_elt = ucl_object_lookup_path_char (schema, path, '/'); } else { /* Use the top object */ @@ -844,26 +868,33 @@ lua_ucl_object_validate (lua_State *L) } if (schema_elt) { - res = ucl_object_validate (schema_elt, obj, &err); + res = ucl_object_validate_root_ext (schema_elt, obj, schema, + ext_refs, &err); if (res) { lua_pushboolean (L, res); lua_pushnil (L); + + if (ext_refs) { + lua_ucl_push_opaque (L, ext_refs); + } } else { lua_pushboolean (L, res); lua_pushfstring (L, "validation error: %s", err.msg); + + if (ext_refs) { + lua_ucl_push_opaque (L, ext_refs); + } } } else { lua_pushboolean (L, res); - if (path) { - lua_pushfstring (L, "cannot find the requested path: %s", path); - } - else { - /* Should not be reached */ - lua_pushstring (L, "unknown error"); + lua_pushfstring (L, "cannot find the requested path: %s", path); + + if (ext_refs) { + lua_ucl_push_opaque (L, ext_refs); } } } @@ -872,6 +903,10 @@ lua_ucl_object_validate (lua_State *L) lua_pushstring (L, "invalid object or schema"); } + if (ext_refs) { + return 3; + } + return 2; } |