schema compile BUGFIX sooner recompilation
Recompilation needs to be performed right
when it is required for the module that
caused it. So now from the point of trying
to compile a new module that sets the
recompile flag to the glob_unres function
that must have caused it, LY_ERECOMPILE
is passed.
Fixes #1528
diff --git a/src/path.c b/src/path.c
index 6a413a3..0190811 100644
--- a/src/path.c
+++ b/src/path.c
@@ -24,6 +24,7 @@
#include "compat.h"
#include "log.h"
#include "plugins_types.h"
+#include "schema_compile.h"
#include "set.h"
#include "tree.h"
#include "tree_data_internal.h"
@@ -431,6 +432,9 @@
assert(unres);
LY_CHECK_GOTO(ret = lys_set_implemented_r((struct lys_module *)*mod, NULL, unres), error);
+ if (unres->recompile) {
+ return LY_ERECOMPILE;
+ }
}
LOG_LOCBACK(cur_node ? 1 : 0, 0, 0, 0);
diff --git a/src/path.h b/src/path.h
index 2183d71..2245298 100644
--- a/src/path.h
+++ b/src/path.h
@@ -168,6 +168,7 @@
* @param[in] prefix_data Format-specific data for resolving any prefixes (see ::ly_resolve_prefix).
* @param[in,out] unres Global unres structure for newly implemented modules, needed only if @p lref is ::LY_PATH_LREF_TRUE.
* @param[out] path Compiled path.
+ * @return LY_ERECOMPILE, only if @p lref is ::LY_PATH_LREF_TRUE.
* @return LY_ERR value.
*/
LY_ERR ly_path_compile(const struct ly_ctx *ctx, const struct lys_module *cur_mod, const struct lysc_node *ctx_node,
diff --git a/src/plugins_types.h b/src/plugins_types.h
index 92a12a3..d104b45 100644
--- a/src/plugins_types.h
+++ b/src/plugins_types.h
@@ -242,6 +242,7 @@
* @param[in] mod Module to implement.
* @param[in] features Array of features to enable.
* @param[in,out] unres Global unres to add to.
+ * @return LY_ERECOMPILE if the context need to be recompiled, should be returned.
* @return LY_ERR value.
*/
LY_ERR lyplg_type_make_implemented(struct lys_module *mod, const char **features, struct lys_glob_unres *unres);
@@ -317,6 +318,7 @@
* @param[out] path Pointer to store the created structure representing the schema path from the @p value.
* @param[out] err Pointer to store the error information provided in case of failure.
* @return LY_SUCCESS on success,
+ * @return LY_ERECOMPILE if the context need to be recompiled, should be returned.
* @return LY_ERR value on error.
*/
LY_ERR lyplg_type_lypath_new(const struct ly_ctx *ctx, const char *value, size_t value_len, uint32_t options,
diff --git a/src/schema_compile.c b/src/schema_compile.c
index b07b1c2..a525ece 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -821,6 +821,9 @@
/* unimplemented module found */
if (implement) {
LY_CHECK_RET(lys_set_implemented_r((struct lys_module *)mod, NULL, unres));
+ if (unres->recompile) {
+ return LY_ERECOMPILE;
+ }
} else {
*mod_p = mod;
break;
@@ -837,6 +840,7 @@
* @param[in] ctx Compile context.
* @param[in] node Node to check.
* @param[in,out] unres Global unres structure.
+ * @return LY_ERECOMPILE
* @return LY_ERR value
*/
static LY_ERR
@@ -967,6 +971,7 @@
* @param[in] node Context node for the leafref.
* @param[in] lref Leafref to check/resolve.
* @param[in,out] unres Global unres structure.
+ * @return LY_ERECOMPILE if context recompilation is needed,
* @return LY_ERR value.
*/
static LY_ERR
@@ -1185,6 +1190,8 @@
uint32_t i;
if (unres->recompile) {
+recompilation:
+ assert(unres->recompile);
/* recompile all the modules and resolve the new unres instead (during recompilation) */
unres->recompile = 0;
return lys_recompile(ctx, 1);
@@ -1223,7 +1230,10 @@
}
LOG_LOCBACK(1, 0, 0, 0);
- if (ret) {
+ if (ret == LY_ERECOMPILE) {
+ /* leafref caused a new module to be implemented, following leafrefs referencing the module would fail */
+ goto recompilation;
+ } else if (ret) {
return ret;
}
}
@@ -1266,7 +1276,11 @@
ret = lys_compile_unres_xpath(&cctx, node, unres);
LOG_LOCBACK(1, 0, 0, 0);
- LY_CHECK_RET(ret);
+ if (ret == LY_ERECOMPILE) {
+ goto recompilation;
+ } else if (ret) {
+ return ret;
+ }
ly_set_rm_index(&unres->xpath, unres->xpath.count - 1, NULL);
}
@@ -1285,14 +1299,18 @@
ret = lys_compile_unres_llist_dflts(&cctx, r->llist, r->dflt, r->dflts, unres);
}
LOG_LOCBACK(1, 0, 0, 0);
- LY_CHECK_RET(ret && (ret != LY_ERECOMPILE), ret);
+ if (ret == LY_ERECOMPILE) {
+ goto recompilation;
+ } else if (ret) {
+ return ret;
+ }
lysc_unres_dflt_free(ctx, r);
ly_set_rm_index(&unres->dflts, unres->dflts.count - 1, NULL);
}
- /* some unres items may have been added or recompilation needed */
- if (unres->leafrefs.count || unres->xpath.count || unres->dflts.count || unres->recompile) {
+ /* some unres items may have been added */
+ if (unres->leafrefs.count || unres->xpath.count || unres->dflts.count) {
return lys_compile_unres_glob(ctx, unres);
}
diff --git a/src/schema_compile.h b/src/schema_compile.h
index c3adbff..bd19aed 100644
--- a/src/schema_compile.h
+++ b/src/schema_compile.h
@@ -233,6 +233,7 @@
* @param[in,out] unres Global unres structure of newly implemented modules.
* @param[out] mod_p Module that is not implemented.
* @return LY_SUCCESS on success.
+ * @return LY_ERECOMPILE if @p implement is set.
* @return LY_ERR on error.
*/
LY_ERR lys_compile_expr_implement(const struct ly_ctx *ctx, const struct lyxp_expr *expr, LY_VALUE_FORMAT format,