libyang  6.3.1
libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
leafref.c
Go to the documentation of this file.
1 
15 #define _GNU_SOURCE /* strdup */
16 
17 #include "plugins_types.h"
18 
19 #include <assert.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 
23 #include "compat.h"
24 #include "dict.h"
25 #include "ly_common.h"
26 #include "plugins_internal.h"
27 #include "tree_data_internal.h" /* lyd_link_leafref_node */
28 
38 static void
39 lyplg_type_lyb_size_leafref(const struct lysc_type *type, enum lyplg_lyb_size_type *size_type, uint64_t *fixed_size_bits)
40 {
41  const struct lysc_type_leafref *type_lr = (struct lysc_type_leafref *)type;
42 
43  LYSC_GET_TYPE_PLG(type_lr->realtype->plugin_ref)->lyb_size(type_lr->realtype, size_type, fixed_size_bits);
44 }
45 
46 static LY_ERR
47 lyplg_type_store_leafref(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint64_t value_size_bits,
48  uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
49  struct lyd_value *storage, struct lys_glob_unres *unres,
50  struct ly_err_item **err)
51 {
52  LY_ERR rc = LY_SUCCESS;
53  struct lysc_type_leafref *type_lr = (struct lysc_type_leafref *)type;
54 
55  assert(type_lr->realtype);
56 
57  /* store the value as the real type of the leafref target */
58  rc = LYSC_GET_TYPE_PLG(type_lr->realtype->plugin_ref)->store(ctx, type_lr->realtype, value, value_size_bits, options,
59  format, prefix_data, hints, ctx_node, storage, unres, err);
60  if (rc == LY_EINCOMPLETE) {
61  /* it is irrelevant whether the target type needs some resolving */
62  rc = LY_SUCCESS;
63  }
64  LY_CHECK_RET(rc);
65 
66  if (type_lr->require_instance) {
67  /* needs to be resolved */
68  return LY_EINCOMPLETE;
69  } else {
70  return LY_SUCCESS;
71  }
72 }
73 
74 static LY_ERR
75 lyplg_type_validate_tree_leafref(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node,
76  const struct lyd_node *tree, struct lyd_value *storage,
77  struct ly_err_item **err)
78 {
79  LY_ERR rc = LY_SUCCESS;
80  struct lysc_type_leafref *type_lr = (struct lysc_type_leafref *)type;
81  char *errmsg = NULL, *path;
82  struct ly_set *targets = NULL;
83  uint32_t i;
84 
85  *err = NULL;
86 
87  if (!type_lr->require_instance) {
88  /* redundant to resolve */
89  return LY_SUCCESS;
90  }
91 
92  rc = lyplg_type_resolve_leafref(type_lr, ctx_node, storage, tree,
93  (ly_ctx_get_options(ctx) & LY_CTX_LEAFREF_LINKING) ? &targets : NULL, &errmsg);
94  if (rc) {
95  path = lyd_path(ctx_node, LYD_PATH_STD, NULL, 0);
96  rc = ly_err_new(err, LY_EVALID, LYVE_DATA, path, strdup("instance-required"), "%s", errmsg);
97  free(errmsg);
98  goto cleanup;
99  }
100 
102  for (i = 0; i < targets->count; ++i) {
103  rc = lyd_link_leafref_node((struct lyd_node_term *)targets->dnodes[i], (struct lyd_node_term *)ctx_node);
104  LY_CHECK_GOTO(rc, cleanup);
105  }
106  }
107 
108 cleanup:
109  ly_set_free(targets, NULL);
110  return rc;
111 }
112 
113 static LY_ERR
114 lyplg_type_compare_leafref(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
115 {
116  return LYSC_GET_TYPE_PLG(val1->realtype->plugin_ref)->compare(ctx, val1, val2);
117 }
118 
119 static int
120 lyplg_type_sort_leafref(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
121 {
122  return LYSC_GET_TYPE_PLG(val1->realtype->plugin_ref)->sort(ctx, val1, val2);
123 }
124 
125 static const void *
126 lyplg_type_print_leafref(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
127  void *prefix_data, ly_bool *dynamic, uint64_t *value_size_bits)
128 {
129  return LYSC_GET_TYPE_PLG(value->realtype->plugin_ref)->print(ctx, value, format, prefix_data, dynamic, value_size_bits);
130 }
131 
132 static LY_ERR
133 lyplg_type_dup_leafref(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
134 {
135  return LYSC_GET_TYPE_PLG(original->realtype->plugin_ref)->duplicate(ctx, original, dup);
136 }
137 
138 static void
139 lyplg_type_free_leafref(const struct ly_ctx *ctx, struct lyd_value *value)
140 {
141  LYSC_GET_TYPE_PLG(value->realtype->plugin_ref)->free(ctx, value);
142 }
143 
152  {
153  .module = "",
154  .revision = NULL,
155  .name = LY_TYPE_LEAFREF_STR,
156 
157  .plugin.id = "ly2 leafref",
158  .plugin.lyb_size = lyplg_type_lyb_size_leafref,
159  .plugin.store = lyplg_type_store_leafref,
160  .plugin.validate_value = NULL,
161  .plugin.validate_tree = lyplg_type_validate_tree_leafref,
162  .plugin.compare = lyplg_type_compare_leafref,
163  .plugin.sort = lyplg_type_sort_leafref,
164  .plugin.print = lyplg_type_print_leafref,
165  .plugin.duplicate = lyplg_type_dup_leafref,
166  .plugin.free = lyplg_type_free_leafref,
167  },
168  {0}
169 };
struct lysc_type * realtype
Definition: tree_data.h:615
Compiled YANG data node.
Definition: tree_schema.h:1430
lyplg_lyb_size_type
Type of the LYB size of a value of a particular type.
Generic structure for a data node.
Definition: tree_data.h:878
LY_ERR
libyang&#39;s error codes returned by the libyang functions.
Definition: log.h:255
uint8_t ly_bool
Type to indicate boolean value.
Definition: log.h:29
libyang dictionary
uintptr_t plugin_ref
Definition: tree_schema.h:1295
LIBYANG_API_DECL char * lyd_path(const struct lyd_node *node, LYD_PATH_TYPE pathtype, char *buffer, size_t buflen)
Generate path of the given node in the requested format.
Data node structure for the terminal data tree nodes - leaves and leaf-lists.
Definition: tree_data.h:930
LIBYANG_API_DECL void ly_set_free(struct ly_set *set, void(*destructor)(void *obj))
Free the ly_set data. If the destructor is not provided, it frees only the set structure content...
struct lyplg_type_record plugins_leafref[]
Plugin information for leafref type implementation.
Definition: leafref.c:151
LIBYANG_API_DECL LY_ERR lyplg_type_resolve_leafref(const struct lysc_type_leafref *lref, const struct lyd_node *node, struct lyd_value *value, const struct lyd_node *tree, struct ly_set **targets, char **errmsg)
Find leafref target in data.
YANG data representation.
Definition: tree_data.h:611
struct lyxp_expr * path
Definition: tree_schema.h:1375
uint32_t count
Definition: set.h:49
Libyang full error structure.
Definition: log.h:301
Definition: log.h:293
LIBYANG_API_DECL LY_ERR ly_err_new(struct ly_err_item **err, LY_ERR ecode, LY_VECODE vecode, char *data_path, char *apptag, const char *err_format,...) _FORMAT_PRINTF(6
Create and fill error structure.
Structure to hold a set of (not necessary somehow connected) objects. Usually used for lyd_node...
Definition: set.h:47
Definition: log.h:263
const char * module
uint8_t require_instance
Definition: tree_schema.h:1378
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: utils.h:93
LIBYANG_API_DECL uint32_t ly_ctx_get_options(const struct ly_ctx *ctx)
Get the currently set context&#39;s options.
#define LY_CTX_LEAFREF_LINKING
Definition: context.h:259
API for (user) types plugins.
struct lysc_type * realtype
Definition: tree_schema.h:1377
libyang context handler.
assert(!value->_canonical)