From ebc3f7fd7dccd4d2d0509766dcde43608d9ebce1 Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Fri, 1 May 2015 23:26:30 +0200 Subject: Implement config_item_get() --- common.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/common.c b/common.c index 0981ed5..c4e9f08 100644 --- a/common.c +++ b/common.c @@ -488,6 +488,18 @@ toupper_ascii (int c) return c >= 'A' && c <= 'Z' ? c : c - ('a' - 'A'); } +static void +split_str (const char *s, char delimiter, struct str_vector *out) +{ + const char *begin = s, *end; + while ((end = strchr (begin, delimiter))) + { + str_vector_add_owned (out, xstrndup (begin, end - begin)); + begin = ++end; + } + str_vector_add (out, begin); +} + // --- Advanced configuration -------------------------------------------------- // This is a new configuration format, superseding the one currently present @@ -718,10 +730,33 @@ config_item_set_from (struct config_item_ *self, struct config_item_ *source, } static struct config_item_ * -config_item_get (struct config_item_ *self, const char *path) +config_item_get (struct config_item_ *self, const char *path, struct error **e) { hard_assert (self->type == CONFIG_ITEM_OBJECT); - // TODO + + struct str_vector v; + str_vector_init (&v); + split_str (path, '.', &v); + + struct config_item_ *result = NULL; + size_t i = 0; + while (true) + { + const char *key = v.vector[i]; + if (!*key) + error_set (e, "empty path element"); + else if (!(self = str_map_find (&self->value.object, key))) + error_set (e, "`%s' not found in object", key); + else if (++i == v.len) + result = self; + else if (self->type != CONFIG_ITEM_OBJECT) + error_set (e, "`%s' is not an object", key); + else + continue; + break; + } + str_vector_free (&v); + return result; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3-70-g09d2