compile schema REFACTOR uses compilation refactoring

Just separation of lys_compile_uses to 2 more
functions.
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 139ec0e..168e820 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -4638,46 +4638,28 @@
 }
 
 /**
- * @brief Compile parsed uses statement - resolve target grouping and connect its content into parent.
- * If present, also apply uses's modificators.
+ * @brief Find grouping for a uses.
  *
- * @param[in] ctx Compile context
- * @param[in] uses_p Parsed uses schema node.
- * @param[in] parent Compiled parent node where the content of the referenced grouping is supposed to be connected. It is
- * NULL for top-level nodes, in such a case the module where the node will be connected is taken from
- * the compile context.
- * @return LY_ERR value - LY_SUCCESS or LY_EVALID.
+ * @param[in] ctx Compile context.
+ * @param[in] uses_p Parsed uses node.
+ * @param[out] gpr_p Found grouping on success.
+ * @param[out] grp_mod Module of @p grp_p on success.
+ * @return LY_ERR value.
  */
 static LY_ERR
-lys_compile_uses(struct lysc_ctx *ctx, struct lysp_node_uses *uses_p, struct lysc_node *parent, struct lysc_node **first_p)
+lys_compile_uses_find_grouping(struct lysc_ctx *ctx, struct lysp_node_uses *uses_p, struct lysp_grp **grp_p,
+        struct lys_module **grp_mod)
 {
     struct lysp_node *node_p;
-    struct lysc_node *node, *child, *iter;
-    /* context_node_fake allows us to temporarily isolate the nodes inserted from the grouping instead of uses */
-    struct lysc_node_container context_node_fake =
-    {.nodetype = LYS_CONTAINER,
-        .module = ctx->mod,
-        .flags = parent ? parent->flags : 0,
-        .child = NULL, .next = NULL,
-        .prev = (struct lysc_node *)&context_node_fake,
-        .actions = NULL, .notifs = NULL};
-    struct lysp_grp *grp = NULL;
+    struct lysp_grp *grp;
     LY_ARRAY_COUNT_TYPE u, v;
-    uint32_t grp_stack_count;
     uint8_t found = 0;
     const char *id, *name, *prefix;
     size_t prefix_len, name_len;
-    struct lys_module *mod, *mod_old;
-    struct lysp_refine *rfn;
-    LY_ERR ret = LY_SUCCESS;
-    uint32_t min, max;
-    uint16_t flags;
-    struct ly_set refined = {0};
-    struct lysc_when **when, *when_shared;
-    struct lysp_augment **augments = NULL;
-    LY_ARRAY_COUNT_TYPE actions_index = 0, notifs_index = 0;
-    struct lysc_notif **notifs = NULL;
-    struct lysc_action **actions = NULL;
+    struct lys_module *mod;
+
+    *grp_p = NULL;
+    *grp_mod = NULL;
 
     /* search for the grouping definition */
     id = uses_p->name;
@@ -4707,26 +4689,27 @@
     if (!found) {
         /* search in top-level groupings of the main module ... */
         grp = mod->parsed->groupings;
-        if (grp) {
-            for (u = 0; !found && u < LY_ARRAY_COUNT(grp); ++u) {
-                if (!strcmp(grp[u].name, name)) {
-                    grp = &grp[u];
-                    found = 1;
-                }
+        LY_ARRAY_FOR(grp, u) {
+            if (!strcmp(grp[u].name, name)) {
+                grp = &grp[u];
+                found = 1;
+                break;
             }
         }
-        if (!found && mod->parsed->includes) {
+        if (!found) {
             /* ... and all the submodules */
-            for (u = 0; !found && u < LY_ARRAY_COUNT(mod->parsed->includes); ++u) {
+            LY_ARRAY_FOR(mod->parsed->includes, u) {
                 grp = mod->parsed->includes[u].submodule->groupings;
-                if (grp) {
-                    for (v = 0; !found && v < LY_ARRAY_COUNT(grp); ++v) {
-                        if (!strcmp(grp[v].name, name)) {
-                            grp = &grp[v];
-                            found = 1;
-                        }
+                LY_ARRAY_FOR(grp, v) {
+                    if (!strcmp(grp[v].name, name)) {
+                        grp = &grp[v];
+                        found = 1;
+                        break;
                     }
                 }
+                if (found) {
+                    break;
+                }
             }
         }
     }
@@ -4736,141 +4719,34 @@
         return LY_EVALID;
     }
 
-    /* grouping must not reference themselves - stack in ctx maintains list of groupings currently being applied */
-    grp_stack_count = ctx->groupings.count;
-    LY_CHECK_RET(ly_set_add(&ctx->groupings, (void *)grp, 0, NULL));
-    if (grp_stack_count == ctx->groupings.count) {
-        /* the target grouping is already in the stack, so we are already inside it -> circular dependency */
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
-               "Grouping \"%s\" references itself through a uses statement.", grp->name);
-        return LY_EVALID;
-    }
     if (!(ctx->options & LYSC_OPT_GROUPING)) {
         /* remember that the grouping is instantiated to avoid its standalone validation */
         grp->flags |= LYS_USED_GRP;
     }
 
-    /* switch context's mod_def */
-    mod_old = ctx->mod_def;
-    ctx->mod_def = mod;
+    *grp_p = grp;
+    *grp_mod = mod;
+    return LY_SUCCESS;
+}
 
-    /* check status */
-    ret = lysc_check_status(ctx, uses_p->flags, mod_old, uses_p->name, grp->flags, mod, grp->name);
-    LY_CHECK_GOTO(ret, cleanup);
+static LY_ERR
+lys_compile_refines(struct lysc_ctx *ctx, struct lysp_refine *refines, const struct lysc_node *context_node)
+{
+    struct lysc_node *node;
+    LY_ARRAY_COUNT_TYPE u;
+    struct lysp_refine *rfn;
+    LY_ERR ret = LY_SUCCESS;
+    uint32_t min, max;
+    uint16_t flags;
+    struct ly_set refined = {0};
 
-    /* remember the currently last child before processing the uses - it is needed to split the siblings to corretly
-     * applu refine and augment only to the nodes from the uses */
-    if (parent) {
-        if (parent->nodetype == LYS_CASE) {
-            child = (struct lysc_node *)lysc_node_children(parent->parent, ctx->options & LYSC_OPT_RPC_MASK);
-        } else {
-            child = (struct lysc_node *)lysc_node_children(parent, ctx->options & LYSC_OPT_RPC_MASK);
-        }
-    } else if (ctx->mod->compiled->data) {
-        child = ctx->mod->compiled->data;
-    } else {
-        child = NULL;
-    }
-    /* remember the last child */
-    if (child) {
-        child = child->prev;
-    }
-
-    /* compile data nodes */
-    LY_LIST_FOR(grp->data, node_p) {
-        /* 0x3 in uses_status is a special bits combination to be able to detect status flags from uses */
-        ret = lys_compile_node(ctx, node_p, parent, (uses_p->flags & LYS_STATUS_MASK) | 0x3);
-        LY_CHECK_GOTO(ret, cleanup);
-    }
-
-    /* split the children and add the uses's data into the fake context node */
-    if (child) {
-        context_node_fake.child = child->next;
-    } else if (parent) {
-        context_node_fake.child = (struct lysc_node *)lysc_node_children(parent, ctx->options & LYSC_OPT_RPC_MASK);
-    } else if (ctx->mod->compiled->data) {
-        context_node_fake.child = ctx->mod->compiled->data;
-    }
-    if (context_node_fake.child) {
-        /* remember child as the last data node added by grouping to fix the list later */
-        child = context_node_fake.child->prev;
-        context_node_fake.child->prev = NULL;
-    }
-
-    when_shared = NULL;
-    LY_LIST_FOR(context_node_fake.child, iter) {
-        iter->parent = (struct lysc_node *)&context_node_fake;
-
-        /* pass uses's when to all the data children, actions and notifications are ignored */
-        if (uses_p->when) {
-            LY_ARRAY_NEW_GOTO(ctx->ctx, iter->when, when, ret, cleanup);
-            if (!when_shared) {
-                ret = lys_compile_when(ctx, uses_p->when, uses_p->flags, parent, when);
-                LY_CHECK_GOTO(ret, cleanup);
-
-                if (!(ctx->options & LYSC_OPT_GROUPING)) {
-                    /* do not check "when" semantics in a grouping */
-                    ret = ly_set_add(&ctx->xpath, iter, 0, NULL);
-                    LY_CHECK_GOTO(ret, cleanup);
-                }
-
-                when_shared = *when;
-            } else {
-                ++when_shared->refcount;
-                (*when) = when_shared;
-
-                if (!(ctx->options & LYSC_OPT_GROUPING)) {
-                    /* in this case check "when" again for all children because of dummy node check */
-                    ret = ly_set_add(&ctx->xpath, iter, 0, NULL);
-                    LY_CHECK_GOTO(ret, cleanup);
-                }
-            }
-        }
-    }
-
-    /* compile actions */
-    actions = parent ? lysc_node_actions_p(parent) : &ctx->mod->compiled->rpcs;
-    if (actions) {
-        actions_index = *actions ? LY_ARRAY_COUNT(*actions) : 0;
-        COMPILE_ARRAY1_GOTO(ctx, grp->actions, *actions, parent, u, lys_compile_action, 0, ret, cleanup);
-        if (*actions && (uses_p->augments || uses_p->refines)) {
-            /* but for augment and refine, we need to separate the compiled grouping's actions to avoid modification of others */
-            LY_ARRAY_CREATE_GOTO(ctx->ctx, context_node_fake.actions, LY_ARRAY_COUNT(*actions) - actions_index, ret, cleanup);
-            LY_ARRAY_COUNT(context_node_fake.actions) = LY_ARRAY_COUNT(*actions) - actions_index;
-            memcpy(context_node_fake.actions, &(*actions)[actions_index], LY_ARRAY_COUNT(context_node_fake.actions) * sizeof **actions);
-        }
-    }
-
-    /* compile notifications */
-    notifs = parent ? lysc_node_notifs_p(parent) : &ctx->mod->compiled->notifs;
-    if (notifs) {
-        notifs_index = *notifs ? LY_ARRAY_COUNT(*notifs) : 0;
-        COMPILE_ARRAY1_GOTO(ctx, grp->notifs, *notifs, parent, u, lys_compile_notif, 0, ret, cleanup);
-        if (*notifs && (uses_p->augments || uses_p->refines)) {
-            /* but for augment and refine, we need to separate the compiled grouping's notification to avoid modification of others */
-            LY_ARRAY_CREATE_GOTO(ctx->ctx, context_node_fake.notifs, LY_ARRAY_COUNT(*notifs) - notifs_index, ret, cleanup);
-            LY_ARRAY_COUNT(context_node_fake.notifs) = LY_ARRAY_COUNT(*notifs) - notifs_index;
-            memcpy(context_node_fake.notifs, &(*notifs)[notifs_index], LY_ARRAY_COUNT(context_node_fake.notifs) * sizeof **notifs);
-        }
-    }
-
-    /* sort and apply augments */
-    ret = lys_compile_augment_sort(ctx, uses_p->augments, NULL, &augments);
-    LY_CHECK_GOTO(ret, cleanup);
-    LY_ARRAY_FOR(augments, u) {
-        ret = lys_compile_augment(ctx, augments[u], (struct lysc_node *)&context_node_fake);
-        LY_CHECK_GOTO(ret, cleanup);
-    }
-
-    /* reload previous context's mod_def */
-    ctx->mod_def = mod_old;
     lysc_update_path(ctx, NULL, "{refine}");
 
     /* apply refine */
-    LY_ARRAY_FOR(uses_p->refines, struct lysp_refine, rfn) {
+    LY_ARRAY_FOR(refines, struct lysp_refine, rfn) {
         lysc_update_path(ctx, NULL, rfn->nodeid);
 
-        ret = lysc_resolve_schema_nodeid(ctx, rfn->nodeid, 0, (struct lysc_node *)&context_node_fake, ctx->mod,
+        ret = lysc_resolve_schema_nodeid(ctx, rfn->nodeid, 0, context_node, ctx->mod,
                 0, 0, (const struct lysc_node **)&node, &flags);
         LY_CHECK_GOTO(ret, cleanup);
         ret = ly_set_add(&refined, node, LY_SET_OPT_USEASLIST, NULL);
@@ -5046,7 +4922,7 @@
     /* do some additional checks of the changed nodes when all the refines are applied */
     for (uint32_t i = 0; i < refined.count; ++i) {
         node = (struct lysc_node *)refined.objs[i];
-        rfn = &uses_p->refines[i];
+        rfn = &refines[i];
         lysc_update_path(ctx, NULL, rfn->nodeid);
 
         /* check possible conflict with default value (default added, mandatory left true) */
@@ -5075,12 +4951,182 @@
                 goto cleanup;
             }
         }
+
+        lysc_update_path(ctx, NULL, NULL);
     }
 
+cleanup:
+    ly_set_erase(&refined, NULL);
+    lysc_update_path(ctx, NULL, NULL);
+    return ret;
+}
+
+/**
+ * @brief Compile parsed uses statement - resolve target grouping and connect its content into parent.
+ * If present, also apply uses's modificators.
+ *
+ * @param[in] ctx Compile context
+ * @param[in] uses_p Parsed uses schema node.
+ * @param[in] parent Compiled parent node where the content of the referenced grouping is supposed to be connected. It is
+ * NULL for top-level nodes, in such a case the module where the node will be connected is taken from
+ * the compile context.
+ * @return LY_ERR value - LY_SUCCESS or LY_EVALID.
+ */
+static LY_ERR
+lys_compile_uses(struct lysc_ctx *ctx, struct lysp_node_uses *uses_p, struct lysc_node *parent, struct lysc_node **first_p)
+{
+    struct lysp_node *node_p;
+    struct lysc_node *child, *iter;
+    /* context_node_fake allows us to temporarily isolate the nodes inserted from the grouping instead of uses */
+    struct lysc_node_container context_node_fake =
+    {.nodetype = LYS_CONTAINER,
+        .module = ctx->mod,
+        .flags = parent ? parent->flags : 0,
+        .child = NULL, .next = NULL,
+        .prev = (struct lysc_node *)&context_node_fake,
+        .actions = NULL, .notifs = NULL};
+    struct lysp_grp *grp = NULL;
+    LY_ARRAY_COUNT_TYPE u;
+    uint32_t grp_stack_count;
+    struct lys_module *grp_mod, *mod_old;
+    LY_ERR ret = LY_SUCCESS;
+    struct lysc_when **when, *when_shared;
+    struct lysp_augment **augments = NULL;
+    LY_ARRAY_COUNT_TYPE actions_index = 0, notifs_index = 0;
+    struct lysc_notif **notifs = NULL;
+    struct lysc_action **actions = NULL;
+
+    /* find the referenced grouping */
+    LY_CHECK_RET(lys_compile_uses_find_grouping(ctx, uses_p, &grp, &grp_mod));
+
+    /* grouping must not reference themselves - stack in ctx maintains list of groupings currently being applied */
+    grp_stack_count = ctx->groupings.count;
+    LY_CHECK_RET(ly_set_add(&ctx->groupings, (void *)grp, 0, NULL));
+    if (grp_stack_count == ctx->groupings.count) {
+        /* the target grouping is already in the stack, so we are already inside it -> circular dependency */
+        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+               "Grouping \"%s\" references itself through a uses statement.", grp->name);
+        return LY_EVALID;
+    }
+
+    /* switch context's mod_def */
+    mod_old = ctx->mod_def;
+    ctx->mod_def = grp_mod;
+
+    /* check status */
+    ret = lysc_check_status(ctx, uses_p->flags, mod_old, uses_p->name, grp->flags, grp_mod, grp->name);
+    LY_CHECK_GOTO(ret, cleanup);
+
+    /* remember the currently last child before processing the uses - it is needed to split the siblings to corretly
+     * applu refine and augment only to the nodes from the uses */
+    if (parent) {
+        child = (struct lysc_node *)lysc_node_children(parent, ctx->options & LYSC_OPT_RPC_MASK);
+    } else if (ctx->mod->compiled->data) {
+        child = ctx->mod->compiled->data;
+    } else {
+        child = NULL;
+    }
+    /* remember the last child */
+    if (child) {
+        child = child->prev;
+    }
+
+    /* compile data nodes */
+    LY_LIST_FOR(grp->data, node_p) {
+        /* 0x3 in uses_status is a special bits combination to be able to detect status flags from uses */
+        ret = lys_compile_node(ctx, node_p, parent, (uses_p->flags & LYS_STATUS_MASK) | 0x3);
+        LY_CHECK_GOTO(ret, cleanup);
+    }
+
+    /* split the children and add the uses's data into the fake context node */
+    if (child) {
+        context_node_fake.child = child->next;
+    } else if (parent) {
+        context_node_fake.child = (struct lysc_node *)lysc_node_children(parent, ctx->options & LYSC_OPT_RPC_MASK);
+    } else if (ctx->mod->compiled->data) {
+        context_node_fake.child = ctx->mod->compiled->data;
+    }
+    if (context_node_fake.child) {
+        /* remember child as the last data node added by grouping to fix the list later */
+        child = context_node_fake.child->prev;
+        context_node_fake.child->prev = NULL;
+    }
+
+    when_shared = NULL;
+    LY_LIST_FOR(context_node_fake.child, iter) {
+        iter->parent = (struct lysc_node *)&context_node_fake;
+
+        /* pass uses's when to all the data children, actions and notifications are ignored */
+        if (uses_p->when) {
+            LY_ARRAY_NEW_GOTO(ctx->ctx, iter->when, when, ret, cleanup);
+            if (!when_shared) {
+                ret = lys_compile_when(ctx, uses_p->when, uses_p->flags, parent, when);
+                LY_CHECK_GOTO(ret, cleanup);
+
+                if (!(ctx->options & LYSC_OPT_GROUPING)) {
+                    /* do not check "when" semantics in a grouping */
+                    ret = ly_set_add(&ctx->xpath, iter, 0, NULL);
+                    LY_CHECK_GOTO(ret, cleanup);
+                }
+
+                when_shared = *when;
+            } else {
+                ++when_shared->refcount;
+                (*when) = when_shared;
+
+                if (!(ctx->options & LYSC_OPT_GROUPING)) {
+                    /* in this case check "when" again for all children because of dummy node check */
+                    ret = ly_set_add(&ctx->xpath, iter, 0, NULL);
+                    LY_CHECK_GOTO(ret, cleanup);
+                }
+            }
+        }
+    }
+
+    /* compile actions */
+    actions = parent ? lysc_node_actions_p(parent) : &ctx->mod->compiled->rpcs;
+    if (actions) {
+        actions_index = *actions ? LY_ARRAY_COUNT(*actions) : 0;
+        COMPILE_ARRAY1_GOTO(ctx, grp->actions, *actions, parent, u, lys_compile_action, 0, ret, cleanup);
+        if (*actions && (uses_p->augments || uses_p->refines)) {
+            /* but for augment and refine, we need to separate the compiled grouping's actions to avoid modification of others */
+            LY_ARRAY_CREATE_GOTO(ctx->ctx, context_node_fake.actions, LY_ARRAY_COUNT(*actions) - actions_index, ret, cleanup);
+            LY_ARRAY_COUNT(context_node_fake.actions) = LY_ARRAY_COUNT(*actions) - actions_index;
+            memcpy(context_node_fake.actions, &(*actions)[actions_index], LY_ARRAY_COUNT(context_node_fake.actions) * sizeof **actions);
+        }
+    }
+
+    /* compile notifications */
+    notifs = parent ? lysc_node_notifs_p(parent) : &ctx->mod->compiled->notifs;
+    if (notifs) {
+        notifs_index = *notifs ? LY_ARRAY_COUNT(*notifs) : 0;
+        COMPILE_ARRAY1_GOTO(ctx, grp->notifs, *notifs, parent, u, lys_compile_notif, 0, ret, cleanup);
+        if (*notifs && (uses_p->augments || uses_p->refines)) {
+            /* but for augment and refine, we need to separate the compiled grouping's notification to avoid modification of others */
+            LY_ARRAY_CREATE_GOTO(ctx->ctx, context_node_fake.notifs, LY_ARRAY_COUNT(*notifs) - notifs_index, ret, cleanup);
+            LY_ARRAY_COUNT(context_node_fake.notifs) = LY_ARRAY_COUNT(*notifs) - notifs_index;
+            memcpy(context_node_fake.notifs, &(*notifs)[notifs_index], LY_ARRAY_COUNT(context_node_fake.notifs) * sizeof **notifs);
+        }
+    }
+
+    /* sort and apply augments */
+    ret = lys_compile_augment_sort(ctx, uses_p->augments, NULL, &augments);
+    LY_CHECK_GOTO(ret, cleanup);
+    LY_ARRAY_FOR(augments, u) {
+        ret = lys_compile_augment(ctx, augments[u], (struct lysc_node *)&context_node_fake);
+        LY_CHECK_GOTO(ret, cleanup);
+    }
+
+    /* reload previous context's mod_def */
+    ctx->mod_def = mod_old;
+
+    /* apply all refines */
+    ret = lys_compile_refines(ctx, uses_p->refines, (struct lysc_node *)&context_node_fake);
+    LY_CHECK_GOTO(ret, cleanup);
+
     if (first_p) {
         *first_p = context_node_fake.child;
     }
-    lysc_update_path(ctx, NULL, NULL);
 
 cleanup:
     /* fix connection of the children nodes from fake context node back into the parent */
@@ -5108,7 +5154,6 @@
     /* remove the grouping from the stack for circular groupings dependency check */
     ly_set_rm_index(&ctx->groupings, ctx->groupings.count - 1, NULL);
     assert(ctx->groupings.count == grp_stack_count);
-    ly_set_erase(&refined, NULL);
     LY_ARRAY_FREE(augments);
 
     return ret;