context UPDATE run-time plugin support (#2213)
* Adding context based extensions plugins support
This patch adds ability to load plugins directly from memory without
need to create shared library by using lyplg_add_plugin() API.
It also allows to associate plugin directly with context, so given
plugin will not affect all contexts, just given context
* Refactored based on PR comments
diff --git a/src/context.c b/src/context.c
index e023f31..307dde7 100644
--- a/src/context.c
+++ b/src/context.c
@@ -1384,7 +1384,11 @@
/* LYB hash lock */
pthread_mutex_destroy(&ctx->lyb_hash_lock);
- /* plugins - will be removed only if this is the last context */
+ /* context specific plugins */
+ ly_set_erase(&ctx->plugins_types, NULL);
+ ly_set_erase(&ctx->plugins_extensions, NULL);
+
+ /* shared plugins - will be removed only if this is the last context */
lyplg_clean();
free(ctx);
diff --git a/src/ly_common.h b/src/ly_common.h
index 00ac506..ec0d3ea 100644
--- a/src/ly_common.h
+++ b/src/ly_common.h
@@ -356,6 +356,8 @@
struct ly_ht *err_ht; /**< hash table of thread-specific list of errors related to the context */
pthread_mutex_t lyb_hash_lock; /**< lock for storing LYB schema hashes in schema nodes */
struct ly_ht *leafref_links_ht; /**< hash table of leafref links between term data nodes */
+ struct ly_set plugins_types; /**< context specific set of type plugins */
+ struct ly_set plugins_extensions; /**< contets specific set of extension plugins */
};
/**
diff --git a/src/plugins.c b/src/plugins.c
index ab264f0..87273fa 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -130,21 +130,22 @@
/**
* @brief Iterate over list of loaded plugins of the given @p type.
*
+ * @param[in] ctx The context for which the plugin is searched for
* @param[in] type Type of the plugins to iterate.
* @param[in,out] index The iterator - set to 0 for the first call.
* @return The plugin records, NULL if no more record is available.
*/
static struct lyplg_record *
-plugins_iter(enum LYPLG type, uint32_t *index)
+plugins_iter(const struct ly_ctx *ctx, enum LYPLG type, uint32_t *index)
{
- struct ly_set *plugins;
+ const struct ly_set *plugins;
assert(index);
if (type == LYPLG_EXTENSION) {
- plugins = &plugins_extensions;
+ plugins = ctx ? &ctx->plugins_extensions : &plugins_extensions;
} else {
- plugins = &plugins_types;
+ plugins = ctx ? &ctx->plugins_types : &plugins_types;
}
if (*index == plugins->count) {
@@ -156,7 +157,7 @@
}
static void *
-lyplg_record_find(enum LYPLG type, const char *module, const char *revision, const char *name)
+lyplg_record_find(const struct ly_ctx *ctx, enum LYPLG type, const char *module, const char *revision, const char *name)
{
uint32_t i = 0;
struct lyplg_record *item;
@@ -164,7 +165,7 @@
assert(module);
assert(name);
- while ((item = plugins_iter(type, &i)) != NULL) {
+ while ((item = plugins_iter(ctx, type, &i)) != NULL) {
if (!strcmp(item->module, module) && !strcmp(item->name, name)) {
if (item->revision && revision && strcmp(item->revision, revision)) {
continue;
@@ -180,23 +181,47 @@
}
struct lyplg_type *
-lyplg_type_plugin_find(const char *module, const char *revision, const char *name)
+lyplg_type_plugin_find(const struct ly_ctx *ctx, const char *module, const char *revision, const char *name)
{
- struct lyplg_record *record;
+ struct lyplg_record *record = NULL;
- record = lyplg_record_find(LYPLG_TYPE, module, revision, name);
+ if (ctx) {
+ /* try to find context specific plugin */
+ record = lyplg_record_find(ctx, LYPLG_TYPE, module, revision, name);
+ }
+
+ if (!record) {
+ /* try to find shared plugin */
+ record = lyplg_record_find(NULL, LYPLG_TYPE, module, revision, name);
+ }
+
return record ? &((struct lyplg_type_record *)record)->plugin : NULL;
}
struct lyplg_ext_record *
-lyplg_ext_record_find(const char *module, const char *revision, const char *name)
+lyplg_ext_record_find(const struct ly_ctx *ctx, const char *module, const char *revision, const char *name)
{
- return lyplg_record_find(LYPLG_EXTENSION, module, revision, name);
+ struct lyplg_ext_record *record = NULL;
+
+ if (ctx) {
+ /* try to find context specific plugin */
+ record = lyplg_record_find(ctx, LYPLG_EXTENSION, module, revision, name);
+ }
+
+ if (!record) {
+ /* try to find shared plugin */
+ record = lyplg_record_find(NULL, LYPLG_EXTENSION, module, revision, name);
+ }
+
+ return record;
}
/**
* @brief Insert the provided extension plugin records into the internal set of extension plugins for use by libyang.
*
+ * @param[in] ctx The context to which the plugin should be associated with. If NULL, the plugin is considered to be shared
+ * between all existing contexts.
+ * @param[in] type The type of plugins records
* @param[in] recs An array of plugin records provided by the plugin implementation. The array must be terminated by a zeroed
* record.
* @return LY_SUCCESS in case of success
@@ -204,8 +229,10 @@
* @return LY_EMEM in case of memory allocation failure.
*/
static LY_ERR
-plugins_insert(enum LYPLG type, const void *recs)
+plugins_insert(struct ly_ctx *ctx, enum LYPLG type, const void *recs)
{
+ struct ly_set *plugins;
+
if (!recs) {
return LY_SUCCESS;
}
@@ -213,14 +240,18 @@
if (type == LYPLG_EXTENSION) {
const struct lyplg_ext_record *rec = (const struct lyplg_ext_record *)recs;
+ plugins = ctx ? &ctx->plugins_extensions : &plugins_extensions;
+
for (uint32_t i = 0; rec[i].name; i++) {
- LY_CHECK_RET(ly_set_add(&plugins_extensions, (void *)&rec[i], 0, NULL));
+ LY_CHECK_RET(ly_set_add(plugins, (void *)&rec[i], 0, NULL));
}
} else { /* LYPLG_TYPE */
const struct lyplg_type_record *rec = (const struct lyplg_type_record *)recs;
+ plugins = ctx ? &ctx->plugins_types : &plugins_types;
+
for (uint32_t i = 0; rec[i].name; i++) {
- LY_CHECK_RET(ly_set_add(&plugins_types, (void *)&rec[i], 0, NULL));
+ LY_CHECK_RET(ly_set_add(plugins, (void *)&rec[i], 0, NULL));
}
}
@@ -329,7 +360,7 @@
}
/* ... and load all the types plugins */
- LY_CHECK_RET(plugins_insert(type, plugins));
+ LY_CHECK_RET(plugins_insert(NULL, type, plugins));
}
return LY_SUCCESS;
@@ -457,48 +488,48 @@
}
/* internal types */
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_binary), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_bits), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_boolean), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_decimal64), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_empty), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_enumeration), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_identityref), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_instanceid), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_integer), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_leafref), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_string), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_union), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_binary), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_bits), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_boolean), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_decimal64), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_empty), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_enumeration), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_identityref), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_instanceid), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_integer), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_leafref), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_string), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_union), error);
if (!builtin_type_plugins_only) {
/* yang */
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_instanceid_keys), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_instanceid_keys), error);
/* ietf-inet-types */
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_ipv4_address), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_ipv4_address_no_zone), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_ipv6_address), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_ipv6_address_no_zone), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_ipv4_prefix), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_ipv6_prefix), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_ipv4_address), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_ipv4_address_no_zone), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_ipv6_address), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_ipv6_address_no_zone), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_ipv4_prefix), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_ipv6_prefix), error);
/* ietf-yang-types */
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_date_and_time), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_hex_string), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_xpath10), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_date_and_time), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_hex_string), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_xpath10), error);
/* ietf-netconf-acm */
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_node_instanceid), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_node_instanceid), error);
/* lyds_tree */
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_TYPE, plugins_lyds_tree), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_lyds_tree), error);
/* internal extensions */
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_metadata), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_nacm), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_yangdata), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_schema_mount), error);
- LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_structure), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_metadata), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_nacm), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_yangdata), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_schema_mount), error);
+ LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_structure), error);
}
#ifndef STATIC
@@ -562,3 +593,60 @@
return ret;
#endif
}
+
+/**
+ * @brief Manually load an extension plugins from memory
+ *
+ * Note, that a plugin can be loaded only if there is at least one context. The loaded plugins are connected with the
+ * existence of a context. When all the contexts are destroyed, all the plugins are unloaded.
+ *
+ * @param[in] ctx The context to which the plugin should be associated with. If NULL, the plugin is considered to be shared
+ * between all existing contexts.
+ * @param[in] version The version of plugin records.
+ * @param[in] type The type of plugins records.
+ * @param[in] recs An array of plugin records provided by the plugin implementation. The array must be terminated by a zeroed
+ * record.
+ *
+ * @return LY_SUCCESS if the plugins with compatible version were successfully loaded.
+ * @return LY_EDENIED in case there is no context and the plugin cannot be loaded.
+ * @return LY_EINVAL when recs is NULL or the plugin contains invalid content for this libyang version.
+ */
+static LY_ERR
+lyplg_add_plugin(struct ly_ctx *ctx, uint32_t version, enum LYPLG type, const void *recs)
+{
+ LY_ERR ret = LY_SUCCESS;
+
+ LY_CHECK_ARG_RET(NULL, recs, LY_EINVAL);
+
+ if (version != plugins_load_info[type].apiver) {
+ LOGERR(ctx, LY_EINVAL, "Adding user %s plugin failed, wrong API version - %d expected, %d found.",
+ plugins_load_info[type].id, plugins_load_info[type].apiver, version);
+ return LY_EINVAL;
+ }
+
+ /* works only in case a context exists */
+ pthread_mutex_lock(&plugins_guard);
+ if (!context_refcount) {
+ /* no context */
+ pthread_mutex_unlock(&plugins_guard);
+ LOGERR(NULL, LY_EDENIED, "To add a plugin, at least one context must exists.");
+ return LY_EDENIED;
+ }
+
+ plugins_insert(ctx, type, recs);
+ pthread_mutex_unlock(&plugins_guard);
+
+ return ret;
+}
+
+LIBYANG_API_DEF LY_ERR
+lyplg_add_extension_plugin(struct ly_ctx *ctx, uint32_t version, const struct lyplg_ext_record *recs)
+{
+ return lyplg_add_plugin(ctx, version, LYPLG_EXTENSION, recs);
+}
+
+LIBYANG_API_DEF LY_ERR
+lyplg_add_type_plugin(struct ly_ctx *ctx, uint32_t version, const struct lyplg_type_record *recs)
+{
+ return lyplg_add_plugin(ctx, version, LYPLG_TYPE, recs);
+}
diff --git a/src/plugins.h b/src/plugins.h
index f868879..3ffc7cf 100644
--- a/src/plugins.h
+++ b/src/plugins.h
@@ -17,6 +17,9 @@
#include "log.h"
+struct lyplg_ext_record;
+struct lyplg_type_record;
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -85,6 +88,41 @@
*/
LIBYANG_API_DECL LY_ERR lyplg_add(const char *pathname);
+/**
+ * @brief Manually load extension plugins from memory
+ *
+ * Note, that a plugin can be loaded only if there is at least one context. The loaded plugins are connected with the
+ * existence of a context. When all the contexts are destroyed, all the plugins are unloaded.
+ *
+ * @param[in] ctx The context to which the plugin should be associated with. If NULL, the plugin is considered to be shared
+ * between all existing contexts.
+ * @param[in] version The version of plugin records.
+ * @param[in] recs An array of plugin records provided by the plugin implementation. The array must be terminated by a zeroed
+ * record.
+ *
+ * @return LY_SUCCESS if the plugins with compatible version were successfully loaded.
+ * @return LY_EDENIED in case there is no context and the plugin cannot be loaded.
+ * @return LY_EINVAL when recs is NULL or the plugin contains invalid content for this libyang version.
+ */
+LIBYANG_API_DECL LY_ERR lyplg_add_extension_plugin(struct ly_ctx *ctx, uint32_t version, const struct lyplg_ext_record *recs);
+
+/**
+ * @brief Manually load type plugins from memory
+ *
+ * Note, that a plugin can be loaded only if there is at least one context. The loaded plugins are connected with the
+ * existence of a context. When all the contexts are destroyed, all the plugins are unloaded.
+ *
+ * @param[in] ctx The context to which the plugin should be associated with. If NULL, the plugin is considered to be shared
+ * between all existing contexts.
+ * @param[in] version The version of plugin records.
+ * @param[in] recs An array of plugin records provided by the plugin implementation. The array must be terminated by a zeroed
+ * record.
+ *
+ * @return LY_SUCCESS if the plugins with compatible version were successfully loaded.
+ * @return LY_EDENIED in case there is no context and the plugin cannot be loaded.
+ * @return LY_EINVAL when recs is NULL or the plugin contains invalid content for this libyang version.
+ */
+LIBYANG_API_DECL LY_ERR lyplg_add_type_plugin(struct ly_ctx *ctx, uint32_t version, const struct lyplg_type_record *recs);
/** @} plugins */
#ifdef __cplusplus
diff --git a/src/plugins_internal.h b/src/plugins_internal.h
index 59adacf..2ba54f1 100644
--- a/src/plugins_internal.h
+++ b/src/plugins_internal.h
@@ -63,6 +63,7 @@
/**
* @brief Find a type plugin.
*
+ * @param[in] ctx The optional context for which the plugin should be find. If NULL, only shared plugins will be searched
* @param[in] module Name of the module where the type is defined. Must not be NULL, in case of plugins for
* built-in types, the module is "".
* @param[in] revision Revision of the module for which the plugin is implemented. NULL is not a wildcard, it matches
@@ -70,17 +71,18 @@
* @param[in] name Name of the type which the plugin implements.
* @return Found type plugin, NULL if none found.
*/
-struct lyplg_type *lyplg_type_plugin_find(const char *module, const char *revision, const char *name);
+struct lyplg_type *lyplg_type_plugin_find(const struct ly_ctx *ctx, const char *module, const char *revision, const char *name);
/**
* @brief Find an extension plugin.
*
+ * @param[in] ctx The optional context for which the plugin should be find. If NULL, only shared plugins will be searched
* @param[in] module Name of the module where the extension is defined.
* @param[in] revision Revision of the module for which the plugin is implemented. NULL is not a wildcard, it matches
* only the plugins with NULL revision specified.
* @param[in] name Name of the extension which the plugin implements.
* @return Found extension record, NULL if none found.
*/
-struct lyplg_ext_record *lyplg_ext_record_find(const char *module, const char *revision, const char *name);
+struct lyplg_ext_record *lyplg_ext_record_find(const struct ly_ctx *ctx, const char *module, const char *revision, const char *name);
#endif /* LY_PLUGINS_INTERNAL_H_ */
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 4187575..53e1bed 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -2263,7 +2263,7 @@
}
/* try to find loaded user type plugins */
- plugin = lyplg_type_plugin_find(tctx->tpdf->type.pmod->mod->name, tctx->tpdf->type.pmod->mod->revision,
+ plugin = lyplg_type_plugin_find(ctx->ctx, tctx->tpdf->type.pmod->mod->name, tctx->tpdf->type.pmod->mod->revision,
tctx->tpdf->name);
if (!plugin && base) {
/* use the base type implementation if available */
@@ -2271,7 +2271,7 @@
}
if (!plugin) {
/* use the internal built-in type implementation */
- plugin = lyplg_type_plugin_find("", NULL, ly_data_type2str[basetype]);
+ plugin = lyplg_type_plugin_find(ctx->ctx, "", NULL, ly_data_type2str[basetype]);
}
assert(plugin);
@@ -2312,7 +2312,7 @@
/* process the type definition in leaf */
if (type_p->flags || type_p->exts || !base || (basetype == LY_TYPE_LEAFREF)) {
/* leaf type has changes that need to be compiled into the type */
- plugin = base ? base->plugin : lyplg_type_plugin_find("", NULL, ly_data_type2str[basetype]);
+ plugin = base ? base->plugin : lyplg_type_plugin_find(ctx->ctx, "", NULL, ly_data_type2str[basetype]);
ret = lys_compile_type_(ctx, context_pnode, context_flags, context_name, (struct lysp_type *)type_p, basetype,
NULL, base, plugin, &tpdf_chain, 0, type);
LY_CHECK_GOTO(ret, cleanup);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index e8b9857..9d9d2b4 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -1362,7 +1362,7 @@
LY_CHECK_RET(lysp_ext_instance_resolve_argument(PARSER_CTX(pctx), ext));
/* find the extension record, if any */
- ext->record = lyplg_ext_record_find(mod->name, mod->revision, ext->def->name);
+ ext->record = lyplg_ext_record_find(mod->ctx, mod->name, mod->revision, ext->def->name);
}
}
diff --git a/tests/utests/basic/test_plugins.c b/tests/utests/basic/test_plugins.c
index cf2e87b..df7523a 100644
--- a/tests/utests/basic/test_plugins.c
+++ b/tests/utests/basic/test_plugins.c
@@ -54,12 +54,12 @@
leaf = (struct lysc_node_leaf *)mod->compiled->data;
assert_int_equal(LYS_LEAF, leaf->nodetype);
- assert_non_null(plugin_t = lyplg_type_plugin_find("libyang-plugins-simple", NULL, "note"));
+ assert_non_null(plugin_t = lyplg_type_plugin_find(NULL, "libyang-plugins-simple", NULL, "note"));
assert_string_equal("ly2 simple test v1", plugin_t->id);
assert_ptr_equal(leaf->type->plugin, plugin_t);
assert_int_equal(1, LY_ARRAY_COUNT(leaf->exts));
- assert_non_null(record_e = lyplg_ext_record_find("libyang-plugins-simple", NULL, "hint"));
+ assert_non_null(record_e = lyplg_ext_record_find(NULL, "libyang-plugins-simple", NULL, "hint"));
assert_string_equal("ly2 simple test v1", record_e->plugin.id);
assert_ptr_equal(leaf->exts[0].def->plugin, &record_e->plugin);
@@ -96,6 +96,49 @@
lyd_free_all(tree);
}
+static LY_ERR
+parse_clb(struct lysp_ctx *UNUSED(pctx), struct lysp_ext_instance *ext)
+{
+ struct lysp_node_leaf *leaf;
+
+ leaf = (struct lysp_node_leaf *)ext->parent;
+ leaf->flags |= LYS_STATUS_OBSLT;
+ return LY_SUCCESS;
+}
+
+struct lyplg_ext_record memory_recs[] = {
+ {
+ .module = "libyang-plugins-simple",
+ .revision = NULL,
+ .name = "hint",
+
+ .plugin.id = "memory-plugin-v1",
+ .plugin.parse = parse_clb,
+ .plugin.compile = NULL,
+ .plugin.printer_info = NULL,
+ .plugin.node = NULL,
+ .plugin.snode = NULL,
+ .plugin.validate = NULL,
+ .plugin.pfree = NULL,
+ .plugin.cfree = NULL
+ },
+ {0} /* terminating zeroed item */
+};
+
+static void
+test_simple_from_memory(void **state)
+{
+ struct lys_module *mod;
+ struct lysc_node_leaf *leaf;
+
+ lyplg_add_extension_plugin(UTEST_LYCTX, LYPLG_EXT_API_VERSION, memory_recs);
+ UTEST_ADD_MODULE(simple, LYS_IN_YANG, NULL, &mod);
+
+ leaf = (struct lysc_node_leaf *)mod->compiled->data;
+ assert_int_equal(LYS_LEAF, leaf->nodetype);
+ assert_true(leaf->flags & LYS_STATUS_OBSLT);
+}
+
int
main(void)
{
@@ -103,6 +146,7 @@
UTEST(test_add_invalid),
UTEST(test_add_simple),
UTEST(test_not_implemented),
+ UTEST(test_simple_from_memory),
};
return cmocka_run_group_tests(tests, NULL, NULL);
diff --git a/tests/utests/types/binary.c b/tests/utests/types/binary.c
index 910f756..4d0cfbc 100644
--- a/tests/utests/types/binary.c
+++ b/tests/utests/types/binary.c
@@ -51,7 +51,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value value = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BINARY]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BINARY]);
struct lysc_type *lysc_type, *lysc_type2;
LY_ERR ly_ret;
const char *schema;
@@ -250,7 +250,7 @@
struct lyd_value value = {0};
struct lys_module *mod;
struct lysc_type *lysc_type;
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BINARY]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BINARY]);
struct ly_err_item *err = NULL;
/* create schema. Prepare common used variables */
@@ -273,7 +273,7 @@
struct lyd_value value = {0}, dup;
struct lys_module *mod;
struct lysc_type *lysc_type;
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BINARY]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BINARY]);
struct ly_err_item *err = NULL;
/* create schema. Prepare common used variables */
@@ -298,7 +298,7 @@
const char *schema;
struct lys_module *mod;
struct lyd_value val1 = {0}, val2 = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BINARY]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BINARY]);
struct lysc_type *lysc_type;
struct ly_err_item *err = NULL;
diff --git a/tests/utests/types/bits.c b/tests/utests/types/bits.c
index ddf8143..3555377 100644
--- a/tests/utests/types/bits.c
+++ b/tests/utests/types/bits.c
@@ -800,7 +800,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value value = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BITS]);
struct lysc_type *lysc_type;
struct lysc_type lysc_type_test;
LY_ERR ly_ret;
@@ -894,7 +894,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BITS]);
struct lysc_type *lysc_type;
LY_ERR ly_ret;
const char *schema;
@@ -956,7 +956,7 @@
{
const char *schema;
struct lys_module *mod;
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BITS]);
struct lysc_type *lysc_type;
struct ly_err_item *err = NULL;
struct lyd_value val1 = {0}, val2 = {0};
@@ -993,7 +993,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BITS]);
struct lysc_type *lysc_type;
LY_ERR ly_ret;
const char *schema;
@@ -1035,7 +1035,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_BITS]);
struct lysc_type *lysc_type;
const char *schema;
LY_ERR ly_ret;
diff --git a/tests/utests/types/enumeration.c b/tests/utests/types/enumeration.c
index 04bbae2..0d42c54 100644
--- a/tests/utests/types/enumeration.c
+++ b/tests/utests/types/enumeration.c
@@ -94,7 +94,7 @@
const char *schema;
struct lys_module *mod;
struct lyd_value val1 = {0}, val2 = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_ENUM]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_ENUM]);
struct lysc_type *lysc_type;
struct ly_err_item *err = NULL;
diff --git a/tests/utests/types/inet_types.c b/tests/utests/types/inet_types.c
index 016d5bb..402cade 100644
--- a/tests/utests/types/inet_types.c
+++ b/tests/utests/types/inet_types.c
@@ -196,7 +196,7 @@
const char *schema;
struct lys_module *mod;
struct lyd_value val1 = {0}, val2 = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_UNION]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_UNION]);
struct lysc_type *lysc_type;
struct ly_err_item *err = NULL;
@@ -238,7 +238,7 @@
/* ipv6-address */
lysc_type = ((struct lysc_node_leaflist *)mod->compiled->data->next)->type;
- type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_STRING]);
v1 = "2008:15:0:0:0:0:feAC:1";
assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, v1, strlen(v1),
@@ -266,7 +266,7 @@
/* ipv4-address-no-zone */
lysc_type = ((struct lysc_node_leaflist *)mod->compiled->data->next->next)->type;
- type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_UNION]);
+ type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_UNION]);
v1 = "127.0.0.1";
assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, v1, strlen(v1),
0, LY_VALUE_JSON, NULL, LYD_VALHINT_STRING, NULL, &val1, NULL, &err));
@@ -281,7 +281,7 @@
/* ipv6-address-no-zone */
lysc_type = ((struct lysc_node_leaflist *)mod->compiled->data->next->next->next)->type;
- type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_STRING]);
v1 = "A:B:c:D:e:f:1:1";
assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, v1, strlen(v1),
0, LY_VALUE_JSON, NULL, LYD_VALHINT_STRING, NULL, &val1, NULL, &err));
diff --git a/tests/utests/types/int8.c b/tests/utests/types/int8.c
index d92d146..dff29ef 100644
--- a/tests/utests/types/int8.c
+++ b/tests/utests/types/int8.c
@@ -1399,7 +1399,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value value = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_INT8]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_INT8]);
struct lysc_type *lysc_type;
LY_ERR ly_ret;
char *alloc;
@@ -1546,7 +1546,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_INT8]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_INT8]);
struct lysc_type *lysc_type;
LY_ERR ly_ret;
const char *schema;
@@ -1631,7 +1631,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_INT8]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_INT8]);
struct lysc_type *lysc_type;
LY_ERR ly_ret;
const char *schema;
@@ -1671,7 +1671,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_INT8]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_INT8]);
struct lysc_type *lysc_type[2];
const char *schema;
LY_ERR ly_ret;
diff --git a/tests/utests/types/leafref.c b/tests/utests/types/leafref.c
index 1941e48..81e8ded 100644
--- a/tests/utests/types/leafref.c
+++ b/tests/utests/types/leafref.c
@@ -216,7 +216,7 @@
const char *schema;
struct lys_module *mod;
struct lyd_value val1 = {0}, val2 = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_LEAFREF]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_LEAFREF]);
struct lysc_type *lysc_type;
struct ly_err_item *err = NULL;
diff --git a/tests/utests/types/string.c b/tests/utests/types/string.c
index f5aec34..2f002b7 100644
--- a/tests/utests/types/string.c
+++ b/tests/utests/types/string.c
@@ -1060,7 +1060,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value value = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_STRING]);
struct lysc_type *lysc_type;
char *alloc_text;
unsigned int alloc_text_size;
@@ -1201,7 +1201,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_STRING]);
struct lysc_type *lysc_type;
LY_ERR ly_ret;
const char *schema;
@@ -1259,7 +1259,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_STRING]);
struct lysc_type *lysc_type;
LY_ERR ly_ret;
@@ -1298,7 +1298,7 @@
struct ly_err_item *err = NULL;
struct lys_module *mod;
struct lyd_value values[10];
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_STRING]);
struct lysc_type *lysc_type[2];
const char *schema;
LY_ERR ly_ret;
diff --git a/tests/utests/types/union.c b/tests/utests/types/union.c
index 2c378df..0d6ad21 100644
--- a/tests/utests/types/union.c
+++ b/tests/utests/types/union.c
@@ -154,7 +154,7 @@
const char *schema;
struct lys_module *mod;
struct lyd_value val1 = {0}, val2 = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_UNION]);
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_UNION]);
struct lysc_type *lysc_type;
struct ly_err_item *err = NULL;
diff --git a/tests/utests/types/yang_types.c b/tests/utests/types/yang_types.c
index 51a7c7f..42e1f32 100644
--- a/tests/utests/types/yang_types.c
+++ b/tests/utests/types/yang_types.c
@@ -235,7 +235,7 @@
const char *schema;
struct lys_module *mod;
struct lyd_value val1 = {0}, val2 = {0};
- struct lyplg_type *type = lyplg_type_plugin_find("ietf-yang-types", "2013-07-15", "date-and-time");
+ struct lyplg_type *type = lyplg_type_plugin_find(NULL, "ietf-yang-types", "2013-07-15", "date-and-time");
struct lysc_type *lysc_type;
struct ly_err_item *err = NULL;
diff --git a/tests/utests/utests.h b/tests/utests/utests.h
index 6824db4..7b8107f 100644
--- a/tests/utests/utests.h
+++ b/tests/utests/utests.h
@@ -231,7 +231,7 @@
assert_non_null(NODE); \
assert_int_equal((NODE)->basetype, TYPE); \
CHECK_ARRAY((NODE)->exts, EXTS); \
- assert_ptr_equal((NODE)->plugin, lyplg_type_plugin_find("", NULL, ly_data_type2str[TYPE]))
+ assert_ptr_equal((NODE)->plugin, lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[TYPE]))
/**
* @brief check compileted numeric type