Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Update to latest version of libucl
Baptiste Daroussin committed 11 years ago
commit 6204884c2f88a0203bb8d782d405da4fe9435a2e
parent 4b5307e
6 files changed +200 -22
modified external/libucl/configure.ac
@@ -1,7 +1,7 @@
m4_define([maj_ver], [0])
m4_define([med_ver], [4])
-
m4_define([min_ver], [0])
-
m4_define([so_version], [maj_ver:med_ver])
+
m4_define([min_ver], [1])
+
m4_define([so_version], [1:0:0])
m4_define([ucl_version], [maj_ver.med_ver.min_ver])

AC_INIT([libucl],[ucl_version],[https://github.com/vstakhov/libucl],[libucl])
modified external/libucl/include/ucl.h
@@ -236,7 +236,13 @@ UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT;
 * @param type type of a new object
 * @return new object
 */
-
UCL_EXTERN ucl_object_t* ucl_object_typed_new (unsigned int type) UCL_WARN_UNUSED_RESULT;
+
UCL_EXTERN ucl_object_t* ucl_object_typed_new (ucl_type_t type) UCL_WARN_UNUSED_RESULT;
+

+
/**
+
 * Return the type of an object
+
 * @return the object type
+
 */
+
UCL_EXTERN ucl_type_t ucl_object_type (const ucl_object_t *obj);

/**
 * Convert any string to an ucl object making the specified transformations
@@ -413,6 +419,15 @@ UCL_EXTERN const ucl_object_t* ucl_array_tail (const ucl_object_t *top);
UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top);

/**
+
 * Return object identified by an index of the array `top`
+
 * @param obj object to get a key from (must be of type UCL_ARRAY)
+
 * @param index index to return
+
 * @return object at the specified index or NULL if index is not found
+
 */
+
UCL_EXTERN const ucl_object_t* ucl_array_find_index (const ucl_object_t *top,
+
		unsigned int index);
+

+
/**
 * Removes the first element from the array `top`. Caller must unref the returned object when it is not
 * needed.
 * @param top array ucl object
@@ -534,6 +549,15 @@ UCL_EXTERN const ucl_object_t* ucl_object_find_keyl (const ucl_object_t *obj,
		const char *key, size_t klen);

/**
+
 * Return object identified by dot notation string
+
 * @param obj object to search in
+
 * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays
+
 * @return object matched the specified path or NULL if path is not found
+
 */
+
UCL_EXTERN const ucl_object_t *ucl_lookup_path (const ucl_object_t *obj,
+
		const char *path);
+

+
/**
 * Returns a key of an object as a NULL terminated string
 * @param obj CL object
 * @return key or NULL if there is no key
@@ -643,6 +667,19 @@ UCL_EXTERN void ucl_parser_register_macro (struct ucl_parser *parser, const char
		ucl_macro_handler handler, void* ud);

/**
+
 * Handler to detect unregistered variables
+
 * @param data variable data
+
 * @param len length of variable
+
 * @param replace (out) replace value for variable
+
 * @param replace_len (out) replace length for variable
+
 * @param need_free (out) UCL will free `dest` after usage
+
 * @param ud opaque userdata
+
 * @return true if variable
+
 */
+
typedef bool (*ucl_variable_handler) (const unsigned char *data, size_t len,
+
		unsigned char **replace, size_t *replace_len, bool *need_free, void* ud);
+

+
/**
 * Register new parser variable
 * @param parser parser object
 * @param var variable name
@@ -652,6 +689,15 @@ UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const c
		const char *value);

/**
+
 * Set handler for unknown variables
+
 * @param parser parser structure
+
 * @param handler desired handler
+
 * @param ud opaque data for the handler
+
 */
+
UCL_EXTERN void ucl_parser_set_variables_handler (struct ucl_parser *parser,
+
		ucl_variable_handler handler, void *ud);
+

+
/**
 * Load new chunk to a parser
 * @param parser parser structure
 * @param data the pointer to the beginning of a chunk
modified external/libucl/src/ucl_internal.h
@@ -197,6 +197,8 @@ struct ucl_parser {
	struct ucl_chunk *chunks;
	struct ucl_pubkey *keys;
	struct ucl_variable *variables;
+
	ucl_variable_handler var_handler;
+
	void *var_data;
	UT_string *err;
};

modified external/libucl/src/ucl_parser.c
@@ -236,6 +236,9 @@ ucl_check_variable_safe (struct ucl_parser *parser, const char *ptr, size_t rema
		size_t *out_len, bool strict, bool *found)
{
	struct ucl_variable *var;
+
	unsigned char *dst;
+
	size_t dstlen;
+
	bool need_free = false;

	LL_FOREACH (parser->variables, var) {
		if (strict) {
@@ -258,6 +261,19 @@ ucl_check_variable_safe (struct ucl_parser *parser, const char *ptr, size_t rema
		}
	}

+
	/* XXX: can only handle ${VAR} */
+
	if (!(*found) && parser->var_handler != NULL && strict) {
+
		/* Call generic handler */
+
		if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
+
				parser->var_data)) {
+
			*found = true;
+
			if (need_free) {
+
				free (dst);
+
			}
+
			return (ptr + remain);
+
		}
+
	}
