yin parser FEATURE support union type
diff --git a/src/parser/yin.c b/src/parser/yin.c
index a4c0f43..cc4016c 100644
--- a/src/parser/yin.c
+++ b/src/parser/yin.c
@@ -1254,8 +1254,47 @@
break;
case LY_TYPE_UNION:
- /* TODO type, 7.4
- * - 1..n, nerekurzivni, resp rekurzivni pro union ale bez vazby na predky, nesmi byt empty nebo leafref */
+ /* RFC 6020 7.4 - type */
+ /* count number of types in union */
+ i = 0;
+ LY_TREE_FOR(yin->child, node) {
+ if (!strcmp(node->name, "type")) {
+ i++;
+ } else {
+ LOGVAL(VE_INSTMT, LOGLINE(node), node->name);
+ goto error;
+ }
+ }
+
+ if (!i) {
+ if (type->der->type.der) {
+ /* this is just a derived type with no base specified/required */
+ break;
+ }
+ LOGVAL(VE_MISSSTMT2, LOGLINE(yin), "type", "(union) type");
+ goto error;
+ }
+
+ /* allocate array for union's types ... */
+ type->info.uni.type = calloc(i, sizeof *type->info.uni.type);
+ /* ... and fill the structures */
+ LY_TREE_FOR_SAFE(yin->child, next, node) {
+ if (fill_yin_type(module, parent, node, &type->info.uni.type[type->info.uni.count])) {
+ goto error;
+ }
+ type->info.uni.count++;
+
+ /* union's type cannot be empty or leafref */
+ if (type->info.uni.type[type->info.uni.count - 1].base == LY_TYPE_EMPTY) {
+ LOGVAL(VE_INARG, LOGLINE(node), "empty", node->name);
+ goto error;
+ } else if (type->info.uni.type[type->info.uni.count - 1].base == LY_TYPE_LEAFREF) {
+ LOGVAL(VE_INARG, LOGLINE(node), "leafref", node->name);
+ goto error;
+ }
+
+ lyxml_free_elem(module->ctx, node);
+ }
break;
default:
@@ -1624,7 +1663,7 @@
struct ly_mnode_leaf *leaf = NULL;
struct ly_mnode_list *list = NULL;
struct ly_type *t = NULL;
- uint8_t *trg_must_size = 0;
+ uint8_t *trg_must_size = NULL;
struct ly_restr **trg_must = NULL;
GETVAL(value, yin, "target-node");
diff --git a/src/tree.c b/src/tree.c
index d22e36d..5f9536f 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -727,6 +727,16 @@
new->info.str.patterns = ly_restr_dup(ctx, old->info.str.patterns, old->info.str.pat_count);
break;
+ case LY_TYPE_UNION:
+ new->info.uni.count = old->info.uni.count;
+ if (new->info.uni.count) {
+ new->info.uni.type = calloc(new->info.uni.count, sizeof *new->info.uni.type);
+ for (i = 0; i < new->info.uni.count; i++) {
+ ly_type_dup(ctx, &(new->info.uni.type[i]), &(old->info.uni.type[i]));
+ }
+ }
+ break;
+
default:
/* TODO - remove default to make sure that all types are covered */
break;
@@ -773,6 +783,10 @@
free(type->info.enums.list);
break;
+ case LY_TYPE_IDENT:
+ /* nothing to do */
+ break;
+
case LY_TYPE_INT8:
case LY_TYPE_INT16:
case LY_TYPE_INT32:
@@ -798,8 +812,11 @@
free(type->info.str.patterns);
break;
- case LY_TYPE_IDENT:
- /* nothing to do */
+ case LY_TYPE_UNION:
+ for (i = 0; i < type->info.uni.count; i++) {
+ ly_type_free(ctx, &type->info.uni.type[i]);
+ }
+ free(type->info.uni.type);
break;
default: