schema tree BUGFIX check grouping children with respect to uses parent
diff --git a/src/tree_schema.c b/src/tree_schema.c
index ad0dd4a..f4571a1 100755
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -755,7 +755,7 @@
 lys_node_addchild(struct lys_node *parent, struct lys_module *module, struct lys_node *child, int options)
 {
     struct ly_ctx *ctx = child->module->ctx;
-    struct lys_node *iter, **pchild;
+    struct lys_node *iter, **pchild, *log_parent;
     struct lys_node_inout *in, *out;
     struct lys_node_case *c;
     int type, shortcase = 0;
@@ -767,10 +767,25 @@
     if (parent) {
         type = parent->nodetype;
         module = parent->module;
+        log_parent = parent;
+
+        if (type == LYS_USES) {
+            /* we are adding children to uses -> we must be copying grouping contents into it, so properly check the parent */
+            log_parent = lys_parent(log_parent);
+            while (log_parent && (log_parent->nodetype == LYS_USES)) {
+                log_parent = lys_parent(log_parent);
+            }
+            if (log_parent) {
+                type = log_parent->nodetype;
+            } else {
+                type = 0;
+            }
+        }
     } else {
         assert(module);
         assert(!(child->nodetype & (LYS_INPUT | LYS_OUTPUT)));
         type = 0;
+        log_parent = NULL;
     }
 
     /* checks */
@@ -782,7 +797,7 @@
         if (!(child->nodetype &
                 (LYS_ANYDATA | LYS_CHOICE | LYS_CONTAINER | LYS_GROUPING | LYS_LEAF |
                  LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ACTION | LYS_NOTIF))) {
-            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), strnodetype(parent->nodetype));
+            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), strnodetype(log_parent->nodetype));
             return EXIT_FAILURE;
         }
         break;
@@ -792,14 +807,14 @@
         if (!(child->nodetype &
                 (LYS_ANYDATA | LYS_CHOICE | LYS_CONTAINER | LYS_GROUPING | LYS_LEAF |
                  LYS_LEAFLIST | LYS_LIST | LYS_USES))) {
-            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), strnodetype(parent->nodetype));
+            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), strnodetype(log_parent->nodetype));
             return EXIT_FAILURE;
         }
         break;
     case LYS_CHOICE:
         if (!(child->nodetype &
                 (LYS_ANYDATA | LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_CHOICE))) {
-            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), "choice");
+            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), "choice");
             return EXIT_FAILURE;
         }
         if (child->nodetype != LYS_CASE) {
@@ -809,14 +824,14 @@
     case LYS_CASE:
         if (!(child->nodetype &
                 (LYS_ANYDATA | LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES))) {
-            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), "case");
+            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), "case");
             return EXIT_FAILURE;
         }
         break;
     case LYS_RPC:
     case LYS_ACTION:
         if (!(child->nodetype & (LYS_INPUT | LYS_OUTPUT | LYS_GROUPING))) {
-            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), "rpc");
+            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), "rpc");
             return EXIT_FAILURE;
         }
         break;
@@ -824,15 +839,15 @@
     case LYS_LEAFLIST:
     case LYS_ANYXML:
     case LYS_ANYDATA:
-        LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), strnodetype(parent->nodetype));
+        LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), strnodetype(log_parent->nodetype));
         LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "The \"%s\" statement cannot have any data substatement.",
-               strnodetype(parent->nodetype));
+               strnodetype(log_parent->nodetype));
         return EXIT_FAILURE;
     case LYS_AUGMENT:
         if (!(child->nodetype &
                 (LYS_ANYDATA | LYS_CASE | LYS_CHOICE | LYS_CONTAINER | LYS_LEAF
                 | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ACTION | LYS_NOTIF))) {
-            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), strnodetype(parent->nodetype));
+            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), strnodetype(log_parent->nodetype));
             return EXIT_FAILURE;
         }
         break;
@@ -841,16 +856,16 @@
         if (!(child->nodetype &
                 (LYS_ANYDATA | LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_GROUPING
                 | LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_RPC | LYS_NOTIF | LYS_AUGMENT))) {
-            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), "(sub)module");
+            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), "(sub)module");
             return EXIT_FAILURE;
         }
         break;
     case LYS_EXT:
         /* plugin-defined */
