libyang  6.4.13
libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
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 
151 const struct lyplg_type_record plugins_leafref[] = {
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 };
libyang dictionary
LIBYANG_API_DECL uint32_t ly_ctx_get_options(const struct ly_ctx *ctx)
Get the currently set context's options.
libyang context handler.
#define LY_CTX_LEAFREF_LINKING
Definition: context.h:226
LY_ERR
libyang's error codes returned by the libyang functions.
Definition: log.h:252
@ LYVE_DATA
Definition: log.h:290
@ LY_EVALID
Definition: log.h:260
@ LY_SUCCESS
Definition: log.h:253
@ LY_EINCOMPLETE
Definition: log.h:262
Libyang full error structure.
Definition: log.h:298
uint32_t count
Definition: set.h:49
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,...
Structure to hold a set of (not necessary somehow connected) objects. Usually used for lyd_node,...
Definition: set.h:47
const char * module
lyplg_lyb_size_type
Type of the LYB size of a value of a particular type.
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.
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 an error structure.
struct lyxp_expr * path
Definition: tree_schema.h:1357
uintptr_t plugin_ref
Definition: tree_schema.h:1277
struct lysc_type * realtype
Definition: tree_schema.h:1359
uint8_t require_instance
Definition: tree_schema.h:1360
Compiled YANG data node.
Definition: tree_schema.h:1412
const struct lyplg_type_record plugins_leafref[]
Plugin information for leafref type implementation.
Definition: leafref.c:151
uint8_t ly_bool
Type to indicate boolean value.
Definition: log.h:29
API for (user) types plugins.
@ LYD_PATH_STD
Definition: tree_data.h:2350
const struct lysc_type * realtype
Definition: tree_data.h:614
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.
Generic structure for a data node.
Definition: tree_data.h:875
Data node structure for the terminal data tree nodes - leaves and leaf-lists.
Definition: tree_data.h:927
YANG data representation.
Definition: tree_data.h:610
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: utils.h:93