schema compile BUGFIX compilation of derived enum or bits type
... without specifying new enums or bits. Such a type
is recompiled in case the inherited type defines
some extensions.
Fixes #1994
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 1ed4c05..186d9a3 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -1765,6 +1765,7 @@
struct lysc_type_leafref *lref;
struct lysc_type_union *un;
struct lys_type_item *tpdf_item;
+ const struct lysp_type *base_type_p;
uint32_t i;
/* alloc and init */
@@ -1791,10 +1792,29 @@
/* RFC 7950 9.7 - bits */
bits = (struct lysc_type_bits *)*type;
if (type_p->bits) {
+ /* compile bits from this type */
LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, type_p->bits, basetype,
base ? (struct lysc_type_bitenum_item *)((struct lysc_type_bits *)base)->bits : NULL,
(struct lysc_type_bitenum_item **)&bits->bits), cleanup);
- }
+ } else if (base) {
+ /* recompile bits from the first superior type with bits */
+ assert(tpdf_chain->count > tpdf_chain_last);
+ base_type_p = NULL;
+ i = tpdf_chain->count;
+ do {
+ --i;
+ tpdf_item = tpdf_chain->objs[i];
+
+ if (tpdf_item->tpdf->type.bits) {
+ base_type_p = &tpdf_item->tpdf->type;
+ break;
+ }
+ } while (i > tpdf_chain_last);
+ assert(base_type_p);
+
+ LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, base_type_p->bits, basetype, NULL,
+ (struct lysc_type_bitenum_item **)&bits->bits), cleanup);
+ } /* else error */
if (!base && !type_p->flags) {
/* type derived from bits built-in type must contain at least one bit */
@@ -1877,7 +1897,24 @@
if (type_p->enums) {
LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, type_p->enums, basetype,
base ? ((struct lysc_type_enum *)base)->enums : NULL, &enumeration->enums), cleanup);
- }
+ } else if (base) {
+ /* recompile enums from the first superior type with enums */
+ assert(tpdf_chain->count > tpdf_chain_last);
+ base_type_p = NULL;
+ i = tpdf_chain->count;
+ do {
+ --i;
+ tpdf_item = tpdf_chain->objs[i];
+
+ if (tpdf_item->tpdf->type.enums) {
+ base_type_p = &tpdf_item->tpdf->type;
+ break;
+ }
+ } while (i > tpdf_chain_last);
+ assert(base_type_p);
+
+ LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, base_type_p->enums, basetype, NULL, &enumeration->enums), cleanup);
+ } /* else error */
if (!base && !type_p->flags) {
/* type derived from enumerations built-in type must contain at least one enum */
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index e9826cd..e4ec983 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -2319,6 +2319,13 @@
" my-ext:shortdesc \"<A.B.C.D>\";\n"
" }\n"
" }\n"
+ " typedef my-enum {\n"
+ " type enumeration {\n"
+ " enum one;\n"
+ " enum two;\n"
+ " enum three;\n"
+ " }\n"
+ " }\n"
"}\n";
schema3 = "module module-a {\n"
" yang-version 1.1;\n"
@@ -2375,6 +2382,12 @@
" }\n"
" }\n"
" }\n"
+ "\n"
+ " leaf my-leaf {\n"
+ " type mod-inet:my-enum {\n"
+ " my-ext:shortdesc \"my enum\";\n"
+ " }\n"
+ " }\n"
"}\n";
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, schema1, LYS_IN_YANG, NULL));