schema CHANGE refactor lys_module structure
- share some of the data between parsed (lysp_module) and compiled
(lysc_module) structures. It should optimize processing and make usage
more simple
- separate lysp_submodule - so far the submodules were same as parsed
modules (using a bit to differentiate). Since the lys_module structure
was optimized more for use with the data (so more focused on the
compiled schema), the lysp_module is now more interconnected with the
lys_module structure, but this cannot be done in submodules. Therefore,
the lysp_submodule was created sharing most of the members with
lysp_module (to unify parsing process) but adding some other members
which are placed into lys_module in case of lysp_module structure.
- except of the moving some of the members of lysp_module/lysc_module
into lys_module structure, the change does not affect the compiled
structures.
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index b2e1a59..37a65c2 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -107,7 +107,7 @@
if (!mod) {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
"Invalid descendant-schema-nodeid value \"%.*s\" - prefix \"%.*s\" not defined in module \"%s\".",
- id - nodeid, nodeid, prefix_len, prefix, context_node->module->compiled->name);
+ id - nodeid, nodeid, prefix_len, prefix, context_node->module->name);
return LY_ENOTFOUND;
}
} else {
@@ -142,22 +142,20 @@
}
LY_ERR
-lysp_check_prefix(struct ly_parser_ctx *ctx, struct lysp_module *module, const char **value)
+lysp_check_prefix(struct ly_parser_ctx *ctx, struct lysp_import *imports, const char *module_prefix, const char **value)
{
struct lysp_import *i;
- if (module->prefix && &module->prefix != value && !strcmp(module->prefix, *value)) {
+ if (module_prefix && &module_prefix != value && !strcmp(module_prefix, *value)) {
LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE,
"Prefix \"%s\" already used as module prefix.", *value);
return LY_EEXIST;
}
- if (module->imports) {
- LY_ARRAY_FOR(module->imports, struct lysp_import, i) {
- if (i->prefix && &i->prefix != value && !strcmp(i->prefix, *value)) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE,
- "Prefix \"%s\" already used to import \"%s\" module.", *value, i->name);
- return LY_EEXIST;
- }
+ LY_ARRAY_FOR(imports, struct lysp_import, i) {
+ if (i->prefix && &i->prefix != value && !strcmp(i->prefix, *value)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE, "Prefix \"%s\" already used to import \"%s\" module.",
+ *value, i->name);
+ return LY_EEXIST;
}
}
return LY_SUCCESS;
@@ -505,7 +503,7 @@
}
LY_ERR
-lysp_check_typedefs(struct ly_parser_ctx *ctx)
+lysp_check_typedefs(struct ly_parser_ctx *ctx, struct lysp_module *mod)
{
struct hash_table *ids_global;
struct hash_table *ids_scoped;
@@ -516,14 +514,14 @@
/* check name collisions - typedefs and groupings */
ids_global = lyht_new(8, sizeof(char*), lysp_id_cmp, NULL, 1);
ids_scoped = lyht_new(8, sizeof(char*), lysp_id_cmp, NULL, 1);
- LY_ARRAY_FOR(ctx->mod->typedefs, i) {
- if (lysp_check_typedef(ctx, NULL, &ctx->mod->typedefs[i], ids_global, ids_scoped)) {
+ LY_ARRAY_FOR(mod->typedefs, i) {
+ if (lysp_check_typedef(ctx, NULL, &mod->typedefs[i], ids_global, ids_scoped)) {
goto cleanup;
}
}
- LY_ARRAY_FOR(ctx->mod->includes, i) {
- LY_ARRAY_FOR(ctx->mod->includes[i].submodule->typedefs, u) {
- if (lysp_check_typedef(ctx, NULL, &ctx->mod->includes[i].submodule->typedefs[u], ids_global, ids_scoped)) {
+ LY_ARRAY_FOR(mod->includes, i) {
+ LY_ARRAY_FOR(mod->includes[i].submodule->typedefs, u) {
+ if (lysp_check_typedef(ctx, NULL, &mod->includes[i].submodule->typedefs[u], ids_global, ids_scoped)) {
goto cleanup;
}
}
@@ -545,18 +543,6 @@
return ret;
}
-void
-lys_module_implement(struct lys_module *mod)
-{
- assert(mod);
- if (mod->parsed) {
- mod->parsed->implemented = 1;
- }
- if (mod->compiled) {
- mod->compiled->implemented = 1;
- }
-}
-
struct lysp_load_module_check_data {
const char *name;
const char *revision;
@@ -565,44 +551,43 @@
};
static LY_ERR
-lysp_load_module_check(struct ly_ctx *ctx, struct lysp_module *mod, void *data)
+lysp_load_module_check(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data)
{
struct lysp_load_module_check_data *info = data;
- const char *filename, *dot, *rev;
+ const char *filename, *dot, *rev, *name;
size_t len;
+ struct lysp_revision *revs;
+
+ name = mod ? mod->mod->name : submod->name;
+ revs = mod ? mod->revs : submod->revs;
if (info->name) {
/* check name of the parsed model */
- if (strcmp(info->name, mod->name)) {
- LOGERR(ctx, LY_EINVAL, "Unexpected module \"%s\" parsed instead of \"%s\").", mod->name, info->name);
+ if (strcmp(info->name, name)) {
+ LOGERR(ctx, LY_EINVAL, "Unexpected module \"%s\" parsed instead of \"%s\").", name, info->name);
return LY_EINVAL;
}
}
if (info->revision) {
/* check revision of the parsed model */
- if (!mod->revs || strcmp(info->revision, mod->revs[0].date)) {
- LOGERR(ctx, LY_EINVAL, "Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").", mod->name,
- mod->revs[0].date, info->revision);
+ if (!revs || strcmp(info->revision, revs[0].date)) {
+ LOGERR(ctx, LY_EINVAL, "Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").", name,
+ revs[0].date, info->revision);
return LY_EINVAL;
}
}
- if (info->submoduleof) {
- /* check that we have really a submodule */
- if (!mod->submodule) {
- /* submodule is not a submodule */
- LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Included \"%s\" schema from \"%s\" is actually not a submodule.",
- mod->name, info->submoduleof);
- return LY_EVALID;
- }
+ if (submod) {
+ assert(info->submoduleof);
+
/* check that the submodule belongs-to our module */
- if (strcmp(info->submoduleof, mod->belongsto)) {
+ if (strcmp(info->submoduleof, submod->belongsto)) {
LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Included \"%s\" submodule from \"%s\" belongs-to a different module \"%s\".",
- mod->name, info->submoduleof, mod->belongsto);
+ submod->name, info->submoduleof, submod->belongsto);
return LY_EVALID;
}
/* check circular dependency */
- if (mod->parsing) {
- LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "A circular dependency (include) for module \"%s\".", mod->name);
+ if (submod->parsing) {
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "A circular dependency (include) for module \"%s\".", submod->name);
return LY_EVALID;
}
}
@@ -615,19 +600,19 @@
filename++;
}
/* name */
- len = strlen(mod->name);
+ len = strlen(name);
rev = strchr(filename, '@');
dot = strrchr(info->path, '.');
- if (strncmp(filename, mod->name, len) ||
+ if (strncmp(filename, name, len) ||
((rev && rev != &filename[len]) || (!rev && dot != &filename[len]))) {
- LOGWRN(ctx, "File name \"%s\" does not match module name \"%s\".", filename, mod->name);
+ LOGWRN(ctx, "File name \"%s\" does not match module name \"%s\".", filename, name);
}
/* revision */
if (rev) {
len = dot - ++rev;
- if (!mod->revs || len != 10 || strncmp(mod->revs[0].date, rev, len)) {
+ if (!revs || len != 10 || strncmp(revs[0].date, rev, len)) {
LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", filename,
- mod->revs ? mod->revs[0].date : "none");
+ revs ? revs[0].date : "none");
}
}
}
@@ -636,14 +621,16 @@
LY_ERR
lys_module_localfile(struct ly_ctx *ctx, const char *name, const char *revision, int implement, struct ly_parser_ctx *main_ctx,
- struct lys_module **result)
+ void **result)
{
int fd;
char *filepath = NULL;
+ const char **fp;
LYS_INFORMAT format;
- struct lys_module *mod = NULL;
+ void *mod = NULL;
LY_ERR ret = LY_SUCCESS;
struct lysp_load_module_check_data check_data = {0};
+ char rpath[PATH_MAX];
LY_CHECK_RET(lys_search_localfile(ly_ctx_get_searchdirs(ctx), !(ctx->flags & LY_CTX_DISABLE_SEARCHDIR_CWD), name, revision,
&filepath, &format));
@@ -666,12 +653,16 @@
close(fd);
LY_CHECK_ERR_GOTO(!mod, ly_errcode(ctx), cleanup);
- if (!mod->parsed->filepath) {
- char rpath[PATH_MAX];
+ if (main_ctx) {
+ fp = &((struct lysp_submodule*)mod)->filepath;
+ } else {
+ fp = &((struct lys_module*)mod)->filepath;
+ }
+ if (!(*fp)) {
if (realpath(filepath, rpath) != NULL) {
- mod->parsed->filepath = lydict_insert(ctx, rpath, 0);
+ (*fp) = lydict_insert(ctx, rpath, 0);
} else {
- mod->parsed->filepath = lydict_insert(ctx, filepath, 0);
+ (*fp) = lydict_insert(ctx, filepath, 0);
}
}
@@ -716,8 +707,8 @@
&format, &module_data, &module_data_free) == LY_SUCCESS) {
check_data.name = name;
check_data.revision = revision;
- *mod = lys_parse_mem_(ctx, module_data, format, implement, NULL,
- lysp_load_module_check, &check_data);
+ *mod = lys_parse_mem_module(ctx, module_data, format, implement,
+ lysp_load_module_check, &check_data);
if (module_data_free) {
module_data_free((void*)module_data, ctx->imp_clb_data);
}
@@ -730,17 +721,17 @@
search_file:
if (!(ctx->flags & LY_CTX_DISABLE_SEARCHDIRS)) {
/* module was not received from the callback or there is no callback set */
- lys_module_localfile(ctx, name, revision, implement, NULL, mod);
+ lys_module_localfile(ctx, name, revision, implement, NULL, (void **)mod);
}
if (!(*mod) && (ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
goto search_clb;
}
}
- if ((*mod) && !revision && ((*mod)->parsed->latest_revision == 1)) {
+ if ((*mod) && !revision && ((*mod)->latest_revision == 1)) {
/* update the latest_revision flag - here we have selected the latest available schema,
* consider that even the callback provides correct latest revision */
- (*mod)->parsed->latest_revision = 2;
+ (*mod)->latest_revision = 2;
}
} else {
/* we have module from the current context */
@@ -766,7 +757,7 @@
if (implement) {
/* mark the module implemented, check for collision was already done */
- lys_module_implement(*mod);
+ (*mod)->implemented = 1;
}
return LY_SUCCESS;
@@ -775,7 +766,7 @@
LY_ERR
lysp_load_submodule(struct ly_parser_ctx *ctx, struct lysp_module *mod, struct lysp_include *inc)
{
- struct lys_module *submod;
+ struct lysp_submodule *submod;
const char *submodule_data = NULL;
LYS_INFORMAT format = LYS_IN_UNKNOWN;
void (*submodule_data_free)(void *module_data, void *user_data) = NULL;
@@ -785,13 +776,13 @@
if (!(ctx->ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
search_clb:
if (ctx->ctx->imp_clb) {
- if (ctx->ctx->imp_clb(mod->name, NULL, inc->name, inc->rev[0] ? inc->rev : NULL, ctx->ctx->imp_clb_data,
+ if (ctx->ctx->imp_clb(mod->mod->name, NULL, inc->name, inc->rev[0] ? inc->rev : NULL, ctx->ctx->imp_clb_data,
&format, &submodule_data, &submodule_data_free) == LY_SUCCESS) {
check_data.name = inc->name;
check_data.revision = inc->rev[0] ? inc->rev : NULL;
- check_data.submoduleof = mod->name;
- submod = lys_parse_mem_(ctx->ctx, submodule_data, format, mod->implemented, ctx,
- lysp_load_module_check, &check_data);
+ check_data.submoduleof = mod->mod->name;
+ submod = lys_parse_mem_submodule(ctx->ctx, submodule_data, format, ctx,
+ lysp_load_module_check, &check_data);
if (submodule_data_free) {
submodule_data_free((void*)submodule_data, ctx->ctx->imp_clb_data);
}
@@ -803,25 +794,25 @@
} else {
search_file:
if (!(ctx->ctx->flags & LY_CTX_DISABLE_SEARCHDIRS)) {
- /* module was not received from the callback or there is no callback set */
- lys_module_localfile(ctx->ctx, inc->name, inc->rev[0] ? inc->rev : NULL, mod->implemented, ctx, &submod);
+ /* submodule was not received from the callback or there is no callback set */
+ lys_module_localfile(ctx->ctx, inc->name, inc->rev[0] ? inc->rev : NULL, 0, ctx, (void**)&submod);
}
if (!submod && (ctx->ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
goto search_clb;
}
}
if (submod) {
- if (!inc->rev[0] && (submod->parsed->latest_revision == 1)) {
+ if (!inc->rev[0] && (submod->latest_revision == 1)) {
/* update the latest_revision flag - here we have selected the latest available schema,
* consider that even the callback provides correct latest revision */
- submod->parsed->latest_revision = 2;
+ submod->latest_revision = 2;
}
- inc->submodule = submod->parsed;
- free(submod);
+ inc->submodule = submod;
}
if (!inc->submodule) {
- LOGVAL(ctx->ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Including \"%s\" submodule into \"%s\" failed.", inc->name, mod->name);
+ LOGVAL(ctx->ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Including \"%s\" submodule into \"%s\" failed.",
+ inc->name, mod->mod->name);
return LY_EVALID;
}
@@ -830,9 +821,9 @@
#define FIND_MODULE(TYPE, MOD) \
TYPE *imp; \
- if (!strncmp((MOD)->prefix, prefix, len) && (MOD)->prefix[len] == '\0') { \
+ if (!strncmp((MOD)->mod->prefix, prefix, len) && (MOD)->mod->prefix[len] == '\0') { \
/* it is the prefix of the module itself */ \
- m = ly_ctx_get_module((MOD)->ctx, (MOD)->name, ((struct lysc_module*)(MOD))->revision); \
+ m = ly_ctx_get_module((MOD)->mod->ctx, (MOD)->mod->name, ((struct lysc_module*)(MOD))->revision); \
} \
/* search in imports */ \
if (!m) { \