schema compilation CHANGE partial support for types

- resolving types
- support for binary type
- support for range/length restriction of the type, but missing checking
that the derived type strictly narrows the defined range/length
diff --git a/tests/src/test_parser_yang.c b/tests/src/test_parser_yang.c
index f50e565..674ba2f 100644
--- a/tests/src/test_parser_yang.c
+++ b/tests/src/test_parser_yang.c
@@ -909,7 +909,6 @@
 test_identity(void **state)
 {
     (void) state; /* unused */
-    int dict = 1; /* magic variable for FREE macros */
 
     struct ly_parser_ctx ctx;
     struct lysp_module *mod = NULL;
@@ -960,7 +959,6 @@
 test_feature(void **state)
 {
     (void) state; /* unused */
-    int dict = 1; /* magic variable for FREE macros */
 
     struct ly_parser_ctx ctx;
     struct lysp_module *mod = NULL;
@@ -1011,7 +1009,6 @@
 test_deviation(void **state)
 {
     (void) state; /* unused */
-    int dict = 1; /* magic variable for FREE macros */
 
     struct ly_parser_ctx ctx;
     struct lysp_deviation *d = NULL;
@@ -1074,7 +1071,7 @@
     /* invalid cardinality */
 #define TEST_DUP(TYPE, MEMBER, VALUE1, VALUE2) \
     TEST_DUP_GENERIC(TYPE" {", MEMBER, VALUE1, VALUE2, parse_deviate, \
-                     &d, "1", lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL)
+                     &d, "1", lysp_deviate_free(ctx.ctx, d); free(d); d = NULL)
 
     TEST_DUP("add", "config", "true", "false");
     TEST_DUP("replace", "default", "int8", "uint8");
@@ -1089,29 +1086,29 @@
     assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
     assert_non_null(d);
     assert_string_equal(" ...", str);
-    lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL;
+    lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
     str = " add {units meters; must 1; must 2; unique x; unique y; default a; default b; config true; mandatory true; min-elements 1; max-elements 2; prefix:ext;} ...";
     assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
     assert_non_null(d);
     assert_string_equal(" ...", str);
-    lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL;
+    lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
     str = " delete {units meters; must 1; must 2; unique x; unique y; default a; default b; prefix:ext;} ...";
     assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
     assert_non_null(d);
     assert_string_equal(" ...", str);
-    lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL;
+    lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
     str = " replace {type string; units meters; default a; config true; mandatory true; min-elements 1; max-elements 2; prefix:ext;} ...";
     assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
     assert_non_null(d);
     assert_string_equal(" ...", str);
-    lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL;
+    lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
 
     /* invalid substatements */
 #define TEST_NOT_SUP(DEV, STMT, VALUE) \
     str = " "DEV" {"STMT" "VALUE";}..."; \
     assert_int_equal(LY_EVALID, parse_deviate(&ctx, &str, &d)); \
     logbuf_assert("Deviate \""DEV"\" does not support keyword \""STMT"\". Line number 1."); \
-    lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL
+    lysp_deviate_free(ctx.ctx, d); free(d); d = NULL
 
     TEST_NOT_SUP("not-supported", "units", "meters");
     TEST_NOT_SUP("not-supported", "must", "1");
@@ -1162,7 +1159,7 @@
     str = "cont {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
     assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c)); \
     logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
-    lysp_node_free(ctx.ctx, (struct lysp_node*)c, 1); c = NULL;
+    lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
 
     TEST_DUP("config", "true", "false");
     TEST_DUP("description", "text1", "text2");
@@ -1193,17 +1190,17 @@
     assert_null(c->next);
     assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR, c->flags);
     ly_set_erase(&ctx.tpdfs_nodes, NULL);
-    lysp_node_free(ctx.ctx, (struct lysp_node*)c, 1); c = NULL;
+    lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
 
     /* invalid */
     str = " cont {augment /root;} ...";
     assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
     logbuf_assert("Invalid keyword \"augment\" as a child of \"container\". Line number 1.");
-    lysp_node_free(ctx.ctx, (struct lysp_node*)c, 1); c = NULL;
+    lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
     str = " cont {nonsence true;} ...";
     assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
     logbuf_assert("Invalid character sequence \"nonsence\", expected a keyword. Line number 1.");
-    lysp_node_free(ctx.ctx, (struct lysp_node*)c, 1); c = NULL;
+    lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
 
     ly_ctx_destroy(ctx.ctx, NULL);
 }
diff --git a/tests/src/test_tree_schema_compile.c b/tests/src/test_tree_schema_compile.c
index 29ba61d..b900800 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/src/test_tree_schema_compile.c
@@ -55,6 +55,18 @@
     return 0;
 }
 
+static int
+logger_teardown(void **state)
+{
+    (void) state; /* unused */
+#if ENABLE_LOGGER_CHECKING
+    if (*state) {
+        fprintf(stderr, "%s\n", logbuf);
+    }
+#endif
+    return 0;
+}
+
 void
 logbuf_clean(void)
 {
@@ -349,13 +361,123 @@
     ly_ctx_destroy(ctx, NULL);
 }
 