+

	return ptr;
}

@@ -271,7 +287,8 @@ ucl_check_variable_safe (struct ucl_parser *parser, const char *ptr, size_t rema
 * @return
 */
static const char *
-
ucl_check_variable (struct ucl_parser *parser, const char *ptr, size_t remain, size_t *out_len, bool *vars_found)
+
ucl_check_variable (struct ucl_parser *parser, const char *ptr,
+
		size_t remain, size_t *out_len, bool *vars_found)
{
	const char *p, *end, *ret = ptr;
	bool found = false;
@@ -282,7 +299,8 @@ ucl_check_variable (struct ucl_parser *parser, const char *ptr, size_t remain, s
		end = ptr + remain;
		while (p < end) {
			if (*p == '}') {
-
				ret = ucl_check_variable_safe (parser, ptr + 1, p - ptr - 1, out_len, true, &found);
+
				ret = ucl_check_variable_safe (parser, ptr + 1, p - ptr - 1,
+
						out_len, true, &found);
				if (found) {
					/* {} must be excluded actually */
					ret ++;
@@ -328,10 +346,13 @@ static const char *
ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
		size_t remain, unsigned char **dest)
{
-
	unsigned char *d = *dest;
+
	unsigned char *d = *dest, *dst;
	const char *p = ptr + 1, *ret;
	struct ucl_variable *var;
+
	size_t dstlen;
+
	bool need_free = false;
	bool found = false;
+
	bool strict = false;

	ret = ptr + 1;
	remain --;
@@ -343,6 +364,7 @@ ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
	}
	else if (*p == '{') {
		p ++;
+
		strict = true;
		ret += 2;
		remain -= 2;
	}
@@ -359,9 +381,22 @@ ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
		}
	}
	if (!found) {
-
		memcpy (d, ptr, 2);
-
		d += 2;
-
		ret --;
+
		if (strict && parser->var_handler != NULL) {
+
			if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
+
							parser->var_data)) {
+
				memcpy (d, dst, dstlen);
+
				ret += dstlen;
+
				d += remain;
+
				found = true;
+
			}
+
		}
+

+
		/* Leave variable as is */
+
		if (!found) {
+
			memcpy (d, ptr, 2);
+
			d += 2;
+
			ret --;
+
		}
	}

	*dest = d;
@@ -1873,6 +1908,14 @@ ucl_parser_register_variable (struct ucl_parser *parser, const char *var,
	}
}

+
void
+
ucl_parser_set_variables_handler (struct ucl_parser *parser,
+
		ucl_variable_handler handler, void *ud)
+
{
+
	parser->var_handler = handler;
+
	parser->var_data = ud;
+
}
+

bool
ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data,
		size_t len)
modified external/libucl/src/ucl_util.c
@@ -1330,20 +1330,10 @@ ucl_object_find_keyl (const ucl_object_t *obj, const char *key, size_t klen)
const ucl_object_t *
ucl_object_find_key (const ucl_object_t *obj, const char *key)
{
-
	size_t klen;
-
	const ucl_object_t *ret;
-
	ucl_object_t srch;
-

-
	if (obj == NULL || obj->type != UCL_OBJECT || key == NULL) {
+
	if (key == NULL)
		return NULL;
-
	}
-

-
	klen = strlen (key);
-
	srch.key = key;
-
	srch.keylen = klen;
-
	ret = ucl_hash_search_obj (obj->value.ov, &srch);

-
	return ret;
+
	return ucl_object_find_keyl (obj, key, strlen(key));
}

