diff options
author | Baptiste Daroussin <bapt@FreeBSD.org> | 2014-05-24 23:40:39 +0000 |
---|---|---|
committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2014-05-24 23:40:39 +0000 |
commit | eaa81a1805da0fde938c109a768e9c48471c3bb9 (patch) | |
tree | 11177c8667280f65b11e0c5d96830f43a8e5d860 /src/ucl_util.c | |
parent | d4fc17b1e5ff64ea70cfb02594ae87f599f81c29 (diff) | |
download | src-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.c | 95 |
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) { |