data tree REFACTOR lyd_target function
diff --git a/src/tree_data.c b/src/tree_data.c
index 934869a..de3b39f 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1430,74 +1430,76 @@
API const struct lyd_node_term *
lyd_target(struct lyd_value_path *path, const struct lyd_node *tree)
{
- unsigned int u, x;
- const struct lyd_node *parent = NULL, *start_search;
+ uint32_t u, x;
+ const struct lyd_node *start_sibling;
struct lyd_node *node = NULL;
uint64_t pos = 1;
+ int match;
LY_CHECK_ARG_RET(NULL, path, tree, NULL);
- LY_ARRAY_FOR(path, u) {
- if (parent) {
- start_search = lyd_node_children(parent);
-search_inner:
- lyd_find_sibling_next(start_search, path[u].node->module, path[u].node->name, 0, NULL, 0, &node);
- } else {
- start_search = tree;
-search_toplevel:
- /* WARNING! to use search_toplevel label correctly, variable v must be preserved and not changed! */
- lyd_find_sibling_next(start_search, path[u].node->module, path[u].node->name, 0, NULL, 0, &node);
- }
+ /* first iteration */
+ start_sibling = tree;
+ u = 0;
+ while (u < LY_ARRAY_SIZE(path)) {
+ /* find next node instance */
+ lyd_find_sibling_next2(start_sibling, path[u].node, NULL, 0, &node);
if (!node) {
- return NULL;
+ break;
}
/* check predicate if any */
+ match = 1;
LY_ARRAY_FOR(path[u].predicates, x) {
if (path[u].predicates[x].type == 0) {
+ assert(LY_ARRAY_SIZE(path[u].predicates) == 1);
/* position predicate */
if (pos != path[u].predicates[x].position) {
pos++;
- goto search_repeat;
+ match = 0;
}
- /* done, no more predicates are allowed here */
- break;
} else if (path[u].predicates[x].type == 1) {
/* key-predicate */
- struct lysc_type *type = ((struct lysc_node_leaf*)path[u].predicates[x].key)->type;
+ struct lysc_type *type = ((struct lysc_node_leaf *)path[u].predicates[x].key)->type;
struct lyd_node *key;
- lyd_find_sibling_next(lyd_node_children(node), path[u].predicates[x].key->module,
- path[u].predicates[x].key->name, 0, NULL, 0, &key);
+
+ lyd_find_sibling_next2(lyd_node_children(node), path[u].predicates[x].key, NULL, 0, &key);
if (!key) {
/* probably error and we shouldn't be here due to previous checks when creating path */
- goto search_repeat;
- }
- if (type->plugin->compare(&((struct lyd_node_term*)key)->value, path[u].predicates[x].value)) {
- goto search_repeat;
+ match = 0;
+ } else if (type->plugin->compare(&((struct lyd_node_term *)key)->value, path[u].predicates[x].value)) {
+ match = 0;
}
} else if (path[u].predicates[x].type == 2) {
/* leaf-list-predicate */
- struct lysc_type *type = ((struct lysc_node_leaf*)path[u].node)->type;
- if (type->plugin->compare(&((struct lyd_node_term*)node)->value, path[u].predicates[x].value)) {
- goto search_repeat;
+ struct lysc_type *type = ((struct lysc_node_leaf *)path[u].node)->type;
+
+ if (type->plugin->compare(&((struct lyd_node_term *)node)->value, path[u].predicates[x].value)) {
+ match = 0;
}
} else {
LOGINT(NULL);
+ return NULL;
+ }
+
+ if (!match) {
+ /* useless to check more predicates */
+ break;
}
}
- parent = node;
+ if (!match) {
+ /* try to match next sibling */
+ start_sibling = node->next;
+ } else {
+ /* matched, move to the next path segment */
+ ++u;
+ start_sibling = lyd_node_children(node);
+ pos = 1;
+ }
}
- return (const struct lyd_node_term*)node;
-
-search_repeat:
- start_search = node->next;
- if (parent) {
- goto search_inner;
- } else {
- goto search_toplevel;
- }
+ return (const struct lyd_node_term *)node;
}
API LY_ERR