-        p = lys_ext_complex_get_substmt(lys_snode2stmt(child->nodetype), (struct lys_ext_instance_complex*)parent, &info);
+        p = lys_ext_complex_get_substmt(lys_snode2stmt(child->nodetype), (struct lys_ext_instance_complex*)log_parent, &info);
         if (!p) {
-            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype),
-                   ((struct lys_ext_instance_complex*)parent)->def->name);
+            LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype),
+                   ((struct lys_ext_instance_complex*)log_parent)->def->name);
             return EXIT_FAILURE;
         }
         /* TODO check cardinality */
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e2e9b77..6c37978 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -9,7 +9,7 @@
 set(api_tests test_libyang test_tree_schema test_xml test_dict test_tree_data test_tree_data_dup test_tree_data_merge test_xpath test_xpath_1.1 test_diff)
 set(data_tests test_data_initialization test_leafref_remove test_instid_remove test_keys test_autodel test_when test_when_1.1 test_must_1.1 test_defaults test_emptycont test_unique test_mandatory test_json test_parse_print test_values test_metadata test_yangtypes_xpath test_yang_data test_unknown_element)
 set(schema_yin_tests test_print_transform)
-set(schema_tests test_ietf test_augment test_deviation test_refine test_typedef test_import test_include test_feature test_conformance test_leaflist test_status test_printer)
+set(schema_tests test_ietf test_augment test_deviation test_refine test_typedef test_import test_include test_feature test_conformance test_leaflist test_status test_printer test_invalid)
 if(CMAKE_BUILD_TYPE MATCHES debug)
     list(APPEND schema_tests test_extensions)
 endif(CMAKE_BUILD_TYPE MATCHES debug)
diff --git a/tests/schema/test_invalid.c b/tests/schema/test_invalid.c
new file mode 100644
index 0000000..7c02d2c
--- /dev/null
+++ b/tests/schema/test_invalid.c
@@ -0,0 +1,93 @@
+/**
+ * \file test_invalid.c
+ * \author Michal Vasko <mvasko@cesnet.cz>
+ * \brief libyang tests - loading invalid schemas
+ *
+ * Copyright (c) 2018 CESNET, z.s.p.o.
+ *
+ * This source code is licensed under BSD 3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <setjmp.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <cmocka.h>
+
+#include "libyang.h"
+#include "tests/config.h"
+
+struct state {
+    struct ly_ctx *ctx;
+};
+
+static int
+setup_ctx(void **state)
+{
+    struct state *st;
+    (*state) = st = calloc(1, sizeof *st);
+    if (!st) {
+        fprintf(stderr, "Memory allocation error");
+        return -1;
+    }
+
+    /* libyang context */
+    st->ctx = ly_ctx_new(NULL, 0);
+    if (!st->ctx) {
+        fprintf(stderr, "Failed to create context.\n");
+        goto error;
+    }
+
+    return 0;
+
+error:
+    ly_ctx_destroy(st->ctx, NULL);
+    free(st);
+    (*state) = NULL;
+
+    return -1;
+}
+
+static int
+teardown_ctx(void **state)
+{
+    struct state *st = (*state);
+
+    ly_ctx_destroy(st->ctx, NULL);
+    free(st);
+    (*state) = NULL;
+
+    return 0;
+}
+
+static void
+test_case_act_notif(void **state)
+{
+    const char *schema = TESTS_DIR"/schema/yang/files/case-act-notif.yang";
+    struct state *st = (*state);
+    const struct lys_module *mod;
+
+    mod = lys_parse_path(st->ctx, schema, LYS_IN_YANG);
+    assert_ptr_equal(mod, NULL);
+}
+
+int
+main(void)
+{
+    const struct CMUnitTest cmut[] = {
+        cmocka_unit_test_setup_teardown(test_case_act_notif, setup_ctx, teardown_ctx),
+    };
+
+    return cmocka_run_group_tests(cmut, NULL, NULL);
+}
diff --git a/tests/schema/yang/files/case-act-notif.yang b/tests/schema/yang/files/case-act-notif.yang
new file mode 100644
index 0000000..cc4dcf2
--- /dev/null
+++ b/tests/schema/yang/files/case-act-notif.yang
@@ -0,0 +1,23 @@
+module case-act-notif {
+    yang-version 1.1;
+    namespace uri:test:case-act-notif;
+    prefix can;
+
+    choice c {
+        case a {
+            leaf aa {
+                type empty;
+            }
+            uses g1;
+            uses g2;
+        }
+    }
+
+    grouping g1 {
+        action act;
+    }
+
+    grouping g2 {
+        notification notif;
+    }
+}