schema helpers CHANGE added LYS_MOD_IMPORTED_REV
The new ::lys_get_module_without_revision() modifies the behavior of
the ::lys_parse_load() when a module is imported without specifying a
revision. Such an imported module is marked with the
::LYS_MOD_IMPORTED_REV flag and its priority is the highest. Also, the
implemented module takes precedence over the module with the latest
revision.
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 5415c28..0dbfefa 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -861,6 +861,53 @@
}
/**
+ * @brief Get module without revision according to priorities.
+ *
+ * 1. Search for the module with LYS_MOD_IMPORTED_REV.
+ * 2. Search for the implemented module.
+ * 3. Search for the latest module in the context.
+ *
+ * @param[in] ctx libyang context where module is searched.
+ * @param[in] name Name of the searched module.
+ * @param[out] keep_search Flag set to 1 if searchpaths or module
+ * callback must be searched to obtain latest available revision.
+ * @return Found module from context or NULL.
+ */
+static struct lys_module *
+lys_get_module_without_revision(struct ly_ctx *ctx, const char *name, ly_bool *keep_search)
+{
+ struct lys_module *mod, *mod_impl;
+ uint32_t index;
+
+ *keep_search = 0;
+
+ /* Try to find module with LYS_MOD_IMPORTED_REV flag. */
+ index = 0;
+ while ((mod = ly_ctx_get_module_iter(ctx, &index))) {
+ if (!strcmp(mod->name, name) && (mod->latest_revision & LYS_MOD_IMPORTED_REV)) {
+ break;
+ }
+ }
+
+ /* Try to find the implemented module. */
+ mod_impl = ly_ctx_get_module_implemented(ctx, name);
+ if (mod && mod_impl) {
+ LOGVRB("Implemented module \"%s@%s\" is not used for import, "
+ "revision \"%s\" is imported instead.",
+ mod_impl->name, mod_impl->revision, mod->revision);
+ return mod;
+ } else if (mod_impl) {
+ return mod_impl;
+ }
+
+ /* Try to find the latest module in the current context. */
+ mod = ly_ctx_get_module_latest(ctx, name);
+ *keep_search = 1;
+
+ return mod;
+}
+
+/**
* @brief Check if a circular dependency exists between modules.
*
* @param[in] ctx libyang context for log an error.
@@ -885,6 +932,7 @@
lys_parse_load(struct ly_ctx *ctx, const char *name, const char *revision, struct ly_set *new_mods,
struct lys_module **mod)
{
+ ly_bool keep_search;
struct lys_module *mod_latest = NULL;
assert(mod && new_mods);
@@ -897,8 +945,8 @@
*mod = ly_ctx_get_module(ctx, name, revision);
} else {
/* Get the requested module of the latest revision in the context. */
- *mod = ly_ctx_get_module_latest(ctx, name);
- if (*mod) {
+ *mod = lys_get_module_without_revision(ctx, name, &keep_search);
+ if (keep_search) {
/* Let us now search with callback and searchpaths to check
* if there is newer revision outside the context.
*/