@@ -103,6 +103,17 @@ lyd_val_getnext_ht_free(struct ly_ht *getnext_ht)
103103 lyht_free (getnext_ht , lyd_val_getnext_ht_free_cb );
104104}
105105
106+ /**
107+ * @brief Wrapper of ::lyd_val_getnext_ht_free() to be used as a set item destructor.
108+ *
109+ * @param[in] getnext_ht Getnext HT to free.
110+ */
111+ static void
112+ lyd_val_getnext_ht_set_free (void * getnext_ht )
113+ {
114+ lyd_val_getnext_ht_free (getnext_ht );
115+ }
116+
106117LY_ERR
107118lyd_val_getnext_get (const struct lysc_node * sparent , const struct lys_module * mod , const struct lysc_ext_instance * ext ,
108119 ly_bool output , struct ly_ht * getnext_ht , const struct lysc_node * * * choices , const struct lysc_node * * * snodes )
@@ -1989,7 +2000,7 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
19892000 LY_ERR r , rc = LY_SUCCESS ;
19902001 struct lyd_node * first , * next , * * first2 , * iter ;
19912002 const struct lys_module * mod ;
1992- struct ly_set node_types = {0 }, meta_types = {0 }, node_when = {0 }, ext_val = {0 };
2003+ struct ly_set node_types = {0 }, meta_types = {0 }, node_when = {0 }, ext_val = {0 }, mod_set = { 0 }, getnext_ht_set = { 0 } ;
19932004 uint32_t i = 0 , impl_opts ;
19942005 struct ly_ht * getnext_ht = NULL ;
19952006
@@ -2025,6 +2036,12 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
20252036 r = lyd_val_getnext_ht_new (& getnext_ht );
20262037 LY_CHECK_ERR_GOTO (r , rc = r , cleanup );
20272038
2039+ /* store getnext_ht and module for final validation */
2040+ r = ly_set_add (& getnext_ht_set , getnext_ht , 1 , NULL );
2041+ LY_CHECK_ERR_GOTO (r , lyd_val_getnext_ht_free (getnext_ht ); rc = r , cleanup );
2042+ r = ly_set_add (& mod_set , mod , 1 , NULL );
2043+ LY_CHECK_ERR_GOTO (r , rc = r , cleanup );
2044+
20282045 /* validate new top-level nodes of this module, autodelete */
20292046 r = lyd_validate_new (first2 , * first2 ? lysc_data_parent ((* first2 )-> schema ) : NULL , mod , NULL , val_opts , 0 ,
20302047 getnext_ht , diff );
@@ -2075,24 +2092,30 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
20752092 r = lyd_validate_unres (first2 , mod , NULL , LYD_TYPE_DATA_YANG , node_when_p , 0 , node_types_p , meta_types_p ,
20762093 ext_val_p , val_opts , diff );
20772094 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
2095+ }
2096+
2097+ if (!(val_opts & LYD_VALIDATE_NOT_FINAL )) {
2098+ /* perform final validation that assumes the data tree is final */
2099+ for (i = 0 ; i < mod_set .count ; ++ i ) {
2100+ mod = mod_set .objs [i ];
2101+ getnext_ht = getnext_ht_set .objs [i ];
2102+
2103+ /* find data of this module */
2104+ first = * tree ;
2105+ lyd_first_module_sibling (& first , mod );
20782106
2079- if (!(val_opts & LYD_VALIDATE_NOT_FINAL )) {
2080- /* perform final validation that assumes the data tree is final */
2081- r = lyd_validate_final_r (* first2 , NULL , NULL , mod , NULL , val_opts , 0 , 0 , getnext_ht );
2107+ r = lyd_validate_final_r (first , NULL , NULL , mod , NULL , val_opts , 0 , 0 , getnext_ht );
20822108 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
20832109 }
2084-
2085- /* free the getnext hash table */
2086- lyht_free (getnext_ht , lyd_val_getnext_ht_free_cb );
2087- getnext_ht = NULL ;
20882110 }
20892111
20902112cleanup :
20912113 ly_set_erase (& node_when , NULL );
20922114 ly_set_erase (& node_types , NULL );
20932115 ly_set_erase (& meta_types , NULL );
20942116 ly_set_erase (& ext_val , free );
2095- lyd_val_getnext_ht_free (getnext_ht );
2117+ ly_set_erase (& mod_set , NULL );
2118+ ly_set_erase (& getnext_ht_set , lyd_val_getnext_ht_set_free );
20962119 return rc ;
20972120}
20982121
0 commit comments