Skip to content

Commit e6c77f1

Browse files
committed
ability to include children
1 parent 14ad790 commit e6c77f1

File tree

5 files changed

+67
-19
lines changed

5 files changed

+67
-19
lines changed

cffi/cdefs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,6 @@ void free(void *);
13531353

13541354
/* From source.c custom C code helpers for backlinks */
13551355
size_t pyly_backlinks_xpath_leafrefs(const struct ly_ctx *ctx, const char *xpath, char ***out);
1356-
size_t pyly_backlinks_find_leafref_nodes(const struct ly_ctx *ctx, const char *base_path, char ***out);
1356+
size_t pyly_backlinks_find_leafref_nodes(const struct ly_ctx *ctx, const char *base_path, int include_children, char ***out);
13571357

13581358
void pyly_cstr_array_free(char **list, size_t nlist);

cffi/source.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void pyly_cstr_array_free(char **list, size_t nlist)
5353
typedef struct {
5454
const struct ly_ctx *ctx;
5555
const char *base_path;
56+
int include_children;
5657
pyly_string_list_t *res;
5758
} pyly_dfs_data_t;
5859

@@ -208,7 +209,8 @@ static LY_ERR pyly_backlinks_find_leafref_nodes_clb(struct lysc_node *node, void
208209

209210
/*! Search the entire loaded schema for any nodes that contain a leafref and
210211
* record the path. If a base_path is specified, only leafrefs that point to
211-
* the specified path will be recorded.
212+
* the specified path will be recorded, if include_children is 1, then children
213+
* of the specified path are also included.
212214
*
213215
* This function is used in replacement for the concept of backlink references
214216
* that were part of libyang v1 but were subsequently removed. This is
@@ -221,14 +223,17 @@ static LY_ERR pyly_backlinks_find_leafref_nodes_clb(struct lysc_node *node, void
221223
* the leafref is pointing as part of building the cache. It is expected most
222224
* users will not need the cache and will simply pass in the base_path as needed.
223225
*
224-
* \param[in] ctx Initialized context with loaded schema
225-
* \param[in] base_path Optional base node path to restrict output.
226-
* \param[out] out Pointer passed by reference that will hold a C array
227-
* of c strings representing the paths for any leaf
228-
* references.
226+
* \param[in] ctx Initialized context with loaded schema
227+
* \param[in] base_path Optional base node path to restrict output.
228+
* \param[in] include_children Whether or not to include children of the
229+
* specified base path or if the path is an
230+
* explicit reference.
231+
* \param[out] out Pointer passed by reference that will hold a C
232+
* array of c strings representing the paths for
233+
* any leaf references.
229234
* \return number of results, or 0 if none.
230235
*/
231-
size_t pyly_backlinks_find_leafref_nodes(const struct ly_ctx *ctx, const char *base_path, char ***out)
236+
size_t pyly_backlinks_find_leafref_nodes(const struct ly_ctx *ctx, const char *base_path, int include_children, char ***out)
232237
{
233238
pyly_string_list_t res;
234239
uint32_t module_idx = 0;
@@ -242,7 +247,7 @@ size_t pyly_backlinks_find_leafref_nodes(const struct ly_ctx *ctx, const char *b
242247

243248
/* Iterate across all loaded modules */
244249
for (module_idx = 0; (module = ly_ctx_get_module_iter(ctx, &module_idx)) != NULL; ) {
245-
pyly_dfs_data_t data = { ctx, base_path, &res };
250+
pyly_dfs_data_t data = { ctx, base_path, include_children, &res };
246251

247252
lysc_module_dfs_full(module, pyly_backlinks_find_leafref_nodes_clb, &data);
248253
/* Ignore error */

libyang/context.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,15 +646,15 @@ def parse_data_file(
646646
json_null=json_null,
647647
)
648648

649-
def backlinks_find_leafref_nodes(self, base_path: str = None) -> list[str]:
649+
def backlinks_find_leafref_nodes(self, base_path: str = None, include_children: bool = False) -> list[str]:
650650
if self.cdata is None:
651651
raise RuntimeError("context already destroyed")
652652

653653
out = []
654654

655655
carray = ffi.new("char ***")
656656
clen = lib.pyly_backlinks_find_leafref_nodes(
657-
self.cdata, str2c(base_path), carray
657+
self.cdata, str2c(base_path), 1 if include_children else 0, carray
658658
)
659659
if clen == 0:
660660
return out

tests/test_schema.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -813,23 +813,58 @@ def tearDown(self):
813813
self.ctx = None
814814

815815
def test_backlinks_all_nodes(self):
816+
expected = [
817+
"/yolo-leafref-search-extmod:my_extref_list/my_extref",
818+
"/yolo-leafref-search:refstr",
819+
"/yolo-leafref-search:refnum",
820+
"/yolo-leafref-search-extmod:my_extref_list/my_extref_union"
821+
]
816822
refs = self.ctx.backlinks_find_leafref_nodes()
817-
assert len(refs) == 3
823+
824+
expected.sort()
825+
refs.sort()
826+
self.assertEqual(expected, refs)
818827

819828
def test_backlinks_one(self):
829+
expected = [
830+
"/yolo-leafref-search-extmod:my_extref_list/my_extref",
831+
"/yolo-leafref-search:refstr",
832+
"/yolo-leafref-search-extmod:my_extref_list/my_extref_union"
833+
]
820834
refs = self.ctx.backlinks_find_leafref_nodes(
821835
base_path="/yolo-leafref-search:my_list/my_leaf_string"
822836
)
823-
assert len(refs) == 3
824-
assert "/yolo-leafref-search-extmod:my_extref_list/my_extref" in refs
825-
assert "/yolo-leafref-search:ref1" in refs
826-
assert "/yolo-leafref-search-extmod:my_extref_list/my_extref_union" in refs
837+
838+
expected.sort()
839+
refs.sort()
840+
self.assertEqual(expected, refs)
841+
842+
def test_backlinks_children(self):
843+
expected = [
844+
"/yolo-leafref-search-extmod:my_extref_list/my_extref",
845+
"/yolo-leafref-search:refstr",
846+
"/yolo-leafref-search:refnum",
847+
"/yolo-leafref-search-extmod:my_extref_list/my_extref_union"
848+
]
849+
refs = self.ctx.backlinks_find_leafref_nodes(
850+
base_path="/yolo-leafref-search:my_list/"
851+
)
852+
853+
expecte.sort()
854+
refs.sort()
855+
self.assertEqual(expected, refs)
827856

828857
def test_backlinks_xpath_leafrefs(self):
858+
expected = [
859+
"/leafref-search:my_list/leafref-search:my_leaf_string"
860+
]
829861
refs = self.ctx.backlinks_xpath_leafrefs(
830862
"/yolo-leafref-search-extmod:my_extref_list/my_extref"
831863
)
832-
assert len(refs) > 0
864+
865+
expected.sort()
866+
refs.sort()
867+
self.assertEqual(expected, refs)
833868

834869

835870
# -------------------------------------------------------------------------------------

tests/yang/yolo/yolo-leafref-search.yang

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,24 @@ module yolo-leafref-search {
1515
leaf my_leaf_string {
1616
type string;
1717
}
18-
leaf-list my_leaf_list_number {
18+
leaf-list my_leaf_number {
1919
description
2020
"A number.";
2121
type types:number;
2222
}
2323
}
2424

25-
leaf ref1 {
25+
leaf refstr {
2626
type leafref {
2727
path "../my_list/my_leaf_string";
2828
}
2929
}
30+
31+
leaf refnum {
32+
type leafref {
33+
path "../my_list/my_leaf_number";
34+
}
35+
}
36+
37+
leaf
3038
}

0 commit comments

Comments
 (0)