schema compile CHANGE add context to must and definition module to when

To resolve XPath correctly, some additional information are needed
(valueable) in the compiled must/when statement structures.
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 9f7e470..847b8d4 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -1156,10 +1156,11 @@
  * @brief YANG when-stmt
  */
 struct lysc_when {
+    struct lys_module *module;       /**< module where the must was defined */
     struct lyxp_expr *cond;          /**< XPath when condition */
+    struct lysc_node *context;       /**< context node for evaluating the expression */
     const char *dsc;                 /**< description */
     const char *ref;                 /**< reference */
-    struct lysc_node *context;       /**< context node for evaluating the expression */
     struct lysc_ext_instance *exts;  /**< list of the extension instances ([sized array](@ref sizedarrays)) */
     uint32_t refcount;               /**< reference counter since some of the when statements are shared among several nodes */
 };
@@ -1247,6 +1248,7 @@
 
 struct lysc_must {
     struct lys_module *module;       /**< module where the must was defined */
+    struct lysc_node *context;       /**< context node for evaluating the expression */
     struct lyxp_expr *cond;          /**< XPath when condition */
     const char *dsc;                 /**< description */
     const char *ref;                 /**< reference */
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 69f76cb..e827ca3 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -84,6 +84,18 @@
         } \
     }
 
+#define COMPILE_ARRAY_MUST_GOTO(CTX, ARRAY_P, ARRAY_C, ITER, PARENT, RET, GOTO) \
+    if (ARRAY_P) { \
+        LY_ARRAY_CREATE_GOTO((CTX)->ctx, ARRAY_C, LY_ARRAY_SIZE(ARRAY_P), RET, GOTO); \
+        size_t __array_offset = LY_ARRAY_SIZE(ARRAY_C); \
+        for (ITER = 0; ITER < LY_ARRAY_SIZE(ARRAY_P); ++ITER) { \
+            LY_ARRAY_INCREMENT(ARRAY_C); \
+            RET = lys_compile_must(CTX, &(ARRAY_P)[ITER], &(ARRAY_C)[ITER + __array_offset]); \
+            LY_CHECK_GOTO(RET != LY_SUCCESS, GOTO); \
+            (ARRAY_C)[ITER + __array_offset].context = lysc_xpath_context((struct lysc_node*)PARENT); \
+        } \
+    }
+
 #define COMPILE_MEMBER_GOTO(CTX, MEMBER_P, MEMBER_C, FUNC, RET, GOTO) \
     if (MEMBER_P) { \
         MEMBER_C = calloc(1, sizeof *(MEMBER_C)); \
@@ -807,6 +819,7 @@
     *when = calloc(1, sizeof **when);
     (*when)->refcount = 1;
     (*when)->cond = lyxp_expr_parse(ctx->ctx, when_p->cond);
+    (*when)->module = ctx->mod_def;
     DUP_STRING(ctx->ctx, when_p->dsc, (*when)->dsc);
     DUP_STRING(ctx->ctx, when_p->ref, (*when)->ref);
     LY_CHECK_ERR_GOTO(!(*when)->cond, ret = ly_errcode(ctx->ctx), done);
@@ -3448,6 +3461,20 @@
     return LY_EEXIST;
 }
 
+/**
+ * @brief Get the XPath context node for the given schema node.
+ * @param[in] start The schema node where the XPath expression appears.
+ * @return The context node to evaluate XPath expression in given schema node.
+ * @return NULL in case the context node is the root node.
+ */
+static struct lysc_node *
+lysc_xpath_context(struct lysc_node *start)
+{
+    for (; start && !(start->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYDATA | LYS_ACTION | LYS_NOTIF));
+            start = start->parent);
+    return start;
+}
+
 static LY_ERR lys_compile_node(struct lysc_ctx *ctx, struct lysp_node *node_p, struct lysc_node *parent, uint16_t uses_status);
 
 /**
@@ -3505,7 +3532,7 @@
 
     /* input */
     lysc_update_path(ctx, (struct lysc_node*)action, "input");
