Skip to content

Commit

Permalink
schema tree FETAURE function for getting data path format string pattern
Browse files Browse the repository at this point in the history
... for schema nodes.
Refs #1087

Signed-off-by: Robin Jarry <[email protected]>
  • Loading branch information
michalvasko committed May 20, 2020
1 parent baa7efd commit c831064
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
72 changes: 72 additions & 0 deletions src/tree_schema.c
Original file line number Diff line number Diff line change
Expand Up @@ -5185,6 +5185,78 @@ lys_data_path(const struct lys_node *node)
return result;
}

API char *
lys_data_path_pattern(const struct lys_node *node, const char *placeholder)
{
FUN_IN;

const struct lys_module *prev_mod, *mod;
char *result = NULL, keys[512], buf[2048];
const char *name, *separator;
struct ly_set *set;
size_t x;
int i;

if (!node || !placeholder) {
LOGARG;
return NULL;
}

buf[0] = '\0';
set = ly_set_new();
LY_CHECK_ERR_GOTO(!set, LOGMEM(node->module->ctx), cleanup);

/* collect all schema nodes that can be instantiated into a set */
while (node) {
ly_set_add(set, (void *)node, 0);
do {
node = lys_parent(node);
} while (node && (node->nodetype & (LYS_USES | LYS_CHOICE | LYS_CASE | LYS_INPUT | LYS_OUTPUT)));
}

x = 0;
prev_mod = NULL;

/* build path for all the collected nodes */
for (i = set->number - 1; i > -1; --i) {
size_t k = 0;
keys[0] = '\0';
node = set->set.s[i];
if (node->nodetype == LYS_EXT) {
if (strcmp(((struct lys_ext_instance *)node)->def->name, "yang-data")) {
continue;
}
name = ((struct lys_ext_instance *)node)->arg_value;
separator = ":#";
} else {
name = node->name;
separator = ":";
}
if (node->nodetype == LYS_LIST) {
/* add specific key values (placeholders) for list */
const struct lys_node_list *list;
list = (const struct lys_node_list *)node;
for (uint8_t j = 0; j < list->keys_size; j++) {
k += sprintf(keys + k, "[%s=%s]", list->keys[j]->name, placeholder);
}
}
mod = lys_node_module(node);
if (mod && mod != prev_mod) {
prev_mod = mod;
x += sprintf(buf + x, "/%s%s%s%s", mod->name, separator, name, keys);
} else {
x += sprintf(buf + x, "/%s%s", name, keys);
}
}

result = strdup(buf);
LY_CHECK_ERR_GOTO(!result, LOGMEM(node->module->ctx), cleanup);

cleanup:
ly_set_free(set);
return result;
}

struct lys_node_augment *
lys_getnext_target_aug(struct lys_node_augment *last, const struct lys_module *mod, const struct lys_node *aug_target)
{
Expand Down
15 changes: 15 additions & 0 deletions src/tree_schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2359,6 +2359,21 @@ char *lys_path(const struct lys_node *node, int options);
*/
char *lys_data_path(const struct lys_node *node);

/**
* @brief Build the data path pattern of a schema node.
*
* For example, when @p node is a leaf in a list with key1 and key2, in a container and `'%s'` is set as
* @p placeholder, the result would be `/model:container/list[key1='%s'][key2='%s']/leaf`. That can
* be used as `printf(3)` format string, for example.
*
* @param[in] node Schema node to be processed.
* @param[in] placeholder Placeholder to insert in the returned path when
* list key values are encountered.
* @return NULL on error, on success the buffer for the resulting path is
* allocated and caller is supposed to free it with free().
*/
char *lys_data_path_pattern(const struct lys_node *node, const char *placeholder);

/**
* @brief Return parent node in the schema tree.
*
Expand Down

0 comments on commit c831064

Please sign in to comment.