@@ -1892,6 +1892,110 @@ lysc_node_lref_targets(const struct lysc_node *node, struct ly_set **set)
1892
1892
return rc ;
1893
1893
}
1894
1894
1895
+ struct lysc_node_lref_backlings_arg {
1896
+ const struct lysc_node * node ;
1897
+ ly_bool match_ancestors ;
1898
+ struct ly_set * set ;
1899
+ };
1900
+
1901
+ static LY_ERR
1902
+ lysc_node_lref_backlinks_clb (struct lysc_node * node , void * data , ly_bool * dfs_continue )
1903
+ {
1904
+ LY_ERR rc = LY_SUCCESS ;
1905
+ struct lysc_node_lref_backlings_arg * arg = data ;
1906
+ struct ly_set * set = NULL ;
1907
+ const struct lysc_node * par ;
1908
+ uint32_t i ;
1909
+
1910
+ (void )dfs_continue ;
1911
+
1912
+ if (!(node -> nodetype & LYD_NODE_TERM )) {
1913
+ /* skip */
1914
+ goto cleanup ;
1915
+ }
1916
+
1917
+ /* get all the leafref targets */
1918
+ LY_CHECK_GOTO (rc = lysc_node_lref_targets (node , & set ), cleanup );
1919
+
1920
+ /* ignore node if has no leafref targets */
1921
+ if (!set -> count ) {
1922
+ goto cleanup ;
1923
+ }
1924
+
1925
+ /* if just collecting leafrefs, we are done */
1926
+ if (!arg -> node ) {
1927
+ rc = ly_set_add (arg -> set , node , 1 , NULL );
1928
+ goto cleanup ;
1929
+ }
1930
+
1931
+ /* check that the node (or the ancestor of) is the target of this leafref */
1932
+ for (i = 0 ; i < set -> count ; ++ i ) {
1933
+ for (par = set -> snodes [i ]; par ; par = par -> parent ) {
1934
+ if (par == arg -> node ) {
1935
+ /* match */
1936
+ break ;
1937
+ }
1938
+
1939
+ if (!arg -> match_ancestors ) {
1940
+ /* not a match */
1941
+ par = NULL ;
1942
+ break ;
1943
+ }
1944
+ }
1945
+
1946
+
1947
+ if (par ) {
1948
+ /* add into the set, matches */
1949
+ LY_CHECK_GOTO (rc = ly_set_add (arg -> set , node , 1 , NULL ), cleanup );
1950
+ break ;
1951
+ }
1952
+ }
1953
+
1954
+ cleanup :
1955
+ ly_set_free (set , NULL );
1956
+ return rc ;
1957
+ }
1958
+
1959
+ LIBYANG_API_DEF LY_ERR
1960
+ lysc_node_lref_backlinks (const struct ly_ctx * ctx , const struct lysc_node * node , ly_bool match_ancestors ,
1961
+ struct ly_set * * set )
1962
+ {
1963
+ LY_ERR rc = LY_SUCCESS ;
1964
+ struct lysc_node_lref_backlings_arg arg = {0 };
1965
+ uint32_t idx = 0 ;
1966
+ const struct lys_module * mod ;
1967
+
1968
+ LY_CHECK_ARG_RET (NULL , ctx || node , set , LY_EINVAL );
1969
+
1970
+ if (!ctx ) {
1971
+ ctx = node -> module -> ctx ;
1972
+ }
1973
+
1974
+ /* allocate return set */
1975
+ LY_CHECK_RET (ly_set_new (set ));
1976
+
1977
+ /* prepare the arg */
1978
+ arg .node = node ;
1979
+ arg .match_ancestors = match_ancestors ;
1980
+ arg .set = * set ;
1981
+
1982
+ /* iterate across all loaded modules */
1983
+ while ((mod = ly_ctx_get_module_iter (ctx , & idx ))) {
1984
+ if (!mod -> compiled ) {
1985
+ continue ;
1986
+ }
1987
+
1988
+ LY_CHECK_GOTO (rc = lysc_module_dfs_full (mod , lysc_node_lref_backlinks_clb , & arg ), cleanup );
1989
+ }
1990
+
1991
+ cleanup :
1992
+ if (rc ) {
1993
+ ly_set_free (* set , NULL );
1994
+ * set = NULL ;
1995
+ }
1996
+ return rc ;
1997
+ }
1998
+
1895
1999
enum ly_stmt
1896
2000
lysp_match_kw (struct ly_in * in , uint64_t * indent )
1897
2001
{
0 commit comments