Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Sync libucl
Baptiste Daroussin committed 11 years ago
commit b264e3aaadb8eb4e2de5a57e175db2e7c385d3a1
parent e73c495
10 files changed +272 -22
added external/libucl/doc/lua_api.md
@@ -0,0 +1,194 @@
+
## Module `ucl`
+

+
This lua module allows to parse objects from strings and to store data into
+
ucl objects. It uses `libucl` C library to parse and manipulate with ucl objects.
+

+
Example:
+

+
~~~lua
+
local ucl = require("ucl")
+

+
local parser = ucl.parser()
+
local res,err = parser:parse_string('{key=value}')
+

+
if not res then
+
	print('parser error: ' .. err)
+
else
+
	local obj = parser:get_object()
+
	local got = ucl.to_format(obj, 'json')
+
endif
+

+
local table = {
+
  str = 'value',
+
  num = 100500,
+
  null = ucl.null,
+
  func = function ()
+
    return 'huh'
+
  end
+

+

+
print(ucl.to_format(table, 'ucl'))
+
-- Output:
+
--[[
+
num = 100500;
+
str = "value";
+
null = null;
+
func = "huh";
+
--]]
+
~~~
+

+
###Brief content:
+

+
**Functions**:
+

+
> [`ucl_object_push_lua(L, obj, allow_array)`](#function-ucl_object_push_lual-obj-allow_array)
+

+
> [`ucl.to_format(var, format)`](#function-uclto_formatvar-format)
+

+

+

+
**Methods**:
+

+
> [`parser:parse_file(name)`](#method-parserparse_filename)
+

+
> [`parser:parse_string(input)`](#method-parserparse_stringinput)
+

+
> [`parser:get_object()`](#method-parserget_object)
+

+

+
## Functions
+

+
The module `ucl` defines the following functions.
+

+
### Function `ucl_object_push_lua(L, obj, allow_array)`
+

+
This is a `C` function to push `UCL` object as lua variable. This function
+
converts `obj` to lua representation using the following conversions:
+

+
- *scalar* values are directly presented by lua objects
+
- *userdata* values are converted to lua function objects using `LUA_REGISTRYINDEX`,
+
this can be used to pass functions from lua to c and vice-versa
+
- *arrays* are converted to lua tables with numeric indicies suitable for `ipairs` iterations
+
- *objects* are converted to lua tables with string indicies
+

+
**Parameters:**
+

+
- `L {lua_State}`: lua state pointer
+
- `obj {ucl_object_t}`: object to push
+
- `allow_array {bool}`: expand implicit arrays (should be true for all but partial arrays)
+

+
**Returns:**
+

+
- `{int}`: `1` if an object is pushed to lua
+

+
Back to [module description](#module-ucl).
+

+
### Function `ucl.to_format(var, format)`
+

+
Converts lua variable `var` to the specified `format`. Formats supported are:
+

+
- `json` - fine printed json
+
- `json-compact` - compacted json
+
- `config` - fine printed configuration
+
- `ucl` - same as `config`
+
- `yaml` - embedded yaml
+

+
If `var` contains function, they are called during output formatting and if
+
they return string value, then this value is used for ouptut.
+

+
**Parameters:**
+

+
- `var {variant}`: any sort of lua variable (if userdata then metafield `__to_ucl` is searched for output)
+
- `format {string}`: any available format
+

+
**Returns:**
+

+
- `{string}`: string representation of `var` in the specific `format`.
+

+
Example:
+

+
~~~lua
+
local table = {
+
  str = 'value',
+
  num = 100500,
+
  null = ucl.null,
+
  func = function ()
+
    return 'huh'
+
  end
+

+

+
print(ucl.to_format(table, 'ucl'))
+
-- Output:
+
--[[
+
num = 100500;
+
str = "value";
+
null = null;
+
func = "huh";
+
--]]
+
~~~
+

+
Back to [module description](#module-ucl).
+

+

+
## Methods
+

+
The module `ucl` defines the following methods.
+

+
### Method `parser:parse_file(name)`
+

+
Parse UCL object from file.
+

+
**Parameters:**
+

+
- `name {string}`: filename to parse
+

+
**Returns:**
+

+
- `{bool[, string]}`: if res is `true` then file has been parsed successfully, otherwise an error string is also returned
+

+
Example:
+

+
~~~lua
+
local parser = ucl.parser()
+
local res,err = parser:parse_file('/some/file.conf')
+

+
if not res then
+
	print('parser error: ' .. err)
+
else
+
	-- Do something with object
+
end
+
~~~
+

+
Back to [module description](#module-ucl).
+

+
### Method `parser:parse_string(input)`
+

+
Parse UCL object from file.
+

+
**Parameters:**
+

+
- `input {string}`: string to parse
+

+
**Returns:**
+

+
- `{bool[, string]}`: if res is `true` then file has been parsed successfully, otherwise an error string is also returned
+

+
Back to [module description](#module-ucl).
+

+
### Method `parser:get_object()`
+

+
Get top object from parser and export it to lua representation.
+

+
**Parameters:**
+

+
	nothing
+

+
**Returns:**
+

+
- `{variant or nil}`: ucl object as lua native variable
+

+
Back to [module description](#module-ucl).
+

+

+
Back to [top](#).
+

modified external/libucl/src/ucl_emitter_streamline.c
@@ -108,9 +108,8 @@ ucl_object_emit_streamline_start_container (struct ucl_emitter_context *ctx,
			st->is_array = false;
			sctx->ops->ucl_emitter_start_object (ctx, obj, print_key);
		}
+
		LL_PREPEND (sctx->containers, st);
	}
-

-
	LL_PREPEND (sctx->containers, st);
}

void
modified external/libucl/src/ucl_emitter_utils.c
@@ -263,19 +263,23 @@ ucl_fd_append_character (unsigned char c, size_t len, void *ud)
	unsigned char *buf;

	if (len == 1) {
-
		write (fd, &c, 1);
+
		return write (fd, &c, 1);
	}
	else {
		buf = malloc (len);
		if (buf == NULL) {
			/* Fallback */
			while (len --) {
-
				write (fd, &c, 1);
+
				if (write (fd, &c, 1) == -1) {
+
					return -1;
+
				}
			}
		}
		else {
			memset (buf, c, len);
-
			write (fd, buf, len);
+
			if (write (fd, buf, len) == -1) {
+
				return -1;
+
			}
			free (buf);
		}
	}
@@ -288,9 +292,7 @@ ucl_fd_append_len (const unsigned char *str, size_t len, void *ud)
{
	int fd = *(int *)ud;

-
	write (fd, str, len);
-

-
	return 0;
+
	return write (fd, str, len);
}

static int
@@ -300,9 +302,7 @@ ucl_fd_append_int (int64_t val, void *ud)
	char intbuf[64];

	snprintf (intbuf, sizeof (intbuf), "%jd", (intmax_t)val);
-
	write (fd, intbuf, strlen (intbuf));
-

-
	return 0;
+
	return write (fd, intbuf, strlen (intbuf));
}

static int
@@ -323,9 +323,7 @@ ucl_fd_append_double (double val, void *ud)
		snprintf (nbuf, sizeof (nbuf), "%lf", val);
	}

-
	write (fd, nbuf, strlen (nbuf));
-

-
	return 0;
+
	return write (fd, nbuf, strlen (nbuf));
}

struct ucl_emitter_functions*
modified external/libucl/src/ucl_internal.h
@@ -271,7 +271,7 @@ ucl_create_err (UT_string **err, const char *fmt, ...)
static inline bool
ucl_maybe_parse_boolean (ucl_object_t *obj, const unsigned char *start, size_t len)
{
-
	const unsigned char *p = start;
+
	const char *p = (const char *)start;
	bool ret = false, val = false;

	if (len == 5) {
modified external/libucl/src/ucl_parser.c
@@ -587,6 +587,7 @@ ucl_add_parser_stack (ucl_object_t *obj, struct ucl_parser *parser, bool is_arra
	if (st == NULL) {
		ucl_set_err (parser, 0, "cannot allocate memory for an object",
				&parser->err);
+
		ucl_object_unref (obj);
		return NULL;
	}
	st->obj = obj;
@@ -1705,7 +1706,6 @@ ucl_state_machine (struct ucl_parser *parser)
			 * if we got [ or { correspondingly or can just treat new data as
			 * a key of newly created object
			 */
-
			obj = parser->cur_obj;
			if (!ucl_skip_comments (parser)) {
				parser->prev_state = parser->state;
				parser->state = UCL_STATE_ERROR;
modified external/libucl/src/ucl_util.c
@@ -965,6 +965,36 @@ ucl_parser_add_file (struct ucl_parser *parser, const char *filename)
	return ret;
}

+
UCL_EXTERN bool
+
ucl_parser_add_fd (struct ucl_parser *parser, int fd)
+
{
+
	unsigned char *buf;
+
	size_t len;
+
	bool ret;
+
	struct stat st;
+

+
	if (fstat (fd, &st) == -1) {
+
		ucl_create_err (&parser->err, "cannot stat fd %d: %s",
+
			fd, strerror (errno));
+
		return false;
+
	}
+
	if ((buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+
		ucl_create_err (&parser->err, "cannot mmap fd %d: %s",
+
			fd, strerror (errno));
+
		return false;
+
	}
+

+
	parser->cur_file = NULL;
+
	len = st.st_size;
+
	ret = ucl_parser_add_chunk (parser, buf, len);
+

+
	if (len > 0) {
+
		ucl_munmap (buf, len);
+
	}
+

+
	return ret;
+
}
+

size_t
ucl_strlcpy (char *dst, const char *src, size_t siz)
{
@@ -1385,9 +1415,6 @@ ucl_iterate_object (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expan
	elt = *iter;
	if (elt == NULL) {
		elt = obj;
-
		if (elt == NULL) {
-
			return NULL;
-
		}
	}
	else if (elt == obj) {
		return NULL;
added external/libucl/tests/basic/comments.in
@@ -0,0 +1,25 @@
+
# This test is intended to check various comments in ucl
+

+
obj {
+
	
+
	key = value
+
	key = "/* value"
+
	/*
+
	key = value
+
	*/
+
# Nested comments
+
	key = nested
+
	/*
+
	adasdasdads
+
	/* asdasdasd */asjdasjldaskd
+
	/* asdsadasd */
+
	/* /* /* /* /* */ */ */ */ */
+
# some
+
	*/
+
	key = quotes # quoted
+
# Quotes
+
	/*
+
	key = "/* value"
+
	key = "*/value"
+
	*/
+
}
added external/libucl/tests/basic/comments.res
@@ -0,0 +1,7 @@
+
obj {
+
    key = "value";
+
    key = "/* value";
+
    key = "nested";
+
    key = "quotes";
+
}
+

modified external/libucl/tests/test_basic.c
@@ -90,7 +90,7 @@ main (int argc, char **argv)
		inlen = strlen (inbuf);
		test_in = malloc (inlen);
		memcpy (test_in, inbuf, inlen);
-
		ucl_parser_add_chunk (parser, test_in, inlen);
+
		ucl_parser_add_chunk (parser, (const unsigned char *)test_in, inlen);
	}
	fclose (in);

@@ -126,7 +126,7 @@ main (int argc, char **argv)
	ucl_parser_free (parser);
	ucl_object_unref (obj);
	parser2 = ucl_parser_new (UCL_PARSER_KEY_LOWERCASE);
-
	ucl_parser_add_string (parser2, emitted, 0);
+
	ucl_parser_add_string (parser2, (const char *)emitted, 0);

	if (ucl_parser_get_error(parser2) != NULL) {
		fprintf (out, "Error occurred: %s\n", ucl_parser_get_error(parser2));
modified external/libucl/tests/test_schema.c
@@ -61,7 +61,7 @@ static bool
perform_test (const ucl_object_t *schema, const ucl_object_t *obj,
		struct ucl_schema_error *err)
{
-
	const const ucl_object_t *valid, *data, *description;
+
	const ucl_object_t *valid, *data, *description;
	bool match;

	data = ucl_object_find_key (obj, "data");