Skip to content

Commit d605c1d

Browse files
committed
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
1 parent 785fb32 commit d605c1d

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

src/schema_compile_node.c

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,7 @@ lys_compile_type_(struct lysc_ctx *ctx, struct lysp_node *context_pnode, uint16_
17651765
struct lysc_type_leafref *lref;
17661766
struct lysc_type_union *un;
17671767
struct lys_type_item *tpdf_item;
1768+
const struct lysp_type *base_type_p;
17681769
uint32_t i;
17691770

17701771
/* alloc and init */
@@ -1791,10 +1792,29 @@ lys_compile_type_(struct lysc_ctx *ctx, struct lysp_node *context_pnode, uint16_
17911792
/* RFC 7950 9.7 - bits */
17921793
bits = (struct lysc_type_bits *)*type;
17931794
if (type_p->bits) {
1795+
/* compile bits from this type */
17941796
LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, type_p->bits, basetype,
17951797
base ? (struct lysc_type_bitenum_item *)((struct lysc_type_bits *)base)->bits : NULL,
17961798
(struct lysc_type_bitenum_item **)&bits->bits), cleanup);
1797-
}
1799+
} else if (base) {
1800+
/* recompile bits from the first superior type with bits */
1801+
assert(tpdf_chain->count > tpdf_chain_last);
1802+
base_type_p = NULL;
1803+
i = tpdf_chain->count;
1804+
do {
1805+
--i;
1806+
tpdf_item = tpdf_chain->objs[i];
1807+
1808+
if (tpdf_item->tpdf->type.bits) {
1809+
base_type_p = &tpdf_item->tpdf->type;
1810+
break;
1811+
}
1812+
} while (i > tpdf_chain_last);
1813+
assert(base_type_p);
1814+
1815+
LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, base_type_p->bits, basetype, NULL,
1816+
(struct lysc_type_bitenum_item **)&bits->bits), cleanup);
1817+
} /* else error */
17981818

17991819
if (!base && !type_p->flags) {
18001820
/* type derived from bits built-in type must contain at least one bit */
@@ -1877,7 +1897,24 @@ lys_compile_type_(struct lysc_ctx *ctx, struct lysp_node *context_pnode, uint16_
18771897
if (type_p->enums) {
18781898
LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, type_p->enums, basetype,
18791899
base ? ((struct lysc_type_enum *)base)->enums : NULL, &enumeration->enums), cleanup);
1880-
}
1900+
} else if (base) {
1901+
/* recompile enums from the first superior type with enums */
1902+
assert(tpdf_chain->count > tpdf_chain_last);
1903+
base_type_p = NULL;
1904+
i = tpdf_chain->count;
1905+
do {
1906+
--i;
1907+
tpdf_item = tpdf_chain->objs[i];
1908+
1909+
if (tpdf_item->tpdf->type.enums) {
1910+
base_type_p = &tpdf_item->tpdf->type;
1911+
break;
1912+
}
1913+
} while (i > tpdf_chain_last);
1914+
assert(base_type_p);
1915+
1916+
LY_CHECK_GOTO(rc = lys_compile_type_enums(ctx, base_type_p->enums, basetype, NULL, &enumeration->enums), cleanup);
1917+
} /* else error */
18811918

18821919
if (!base && !type_p->flags) {
18831920
/* type derived from enumerations built-in type must contain at least one enum */

tests/utests/schema/test_tree_schema_compile.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,13 @@ test_type_exts(void **state)
23192319
" my-ext:shortdesc \"<A.B.C.D>\";\n"
23202320
" }\n"
23212321
" }\n"
2322+
" typedef my-enum {\n"
2323+
" type enumeration {\n"
2324+
" enum one;\n"
2325+
" enum two;\n"
2326+
" enum three;\n"
2327+
" }\n"
2328+
" }\n"
23222329
"}\n";
23232330
schema3 = "module module-a {\n"
23242331
" yang-version 1.1;\n"
@@ -2375,6 +2382,12 @@ test_type_exts(void **state)
23752382
" }\n"
23762383
" }\n"
23772384
" }\n"
2385+
"\n"
2386+
" leaf my-leaf {\n"
2387+
" type mod-inet:my-enum {\n"
2388+
" my-ext:shortdesc \"my enum\";\n"
2389+
" }\n"
2390+
" }\n"
23782391
"}\n";
23792392

23802393
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, schema1, LYS_IN_YANG, NULL));

0 commit comments

Comments
 (0)