libyang  4.0.2
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 "libyang.h"
24 
25 /* additional internal headers for some useful simple macros */
26 #include "compat.h"
27 #include "ly_common.h"
28 #include "plugins_internal.h" /* LY_TYPE_*_STR */
29 #include "tree_data_internal.h" /* lyd_link_leafref_node */
30 
40 static void
41 lyplg_type_lyb_size_leafref(const struct lysc_type *type, enum lyplg_lyb_size_type *size_type, uint32_t *fixed_size_bits)
42 {
43  const struct lysc_type_leafref *type_lr = (struct lysc_type_leafref *)type;
44 
45  LYSC_GET_TYPE_PLG(type_lr->realtype->plugin_ref)->lyb_size(type_lr->realtype, size_type, fixed_size_bits);
46 }
47 
48 static LY_ERR
49 lyplg_type_store_leafref(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint32_t value_size_bits,
50  uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
51  const struct lysc_ext_instance *top_ext, struct lyd_value *storage, struct lys_glob_unres *unres,
52  struct ly_err_item **err)
53 {
54  LY_ERR rc = LY_SUCCESS;
55  struct lysc_type_leafref *type_lr = (struct lysc_type_leafref *)type;
56 
57  assert(type_lr->realtype);
58 
59  /* store the value as the real type of the leafref target */
60  rc = LYSC_GET_TYPE_PLG(type_lr->realtype->plugin_ref)->store(ctx, type_lr->realtype, value, value_size_bits, options,
61  format, prefix_data, hints, ctx_node, top_ext, storage, unres, err);
62  if (rc == LY_EINCOMPLETE) {
63  /* it is irrelevant whether the target type needs some resolving */
64  rc = LY_SUCCESS;
65  }
66  LY_CHECK_RET(rc);
67 
68  if (type_lr->require_instance) {
69  /* needs to be resolved */
70  return LY_EINCOMPLETE;
71  } else {
72  return LY_SUCCESS;
73  }
74 }
75 
76 static LY_ERR
77 lyplg_type_validate_tree_leafref(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node,
78  const struct lyd_node *tree, const struct lysc_ext_instance *top_ext, struct lyd_value *storage,
79  struct ly_err_item **err)
80 {
81  LY_ERR rc = LY_SUCCESS;
82  struct lysc_type_leafref *type_lr = (struct lysc_type_leafref *)type;
83  char *errmsg = NULL, *path;
84  struct ly_set *targets = NULL;
85  uint32_t i;
86 
87  *err = NULL;
88 
89  if (!type_lr->require_instance) {
90  /* redundant to resolve */
91  return LY_SUCCESS;
92  }
93 
94  rc = lyplg_type_resolve_leafref(type_lr, ctx_node, storage, tree, top_ext,
95  (ly_ctx_get_options(ctx) & LY_CTX_LEAFREF_LINKING) ? &targets : NULL, &errmsg);
96  if (rc) {
97  path = lyd_path(ctx_node, LYD_PATH_STD, NULL, 0);
98  rc = ly_err_new(err, LY_EVALID, LYVE_DATA, path, strdup("instance-required"), "%s", errmsg);
99  free(errmsg);
100  goto cleanup;
101  }
102 
104  for (i = 0; i < targets->count; ++i) {
105  rc = lyd_link_leafref_node((struct lyd_node_term *)targets->dnodes[i], (struct lyd_node_term *)ctx_node);
106  LY_CHECK_GOTO(rc, cleanup);
107  }
108  }
109 
110 cleanup:
111  ly_set_free(targets, NULL);
112  return rc;
113 }
114 
115 static LY_ERR
116 lyplg_type_compare_leafref(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
117 {
118  return LYSC_GET_TYPE_PLG(val1->realtype->plugin_ref)->compare(ctx, val1, val2);
119 }
120 
121 static int
122 lyplg_type_sort_leafref(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
123 {
124  return LYSC_GET_TYPE_PLG(val1->realtype->plugin_ref)->sort(ctx, val1, val2);
125 }
126 
127 static const void *
128 lyplg_type_print_leafref(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
129  void *prefix_data, ly_bool *dynamic, uint32_t *value_size_bits)
130 {
131  return LYSC_GET_TYPE_PLG(value->realtype->plugin_ref)->print(ctx, value, format, prefix_data, dynamic, value_size_bits);
132 }
133 
134 static LY_ERR
135 lyplg_type_dup_leafref(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
136 {
137  return LYSC_GET_TYPE_PLG(original->realtype->plugin_ref)->duplicate(ctx, original, dup);
138 }
139 
140 static void
141 lyplg_type_free_leafref(const struct ly_ctx *ctx, struct lyd_value *value)
142 {
143  LYSC_GET_TYPE_PLG(value->realtype->plugin_ref)->free(ctx, value);
144 }
145 
154  {
155  .module = "",
156  .revision = NULL,
157  .name = LY_TYPE_LEAFREF_STR,
158 
159  .plugin.id = "ly2 leafref",
160  .plugin.lyb_size = lyplg_type_lyb_size_leafref,
161  .plugin.store = lyplg_type_store_leafref,
162  .plugin.validate_value = NULL,
163  .plugin.validate_tree = lyplg_type_validate_tree_leafref,
164  .plugin.compare = lyplg_type_compare_leafref,
165  .plugin.sort = lyplg_type_sort_leafref,
166  .plugin.print = lyplg_type_print_leafref,
167  .plugin.duplicate = lyplg_type_dup_leafref,
168  .plugin.free = lyplg_type_free_leafref,
169  },
170  {0}
171 };
struct lysc_type * realtype
Definition: tree_data.h:567
Compiled YANG data node.
Definition: tree_schema.h:1434
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:792
YANG extension compiled instance.
Definition: plugins_exts.h:436
LY_ERR
libyang&#39;s error codes returned by the libyang functions.
Definition: log.h:240
uint8_t ly_bool
Type to indicate boolean value.
Definition: log.h:28
uintptr_t plugin_ref
Definition: tree_schema.h:1299
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:844
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:153
The main libyang public header.
YANG data representation.
Definition: tree_data.h:563
struct lyxp_expr * path
Definition: tree_schema.h:1379
uint32_t count
Definition: set.h:49
Libyang full error structure.
Definition: log.h:285
Definition: log.h:277
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:248
const char * module
uint8_t require_instance
Definition: tree_schema.h:1382
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: tree.h:234
LIBYANG_API_DECL uint32_t ly_ctx_get_options(const struct ly_ctx *ctx)
Get the currently set context&#39;s options.
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, const struct lysc_ext_instance *top_ext, struct ly_set **targets, char **errmsg)
Find leafref target in data.
#define LY_CTX_LEAFREF_LINKING
Definition: context.h:259
API for (user) types plugins.
struct lysc_type * realtype
Definition: tree_schema.h:1381
libyang context handler.
assert(!value->_canonical)