schema parser CHANGE importing/including the modules

Redesign storing the imported/included schemas in the schema tree
structure and propagating them to the main module from submodules.
The code should be more readable without code duplication and a little
bit faster. The changes include corrected detection of
importing/including a schema in multiple revisions.
diff --git a/src/parser.c b/src/parser.c
index e8f2873..15bb90f 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1580,19 +1580,20 @@
     char *module_data;
     void (*module_data_free)(void *module_data) = NULL;
     LYS_INFORMAT format = LYS_IN_UNKNOWN;
-    int count, i, j;
+    int i, j;
 
     /* check that the submodule was not included yet (previous submodule could have included it) */
-    for (i = 0; i < module->inc_size && module->inc[i].submodule; ++i) {
+    for (i = 0; i < module->inc_size; ++i) {
+        if (!module->inc[i].submodule) {
+            /* skip the not yet filled records */
+            continue;
+        }
         if (ly_strequal(module->inc[i].submodule->name, value, 1)) {
             /* check revisions, including multiple revisions of a single module is error */
-            if (inc->rev[0] && !module->inc[i].submodule->rev_size) {
-                /* the already included submodule has no revision, but here we require some */
-                LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "include");
-                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Including multiple revisions of submodule \"%s\".", value);
-                return -1;
-            } else if (inc->rev[0] && module->inc[i].submodule->rev_size &&
-                    strcmp(module->inc[i].submodule->rev[0].date, inc->rev)) {
+            if (inc->rev[0] && (!module->inc[i].submodule->rev_size || strcmp(module->inc[i].submodule->rev[0].date, inc->rev))) {
+                /* the already included submodule has
+                 * - no revision, but here we require some
+                 * - different revision than the one required here */
                 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "include");
                 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Including multiple revisions of submodule \"%s\".", value);
                 return -1;
@@ -1613,13 +1614,6 @@
             if (!submodule) {
                 /* the included submodule is no longer external */
                 module->inc[i].external = 0;
-                /* the expected array will be shorter due to duplicity */
-                module->inc_size--;
-                module->inc = ly_realloc(module->inc, module->inc_size * sizeof *module->inc);
-                if (!module->inc) {
-                    LOGMEM;
-                    return -1;
-                }
             }
             return 1;
         }
@@ -1678,75 +1672,120 @@
     return EXIT_FAILURE;
 }
 
+/* returns:
+ *  0 - imp successfully filled
+ * -1 - error, imp not cleaned
+ */
 int
 lyp_check_import(struct lys_module *module, const char *value, struct lys_import *imp)
 {
-    int count;
+    int i;
+    struct lys_module *dup = NULL;
+    LY_LOG_LEVEL verb;
 
-    /* check for circular import, store it if passed */
-    if (!module->ctx->models.parsing) {
-        count = 0;
-    } else {
-        for (count = 0; module->ctx->models.parsing[count]; ++count) {
-            if (ly_strequal(value, module->ctx->models.parsing[count], 1)) {
-                LOGERR(LY_EVALID, "Circular import dependency on the module \"%s\".", value);
-                goto error;
+    /* check for importing a single module in multiple revisions */
+    for (i = 0; i < module->imp_size; i++) {
+        if (!module->imp[i].module) {
+            /* skip the not yet filled records */
+            continue;
+        }
+        if (ly_strequal(module->imp[i].module->name, value, 1)) {
+            /* check revisions, including multiple revisions of a single module is error */
+            if (imp->rev[0] && (!module->imp[i].module->rev_size || strcmp(module->imp[i].module->rev[0].date, imp->rev))) {
+                /* the already imported module has
+                 * - no revision, but here we require some
+                 * - different revision than the one required here */
+                LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "import");
+                LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Importing multiple revisions of module \"%s\".", value);
+                return -1;
+            } else if (!imp->rev[0]) {
+                /* no revision, remember the duplication, but check revisions after loading the module
+                 * because the current revision can be the same (then it is ok) or it can differ (then it
+                 * is error */
+                dup = module->imp[i].module;
+                break;
             }
+
+            /* there is duplication, but since prefixes differs (checked in caller of this function),
+             * it is ok */
+            imp->module = module->imp[i].module;
+            return 0;
         }
     }
-    ++count;
-    module->ctx->models.parsing =
-        ly_realloc(module->ctx->models.parsing, (count + 1) * sizeof *module->ctx->models.parsing);
-    if (!module->ctx->models.parsing) {
-        LOGMEM;
-        goto error;
+
+    /* circular import check */
+    if (lyp_check_circmod(module, value, 1)) {
+        return -1;
     }
-    module->ctx->models.parsing[count - 1] = value;
-    module->ctx->models.parsing[count] = NULL;
 
     /* 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 */
+        verb = ly_log_level;
+        ly_verb(LY_LLSILENT);
+        (struct lys_module *)ly_ctx_load_module(module->ctx, value, imp->rev[0] ? imp->rev : 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);
+            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_module(module->ctx, value, imp->rev[0] ? imp->rev : NULL);
     }
 
-    /* remove the new module name now that its parsing is finished (even if failed) */
-    if (module->ctx->models.parsing[count] || !ly_strequal(module->ctx->models.parsing[count - 1], value, 1)) {
-        LOGINT;
-    }
-    --count;
-    if (count) {
-        module->ctx->models.parsing[count] = NULL;
-    } else {
-        free(module->ctx->models.parsing);
-        module->ctx->models.parsing = NULL;
-    }
+    /* update the list of currently being parsed modules */
+    lyp_check_circmod_pop(module);
 
     /* check the result */
     if (!imp->module) {
         LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "import");
         LOGERR(LY_EVALID, "Importing \"%s\" module into \"%s\" failed.", value, module->name);
-        goto error;
+        return -1;
     }
 
-    return EXIT_SUCCESS;
+    if (dup) {
+        /* check the revisions */
+        if ((dup != imp->module) ||
+                (dup->rev_size != imp->module->rev_size && (!dup->rev_size || imp->module->rev_size)) ||
+                (dup->rev_size && strcmp(dup->rev[0].date, imp->module->rev[0].date))) {
+            /* - 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 */
+            LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "import");
+            LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Importing multiple revisions of module \"%s\".", value);
+            return -1;
+        }
+    }
 
