schema parser CHANGE simplify module importing

better integrate functionality of selecting module to import (if read
a module from file or use one in context).

Parsing errors of the imported modules were hidden and it wasn't clear
why the main module is not loaded.
diff --git a/src/common.h b/src/common.h
index 9a7a3e2..1998c85 100644
--- a/src/common.h
+++ b/src/common.h
@@ -235,8 +235,17 @@
 
 void ly_vlog_build_path_reverse(enum LY_VLOG_ELEM elem_type, const void *elem, char *path, uint16_t *index);
 
-struct lys_module *ly_ctx_load_sub_module(struct ly_ctx *ctx, struct lys_module *module, const char *name,
-                                          const char *revision, int implement, struct unres_schema *unres);
+/*
+ * - if \p module specified, it searches for submodules, they can be loaded only from a file or via module callback,
+ *   they cannot be get from context
+ * - if \p module is not specified
+ *   - if specific revision is specified, the first try is to get module from the context
+ *   - if no specific revision is specified, it tries to get the newest module - first it searches for the file and
+ *     then checks that the schema loaded from the same source isn't already in context. If the source wasn't
+ *     previously loaded, it is parsed.
+ */
+const struct lys_module *ly_ctx_load_sub_module(struct ly_ctx *ctx, struct lys_module *module, const char *name,
+                                                const char *revision, int implement, struct unres_schema *unres);
 
 /**
  * @brief Basic functionality like strpbrk(3). However, it searches string \p s
diff --git a/src/context.c b/src/context.c
index 2d5fc86..719fd19 100644
--- a/src/context.c
+++ b/src/context.c
@@ -357,18 +357,18 @@
     return ctx->module_clb;
 }
 
-struct lys_module *
+const struct lys_module *
 ly_ctx_load_sub_module(struct ly_ctx *ctx, struct lys_module *module, const char *name, const char *revision,
                        int implement, struct unres_schema *unres)
 {
-    struct lys_module *mod;
+    const struct lys_module *mod;
     char *module_data;
     int i;
     void (*module_data_free)(void *module_data) = NULL;
     LYS_INFORMAT format = LYS_IN_UNKNOWN;
 
-    /* exception for internal modules */
     if (!module) {
+        /* exception for internal modules */
         for (i = 0; i < INTERNAL_MODULES_COUNT; i++) {
             if (ly_strequal(name, internal_modules[i].name, 0)) {
                 if (!revision || ly_strequal(revision, internal_modules[i].revision, 0)) {
@@ -377,6 +377,32 @@
                 }
             }
         }
+        if (revision) {
+            /* try to get the schema with the specific revision from the context */
+            mod = ly_ctx_get_module(ctx, name, revision);
+            if (mod) {
+                /* we get such a module, make it implemented */
+                if (lys_set_implemented(mod)) {
+                    /* the schema cannot be implemented */
+                    mod = NULL;
+                }
+                return mod;
+            }
+        }
+    } else {
+        /* searching for submodule, try if it is already loaded */
+        mod = (struct lys_module *)ly_ctx_get_submodule2(module, name);
+        if (mod) {
+            if (!revision || (mod->rev_size && ly_strequal(mod->rev[0].date, revision, 0))) {
+                /* success */
+                return mod;
+            } else {
+                /* there is already another revision of the submodule */
+                LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, mod->rev[0].date, "revision");
+                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Multiple revisions of a submodule included.");
+                return NULL;
+            }
+        }
     }
 
     if (ctx->module_clb) {
@@ -387,8 +413,15 @@
             module_data = ctx->module_clb(name, revision, NULL, NULL, ctx->module_clb_data, &format, &module_data_free);
         }
         if (!module_data) {
-            LOGERR(0, "User module retrieval callback failed!");
-            return NULL;
+            if (module || revision) {
+                /* we already know that the specified revision is not present in context, and we have no other
+                 * option in case of submodules */
+                LOGERR(LY_ESYS, "User module retrieval callback failed!");
+                return NULL;
+            } else {
+                /* get the newest revision from the context */
+                return ly_ctx_get_module(ctx, name, revision);
+            }
         }
 
         if (module) {
diff --git a/src/parser.c b/src/parser.c
index 89646cf..5e06ce9 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -223,22 +223,6 @@
     struct lys_module *result = NULL;
     int localsearch = 0;
 
-    if (module) {
-        /* searching for submodule, try if it is already loaded */
-        result = (struct lys_module *)ly_ctx_get_submodule2(module, name);
-        if (result) {
-            if (!revision || (result->rev_size && ly_strequal(result->rev[0].date, revision, 0))) {
-                /* success */
-                return result;
-            } else {
-                /* there is already another revision of the submodule */
-                LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, result->rev[0].date, "revision");
-                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Multiple revisions of a submodule included.");
-                return NULL;
-            }
-        }
-    }
-
     len = strlen(name);
     if (ctx->models.search_path) {
         /* try context's search_path first */
@@ -259,7 +243,7 @@
     dir_len = strlen(wd);
     LOGVRB("Searching for \"%s\" in %s.", name, wd);
     if (!dir) {
-        LOGWRN("Unable to open directory \"%s\" for searching referenced modules (%s)",
+        LOGWRN("Unable to open directory \"%s\" for searching referenced modules (%s).",
                wd, strerror(errno));
     } else {
         while ((file = readdir(dir))) {
@@ -342,8 +326,13 @@
     }
 
     if (!match_name) {
-        LOGERR(LY_ESYS, "Data model \"%s\" not found (neither in search path \"%s\" nor in working directory \"%s\")",
-               name, ctx->models.search_path, wd);
+        if (!module) {
+            result = (struct lys_module *)ly_ctx_get_module(ctx, name, revision);
+        }
+        if (!result) {
+            LOGERR(LY_ESYS, "Data model \"%s\" not found.",
+                   name, ctx->models.search_path, wd);
+        }
         goto cleanup;
     }
 
@@ -351,18 +340,20 @@
     /* cut the format for now */
     strrchr(match_name, '.')[1] = '\0';
 
-    /* check that the same file was not already loaded */
-    for (i = 0; i < ctx->models.used; ++i) {
-        if (ctx->models.list[i]->filepath && !strcmp(name, ctx->models.list[i]->name)
-                && !strncmp(match_name, ctx->models.list[i]->filepath, strlen(match_name))) {
-            result = ctx->models.list[i];
-            if (implement && !result->implemented) {
-                /* make it implemented now */
-                if (lys_set_implemented(result)) {
-                    result = NULL;
+    /* check that the same file was not already loaded - it make sense only in case of loading the newest revision */
+    if (!revision) {
+        for (i = 0; i < ctx->models.used; ++i) {
+            if (ctx->models.list[i]->filepath && !strcmp(name, ctx->models.list[i]->name)
+                    && !strncmp(match_name, ctx->models.list[i]->filepath, strlen(match_name))) {
+                result = ctx->models.list[i];
+                if (implement && !result->implemented) {
+                    /* make it implemented now */
+                    if (lys_set_implemented(result)) {
+                        result = NULL;
+                    }
                 }
+                goto cleanup;
             }
-            goto cleanup;
         }
     }
 
@@ -1809,10 +1800,7 @@
 {
     int i;
     struct lys_module *dup = NULL;
-    LY_LOG_LEVEL verb;
 
-    /* store current log level, some magic is happening with it here */
-    verb = ly_log_level;
 
     /* check for importing a single module in multiple revisions */
     for (i = 0; i < module->imp_size; i++) {
@@ -1826,10 +1814,8 @@
                 /* the already imported module has
                  * - no revision, but here we require some
                  * - different revision than the one required here */
-                ly_verb(LY_LLERR);
                 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "import");
                 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Importing multiple revisions of module \"%s\".", value);
-                ly_verb(verb);
                 return -1;
             } else if (!imp->rev[0]) {
                 /* no revision, remember the duplication, but check revisions after loading the module
@@ -1851,44 +1837,15 @@
         return -1;
     }
 
-    /* try to load the module */
-    if (!imp->rev[0]) {
-        /* no revision specified, try to load the newest module from the search locations into the context */
-        ly_verb(LY_LLSILENT);
-        ly_ctx_load_sub_module(module->ctx, NULL, value, imp->rev[0] ? imp->rev : NULL, 0, NULL);
-        ly_verb(verb);
-        if (ly_errno == LY_ESYS) {
-            /* it is ok, that the e.g. input file was not found */
-            ly_errno = LY_SUCCESS;
-        } else if (ly_errno != LY_SUCCESS) {
-            /* but it is not ok if e.g. the input data were found and they are invalid */
-            lyp_check_circmod_pop(module);
-            /* really print this, even if we are recursively in this function */
-            ly_verb(LY_LLERR);
-            LOGERR(ly_errno, ly_errmsg());
-            LOGERR(LY_EVALID, "Importing \"%s\" module into \"%s\" failed.", value, module->name);
-            ly_verb(verb);
-            return -1;
-        }
-
-        /* If the loaded module (if any) is really the newest, it will be loaded on the next line
-         * by ly_ctx_get_module() */
-    }
-    imp->module = (struct lys_module *)ly_ctx_get_module(module->ctx, value, imp->rev[0] ? imp->rev : NULL);
-    if (!imp->module) {
-        /* whether to use a user callback is decided in the function */
-        imp->module = (struct lys_module *)ly_ctx_load_sub_module(module->ctx, NULL, value, imp->rev[0] ? imp->rev : NULL, 0, NULL);
-    }
+    /* load module - in specific situations it tries to get the module from the context */
+    imp->module = (struct lys_module *)ly_ctx_load_sub_module(module->ctx, NULL, value, imp->rev[0] ? imp->rev : NULL, 0, NULL);
 
     /* update the list of currently being parsed modules */
     lyp_check_circmod_pop(module);
 
     /* check the result */
     if (!imp->module) {
-        ly_verb(LY_LLERR);
-        LOGERR(ly_errno, ly_errmsg());
         LOGERR(LY_EVALID, "Importing \"%s\" module into \"%s\" failed.", value, module->name);
-        ly_verb(verb);
         return -1;
     }
 
@@ -1900,10 +1857,8 @@
             /* - modules are not the same
              * - one of modules has no revision (except they both has no revision)
              * - revisions of the modules are not the same */
-            ly_verb(LY_LLERR);
             LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "import");
             LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Importing multiple revisions of module \"%s\".", value);
-            ly_verb(verb);
             return -1;
         }
     }