summaryrefslogtreecommitdiff
path: root/lua/lua_ucl.c
diff options
context:
space:
mode:
Diffstat (limited to 'lua/lua_ucl.c')
-rw-r--r--lua/lua_ucl.c85
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;
}