-error:
-
-    return EXIT_FAILURE;
+    return 0;
 }
 
 /* Propagate imports and includes into the main module */
 int
 lyp_propagate_submodule(struct lys_module *module, struct lys_submodule *submodule)
 {
-    int i, j, r;
+    uint8_t i, j;
+    size_t size;
     struct lys_include *aux_inc;
     struct lys_import *aux_imp;
+    struct lys_import *impiter;
+    struct lys_include *inciter;
+    struct ly_set *set;
+
+    set = ly_set_new();
 
     /* propagate imports into the main module */
-    for (i = r = 0; i < submodule->imp_size; i++) {
+    for (i = 0; i < submodule->imp_size; i++) {
         for (j = 0; j < module->imp_size; j++) {
             if (submodule->imp[i].module == module->imp[j].module &&
                     !strcmp(submodule->imp[i].rev, module->imp[j].rev)) {
@@ -1761,40 +1800,46 @@
         }
         if (j == module->imp_size) {
             /* new import */
-            r++;
+            ly_set_add(set, &submodule->imp[i], LY_SET_OPT_USEASLIST);
         }
     }
-    if (r) {
-        aux_imp = realloc(module->imp, (module->imp_size + r) * sizeof *module->imp);
+    if (set->number) {
+        if (!(void*)module->imp) {
+            /* no import array in main module */
+            i = 0;
+        } else {
+            /* get array size by searching for stop block */
+            for (i = 0; (void*)module->imp[i].module != (void*)0x1; i++);
+        }
+        size = (i + set->number) * sizeof *module->imp;
+        aux_imp = realloc(module->imp, size + sizeof(void*));
         if (!aux_imp) {
             LOGMEM;
             goto error;
         }
         module->imp = aux_imp;
-        for (i = r = 0; i < submodule->imp_size; i++) {
-            for (j = 0; j < module->imp_size; j++) {
-                if (submodule->imp[i].module == module->imp[j].module) {
-                    break;
-                }
+        memset(&module->imp[module->imp_size + set->number], 0, (i - module->imp_size) * sizeof *module->imp);
+        module->imp[i + set->number].module = (void*)0x1; /* set stop block */
+
+        for (i = 0; i < set->number; i++) {
+            impiter = (struct lys_import *)set->set.g[i];
+
+            /* check prefix uniqueness */
+            if (dup_prefix_check(impiter->prefix, module)) {
+                LOGVAL(LYE_DUPID, LY_VLOG_NONE, NULL, "prefix", impiter->prefix);
+                goto error;
             }
-            if (j == module->imp_size) {
-                /* new import */
-                /* check prefix uniqueness */
-                if (dup_prefix_check(submodule->imp[i].prefix, module)) {
-                    LOGVAL(LYE_DUPID, LY_VLOG_NONE, NULL, "prefix", submodule->imp[i].prefix);
-                    goto error;
-                }
-                memcpy(&module->imp[module->imp_size + r], &submodule->imp[i], sizeof *submodule->imp);
-                module->imp[module->imp_size + r].prefix = lydict_insert(module->ctx, module->imp[module->imp_size + r].prefix, 0);
-                module->imp[module->imp_size + r].external = 1;
-                r++;
-            }
+
+            memcpy(&module->imp[module->imp_size], impiter, sizeof *module->imp);
+            module->imp[module->imp_size].prefix = lydict_insert(module->ctx, impiter->prefix, 0);
+            module->imp[module->imp_size].external = 1;
+            module->imp_size++;
         }
-        module->imp_size += r;
+        ly_set_clean(set);
     }
 
     /* propagate includes into the main module */
-    for (i = r = 0; i < submodule->inc_size; i++) {
+    for (i = 0; i < submodule->inc_size; i++) {
         for (j = 0; j < module->inc_size; j++) {
             if (submodule->inc[i].submodule == module->inc[j].submodule) {
                 break;
@@ -1802,35 +1847,36 @@
         }
         if (j == module->inc_size) {
             /* new include */
-            r++;
+            ly_set_add(set, &submodule->inc[i], LY_SET_OPT_USEASLIST);
         }
     }
 
-    if (r) {
-        aux_inc = realloc(module->inc, (module->inc_size + r) * sizeof *module->inc);
+    if (set->number) {
+        for (i = 0; (void*)module->inc[i].submodule != (void*)0x1; i++); /* get array size by searching for stop block */
+        size = (i + set->number) * sizeof *module->inc;
+        aux_inc = realloc(module->inc, size + sizeof(void*));
         if (!aux_inc) {
             LOGMEM;
             goto error;
         }
         module->inc = aux_inc;
-        for (i = r = 0; i < submodule->inc_size; i++) {
-            for (j = 0; j < module->inc_size; j++) {
-                if (submodule->inc[i].submodule == module->inc[j].submodule) {
-                    break;
-                }
-            }
-            if (j == module->inc_size) {
-                /* new include */
-                memcpy(&module->inc[module->inc_size + r], &submodule->inc[i], sizeof *submodule->inc);
-                module->inc[module->inc_size + r].external = 1;
-                r++;
-            }
+        memset(&module->inc[module->inc_size + set->number], 0, (i - module->inc_size) * sizeof *module->inc);
+        module->inc[i + set->number].submodule = (void*)0x1; /* set stop block */
+
+        for (i = 0; i < set->number; i++) {
+            inciter = (struct lys_include *)set->set.g[i];
+
+            memcpy(&module->inc[module->inc_size], inciter, sizeof *module->inc);
+            module->inc[module->inc_size].external = 1;
+            module->inc_size++;
         }
-        module->inc_size += r;
     }
+
+    ly_set_free(set);
     return EXIT_SUCCESS;
 
 error:
+    ly_set_free(set);
     return EXIT_FAILURE;
 }
 
diff --git a/src/parser_yang.c b/src/parser_yang.c
index d0501fc..27429a1 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -89,30 +89,17 @@
 yang_fill_import(struct lys_module *module, struct lys_import *imp, char *value)
 {
     const char *exp;
-    int rc, i;
+    int rc;
 
     exp = lydict_insert_zc(module->ctx, value);
     rc = lyp_check_import(module, exp, imp);
     lydict_remove(module->ctx, exp);
+    module->imp_size++;
     if (rc) {
-        goto error;
+        return EXIT_FAILURE;
     }
 
-    /* check duplicities in imported modules */
-    for (i = 0; i < module->imp_size; i++) {
-        if (!strcmp(module->imp[i].module->name, module->imp[module->imp_size].module->name) &&
-                module->imp[i].module != module->imp[module->imp_size].module) {
-            LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, module->imp[i].module->name, "import");
-            LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Importing multiple revisions of module \"%s\".", module->imp[i].module->name);
-            goto error;
-        }
-    }
-    module->imp_size++;
     return EXIT_SUCCESS;
-
-error:
-    module->imp_size++;
-    return EXIT_FAILURE;
 }
 
 int
@@ -1969,7 +1956,7 @@
 
 int
 yang_fill_include(struct lys_module *module, struct lys_submodule *submodule, char *value,
-                  char *rev, int inc_size, struct unres_schema *unres)
+                  char *rev, struct unres_schema *unres)
 {
     struct lys_include inc;
     struct lys_module *trg;
@@ -1985,7 +1972,8 @@
     rc = lyp_check_include(module, submodule, str, &inc, unres);
     if (!rc) {
         /* success, copy the filled data into the final array */
-        memcpy(&trg->inc[inc_size], &inc, sizeof inc);
+        memcpy(&trg->inc[trg->inc_size], &inc, sizeof inc);
+        trg->inc_size++;
     } else if (rc == -1) {
         ret = EXIT_FAILURE;
     }
@@ -2208,6 +2196,9 @@
             goto error;
         }
         for (i = 0; i < module->inc_size; ++i) {
+            if (!module->inc[i].submodule) {
+                continue;
+            }
             if (lys_sub_module_set_dev_aug_target_implement((struct lys_module *)module->inc[i].submodule)) {
                 goto error;
             }
diff --git a/src/parser_yang.h b/src/parser_yang.h
index b2ef722..0d25628 100644
--- a/src/parser_yang.h
+++ b/src/parser_yang.h
@@ -233,7 +233,7 @@
 int yang_check_deviation(struct lys_module *module, struct type_deviation *dev, struct unres_schema *unres);
 
 int yang_fill_include(struct lys_module *module, struct lys_submodule *submodule, char *value,
-                      char *rev, int inc_size, struct unres_schema *unres);
+                      char *rev, struct unres_schema *unres);
 
 int yang_use_extension(struct lys_module *module, struct lys_node *data_node, void *actual, char *value);
 
diff --git a/src/parser_yang_bis.c b/src/parser_yang_bis.c
index c61b1ea..8ba1c2f 100644
--- a/src/parser_yang_bis.c
+++ b/src/parser_yang_bis.c
@@ -584,80 +584,80 @@
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   244,   244,   245,   251,   251,   270,   272,   271,   303,
-     316,   303,   325,   326,   327,   328,   331,   344,   331,   355,
-     356,   362,   362,   371,   373,   373,   377,   385,   387,   410,
-     411,   414,   422,   414,   439,   441,   441,   461,   462,   466,
-     467,   469,   481,   492,   481,   501,   503,   504,   505,   506,
-     511,   517,   519,   521,   523,   525,   533,   536,   536,   545,
-     546,   546,   551,   552,   557,   564,   564,   573,   579,   620,
-     623,   624,   625,   626,   627,   628,   629,   635,   636,   637,
-     639,   639,   658,   659,   663,   664,   671,   678,   689,   701,
-     701,   703,   704,   708,   710,   711,   712,   723,   725,   726,
-     725,   729,   730,   731,   732,   749,   749,   758,   759,   764,
-     783,   790,   796,   801,   807,   809,   809,   818,   820,   819,
-     827,   828,   839,   845,   851,   858,   862,   860,   879,   889,
-     889,   896,   899,   899,   914,   915,   921,   927,   932,   938,
-     939,   945,   950,   951,   952,   959,   967,   972,   976,  1006,
-    1007,  1011,  1012,  1013,  1021,  1034,  1040,  1041,  1059,  1063,
-    1073,  1074,  1079,  1094,  1099,  1104,  1109,  1115,  1119,  1129,
-    1130,  1135,  1135,  1153,  1154,  1157,  1169,  1179,  1180,  1185,
-    1186,  1195,  1201,  1206,  1212,  1224,  1225,  1243,  1248,  1249,
-    1254,  1256,  1258,  1262,  1266,  1281,  1281,  1299,  1300,  1302,
-    1313,  1323,  1324,  1329,  1330,  1339,  1345,  1350,  1356,  1368,
-    1369,  1384,  1386,  1388,  1390,  1392,  1392,  1399,  1400,  1405,
-    1425,  1431,  1436,  1441,  1442,  1449,  1452,  1453,  1454,  1455,
-    1456,  1457,  1458,  1461,  1461,  1469,  1470,  1475,  1509,  1509,
-    1511,  1518,  1518,  1526,  1527,  1533,  1539,  1544,  1549,  1549,
-    1554,  1554,  1562,  1562,  1569,  1576,  1569,  1596,  1624,  1624,
-    1626,  1633,  1638,  1633,  1648,  1649,  1649,  1657,  1660,  1666,
-    1672,  1678,  1683,  1689,  1696,  1689,  1715,  1743,  1743,  1745,
-    1752,  1757,  1752,  1767,  1768,  1768,  1776,  1782,  1796,  1810,
-    1822,  1828,  1833,  1839,  1846,  1839,  1871,  1912,  1912,  1914,
-    1921,  1921,  1929,  1939,  1947,  1953,  1967,  1981,  1993,  1999,
-    2004,  2009,  2009,  2017,  2017,  2022,  2022,  2030,  2030,  2041,
-    2043,  2042,  2060,  2081,  2081,  2083,  2096,  2108,  2116,  2124,
-    2132,  2141,  2150,  2150,  2160,  2161,  2164,  2165,  2166,  2167,
-    2168,  2171,  2171,  2179,  2180,  2184,  2204,  2204,  2206,  2213,
-    2219,  2224,  2229,  2229,  2236,  2236,  2247,  2248,  2252,  2279,
-    2279,  2281,  2288,  2288,  2296,  2302,  2308,  2314,  2319,  2325,
-    2325,  2341,  2342,  2346,  2381,  2381,  2383,  2390,  2396,  2401,
-    2406,  2406,  2414,  2414,  2429,  2429,  2438,  2439,  2444,  2445,
-    2448,  2468,  2475,  2499,  2523,  2542,  2561,  2584,  2607,  2612,
-    2618,  2627,  2618,  2634,  2635,  2638,  2647,  2638,  2659,  2680,
-    2680,  2682,  2689,  2698,  2703,  2708,  2708,  2716,  2716,  2726,
-    2727,  2730,  2730,  2741,  2742,  2747,  2775,  2782,  2788,  2793,
-    2798,  2798,  2806,  2806,  2811,  2811,  2823,  2823,  2836,  2850,
-    2836,  2857,  2877,  2877,  2885,  2885,  2890,  2890,  2900,  2914,
-    2900,  2921,  2921,  2931,  2935,  2940,  2967,  2974,  2980,  2985,
-    2990,  2990,  2998,  2998,  3003,  3003,  3010,  3019,  3010,  3032,
-    3051,  3058,  3065,  3075,  3076,  3078,  3083,  3085,  3086,  3087,
-    3090,  3092,  3092,  3098,  3099,  3103,  3125,  3133,  3141,  3157,
-    3165,  3172,  3179,  3190,  3202,  3202,  3208,  3209,  3213,  3235,
-    3243,  3254,  3264,  3273,  3273,  3279,  3280,  3284,  3289,  3295,
-    3303,  3311,  3318,  3325,  3336,  3348,  3348,  3351,  3352,  3356,
-    3357,  3362,  3368,  3370,  3371,  3370,  3374,  3375,  3376,  3391,
-    3393,  3394,  3393,  3397,  3398,  3399,  3414,  3416,  3418,  3419,
-    3440,  3442,  3443,  3444,  3465,  3467,  3468,  3469,  3481,  3481,
-    3489,  3490,  3495,  3497,  3498,  3500,  3501,  3503,  3505,  3505,
-    3514,  3517,  3517,  3528,  3531,  3541,  3562,  3564,  3565,  3568,
-    3568,  3587,  3587,  3596,  3596,  3605,  3608,  3610,  3612,  3613,
-    3615,  3617,  3619,  3620,  3622,  3624,  3625,  3627,  3628,  3630,
-    3632,  3635,  3639,  3641,  3642,  3644,  3645,  3647,  3649,  3660,
-    3661,  3664,  3665,  3677,  3678,  3680,  3681,  3683,  3684,  3690,
-    3691,  3694,  3695,  3696,  3722,  3723,  3726,  3727,  3728,  3731,
-    3731,  3739,  3741,  3742,  3744,  3745,  3747,  3748,  3750,  3751,
-    3753,  3754,  3756,  3757,  3759,  3760,  3763,  3764,  3767,  3769,
-    3770,  3774,  3774,  3783,  3785,  3786,  3787,  3788,  3789,  3790,
-    3791,  3793,  3794,  3795,  3796,  3797,  3798,  3799,  3800,  3801,
-    3802,  3803,  3804,  3805,  3806,  3807,  3808,  3809,  3810,  3811,
-    3812,  3813,  3814,  3815,  3816,  3817,  3818,  3819,  3820,  3821,
-    3822,  3823,  3824,  3825,  3826,  3827,  3828,  3829,  3830,  3831,
-    3832,  3833,  3834,  3835,  3836,  3837,  3838,  3839,  3840,  3841,
-    3842,  3843,  3844,  3845,  3846,  3847,  3848,  3849,  3850,  3851,
-    3852,  3853,  3854,  3855,  3856,  3857,  3858,  3859,  3860,  3861,
-    3862,  3863,  3864,  3865,  3866,  3867,  3868,  3869,  3870,  3873,
-    3882
+       0,   244,   244,   245,   260,   260,   279,   281,   280,   312,
+     325,   312,   334,   335,   336,   337,   340,   353,   340,   364,
+     365,   371,   371,   380,   382,   382,   386,   394,   396,   419,
+     420,   423,   431,   423,   448,   450,   450,   472,   473,   477,
+     478,   480,   492,   503,   492,   512,   514,   515,   516,   517,
+     522,   528,   530,   532,   534,   536,   544,   547,   547,   556,
+     557,   557,   562,   563,   568,   575,   575,   584,   590,   631,
+     634,   635,   636,   637,   638,   639,   640,   646,   647,   648,
+     650,   650,   669,   670,   674,   675,   682,   689,   700,   712,
+     712,   714,   715,   719,   721,   722,   723,   734,   736,   737,
+     736,   740,   741,   742,   743,   760,   760,   769,   770,   775,
+     794,   801,   807,   812,   818,   820,   820,   829,   831,   830,
+     838,   839,   850,   856,   862,   869,   873,   871,   890,   900,
+     900,   907,   910,   910,   925,   926,   932,   938,   943,   949,
+     950,   956,   961,   962,   963,   970,   978,   983,   987,  1017,
+    1018,  1022,  1023,  1024,  1032,  1045,  1051,  1052,  1070,  1074,
+    1084,  1085,  1090,  1105,  1110,  1115,  1120,  1126,  1130,  1140,
+    1141,  1146,  1146,  1164,  1165,  1168,  1180,  1190,  1191,  1196,
+    1197,  1206,  1212,  1217,  1223,  1235,  1236,  1254,  1259,  1260,
+    1265,  1267,  1269,  1273,  1277,  1292,  1292,  1310,  1311,  1313,
+    1324,  1334,  1335,  1340,  1341,  1350,  1356,  1361,  1367,  1379,
+    1380,  1395,  1397,  1399,  1401,  1403,  1403,  1410,  1411,  1416,
+    1436,  1442,  1447,  1452,  1453,  1460,  1463,  1464,  1465,  1466,
+    1467,  1468,  1469,  1472,  1472,  1480,  1481,  1486,  1520,  1520,
+    1522,  1529,  1529,  1537,  1538,  1544,  1550,  1555,  1560,  1560,
+    1565,  1565,  1573,  1573,  1580,  1587,  1580,  1607,  1635,  1635,
+    1637,  1644,  1649,  1644,  1659,  1660,  1660,  1668,  1671,  1677,
+    1683,  1689,  1694,  1700,  1707,  1700,  1726,  1754,  1754,  1756,
+    1763,  1768,  1763,  1778,  1779,  1779,  1787,  1793,  1807,  1821,
+    1833,  1839,  1844,  1850,  1857,  1850,  1882,  1923,  1923,  1925,
+    1932,  1932,  1940,  1950,  1958,  1964,  1978,  1992,  2004,  2010,
+    2015,  2020,  2020,  2028,  2028,  2033,  2033,  2041,  2041,  2052,
+    2054,  2053,  2071,  2092,  2092,  2094,  2107,  2119,  2127,  2135,
+    2143,  2152,  2161,  2161,  2171,  2172,  2175,  2176,  2177,  2178,
+    2179,  2182,  2182,  2190,  2191,  2195,  2215,  2215,  2217,  2224,
+    2230,  2235,  2240,  2240,  2247,  2247,  2258,  2259,  2263,  2290,
+    2290,  2292,  2299,  2299,  2307,  2313,  2319,  2325,  2330,  2336,
+    2336,  2352,  2353,  2357,  2392,  2392,  2394,  2401,  2407,  2412,
+    2417,  2417,  2425,  2425,  2440,  2440,  2449,  2450,  2455,  2456,
+    2459,  2479,  2486,  2510,  2534,  2553,  2572,  2595,  2618,  2623,
+    2629,  2638,  2629,  2645,  2646,  2649,  2658,  2649,  2670,  2691,
+    2691,  2693,  2700,  2709,  2714,  2719,  2719,  2727,  2727,  2737,
+    2738,  2741,  2741,  2752,  2753,  2758,  2786,  2793,  2799,  2804,
+    2809,  2809,  2817,  2817,  2822,  2822,  2834,  2834,  2847,  2861,
+    2847,  2868,  2888,  2888,  2896,  2896,  2901,  2901,  2911,  2925,
+    2911,  2932,  2932,  2942,  2946,  2951,  2978,  2985,  2991,  2996,
+    3001,  3001,  3009,  3009,  3014,  3014,  3021,  3030,  3021,  3043,
+    3062,  3069,  3076,  3086,  3087,  3089,  3094,  3096,  3097,  3098,
+    3101,  3103,  3103,  3109,  3110,  3114,  3136,  3144,  3152,  3168,
+    3176,  3183,  3190,  3201,  3213,  3213,  3219,  3220,  3224,  3246,
+    3254,  3265,  3275,  3284,  3284,  3290,  3291,  3295,  3300,  3306,
+    3314,  3322,  3329,  3336,  3347,  3359,  3359,  3362,  3363,  3367,
+    3368,  3373,  3379,  3381,  3382,  3381,  3385,  3386,  3387,  3402,
+    3404,  3405,  3404,  3408,  3409,  3410,  3425,  3427,  3429,  3430,
+    3451,  3453,  3454,  3455,  3476,  3478,  3479,  3480,  3492,  3492,
+    3500,  3501,  3506,  3508,  3509,  3511,  3512,  3514,  3516,  3516,
+    3525,  3528,  3528,  3539,  3542,  3552,  3573,  3575,  3576,  3579,
+    3579,  3598,  3598,  3607,  3607,  3616,  3619,  3621,  3623,  3624,
+    3626,  3628,  3630,  3631,  3633,  3635,  3636,  3638,  3639,  3641,
+    3643,  3646,  3650,  3652,  3653,  3655,  3656,  3658,  3660,  3671,
+    3672,  3675,  3676,  3688,  3689,  3691,  3692,  3694,  3695,  3701,
+    3702,  3705,  3706,  3707,  3733,  3734,  3737,  3738,  3739,  3742,
+    3742,  3750,  3752,  3753,  3755,  3756,  3758,  3759,  3761,  3762,
+    3764,  3765,  3767,  3768,  3770,  3771,  3774,  3775,  3778,  3780,
+    3781,  3785,  3785,  3794,  3796,  3797,  3798,  3799,  3800,  3801,
+    3802,  3804,  3805,  3806,  3807,  3808,  3809,  3810,  3811,  3812,
+    3813,  3814,  3815,  3816,  3817,  3818,  3819,  3820,  3821,  3822,
+    3823,  3824,  3825,  3826,  3827,  3828,  3829,  3830,  3831,  3832,
+    3833,  3834,  3835,  3836,  3837,  3838,  3839,  3840,  3841,  3842,
+    3843,  3844,  3845,  3846,  3847,  3848,  3849,  3850,  3851,  3852,
+    3853,  3854,  3855,  3856,  3857,  3858,  3859,  3860,  3861,  3862,
+    3863,  3864,  3865,  3866,  3867,  3868,  3869,  3870,  3871,  3872,
+    3873,  3874,  3875,  3876,  3877,  3878,  3879,  3880,  3881,  3884,
+    3893
 };
 #endif
 
@@ -2869,6 +2869,15 @@
     { if (read_all && lyp_propagate_submodule(module, submodule)) {
                        YYABORT;
                      }
+                     if (!submodule && module->inc_size) {
+                       /* update the size of the array, it can be smaller due to possible duplicities
+                        * found in submodules */
+                       module->inc = ly_realloc(module->inc, module->inc_size * sizeof *module->inc);
+                       if (!module->inc) {
+                         LOGMEM;
+                         YYABORT;
+                       }
+                     }
                    }
 
     break;
@@ -3058,24 +3067,24 @@
 
     { if (read_all) {
                           if (size_arrays->imp) {
-                            trg->imp = calloc(size_arrays->imp, sizeof *trg->imp);
+                            size_t size = (size_arrays->imp * sizeof *trg->imp) + sizeof(void*);
+                            trg->imp = calloc(1, size);
                             if (!trg->imp) {
                               LOGMEM;
                               YYABORT;
                             }
+                            /* set stop block for possible realloc */
+                            trg->imp[size_arrays->imp].module = (void*)0x1;
                           }
                           if (size_arrays->inc) {
-                            trg->inc = calloc(size_arrays->inc, sizeof *trg->inc);
+                            size_t size = (size_arrays->inc * sizeof *trg->inc) + sizeof(void*);
+                            trg->inc = calloc(1, size);
                             if (!trg->inc) {
                               LOGMEM;
                               YYABORT;
                             }
-                            trg->inc_size = size_arrays->inc;
-                            size_arrays->inc = 0;
-                            /* trg->inc_size can be updated by the included submodules,
-                             * so we will use size_arrays->inc here, trg->inc_size stores the
-                             * target size of the array
-                             */
+                            /* set stop block for possible realloc */
+                            trg->inc[size_arrays->inc].submodule = (void*)0x1;
                           }
                         }
                       }
@@ -3142,13 +3151,15 @@
 
     { if (read_all) {
                                       (yyval.inc) = trg;
-                                      if (yang_fill_include(module, submodule, (yyvsp[-3].str), rev, size_arrays->inc, unres)) {
+                                      int rc;
+                                      rc = yang_fill_include(module, submodule, (yyvsp[-3].str), rev, unres);
+                                      if (!rc) {
+                                        s = NULL;
+                                        trg = (yyval.inc);
+                                        config_inherit = ENABLE_INHERIT;
+                                      } else if (rc == -1) {
                                         YYABORT;
                                       }
-                                      size_arrays->inc++;
-                                      s = NULL;
-                                      trg = (yyval.inc);
-                                      config_inherit = ENABLE_INHERIT;
                                     }
                                   }
 
diff --git a/src/parser_yang_lex.c b/src/parser_yang_lex.c
index fb5cc10..a67841b 100644
--- a/src/parser_yang_lex.c
+++ b/src/parser_yang_lex.c
@@ -195,7 +195,7 @@
 	do \
 		{ \
 		/* Undo effects of setting up yytext. */ \
-        yy_size_t yyless_macro_arg = (n); \
+        int yyless_macro_arg = (n); \
         YY_LESS_LINENO(yyless_macro_arg);\
 		*yy_cp = yyg->yy_hold_char; \
 		YY_RESTORE_YY_MORE_OFFSET \
@@ -2968,7 +2968,7 @@
 	do \
 		{ \
 		/* Undo effects of setting up yytext. */ \
-        yy_size_t yyless_macro_arg = (n); \
+        int yyless_macro_arg = (n); \
         YY_LESS_LINENO(yyless_macro_arg);\
 		yytext[yyleng] = yyg->yy_hold_char; \
 		yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 618a2f6..95608f6 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -4530,7 +4530,7 @@
     struct lys_include inc;
     const char *value;
     int i, r;
-    int inc_size_aux = 0;
+    size_t size;
     int version_flag = 0;
     /* counters */
     int c_imp = 0, c_rev = 0, c_tpdf = 0, c_ident = 0, c_inc = 0, c_aug = 0, c_ftrs = 0, c_dev = 0;
@@ -4750,11 +4750,14 @@
 
     /* allocate arrays for elements with cardinality of 0..n */
     if (c_imp) {
-        trg->imp = calloc(c_imp, sizeof *trg->imp);
+        size = (c_imp * sizeof *trg->imp) + sizeof(void*);
+        trg->imp = calloc(1, size);
         if (!trg->imp) {
             LOGMEM;
             goto error;
         }
+        /* set stop block for possible realloc */
+        trg->imp[c_imp].module = (void*)0x1;
     }
     if (c_rev) {
         trg->rev = calloc(c_rev, sizeof *trg->rev);
@@ -4778,16 +4781,14 @@
         }
     }
     if (c_inc) {
-        trg->inc = calloc(c_inc, sizeof *trg->inc);
+        size = (c_inc * sizeof *trg->inc) + sizeof(void*);
+        trg->inc = calloc(1, size);
         if (!trg->inc) {
             LOGMEM;
             goto error;
         }
-        trg->inc_size = c_inc;
-        /* trg->inc_size can be updated by the included submodules,
-         * so we will use inc_size_aux here, trg->inc_size stores the
-         * target size of the array
-         */
+        /* set stop block for possible realloc */
+        trg->inc[c_inc].submodule = (void*)0x1;
     }
     if (c_aug) {
         trg->augment = calloc(c_aug, sizeof *trg->augment);
@@ -4820,16 +4821,6 @@
                 goto error;
             }
 
-            /* check for importing a single module in multiple revisions */
-            for (i = 0; i < trg->imp_size - 1; i++) {
-                if (!strcmp(trg->imp[i].module->name, trg->imp[trg->imp_size - 1].module->name) &&
-                        trg->imp[i].module != trg->imp[trg->imp_size - 1].module) {
-                    LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, trg->imp[i].module->name, "import");
-                    LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Importing multiple revisions of module \"%s\".", trg->imp[i].module->name);
-                    goto error;
-                }
-            }
-
         } else if (!strcmp(child->name, "include")) {
             memset(&inc, 0, sizeof inc);
             /* 1) pass module, not trg, since we want to pass the main module
@@ -4838,8 +4829,8 @@
             r = fill_yin_include(module, submodule, child, &inc, unres);
             if (!r) {
                 /* success, copy the filled data into the final array */
-                memcpy(&trg->inc[inc_size_aux], &inc, sizeof inc);
-                inc_size_aux++;
+                memcpy(&trg->inc[trg->inc_size], &inc, sizeof inc);
+                trg->inc_size++;
             } else if (r == -1) {
                 goto error;
             }
@@ -4946,6 +4937,15 @@
     if (submodule && lyp_propagate_submodule(module, submodule)) {
         goto error;
     }
+    if (!submodule && module->inc_size) {
+        /* update the size of the array, it can be smaller due to possible duplicities
+         * found in submodules */
+        module->inc = ly_realloc(module->inc, module->inc_size * sizeof *module->inc);
+        if (!module->inc) {
+            LOGMEM;
+            goto error;
+        }
+    }
 
     /* process data nodes. Start with groupings to allow uses
      * refer to them. Submodule's data nodes are stored in the
@@ -5161,6 +5161,9 @@
             goto error;
         }
         for (i = 0; i < module->inc_size; ++i) {
+            if (!module->inc[i].submodule) {
+                continue;
+            }
             if (lys_sub_module_set_dev_aug_target_implement((struct lys_module *)module->inc[i].submodule)) {
                 goto error;
             }
diff --git a/src/yang.y.in b/src/yang.y.in
index 86a4a14..24c14ad 100644
--- a/src/yang.y.in
+++ b/src/yang.y.in
@@ -245,6 +245,15 @@
  |  submodule_stmt { if (read_all && lyp_propagate_submodule(module, submodule)) {

                        YYABORT;

                      }

+                     if (!submodule && module->inc_size) {

+                       /* update the size of the array, it can be smaller due to possible duplicities

+                        * found in submodules */

+                       module->inc = ly_realloc(module->inc, module->inc_size * sizeof *module->inc);

+                       if (!module->inc) {

+                         LOGMEM;

+                         YYABORT;

+                       }

+                     }

                    }

 

 

@@ -386,24 +395,24 @@
 

 linkage_stmts: @EMPTYDIR@ { if (read_all) {

                           if (size_arrays->imp) {

-                            trg->imp = calloc(size_arrays->imp, sizeof *trg->imp);

+                            size_t size = (size_arrays->imp * sizeof *trg->imp) + sizeof(void*);

+                            trg->imp = calloc(1, size);

                             if (!trg->imp) {

                               LOGMEM;

                               YYABORT;

                             }

+                            /* set stop block for possible realloc */

+                            trg->imp[size_arrays->imp].module = (void*)0x1;

                           }

                           if (size_arrays->inc) {

-                            trg->inc = calloc(size_arrays->inc, sizeof *trg->inc);

+                            size_t size = (size_arrays->inc * sizeof *trg->inc) + sizeof(void*);

+                            trg->inc = calloc(1, size);

                             if (!trg->inc) {

                               LOGMEM;

                               YYABORT;

                             }

-                            trg->inc_size = size_arrays->inc;

-                            size_arrays->inc = 0;

-                            /* trg->inc_size can be updated by the included submodules,

-                             * so we will use size_arrays->inc here, trg->inc_size stores the

-                             * target size of the array

-                             */

+                            /* set stop block for possible realloc */

+                            trg->inc[size_arrays->inc].submodule = (void*)0x1;

                           }

                         }

                       }

@@ -448,13 +457,15 @@
                                                          }

               include_end stmtsep { if (read_all) {

                                       $$ = trg;

-                                      if (yang_fill_include(module, submodule, $3, rev, size_arrays->inc, unres)) {

+                                      int rc;

+                                      rc = yang_fill_include(module, submodule, $3, rev, unres);

+                                      if (!rc) {

+                                        s = NULL;

+                                        trg = $$;

+                                        config_inherit = ENABLE_INHERIT;

+                                      } else if (rc == -1) {

                                         YYABORT;

                                       }

-                                      size_arrays->inc++;

-                                      s = NULL;

-                                      trg = $$;

-                                      config_inherit = ENABLE_INHERIT;

                                     }

                                   }