const ucl_object_t*
@@ -1396,6 +1386,58 @@ ucl_iterate_object (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expan
	return NULL;
}

+
const ucl_object_t *
+
ucl_lookup_path (const ucl_object_t *top, const char *path_in) {
+
	const ucl_object_t *o = NULL, *found;
+
	const char *p, *c;
+
	char *err_str;
+
	unsigned index;
+

+
	if (path_in == NULL || top == NULL) {
+
		return NULL;
+
	}
+

+
	found = NULL;
+
	p = path_in;
+

+
	/* Skip leading dots */
+
	while (*p == '.') {
+
		p ++;
+
	}
+

+
	c = p;
+
	while (*p != '\0') {
+
		p ++;
+
		if (*p == '.' || *p == '\0') {
+
			if (p > c) {
+
				switch (top->type) {
+
				case UCL_ARRAY:
+
					/* Key should be an int */
+
					index = strtoul (c, &err_str, 10);
+
					if (err_str != NULL && (*err_str != '.' && *err_str != '\0')) {
+
						return NULL;
+
					}
+
					o = ucl_array_find_index (top, index);
+
					break;
+
				default:
+
					o = ucl_object_find_keyl (top, c, p - c);
+
					break;
+
				}
+
				if (o == NULL) {
+
					return NULL;
+
				}
+
				top = o;
+
			}
+
			if (*p != '\0') {
+
				c = p + 1;
+
			}
+
		}
+
	}
+
	found = o;
+

+
	return found;
+
}
+


ucl_object_t *
ucl_object_new (void)
@@ -1411,7 +1453,7 @@ ucl_object_new (void)
}

ucl_object_t *
-
ucl_object_typed_new (unsigned int type)
+
ucl_object_typed_new (ucl_type_t type)
{
	ucl_object_t *new;
	new = malloc (sizeof (ucl_object_t));
@@ -1423,6 +1465,12 @@ ucl_object_typed_new (unsigned int type)
	return new;
}

+
ucl_type_t
+
ucl_object_type (const ucl_object_t *obj)
+
{
+
	return obj->type;
+
}
+

ucl_object_t*
ucl_object_fromstring (const char *str)
{
@@ -1591,6 +1639,27 @@ ucl_array_pop_first (ucl_object_t *top)
	return ucl_array_delete (top, __DECONST(ucl_object_t *, ucl_array_head (top)));
}

+
const ucl_object_t *
+
ucl_array_find_index (const ucl_object_t *top, unsigned int index)
+
{
+
	ucl_object_iter_t it = NULL;
+
	const ucl_object_t *ret;
+

+
	if (top == NULL || top->type != UCL_ARRAY || top->len == 0 ||
+
	    (index + 1) > top->len) {
+
		return NULL;
+
	}
+

+
	while ((ret = ucl_iterate_object (top, &it, true)) != NULL) {
+
		if (index == 0) {
+
			return ret;
+
		}
+
		--index;
+
	}
+

+
	return NULL;
+
}
+

ucl_object_t *
ucl_elt_append (ucl_object_t *head, ucl_object_t *elt)
{
modified external/libucl/tests/test_generate.c
@@ -30,6 +30,7 @@ int
main (int argc, char **argv)
{
	ucl_object_t *obj, *cur, *ar, *ref;
+
	const ucl_object_t *found;
	FILE *out;
	unsigned char *emitted;
	const char *fname_out = NULL;
@@ -114,6 +115,23 @@ main (int argc, char **argv)
	cur = ucl_object_frombool (true);
	ucl_object_insert_key (obj, cur, "k=3", 0, false);

+
	/* Try to find using path */
+
	/* Should exist */
+
	found = ucl_lookup_path (obj, "key4.1");
+
	assert (found != NULL && ucl_object_toint (found) == 10);
+
	/* . should be ignored */
+
	found = ucl_lookup_path (obj, ".key4.1");
+
	assert (found != NULL && ucl_object_toint (found) == 10);
+
	/* moar dots... */
+
	found = ucl_lookup_path (obj, ".key4........1...");
+
	assert (found != NULL && ucl_object_toint (found) == 10);
+
	/* No such index */
+
	found = ucl_lookup_path (obj, ".key4.3");
+
	assert (found == NULL);
+
	/* No such key */
+
	found = ucl_lookup_path (obj, "key9..key1");
+
	assert (found == NULL);
+

	emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG);

	fprintf (out, "%s\n", emitted);