schema tree BUGFIX using of module's latest_revision flag
update it when the module is being inserted into context and use
it when searching for the latest revision of a module in the context.
diff --git a/src/context.c b/src/context.c
index 4e1b0bc..5dcc621 100644
--- a/src/context.c
+++ b/src/context.c
@@ -354,42 +354,16 @@
static const struct lys_module *
ly_ctx_get_module_latest_by(const struct ly_ctx *ctx, const char *key, size_t key_offset)
{
- const struct lys_module *mod, *newest = NULL;
+ const struct lys_module *mod;
unsigned int index = 0;
- const char *date, *date_newest = NULL;
while ((mod = ly_ctx_get_module_by_iter(ctx, key, key_offset, &index))) {
- if (!newest) {
- newest = mod;
- } else {
- if ((newest->compiled && !newest->compiled->revs) || (!newest->compiled && !newest->parsed->revs)) {
- /* prefer modules with revisions, module with no revision
- * is supposed to be the oldest one */
- newest = mod;
- date_newest = NULL;
- } else if ((mod->compiled && mod->compiled->revs) || (!mod->compiled && mod->parsed->revs)) {
- if (!date_newest) {
- if (newest->compiled) {
- date_newest = newest->compiled->revs[0].date;
- } else {
- date_newest = newest->parsed->revs[0].date;
- }
- }
- if (mod->compiled) {
- date = mod->compiled->revs[0].date;
- } else {
- date = mod->parsed->revs[0].date;
- }
- if (strcmp(date, date_newest) > 0) {
- /* the current module is newer than so far newest, so remember it */
- newest = mod;
- date_newest = NULL;
- }
- }
+ if ((mod->compiled && mod->compiled->latest_revision) || (!mod->compiled && mod->parsed->latest_revision)) {
+ return mod;
}
}
- return newest;
+ return NULL;
}
API const struct lys_module *
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 7ea75c6..ffdcdc8 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -4665,9 +4665,6 @@
}
assert(!buf);
- /* make sure that the newest revision is at position 0 */
- lysp_sort_revisions(mod->revs);
-
*mod_p = mod;
return ret;
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 60bd9b9..29e418e 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -1076,10 +1076,21 @@
return ret;
}
+static void
+lys_latest_unset(struct lys_module *mod)
+{
+ if (mod->parsed) {
+ mod->parsed->latest_revision = 0;
+ }
+ if (mod->compiled) {
+ mod->compiled->latest_revision = 0;
+ }
+}
+
static const struct lys_module *
lys_parse_mem_(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, const char *revision, int implement)
{
- struct lys_module *mod = NULL;
+ struct lys_module *mod = NULL, *latest;
LY_ERR ret;
LY_CHECK_ARG_RET(ctx, ctx, data, NULL);
@@ -1095,14 +1106,18 @@
break;
case LYS_IN_YANG:
ret = yang_parse(ctx, data, &mod->parsed);
- LY_CHECK_RET(ret, NULL);
break;
default:
LOGERR(ctx, LY_EINVAL, "Invalid schema input format.");
break;
}
+ LY_CHECK_RET(ret, NULL);
+
+ /* make sure that the newest revision is at position 0 */
+ lysp_sort_revisions(mod->parsed->revs);
if (implement) {
+ /* mark the loaded module implemented */
if (ly_ctx_get_module_implemented(ctx, mod->parsed->name)) {
LOGERR(ctx, LY_EDENIED, "Module \"%s\" is already implemented in the context.", mod->parsed->name);
lys_module_free(mod, NULL);
@@ -1134,6 +1149,25 @@
return NULL;
}
+ /* decide the latest revision */
+ latest = (struct lys_module*)ly_ctx_get_module_latest(ctx, mod->parsed->name);
+ if (latest) {
+ if (mod->parsed->revs) {
+ if ((latest->parsed && !latest->parsed->revs) || (!latest->parsed && !latest->compiled->revs)) {
+ /* latest has no revision, so mod is anyway newer */
+ mod->parsed->latest_revision = 1;
+ lys_latest_unset(latest);
+ } else {
+ if (strcmp(mod->parsed->revs[0].date, latest->parsed ? latest->parsed->revs[0].date : latest->compiled->revs[0].date) > 0) {
+ mod->parsed->latest_revision = 1;
+ lys_latest_unset(latest);
+ }
+ }
+ }
+ } else {
+ mod->parsed->latest_revision = 1;
+ }
+
/* add into context */
ly_set_add(&ctx->list, mod, LY_SET_OPT_USEASLIST);