schema tree CHANGE redesign revision in compiled schema
diff --git a/src/context.c b/src/context.c
index f151a74..f8e2918 100644
--- a/src/context.c
+++ b/src/context.c
@@ -337,12 +337,12 @@
while ((mod = ly_ctx_get_module_by_iter(ctx, key, key_offset, &index))) {
if (!revision) {
- if ((mod->compiled && !mod->compiled->revs) || (!mod->compiled && !mod->parsed->revs)) {
+ if ((mod->compiled && !mod->compiled->revision) || (!mod->compiled && !mod->parsed->revs)) {
/* found requested module without revision */
return mod;
}
} else {
- if ((mod->compiled && mod->compiled->revs && !strcmp(mod->compiled->revs[0].date, revision)) ||
+ if ((mod->compiled && mod->compiled->revision && !strcmp(mod->compiled->revision, revision)) ||
(!mod->compiled && mod->parsed->revs && !strcmp(mod->parsed->revs[0].date, revision))) {
/* found requested module of the specific revision */
return mod;
diff --git a/src/tree_schema.c b/src/tree_schema.c
index cd55950..9db0f77 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -99,6 +99,7 @@
if (include->submodule && !(--include->submodule->refcount)) {
lysp_module_free(include->submodule);
}
+ dict = 1; /* includes not present in compiled tree, so the data are not reused there in anyway */
FREE_STRING(ctx, include->name, dict);
FREE_STRING(ctx, include->dsc, dict);
FREE_STRING(ctx, include->ref, dict);
@@ -514,6 +515,7 @@
FREE_STRING(ctx, module->name, dict);
FREE_STRING(ctx, module->ns, dict);
FREE_STRING(ctx, module->prefix, dict);
+ FREE_STRING(ctx, module->revision, 1);
FREE_ARRAY(ctx, module->imports, lysc_import_free);
FREE_ARRAY(ctx, module->features, lysc_feature_free);
@@ -1074,7 +1076,7 @@
lys_compile_import(struct lysc_ctx *ctx, struct lysp_import *imp_p, int options, struct lysc_import *imp)
{
unsigned int u;
- struct lys_module *mod;
+ struct lys_module *mod = NULL;
struct lysc_module *comp;
LY_ERR ret = LY_SUCCESS;
@@ -1103,14 +1105,14 @@
}
}
if (!mod) {
- if (lysp_load_module(ctx->mod->ctx, comp->name, comp->revs ? comp->revs[0].date : NULL, 0, 1, &mod)) {
+ if (lysp_load_module(ctx->mod->ctx, comp->name, comp->revision, 0, 1, &mod)) {
LOGERR(ctx->mod->ctx, LY_ENOTFOUND, "Unable to reload \"%s\" module to import it into \"%s\", source data not found.",
comp->name, ctx->mod->name);
return LY_ENOTFOUND;
}
}
} else if (!imp->module->compiled) {
- return lys_compile(imp->module->parsed, options, &imp->module->compiled);
+ return lys_compile(imp->module, options);
}
done:
@@ -1217,21 +1219,23 @@
}
LY_ERR
-lys_compile(struct lysp_module *sp, int options, struct lysc_module **sc)
+lys_compile(const struct lys_module *mod, int options)
{
struct lysc_ctx ctx = {0};
struct lysc_module *mod_c;
+ struct lysp_module *sp;
unsigned int u;
LY_ERR ret;
- LY_CHECK_ARG_RET(NULL, sc, sp, sp->ctx, LY_EINVAL);
+ LY_CHECK_ARG_RET(NULL, mod, mod->parsed, mod->parsed->ctx, LY_EINVAL);
+ sp = mod->parsed;
if (sp->submodule) {
LOGERR(sp->ctx, LY_EINVAL, "Submodules (%s) are not supposed to be compiled, compile only the main modules.", sp->name);
return LY_EINVAL;
}
- ctx.mod = *sc = mod_c = calloc(1, sizeof *mod_c);
+ ctx.mod = ((struct lys_module*)mod)->compiled = mod_c = calloc(1, sizeof *mod_c);
LY_CHECK_ERR_RET(!mod_c, LOGMEM(sp->ctx), LY_EMEM);
mod_c->ctx = sp->ctx;
mod_c->version = sp->version;
@@ -1247,7 +1251,9 @@
mod_c->ns = lydict_insert(sp->ctx, sp->ns, 0);
mod_c->prefix = lydict_insert(sp->ctx, sp->prefix, 0);
}
-
+ if (sp->revs) {
+ mod_c->revision = lydict_insert(sp->ctx, sp->revs[0].date, 10);
+ }
COMPILE_ARRAY_GOTO(&ctx, sp->imports, mod_c->imports, options, u, lys_compile_import, ret, error);
COMPILE_ARRAY_GOTO(&ctx, sp->features, mod_c->features, options, u, lys_compile_feature, ret, error);
COMPILE_ARRAY_GOTO(&ctx, sp->identities, mod_c->identities, options, u, lys_compile_identity, ret, error);
@@ -1258,14 +1264,16 @@
COMPILE_ARRAY_GOTO(&ctx, sp->exts, mod_c->exts, options, u, lys_compile_ext, ret, error);
if (options & LYSC_OPT_FREE_SP) {
- lysp_module_free_(sp, 0);
+ lysp_module_free_(mod->parsed, 0);
+ ((struct lys_module*)mod)->parsed = NULL;
}
+ ((struct lys_module*)mod)->compiled = mod_c;
return LY_SUCCESS;
error:
lysc_module_free_(mod_c, (options & LYSC_OPT_FREE_SP) ? 0 : 1);
-
+ ((struct lys_module*)mod)->compiled = NULL;
return ret;
}
@@ -1396,11 +1404,11 @@
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)) {
+ if ((latest->parsed && !latest->parsed->revs) || (!latest->parsed && !latest->compiled->revision)) {
/* latest has no revision, so mod is anyway newer */
lys_latest_switch(latest, mod->parsed);
} else {
- if (strcmp(mod->parsed->revs[0].date, latest->parsed ? latest->parsed->revs[0].date : latest->compiled->revs[0].date) > 0) {
+ if (strcmp(mod->parsed->revs[0].date, latest->parsed ? latest->parsed->revs[0].date : latest->compiled->revision) > 0) {
lys_latest_switch(latest, mod->parsed);
}
}
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 4e07c7d..bb42de5 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -859,8 +859,7 @@
const char *filepath; /**< path, if the schema was read from a file, NULL in case of reading from memory */
const char *ns; /**< namespace of the module (mandatory) */
const char *prefix; /**< module prefix (mandatory) */
- struct lysc_revision *revs; /**< list of the module revisions ([sized array](@ref sizedarrays)), the first revision
- in the list is always the last (newest) revision of the module */
+ const char *revision; /**< the revision of the module */
struct lysc_import *imports; /**< list of imported modules ([sized array](@ref sizedarrays)) */
struct lysc_feature *features; /**< list of feature definitions ([sized array](@ref sizedarrays)) */
@@ -1005,12 +1004,12 @@
/**
* @brief Compile printable schema into a validated schema linking all the references.
*
- * @param[in] sp Simple parsed printable schema to compile. Can be changed according to the provided options.
+ * @param[in, out] mod Schema structure holding pointers to both schema structure types. The ::lys_module#parsed
+ * member is used as input and ::lys_module#compiled is used to hold the result of the compilation.
* @param[in] options Various options to modify compiler behavior, see [compile flags](@ref scflags).
- * @param[out] sc Resulting compiled schema structure.
* @return LY_ERR value.
*/
-LY_ERR lys_compile(struct lysp_module *sp, int options, struct lysc_module **sc);
+LY_ERR lys_compile(const struct lys_module *mod, int options);
/** @} */
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 88b90cd..c48643f 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -176,7 +176,7 @@
}
/* circular check */
- if ((*mod)->parsed->parsing) {
+ if ((*mod)->parsed && (*mod)->parsed->parsing) {
LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "A circular dependency (import) for module \"%s\".", name);
*mod = NULL;
return LY_EVALID;
@@ -284,7 +284,7 @@
TYPE *imp; \
if (!strncmp((MOD)->prefix, prefix, len) && (MOD)->prefix[len] == '\0') { \
/* it is the prefix of the module itself */ \
- return (struct lys_module*)ly_ctx_get_module((MOD)->ctx, (MOD)->name, (MOD)->revs ? (MOD)->revs[0].date : NULL); \
+ return (struct lys_module*)ly_ctx_get_module((MOD)->ctx, (MOD)->name, ((struct lysc_module*)(MOD))->revision); \
} \
/* search in imports */ \
LY_ARRAY_FOR((MOD)->imports, TYPE, imp) { \