Skip to content

Commit 3399c79

Browse files
committed
schema compile BUGFIX compile extensions of submodules
Fixes #2481
1 parent 4864e46 commit 3399c79

2 files changed

Lines changed: 107 additions & 29 deletions

File tree

src/schema_compile.c

Lines changed: 78 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,58 +1824,112 @@ lys_compile(struct lys_module *mod, struct lys_depset_unres *unres)
18241824
return ret;
18251825
}
18261826

1827-
LY_ERR
1828-
lys_compile_extensions(struct lys_module *mod)
1827+
/**
1828+
* @brief Compile all extension definitions in a parsed module into the main module.
1829+
*
1830+
* @param[in] mod Module to use.
1831+
* @param[in] pmod Parsed (sub)module to use.
1832+
* @return LY_ERR value.
1833+
*/
1834+
static LY_ERR
1835+
lys_compile_extensions_pmod(struct lys_module *mod, struct lysp_module *pmod)
18291836
{
18301837
LY_ERR rc = LY_SUCCESS;
18311838
struct lysc_ctx ctx = {0};
18321839
LY_ARRAY_COUNT_TYPE u;
18331840
struct lysp_ext *ep;
18341841
struct lysc_ext *ec;
18351842

1836-
if (!mod->parsed->extensions) {
1837-
return LY_SUCCESS;
1838-
}
1839-
1840-
LYSC_CTX_INIT_PMOD(ctx, mod->parsed, NULL);
1843+
LYSC_CTX_INIT_PMOD(ctx, pmod, NULL);
18411844

1842-
/* allocate the array */
1843-
LY_ARRAY_CREATE_RET(mod->ctx, mod->extensions, LY_ARRAY_COUNT(mod->parsed->extensions), LY_EMEM);
1845+
LY_ARRAY_FOR(pmod->extensions, u) {
1846+
ep = &pmod->extensions[u];
18441847

1845-
/* compile all extension definitions */
1846-
LY_ARRAY_FOR(mod->parsed->extensions, u) {
1847-
ep = &mod->parsed->extensions[u];
1848-
ec = &mod->extensions[u];
1848+
/* allocate a new extension */
1849+
LY_ARRAY_NEW_GOTO(mod->ctx, mod->extensions, ec, rc, cleanup);
18491850

18501851
/* compile the extension definition */
18511852
DUP_STRING_GOTO(ctx.ctx, ep->name, ec->name, rc, cleanup);
18521853
DUP_STRING_GOTO(ctx.ctx, ep->argname, ec->argname, rc, cleanup);
18531854
ec->module = mod;
18541855
ec->plugin_ref = ep->plugin_ref;
1855-
1856-
LY_ARRAY_INCREMENT(mod->extensions);
18571856
}
18581857

1859-
/* compile all nested extension instances, which can reference the compiled definitions */
1860-
LY_ARRAY_FOR(mod->parsed->extensions, u) {
1861-
ep = &mod->parsed->extensions[u];
1862-
ec = &mod->extensions[u];
1858+
cleanup:
1859+
return rc;
1860+
}
1861+
1862+
/**
1863+
* @brief Compile all ext instances of extension definitions in a parsed module.
1864+
*
1865+
* @param[in] mod Module to use.
1866+
* @param[in] mod_ext_idx Index in ext of @p mod to start at.
1867+
* @param[in] pmod Parsed (sub)module to use.
1868+
* @return LY_ERR value.
1869+
*/
1870+
static LY_ERR
1871+
lys_compile_extensions_ext_pmod(struct lys_module *mod, LY_ARRAY_COUNT_TYPE mod_ext_idx, struct lysp_module *pmod)
1872+
{
1873+
LY_ERR rc = LY_SUCCESS;
1874+
struct lysc_ctx ctx = {0};
1875+
LY_ARRAY_COUNT_TYPE u;
1876+
struct lysp_ext *ep;
1877+
struct lysc_ext *ec;
1878+
1879+
LYSC_CTX_INIT_PMOD(ctx, pmod, NULL);
1880+
1881+
LY_ARRAY_FOR(pmod->extensions, u) {
1882+
ep = &pmod->extensions[u];
1883+
ec = &mod->extensions[mod_ext_idx];
18631884

18641885
lysc_update_path(&ctx, NULL, "{extension}");
18651886
lysc_update_path(&ctx, NULL, ep->name);
18661887

18671888
/* compile nested extensions */
1868-
COMPILE_EXTS_GOTO(&ctx, ep->exts, ec->exts, ec, rc, cleanup);
1869-
1889+
COMPILE_EXTS_GOTO(&ctx, ep->exts, ec->exts, ec, rc, next_line);
1890+
next_line:
18701891
lysc_update_path(&ctx, NULL, NULL);
18711892
lysc_update_path(&ctx, NULL, NULL);
1893+
1894+
LY_CHECK_GOTO(rc, cleanup);
1895+
1896+
++mod_ext_idx;
18721897
}
18731898

18741899
cleanup:
1875-
if (rc) {
1876-
lysc_update_path(&ctx, NULL, NULL);
1877-
lysc_update_path(&ctx, NULL, NULL);
1900+
return rc;
1901+
}
1902+
1903+
LY_ERR
1904+
lys_compile_extensions(struct lys_module *mod)
1905+
{
1906+
LY_ERR rc = LY_SUCCESS;
1907+
LY_ARRAY_COUNT_TYPE u, v;
1908+
struct lysp_include *inc;
1909+
1910+
/* compile all module and submodule extension definitions */
1911+
LY_CHECK_GOTO(rc = lys_compile_extensions_pmod(mod, mod->parsed), cleanup);
1912+
LY_ARRAY_FOR(mod->parsed->includes, u) {
1913+
LY_CHECK_GOTO(rc = lys_compile_extensions_pmod(mod, (struct lysp_module *)mod->parsed->includes[u].submodule),
1914+
cleanup);
18781915
}
1916+
1917+
/* compile all nested extension instances, which can reference the compiled definitions,
1918+
* there is one extensions array in main mod for the parsed module and all submodules so we need a special index */
1919+
v = 0;
1920+
LY_CHECK_GOTO(rc = lys_compile_extensions_ext_pmod(mod, v, mod->parsed), cleanup);
1921+
1922+
v += LY_ARRAY_COUNT(mod->parsed->extensions);
1923+
LY_ARRAY_FOR(mod->parsed->includes, u) {
1924+
inc = &mod->parsed->includes[u];
1925+
LY_CHECK_GOTO(rc = lys_compile_extensions_ext_pmod(mod, v, (struct lysp_module *)inc->submodule), cleanup);
1926+
1927+
v += LY_ARRAY_COUNT(inc->submodule->extensions);
1928+
}
1929+
1930+
assert(v == LY_ARRAY_COUNT(mod->extensions));
1931+
1932+
cleanup:
18791933
return rc;
18801934
}
18811935

src/tree_schema.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,6 +1519,34 @@ lysp_resolve_ext_instance_log_path(const struct lysp_ctx *pctx, const struct lys
15191519
return LY_SUCCESS;
15201520
}
15211521

1522+
/**
1523+
* @brief Find ext instance plugins for all the parsed extensions.
1524+
*
1525+
* @param[in] mod Module to use.
1526+
*/
1527+
static void
1528+
lysp_resolve_ext_instance_plugins(struct lys_module *mod)
1529+
{
1530+
LY_ARRAY_COUNT_TYPE u, v;
1531+
const struct lysp_include *inc;
1532+
1533+
/* module */
1534+
LY_ARRAY_FOR(mod->parsed->extensions, u) {
1535+
mod->parsed->extensions[u].plugin_ref = lyplg_ext_plugin_find(mod->ctx, mod->name,
1536+
mod->revision, mod->parsed->extensions[u].name);
1537+
}
1538+
1539+
/* submodules */
1540+
LY_ARRAY_FOR(mod->parsed->includes, v) {
1541+
inc = &mod->parsed->includes[v];
1542+
1543+
LY_ARRAY_FOR(inc->submodule->extensions, u) {
1544+
inc->submodule->extensions[u].plugin_ref = lyplg_ext_plugin_find(mod->ctx, mod->name,
1545+
mod->revision, inc->submodule->extensions[u].name);
1546+
}
1547+
}
1548+
}
1549+
15221550
/**
15231551
* @brief Resolve (find) all extension instance records and finish their parsing.
15241552
*
@@ -2218,7 +2246,6 @@ lys_parse_in(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const st
22182246
struct lysp_yang_ctx *yangctx = NULL;
22192247
struct lysp_yin_ctx *yinctx = NULL;
22202248
struct lysp_ctx *pctx = NULL;
2221-
LY_ARRAY_COUNT_TYPE u;
22222249
ly_bool mod_created = 0, mod_exists = 0;
22232250

22242251
assert(ctx && in && new_mods);
@@ -2355,10 +2382,7 @@ lys_parse_in(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const st
23552382
LY_CHECK_GOTO(rc = lysp_resolve_import_include(pctx, mod->parsed, new_mods), cleanup);
23562383

23572384
/* resolve extension plugins and parse extension instances */
2358-
LY_ARRAY_FOR(mod->parsed->extensions, u) {
2359-
mod->parsed->extensions[u].plugin_ref = lyplg_ext_plugin_find(mod->ctx, mod->name,
2360-
mod->revision, mod->parsed->extensions[u].name);
2361-
}
2385+
lysp_resolve_ext_instance_plugins(mod);
23622386
LY_CHECK_GOTO(rc = lysp_resolve_ext_instance_records(pctx), cleanup);
23632387

23642388
/* check name collisions */

0 commit comments

Comments
 (0)