+static void
+test_node_type_length_range(void **state)
+{
+    *state = test_node_type_length_range;
+
+    struct ly_ctx *ctx;
+    struct lys_module *mod;
+    struct lysc_type *type;
+
+    assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
+
+    assert_non_null(mod = lys_parse_mem(ctx, "module a {namespace urn:a;prefix a;leaf l {type binary {length min;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+    type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+    assert_non_null(type);
+    assert_non_null(((struct lysc_type_bin*)type)->length);
+    assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+    assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+    assert_int_equal(0, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+    assert_int_equal(0, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+    assert_non_null(mod = lys_parse_mem(ctx, "module b {namespace urn:b;prefix b;leaf l {type binary {length max;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+    type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+    assert_non_null(type);
+    assert_non_null(((struct lysc_type_bin*)type)->length);
+    assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+    assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+    assert_int_equal(__UINT64_C(18446744073709551615), ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+    assert_int_equal(__UINT64_C(18446744073709551615), ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+    assert_non_null(mod = lys_parse_mem(ctx, "module c {namespace urn:c;prefix c;leaf l {type binary {length min..max;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+    type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+    assert_non_null(type);
+    assert_non_null(((struct lysc_type_bin*)type)->length);
+    assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+    assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+    assert_int_equal(0, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+    assert_int_equal(__UINT64_C(18446744073709551615), ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+    assert_non_null(mod = lys_parse_mem(ctx, "module d {namespace urn:d;prefix d;leaf l {type binary {length 5;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+    type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+    assert_non_null(type);
+    assert_non_null(((struct lysc_type_bin*)type)->length);
+    assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+    assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+    assert_int_equal(5, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+    assert_int_equal(5, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+    assert_non_null(mod = lys_parse_mem(ctx, "module e {namespace urn:e;prefix e;leaf l {type binary {length 1..10;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+    type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+    assert_non_null(type);
+    assert_non_null(((struct lysc_type_bin*)type)->length);
+    assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+    assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+    assert_int_equal(1, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+    assert_int_equal(10, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+    assert_non_null(mod = lys_parse_mem(ctx, "module f {namespace urn:f;prefix f;leaf l {type binary {length 1..10|20..30;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+    type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+    assert_non_null(type);
+    assert_non_null(((struct lysc_type_bin*)type)->length);
+    assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+    assert_int_equal(2, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+    assert_int_equal(1, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+    assert_int_equal(10, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+    assert_int_equal(20, ((struct lysc_type_bin*)type)->length->parts[1].min_u64);
+    assert_int_equal(30, ((struct lysc_type_bin*)type)->length->parts[1].max_u64);
+
+    assert_non_null(mod = lys_parse_mem(ctx, "module g {namespace urn:g;prefix g;leaf l {type binary {length \"16 | 32\";}}}", LYS_IN_YANG));
+    assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+    type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+    assert_non_null(type);
+    assert_non_null(((struct lysc_type_bin*)type)->length);
+    assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+    assert_int_equal(2, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+    assert_int_equal(16, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+    assert_int_equal(16, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+    assert_int_equal(32, ((struct lysc_type_bin*)type)->length->parts[1].min_u64);
+    assert_int_equal(32, ((struct lysc_type_bin*)type)->length->parts[1].max_u64);
+
+    /* invalid values */
+    assert_non_null(mod = lys_parse_mem(ctx, "module aa {namespace urn:aa;prefix aa;leaf l {type binary {length -10;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+    logbuf_assert("Invalid length restriction - value \"-10\" does not fit the type limitations.");
+    assert_non_null(mod = lys_parse_mem(ctx, "module bb {namespace urn:bb;prefix bb;leaf l {type binary {length 18446744073709551616;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+    logbuf_assert("Invalid length restriction - invalid value \"18446744073709551616\".");
+    assert_non_null(mod = lys_parse_mem(ctx, "module cc {namespace urn:cc;prefix cc;leaf l {type binary {length \"max .. 10\";}}}", LYS_IN_YANG));
+    assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+    logbuf_assert("Invalid length restriction - unexpected data after max keyword (.. 10).");
+    assert_non_null(mod = lys_parse_mem(ctx, "module dd {namespace urn:dd;prefix dd;leaf l {type binary {length 50..10;}}}", LYS_IN_YANG));
+    assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+    logbuf_assert("Invalid length restriction - values are not in ascending order (10).");
+    assert_non_null(mod = lys_parse_mem(ctx, "module ee {namespace urn:ee;prefix ee;leaf l {type binary {length \"50 | 10\";}}}", LYS_IN_YANG));
+    assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+    logbuf_assert("Invalid length restriction - values are not in ascending order (10).");
+    assert_non_null(mod = lys_parse_mem(ctx, "module ff {namespace urn:ff;prefix ff;leaf l {type binary {length \"x\";}}}", LYS_IN_YANG));
+    assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+    logbuf_assert("Invalid length restriction - unexpected data (x).");
+
+    *state = NULL;
+    ly_ctx_destroy(ctx, NULL);
+}
+
 int main(void)
 {
     const struct CMUnitTest tests[] = {
-        cmocka_unit_test_setup(test_module, logger_setup),
-        cmocka_unit_test_setup(test_feature, logger_setup),
-        cmocka_unit_test_setup(test_identity, logger_setup),
-        cmocka_unit_test_setup(test_node_container, logger_setup),
+        cmocka_unit_test_setup_teardown(test_module, logger_setup, logger_teardown),
+        cmocka_unit_test_setup_teardown(test_feature, logger_setup, logger_teardown),
+        cmocka_unit_test_setup_teardown(test_identity, logger_setup, logger_teardown),
+        cmocka_unit_test_setup_teardown(test_node_type_length_range, logger_setup, logger_teardown),
+        cmocka_unit_test_setup_teardown(test_node_container, logger_setup, logger_teardown),
     };
 
     return cmocka_run_group_tests(tests, NULL, NULL);