aboutsummaryrefslogtreecommitdiff
path: root/src/ucl_util.c
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2014-05-24 23:40:39 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2014-05-24 23:40:39 +0000
commiteaa81a1805da0fde938c109a768e9c48471c3bb9 (patch)
tree11177c8667280f65b11e0c5d96830f43a8e5d860 /src/ucl_util.c
parentd4fc17b1e5ff64ea70cfb02594ae87f599f81c29 (diff)
downloadsrc-23aa14c25d6c9dda34b1a3d09ce75b3bd7bffed0.tar.gz
src-23aa14c25d6c9dda34b1a3d09ce75b3bd7bffed0.zip
Import libucl version 2014-05-14 (almost 0.4.1)vendor/libucl/20140514
This bring ucl_lookup_path (xpath like for ucl objects)
Diffstat (limited to 'src/ucl_util.c')
-rw-r--r--src/ucl_util.c95
1 files changed, 82 insertions, 13 deletions
diff --git a/src/ucl_util.c b/src/ucl_util.c
index 9178795d9446..63f5e629826f 100644
--- a/src/ucl_util.c
+++ b/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)
{