Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding ly_ctx_add_parsed_module API #2187

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 48 additions & 11 deletions src/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,17 +192,23 @@ ly_ctx_unset_searchdir_last(struct ly_ctx *ctx, uint32_t count)
return LY_SUCCESS;
}

LIBYANG_API_DEF struct lys_module *
ly_ctx_load_module(struct ly_ctx *ctx, const char *name, const char *revision, const char **features)
/**
* @brief Implements and compile the module
*
* @param[in] ctx The context holding the module
* @param[in] mod The module to implement and compile
* @param[in] features Optional array of features ended with NULL to be enabled if the module is being implemented.
* The feature string '*' enables all and array of length 1 with only the terminating NULL explicitly disables all
* the features. In case the parameter is NULL, the features are untouched - left disabled in newly loaded module or
* with the current features settings in case the module is already present in the context.
* @return Pointer to the data model structure, NULL if not found or some error occurred.
*/
static LY_ERR
_ly_ctx_implement_and_compile_module(struct ly_ctx *ctx, struct lys_module *mod, const char **features)
{
struct lys_module *mod = NULL;
LY_ERR ret = LY_SUCCESS;

LY_CHECK_ARG_RET(ctx, ctx, name, NULL);
LY_ERR ret;

/* load and parse */
ret = lys_parse_load(ctx, name, revision, &ctx->unres.creating, &mod);
LY_CHECK_GOTO(ret, cleanup);
LY_CHECK_ARG_RET(ctx, mod, LY_EINVAL);

/* implement */
ret = _lys_set_implemented(mod, features, &ctx->unres);
Expand All @@ -223,9 +229,40 @@ ly_ctx_load_module(struct ly_ctx *ctx, const char *name, const char *revision, c
if (ret) {
lys_unres_glob_revert(ctx, &ctx->unres);
lys_unres_glob_erase(&ctx->unres);
mod = NULL;
}
return mod;
return ret;
}

LIBYANG_API_DEF struct lys_module *
ly_ctx_load_module(struct ly_ctx *ctx, const char *name, const char *revision, const char **features)
{
struct lys_module *mod = NULL;
LY_ERR ret = LY_SUCCESS;

LY_CHECK_ARG_RET(ctx, ctx, name, NULL);

/* load and parse */
ret = lys_parse_load(ctx, name, revision, &ctx->unres.creating, &mod);
if (ret) {
lys_unres_glob_revert(ctx, &ctx->unres);
lys_unres_glob_erase(&ctx->unres);
return NULL;
}

ret = _ly_ctx_implement_and_compile_module(ctx, mod, features);
return ret ? NULL : mod;
}

LIBYANG_API_DEF LY_ERR
ly_ctx_add_parsed_module(struct ly_ctx *ctx, struct lys_module *mod, const char **features)
{
LY_CHECK_ARG_RET(ctx, ctx, mod, LY_EINVAL);

mod->ctx = ctx;

LY_CHECK_RET(ly_set_add(&ctx->list, mod, 1, NULL));
ctx->change_count++;
return _ly_ctx_implement_and_compile_module(ctx, mod, features);
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,23 @@ LIBYANG_API_DECL uint32_t ly_ctx_internal_modules_count(const struct ly_ctx *ctx
LIBYANG_API_DECL struct lys_module *ly_ctx_load_module(struct ly_ctx *ctx, const char *name, const char *revision,
const char **features);

/**
* @brief Adds parsed module to the context
*
* The module will be automatically implemented and optionally compiled in the same way as it would be loaded via
* ::ly_ctx_load_module. Once module is successfully added into context, context is taking over ownership of data,
* including performing data cleanup if necessary
*
* @param[in] ctx Context to add to.
* @param[in] mod The parsed module.
* @param[in] features Optional array of features ended with NULL to be enabled if the module is being implemented.
* The feature string '*' enables all and array of length 1 with only the terminating NULL explicitly disables all
* the features. In case the parameter is NULL, the features are untouched - left disabled in newly loaded module or
* with the current features settings in case the module is already present in the context.
* @return LY_ERR value
*/
LIBYANG_API_DEF LY_ERR ly_ctx_add_parsed_module(struct ly_ctx *ctx, struct lys_module *mod, const char **features);

/**
* @brief Get data of the internal ietf-yang-library module with information about all the loaded modules.
* ietf-yang-library module must be loaded.
Expand Down
42 changes: 42 additions & 0 deletions tests/utests/basic/test_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,47 @@ test_explicit_compile(void **state)
assert_non_null(mod);
}

static void
test_add_parsed_module(void **state)
{
struct lys_module *mod;

mod = calloc(1, sizeof(*mod));
assert_non_null(mod);
assert_int_equal(LY_SUCCESS, lydict_insert(UTEST_LYCTX, "module1", 0, &mod->name));
assert_int_equal(LY_SUCCESS, lydict_insert(UTEST_LYCTX, "m1", 0, &mod->prefix));
assert_int_equal(LY_SUCCESS, lydict_insert(UTEST_LYCTX, "urn:tests:m1", 0, &mod->ns));
mod->parsed = calloc(1, sizeof(*mod->parsed));
assert_non_null(mod->parsed);
mod->parsed->mod = mod;
mod->parsed->version = LYS_VERSION_1_1;

struct lysp_node_list *list_node;

list_node = calloc(1, sizeof(*list_node));
assert_non_null(list_node);
list_node->nodetype = LYS_LIST;
list_node->flags = LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM;
assert_int_equal(LY_SUCCESS, lydict_insert(UTEST_LYCTX, "list1", 0, &list_node->name));
assert_int_equal(LY_SUCCESS, lydict_insert(UTEST_LYCTX, "leaf1", 0, &list_node->key));
mod->parsed->data = (struct lysp_node *)list_node;

struct lysp_node_leaf *leaf_node;

leaf_node = calloc(1, sizeof(*leaf_node));
assert_non_null(leaf_node);
leaf_node->parent = (struct lysp_node *)list_node;
leaf_node->nodetype = LYS_LEAF;
leaf_node->flags = LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE;
assert_int_equal(LY_SUCCESS, lydict_insert(UTEST_LYCTX, "leaf1", 0, &leaf_node->name));
assert_int_equal(LY_SUCCESS, lydict_insert(UTEST_LYCTX, "string", 0, &leaf_node->type.name));
leaf_node->type.pmod = mod->parsed;
list_node->child = (struct lysp_node *)leaf_node;

assert_int_equal(LY_SUCCESS, ly_ctx_add_parsed_module(UTEST_LYCTX, mod, NULL));
assert_non_null(ly_ctx_get_module_implemented(UTEST_LYCTX, "module1"));
}

int
main(void)
{
Expand All @@ -1078,6 +1119,7 @@ main(void)
UTEST(test_ylmem),
UTEST(test_set_priv_parsed),
UTEST(test_explicit_compile),
UTEST(test_add_parsed_module),
};

return cmocka_run_group_tests(tests, NULL, NULL);
Expand Down
Loading