Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Sync libucl
Baptiste Daroussin committed 12 years ago
commit 9779c4a47376f4f8315f10b75e344b9821e44a73
parent b84e1cc
4 files changed +82 -11
modified external/libucl/include/ucl.h
@@ -306,6 +306,19 @@ ucl_object_t* ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt,
		const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT;

/**
+
 * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist,
+
 * try to merge its content
+
 * @param top destination object (will be created automatically if top is NULL)
+
 * @param elt element to insert (must NOT be NULL)
+
 * @param key key to associate with this object (either const or preallocated)
+
 * @param keylen length of the key (or 0 for NULL terminated keys)
+
 * @param copy_key make an internal copy of key
+
 * @return new value of top object
+
 */
+
ucl_object_t* ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt,
+
		const char *key, size_t keylen, bool copy_key) UCL_WARN_UNUSED_RESULT;
+

+
/**
 * Append an element to the array object
 * @param top destination object (will be created automatically if top is NULL)
 * @param eltelement to append (must NOT be NULL)
modified external/libucl/src/ucl_hash.c
@@ -66,7 +66,7 @@ ucl_hash_iterate (ucl_hash_t *hashlin, ucl_hash_iter_t *iter)
	ucl_hash_node_t *elt = *iter;

	if (elt == NULL) {
-
		if (hashlin->buckets == NULL) {
+
		if (hashlin == NULL || hashlin->buckets == NULL) {
			return NULL;
		}
		elt = hashlin->buckets;
@@ -103,3 +103,15 @@ ucl_hash_search (ucl_hash_t* hashlin, const char *key, unsigned keylen)
	}
	return NULL;
}
+

+
void
+
ucl_hash_delete (ucl_hash_t* hashlin, ucl_object_t *obj)
+
{
+
	ucl_hash_node_t *found;
+

+
	HASH_FIND (hh, hashlin->buckets, obj->key, obj->keylen, found);
+

+
	if (found) {
+
		HASH_DELETE (hh, hashlin->buckets, found);
+
	}
+
}
modified external/libucl/src/ucl_hash.h
@@ -65,6 +65,11 @@ void ucl_hash_destroy (ucl_hash_t* hashlin, ucl_hash_free_func *func);
void ucl_hash_insert (ucl_hash_t* hashlin, ucl_object_t *obj, const char *key, unsigned keylen);

/**
+
 * Delete an element from the the hashtable.
+
 */
+
void ucl_hash_delete (ucl_hash_t* hashlin, ucl_object_t *obj);
+

+
/**
 * Searches an element in the hashtable.
 */
ucl_object_t* ucl_hash_search (ucl_hash_t* hashlin, const char *key, unsigned keylen);
modified external/libucl/src/ucl_util.c
@@ -62,7 +62,7 @@ ucl_object_free_internal (ucl_object_t *obj, bool allow_rec)
		}
		else if (obj->type == UCL_OBJECT) {
			if (obj->value.ov != NULL) {
-
				ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func *)ucl_obj_free);
+
				ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func *)ucl_object_unref);
			}
		}
		tmp = obj->next;
@@ -858,11 +858,12 @@ ucl_object_fromstring_common (const char *str, size_t len, enum ucl_string_flags
	return obj;
}

-
ucl_object_t *
-
ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt,
-
		const char *key, size_t keylen, bool copy_key)
+
static ucl_object_t *
+
ucl_object_insert_key_common (ucl_object_t *top, ucl_object_t *elt,
+
		const char *key, size_t keylen, bool copy_key, bool merge)
{
-
	ucl_object_t *found;
+
	ucl_object_t *found, *cur;
+
	ucl_object_iter_t it = NULL;
	const char *p;

	if (elt == NULL || key == NULL) {
@@ -892,22 +893,62 @@ ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt,
	elt->key = key;
	elt->keylen = keylen;

+
	if (copy_key) {
+
		ucl_copy_key_trash (elt);
+
	}
+

	found = ucl_hash_search_obj (top->value.ov, elt);

	if (!found) {
		top->value.ov = ucl_hash_insert_object (top->value.ov, elt);
+
		DL_APPEND (found, elt);
	}
-

-
	DL_APPEND (found, elt);
-

-
	if (copy_key) {
-
		ucl_copy_key_trash (elt);
+
	else if (!merge) {
+
		DL_APPEND (found, elt);
+
	}
+
	else {
+
		if (found->type != UCL_OBJECT && elt->type == UCL_OBJECT) {
+
			/* Insert old elt to new one */
+
			elt = ucl_object_insert_key_common (elt, found, found->key, found->keylen, copy_key, false);
+
			ucl_hash_delete (top->value.ov, found);
+
			top->value.ov = ucl_hash_insert_object (top->value.ov, elt);
+
		}
+
		else if (found->type == UCL_OBJECT && elt->type != UCL_OBJECT) {
+
			/* Insert new to old */
+
			found = ucl_object_insert_key_common (found, elt, elt->key, elt->keylen, copy_key, false);
+
		}
+
		else if (found->type == UCL_OBJECT && elt->type == UCL_OBJECT) {
+
			/* Mix two hashes */
+
			while ((cur = ucl_iterate_object (elt, &it, true)) != NULL) {
+
				ucl_object_ref (cur);
+
				found = ucl_object_insert_key_common (found, cur, cur->key, cur->keylen, copy_key, false);
+
			}
+
			ucl_object_unref (elt);
+
		}
+
		else {
+
			/* Just make a list of scalars */
+
			DL_APPEND (found, elt);
+
		}
	}

	return top;
}

ucl_object_t *
+
ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt,
+
		const char *key, size_t keylen, bool copy_key)
+
{
+
	return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, false);
+
}
+

+
ucl_object_t *
+
ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt,
+
		const char *key, size_t keylen, bool copy_key)
+
{
+
	return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, true);
+
}
+

+
ucl_object_t *
ucl_obj_get_keyl (ucl_object_t *obj, const char *key, size_t klen)
{
	ucl_object_t *ret, srch;