context FEATURE allow custom content-id in yang-library data
diff --git a/doc/transition.dox b/doc/transition.dox
index c1e3cf0..6b34baa 100644
--- a/doc/transition.dox
+++ b/doc/transition.dox
@@ -111,8 +111,8 @@
* ly_ctx_remove_module() | - | ^
* ly_ctx_set_module_data_clb() and the associated ly_module_data_clb type. | - | ^
* ly_ctx_get_disabled_module() and the associated ly_ctx_get_disabled_module_iter() | - | ^
- * ly_ctx_info() | ::ly_ctx_get_yanglib_data() | Clarification of what to expect as the output of the function.
- * - | ::ly_ctx_get_yanglib_id () | Supplement functionality for ::ly_ctx_get_yanglib_data().
+ * ly_ctx_info() | ::ly_ctx_get_yanglib_data() | Clarification of what to expect as the output of the function and possibility to specify custom content ID.
+ * ly_ctx_get_module_set_id() | ::ly_ctx_get_change_count() | The functionality is the same but the exact meaning of the value was clarified.
* ly_ctx_new_ylmem() | TBD | Not yet implemented feature.
* ly_ctx_new_ylpath() | TBD | ^
* - | ::ly_ctx_unset_searchdir_last() | Extend the functionality of the ::ly_ctx_unset_searchdir() to make its use easier.
diff --git a/src/common.h b/src/common.h
index 3d52a67..891688f 100644
--- a/src/common.h
+++ b/src/common.h
@@ -301,7 +301,7 @@
struct ly_set list; /**< set of loaded YANG schemas */
ly_module_imp_clb imp_clb; /**< Optional callback for retrieving missing included or imported models in a custom way. */
void *imp_clb_data; /**< Optional private data for ::ly_ctx.imp_clb */
- uint16_t module_set_id; /**< ID of the current set of schemas */
+ uint16_t change_count; /**< Count of changes of the context, on some changes it could be incremented more times */
uint16_t flags; /**< context settings, see @ref contextoptions. */
pthread_key_t errlist_key; /**< key for the thread-specific list of errors related to the context */
};
diff --git a/src/context.c b/src/context.c
index 1a80bb9..801d636 100644
--- a/src/context.c
+++ b/src/context.c
@@ -262,7 +262,7 @@
goto error;
}
}
- ctx->module_set_id = 1;
+ ctx->change_count = 1;
/* create dummy in */
rc = ly_in_new_memory(internal_modules[0].data, &in);
@@ -322,10 +322,11 @@
}
API uint16_t
-ly_ctx_get_module_set_id(const struct ly_ctx *ctx)
+ly_ctx_get_change_count(const struct ly_ctx *ctx)
{
LY_CHECK_ARG_RET(ctx, ctx, 0);
- return ctx->module_set_id;
+
+ return ctx->change_count;
}
API void
@@ -740,14 +741,8 @@
return LY_SUCCESS;
}
-API uint16_t
-ly_ctx_get_yanglib_id(const struct ly_ctx *ctx)
-{
- return ctx->module_set_id;
-}
-
API LY_ERR
-ly_ctx_get_yanglib_data(const struct ly_ctx *ctx, struct lyd_node **root_p)
+ly_ctx_get_yanglib_data(const struct ly_ctx *ctx, struct lyd_node **root_p, const char *content_id_format, ...)
{
LY_ERR ret;
uint32_t i;
@@ -756,6 +751,7 @@
char *str;
const struct lys_module *mod;
struct lyd_node *root = NULL, *root_bis = NULL, *cont, *set_bis = NULL;
+ va_list ap;
LY_CHECK_ARG_RET(ctx, ctx, root_p, LY_EINVAL);
@@ -858,7 +854,9 @@
}
/* IDs */
- r = asprintf(&str, "%u", ctx->module_set_id);
+ va_start(ap, content_id_format);
+ r = vasprintf(&str, content_id_format, ap);
+ va_end(ap);
LY_CHECK_ERR_GOTO(r == -1, LOGMEM(ctx); ret = LY_EMEM, error);
ret = lyd_new_term(root, NULL, "module-set-id", str, 0, NULL);
LY_CHECK_ERR_GOTO(ret, free(str), error);
diff --git a/src/context.h b/src/context.h
index ee48010..77a4a60 100644
--- a/src/context.h
+++ b/src/context.h
@@ -125,9 +125,8 @@
* - ::ly_ctx_reset_latests()
*
* - ::ly_ctx_get_yanglib_data()
- * - ::ly_ctx_get_yanglib_id()
*
- * - ::ly_ctx_get_module_set_id()
+ * - ::ly_ctx_get_change_count()
* - ::ly_ctx_internal_modules_count()
*
* - ::lys_search_localfile()
@@ -283,13 +282,12 @@
LY_ERR ly_ctx_unset_options(struct ly_ctx *ctx, uint16_t option);
/**
- * @brief Get current ID of the modules set. The value is available also
- * as module-set-id in ::ly_ctx_get_yanglib_data() result.
+ * @brief Get the change count of the context (module set) during its life-time.
*
* @param[in] ctx Context to be examined.
- * @return Numeric identifier of the current context's modules set.
+ * @return Context change count.
*/
-uint16_t ly_ctx_get_module_set_id(const struct ly_ctx *ctx);
+uint16_t ly_ctx_get_change_count(const struct ly_ctx *ctx);
/**
* @brief Callback for freeing returned module data in #ly_module_imp_clb.
@@ -511,23 +509,26 @@
const char **features);
/**
- * @brief Get current ID of the modules set. The value is available also
- * as module-set-id in ::ly_ctx_get_yanglib_data() result.
- *
- * @param[in] ctx Context to be examined.
- * @return Numeric identifier of the current context's modules set.
- */
-uint16_t ly_ctx_get_yanglib_id(const struct ly_ctx *ctx);
-
-/**
* @brief Get data of the internal ietf-yang-library module with information about all the loaded modules.
* ietf-yang-library module must be loaded.
*
+ * Note that "/ietf-yang-library:yang-library/datastore" list instances are not created and should be
+ * appended by the caller. There is a single "/ietf-yang-library:yang-library/schema" instance created
+ * with the key value "complete".
+ *
+ * If the data identifier can be limited to the existence and changes of this context, the following
+ * last 2 parameters can be used:
+ *
+ * "%u" as @p content_id_format and ::ly_ctx_get_change_count() as its parameter.
+ *
* @param[in] ctx Context with the modules.
* @param[out] root Generated yang-library data.
+ * @param[in] content_id_format Format string (printf-like) for the yang-library data identifier, which is
+ * the "content_id" node in the 2019-01-04 revision of ietf-yang-library.
+ * @param[in] ... Parameters for @p content_id_format.
* @return LY_ERR value
*/
-LY_ERR ly_ctx_get_yanglib_data(const struct ly_ctx *ctx, struct lyd_node **root);
+LY_ERR ly_ctx_get_yanglib_data(const struct ly_ctx *ctx, struct lyd_node **root, const char *content_id_format, ...);
/**
* @brief Free all internal structures of the specified context.
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 16ffe3d..0877fea 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -1600,7 +1600,7 @@
}
/* context will be changed */
- ++mod->ctx->module_set_id;
+ ++mod->ctx->change_count;
sp = mod->parsed;
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 67e4804..c145c04 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -1360,7 +1360,7 @@
/* add into context */
ret = ly_set_add(&ctx->list, mod, 1, NULL);
LY_CHECK_GOTO(ret, cleanup);
- ctx->module_set_id++;
+ ctx->change_count++;
/* resolve includes and all imports */
LY_CHECK_GOTO(ret = lys_resolve_import_include(pctx, mod->parsed), cleanup);
diff --git a/tests/utests/basic/test_context.c b/tests/utests/basic/test_context.c
index de535f0..f6ab81c 100644
--- a/tests/utests/basic/test_context.c
+++ b/tests/utests/basic/test_context.c
@@ -208,11 +208,11 @@
ly_ctx_destroy(UTEST_LYCTX, NULL);
/* invalid arguments */
- assert_int_equal(0, ly_ctx_get_module_set_id(NULL));
- CHECK_LOG("Invalid argument ctx (ly_ctx_get_module_set_id()).", NULL);
+ assert_int_equal(0, ly_ctx_get_change_count(NULL));
+ CHECK_LOG("Invalid argument ctx (ly_ctx_get_change_count()).", NULL);
assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &UTEST_LYCTX));
- assert_int_equal(UTEST_LYCTX->module_set_id, ly_ctx_get_module_set_id(UTEST_LYCTX));
+ assert_int_equal(UTEST_LYCTX->change_count, ly_ctx_get_change_count(UTEST_LYCTX));
assert_int_equal(LY_SUCCESS, ly_in_new_memory("module x {namespace urn:x;prefix x;}", &in));
assert_int_equal(LY_EINVAL, lys_create_module(UTEST_LYCTX, in, 4, 1, NULL, NULL, NULL, &unres, &mod1));
diff --git a/tests/utests/basic/test_yanglib.c b/tests/utests/basic/test_yanglib.c
index 563fbb3..9c52ac0 100644
--- a/tests/utests/basic/test_yanglib.c
+++ b/tests/utests/basic/test_yanglib.c
@@ -114,7 +114,13 @@
UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, feats, NULL);
UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
- assert_int_equal(LY_SUCCESS, ly_ctx_get_yanglib_data(UTEST_LYCTX, &tree));
+ assert_int_equal(LY_SUCCESS, ly_ctx_get_yanglib_data(UTEST_LYCTX, &tree, "<<%u>>", ly_ctx_get_change_count(UTEST_LYCTX)));
+ lyd_free_all(tree);
+ assert_int_equal(LY_SUCCESS, ly_ctx_get_yanglib_data(UTEST_LYCTX, &tree, "%u", -10));
+ lyd_free_all(tree);
+ assert_int_equal(LY_SUCCESS, ly_ctx_get_yanglib_data(UTEST_LYCTX, &tree, ""));
+ lyd_free_all(tree);
+ assert_int_equal(LY_SUCCESS, ly_ctx_get_yanglib_data(UTEST_LYCTX, &tree, "%u", ly_ctx_get_change_count(UTEST_LYCTX)));
/* make sure there is "a" with a submodule and deviation */
ret = lyd_find_xpath(tree, "/ietf-yang-library:yang-library/module-set/module[name='a'][submodule/name='a_sub']"
diff --git a/tools/lint/common.c b/tools/lint/common.c
index db9036c..444f527 100644
--- a/tools/lint/common.c
+++ b/tools/lint/common.c
@@ -349,7 +349,7 @@
const struct lys_module *mod;
if (outformat != LYD_UNKNOWN) {
- if (ly_ctx_get_yanglib_data(ctx, &ylib)) {
+ if (ly_ctx_get_yanglib_data(ctx, &ylib, "%u", ly_ctx_get_change_count(ctx))) {
YLMSG_E("Getting context info (ietf-yang-library data) failed. If the YANG module is missing or not implemented, use an option to add it internally.\n");
return 1;
}