Skip to content

Commit c831064

Browse files
committed
schema tree FETAURE function for getting data path format string pattern
... for schema nodes. Refs #1087 Signed-off-by: Robin Jarry <robin.jarry@6wind.com>
1 parent baa7efd commit c831064

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

src/tree_schema.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5185,6 +5185,78 @@ lys_data_path(const struct lys_node *node)
51855185
return result;
51865186
}
51875187

5188+
API char *
5189+
lys_data_path_pattern(const struct lys_node *node, const char *placeholder)
5190+
{
5191+
FUN_IN;
5192+
5193+
const struct lys_module *prev_mod, *mod;
5194+
char *result = NULL, keys[512], buf[2048];
5195+
const char *name, *separator;
5196+
struct ly_set *set;
5197+
size_t x;
5198+
int i;
5199+
5200+
if (!node || !placeholder) {
5201+
LOGARG;
5202+
return NULL;
5203+
}
5204+
5205+
buf[0] = '\0';
5206+
set = ly_set_new();
5207+
LY_CHECK_ERR_GOTO(!set, LOGMEM(node->module->ctx), cleanup);
5208+
5209+
/* collect all schema nodes that can be instantiated into a set */
5210+
while (node) {
5211+
ly_set_add(set, (void *)node, 0);
5212+
do {
5213+
node = lys_parent(node);
5214+
} while (node && (node->nodetype & (LYS_USES | LYS_CHOICE | LYS_CASE | LYS_INPUT | LYS_OUTPUT)));
5215+
}
5216+
5217+
x = 0;
5218+
prev_mod = NULL;
5219+
5220+
/* build path for all the collected nodes */
5221+
for (i = set->number - 1; i > -1; --i) {
5222+
size_t k = 0;
5223+
keys[0] = '\0';
5224+
node = set->set.s[i];
5225+
if (node->nodetype == LYS_EXT) {
5226+
if (strcmp(((struct lys_ext_instance *)node)->def->name, "yang-data")) {
5227+
continue;
5228+
}
5229+
name = ((struct lys_ext_instance *)node)->arg_value;
5230+
separator = ":#";
5231+
} else {
5232+
name = node->name;
5233+
separator = ":";
5234+
}
5235+
if (node->nodetype == LYS_LIST) {
5236+
/* add specific key values (placeholders) for list */
5237+
const struct lys_node_list *list;
5238+
list = (const struct lys_node_list *)node;
5239+
for (uint8_t j = 0; j < list->keys_size; j++) {
5240+
k += sprintf(keys + k, "[%s=%s]", list->keys[j]->name, placeholder);
5241+
}
5242+
}
5243+
mod = lys_node_module(node);
5244+
if (mod && mod != prev_mod) {
5245+
prev_mod = mod;
5246+
x += sprintf(buf + x, "/%s%s%s%s", mod->name, separator, name, keys);
5247+
} else {
5248+
x += sprintf(buf + x, "/%s%s", name, keys);
5249+
}
5250+
}
5251+
5252+
result = strdup(buf);
5253+
LY_CHECK_ERR_GOTO(!result, LOGMEM(node->module->ctx), cleanup);
5254+
5255+
cleanup:
5256+
ly_set_free(set);
5257+
return result;
5258+
}
5259+
51885260
struct lys_node_augment *
51895261
lys_getnext_target_aug(struct lys_node_augment *last, const struct lys_module *mod, const struct lys_node *aug_target)
51905262
{

src/tree_schema.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,6 +2359,21 @@ char *lys_path(const struct lys_node *node, int options);
23592359
*/
23602360
char *lys_data_path(const struct lys_node *node);
23612361

2362+
/**
2363+
* @brief Build the data path pattern of a schema node.
2364+
*
2365+
* For example, when @p node is a leaf in a list with key1 and key2, in a container and `'%s'` is set as
2366+
* @p placeholder, the result would be `/model:container/list[key1='%s'][key2='%s']/leaf`. That can
2367+
* be used as `printf(3)` format string, for example.
2368+
*
2369+
* @param[in] node Schema node to be processed.
2370+
* @param[in] placeholder Placeholder to insert in the returned path when
2371+
* list key values are encountered.
2372+
* @return NULL on error, on success the buffer for the resulting path is
2373+
* allocated and caller is supposed to free it with free().
2374+
*/
2375+
char *lys_data_path_pattern(const struct lys_node *node, const char *placeholder);
2376+
23622377
/**
23632378
* @brief Return parent node in the schema tree.
23642379
*

0 commit comments

Comments
 (0)