-    COMPILE_ARRAY_GOTO(ctx, action_p->input.musts, action->input.musts, u, lys_compile_must, ret, cleanup);
+    COMPILE_ARRAY_MUST_GOTO(ctx, action_p->input.musts, action->input.musts, u, action, ret, cleanup);
     COMPILE_EXTS_GOTO(ctx, action_p->input.exts, action->input_exts, &action->input, LYEXT_PAR_INPUT, ret, cleanup);
     ctx->options |= LYSC_OPT_RPC_INPUT;
     LY_LIST_FOR(action_p->input.data, child_p) {
@@ -3516,7 +3543,7 @@
 
     /* output */
     lysc_update_path(ctx, (struct lysc_node*)action, "output");
-    COMPILE_ARRAY_GOTO(ctx, action_p->output.musts, action->output.musts, u, lys_compile_must, ret, cleanup);
+    COMPILE_ARRAY_MUST_GOTO(ctx, action_p->output.musts, action->output.musts, u, action, ret, cleanup);
     COMPILE_EXTS_GOTO(ctx, action_p->output.exts, action->output_exts, &action->output, LYEXT_PAR_OUTPUT, ret, cleanup);
     ctx->options |= LYSC_OPT_RPC_OUTPUT;
     LY_LIST_FOR(action_p->output.data, child_p) {
@@ -3581,7 +3608,7 @@
     DUP_STRING(ctx->ctx, notif_p->dsc, notif->dsc);
     DUP_STRING(ctx->ctx, notif_p->ref, notif->ref);
     COMPILE_ARRAY_GOTO(ctx, notif_p->iffeatures, notif->iffeatures, u, lys_compile_iffeature, ret, cleanup);
-    COMPILE_ARRAY_GOTO(ctx, notif_p->musts, notif->musts, u, lys_compile_must, ret, cleanup);
+    COMPILE_ARRAY_MUST_GOTO(ctx, notif_p->musts, notif->musts, u, notif, ret, cleanup);
     COMPILE_EXTS_GOTO(ctx, notif_p->exts, notif->exts, notif, LYEXT_PAR_NODE, ret, cleanup);
 
     ctx->options |= LYSC_OPT_NOTIFICATION;
@@ -3620,7 +3647,7 @@
         LY_CHECK_RET(lys_compile_node(ctx, child_p, node, 0));
     }
 
-    COMPILE_ARRAY_GOTO(ctx, cont_p->musts, cont->musts, u, lys_compile_must, ret, done);
+    COMPILE_ARRAY_MUST_GOTO(ctx, cont_p->musts, cont->musts, u, node, ret, done);
     COMPILE_ARRAY1_GOTO(ctx, cont_p->actions, cont->actions, node, u, lys_compile_action, 0, ret, done);
     COMPILE_ARRAY1_GOTO(ctx, cont_p->notifs, cont->notifs, node, u, lys_compile_notif, 0, ret, done);
 
@@ -3701,7 +3728,7 @@
     unsigned int u;
     LY_ERR ret = LY_SUCCESS;
 
-    COMPILE_ARRAY_GOTO(ctx, leaf_p->musts, leaf->musts, u, lys_compile_must, ret, done);
+    COMPILE_ARRAY_MUST_GOTO(ctx, leaf_p->musts, leaf->musts, u, node, ret, done);
     if (leaf_p->units) {
         leaf->units = lydict_insert(ctx->ctx, leaf_p->units, 0);
         leaf->flags |= LYS_SET_UNITS;
@@ -3762,7 +3789,7 @@
     unsigned int u, v;
     LY_ERR ret = LY_SUCCESS;
 
-    COMPILE_ARRAY_GOTO(ctx, llist_p->musts, llist->musts, u, lys_compile_must, ret, done);
+    COMPILE_ARRAY_MUST_GOTO(ctx, llist_p->musts, llist->musts, u, node, ret, done);
     if (llist_p->units) {
         llist->units = lydict_insert(ctx->ctx, llist_p->units, 0);
         llist->flags |= LYS_SET_UNITS;
@@ -3943,7 +3970,7 @@
         LY_CHECK_RET(lys_compile_node(ctx, child_p, node, 0));
     }
 
-    COMPILE_ARRAY_GOTO(ctx, list_p->musts, list->musts, u, lys_compile_must, ret, done);
+    COMPILE_ARRAY_MUST_GOTO(ctx, list_p->musts, list->musts, u, node, ret, done);
 
     /* keys */
     if ((list->flags & LYS_CONFIG_W) && (!list_p->key || !list_p->key[0])) {
@@ -4242,7 +4269,7 @@
     unsigned int u;
     LY_ERR ret = LY_SUCCESS;
 
-    COMPILE_ARRAY_GOTO(ctx, any_p->musts, any->musts, u, lys_compile_must, ret, done);
+    COMPILE_ARRAY_MUST_GOTO(ctx, any_p->musts, any->musts, u, node, ret, done);
 
     if (any->flags & LYS_CONFIG_W) {
         LOGWRN(ctx->ctx, "Use of %s to define configuration data is not recommended.",
@@ -4297,20 +4324,6 @@
 }
 
 /**
- * @brief Get the XPath context node for the given schema node.
- * @param[in] start The schema node where the XPath expression appears.
- * @return The context node to evaluate XPath expression in given schema node.
- * @return NULL in case the context node is the root node.
- */
-static struct lysc_node *
-lysc_xpath_context(struct lysc_node *start)
-{
-    for (; start && !(start->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYDATA | LYS_ACTION | LYS_NOTIF));
-            start = start->parent);
-    return start;
-}
-
-/**
  * @brief Prepare the case structure in choice node for the new data node.
  *
  * It is able to handle implicit as well as explicit cases and the situation when the case has multiple data nodes and the case was already
@@ -5146,20 +5159,20 @@
         if (rfn->musts) {
             switch (node->nodetype) {
             case LYS_LEAF:
-                COMPILE_ARRAY_GOTO(ctx, rfn->musts, ((struct lysc_node_leaf*)node)->musts, u, lys_compile_must, ret, cleanup);
+                COMPILE_ARRAY_MUST_GOTO(ctx, rfn->musts, ((struct lysc_node_leaf*)node)->musts, u, node, ret, cleanup);
                 break;
             case LYS_LEAFLIST:
-                COMPILE_ARRAY_GOTO(ctx, rfn->musts, ((struct lysc_node_leaflist*)node)->musts, u, lys_compile_must, ret, cleanup);
+                COMPILE_ARRAY_MUST_GOTO(ctx, rfn->musts, ((struct lysc_node_leaflist*)node)->musts, u, node, ret, cleanup);
                 break;
             case LYS_LIST:
-                COMPILE_ARRAY_GOTO(ctx, rfn->musts, ((struct lysc_node_list*)node)->musts, u, lys_compile_must, ret, cleanup);
+                COMPILE_ARRAY_MUST_GOTO(ctx, rfn->musts, ((struct lysc_node_list*)node)->musts, u, node, ret, cleanup);
                 break;
             case LYS_CONTAINER:
-                COMPILE_ARRAY_GOTO(ctx, rfn->musts, ((struct lysc_node_container*)node)->musts, u, lys_compile_must, ret, cleanup);
+                COMPILE_ARRAY_MUST_GOTO(ctx, rfn->musts, ((struct lysc_node_container*)node)->musts, u, node, ret, cleanup);
                 break;
             case LYS_ANYXML:
             case LYS_ANYDATA:
-                COMPILE_ARRAY_GOTO(ctx, rfn->musts, ((struct lysc_node_anydata*)node)->musts, u, lys_compile_must, ret, cleanup);
+                COMPILE_ARRAY_MUST_GOTO(ctx, rfn->musts, ((struct lysc_node_anydata*)node)->musts, u, node, ret, cleanup);
                 break;
             default:
                 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
@@ -5947,27 +5960,27 @@
                     switch (devs[u]->target->nodetype) {
                     case LYS_CONTAINER:
                     case LYS_LIST:
-                        COMPILE_ARRAY_GOTO(ctx, d_add->musts, ((struct lysc_node_container*)devs[u]->target)->musts,
-                                           x, lys_compile_must, ret, cleanup);
+                        COMPILE_ARRAY_MUST_GOTO(ctx, d_add->musts, ((struct lysc_node_container*)devs[u]->target)->musts,
+                                                x, devs[u]->target, ret, cleanup);
                         break;
                     case LYS_LEAF:
                     case LYS_LEAFLIST:
                     case LYS_ANYDATA:
-                        COMPILE_ARRAY_GOTO(ctx, d_add->musts, ((struct lysc_node_leaf*)devs[u]->target)->musts,
-                                           x, lys_compile_must, ret, cleanup);
+                        COMPILE_ARRAY_MUST_GOTO(ctx, d_add->musts, ((struct lysc_node_leaf*)devs[u]->target)->musts,
+                                                x, devs[u]->target, ret, cleanup);
                         break;
                     case LYS_NOTIF:
-                        COMPILE_ARRAY_GOTO(ctx, d_add->musts, ((struct lysc_notif*)devs[u]->target)->musts,
-                                           x, lys_compile_must, ret, cleanup);
+                        COMPILE_ARRAY_MUST_GOTO(ctx, d_add->musts, ((struct lysc_notif*)devs[u]->target)->musts,
+                                                x, devs[u]->target, ret, cleanup);
                         break;
                     case LYS_ACTION:
                         if (devs[u]->flags & LYSC_OPT_RPC_INPUT) {
-                            COMPILE_ARRAY_GOTO(ctx, d_add->musts, ((struct lysc_action*)devs[u]->target)->input.musts,
-                                               x, lys_compile_must, ret, cleanup);
+                            COMPILE_ARRAY_MUST_GOTO(ctx, d_add->musts, ((struct lysc_action*)devs[u]->target)->input.musts,
+                                                    x, devs[u]->target, ret, cleanup);
                             break;
                         } else  if (devs[u]->flags & LYSC_OPT_RPC_OUTPUT) {
-                            COMPILE_ARRAY_GOTO(ctx, d_add->musts, ((struct lysc_action*)devs[u]->target)->output.musts,
-                                               x, lys_compile_must, ret, cleanup);
+                            COMPILE_ARRAY_MUST_GOTO(ctx, d_add->musts, ((struct lysc_action*)devs[u]->target)->output.musts,
+                                                    x, devs[u]->target, ret, cleanup);
                             break;
                         }
                         /* fall through */