libyang  5.4.9
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
xpath1.0.c
Go to the documentation of this file.
1 
15 #define _GNU_SOURCE
16 
17 #include "plugins_types.h"
18 
19 #include <assert.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "libyang.h"
25 
26 #include "compat.h"
27 #include "ly_common.h"
28 #include "xml.h"
29 #include "xpath.h"
30 
40 LIBYANG_API_DEF LY_ERR
41 lyplg_type_xpath10_print_token(const char *token, uint16_t tok_len, ly_bool is_nametest, const struct lys_module **context_mod,
42  const struct ly_ctx *resolve_ctx, LY_VALUE_FORMAT resolve_format, const void *resolve_prefix_data,
43  LY_VALUE_FORMAT get_format, void *get_prefix_data, char **token_p, struct ly_err_item **err)
44 {
45  LY_ERR ret = LY_SUCCESS;
46  const char *str_begin, *str_next, *prefix;
47  ly_bool is_prefix, has_prefix = 0;
48  char *str = NULL;
49  void *mem;
50  uint32_t len, str_len = 0, pref_len;
51  const struct lys_module *mod;
52 
53  str_begin = token;
54 
55  while (!(ret = ly_value_prefix_next(str_begin, token + tok_len, &len, &is_prefix, &str_next)) && len) {
56  if (!is_prefix) {
57  if (!has_prefix && is_nametest && (get_format == LY_VALUE_XML) && *context_mod) {
58  /* get the prefix */
59  prefix = lyplg_type_get_prefix(*context_mod, get_format, get_prefix_data);
60  assert(prefix);
61 
62  /* append the nametest and prefix */
63  mem = realloc(str, str_len + strlen(prefix) + 1 + len + 1);
64  LY_CHECK_ERR_GOTO(!mem, ret = ly_err_new(err, LY_EMEM, LYVE_DATA, NULL, NULL, "No memory."), cleanup);
65  str = mem;
66  str_len += sprintf(str + str_len, "%s:%.*s", prefix, (int)len, str_begin);
67  } else {
68  /* just append the string, we may get the first expression node without a prefix but since this
69  * is not strictly forbidden, allow it */
70  mem = realloc(str, str_len + len + 1);
71  LY_CHECK_ERR_GOTO(!mem, ret = ly_err_new(err, LY_EMEM, LYVE_DATA, NULL, NULL, "No memory."), cleanup);
72  str = mem;
73  str_len += sprintf(str + str_len, "%.*s", (int)len, str_begin);
74  }
75  } else {
76  /* remember there was a prefix found */
77  has_prefix = 1;
78 
79  /* resolve the module in the original format */
80  mod = lys_find_module(resolve_ctx, NULL, str_begin, len, resolve_format, resolve_prefix_data);
81  if (!mod && is_nametest) {
82  ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Failed to resolve prefix \"%.*s\".",
83  (int)len, str_begin);
84  goto cleanup;
85  }
86 
87  if (is_nametest && ((get_format == LY_VALUE_JSON) || (get_format == LY_VALUE_LYB)) && (*context_mod == mod)) {
88  /* inherit the prefix and do not print it again */
89  } else {
90  if (mod) {
91  /* get the prefix in the target format */
92  prefix = lyplg_type_get_prefix(mod, get_format, get_prefix_data);
93  assert(prefix);
94  pref_len = strlen(prefix);
95  } else {
96  /* invalid prefix, just copy it */
97  prefix = str_begin;
98  pref_len = len;
99  }
100 
101  /* append the prefix */
102  mem = realloc(str, str_len + pref_len + 2);
103  LY_CHECK_ERR_GOTO(!mem, ret = ly_err_new(err, LY_EMEM, LYVE_DATA, NULL, NULL, "No memory."), cleanup);
104  str = mem;
105  str_len += sprintf(str + str_len, "%.*s:", (int)pref_len, prefix);
106  }
107 
108  if (is_nametest) {
109  /* update context module */
110  *context_mod = mod;
111  }
112  }
113 
114  str_begin = str_next;
115  }
116 
117 cleanup:
118  if (ret) {
119  free(str);
120  } else {
121  *token_p = str;
122  }
123  return ret;
124 }
125 
141 static LY_ERR
142 xpath10_print_subexpr_r(uint16_t *cur_idx, enum lyxp_token end_tok, const struct lys_module *context_mod,
143  const struct lyd_value_xpath10 *xp_val, LY_VALUE_FORMAT format, void *prefix_data, char **str_value,
144  uint32_t *str_len, struct ly_err_item **err)
145 {
146  enum lyxp_token cur_tok, sub_end_tok;
147  char *str_tok;
148  void *mem;
149  const char *cur_exp_ptr;
150  ly_bool is_nt;
151  const struct lys_module *orig_context_mod = context_mod;
152 
153  while (*cur_idx < xp_val->exp->used) {
154  cur_tok = xp_val->exp->tokens[*cur_idx];
155  cur_exp_ptr = xp_val->exp->expr + xp_val->exp->tok_pos[*cur_idx];
156 
157  if ((cur_tok == LYXP_TOKEN_NAMETEST) || (cur_tok == LYXP_TOKEN_LITERAL)) {
158  /* tokens that may include prefixes, get them in the target format */
159  is_nt = (cur_tok == LYXP_TOKEN_NAMETEST) ? 1 : 0;
160  LY_CHECK_RET(lyplg_type_xpath10_print_token(cur_exp_ptr, xp_val->exp->tok_len[*cur_idx], is_nt, &context_mod,
161  xp_val->ctx, xp_val->format, xp_val->prefix_data, format, prefix_data, &str_tok, err));
162 
163  /* append the converted token */
164  mem = realloc(*str_value, *str_len + strlen(str_tok) + 1);
165  LY_CHECK_ERR_GOTO(!mem, free(str_tok), error_mem);
166  *str_value = mem;
167  *str_len += sprintf(*str_value + *str_len, "%s", str_tok);
168  free(str_tok);
169 
170  /* token processed */
171  ++(*cur_idx);
172  } else {
173  if ((cur_tok == LYXP_TOKEN_OPER_LOG) || (cur_tok == LYXP_TOKEN_OPER_UNI) || (cur_tok == LYXP_TOKEN_OPER_MATH)) {
174  /* copy the token with spaces around */
175  mem = realloc(*str_value, *str_len + 1 + xp_val->exp->tok_len[*cur_idx] + 2);
176  LY_CHECK_GOTO(!mem, error_mem);
177  *str_value = mem;
178  *str_len += sprintf(*str_value + *str_len, " %.*s ", (int)xp_val->exp->tok_len[*cur_idx], cur_exp_ptr);
179 
180  /* reset context mod */
181  context_mod = orig_context_mod;
182  } else {
183  /* just copy the token */
184  mem = realloc(*str_value, *str_len + xp_val->exp->tok_len[*cur_idx] + 1);
185  LY_CHECK_GOTO(!mem, error_mem);
186  *str_value = mem;
187  *str_len += sprintf(*str_value + *str_len, "%.*s", (int)xp_val->exp->tok_len[*cur_idx], cur_exp_ptr);
188  }
189 
190  /* token processed but keep it in cur_tok */
191  ++(*cur_idx);
192 
193  if (end_tok && (cur_tok == end_tok)) {
194  /* end token found */
195  break;
196  } else if ((cur_tok == LYXP_TOKEN_BRACK1) || (cur_tok == LYXP_TOKEN_PAR1)) {
197  sub_end_tok = (cur_tok == LYXP_TOKEN_BRACK1) ? LYXP_TOKEN_BRACK2 : LYXP_TOKEN_PAR2;
198 
199  /* parse the subexpression separately, use the current context mod */
200  LY_CHECK_RET(xpath10_print_subexpr_r(cur_idx, sub_end_tok, context_mod, xp_val, format, prefix_data,
201  str_value, str_len, err));
202  }
203  }
204  }
205 
206  return LY_SUCCESS;
207 
208 error_mem:
209  return ly_err_new(err, LY_EMEM, LYVE_DATA, NULL, NULL, "No memory.");
210 }
211 
212 LIBYANG_API_DEF LY_ERR
213 lyplg_type_print_xpath10_value(const struct lyd_value_xpath10 *xp_val, LY_VALUE_FORMAT format, void *prefix_data,
214  char **str_value, struct ly_err_item **err)
215 {
216  LY_ERR ret = LY_SUCCESS;
217  uint16_t expr_idx = 0;
218  uint32_t str_len = 0;
219  const struct lys_module *local_mod = NULL;
220  struct ly_set *mods;
221 
222  *str_value = NULL;
223  *err = NULL;
224 
225  if (format == LY_VALUE_XML) {
226  /* null the local module so that all the prefixes are printed */
227  mods = prefix_data;
228  local_mod = mods->objs[0];
229  mods->objs[0] = NULL;
230  }
231 
232  /* recursively print the expression */
233  ret = xpath10_print_subexpr_r(&expr_idx, 0, NULL, xp_val, format, prefix_data, str_value, &str_len, err);
234 
235  if (local_mod) {
236  mods->objs[0] = (void *)local_mod;
237  }
238  if (ret) {
239  free(*str_value);
240  *str_value = NULL;
241  }
242  return ret;
243 }
244 
245 static LY_ERR
246 lyplg_type_store_xpath10(const struct ly_ctx *ctx, const struct lysc_type *type, const void *value, uint64_t value_size_bits,
247  uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node,
248  struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
249 {
250  LY_ERR ret = LY_SUCCESS;
251  const struct ly_err_item *e;
252  uint32_t value_size, temp_lo = LY_LOSTORE;
253  struct lyd_value_xpath10 *val;
254  char *canon;
255 
256  /* init storage */
257  memset(storage, 0, sizeof *storage);
258  LYPLG_TYPE_VAL_INLINE_PREPARE(storage, val);
259  LY_CHECK_ERR_GOTO(!val, ret = LY_EMEM, cleanup);
260  storage->realtype = type;
261 
262  /* check value length */
263  ret = lyplg_type_check_value_size("xpath1.0", format, value_size_bits, LYPLG_LYB_SIZE_VARIABLE_BYTES, 0,
264  &value_size, err);
265  LY_CHECK_GOTO(ret, cleanup);
266 
267  /* check hints */
268  ret = lyplg_type_check_hints(hints, value, value_size, type->basetype, NULL, err);
269  LY_CHECK_GOTO(ret, cleanup);
270 
271  /* parse */
272  ly_temp_log_options(&temp_lo);
273  ret = lyxp_expr_parse(ctx, NULL, value_size ? value : "", value_size, 1, &val->exp);
274  ly_temp_log_options(NULL);
275  if (ret) {
276  /* get a copy of the error */
277  e = ly_err_last(ctx);
278  if (e) {
279  ly_err_new(err, e->err, e->vecode, e->data_path, e->apptag, "%s", e->msg);
280  ly_err_clean(ctx, (struct ly_err_item *)e);
281  }
282  goto cleanup;
283  }
284  val->ctx = ctx;
285 
286  if (ctx_node && !strcmp(ctx_node->name, "parent-reference") && !strcmp(ctx_node->module->name, "ietf-yang-schema-mount")) {
287  /* special case, this type uses prefix-namespace mapping provided directly in data, keep empty for now */
288  val->format = format = LY_VALUE_STR_NS;
289  ret = ly_set_new((struct ly_set **)&val->prefix_data);
290  LY_CHECK_GOTO(ret, cleanup);
291  } else {
292  /* store format-specific data and context for later prefix resolution */
293  ret = lyplg_type_prefix_data_new(ctx, value, value_size, format, prefix_data, &val->format, &val->prefix_data);
294  LY_CHECK_GOTO(ret, cleanup);
295  }
296 
297  switch (format) {
298  case LY_VALUE_CANON:
299  case LY_VALUE_JSON:
300  case LY_VALUE_LYB:
301  case LY_VALUE_STR_NS:
302  /* store canonical value */
303  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
304  ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
305  options &= ~LYPLG_TYPE_STORE_DYNAMIC;
306  LY_CHECK_GOTO(ret, cleanup);
307  } else {
308  ret = lydict_insert(ctx, value_size ? value : "", value_size, &storage->_canonical);
309  LY_CHECK_GOTO(ret, cleanup);
310  }
311  break;
312  case LY_VALUE_SCHEMA:
314  case LY_VALUE_XML:
315  /* JSON format with prefix is the canonical one */
316  ret = lyplg_type_print_xpath10_value(val, LY_VALUE_JSON, NULL, &canon, err);
317  LY_CHECK_GOTO(ret, cleanup);
318 
319  ret = lydict_insert_zc(ctx, canon, &storage->_canonical);
320  LY_CHECK_GOTO(ret, cleanup);
321  break;
322  }
323 
324 cleanup:
325  if (options & LYPLG_TYPE_STORE_DYNAMIC) {
326  free((void *)value);
327  }
328 
329  if (ret) {
330  lyplg_type_free_xpath10(ctx, storage);
331  } else if (val->format == LY_VALUE_STR_NS) {
332  /* needs validation */
333  return LY_EINCOMPLETE;
334  }
335  return ret;
336 }
337 
346 static LY_ERR
347 xpath10_add_ns(struct ly_set *set, const char *pref, const char *uri)
348 {
349  LY_ERR rc = LY_SUCCESS;
350  struct lyxml_ns *ns = NULL;
351 
352  /* create new ns */
353  ns = calloc(1, sizeof *ns);
354  if (!ns) {
355  rc = LY_EMEM;
356  goto cleanup;
357  }
358  ns->prefix = strdup(pref);
359  ns->uri = strdup(uri);
360  if (!ns->prefix || !ns->uri) {
361  rc = LY_EMEM;
362  goto cleanup;
363  }
364  ns->depth = 1;
365 
366  /* add into the XML namespace set */
367  if ((rc = ly_set_add(set, ns, 1, NULL))) {
368  goto cleanup;
369  }
370  ns = NULL;
371 
372 cleanup:
373  if (ns) {
374  free(ns->prefix);
375  free(ns->uri);
376  free(ns);
377  }
378  return rc;
379 }
380 
384 static LY_ERR
385 lyplg_type_validate_tree_xpath10(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *UNUSED(type),
386  const struct lyd_node *ctx_node, const struct lyd_node *UNUSED(tree), struct lyd_value *storage,
387  struct ly_err_item **err)
388 {
389  LY_ERR ret = LY_SUCCESS;
390  struct lyd_value_xpath10 *val;
391  struct ly_set *set = NULL;
392  uint32_t i;
393  const char *pref, *uri;
394  const struct ly_err_item *eitem;
395 
396  *err = NULL;
397  LYD_VALUE_GET(storage, val);
398 
399  if (val->format != LY_VALUE_STR_NS) {
400  /* nothing to validate */
401  return LY_SUCCESS;
402  }
403 
404  /* the XML namespace set must exist */
405  assert(val->prefix_data);
406 
407  /* special handling of this particular node */
408  assert(!strcmp(LYD_NAME(ctx_node), "parent-reference") &&
409  !strcmp(ctx_node->schema->module->name, "ietf-yang-schema-mount"));
410 
411  /* get all the prefix mappings */
412  if ((ret = lyd_find_xpath(ctx_node, "../../../namespace", &set))) {
413  goto cleanup;
414  }
415 
416  for (i = 0; i < set->count; ++i) {
417  assert(!strcmp(LYD_NAME(lyd_child(set->dnodes[i])), "prefix"));
418  pref = lyd_get_value(lyd_child(set->dnodes[i]));
419 
420  if (!lyd_child(set->dnodes[i])->next) {
421  /* missing URI - invalid mapping, skip */
422  continue;
423  }
424  assert(!strcmp(LYD_NAME(lyd_child(set->dnodes[i])->next), "uri"));
425  uri = lyd_get_value(lyd_child(set->dnodes[i])->next);
426 
427  /* new NS */
428  if ((ret = xpath10_add_ns(val->prefix_data, pref, uri))) {
429  goto cleanup;
430  }
431  }
432 
433 cleanup:
434  ly_set_free(set, NULL);
435  if (ret == LY_EMEM) {
436  ly_err_new(err, LY_EMEM, LYVE_DATA, NULL, NULL, LY_EMEM_MSG);
437  } else if (ret) {
438  eitem = ly_err_last(LYD_CTX(ctx_node));
439  ly_err_new(err, ret, LYVE_DATA, eitem->data_path, NULL, "%s", eitem->msg);
440  }
441  return ret;
442 }
443 
444 LIBYANG_API_DEF const void *
445 lyplg_type_print_xpath10(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
446  void *prefix_data, ly_bool *dynamic, uint64_t *value_size_bits)
447 {
448  struct lyd_value_xpath10 *val;
449  char *ret;
450  struct ly_err_item *err = NULL;
451 
452  LYD_VALUE_GET(value, val);
453 
454  /* LY_VALUE_STR_NS should never be transformed */
455  if ((val->format == LY_VALUE_STR_NS) || (format == LY_VALUE_CANON) || (format == LY_VALUE_JSON) ||
456  (format == LY_VALUE_LYB)) {
457  /* canonical */
458  if (dynamic) {
459  *dynamic = 0;
460  }
461  if (value_size_bits) {
462  *value_size_bits = strlen(value->_canonical) * 8;
463  }
464  return value->_canonical;
465  }
466 
467  /* print in the specific format */
468  if (lyplg_type_print_xpath10_value(val, format, prefix_data, &ret, &err)) {
469  if (err) {
470  ly_err_print(ctx, err, NULL, NULL);
471  ly_err_free(err);
472  }
473  return NULL;
474  }
475 
476  *dynamic = 1;
477  if (value_size_bits) {
478  *value_size_bits = strlen(ret) * 8;
479  }
480  return ret;
481 }
482 
483 LIBYANG_API_DEF LY_ERR
484 lyplg_type_dup_xpath10(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
485 {
486  LY_ERR ret = LY_SUCCESS;
487  struct lyd_value_xpath10 *orig_val, *dup_val;
488 
489  /* init dup value */
490  memset(dup, 0, sizeof *dup);
491  dup->realtype = original->realtype;
492 
493  ret = lydict_insert(ctx, original->_canonical, 0, &dup->_canonical);
494  LY_CHECK_GOTO(ret, cleanup);
495 
496  LYPLG_TYPE_VAL_INLINE_PREPARE(dup, dup_val);
497  LY_CHECK_ERR_GOTO(!dup_val, LOGMEM(ctx); ret = LY_EMEM, cleanup);
498  dup_val->ctx = ctx;
499 
500  LYD_VALUE_GET(original, orig_val);
501  ret = lyxp_expr_dup(ctx, orig_val->exp, 0, 0, &dup_val->exp);
502  LY_CHECK_GOTO(ret, cleanup);
503 
504  ret = lyplg_type_prefix_data_dup(ctx, orig_val->format, orig_val->prefix_data, &dup_val->prefix_data);
505  LY_CHECK_GOTO(ret, cleanup);
506  dup_val->format = orig_val->format;
507 
508 cleanup:
509  if (ret) {
510  lyplg_type_free_xpath10(ctx, dup);
511  }
512  return ret;
513 }
514 
515 LIBYANG_API_DEF void
516 lyplg_type_free_xpath10(const struct ly_ctx *ctx, struct lyd_value *value)
517 {
518  struct lyd_value_xpath10 *val;
519 
520  lydict_remove(ctx, value->_canonical);
521  value->_canonical = NULL;
522  LYD_VALUE_GET(value, val);
523  if (val) {
524  lyxp_expr_free(val->exp);
526 
528  }
529 }
530 
539  {
540  .module = "ietf-yang-types",
541  .revision = NULL,
542  .name = "xpath1.0",
543 
544  .plugin.id = "ly2 xpath1.0",
545  .plugin.lyb_size = lyplg_type_lyb_size_variable_bytes,
546  .plugin.store = lyplg_type_store_xpath10,
547  .plugin.validate_value = NULL,
548  .plugin.validate_tree = lyplg_type_validate_tree_xpath10,
549  .plugin.compare = lyplg_type_compare_simple,
550  .plugin.sort = lyplg_type_sort_simple,
551  .plugin.print = lyplg_type_print_xpath10,
552  .plugin.duplicate = lyplg_type_dup_xpath10,
553  .plugin.free = lyplg_type_free_xpath10,
554  },
555  {0}
556 };
struct lysc_type * realtype
Definition: tree_data.h:527
Compiled YANG data node.
Definition: tree_schema.h:1431
memset(value->fixed_mem, 0, LYD_VALUE_FIXED_MEM_SIZE)
Generic structure for a data node.
Definition: tree_data.h:783
LIBYANG_API_DECL void ly_err_clean(const struct ly_ctx *ctx, struct ly_err_item *eitem)
Free error structures from a context.
LIBYANG_API_DECL LY_ERR lyd_find_xpath(const struct lyd_node *ctx_node, const char *xpath, struct ly_set **set)
Search in the given data for instances of nodes matching the provided XPath.
LIBYANG_API_DECL void lyplg_type_lyb_size_variable_bytes(const struct lysc_type *type, enum lyplg_lyb_size_type *size_type, uint64_t *fixed_size_bits)
Implementation of lyplg_type_lyb_size_clb for a type with variable length rounded to bytes...
LIBYANG_API_DECL uint32_t * ly_temp_log_options(uint32_t *opts)
Set temporary thread-safe (thread-specific) logger options overwriting those set by ly_log_options()...
LIBYANG_API_DECL struct lys_module * lys_find_module(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const char *prefix, uint32_t prefix_len, LY_VALUE_FORMAT format, const void *prefix_data)
Find a module matching a prefix (or a default one).
LIBYANG_API_DECL LY_ERR lyplg_type_compare_simple(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_compare_clb for a generic simple type.
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
LY_ERR err
Definition: log.h:302
LIBYANG_API_DECL LY_ERR lyplg_type_check_value_size(const char *type_name, LY_VALUE_FORMAT format, uint64_t value_size_bits, enum lyplg_lyb_size_type lyb_size_type, uint64_t lyb_fixed_size_bits, uint32_t *value_size, struct ly_err_item **err)
Check a value type in bits is correct and as expected.
const char * name
Definition: tree_schema.h:1442
#define LYPLG_TYPE_STORE_DYNAMIC
LIBYANG_API_DECL const void * lyplg_type_print_xpath10(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format, void *prefix_data, ly_bool *dynamic, uint64_t *value_size_bits)
Implementation of lyplg_type_print_clb for the ietf-yang-types xpath1.0 type.
Definition: xpath1.0.c:445
#define LOGMEM(CTX)
Definition: tree_edit.h:22
LIBYANG_API_DECL LY_ERR lyplg_type_prefix_data_new(const struct ly_ctx *ctx, const void *value, uint32_t value_size, LY_VALUE_FORMAT format, const void *prefix_data, LY_VALUE_FORMAT *format_p, void **prefix_data_p)
Store used prefixes in a string into an internal libyang structure used in lyd_value.
char * apptag
Definition: log.h:308
char * msg
Definition: log.h:304
void * prefix_data
Definition: tree_data.h:703
LIBYANG_API_DECL void ly_err_print(const struct ly_ctx *ctx, const struct ly_err_item *eitem, const struct lyd_node *lnode, const struct lysc_node *snode)
Print the error structure as if just generated.
LIBYANG_API_DECL LY_ERR lyplg_type_dup_xpath10(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
Implementation of lyplg_type_dup_clb for the ietf-yang-types xpath1.0 type.
Definition: xpath1.0.c:484
LIBYANG_API_DEF int lyplg_type_sort_simple(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
Implementation of lyplg_type_sort_clb for a generic simple type.
LIBYANG_API_DECL LY_ERR ly_set_add(struct ly_set *set, const void *object, ly_bool list, uint32_t *index_p)
Add an object into the set.
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 lysc_node * schema
Definition: tree_data.h:789
LIBYANG_API_DECL const char * lyplg_type_get_prefix(const struct lys_module *mod, LY_VALUE_FORMAT format, void *prefix_data)
Get format-specific prefix for a module.
LYPLG_TYPE_VAL_INLINE_DESTROY(val)
Definition: log.h:257
The main libyang public header.
YANG data representation.
Definition: tree_data.h:523
const char * _canonical
Definition: tree_data.h:524
uint32_t count
Definition: set.h:49
Libyang full error structure.
Definition: log.h:300
struct ly_ctx * ctx
Definition: tree_data.h:702
Definition: log.h:292
#define LYD_VALUE_GET(value, type_val)
Get the value in format specific to the type.
Definition: tree_data.h:566
LIBYANG_API_DECL LY_ERR LIBYANG_API_DECL void ly_err_free(void *ptr)
Destructor for the error records created with ly_err_new().
struct lyplg_type_record plugins_xpath10[]
Plugin information for xpath1.0 type implementation.
Definition: xpath1.0.c:538
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.
#define LYD_NAME(node)
Get the name (associated with) of a data node. Works for opaque nodes as well.
Definition: tree_data.h:900
Structure to hold a set of (not necessary somehow connected) objects. Usually used for lyd_node...
Definition: set.h:47
LIBYANG_API_DECL LY_ERR lydict_remove(const struct ly_ctx *ctx, const char *value)
Remove specified string from the dictionary. It decrement reference counter for the string and if it ...
LIBYANG_API_DECL LY_ERR lydict_insert(const struct ly_ctx *ctx, const char *value, size_t len, const char **str_p)
Insert string into dictionary. If the string is already present, only a reference counter is incremen...
Available YANG schema tree structures representing YANG module.
Definition: tree_schema.h:2256
Definition: log.h:263
const char * module
LIBYANG_API_DECL LY_ERR lyplg_type_prefix_data_dup(const struct ly_ctx *ctx, LY_VALUE_FORMAT format, const void *orig, void **dup)
Duplicate prefix data.
LIBYANG_API_DECL void lyplg_type_prefix_data_free(LY_VALUE_FORMAT format, void *prefix_data)
Free internal prefix data.
LIBYANG_API_DECL LY_ERR lydict_insert_zc(const struct ly_ctx *ctx, char *value, const char **str_p)
Insert string into dictionary - zerocopy version. If the string is already present, only a reference counter is incremented and no memory allocation is performed. This insert function variant avoids duplication of specified value - it is inserted into the dictionary directly.
struct lys_module * module
Definition: tree_schema.h:1435
Special lyd_value structure for ietf-yang-types xpath1.0 values.
Definition: tree_data.h:700
#define LYD_CTX(node)
Macro to get context from a data tree node.
Definition: tree_data.h:494
LIBYANG_API_DECL LY_ERR lyplg_type_print_xpath10_value(const struct lyd_value_xpath10 *xp_val, LY_VALUE_FORMAT format, void *prefix_data, char **str_value, struct ly_err_item **err)
Print xpath1.0 value in the specific format.
Definition: xpath1.0.c:213
LY_VALUE_FORMAT format
Definition: tree_data.h:704
LY_VECODE vecode
Definition: log.h:303
LY_VALUE_FORMAT
All kinds of supported value formats and prefix mappings to modules.
Definition: tree.h:234
LIBYANG_API_DECL struct ly_err_item * ly_err_last(const struct ly_ctx *ctx)
Get the latest (thread, context-specific) generated error structure.
#define LYPLG_TYPE_VAL_INLINE_PREPARE(storage, type_val)
Prepare value memory for storing a specific type value, may be allocated dynamically.
LIBYANG_API_DECL LY_ERR ly_set_new(struct ly_set **set_p)
Create and initiate new ly_set structure.
LIBYANG_API_DECL void lyplg_type_free_xpath10(const struct ly_ctx *ctx, struct lyd_value *value)
Implementation of lyplg_type_free_clb for the ietf-yang-types xpath1.0 type.
Definition: xpath1.0.c:516
LY_DATA_TYPE basetype
Definition: tree_schema.h:1297
LIBYANG_API_DECL LY_ERR lyplg_type_xpath10_print_token(const char *token, uint16_t tok_len, ly_bool is_nametest, const struct lys_module **context_mod, const struct ly_ctx *resolve_ctx, LY_VALUE_FORMAT resolve_format, const void *resolve_prefix_data, LY_VALUE_FORMAT get_format, void *get_prefix_data, char **token_p, struct ly_err_item **err)
Print xpath1.0 token in the specific format.
Definition: xpath1.0.c:41
struct lyxp_expr * exp
Definition: tree_data.h:701
LIBYANG_API_DECL LY_ERR lyplg_type_check_hints(uint32_t hints, const char *value, uint32_t value_len, LY_DATA_TYPE type, int *base, struct ly_err_item **err)
Check that the type is suitable for the parser&#39;s hints (if any) in the specified format.
API for (user) types plugins.
#define LY_LOSTORE
Definition: log.h:122
libyang context handler.
const char * name
Definition: tree_schema.h:2258
char * data_path
Definition: log.h:305
assert(!value->_canonical)