schema tree CHANGE remove compiled ext defs arrays
They are now only parsed or additionally referenced
only from extension instances.
diff --git a/src/tree_schema.c b/src/tree_schema.c
index b1a662e..350201a 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -802,9 +802,8 @@
}
if (!mod->implemented) {
- /* pre-compile features and extension definitions of the module */
+ /* pre-compile features of the module */
LY_CHECK_GOTO(lys_feature_precompile(NULL, ctx, mod, mod->parsed->features, &mod->off_features), error);
- LY_CHECK_GOTO(lys_extension_precompile(NULL, ctx, mod, mod->parsed->extensions, &mod->off_extensions), error);
}
if (latest) {
@@ -836,9 +835,8 @@
goto error_ctx;
}
if (!mod->implemented) {
- /* pre-compile features and extension definitions of the module */
+ /* pre-compile features of the submodule */
LY_CHECK_GOTO(lys_feature_precompile(NULL, ctx, mod, inc->submodule->features, &mod->off_features), error);
- LY_CHECK_GOTO(lys_extension_precompile(NULL, ctx, mod, mod->parsed->extensions, &mod->off_extensions), error);
}
}
mod->parsed->parsing = 0;
diff --git a/src/tree_schema.h b/src/tree_schema.h
index ace3bfd..855a1bf 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -371,6 +371,8 @@
const char *ref; /**< reference statement */
struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
uint16_t flags; /**< LYS_STATUS_* and LYS_YINELEM_* values (@ref snodeflags) */
+
+ struct lysc_ext *compiled; /**< pointer to the compiled extension definition */
};
/**
@@ -1645,7 +1647,6 @@
struct lysc_node *data; /**< list of module's top-level data nodes (linked list) */
struct lysc_action *rpcs; /**< list of RPCs ([sized array](@ref sizedarrays)) */
struct lysc_notif *notifs; /**< list of notifications ([sized array](@ref sizedarrays)) */
- struct lysc_ext **extensions; /**< list of pointers to extension definitions ([sized array](@ref sizedarrays)) */
struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
};
@@ -1777,12 +1778,6 @@
from if-feature statements of the compiled schemas and their proper use in case
the module became implemented in future (no matter if implicitly via augment/deviate
or explicitly via ly_ctx_module_implement()). */
- struct lysc_ext **off_extensions;/**< List of pointers to pre-compiled extension definitions of the module in non-implemented modules
- ([sized array](@ref sizedarrays)). These extensions are prepared to be linked with the extension instances,
- but they are not implemented (connected with any extension plugin). In case the module become
- implemented, the list is moved into the compiled module structure and available extension plugins
- are connected with the appropriate extension definision. */
-
uint8_t implemented; /**< flag if the module is implemented, not just imported. The module is implemented if
the flag has non-zero value. Specific values are used internally:
1 - implemented module
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 61f4a19..a9649e3 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -33,6 +33,9 @@
#include "tree_schema_internal.h"
#include "xpath.h"
+static LY_ERR lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext,
+ void *parent, LYEXT_PARENT parent_type, const struct lys_module *ext_mod);
+
/**
* @brief Duplicate string into dictionary
* @param[in] CTX libyang context of the dictionary.
@@ -442,6 +445,39 @@
}
/**
+ * @brief Fill in the prepared compiled extensions definition structure according to the parsed extension definition.
+ */
+static LY_ERR
+lys_compile_extension(struct lysc_ctx *ctx, const struct lys_module *ext_mod, struct lysp_ext *ext_p, struct lysc_ext **ext)
+{
+ LY_ERR ret = LY_SUCCESS;
+
+ if (!ext_p->compiled) {
+ lysc_update_path(ctx, NULL, "{extension}");
+ lysc_update_path(ctx, NULL, ext_p->name);
+
+ /* compile the extension definition */
+ ext_p->compiled = calloc(1, sizeof **ext);
+ ext_p->compiled->refcount = 1;
+ DUP_STRING(ctx->ctx, ext_p->name, ext_p->compiled->name);
+ DUP_STRING(ctx->ctx, ext_p->argument, ext_p->compiled->argument);
+ ext_p->compiled->module = (struct lys_module *)ext_mod;
+ COMPILE_EXTS_GOTO(ctx, ext_p->exts, ext_p->compiled->exts, *ext, LYEXT_PAR_EXT, ret, done);
+
+ lysc_update_path(ctx, NULL, NULL);
+ lysc_update_path(ctx, NULL, NULL);
+
+ /* find extension definition plugin */
+ ext_p->compiled->plugin = lyext_get_plugin(ext_p->compiled);
+ }
+
+ *ext = lysc_ext_dup(ext_p->compiled);
+
+done:
+ return ret;
+}
+
+/**
* @brief Fill in the prepared compiled extension instance structure according to the parsed extension instance.
*
* @param[in] ctx Compilation context.
@@ -458,7 +494,6 @@
LY_ERR ret = LY_EVALID;
const char *name;
unsigned int u;
- struct lysc_ext **elist = NULL;
const char *prefixed_name = NULL;
DUP_STRING(ctx->ctx, ext_p->argument, ext->argument);
@@ -516,15 +551,11 @@
}
name = &prefixed_name[u];
- /* find the extension definition there */
- if (ext_mod->off_extensions) {
- elist = ext_mod->off_extensions;
- } else {
- elist = ext_mod->compiled->extensions;
- }
- LY_ARRAY_FOR(elist, u) {
- if (!strcmp(name, elist[u]->name)) {
- ext->def = lysc_ext_dup(elist[u]);
+ /* find the parsed extension definition there */
+ LY_ARRAY_FOR(ext_mod->parsed->extensions, u) {
+ if (!strcmp(name, ext_mod->parsed->extensions[u].name)) {
+ /* compile extension definition and assign it */
+ LY_CHECK_RET(lys_compile_extension(ctx, ext_mod, &ext_mod->parsed->extensions[u], &ext->def));
break;
}
}
@@ -601,82 +632,6 @@
}
/**
- * @brief Fill in the prepared compiled extensions definition structure according to the parsed extension definition.
- */
-static LY_ERR
-lys_compile_extension(struct lysc_ctx *ctx, struct lysp_ext *ext_p, struct lysc_ext **ext)
-{
- LY_ERR ret = LY_SUCCESS;
-
- *ext = calloc(1, sizeof **ext);
- (*ext)->refcount = 1;
- DUP_STRING(ctx->ctx, ext_p->name, (*ext)->name);
- DUP_STRING(ctx->ctx, ext_p->argument, (*ext)->argument);
- (*ext)->module = ctx->mod_def;
- COMPILE_EXTS_GOTO(ctx, ext_p->exts, (*ext)->exts, *ext, LYEXT_PAR_EXT, ret, done);
-
-done:
- return ret;
-}
-
-/**
- * @brief Link the extensions definitions with the available extension plugins.
- *
- * This is done only in the compiled (implemented) module. Extensions of a non-implemented modules
- * are not connected with even available extension plugins.
- *
- * @param[in] extensions List of pointers to extensions to be processed ([sized array](@ref sizedarrays)).
- */
-static void
-lys_compile_extension_plugins(struct lysc_ext **extensions)
-{
- unsigned int u;
-
- LY_ARRAY_FOR(extensions, u) {
- extensions[u]->plugin = lyext_get_plugin(extensions[u]);
- }
-}
-
-LY_ERR
-lys_extension_precompile(struct lysc_ctx *ctx_sc, struct ly_ctx *ctx, struct lys_module *module,
- struct lysp_ext *extensions_p, struct lysc_ext ***extensions)
-{
- unsigned int offset = 0, u;
- struct lysc_ctx context = {0};
-
- assert(ctx_sc || ctx);
-
- if (!ctx_sc) {
- context.ctx = ctx;
- context.mod = module;
- context.mod_def = module;
- context.path_len = 1;
- context.path[0] = '/';
- ctx_sc = &context;
- }
-
- if (!extensions_p) {
- return LY_SUCCESS;
- }
- if (*extensions) {
- offset = LY_ARRAY_SIZE(*extensions);
- }
-
- lysc_update_path(ctx_sc, NULL, "{extension}");
- LY_ARRAY_CREATE_RET(ctx_sc->ctx, *extensions, LY_ARRAY_SIZE(extensions_p), LY_EMEM);
- LY_ARRAY_FOR(extensions_p, u) {
- lysc_update_path(ctx_sc, NULL, extensions_p[u].name);
- LY_ARRAY_INCREMENT(*extensions);
- LY_CHECK_RET(lys_compile_extension(ctx_sc, &extensions_p[u], &(*extensions)[offset + u]));
- COMPILE_CHECK_UNIQUENESS_PARRAY(ctx_sc, *extensions, name, &(*extensions)[offset + u], "extension", extensions_p[u].name);
- lysc_update_path(ctx_sc, NULL, NULL);
- }
- lysc_update_path(ctx_sc, NULL, NULL);
-
- return LY_SUCCESS;
-}
-
-/**
* @brief Compile information from the if-feature statement
* @param[in] ctx Compile context.
* @param[in] value The if-feature argument to process. It is pointer-to-pointer-to-char just to unify the compile functions.
@@ -6836,11 +6791,6 @@
ret = lys_feature_precompile(ctx, NULL, NULL, submod->features, &mainmod->features);
LY_CHECK_GOTO(ret, error);
}
- if (!mainmod->mod->off_extensions) {
- /* extensions are compiled directly into the compiled module structure, compilation is finished in the main module (lys_compile()). */
- ret = lys_extension_precompile(ctx, NULL, NULL, submod->extensions, &mainmod->extensions);
- LY_CHECK_GOTO(ret, error);
- }
lysc_update_path(ctx, NULL, "{identity}");
COMPILE_ARRAY_UNIQUE_GOTO(ctx, submod->identities, mainmod->identities, u, lys_compile_identity, ret, error);
@@ -7328,20 +7278,6 @@
}
lysc_update_path(&ctx, NULL, NULL);
- /* extensions */
- /* 2-steps: a) prepare compiled structures and ... */
- if (mod->off_extensions) {
- /* there is already precompiled array of extension definitions */
- mod_c->extensions = mod->off_extensions;
- mod->off_extensions = NULL;
- } else {
- /* extension definitions are compiled directly into the compiled module structure */
- ret = lys_extension_precompile(&ctx, NULL, NULL, sp->extensions, &mod_c->extensions);
- LY_CHECK_GOTO(ret, error);
- }
- /* ... b) connect the extension definitions with the appropriate extension plugins */
- lys_compile_extension_plugins(mod_c->extensions);
-
/* identities */
lysc_update_path(&ctx, NULL, "{identity}");
COMPILE_ARRAY_UNIQUE_GOTO(&ctx, sp->identities, mod_c->identities, u, lys_compile_identity, ret, error);
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index deaf20c..79d46ba 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -25,6 +25,7 @@
void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
+void lysc_extension_free(struct ly_ctx *ctx, struct lysc_ext **ext);
static void
lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
@@ -93,6 +94,9 @@
FREE_STRING(ctx, ext->dsc);
FREE_STRING(ctx, ext->ref);
FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
+ if (ext->compiled) {
+ lysc_extension_free(ctx, &ext->compiled);
+ }
}
void
@@ -837,8 +841,6 @@
}
FREE_ARRAY(ctx, module->rpcs, lysc_action_free);
FREE_ARRAY(ctx, module->notifs, lysc_notif_free);
-
- FREE_ARRAY(ctx, module->extensions, lysc_extension_free);
FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
free(module);
@@ -864,7 +866,6 @@
lysc_module_free(module->compiled, private_destructor);
FREE_ARRAY(module->ctx, module->off_features, lysc_feature_free);
- FREE_ARRAY(module->ctx, module->off_extensions, lysc_extension_free);
lysp_module_free(module->parsed);
FREE_STRING(module->ctx, module->name);
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 5efbb1e..457a596 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -674,21 +674,6 @@
const struct lysc_node **target);
/**
- * @brief Internal wrapper around lys_compile_extension() to be able to prepare list of compiled extension definitions
- * even for the parsed (not-implemented) module - see lys_module::off_extensions.
- *
- * @param[in] ctx_sc Compile context - alternative to the combination of @p ctx and @p module.
- * @param[in] ctx libyang context.
- * @param[in] module Module of the extensions.
- * @param[in] extensions_p Array of the parsed extension definitions to precompile.
- * @param[in,out] extensions Pointer to the storage of the (pre)compiled extensions array where the new extensions are
- * supposed to be added. The storage is supposed to be initiated to NULL when the first parsed extensions are going
- * to be processed.
- * @return LY_ERR value.
- */
-LY_ERR lys_extension_precompile(struct lysc_ctx *ctx_sc, struct ly_ctx *ctx, struct lys_module *module,
- struct lysp_ext *extensions_p, struct lysc_ext ***extensions);
-/**
* @brief Macro to free [sized array](@ref sizedarrays) of items using the provided free function. The ARRAY itself is also freed,
* but the memory is not sanitized.
*/