types REFACTOR move instance-identifier specific functions into a standalone source file
Split the plugins_types.c file to distinct internal implementation of
plugins types API and the (base) type plugins themselves.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0d05dc4..f188fba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -141,6 +141,7 @@
src/plugins_types_empty.c
src/plugins_types_enumeration.c
src/plugins_types_identityref.c
+ src/plugins_types_instanceid.c
src/plugins_types_integer.c
src/plugins_types_string.c
src/plugins_exts.c
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 6f4c385..21fdc31 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -747,298 +747,6 @@
return LY_ENOTFOUND;
}
-static const char *ly_type_print_instanceid(const struct lyd_value *value, LY_PREFIX_FORMAT format, void *prefix_data,
- ly_bool *dynamic);
-
-/**
- * @brief Validate and store value of the YANG built-in instance-identifier type.
- *
- * Implementation of the ly_type_store_clb.
- */
-static LY_ERR
-ly_type_store_instanceid(const struct ly_ctx *ctx, const struct lysc_type *type, const char *value, size_t value_len,
- uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
- struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
-{
- LY_ERR ret = LY_SUCCESS;
- struct lysc_type_instanceid *type_inst = (struct lysc_type_instanceid *)type;
- char *str;
- struct ly_path *path = NULL;
- ly_bool dyn;
-
- /* init */
- *err = NULL;
-
- /* check hints */
- ret = ly_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
- LY_CHECK_GOTO(ret != LY_SUCCESS, cleanup_value);
-
- LY_CHECK_GOTO(ret = ly_type_store_lypath_new(ctx, value, value_len, options, format, prefix_data, ctx_node,
- unres, &path, err), cleanup);
-
- /* store resolved schema path */
- storage->target = path;
- path = NULL;
-
- /* store JSON string value */
- str = (char *)ly_type_print_instanceid(storage, LY_PREF_JSON, NULL, &dyn);
- assert(str && dyn);
- LY_CHECK_GOTO(ret = lydict_insert_zc(ctx, str, &storage->canonical), cleanup);
- storage->realtype = type;
-
- /* cleanup */
-cleanup:
- ly_type_store_lypath_free(ctx, path);
-
-cleanup_value:
- if (options & LY_TYPE_STORE_DYNAMIC) {
- free((char *)value);
- }
-
- if ((ret == LY_SUCCESS) && type_inst->require_instance) {
- /* needs to be resolved */
- return LY_EINCOMPLETE;
- } else {
- return ret;
- }
-}
-
-/**
- * @brief Validate value of the YANG built-in instance-identifier type.
- *
- * Implementation of the ly_type_validate_clb.
- */
-static LY_ERR
-ly_type_validate_instanceid(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *UNUSED(type),
- const struct lyd_node *UNUSED(ctx_node), const struct lyd_node *tree, struct lyd_value *storage,
- struct ly_err_item **err)
-{
- struct lysc_type_instanceid *type_inst = (struct lysc_type_instanceid *)storage->realtype;
- LY_ERR ret = LY_SUCCESS;
-
- *err = NULL;
-
- if (!type_inst->require_instance) {
- /* redundant to resolve */
- return LY_SUCCESS;
- }
-
- /* find the target in data */
- ret = ly_path_eval(storage->target, tree, NULL);
- return ly_err_new(err, ret, LYVE_DATA, NULL, NULL, LY_ERRMSG_NOINST, storage->canonical);
-}
-
-/**
- * @brief Comparison callback checking the instance-identifier value.
- *
- * Implementation of the ly_type_compare_clb.
- */
-static LY_ERR
-ly_type_compare_instanceid(const struct lyd_value *val1, const struct lyd_value *val2)
-{
- LY_ARRAY_COUNT_TYPE u, v;
-
- if (val1->realtype != val2->realtype) {
- return LY_ENOT;
- }
-
- if (val1 == val2) {
- return LY_SUCCESS;
- } else if (!val1->target || !val2->target || (LY_ARRAY_COUNT(val1->target) != LY_ARRAY_COUNT(val2->target))) {
- return LY_ENOT;
- }
-
- LY_ARRAY_FOR(val1->target, u) {
- struct ly_path *s1 = &val1->target[u];
- struct ly_path *s2 = &val2->target[u];
-
- if ((s1->node != s2->node) || (s1->pred_type != s2->pred_type) ||
- (s1->predicates && (LY_ARRAY_COUNT(s1->predicates) != LY_ARRAY_COUNT(s2->predicates)))) {
- return LY_ENOT;
- }
- if (s1->predicates) {
- LY_ARRAY_FOR(s1->predicates, v) {
- struct ly_path_predicate *pred1 = &s1->predicates[v];
- struct ly_path_predicate *pred2 = &s2->predicates[v];
-
- switch (s1->pred_type) {
- case LY_PATH_PREDTYPE_NONE:
- break;
- case LY_PATH_PREDTYPE_POSITION:
- /* position predicate */
- if (pred1->position != pred2->position) {
- return LY_ENOT;
- }
- break;
- case LY_PATH_PREDTYPE_LIST:
- /* key-predicate */
- if ((pred1->key != pred2->key) || ((struct lysc_node_leaf *)pred1->key)->type->plugin->compare(&pred1->value, &pred2->value)) {
- return LY_ENOT;
- }
- break;
- case LY_PATH_PREDTYPE_LEAFLIST:
- /* leaf-list predicate */
- if (((struct lysc_node_leaflist *)s1->node)->type->plugin->compare(&pred1->value, &pred2->value)) {
- return LY_ENOT;
- }
- }
- }
- }
- }
-
- return LY_SUCCESS;
-}
-
-/**
- * @brief Printer callback printing the instance-identifier value.
- *
- * Implementation of the ly_type_print_clb.
- */
-static const char *
-ly_type_print_instanceid(const struct lyd_value *value, LY_PREFIX_FORMAT format, void *prefix_data, ly_bool *dynamic)
-{
- LY_ARRAY_COUNT_TYPE u, v;
- char *result = NULL;
-
- if (!value->target) {
- /* value was not fully processed */
- return NULL;
- }
-
- if ((format == LY_PREF_XML) || (format == LY_PREF_SCHEMA)) {
- /* everything is prefixed */
- LY_ARRAY_FOR(value->target, u) {
- ly_strcat(&result, "/%s:%s", ly_type_print_get_prefix(value->target[u].node->module, format, prefix_data),
- value->target[u].node->name);
- LY_ARRAY_FOR(value->target[u].predicates, v) {
- struct ly_path_predicate *pred = &value->target[u].predicates[v];
-
- switch (value->target[u].pred_type) {
- case LY_PATH_PREDTYPE_NONE:
- break;
- case LY_PATH_PREDTYPE_POSITION:
- /* position predicate */
- ly_strcat(&result, "[%" PRIu64 "]", pred->position);
- break;
- case LY_PATH_PREDTYPE_LIST: {
- /* key-predicate */
- ly_bool d = 0;
- const char *str = pred->value.realtype->plugin->print(&pred->value, format, prefix_data, &d);
- char quot = '\'';
- if (strchr(str, quot)) {
- quot = '"';
- }
- ly_strcat(&result, "[%s:%s=%c%s%c]", ly_type_print_get_prefix(pred->key->module, format, prefix_data),
- pred->key->name, quot, str, quot);
- if (d) {
- free((char *)str);
- }
- break;
- }
- case LY_PATH_PREDTYPE_LEAFLIST: {
- /* leaf-list-predicate */
- ly_bool d = 0;
- const char *str = pred->value.realtype->plugin->print(&pred->value, format, prefix_data, &d);
- char quot = '\'';
- if (strchr(str, quot)) {
- quot = '"';
- }
- ly_strcat(&result, "[.=%c%s%c]", quot, str, quot);
- if (d) {
- free((char *)str);
- }
- break;
- }
- }
- }
- }
- } else if (format == LY_PREF_JSON) {
- /* only the first node or the node changing module is prefixed */
- struct lys_module *mod = NULL;
- LY_ARRAY_FOR(value->target, u) {
- if (mod != value->target[u].node->module) {
- mod = value->target[u].node->module;
- ly_strcat(&result, "/%s:%s", ly_type_print_get_prefix(mod, format, prefix_data), value->target[u].node->name);
- } else {
- ly_strcat(&result, "/%s", value->target[u].node->name);
- }
- LY_ARRAY_FOR(value->target[u].predicates, v) {
- struct ly_path_predicate *pred = &value->target[u].predicates[v];
-
- switch (value->target[u].pred_type) {
- case LY_PATH_PREDTYPE_NONE:
- break;
- case LY_PATH_PREDTYPE_POSITION:
- /* position predicate */
- ly_strcat(&result, "[%" PRIu64 "]", pred->position);
- break;
- case LY_PATH_PREDTYPE_LIST: {
- /* key-predicate */
- ly_bool d = 0;
- const char *str = pred->value.realtype->plugin->print(&pred->value, format, prefix_data, &d);
- char quot = '\'';
- if (strchr(str, quot)) {
- quot = '"';
- }
- ly_strcat(&result, "[%s=%c%s%c]", pred->key->name, quot, str, quot);
- if (d) {
- free((char *)str);
- }
- break;
- }
- case LY_PATH_PREDTYPE_LEAFLIST: {
- /* leaf-list-predicate */
- ly_bool d = 0;
- const char *str = pred->value.realtype->plugin->print(&pred->value, format, prefix_data, &d);
- char quot = '\'';
- if (strchr(str, quot)) {
- quot = '"';
- }
- ly_strcat(&result, "[.=%c%s%c]", quot, str, quot);
- if (d) {
- free((char *)str);
- }
- break;
- }
- }
- }
- }
- } else {
- /* not supported format */
- free(result);
- return NULL;
- }
-
- *dynamic = 1;
- return result;
-}
-
-/**
- * @brief Duplication callback of the instance-identifier values.
- *
- * Implementation of the ly_type_dup_clb.
- */
-static LY_ERR
-ly_type_dup_instanceid(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
-{
- LY_CHECK_RET(lydict_insert(ctx, original->canonical, strlen(original->canonical), &dup->canonical));
- dup->realtype = original->realtype;
- return ly_path_dup(ctx, original->target, &dup->target);
-}
-
-/**
- * @brief Free value of the YANG built-in instance-identifier types.
- *
- * Implementation of the ly_type_free_clb.
- */
-static void
-ly_type_free_instanceid(const struct ly_ctx *ctx, struct lyd_value *value)
-{
- ly_path_free(ctx, value->target);
- value->target = NULL;
- ly_type_free_simple(ctx, value);
-}
-
LY_ERR
ly_type_find_leafref(const struct lysc_type_leafref *lref, const struct lyd_node *node, struct lyd_value *value,
const struct lyd_node *tree, struct lyd_node **target, char **errmsg)
@@ -1499,6 +1207,18 @@
extern const char *ly_type_print_identityref(const struct lyd_value *value, LY_PREFIX_FORMAT format, void *prefix_data,
ly_bool *dynamic);
+/* plugins_types_instanceid.c */
+extern LY_ERR ly_type_store_instanceid(const struct ly_ctx *ctx, const struct lysc_type *type,
+ const char *value, size_t value_len, uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints,
+ const struct lysc_node *ctx_node, struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err);
+extern LY_ERR ly_type_validate_instanceid(const struct ly_ctx *ctx, const struct lysc_type *type,
+ const struct lyd_node *ctx_node, const struct lyd_node *tree, struct lyd_value *storage, struct ly_err_item **err);
+extern LY_ERR ly_type_compare_instanceid(const struct lyd_value *val1, const struct lyd_value *val2);
+extern const char *ly_type_print_instanceid(const struct lyd_value *value, LY_PREFIX_FORMAT format, void *prefix_data,
+ ly_bool *dynamic);
+extern LY_ERR ly_type_dup_instanceid(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup);
+extern void ly_type_free_instanceid(const struct ly_ctx *ctx, struct lyd_value *value);
+
/**
* @brief Set of type plugins for YANG built-in types
*/
diff --git a/src/plugins_types_instanceid.c b/src/plugins_types_instanceid.c
new file mode 100644
index 0000000..97c1530
--- /dev/null
+++ b/src/plugins_types_instanceid.c
@@ -0,0 +1,321 @@
+/**
+ * @file plugins_types_instanceid.c
+ * @author Radek Krejci <rkrejci@cesnet.cz>
+ * @brief Built-in instance-identifier type plugin.
+ *
+ * Copyright (c) 2019-2021 CESNET, z.s.p.o.
+ *
+ * This source code is licensed under BSD 3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#define _GNU_SOURCE
+
+#include "plugins_types.h"
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libyang.h"
+
+/* additional internal headers for some useful simple macros */
+#include "common.h"
+#include "compat.h"
+
+#include "path.h"
+
+/**
+ * @brief Printer callback printing the instance-identifier value.
+ *
+ * Implementation of the ly_type_print_clb.
+ */
+const char *
+ly_type_print_instanceid(const struct lyd_value *value, LY_PREFIX_FORMAT format, void *prefix_data, ly_bool *dynamic)
+{
+ LY_ARRAY_COUNT_TYPE u, v;
+ char *result = NULL;
+
+ if (!value->target) {
+ /* value was not fully processed */
+ return NULL;
+ }
+
+ if ((format == LY_PREF_XML) || (format == LY_PREF_SCHEMA)) {
+ /* everything is prefixed */
+ LY_ARRAY_FOR(value->target, u) {
+ ly_strcat(&result, "/%s:%s", ly_type_print_get_prefix(value->target[u].node->module, format, prefix_data),
+ value->target[u].node->name);
+ LY_ARRAY_FOR(value->target[u].predicates, v) {
+ struct ly_path_predicate *pred = &value->target[u].predicates[v];
+
+ switch (value->target[u].pred_type) {
+ case LY_PATH_PREDTYPE_NONE:
+ break;
+ case LY_PATH_PREDTYPE_POSITION:
+ /* position predicate */
+ ly_strcat(&result, "[%" PRIu64 "]", pred->position);
+ break;
+ case LY_PATH_PREDTYPE_LIST: {
+ /* key-predicate */
+ ly_bool d = 0;
+ const char *str = pred->value.realtype->plugin->print(&pred->value, format, prefix_data, &d);
+ char quot = '\'';
+ if (strchr(str, quot)) {
+ quot = '"';
+ }
+ ly_strcat(&result, "[%s:%s=%c%s%c]", ly_type_print_get_prefix(pred->key->module, format, prefix_data),
+ pred->key->name, quot, str, quot);
+ if (d) {
+ free((char *)str);
+ }
+ break;
+ }
+ case LY_PATH_PREDTYPE_LEAFLIST: {
+ /* leaf-list-predicate */
+ ly_bool d = 0;
+ const char *str = pred->value.realtype->plugin->print(&pred->value, format, prefix_data, &d);
+ char quot = '\'';
+ if (strchr(str, quot)) {
+ quot = '"';
+ }
+ ly_strcat(&result, "[.=%c%s%c]", quot, str, quot);
+ if (d) {
+ free((char *)str);
+ }
+ break;
+ }
+ }
+ }
+ }
+ } else if (format == LY_PREF_JSON) {
+ /* only the first node or the node changing module is prefixed */
+ struct lys_module *mod = NULL;
+ LY_ARRAY_FOR(value->target, u) {
+ if (mod != value->target[u].node->module) {
+ mod = value->target[u].node->module;
+ ly_strcat(&result, "/%s:%s", ly_type_print_get_prefix(mod, format, prefix_data), value->target[u].node->name);
+ } else {
+ ly_strcat(&result, "/%s", value->target[u].node->name);
+ }
+ LY_ARRAY_FOR(value->target[u].predicates, v) {
+ struct ly_path_predicate *pred = &value->target[u].predicates[v];
+
+ switch (value->target[u].pred_type) {
+ case LY_PATH_PREDTYPE_NONE:
+ break;
+ case LY_PATH_PREDTYPE_POSITION:
+ /* position predicate */
+ ly_strcat(&result, "[%" PRIu64 "]", pred->position);
+ break;
+ case LY_PATH_PREDTYPE_LIST: {
+ /* key-predicate */
+ ly_bool d = 0;
+ const char *str = pred->value.realtype->plugin->print(&pred->value, format, prefix_data, &d);
+ char quot = '\'';
+ if (strchr(str, quot)) {
+ quot = '"';
+ }
+ ly_strcat(&result, "[%s=%c%s%c]", pred->key->name, quot, str, quot);
+ if (d) {
+ free((char *)str);
+ }
+ break;
+ }
+ case LY_PATH_PREDTYPE_LEAFLIST: {
+ /* leaf-list-predicate */
+ ly_bool d = 0;
+ const char *str = pred->value.realtype->plugin->print(&pred->value, format, prefix_data, &d);
+ char quot = '\'';
+ if (strchr(str, quot)) {
+ quot = '"';
+ }
+ ly_strcat(&result, "[.=%c%s%c]", quot, str, quot);
+ if (d) {
+ free((char *)str);
+ }
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ /* not supported format */
+ free(result);
+ return NULL;
+ }
+
+ *dynamic = 1;
+ return result;
+}
+
+/**
+ * @brief Validate and store value of the YANG built-in instance-identifier type.
+ *
+ * Implementation of the ly_type_store_clb.
+ */
+LY_ERR
+ly_type_store_instanceid(const struct ly_ctx *ctx, const struct lysc_type *type, const char *value, size_t value_len,
+ uint32_t options, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
+ struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err)
+{
+ LY_ERR ret = LY_SUCCESS;
+ struct lysc_type_instanceid *type_inst = (struct lysc_type_instanceid *)type;
+ char *str;
+ struct ly_path *path = NULL;
+ ly_bool dyn;
+
+ /* init */
+ *err = NULL;
+
+ /* check hints */
+ ret = ly_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
+ LY_CHECK_GOTO(ret != LY_SUCCESS, cleanup_value);
+
+ LY_CHECK_GOTO(ret = ly_type_store_lypath_new(ctx, value, value_len, options, format, prefix_data, ctx_node,
+ unres, &path, err), cleanup);
+
+ /* store resolved schema path */
+ storage->target = path;
+ path = NULL;
+
+ /* store JSON string value */
+ str = (char *)ly_type_print_instanceid(storage, LY_PREF_JSON, NULL, &dyn);
+ assert(str && dyn);
+ LY_CHECK_GOTO(ret = lydict_insert_zc(ctx, str, &storage->canonical), cleanup);
+ storage->realtype = type;
+
+ /* cleanup */
+cleanup:
+ ly_type_store_lypath_free(ctx, path);
+
+cleanup_value:
+ if (options & LY_TYPE_STORE_DYNAMIC) {
+ free((char *)value);
+ }
+
+ if ((ret == LY_SUCCESS) && type_inst->require_instance) {
+ /* needs to be resolved */
+ return LY_EINCOMPLETE;
+ } else {
+ return ret;
+ }
+}
+
+/**
+ * @brief Validate value of the YANG built-in instance-identifier type.
+ *
+ * Implementation of the ly_type_validate_clb.
+ */
+LY_ERR
+ly_type_validate_instanceid(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *UNUSED(type),
+ const struct lyd_node *UNUSED(ctx_node), const struct lyd_node *tree, struct lyd_value *storage,
+ struct ly_err_item **err)
+{
+ struct lysc_type_instanceid *type_inst = (struct lysc_type_instanceid *)storage->realtype;
+ LY_ERR ret = LY_SUCCESS;
+
+ *err = NULL;
+
+ if (!type_inst->require_instance) {
+ /* redundant to resolve */
+ return LY_SUCCESS;
+ }
+
+ /* find the target in data */
+ ret = ly_path_eval(storage->target, tree, NULL);
+ return ly_err_new(err, ret, LYVE_DATA, NULL, NULL, LY_ERRMSG_NOINST, storage->canonical);
+}
+
+/**
+ * @brief Comparison callback checking the instance-identifier value.
+ *
+ * Implementation of the ly_type_compare_clb.
+ */
+LY_ERR
+ly_type_compare_instanceid(const struct lyd_value *val1, const struct lyd_value *val2)
+{
+ LY_ARRAY_COUNT_TYPE u, v;
+
+ if (val1->realtype != val2->realtype) {
+ return LY_ENOT;
+ }
+
+ if (val1 == val2) {
+ return LY_SUCCESS;
+ } else if (!val1->target || !val2->target || (LY_ARRAY_COUNT(val1->target) != LY_ARRAY_COUNT(val2->target))) {
+ return LY_ENOT;
+ }
+
+ LY_ARRAY_FOR(val1->target, u) {
+ struct ly_path *s1 = &val1->target[u];
+ struct ly_path *s2 = &val2->target[u];
+
+ if ((s1->node != s2->node) || (s1->pred_type != s2->pred_type) ||
+ (s1->predicates && (LY_ARRAY_COUNT(s1->predicates) != LY_ARRAY_COUNT(s2->predicates)))) {
+ return LY_ENOT;
+ }
+ if (s1->predicates) {
+ LY_ARRAY_FOR(s1->predicates, v) {
+ struct ly_path_predicate *pred1 = &s1->predicates[v];
+ struct ly_path_predicate *pred2 = &s2->predicates[v];
+
+ switch (s1->pred_type) {
+ case LY_PATH_PREDTYPE_NONE:
+ break;
+ case LY_PATH_PREDTYPE_POSITION:
+ /* position predicate */
+ if (pred1->position != pred2->position) {
+ return LY_ENOT;
+ }
+ break;
+ case LY_PATH_PREDTYPE_LIST:
+ /* key-predicate */
+ if ((pred1->key != pred2->key) || ((struct lysc_node_leaf *)pred1->key)->type->plugin->compare(&pred1->value, &pred2->value)) {
+ return LY_ENOT;
+ }
+ break;
+ case LY_PATH_PREDTYPE_LEAFLIST:
+ /* leaf-list predicate */
+ if (((struct lysc_node_leaflist *)s1->node)->type->plugin->compare(&pred1->value, &pred2->value)) {
+ return LY_ENOT;
+ }
+ }
+ }
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Duplication callback of the instance-identifier values.
+ *
+ * Implementation of the ly_type_dup_clb.
+ */
+LY_ERR
+ly_type_dup_instanceid(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
+{
+ LY_CHECK_RET(lydict_insert(ctx, original->canonical, strlen(original->canonical), &dup->canonical));
+ dup->realtype = original->realtype;
+ return ly_path_dup(ctx, original->target, &dup->target);
+}
+
+/**
+ * @brief Free value of the YANG built-in instance-identifier types.
+ *
+ * Implementation of the ly_type_free_clb.
+ */
+void
+ly_type_free_instanceid(const struct ly_ctx *ctx, struct lyd_value *value)
+{
+ ly_path_free(ctx, value->target);
+ value->target = NULL;
+ ly_type_free_simple(ctx, value);
+}