Merging upstream version 3.4.2+dfsg.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
511f72b68b
commit
948b3e00b3
75 changed files with 1082 additions and 878 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
@ -64,13 +64,13 @@ jobs:
|
|||
build-cmd: "make"
|
||||
}
|
||||
- {
|
||||
name: "Release, macOS 11, clang",
|
||||
os: "macos-11",
|
||||
name: "Release, macOS 14, clang",
|
||||
os: "macos-14",
|
||||
build-type: "Release",
|
||||
cc: "clang",
|
||||
options: "-DENABLE_TESTS=ON -DPATH_EXPECT=",
|
||||
packager: "brew",
|
||||
packages: "cmocka shunit2",
|
||||
packages: "cmocka shunit2 tcl-tk",
|
||||
snaps: "",
|
||||
build-cmd: "make"
|
||||
}
|
||||
|
|
|
@ -59,14 +59,14 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|||
|
||||
# set version of the project
|
||||
set(LIBYANG_MAJOR_VERSION 3)
|
||||
set(LIBYANG_MINOR_VERSION 1)
|
||||
set(LIBYANG_MICRO_VERSION 0)
|
||||
set(LIBYANG_MINOR_VERSION 4)
|
||||
set(LIBYANG_MICRO_VERSION 2)
|
||||
set(LIBYANG_VERSION ${LIBYANG_MAJOR_VERSION}.${LIBYANG_MINOR_VERSION}.${LIBYANG_MICRO_VERSION})
|
||||
|
||||
# set version of the library
|
||||
set(LIBYANG_MAJOR_SOVERSION 3)
|
||||
set(LIBYANG_MINOR_SOVERSION 2)
|
||||
set(LIBYANG_MICRO_SOVERSION 0)
|
||||
set(LIBYANG_MINOR_SOVERSION 4)
|
||||
set(LIBYANG_MICRO_SOVERSION 2)
|
||||
set(LIBYANG_SOVERSION_FULL ${LIBYANG_MAJOR_SOVERSION}.${LIBYANG_MINOR_SOVERSION}.${LIBYANG_MICRO_SOVERSION})
|
||||
set(LIBYANG_SOVERSION ${LIBYANG_MAJOR_SOVERSION})
|
||||
|
||||
|
@ -106,7 +106,8 @@ set(type_plugins
|
|||
src/plugins_types/date_and_time.c
|
||||
src/plugins_types/hex_string.c
|
||||
src/plugins_types/xpath1.0.c
|
||||
src/plugins_types/node_instanceid.c)
|
||||
src/plugins_types/node_instanceid.c
|
||||
src/plugins_types/time_period.c)
|
||||
|
||||
set(libsrc
|
||||
src/ly_common.c
|
||||
|
@ -471,7 +472,7 @@ endif()
|
|||
|
||||
# generate API/ABI report
|
||||
if("${BUILD_TYPE_UPPER}" STREQUAL "ABICHECK")
|
||||
lib_abi_check(yang "${headers}" ${LIBYANG_SOVERSION_FULL} 708a8bfad983a4095c8d4dc537a9d2a1d5ca65c5)
|
||||
lib_abi_check(yang "${headers}" ${LIBYANG_SOVERSION_FULL} 670385f9595014dc9307615fa6e929b46dba026b)
|
||||
endif()
|
||||
|
||||
# source code format target for Makefile
|
||||
|
|
|
@ -58,8 +58,6 @@ the `distro` directory.
|
|||
* C compiler
|
||||
* cmake >= 2.8.12
|
||||
* libpcre2 >= 10.21 (including devel package)
|
||||
* note, that PCRE is supposed to be compiled with unicode support (configure's options
|
||||
`--enable-utf` and `--enable-unicode-properties`)
|
||||
|
||||
#### Optional
|
||||
|
||||
|
|
|
@ -721,7 +721,7 @@ ly_ctx_unset_options(struct ly_ctx *ctx, uint16_t option)
|
|||
ext = &mod->compiled->exts[u];
|
||||
LY_ARRAY_FOR(ext->substmts, v) {
|
||||
if (ext->substmts[v].stmt & LY_STMT_DATA_NODE_MASK) {
|
||||
LY_LIST_FOR(*VOIDPTR2_C(ext->substmts[v].storage), root) {
|
||||
LY_LIST_FOR(*ext->substmts[v].storage_p, root) {
|
||||
lysc_tree_dfs_full(root, lysc_node_clear_priv_dfs_cb, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -602,10 +602,10 @@ LIBYANG_API_DECL const struct lysp_submodule *ly_ctx_get_submodule2_latest(const
|
|||
LIBYANG_API_DECL uint32_t ly_ctx_internal_modules_count(const struct ly_ctx *ctx);
|
||||
|
||||
/**
|
||||
* @brief Try to find the model in the searchpaths of \p ctx and load it into it. If custom missing
|
||||
* @brief Try to find the model in the searchpaths of @p ctx and load it into it. If custom missing
|
||||
* module callback is set, it is used instead.
|
||||
*
|
||||
* The context itself is searched for the requested module first. If \p revision is not specified
|
||||
* The context itself is searched for the requested module first. If @p revision is not specified
|
||||
* (the module of the latest revision is requested) and there is implemented revision of the requested
|
||||
* module in the context, this implemented revision is returned despite there might be a newer revision.
|
||||
* This behavior is cause by the fact that it is not possible to have multiple implemented revisions of
|
||||
|
@ -660,7 +660,7 @@ LIBYANG_API_DECL LY_ERR ly_ctx_get_yanglib_data(const struct ly_ctx *ctx, struct
|
|||
* Note that the data stored by user into the ::lysc_node.priv pointer are kept
|
||||
* untouched and the caller is responsible for freeing this private data.
|
||||
*
|
||||
* @param[in] ctx libyang context to destroy
|
||||
* @param[in] ctx Context to destroy.
|
||||
*/
|
||||
LIBYANG_API_DECL void ly_ctx_destroy(struct ly_ctx *ctx);
|
||||
|
||||
|
|
55
src/dict.c
55
src/dict.c
|
@ -104,9 +104,6 @@ lydict_resize_val_eq(void *val1_p, void *val2_p, ly_bool mod, void *UNUSED(cb_da
|
|||
str1 = ((struct ly_dict_rec *)val1_p)->value;
|
||||
str2 = ((struct ly_dict_rec *)val2_p)->value;
|
||||
|
||||
LY_CHECK_ERR_RET(!str1, LOGARG(NULL, val1_p), 0);
|
||||
LY_CHECK_ERR_RET(!str2, LOGARG(NULL, val2_p), 0);
|
||||
|
||||
if (mod) {
|
||||
/* used when inserting new values */
|
||||
if (strcmp(str1, str2) == 0) {
|
||||
|
@ -177,7 +174,7 @@ finish:
|
|||
return ret;
|
||||
}
|
||||
|
||||
LY_ERR
|
||||
static LY_ERR
|
||||
dict_insert(const struct ly_ctx *ctx, char *value, size_t len, ly_bool zerocopy, const char **str_p)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
@ -221,9 +218,7 @@ dict_insert(const struct ly_ctx *ctx, char *value, size_t len, ly_bool zerocopy,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (str_p) {
|
||||
*str_p = match->value;
|
||||
}
|
||||
*str_p = match->value;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -269,3 +264,49 @@ lydict_insert_zc(const struct ly_ctx *ctx, char *value, const char **str_p)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
static LY_ERR
|
||||
dict_dup(const struct ly_ctx *ctx, char *value, const char **str_p)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
struct ly_dict_rec *match = NULL, rec;
|
||||
uint32_t hash;
|
||||
|
||||
/* set new callback to only compare memory addresses */
|
||||
lyht_value_equal_cb prev = lyht_set_cb(ctx->dict.hash_tab, lydict_resize_val_eq);
|
||||
|
||||
LOGDBG(LY_LDGDICT, "duplicating %s", value);
|
||||
hash = lyht_hash(value, strlen(value));
|
||||
rec.value = value;
|
||||
|
||||
ret = lyht_find(ctx->dict.hash_tab, (void *)&rec, hash, (void **)&match);
|
||||
if (ret == LY_SUCCESS) {
|
||||
/* record found, increase refcount */
|
||||
match->refcount++;
|
||||
*str_p = match->value;
|
||||
}
|
||||
|
||||
/* restore callback */
|
||||
lyht_set_cb(ctx->dict.hash_tab, prev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
lydict_dup(const struct ly_ctx *ctx, const char *value, const char **str_p)
|
||||
{
|
||||
LY_ERR result;
|
||||
|
||||
LY_CHECK_ARG_RET(ctx, ctx, str_p, LY_EINVAL);
|
||||
|
||||
if (!value) {
|
||||
*str_p = NULL;
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
pthread_mutex_lock((pthread_mutex_t *)&ctx->dict.lock);
|
||||
result = dict_dup(ctx, (char *)value, str_p);
|
||||
pthread_mutex_unlock((pthread_mutex_t *)&ctx->dict.lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
12
src/dict.h
12
src/dict.h
|
@ -113,6 +113,18 @@ LIBYANG_API_DECL LY_ERR lydict_insert_zc(const struct ly_ctx *ctx, char *value,
|
|||
*/
|
||||
LIBYANG_API_DECL LY_ERR lydict_remove(const struct ly_ctx *ctx, const char *value);
|
||||
|
||||
/**
|
||||
* @brief Duplicate string in dictionary. Only a reference counter is incremented.
|
||||
*
|
||||
* @param[in] ctx libyang context handler
|
||||
* @param[in] value NULL-terminated string to be duplicated in the dictionary (reference counter is incremented).
|
||||
* @param[out] str_p Optional parameter to get pointer to the string corresponding to the @p value and stored in dictionary.
|
||||
* @return LY_SUCCESS in case the string already exists in the dictionary.
|
||||
* @return LY_ENOTFOUND in case the string was not found.
|
||||
* @return LY_ERR on other errors
|
||||
*/
|
||||
LIBYANG_API_DECL LY_ERR lydict_dup(const struct ly_ctx *ctx, const char *value, const char **str_p);
|
||||
|
||||
/** @} dict */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -179,6 +179,7 @@ lyht_free(struct ly_ht *ht, void (*val_free)(void *val_p))
|
|||
*
|
||||
* @param[in] ht Hash table to resize.
|
||||
* @param[in] operation Operation to perform. 1 to enlarge, -1 to shrink, 0 to only rehash all records.
|
||||
* @param[in] check Whether to check if the value has already been inserted or not.
|
||||
* @return LY_ERR value.
|
||||
*/
|
||||
static LY_ERR
|
||||
|
@ -247,7 +248,6 @@ lyht_resize(struct ly_ht *ht, int operation, int check)
|
|||
* @param[in] hash Hash to find.
|
||||
* @param[in] mod Whether the operation modifies the hash table (insert or remove) or not (find).
|
||||
* @param[in] val_equal Callback for checking value equivalence.
|
||||
* @param[out] crec_p Optional found first record.
|
||||
* @param[out] col Optional collision number of @p rec_p, 0 for no collision.
|
||||
* @param[out] rec_p Found exact matching record, may be a collision of @p crec_p.
|
||||
* @return LY_ENOTFOUND if no record found,
|
||||
|
@ -255,15 +255,12 @@ lyht_resize(struct ly_ht *ht, int operation, int check)
|
|||
*/
|
||||
static LY_ERR
|
||||
lyht_find_rec(const struct ly_ht *ht, void *val_p, uint32_t hash, ly_bool mod, lyht_value_equal_cb val_equal,
|
||||
struct ly_ht_rec **crec_p, uint32_t *col, struct ly_ht_rec **rec_p)
|
||||
uint32_t *col, struct ly_ht_rec **rec_p)
|
||||
{
|
||||
uint32_t hlist_idx = hash & (ht->size - 1);
|
||||
struct ly_ht_rec *rec;
|
||||
uint32_t rec_idx;
|
||||
|
||||
if (crec_p) {
|
||||
*crec_p = NULL;
|
||||
}
|
||||
if (col) {
|
||||
*col = 0;
|
||||
}
|
||||
|
@ -271,9 +268,6 @@ lyht_find_rec(const struct ly_ht *ht, void *val_p, uint32_t hash, ly_bool mod, l
|
|||
|
||||
LYHT_ITER_HLIST_RECS(ht, hlist_idx, rec_idx, rec) {
|
||||
if ((rec->hash == hash) && val_equal(val_p, &rec->val, mod, ht->cb_data)) {
|
||||
if (crec_p) {
|
||||
*crec_p = rec;
|
||||
}
|
||||
*rec_p = rec;
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
@ -292,7 +286,11 @@ lyht_find(const struct ly_ht *ht, void *val_p, uint32_t hash, void **match_p)
|
|||
{
|
||||
struct ly_ht_rec *rec;
|
||||
|
||||
lyht_find_rec(ht, val_p, hash, 0, ht->val_equal, NULL, NULL, &rec);
|
||||
if (match_p) {
|
||||
*match_p = NULL;
|
||||
}
|
||||
|
||||
lyht_find_rec(ht, val_p, hash, 0, ht->val_equal, NULL, &rec);
|
||||
|
||||
if (rec && match_p) {
|
||||
*match_p = rec->val;
|
||||
|
@ -305,7 +303,7 @@ lyht_find_with_val_cb(const struct ly_ht *ht, void *val_p, uint32_t hash, lyht_v
|
|||
{
|
||||
struct ly_ht_rec *rec;
|
||||
|
||||
lyht_find_rec(ht, val_p, hash, 0, val_equal ? val_equal : ht->val_equal, NULL, NULL, &rec);
|
||||
lyht_find_rec(ht, val_p, hash, 0, val_equal ? val_equal : ht->val_equal, NULL, &rec);
|
||||
|
||||
if (rec && match_p) {
|
||||
*match_p = rec->val;
|
||||
|
@ -317,12 +315,12 @@ LIBYANG_API_DEF LY_ERR
|
|||
lyht_find_next_with_collision_cb(const struct ly_ht *ht, void *val_p, uint32_t hash,
|
||||
lyht_value_equal_cb collision_val_equal, void **match_p)
|
||||
{
|
||||
struct ly_ht_rec *rec, *crec;
|
||||
struct ly_ht_rec *rec;
|
||||
uint32_t rec_idx;
|
||||
uint32_t i;
|
||||
|
||||
/* find the record of the previously found value */
|
||||
if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, &crec, &i, &rec)) {
|
||||
if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, &i, &rec)) {
|
||||
/* not found, cannot happen */
|
||||
LOGINT_RET(NULL);
|
||||
}
|
||||
|
@ -373,7 +371,7 @@ _lyht_insert_with_resize_cb(struct ly_ht *ht, void *val_p, uint32_t hash, lyht_v
|
|||
uint32_t rec_idx;
|
||||
|
||||
if (check) {
|
||||
if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, NULL, NULL, &rec) == LY_SUCCESS) {
|
||||
if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, NULL, &rec) == LY_SUCCESS) {
|
||||
if (rec && match_p) {
|
||||
*match_p = rec->val;
|
||||
}
|
||||
|
@ -459,7 +457,7 @@ lyht_remove_with_resize_cb(struct ly_ht *ht, void *val_p, uint32_t hash, lyht_va
|
|||
uint32_t prev_rec_idx;
|
||||
uint32_t rec_idx;
|
||||
|
||||
if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, NULL, NULL, &found_rec)) {
|
||||
if (lyht_find_rec(ht, val_p, hash, 1, ht->val_equal, NULL, &found_rec)) {
|
||||
LOGARG(NULL, hash);
|
||||
return LY_ENOTFOUND;
|
||||
}
|
||||
|
|
11
src/log.c
11
src/log.c
|
@ -189,10 +189,15 @@ ly_err_get_rec(const struct ly_ctx *ctx)
|
|||
/* prepare record */
|
||||
rec.tid = pthread_self();
|
||||
|
||||
/* reuse lock */
|
||||
/* LOCK */
|
||||
pthread_mutex_lock((pthread_mutex_t *)&ctx->lyb_hash_lock);
|
||||
|
||||
/* get the pointer to the matching record */
|
||||
if (lyht_find(ctx->err_ht, &rec, lyht_hash((void *)&rec.tid, sizeof rec.tid), (void **)&match)) {
|
||||
return NULL;
|
||||
}
|
||||
lyht_find(ctx->err_ht, &rec, lyht_hash((void *)&rec.tid, sizeof rec.tid), (void **)&match);
|
||||
|
||||
/* UNLOCK */
|
||||
pthread_mutex_unlock((pthread_mutex_t *)&ctx->lyb_hash_lock);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
|
|
@ -40,19 +40,53 @@
|
|||
#include "version.h"
|
||||
#include "xml.h"
|
||||
|
||||
LIBYANG_API_DEF struct ly_version ly_version_so = {
|
||||
.major = LY_VERSION_MAJOR,
|
||||
.minor = LY_VERSION_MINOR,
|
||||
.micro = LY_VERSION_MICRO,
|
||||
.str = LY_VERSION
|
||||
};
|
||||
LIBYANG_API_DEF uint32_t
|
||||
ly_version_so_major(void)
|
||||
{
|
||||
return LY_VERSION_MAJOR;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF struct ly_version ly_version_proj = {
|
||||
.major = LY_PROJ_VERSION_MAJOR,
|
||||
.minor = LY_PROJ_VERSION_MINOR,
|
||||
.micro = LY_PROJ_VERSION_MICRO,
|
||||
.str = LY_PROJ_VERSION
|
||||
};
|
||||
LIBYANG_API_DEF uint32_t
|
||||
ly_version_so_minor(void)
|
||||
{
|
||||
return LY_VERSION_MINOR;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF uint32_t
|
||||
ly_version_so_micro(void)
|
||||
{
|
||||
return LY_VERSION_MICRO;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF const char *
|
||||
ly_version_so_str(void)
|
||||
{
|
||||
return LY_VERSION;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF uint32_t
|
||||
ly_version_proj_major(void)
|
||||
{
|
||||
return LY_PROJ_VERSION_MAJOR;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF uint32_t
|
||||
ly_version_proj_minor(void)
|
||||
{
|
||||
return LY_PROJ_VERSION_MINOR;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF uint32_t
|
||||
ly_version_proj_micro(void)
|
||||
{
|
||||
return LY_PROJ_VERSION_MICRO;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF const char *
|
||||
ly_version_proj_str(void)
|
||||
{
|
||||
return LY_PROJ_VERSION;
|
||||
}
|
||||
|
||||
void *
|
||||
ly_realloc(void *ptr, size_t size)
|
||||
|
|
|
@ -61,9 +61,6 @@ struct lysc_node;
|
|||
#define GETMACRO6(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
|
||||
#define GETMACRO7(_1, _2, _3, _4, _5, _6, _7, NAME, ...) NAME
|
||||
|
||||
#define VOIDPTR_C(var) ((void *)(uintptr_t)(var))
|
||||
#define VOIDPTR2_C(var) ((void **)(uintptr_t)(var))
|
||||
|
||||
/******************************************************************************
|
||||
* Logger
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Michal Vasko <mvasko@cesnet.cz>
|
||||
* @brief libyang common parser functions.
|
||||
*
|
||||
* Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
|
||||
* Copyright (c) 2015 - 2024 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.
|
||||
|
@ -70,34 +70,48 @@ lyd_parser_notif_eventtime_validate(const struct lyd_node *node)
|
|||
{
|
||||
LY_ERR rc = LY_SUCCESS;
|
||||
struct ly_ctx *ctx = (struct ly_ctx *)LYD_CTX(node);
|
||||
struct lysc_ctx cctx;
|
||||
const struct lys_module *mod;
|
||||
struct lysc_ctx cctx = {0};
|
||||
const struct lys_module *mod1, *mod2;
|
||||
const struct lysc_node *schema;
|
||||
LY_ARRAY_COUNT_TYPE u;
|
||||
struct ly_err_item *err = NULL;
|
||||
struct lysp_type *type_p = NULL;
|
||||
struct lysc_pattern **patterns = NULL;
|
||||
const char *value;
|
||||
|
||||
LYSC_CTX_INIT_CTX(cctx, ctx);
|
||||
/* find the used modules, we will either use a compiled leaf or compile the relevant type ourselves */
|
||||
mod1 = ly_ctx_get_module_implemented(ctx, "notifications");
|
||||
mod2 = ly_ctx_get_module_latest(ctx, "ietf-yang-types");
|
||||
assert(mod2);
|
||||
|
||||
/* get date-and-time parsed type */
|
||||
mod = ly_ctx_get_module_latest(ctx, "ietf-yang-types");
|
||||
assert(mod);
|
||||
LY_ARRAY_FOR(mod->parsed->typedefs, u) {
|
||||
if (!strcmp(mod->parsed->typedefs[u].name, "date-and-time")) {
|
||||
type_p = &mod->parsed->typedefs[u].type;
|
||||
break;
|
||||
if (mod1 || !mod2->parsed) {
|
||||
/* get date-and-time leaf */
|
||||
schema = lys_find_path(LYD_CTX(node), NULL, "/notifications:notification/eventTime", 0);
|
||||
LY_CHECK_RET(!schema, LY_ENOTFOUND);
|
||||
|
||||
/* validate the value */
|
||||
value = lyd_get_value(node);
|
||||
LY_CHECK_RET(lyd_value_validate(LYD_CTX(node), schema, value, strlen(value), NULL, NULL, NULL));
|
||||
} else {
|
||||
LYSC_CTX_INIT_CTX(cctx, ctx);
|
||||
|
||||
/* get date-and-time parsed type */
|
||||
LY_ARRAY_FOR(mod2->parsed->typedefs, u) {
|
||||
if (!strcmp(mod2->parsed->typedefs[u].name, "date-and-time")) {
|
||||
type_p = &mod2->parsed->typedefs[u].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(type_p);
|
||||
|
||||
/* compile patterns */
|
||||
assert(type_p->patterns);
|
||||
LY_CHECK_GOTO(rc = lys_compile_type_patterns(&cctx, type_p->patterns, NULL, &patterns), cleanup);
|
||||
|
||||
/* validate */
|
||||
value = lyd_get_value(node);
|
||||
rc = lyplg_type_validate_patterns(patterns, value, strlen(value), &err);
|
||||
}
|
||||
assert(type_p);
|
||||
|
||||
/* compile patterns */
|
||||
assert(type_p->patterns);
|
||||
LY_CHECK_GOTO(rc = lys_compile_type_patterns(&cctx, type_p->patterns, NULL, &patterns), cleanup);
|
||||
|
||||
/* validate */
|
||||
value = lyd_get_value(node);
|
||||
rc = lyplg_type_validate_patterns(patterns, value, strlen(value), &err);
|
||||
|
||||
cleanup:
|
||||
FREE_ARRAY(&cctx.free_ctx, patterns, lysc_pattern_free);
|
||||
|
@ -3559,7 +3573,7 @@ lys_parse_ext_instance_stmt(struct lysp_ctx *pctx, struct lysp_ext_substmt *subs
|
|||
{
|
||||
LY_ERR rc = LY_SUCCESS;
|
||||
|
||||
if (!substmt->storage) {
|
||||
if (!substmt->storage_p) {
|
||||
/* nothing to parse, ignored */
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -3587,7 +3601,7 @@ lys_parse_ext_instance_stmt(struct lysp_ctx *pctx, struct lysp_ext_substmt *subs
|
|||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, (void **)&pnode, NULL), cleanup);
|
||||
|
||||
/* usually is a linked-list of all the parsed schema nodes */
|
||||
pnodes_p = VOIDPTR_C(substmt->storage);
|
||||
pnodes_p = (struct lysp_node **)substmt->storage_p;
|
||||
while (*pnodes_p) {
|
||||
pnodes_p = &(*pnodes_p)->next;
|
||||
}
|
||||
|
@ -3615,7 +3629,7 @@ lys_parse_ext_instance_stmt(struct lysp_ctx *pctx, struct lysp_ext_substmt *subs
|
|||
case LY_STMT_TYPEDEF:
|
||||
case LY_STMT_UNIQUE:
|
||||
/* parse, sized array */
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, VOIDPTR_C(substmt->storage), NULL), cleanup);
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage_p, NULL), cleanup);
|
||||
break;
|
||||
|
||||
case LY_STMT_ARGUMENT:
|
||||
|
@ -3650,50 +3664,50 @@ lys_parse_ext_instance_stmt(struct lysp_ctx *pctx, struct lysp_ext_substmt *subs
|
|||
case LY_STMT_YANG_VERSION:
|
||||
case LY_STMT_YIN_ELEMENT:
|
||||
/* single item */
|
||||
if (*VOIDPTR2_C(substmt->storage)) {
|
||||
if (*substmt->storage_p) {
|
||||
LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
|
||||
rc = LY_EVALID;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* parse */
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, VOIDPTR_C(substmt->storage), NULL), cleanup);
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage_p, NULL), cleanup);
|
||||
break;
|
||||
|
||||
case LY_STMT_CONFIG:
|
||||
/* single item */
|
||||
if ((*(uint16_t *)VOIDPTR2_C(substmt->storage)) & LYS_CONFIG_MASK) {
|
||||
if ((*(uint16_t *)substmt->storage_p) & LYS_CONFIG_MASK) {
|
||||
LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
|
||||
rc = LY_EVALID;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* parse */
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, VOIDPTR_C(substmt->storage), NULL), cleanup);
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage_p, NULL), cleanup);
|
||||
break;
|
||||
|
||||
case LY_STMT_ORDERED_BY:
|
||||
/* single item */
|
||||
if ((*(uint16_t *)VOIDPTR2_C(substmt->storage)) & LYS_ORDBY_MASK) {
|
||||
if ((*(uint16_t *)substmt->storage_p) & LYS_ORDBY_MASK) {
|
||||
LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
|
||||
rc = LY_EVALID;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* parse */
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, VOIDPTR_C(substmt->storage), NULL), cleanup);
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage_p, NULL), cleanup);
|
||||
break;
|
||||
|
||||
case LY_STMT_STATUS:
|
||||
/* single item */
|
||||
if ((*(uint16_t *)VOIDPTR2_C(substmt->storage)) & LYS_STATUS_MASK) {
|
||||
if ((*(uint16_t *)substmt->storage_p) & LYS_STATUS_MASK) {
|
||||
LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
|
||||
rc = LY_EVALID;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* parse */
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, VOIDPTR_C(substmt->storage), NULL), cleanup);
|
||||
LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage_p, NULL), cleanup);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -53,6 +53,30 @@ lyd_xml_ctx_free(struct lyd_ctx *lydctx)
|
|||
free(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Log namespace error.
|
||||
*
|
||||
* @param[in] xmlctx XML context
|
||||
* @param[in] prefix XML prefix.
|
||||
* @param[in] prefix_len XML prefix length.
|
||||
* @param[in] attr_name Current XML attribute name.
|
||||
* @param[in] attr_len Current XML attribute name length.
|
||||
*/
|
||||
static void
|
||||
lydxml_log_namespace_err(struct lyxml_ctx *xmlctx, const char *prefix, size_t prefix_len,
|
||||
const char *attr_name, size_t attr_len)
|
||||
{
|
||||
if (prefix_len && attr_len) {
|
||||
LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\" at attribute \"%.*s\".",
|
||||
(int)prefix_len, prefix, (int)attr_len, attr_name);
|
||||
} else if (prefix_len) {
|
||||
LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
|
||||
(int)prefix_len, prefix);
|
||||
} else {
|
||||
LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Missing XML namespace.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse and create XML metadata.
|
||||
*
|
||||
|
@ -109,8 +133,10 @@ lydxml_metadata(struct lyd_xml_ctx *lydctx, const struct lysc_node *sparent, str
|
|||
if (lydctx->parse_opts & LYD_PARSE_STRICT) {
|
||||
LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Missing mandatory prefix for XML metadata \"%.*s\".",
|
||||
(int)xmlctx->name_len, xmlctx->name);
|
||||
ret = LY_EVALID;
|
||||
goto cleanup;
|
||||
/* If LYD_VALIDATE_MULTI_ERROR is set, then continue parsing, because otherwise the parser context
|
||||
* will remain in a bad state, which will cause termination on some assert or undefined behavior.
|
||||
*/
|
||||
LY_DPARSER_ERR_GOTO(LY_EVALID, ret = LY_EVALID, lydctx, cleanup);
|
||||
}
|
||||
|
||||
/* skip attr */
|
||||
|
@ -123,8 +149,7 @@ lydxml_metadata(struct lyd_xml_ctx *lydctx, const struct lysc_node *sparent, str
|
|||
/* get namespace of the attribute to find its annotation definition */
|
||||
ns = lyxml_ns_get(&xmlctx->ns, xmlctx->prefix, xmlctx->prefix_len);
|
||||
if (!ns) {
|
||||
/* unknown namespace, XML error */
|
||||
LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", (int)xmlctx->prefix_len, xmlctx->prefix);
|
||||
lydxml_log_namespace_err(xmlctx, xmlctx->prefix, xmlctx->prefix_len, xmlctx->name, xmlctx->name_len);
|
||||
ret = LY_ENOTFOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -215,7 +240,7 @@ lydxml_attrs(struct lyxml_ctx *xmlctx, struct lyd_attr **attr)
|
|||
if (prefix_len) {
|
||||
ns = lyxml_ns_get(&xmlctx->ns, prefix, prefix_len);
|
||||
if (!ns) {
|
||||
LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", (int)prefix_len, prefix);
|
||||
lydxml_log_namespace_err(xmlctx, prefix, prefix_len, name, name_len);
|
||||
ret = LY_EVALID;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -441,7 +466,9 @@ lydxml_get_hints_opaq(const char *name, size_t name_len, const char *value, size
|
|||
{
|
||||
struct lyd_node_opaq *opaq;
|
||||
char *ptr;
|
||||
long num;
|
||||
/* this needs to be at least 64bit, and it "should not" be an explicit int64_t
|
||||
* because the code calls strtoll later on, which "might" return a bigger type */
|
||||
long long num;
|
||||
|
||||
*hints = 0;
|
||||
*anchor = NULL;
|
||||
|
@ -453,11 +480,11 @@ lydxml_get_hints_opaq(const char *name, size_t name_len, const char *value, size
|
|||
/* boolean value */
|
||||
*hints |= LYD_VALHINT_BOOLEAN;
|
||||
} else {
|
||||
num = strtol(value, &ptr, 10);
|
||||
num = strtoll(value, &ptr, 10);
|
||||
if ((unsigned)(ptr - value) == value_len) {
|
||||
/* number value */
|
||||
*hints |= LYD_VALHINT_DECNUM;
|
||||
if ((num < INT32_MIN) || (num > (long)UINT32_MAX)) {
|
||||
if ((num < INT32_MIN) || (num > UINT32_MAX)) {
|
||||
/* large number */
|
||||
*hints |= LYD_VALHINT_NUM64;
|
||||
}
|
||||
|
@ -535,12 +562,7 @@ lydxml_subtree_get_snode(struct lyd_xml_ctx *lydctx, const struct lyd_node *pare
|
|||
if (lydctx->int_opts & LYD_INTOPT_ANY) {
|
||||
goto unknown_module;
|
||||
}
|
||||
|
||||
if (prefix_len) {
|
||||
LOGVAL(ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", (int)prefix_len, prefix);
|
||||
} else {
|
||||
LOGVAL(ctx, LYVE_REFERENCE, "Missing XML namespace.");
|
||||
}
|
||||
lydxml_log_namespace_err(xmlctx, prefix, prefix_len, NULL, 0);
|
||||
return LY_EVALID;
|
||||
}
|
||||
|
||||
|
@ -1056,14 +1078,13 @@ lydxml_subtree_r(struct lyd_xml_ctx *lydctx, struct lyd_node *parent, struct lyd
|
|||
/* create metadata/attributes */
|
||||
if (xmlctx->status == LYXML_ATTRIBUTE) {
|
||||
if (snode) {
|
||||
rc = lydxml_metadata(lydctx, snode, &meta);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
r = lydxml_metadata(lydctx, snode, &meta);
|
||||
} else {
|
||||
assert(lydctx->parse_opts & LYD_PARSE_OPAQ);
|
||||
rc = lydxml_attrs(xmlctx, &attr);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
r = lydxml_attrs(xmlctx, &attr);
|
||||
}
|
||||
}
|
||||
LY_DPARSER_ERR_GOTO(r, rc = r, lydctx, cleanup);
|
||||
|
||||
assert(xmlctx->status == LYXML_ELEM_CONTENT);
|
||||
if (!snode) {
|
||||
|
@ -1175,7 +1196,7 @@ lydxml_envelope(struct lyxml_ctx *xmlctx, const char *name, const char *uri, ly_
|
|||
prefix_len = xmlctx->prefix_len;
|
||||
ns = lyxml_ns_get(&xmlctx->ns, prefix, prefix_len);
|
||||
if (!ns) {
|
||||
LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", (int)prefix_len, prefix);
|
||||
lydxml_log_namespace_err(xmlctx, prefix, prefix_len, NULL, 0);
|
||||
return LY_EVALID;
|
||||
} else if (strcmp(ns->uri, uri)) {
|
||||
/* different namespace */
|
||||
|
@ -1399,7 +1420,7 @@ lydxml_opaq_r(struct lyxml_ctx *xmlctx, struct lyd_node *parent)
|
|||
prefix_len = xmlctx->prefix_len;
|
||||
ns = lyxml_ns_get(&xmlctx->ns, prefix, prefix_len);
|
||||
if (!ns) {
|
||||
LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", (int)prefix_len, prefix);
|
||||
lydxml_log_namespace_err(xmlctx, prefix, prefix_len, NULL, 0);
|
||||
return LY_EVALID;
|
||||
}
|
||||
|
||||
|
|
|
@ -596,6 +596,7 @@ get_argument(struct lysp_yang_ctx *ctx, enum yang_arg arg, uint16_t *flags, char
|
|||
size_t buf_len = 0;
|
||||
uint8_t prefix = 0;
|
||||
ly_bool str_end = 0;
|
||||
int comment;
|
||||
|
||||
/* word buffer - dynamically allocated */
|
||||
*word_b = NULL;
|
||||
|
@ -627,18 +628,30 @@ get_argument(struct lysp_yang_ctx *ctx, enum yang_arg arg, uint16_t *flags, char
|
|||
str_end = 1;
|
||||
break;
|
||||
case '/':
|
||||
comment = 0;
|
||||
if (ctx->in->current[1] == '/') {
|
||||
/* one-line comment */
|
||||
MOVE_INPUT(ctx, 2);
|
||||
LY_CHECK_GOTO(ret = skip_comment(ctx, 1), error);
|
||||
comment = 1;
|
||||
} else if (ctx->in->current[1] == '*') {
|
||||
/* block comment */
|
||||
MOVE_INPUT(ctx, 2);
|
||||
LY_CHECK_GOTO(ret = skip_comment(ctx, 2), error);
|
||||
comment = 2;
|
||||
} else {
|
||||
/* not a comment after all */
|
||||
LY_CHECK_GOTO(ret = buf_store_char(ctx, arg, word_p, word_len, word_b, &buf_len, 0, &prefix), error);
|
||||
}
|
||||
|
||||
if (comment) {
|
||||
if (*word_len) {
|
||||
/* invalid comment sequence (RFC 7950 sec. 6.1.3.) */
|
||||
LOGVAL_PARSER(ctx, LYVE_SYNTAX, "Invalid comment sequence \"%.2s\" in an unquoted string.", ctx->in->current);
|
||||
ret = LY_EVALID;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* skip the comment */
|
||||
MOVE_INPUT(ctx, 2);
|
||||
LY_CHECK_GOTO(ret = skip_comment(ctx, comment), error);
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
if (*word_len) {
|
||||
|
@ -838,6 +851,8 @@ keyword_start:
|
|||
/* fall through */
|
||||
default:
|
||||
MOVE_INPUT(ctx, 1);
|
||||
/* fall through */
|
||||
case '\0':
|
||||
LOGVAL_PARSER(ctx, LY_VCODE_INSTREXP, (int)(ctx->in->current - word_start), word_start,
|
||||
"a keyword followed by a separator");
|
||||
return LY_EVALID;
|
||||
|
@ -982,8 +997,16 @@ parse_ext(struct lysp_yang_ctx *ctx, const char *ext_name, size_t ext_name_len,
|
|||
e->parent_stmt_index = parent_stmt_index;
|
||||
|
||||
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
|
||||
LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, kw, word, word_len, &e->child), cleanup)
|
||||
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
|
||||
switch (kw) {
|
||||
case LY_STMT_EXTENSION_INSTANCE:
|
||||
LY_CHECK_GOTO(parse_ext(ctx, word, word_len, e, LY_STMT_EXTENSION_INSTANCE, 0, &e->exts), cleanup);
|
||||
break;
|
||||
default:
|
||||
/* just store all the statements */
|
||||
LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, kw, word, word_len, &e->child), cleanup)
|
||||
break;
|
||||
}
|
||||
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, e->exts, ret, cleanup);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @author Michal Vasko <mvasko@cesnet.cz>
|
||||
* @brief YIN parser.
|
||||
*
|
||||
* Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
|
||||
* Copyright (c) 2015 - 2024 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.
|
||||
|
@ -3409,6 +3409,14 @@ yin_parse_extension_instance(struct lysp_yin_ctx *ctx, const void *parent, enum
|
|||
if (ctx->xmlctx->ws_only) {
|
||||
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
|
||||
while (ctx->xmlctx->status == LYXML_ELEMENT) {
|
||||
/* BUG nested extensions will not be parsed because we are not able to dinsguish between them
|
||||
* and the argument of this extension, in case there is one and its 'yin-element' is 'true'
|
||||
stmt = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
|
||||
ctx->xmlctx->prefix_len, LY_STMT_EXTENSION_INSTANCE);
|
||||
if (stmt == LY_STMT_EXTENSION_INSTANCE) {
|
||||
LY_CHECK_RET(yin_parse_extension_instance(ctx, e, LY_STMT_EXTENSION_INSTANCE, 0, &e->exts));
|
||||
} else { */
|
||||
|
||||
LY_CHECK_RET(yin_parse_element_generic(ctx, LY_STMT_EXTENSION_INSTANCE, &new_subelem));
|
||||
if (!e->child) {
|
||||
e->child = new_subelem;
|
||||
|
@ -3420,6 +3428,9 @@ yin_parse_extension_instance(struct lysp_yin_ctx *ctx, const void *parent, enum
|
|||
assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
|
||||
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
|
||||
}
|
||||
|
||||
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
|
||||
LY_CHECK_RET(yin_unres_exts_add(ctx, e->exts));
|
||||
} else if (ctx->xmlctx->value_len) {
|
||||
/* invalid text content */
|
||||
LOGVAL_PARSER(ctx, LYVE_SYNTAX, "Extension instance \"%s\" with unexpected text content \"%.*s\".", ext_name,
|
||||
|
|
26
src/path.c
26
src/path.c
|
@ -708,7 +708,7 @@ ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_
|
|||
|
||||
/* store the value */
|
||||
LOG_LOCSET(key, NULL);
|
||||
ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaf *)key)->type, val, val_len, 0, 0,
|
||||
ret = lyd_value_store(ctx_node->module->ctx, &p->value, ((struct lysc_node_leaf *)key)->type, val, val_len, 0, 0,
|
||||
NULL, format, prefix_data, LYD_HINT_DATA, key, NULL);
|
||||
LOG_LOCBACK(1, 0);
|
||||
LY_CHECK_ERR_GOTO(ret, p->value.realtype = NULL, cleanup);
|
||||
|
@ -736,7 +736,7 @@ ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_
|
|||
/* names (keys) are unique - it was checked when parsing */
|
||||
LOGVAL(ctx, LYVE_XPATH, "Predicate missing for a key of %s \"%s\" in path.",
|
||||
lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
|
||||
ly_path_predicates_free(ctx, *predicates);
|
||||
ly_path_predicates_free(ctx_node->module->ctx, *predicates);
|
||||
*predicates = NULL;
|
||||
ret = LY_EVALID;
|
||||
goto cleanup;
|
||||
|
@ -771,12 +771,10 @@ ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_
|
|||
}
|
||||
|
||||
/* store the value */
|
||||
if (ctx_node) {
|
||||
LOG_LOCSET(ctx_node, NULL);
|
||||
}
|
||||
ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaflist *)ctx_node)->type, val, val_len, 0, 0,
|
||||
LOG_LOCSET(ctx_node, NULL);
|
||||
ret = lyd_value_store(ctx_node->module->ctx, &p->value, ((struct lysc_node_leaflist *)ctx_node)->type, val, val_len, 0, 0,
|
||||
NULL, format, prefix_data, LYD_HINT_DATA, ctx_node, NULL);
|
||||
LOG_LOCBACK(ctx_node ? 1 : 0, 0);
|
||||
LOG_LOCBACK(1, 0);
|
||||
LY_CHECK_ERR_GOTO(ret, p->value.realtype = NULL, cleanup);
|
||||
++(*tok_idx);
|
||||
|
||||
|
@ -1093,7 +1091,7 @@ ly_path_compile_deref(const struct ly_ctx *ctx, const struct lysc_node *ctx_node
|
|||
}
|
||||
lref = (const struct lysc_type_leafref *)deref_leaf_node->type;
|
||||
LY_CHECK_GOTO(ret = ly_path_append(ctx, path2, path), cleanup);
|
||||
ly_path_free(ctx, path2);
|
||||
ly_path_free(path2);
|
||||
path2 = NULL;
|
||||
|
||||
/* compile dereferenced leafref expression and append it to the path */
|
||||
|
@ -1101,7 +1099,7 @@ ly_path_compile_deref(const struct ly_ctx *ctx, const struct lysc_node *ctx_node
|
|||
&path2), cleanup);
|
||||
node2 = path2[LY_ARRAY_COUNT(path2) - 1].node;
|
||||
LY_CHECK_GOTO(ret = ly_path_append(ctx, path2, path), cleanup);
|
||||
ly_path_free(ctx, path2);
|
||||
ly_path_free(path2);
|
||||
path2 = NULL;
|
||||
|
||||
/* properly parsed path must always continue with ')' and '/' */
|
||||
|
@ -1125,9 +1123,9 @@ ly_path_compile_deref(const struct ly_ctx *ctx, const struct lysc_node *ctx_node
|
|||
LY_CHECK_GOTO(ret = ly_path_append(ctx, path2, path), cleanup);
|
||||
|
||||
cleanup:
|
||||
ly_path_free(ctx, path2);
|
||||
ly_path_free(path2);
|
||||
if (ret) {
|
||||
ly_path_free(ctx, *path);
|
||||
ly_path_free(*path);
|
||||
*path = NULL;
|
||||
}
|
||||
return ret;
|
||||
|
@ -1283,7 +1281,7 @@ _ly_path_compile(const struct ly_ctx *ctx, const struct lys_module *cur_mod, con
|
|||
|
||||
cleanup:
|
||||
if (ret) {
|
||||
ly_path_free(ctx, *path);
|
||||
ly_path_free(*path);
|
||||
*path = NULL;
|
||||
}
|
||||
LOG_LOCBACK(cur_node ? 1 : 0, 0);
|
||||
|
@ -1488,7 +1486,7 @@ ly_path_predicates_free(const struct ly_ctx *ctx, struct ly_path_predicate *pred
|
|||
}
|
||||
|
||||
void
|
||||
ly_path_free(const struct ly_ctx *ctx, struct ly_path *path)
|
||||
ly_path_free(struct ly_path *path)
|
||||
{
|
||||
LY_ARRAY_COUNT_TYPE u;
|
||||
|
||||
|
@ -1497,7 +1495,7 @@ ly_path_free(const struct ly_ctx *ctx, struct ly_path *path)
|
|||
}
|
||||
|
||||
LY_ARRAY_FOR(path, u) {
|
||||
ly_path_predicates_free(ctx, path[u].predicates);
|
||||
ly_path_predicates_free(path[u].node->module->ctx, path[u].predicates);
|
||||
}
|
||||
LY_ARRAY_FREE(path);
|
||||
}
|
||||
|
|
|
@ -257,9 +257,8 @@ void ly_path_predicates_free(const struct ly_ctx *ctx, struct ly_path_predicate
|
|||
/**
|
||||
* @brief Free ly_path structure.
|
||||
*
|
||||
* @param[in] ctx libyang context.
|
||||
* @param[in] path The structure ([sized array](@ref sizedarrays)) to free.
|
||||
*/
|
||||
void ly_path_free(const struct ly_ctx *ctx, struct ly_path *path);
|
||||
void ly_path_free(struct ly_path *path);
|
||||
|
||||
#endif /* LY_PATH_H_ */
|
||||
|
|
|
@ -80,6 +80,11 @@ extern const struct lyplg_type_record plugins_xpath10[];
|
|||
*/
|
||||
extern const struct lyplg_type_record plugins_node_instanceid[];
|
||||
|
||||
/*
|
||||
* libnetconf2-netconf-server
|
||||
*/
|
||||
extern const struct lyplg_type_record plugins_time_period[];
|
||||
|
||||
/*
|
||||
* lyds_tree
|
||||
*/
|
||||
|
@ -522,6 +527,9 @@ lyplg_init(ly_bool builtin_type_plugins_only)
|
|||
LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_hex_string), error);
|
||||
LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_xpath10), error);
|
||||
|
||||
/* libnetconf2-netconf-server */
|
||||
LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_time_period), error);
|
||||
|
||||
/* ietf-netconf-acm */
|
||||
LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_TYPE, plugins_node_instanceid), error);
|
||||
|
||||
|
|
|
@ -38,19 +38,22 @@ extern "C" {
|
|||
* Furthermore, there are several internal plugins, implementing built-in data types and selected derived types and YANG
|
||||
* extensions. These internal plugins uses the same API and can be taken as examples for implementing user plugins. Internal
|
||||
* plugins are always loaded with the first created [context](@ref howtoContext) and unloaded with destroying the last one.
|
||||
* The external plugins are in the same phase loaded from the default directories specified at compile time via cmake
|
||||
* variables `PLUGINS_DIR` (where the `extensions` and `types` subdirectories are added for each plugin type) or separately
|
||||
* via `PLUGINS_DIR_EXTENSIONS` and `PLUGINS_DIR_TYPES` for each plugin type. The default directories can be replaced runtime
|
||||
* using environment variables `LIBYANG_TYPES_PLUGINS_DIR` and `LIBYANG_EXTENSIONS_PLUGINS_DIR`.
|
||||
* The external plugins are in the same phase loaded as dynamic shared objects (shared libraries) from the default directories
|
||||
* specified at compile time via cmake variables `PLUGINS_DIR` (where the `extensions` and `types` subdirectories are added
|
||||
* for each plugin type) or separately via `PLUGINS_DIR_EXTENSIONS` and `PLUGINS_DIR_TYPES` for each plugin type. The default
|
||||
* directories can be replaced runtime using environment variables `LIBYANG_TYPES_PLUGINS_DIR` and `LIBYANG_EXTENSIONS_PLUGINS_DIR`.
|
||||
* There is also a separate function ::lyplg_add() to manually add a plugin (dynamic shared object) anytime later.
|
||||
* Another option to manually add an external plugin is using the ::lyplg_add_extension_plugin() or ::lyplg_add_type_plugin()
|
||||
* which is useful when loading a dynamic shared object is problematic. These functions allow for setting the necessary callbacks
|
||||
* for the plugin at runtime.
|
||||
*
|
||||
* Order of the plugins determines their priority. libyang searches for the first match with the extension and type, so the
|
||||
* firstly loaded plugin for the specific item is used. Since the internal plugins are loaded always before the external
|
||||
* plugins, the internal plugins cannot be replaced.
|
||||
*
|
||||
* There is also a separate function ::lyplg_add() to add a plugin anytime later. Note, that such a plugin is being used
|
||||
* after it is added with the lowest priority among other already loaded plugins. Also note that since all the plugins are
|
||||
* unloaded with the destruction of the last context, creating a new context after that starts the standard plugins
|
||||
* initiation and the manually added plugins are not loaded automatically.
|
||||
* Note, that manually added plugin via lyplg_add*() function is added with the lowest priority among other already loaded plugins.
|
||||
* Also note that since all the plugins are unloaded with the destruction of the last context, creating a new context after that
|
||||
* starts the standard plugins initiation and the manually added plugins are not loaded automatically.
|
||||
*
|
||||
* The following pages contain description of the API for creating user plugins.
|
||||
*
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @author Michal Vasko <mvasko@cesnet.cz>
|
||||
* @brief helper functions for extension plugins
|
||||
*
|
||||
* Copyright (c) 2019 - 2022 CESNET, z.s.p.o.
|
||||
* Copyright (c) 2019 - 2024 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.
|
||||
|
@ -81,34 +81,34 @@ cleanup:
|
|||
* @brief Compile an instance extension statement.
|
||||
*
|
||||
* @param[in] ctx Compile context.
|
||||
* @param[in] parsed Parsed ext instance substatement structure.
|
||||
* @param[in] parsed_p Parsed ext instance substatement structure.
|
||||
* @param[in] ext Compiled ext instance.
|
||||
* @param[in] substmt Compled ext instance substatement info.
|
||||
* @return LY_ERR value.
|
||||
*/
|
||||
static LY_ERR
|
||||
lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, uint64_t parsed, struct lysc_ext_instance *ext,
|
||||
lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, void **parsed_p, struct lysc_ext_instance *ext,
|
||||
struct lysc_ext_substmt *substmt)
|
||||
{
|
||||
LY_ERR rc = LY_SUCCESS;
|
||||
ly_bool length_restr = 0;
|
||||
LY_DATA_TYPE basetype;
|
||||
|
||||
assert(parsed);
|
||||
assert(*parsed_p);
|
||||
|
||||
/* compilation wthout any storage */
|
||||
if (substmt->stmt == LY_STMT_IF_FEATURE) {
|
||||
ly_bool enabled;
|
||||
|
||||
/* evaluate */
|
||||
LY_CHECK_GOTO(rc = lys_eval_iffeatures(ctx->ctx, VOIDPTR_C(parsed), &enabled), cleanup);
|
||||
LY_CHECK_GOTO(rc = lys_eval_iffeatures(ctx->ctx, *parsed_p, &enabled), cleanup);
|
||||
if (!enabled) {
|
||||
/* it is disabled, remove the whole extension instance */
|
||||
rc = LY_ENOT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!substmt->storage) {
|
||||
if (!substmt->storage_p) {
|
||||
/* nothing to store */
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, uint64_t parsed, struct lysc
|
|||
struct lysc_node *node;
|
||||
|
||||
lyplg_ext_get_storage(ext, LY_STMT_STATUS, sizeof flags, (const void **)&flags);
|
||||
pnodes = VOIDPTR_C(parsed);
|
||||
pnodes = *parsed_p;
|
||||
|
||||
/* compile nodes */
|
||||
LY_LIST_FOR(pnodes, pnode) {
|
||||
|
@ -163,7 +163,7 @@ lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, uint64_t parsed, struct lysc
|
|||
case LY_STMT_REFERENCE:
|
||||
case LY_STMT_UNITS:
|
||||
/* just make a copy */
|
||||
LY_CHECK_GOTO(rc = lydict_insert(ctx->ctx, VOIDPTR_C(parsed), 0, VOIDPTR_C(substmt->storage)), cleanup);
|
||||
LY_CHECK_GOTO(rc = lydict_insert(ctx->ctx, *parsed_p, 0, (const char **)substmt->storage_p), cleanup);
|
||||
break;
|
||||
|
||||
case LY_STMT_BIT:
|
||||
|
@ -175,7 +175,7 @@ lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, uint64_t parsed, struct lysc
|
|||
}
|
||||
|
||||
/* compile */
|
||||
rc = lys_compile_type_enums(ctx, VOIDPTR_C(parsed), basetype, NULL, VOIDPTR_C(substmt->storage));
|
||||
rc = lys_compile_type_enums(ctx, *parsed_p, basetype, NULL, (struct lysc_type_bitenum_item **)substmt->storage_p);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
break;
|
||||
|
||||
|
@ -183,7 +183,7 @@ lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, uint64_t parsed, struct lysc
|
|||
uint16_t flags;
|
||||
|
||||
if (!(ctx->compile_opts & LYS_COMPILE_NO_CONFIG)) {
|
||||
memcpy(&flags, &parsed, 2);
|
||||
memcpy(&flags, parsed_p, 2);
|
||||
if (flags & LYS_CONFIG_MASK) {
|
||||
/* explicitly set */
|
||||
flags |= LYS_SET_CONFIG;
|
||||
|
@ -194,56 +194,56 @@ lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, uint64_t parsed, struct lysc
|
|||
/* default config */
|
||||
flags = LYS_CONFIG_W;
|
||||
}
|
||||
memcpy(VOIDPTR_C(substmt->storage), &flags, 2);
|
||||
memcpy(substmt->storage_p, &flags, 2);
|
||||
} /* else leave zero */
|
||||
break;
|
||||
}
|
||||
case LY_STMT_MUST: {
|
||||
const struct lysp_restr *restrs = VOIDPTR_C(parsed);
|
||||
const struct lysp_restr *restrs = *parsed_p;
|
||||
|
||||
/* sized array */
|
||||
COMPILE_ARRAY_GOTO(ctx, restrs, *(struct lysc_must **)VOIDPTR_C(substmt->storage), lys_compile_must, rc, cleanup);
|
||||
COMPILE_ARRAY_GOTO(ctx, restrs, *(struct lysc_must **)substmt->storage_p, lys_compile_must, rc, cleanup);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_WHEN: {
|
||||
const uint16_t flags;
|
||||
const struct lysp_when *when = VOIDPTR_C(parsed);
|
||||
const struct lysp_when *when = *parsed_p;
|
||||
|
||||
/* read compiled status */
|
||||
lyplg_ext_get_storage(ext, LY_STMT_STATUS, sizeof flags, (const void **)&flags);
|
||||
|
||||
/* compile */
|
||||
LY_CHECK_GOTO(rc = lys_compile_when(ctx, when, flags, NULL, NULL, NULL, VOIDPTR_C(substmt->storage)), cleanup);
|
||||
LY_CHECK_GOTO(rc = lys_compile_when(ctx, when, flags, NULL, NULL, NULL, (struct lysc_when **)substmt->storage_p), cleanup);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_FRACTION_DIGITS:
|
||||
case LY_STMT_REQUIRE_INSTANCE:
|
||||
/* just make a copy */
|
||||
memcpy(VOIDPTR_C(substmt->storage), &parsed, 1);
|
||||
memcpy(substmt->storage_p, parsed_p, 1);
|
||||
break;
|
||||
|
||||
case LY_STMT_MANDATORY:
|
||||
case LY_STMT_ORDERED_BY:
|
||||
case LY_STMT_STATUS:
|
||||
/* just make a copy */
|
||||
memcpy(VOIDPTR_C(substmt->storage), &parsed, 2);
|
||||
memcpy(substmt->storage_p, parsed_p, 2);
|
||||
break;
|
||||
|
||||
case LY_STMT_MAX_ELEMENTS:
|
||||
case LY_STMT_MIN_ELEMENTS:
|
||||
/* just make a copy */
|
||||
memcpy(VOIDPTR_C(substmt->storage), &parsed, 4);
|
||||
memcpy(substmt->storage_p, parsed_p, 4);
|
||||
break;
|
||||
|
||||
case LY_STMT_POSITION:
|
||||
case LY_STMT_VALUE:
|
||||
/* just make a copy */
|
||||
memcpy(VOIDPTR_C(substmt->storage), &parsed, 8);
|
||||
memcpy(substmt->storage_p, parsed_p, 8);
|
||||
break;
|
||||
|
||||
case LY_STMT_IDENTITY:
|
||||
/* compile */
|
||||
rc = lys_identity_precompile(ctx, NULL, NULL, VOIDPTR_C(parsed), VOIDPTR_C(substmt->storage));
|
||||
rc = lys_identity_precompile(ctx, NULL, NULL, *parsed_p, (struct lysc_ident **)substmt->storage_p);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
break;
|
||||
|
||||
|
@ -252,36 +252,36 @@ lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, uint64_t parsed, struct lysc
|
|||
/* fallthrough */
|
||||
case LY_STMT_RANGE:
|
||||
/* compile, use uint64 default range */
|
||||
rc = lys_compile_type_range(ctx, VOIDPTR_C(parsed), LY_TYPE_UINT64, length_restr, 0, NULL, VOIDPTR_C(substmt->storage));
|
||||
rc = lys_compile_type_range(ctx, *parsed_p, LY_TYPE_UINT64, length_restr, 0, NULL, (struct lysc_range **)substmt->storage_p);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
break;
|
||||
|
||||
case LY_STMT_PATTERN:
|
||||
/* compile */
|
||||
rc = lys_compile_type_patterns(ctx, VOIDPTR_C(parsed), NULL, VOIDPTR_C(substmt->storage));
|
||||
rc = lys_compile_type_patterns(ctx, *parsed_p, NULL, (struct lysc_pattern ***)substmt->storage_p);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
break;
|
||||
|
||||
case LY_STMT_TYPE: {
|
||||
const uint16_t flags;
|
||||
const char *units;
|
||||
const struct lysp_type *ptype = VOIDPTR_C(parsed);
|
||||
const struct lysp_type *ptype = *parsed_p;
|
||||
|
||||
/* read compiled info */
|
||||
lyplg_ext_get_storage(ext, LY_STMT_STATUS, sizeof flags, (const void **)&flags);
|
||||
lyplg_ext_get_storage(ext, LY_STMT_UNITS, sizeof units, (const void **)&units);
|
||||
|
||||
/* compile */
|
||||
rc = lys_compile_type(ctx, NULL, flags, ext->def->name, ptype, VOIDPTR_C(substmt->storage), &units, NULL);
|
||||
rc = lys_compile_type(ctx, NULL, flags, ext->def->name, ptype, (struct lysc_type **)substmt->storage_p, &units, NULL);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
LY_ATOMIC_INC_BARRIER((*(struct lysc_type **)VOIDPTR_C(substmt->storage))->refcount);
|
||||
LY_ATOMIC_INC_BARRIER((*(struct lysc_type **)substmt->storage_p)->refcount);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_EXTENSION_INSTANCE: {
|
||||
struct lysp_ext_instance *extps = VOIDPTR_C(parsed);
|
||||
struct lysp_ext_instance *extps = *parsed_p;
|
||||
|
||||
/* compile sized array */
|
||||
COMPILE_EXTS_GOTO(ctx, extps, *(struct lysc_ext_instance **)VOIDPTR_C(substmt->storage), ext, rc, cleanup);
|
||||
COMPILE_EXTS_GOTO(ctx, extps, *(struct lysc_ext_instance **)substmt->storage_p, ext, rc, cleanup);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_AUGMENT:
|
||||
|
@ -330,7 +330,7 @@ lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext
|
|||
LY_ERR rc = LY_SUCCESS;
|
||||
LY_ARRAY_COUNT_TYPE u, v;
|
||||
enum ly_stmt stmtp;
|
||||
uint64_t storagep;
|
||||
void **storagep;
|
||||
struct ly_set storagep_compiled = {0};
|
||||
|
||||
LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, extp, ext, LY_EINVAL);
|
||||
|
@ -340,9 +340,9 @@ lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext
|
|||
|
||||
LY_ARRAY_FOR(extp->substmts, u) {
|
||||
stmtp = extp->substmts[u].stmt;
|
||||
storagep = *(uint64_t *)VOIDPTR_C(extp->substmts[u].storage);
|
||||
storagep = extp->substmts[u].storage_p;
|
||||
|
||||
if (!storagep || ly_set_contains(&storagep_compiled, VOIDPTR_C(storagep), NULL)) {
|
||||
if (!*storagep || ly_set_contains(&storagep_compiled, storagep, NULL)) {
|
||||
/* nothing parsed or already compiled (for example, if it is a linked list of parsed nodes) */
|
||||
continue;
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext
|
|||
}
|
||||
|
||||
/* compiled */
|
||||
ly_set_add(&storagep_compiled, VOIDPTR_C(storagep), 1, NULL);
|
||||
ly_set_add(&storagep_compiled, storagep, 1, NULL);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -420,7 +420,7 @@ lyplg_ext_sprinter_ctree_add_ext_nodes(const struct lyspr_tree_ctx *ctx, struct
|
|||
uint32_t i;
|
||||
struct lysc_node *schema;
|
||||
|
||||
LY_CHECK_ARG_RET2(NULL, ctx, ext, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(NULL, ctx, ext, LY_EINVAL);
|
||||
|
||||
LY_ARRAY_FOR(ext->substmts, i) {
|
||||
switch (ext->substmts[i].stmt) {
|
||||
|
@ -437,7 +437,7 @@ lyplg_ext_sprinter_ctree_add_ext_nodes(const struct lyspr_tree_ctx *ctx, struct
|
|||
case LY_STMT_LEAF:
|
||||
case LY_STMT_LEAF_LIST:
|
||||
case LY_STMT_LIST:
|
||||
schema = *VOIDPTR2_C(ext->substmts[i].storage);
|
||||
schema = *ext->substmts[i].storage_p;
|
||||
if (schema) {
|
||||
rc = lyplg_ext_sprinter_ctree_add_nodes(ctx, schema, clb);
|
||||
return rc;
|
||||
|
@ -458,7 +458,7 @@ lyplg_ext_sprinter_ptree_add_ext_nodes(const struct lyspr_tree_ctx *ctx, struct
|
|||
uint32_t i;
|
||||
struct lysp_node *schema;
|
||||
|
||||
LY_CHECK_ARG_RET2(NULL, ctx, ext, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(NULL, ctx, ext, LY_EINVAL);
|
||||
|
||||
LY_ARRAY_FOR(ext->substmts, i) {
|
||||
switch (ext->substmts[i].stmt) {
|
||||
|
@ -475,7 +475,7 @@ lyplg_ext_sprinter_ptree_add_ext_nodes(const struct lyspr_tree_ctx *ctx, struct
|
|||
case LY_STMT_LEAF:
|
||||
case LY_STMT_LEAF_LIST:
|
||||
case LY_STMT_LIST:
|
||||
schema = *VOIDPTR2_C(ext->substmts[i].storage);
|
||||
schema = *ext->substmts[i].storage_p;
|
||||
if (schema) {
|
||||
rc = lyplg_ext_sprinter_ptree_add_nodes(ctx, schema, clb);
|
||||
return rc;
|
||||
|
@ -494,7 +494,7 @@ lyplg_ext_sprinter_ctree_add_nodes(const struct lyspr_tree_ctx *ctx, struct lysc
|
|||
{
|
||||
struct lyspr_tree_schema *new;
|
||||
|
||||
LY_CHECK_ARG_RET1(NULL, ctx, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(NULL, ctx, LY_EINVAL);
|
||||
|
||||
if (!nodes) {
|
||||
return LY_SUCCESS;
|
||||
|
@ -514,7 +514,7 @@ lyplg_ext_sprinter_ptree_add_nodes(const struct lyspr_tree_ctx *ctx, struct lysp
|
|||
{
|
||||
struct lyspr_tree_schema *new;
|
||||
|
||||
LY_CHECK_ARG_RET1(NULL, ctx, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(NULL, ctx, LY_EINVAL);
|
||||
|
||||
if (!nodes) {
|
||||
return LY_SUCCESS;
|
||||
|
@ -531,7 +531,7 @@ lyplg_ext_sprinter_ptree_add_nodes(const struct lyspr_tree_ctx *ctx, struct lysp
|
|||
LIBYANG_API_DECL LY_ERR
|
||||
lyplg_ext_sprinter_tree_set_priv(const struct lyspr_tree_ctx *ctx, void *plugin_priv, void (*free_clb)(void *plugin_priv))
|
||||
{
|
||||
LY_CHECK_ARG_RET1(NULL, ctx, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(NULL, ctx, LY_EINVAL);
|
||||
|
||||
((struct lyspr_tree_ctx *)ctx)->plugin_priv = plugin_priv;
|
||||
((struct lyspr_tree_ctx *)ctx)->free_plugin_priv = free_clb;
|
||||
|
@ -587,12 +587,12 @@ lyplg_ext_nodetype2stmt(uint16_t nodetype)
|
|||
}
|
||||
|
||||
LY_ERR
|
||||
lyplg_ext_get_storage_p(const struct lysc_ext_instance *ext, int stmt, uint64_t *storage_p)
|
||||
lyplg_ext_get_storage_p(const struct lysc_ext_instance *ext, int stmt, void ***storage_pp)
|
||||
{
|
||||
LY_ARRAY_COUNT_TYPE u;
|
||||
enum ly_stmt match = 0;
|
||||
|
||||
*storage_p = 0;
|
||||
*storage_pp = NULL;
|
||||
|
||||
if (!(stmt & LY_STMT_NODE_MASK)) {
|
||||
/* matching a non-node statement */
|
||||
|
@ -601,7 +601,7 @@ lyplg_ext_get_storage_p(const struct lysc_ext_instance *ext, int stmt, uint64_t
|
|||
|
||||
LY_ARRAY_FOR(ext->substmts, u) {
|
||||
if ((match && (ext->substmts[u].stmt == match)) || (!match && (ext->substmts[u].stmt & stmt))) {
|
||||
*storage_p = ext->substmts[u].storage;
|
||||
*storage_pp = ext->substmts[u].storage_p;
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -613,14 +613,14 @@ LIBYANG_API_DEF LY_ERR
|
|||
lyplg_ext_get_storage(const struct lysc_ext_instance *ext, int stmt, uint32_t storage_size, const void **storage)
|
||||
{
|
||||
LY_ERR rc = LY_SUCCESS;
|
||||
uint64_t s;
|
||||
void **s_p;
|
||||
|
||||
/* get pointer to the storage, is set even on error */
|
||||
rc = lyplg_ext_get_storage_p(ext, stmt, &s);
|
||||
rc = lyplg_ext_get_storage_p(ext, stmt, &s_p);
|
||||
|
||||
/* assign */
|
||||
if (s) {
|
||||
memcpy(storage, VOIDPTR_C(s), storage_size);
|
||||
if (s_p) {
|
||||
memcpy(storage, s_p, storage_size);
|
||||
} else {
|
||||
memset(storage, 0, storage_size);
|
||||
}
|
||||
|
@ -634,7 +634,9 @@ lyplg_ext_parsed_get_storage(const struct lysc_ext_instance *ext, int stmt, uint
|
|||
LY_ARRAY_COUNT_TYPE u;
|
||||
const struct lysp_ext_instance *extp = NULL;
|
||||
enum ly_stmt match = 0;
|
||||
uint64_t s = 0;
|
||||
void **s_p = NULL;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, ext, ext->module->parsed, LY_EINVAL);
|
||||
|
||||
/* find the parsed ext instance */
|
||||
LY_ARRAY_FOR(ext->module->parsed->exts, u) {
|
||||
|
@ -655,14 +657,14 @@ lyplg_ext_parsed_get_storage(const struct lysc_ext_instance *ext, int stmt, uint
|
|||
/* get the substatement */
|
||||
LY_ARRAY_FOR(extp->substmts, u) {
|
||||
if ((match && (extp->substmts[u].stmt == match)) || (!match && (extp->substmts[u].stmt & stmt))) {
|
||||
s = extp->substmts[u].storage;
|
||||
s_p = extp->substmts[u].storage_p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* assign */
|
||||
if (s) {
|
||||
memcpy(storage, VOIDPTR_C(s), storage_size);
|
||||
if (s_p) {
|
||||
memcpy(storage, s_p, storage_size);
|
||||
} else {
|
||||
memset(storage, 0, storage_size);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ extern "C" {
|
|||
/**
|
||||
* @brief Extensions API version
|
||||
*/
|
||||
#define LYPLG_EXT_API_VERSION 6
|
||||
#define LYPLG_EXT_API_VERSION 8
|
||||
|
||||
/**
|
||||
* @brief Mask for an operation statement.
|
||||
|
@ -393,7 +393,7 @@ struct lysp_stmt {
|
|||
*/
|
||||
struct lysp_ext_substmt {
|
||||
enum ly_stmt stmt; /**< parsed substatement */
|
||||
uint64_t storage; /**< (pointer to) the parsed storage of the statement according to the specific
|
||||
void **storage_p; /**< pointer to the parsed storage of the statement according to the specific
|
||||
lys_ext_substmt::stmt */
|
||||
};
|
||||
|
||||
|
@ -419,6 +419,7 @@ struct lysp_ext_instance {
|
|||
parsed data ([sized array](@ref sizedarrays)) */
|
||||
void *parsed; /**< private plugin parsed data */
|
||||
struct lysp_stmt *child; /**< list of generic (unknown) YANG statements */
|
||||
struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -426,7 +427,7 @@ struct lysp_ext_instance {
|
|||
*/
|
||||
struct lysc_ext_substmt {
|
||||
enum ly_stmt stmt; /**< compiled substatement */
|
||||
uint64_t storage; /**< (pointer to) the compiled storage of the statement according to the specific
|
||||
void **storage_p; /**< pointer to the compiled storage of the statement according to the specific
|
||||
lys_ext_substmt::stmt */
|
||||
};
|
||||
|
||||
|
|
|
@ -79,27 +79,27 @@ annotation_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
|
|||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[0].stmt = LY_STMT_IF_FEATURE;
|
||||
ext->substmts[0].storage = (uint64_t)(uintptr_t)&ann_pdata->iffeatures;
|
||||
ext->substmts[0].storage_p = (void **)&ann_pdata->iffeatures;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[1].stmt = LY_STMT_UNITS;
|
||||
ext->substmts[1].storage = (uint64_t)(uintptr_t)&ann_pdata->units;
|
||||
ext->substmts[1].storage_p = (void **)&ann_pdata->units;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[2].stmt = LY_STMT_STATUS;
|
||||
ext->substmts[2].storage = (uint64_t)(uintptr_t)&ann_pdata->flags;
|
||||
ext->substmts[2].storage_p = (void **)&ann_pdata->flags;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[3].stmt = LY_STMT_TYPE;
|
||||
ext->substmts[3].storage = (uint64_t)(uintptr_t)&ann_pdata->type;
|
||||
ext->substmts[3].storage_p = (void **)&ann_pdata->type;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[4].stmt = LY_STMT_DESCRIPTION;
|
||||
ext->substmts[4].storage = (uint64_t)(uintptr_t)&ann_pdata->dsc;
|
||||
ext->substmts[4].storage_p = (void **)&ann_pdata->dsc;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[5].stmt = LY_STMT_REFERENCE;
|
||||
ext->substmts[5].storage = (uint64_t)(uintptr_t)&ann_pdata->ref;
|
||||
ext->substmts[5].storage_p = (void **)&ann_pdata->ref;
|
||||
|
||||
if ((r = lyplg_ext_parse_extension_instance(pctx, ext))) {
|
||||
return r;
|
||||
|
@ -139,27 +139,27 @@ annotation_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp,
|
|||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[0].stmt = LY_STMT_IF_FEATURE;
|
||||
ext->substmts[0].storage = 0;
|
||||
ext->substmts[0].storage_p = NULL;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[1].stmt = LY_STMT_UNITS;
|
||||
ext->substmts[1].storage = (uint64_t)(uintptr_t)&ann_cdata->units;
|
||||
ext->substmts[1].storage_p = (void **)&ann_cdata->units;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[2].stmt = LY_STMT_STATUS;
|
||||
ext->substmts[2].storage = (uint64_t)(uintptr_t)&ann_cdata->flags;
|
||||
ext->substmts[2].storage_p = (void **)&ann_cdata->flags;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[3].stmt = LY_STMT_TYPE;
|
||||
ext->substmts[3].storage = (uint64_t)(uintptr_t)&ann_cdata->type;
|
||||
ext->substmts[3].storage_p = (void **)&ann_cdata->type;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[4].stmt = LY_STMT_DESCRIPTION;
|
||||
ext->substmts[4].storage = (uint64_t)(uintptr_t)&ann_cdata->dsc;
|
||||
ext->substmts[4].storage_p = (void **)&ann_cdata->dsc;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[5].stmt = LY_STMT_REFERENCE;
|
||||
ext->substmts[5].storage = (uint64_t)(uintptr_t)&ann_cdata->ref;
|
||||
ext->substmts[5].storage_p = (void **)&ann_cdata->ref;
|
||||
|
||||
ret = lyplg_ext_compile_extension_instance(cctx, extp, ext);
|
||||
return ret;
|
||||
|
|
|
@ -90,60 +90,60 @@ structure_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
|
|||
/* parse substatements */
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[0].stmt = LY_STMT_MUST;
|
||||
ext->substmts[0].storage = (uint64_t)(uintptr_t)&struct_pdata->musts;
|
||||
ext->substmts[0].storage_p = (void **)&struct_pdata->musts;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[1].stmt = LY_STMT_STATUS;
|
||||
ext->substmts[1].storage = (uint64_t)(uintptr_t)&struct_pdata->flags;
|
||||
ext->substmts[1].storage_p = (void **)&struct_pdata->flags;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
|
||||
ext->substmts[2].storage = (uint64_t)(uintptr_t)&struct_pdata->dsc;
|
||||
ext->substmts[2].storage_p = (void **)&struct_pdata->dsc;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[3].stmt = LY_STMT_REFERENCE;
|
||||
ext->substmts[3].storage = (uint64_t)(uintptr_t)&struct_pdata->ref;
|
||||
ext->substmts[3].storage_p = (void **)&struct_pdata->ref;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[4].stmt = LY_STMT_TYPEDEF;
|
||||
ext->substmts[4].storage = (uint64_t)(uintptr_t)&struct_pdata->typedefs;
|
||||
ext->substmts[4].storage_p = (void **)&struct_pdata->typedefs;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[5].stmt = LY_STMT_GROUPING;
|
||||
ext->substmts[5].storage = (uint64_t)(uintptr_t)&struct_pdata->groupings;
|
||||
ext->substmts[5].storage_p = (void **)&struct_pdata->groupings;
|
||||
|
||||
/* data-def-stmt */
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[6].stmt = LY_STMT_CONTAINER;
|
||||
ext->substmts[6].storage = (uint64_t)(uintptr_t)&struct_pdata->child;
|
||||
ext->substmts[6].storage_p = (void **)&struct_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[7].stmt = LY_STMT_LEAF;
|
||||
ext->substmts[7].storage = (uint64_t)(uintptr_t)&struct_pdata->child;
|
||||
ext->substmts[7].storage_p = (void **)&struct_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
|
||||
ext->substmts[8].storage = (uint64_t)(uintptr_t)&struct_pdata->child;
|
||||
ext->substmts[8].storage_p = (void **)&struct_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[9].stmt = LY_STMT_LIST;
|
||||
ext->substmts[9].storage = (uint64_t)(uintptr_t)&struct_pdata->child;
|
||||
ext->substmts[9].storage_p = (void **)&struct_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[10].stmt = LY_STMT_CHOICE;
|
||||
ext->substmts[10].storage = (uint64_t)(uintptr_t)&struct_pdata->child;
|
||||
ext->substmts[10].storage_p = (void **)&struct_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[11].stmt = LY_STMT_ANYDATA;
|
||||
ext->substmts[11].storage = (uint64_t)(uintptr_t)&struct_pdata->child;
|
||||
ext->substmts[11].storage_p = (void **)&struct_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[12].stmt = LY_STMT_ANYXML;
|
||||
ext->substmts[12].storage = (uint64_t)(uintptr_t)&struct_pdata->child;
|
||||
ext->substmts[12].storage_p = (void **)&struct_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[13].stmt = LY_STMT_USES;
|
||||
ext->substmts[13].storage = (uint64_t)(uintptr_t)&struct_pdata->child;
|
||||
ext->substmts[13].storage_p = (void **)&struct_pdata->child;
|
||||
|
||||
rc = lyplg_ext_parse_extension_instance(pctx, ext);
|
||||
return rc;
|
||||
|
@ -190,60 +190,60 @@ structure_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, s
|
|||
LY_ARRAY_CREATE_GOTO(cctx->ctx, ext->substmts, 14, rc, emem);
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[0].stmt = LY_STMT_MUST;
|
||||
ext->substmts[0].storage = (uint64_t)(uintptr_t)&struct_cdata->musts;
|
||||
ext->substmts[0].storage_p = (void **)&struct_cdata->musts;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[1].stmt = LY_STMT_STATUS;
|
||||
ext->substmts[1].storage = (uint64_t)(uintptr_t)&struct_cdata->flags;
|
||||
ext->substmts[1].storage_p = (void **)&struct_cdata->flags;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
|
||||
ext->substmts[2].storage = (uint64_t)(uintptr_t)&struct_cdata->dsc;
|
||||
ext->substmts[2].storage_p = (void **)&struct_cdata->dsc;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[3].stmt = LY_STMT_REFERENCE;
|
||||
ext->substmts[3].storage = (uint64_t)(uintptr_t)&struct_cdata->ref;
|
||||
ext->substmts[3].storage_p = (void **)&struct_cdata->ref;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[4].stmt = LY_STMT_TYPEDEF;
|
||||
ext->substmts[4].storage = 0;
|
||||
ext->substmts[4].storage_p = 0;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[5].stmt = LY_STMT_GROUPING;
|
||||
ext->substmts[5].storage = 0;
|
||||
ext->substmts[5].storage_p = 0;
|
||||
|
||||
/* data-def-stmt */
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[6].stmt = LY_STMT_CONTAINER;
|
||||
ext->substmts[6].storage = (uint64_t)(uintptr_t)&struct_cdata->child;
|
||||
ext->substmts[6].storage_p = (void **)&struct_cdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[7].stmt = LY_STMT_LEAF;
|
||||
ext->substmts[7].storage = (uint64_t)(uintptr_t)&struct_cdata->child;
|
||||
ext->substmts[7].storage_p = (void **)&struct_cdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
|
||||
ext->substmts[8].storage = (uint64_t)(uintptr_t)&struct_cdata->child;
|
||||
ext->substmts[8].storage_p = (void **)&struct_cdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[9].stmt = LY_STMT_LIST;
|
||||
ext->substmts[9].storage = (uint64_t)(uintptr_t)&struct_cdata->child;
|
||||
ext->substmts[9].storage_p = (void **)&struct_cdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[10].stmt = LY_STMT_CHOICE;
|
||||
ext->substmts[10].storage = (uint64_t)(uintptr_t)&struct_cdata->child;
|
||||
ext->substmts[10].storage_p = (void **)&struct_cdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[11].stmt = LY_STMT_ANYDATA;
|
||||
ext->substmts[11].storage = (uint64_t)(uintptr_t)&struct_cdata->child;
|
||||
ext->substmts[11].storage_p = (void **)&struct_cdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[12].stmt = LY_STMT_ANYXML;
|
||||
ext->substmts[12].storage = (uint64_t)(uintptr_t)&struct_cdata->child;
|
||||
ext->substmts[12].storage_p = (void **)&struct_cdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[13].stmt = LY_STMT_USES;
|
||||
ext->substmts[13].storage = (uint64_t)(uintptr_t)&struct_cdata->child;
|
||||
ext->substmts[13].storage_p = (void **)&struct_cdata->child;
|
||||
|
||||
*lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
|
||||
rc = lyplg_ext_compile_extension_instance(cctx, extp, ext);
|
||||
|
@ -339,53 +339,53 @@ structure_aug_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
|
|||
/* parse substatements */
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[0].stmt = LY_STMT_STATUS;
|
||||
ext->substmts[0].storage = (uint64_t)(uintptr_t)&aug_pdata->flags;
|
||||
ext->substmts[0].storage_p = (void **)&aug_pdata->flags;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[1].stmt = LY_STMT_DESCRIPTION;
|
||||
ext->substmts[1].storage = (uint64_t)(uintptr_t)&aug_pdata->dsc;
|
||||
ext->substmts[1].storage_p = (void **)&aug_pdata->dsc;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[2].stmt = LY_STMT_REFERENCE;
|
||||
ext->substmts[2].storage = (uint64_t)(uintptr_t)&aug_pdata->ref;
|
||||
ext->substmts[2].storage_p = (void **)&aug_pdata->ref;
|
||||
|
||||
/* data-def-stmt */
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[3].stmt = LY_STMT_CONTAINER;
|
||||
ext->substmts[3].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[3].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[4].stmt = LY_STMT_LEAF;
|
||||
ext->substmts[4].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[4].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[5].stmt = LY_STMT_LEAF_LIST;
|
||||
ext->substmts[5].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[5].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[6].stmt = LY_STMT_LIST;
|
||||
ext->substmts[6].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[6].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[7].stmt = LY_STMT_CHOICE;
|
||||
ext->substmts[7].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[7].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[8].stmt = LY_STMT_ANYDATA;
|
||||
ext->substmts[8].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[8].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[9].stmt = LY_STMT_ANYXML;
|
||||
ext->substmts[9].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[9].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[10].stmt = LY_STMT_USES;
|
||||
ext->substmts[10].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[10].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
/* case */
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[11].stmt = LY_STMT_CASE;
|
||||
ext->substmts[11].storage = (uint64_t)(uintptr_t)&aug_pdata->child;
|
||||
ext->substmts[11].storage_p = (void **)&aug_pdata->child;
|
||||
|
||||
if ((rc = lyplg_ext_parse_extension_instance(pctx, ext))) {
|
||||
return rc;
|
||||
|
@ -394,7 +394,7 @@ structure_aug_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
|
|||
/* add fake parsed augment node */
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[12].stmt = LY_STMT_AUGMENT;
|
||||
ext->substmts[12].storage = (uint64_t)(uintptr_t)&aug_pdata->aug;
|
||||
ext->substmts[12].storage_p = (void **)&aug_pdata->aug;
|
||||
|
||||
aug_pdata->aug = calloc(1, sizeof *aug_pdata->aug);
|
||||
if (!aug_pdata->aug) {
|
||||
|
@ -476,7 +476,7 @@ structure_aug_sprinter_ptree(struct lysp_ext_instance *ext, const struct lyspr_t
|
|||
|
||||
assert(ctx);
|
||||
|
||||
aug = (struct lysp_node_augment **)(uintptr_t)ext->substmts[12].storage;
|
||||
aug = (struct lysp_node_augment **)ext->substmts[12].storage_p;
|
||||
rc = lyplg_ext_sprinter_ptree_add_nodes(ctx, (*aug)->child, structure_sprinter_pnode);
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -58,15 +58,15 @@ yangdata_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
|
|||
LY_ARRAY_CREATE_GOTO(lyplg_ext_parse_get_cur_pmod(pctx)->mod->ctx, ext->substmts, 3, ret, emem);
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[0].stmt = LY_STMT_CONTAINER;
|
||||
ext->substmts[0].storage = (uint64_t)(uintptr_t)&ext->parsed;
|
||||
ext->substmts[0].storage_p = (void **)&ext->parsed;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[1].stmt = LY_STMT_CHOICE;
|
||||
ext->substmts[1].storage = (uint64_t)(uintptr_t)&ext->parsed;
|
||||
ext->substmts[1].storage_p = (void **)&ext->parsed;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[2].stmt = LY_STMT_USES;
|
||||
ext->substmts[2].storage = (uint64_t)(uintptr_t)&ext->parsed;
|
||||
ext->substmts[2].storage_p = (void **)&ext->parsed;
|
||||
|
||||
if ((ret = lyplg_ext_parse_extension_instance(pctx, ext))) {
|
||||
return ret;
|
||||
|
@ -96,15 +96,15 @@ yangdata_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, st
|
|||
LY_ARRAY_CREATE_GOTO(cctx->ctx, ext->substmts, 3, ret, emem);
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[0].stmt = LY_STMT_CONTAINER;
|
||||
ext->substmts[0].storage = (uint64_t)(uintptr_t)&ext->compiled;
|
||||
ext->substmts[0].storage_p = (void **)&ext->compiled;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[1].stmt = LY_STMT_CHOICE;
|
||||
ext->substmts[1].storage = (uint64_t)(uintptr_t)&ext->compiled;
|
||||
ext->substmts[1].storage_p = (void **)&ext->compiled;
|
||||
|
||||
LY_ARRAY_INCREMENT(ext->substmts);
|
||||
ext->substmts[2].stmt = LY_STMT_USES;
|
||||
ext->substmts[2].storage = (uint64_t)(uintptr_t)&ext->compiled;
|
||||
ext->substmts[2].storage_p = (void **)&ext->compiled;
|
||||
|
||||
*lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
|
||||
ret = lyplg_ext_compile_extension_instance(cctx, extp, ext);
|
||||
|
|
|
@ -352,10 +352,16 @@ lyplg_type_print_simple(const struct ly_ctx *UNUSED(ctx), const struct lyd_value
|
|||
LIBYANG_API_DEF LY_ERR
|
||||
lyplg_type_dup_simple(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
|
||||
{
|
||||
memset(dup, 0, sizeof *dup);
|
||||
LY_CHECK_RET(lydict_insert(ctx, original->_canonical, 0, &dup->_canonical));
|
||||
LY_ERR r;
|
||||
|
||||
if ((r = lydict_dup(ctx, original->_canonical, &dup->_canonical))) {
|
||||
/* in case of error NULL the values so that freeing does not fail */
|
||||
memset(dup, 0, sizeof *dup);
|
||||
return r;
|
||||
}
|
||||
memcpy(dup->fixed_mem, original->fixed_mem, sizeof dup->fixed_mem);
|
||||
dup->realtype = original->realtype;
|
||||
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -831,8 +837,9 @@ lyplg_type_lypath_new(const struct ly_ctx *ctx, const char *value, size_t value_
|
|||
uint32_t prefix_opt = 0;
|
||||
struct ly_err_item *e;
|
||||
const char *err_fmt = NULL;
|
||||
uint16_t oper;
|
||||
|
||||
LY_CHECK_ARG_RET(ctx, ctx, value, ctx_node, path, err, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(ctx, ctx, value, path, err, LY_EINVAL);
|
||||
|
||||
*path = NULL;
|
||||
*err = NULL;
|
||||
|
@ -871,8 +878,8 @@ lyplg_type_lypath_new(const struct ly_ctx *ctx, const char *value, size_t value_
|
|||
}
|
||||
|
||||
/* resolve it on schema tree */
|
||||
ret = ly_path_compile(ctx, NULL, ctx_node, NULL, exp, (ctx_node->flags & LYS_IS_OUTPUT) ?
|
||||
LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_SINGLE, 1, format, prefix_data, path);
|
||||
oper = (ctx_node && (ctx_node->flags & LYS_IS_OUTPUT)) ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
|
||||
ret = ly_path_compile(ctx, NULL, ctx_node, NULL, exp, oper, LY_PATH_TARGET_SINGLE, 1, format, prefix_data, path);
|
||||
if (ret) {
|
||||
err_fmt = "Invalid instance-identifier \"%.*s\" value - semantic error%s%s";
|
||||
goto cleanup;
|
||||
|
@ -888,7 +895,7 @@ cleanup:
|
|||
ly_err_clean((struct ly_ctx *)ctx, e);
|
||||
}
|
||||
|
||||
ly_path_free(ctx, *path);
|
||||
ly_path_free(*path);
|
||||
*path = NULL;
|
||||
}
|
||||
|
||||
|
@ -896,9 +903,9 @@ cleanup:
|
|||
}
|
||||
|
||||
LIBYANG_API_DEF void
|
||||
lyplg_type_lypath_free(const struct ly_ctx *ctx, struct ly_path *path)
|
||||
lyplg_type_lypath_free(const struct ly_ctx *UNUSED(ctx), struct ly_path *path)
|
||||
{
|
||||
ly_path_free(ctx, path);
|
||||
ly_path_free(path);
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
|
@ -1007,7 +1014,7 @@ lyplg_type_resolve_leafref_get_target_path(const struct lyxp_expr *path, const s
|
|||
LY_CHECK_GOTO(lyxp_expr_parse(ctx_node->module->ctx, str_path, 0, 1, target_path), cleanup);
|
||||
|
||||
cleanup:
|
||||
ly_path_free(ctx_node->module->ctx, p);
|
||||
ly_path_free(p);
|
||||
free(str_path);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -475,8 +475,10 @@ LIBYANG_API_DECL LY_ERR lyplg_type_print_xpath10_value(const struct lyd_value_xp
|
|||
#define LYPLG_TYPE_STORE_IMPLEMENT 0x02 /**< If a foreign module is needed to be implemented to successfully instantiate
|
||||
the value, make the module implemented. */
|
||||
#define LYPLG_TYPE_STORE_IS_UTF8 0x04 /**< The value is guaranteed to be a valid UTF-8 string, if applicable for the type. */
|
||||
#define LYPLG_TYPE_STORE_ONLY 0x08 /**< The value is stored only. The validation must be done using [validate](@ref lyplg_type_validate_clb) */
|
||||
/** @} plugintypestoreopts */
|
||||
#define LYPLG_TYPE_STORE_ONLY 0x08 /**< The value is stored only, type-specific validation is skipped (performed before) */
|
||||
/**
|
||||
* @} plugintypestoreopts
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Callback to store the given @p value according to the given @p type.
|
||||
|
@ -490,7 +492,9 @@ LIBYANG_API_DECL LY_ERR lyplg_type_print_xpath10_value(const struct lyd_value_xp
|
|||
* @p value_len is always correct. All store functions have to free a dynamically allocated @p value in all
|
||||
* cases (even on error).
|
||||
*
|
||||
* @param[in] ctx libyang context
|
||||
* No unnecessary validation tasks should be performed by this callback and left for ::lyplg_type_validate_clb instead.
|
||||
*
|
||||
* @param[in] ctx libyang context.
|
||||
* @param[in] type Type of the value being stored.
|
||||
* @param[in] value Value to be stored.
|
||||
* @param[in] value_len Length (number of bytes) of the given @p value.
|
||||
|
@ -513,15 +517,14 @@ LIBYANG_API_DECL typedef LY_ERR (*lyplg_type_store_clb)(const struct ly_ctx *ctx
|
|||
const struct lysc_node *ctx_node, struct lyd_value *storage, struct lys_glob_unres *unres, struct ly_err_item **err);
|
||||
|
||||
/**
|
||||
* @brief Callback to validate the stored value in data.
|
||||
* @brief Callback to validate the stored value in the accessible data tree.
|
||||
*
|
||||
* This callback is optional for types that can only be validated in a data tree. It must be called and succeed
|
||||
* in case the ::lyplg_type_store_clb callback returned ::LY_EINCOMPLETE for the value to be valid. However, this
|
||||
* callback can be called even in other cases (such as separate/repeated validation).
|
||||
* This callback is optional and may not be defined for types that do not require the accessible data tree for
|
||||
* validation (::lyplg_type_store_cb fully stores and validates the value).
|
||||
*
|
||||
* @param[in] ctx libyang context
|
||||
* @param[in] ctx libyang context.
|
||||
* @param[in] type Original type of the value (not necessarily the stored one) being validated.
|
||||
* @param[in] ctx_node The value data context node for validation.
|
||||
* @param[in] ctx_node Value data context node for validation.
|
||||
* @param[in] tree External data tree (e.g. when validating RPC/Notification) with possibly referenced data.
|
||||
* @param[in,out] storage Storage of the value successfully filled by ::lyplg_type_store_clb. May be modified.
|
||||
* @param[out] err Optionally provided error information in case of failure. If not provided to the caller, a generic
|
||||
|
@ -619,7 +622,7 @@ struct lyplg_type {
|
|||
const char *id; /**< Plugin identification (mainly for distinguish incompatible versions when
|
||||
used by external tools) */
|
||||
lyplg_type_store_clb store; /**< store and canonize the value in the type-specific way */
|
||||
lyplg_type_validate_clb validate; /**< optional, validate the value in the type-specific way in data */
|
||||
lyplg_type_validate_clb validate; /**< optional, validate the value in the accessible data tree */
|
||||
lyplg_type_compare_clb compare; /**< comparison callback to compare 2 values of the same type */
|
||||
lyplg_type_sort_clb sort; /**< comparison callback for sorting values */
|
||||
lyplg_type_print_clb print; /**< printer callback to get string representing the value */
|
||||
|
@ -947,18 +950,6 @@ LIBYANG_API_DECL LY_ERR lyplg_type_store_instanceid(const struct ly_ctx *ctx, co
|
|||
LIBYANG_API_DECL LY_ERR lyplg_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);
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_compare_clb for the built-in instance-identifier type.
|
||||
*/
|
||||
LIBYANG_API_DECL LY_ERR lyplg_type_compare_instanceid(const struct ly_ctx *ctx, const struct lyd_value *val1,
|
||||
const struct lyd_value *val2);
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_sort_clb for the built-in instance-identifier type.
|
||||
*/
|
||||
LIBYANG_API_DEF int lyplg_type_sort_instanceid(const struct ly_ctx *ctx, const struct lyd_value *val1,
|
||||
const struct lyd_value *val2);
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_print_clb for the built-in instance-identifier type.
|
||||
*/
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
*/
|
||||
static const char b64_etable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static LY_ERR lyplg_type_validate_binary(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node), const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err);
|
||||
|
||||
/**
|
||||
* @brief Encode binary value into a base64 string value.
|
||||
*
|
||||
|
@ -260,6 +258,7 @@ lyplg_type_store_binary(const struct ly_ctx *ctx, const struct lysc_type *type,
|
|||
struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
struct lysc_type_bin *type_bin = (struct lysc_type_bin *)type;
|
||||
struct lyd_value_binary *val;
|
||||
|
||||
/* init storage */
|
||||
|
@ -312,15 +311,20 @@ lyplg_type_store_binary(const struct ly_ctx *ctx, const struct lysc_type *type,
|
|||
ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
|
||||
options &= ~LYPLG_TYPE_STORE_DYNAMIC;
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* value may have been freed */
|
||||
value = storage->_canonical;
|
||||
} else {
|
||||
ret = lydict_insert(ctx, value_len ? value : "", value_len, &storage->_canonical);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* validate value */
|
||||
ret = lyplg_type_validate_binary(ctx, type, NULL, NULL, storage, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
/* validate length restriction of the binary value */
|
||||
if (type_bin->length) {
|
||||
ret = lyplg_type_validate_range(LY_TYPE_BINARY, type_bin->length, val->size, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -334,33 +338,6 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_validate_clb for the binary type.
|
||||
*/
|
||||
static LY_ERR
|
||||
lyplg_type_validate_binary(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node),
|
||||
const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err)
|
||||
{
|
||||
struct lysc_type_bin *type_bin = (struct lysc_type_bin *)type;
|
||||
struct lyd_value_binary *val;
|
||||
const void *value;
|
||||
size_t value_len;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, type, storage, err, LY_EINVAL);
|
||||
|
||||
val = LYPLG_TYPE_VAL_IS_DYN(val) ? (struct lyd_value_binary *)(storage->dyn_mem) : (struct lyd_value_binary *)(storage->fixed_mem);
|
||||
value = lyd_value_get_canonical(ctx, storage);
|
||||
value_len = strlen(value);
|
||||
*err = NULL;
|
||||
|
||||
/* length restriction of the binary value */
|
||||
if (type_bin->length) {
|
||||
LY_CHECK_RET(lyplg_type_validate_range(LY_TYPE_BINARY, type_bin->length, val->size, value, value_len, err));
|
||||
}
|
||||
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
lyplg_type_compare_binary(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
|
||||
{
|
||||
|
@ -496,7 +473,7 @@ const struct lyplg_type_record plugins_binary[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - binary, version 1",
|
||||
.plugin.store = lyplg_type_store_binary,
|
||||
.plugin.validate = lyplg_type_validate_binary,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_binary,
|
||||
.plugin.sort = lyplg_type_sort_binary,
|
||||
.plugin.print = lyplg_type_print_binary,
|
||||
|
|
|
@ -53,7 +53,6 @@ lyplg_type_store_date_and_time(const struct ly_ctx *ctx, const struct lysc_type
|
|||
struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
struct lysc_type_str *type_dat = (struct lysc_type_str *)type;
|
||||
struct lyd_value_date_and_time *val;
|
||||
uint32_t i;
|
||||
char c;
|
||||
|
@ -102,20 +101,9 @@ lyplg_type_store_date_and_time(const struct ly_ctx *ctx, const struct lysc_type
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction, there can be only ASCII chars */
|
||||
if (type_dat->length) {
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_dat->length, value_len, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* date-and-time pattern */
|
||||
ret = lyplg_type_validate_patterns(type_dat->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* convert to UNIX time and fractions of second */
|
||||
ret = ly_time_str2time(value, &val->time, &val->fractions_s);
|
||||
if (ret) {
|
||||
ret = ly_err_new(err, ret, 0, NULL, NULL, "%s", ly_last_logmsg());
|
||||
/* convert to UNIX time and fractions of second, function must check for all the possible errors */
|
||||
if (ly_time_str2time(value, &val->time, &val->fractions_s)) {
|
||||
ret = ly_err_new(err, LY_EVALID, 0, NULL, NULL, "%s", ly_last_logmsg());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
* | 8 | yes | `int64_t *` | little-endian value represented without floating point |
|
||||
*/
|
||||
|
||||
static LY_ERR lyplg_type_validate_decimal64(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node), const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err);
|
||||
|
||||
/**
|
||||
* @brief Convert decimal64 number to canonical string.
|
||||
*
|
||||
|
@ -90,7 +88,7 @@ lyplg_type_store_decimal64(const struct ly_ctx *ctx, const struct lysc_type *typ
|
|||
{
|
||||
struct lysc_type_dec *type_dec = (struct lysc_type_dec *)type;
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
int64_t num;
|
||||
int64_t num = 0;
|
||||
char *canon;
|
||||
|
||||
/* init storage */
|
||||
|
@ -144,8 +142,12 @@ lyplg_type_store_decimal64(const struct ly_ctx *ctx, const struct lysc_type *typ
|
|||
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* validate value */
|
||||
ret = lyplg_type_validate_decimal64(ctx, type, NULL, NULL, storage, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
if (type_dec->range) {
|
||||
/* check range of the number */
|
||||
ret = lyplg_type_validate_range(type->basetype, type_dec->range, num, storage->_canonical,
|
||||
strlen(storage->_canonical), err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -159,31 +161,6 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_validate_clb for the built-in decimal64 type.
|
||||
*/
|
||||
static LY_ERR
|
||||
lyplg_type_validate_decimal64(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node),
|
||||
const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret;
|
||||
struct lysc_type_dec *type_dec = (struct lysc_type_dec *)type;
|
||||
int64_t num;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, type, storage, err, LY_EINVAL);
|
||||
*err = NULL;
|
||||
num = storage->dec64;
|
||||
|
||||
if (type_dec->range) {
|
||||
/* check range of the number */
|
||||
ret = lyplg_type_validate_range(type->basetype, type_dec->range, num, storage->_canonical,
|
||||
strlen(storage->_canonical), err);
|
||||
LY_CHECK_RET(ret);
|
||||
}
|
||||
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
lyplg_type_compare_decimal64(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1,
|
||||
const struct lyd_value *val2)
|
||||
|
@ -262,7 +239,7 @@ const struct lyplg_type_record plugins_decimal64[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - decimal64, version 1",
|
||||
.plugin.store = lyplg_type_store_decimal64,
|
||||
.plugin.validate = lyplg_type_validate_decimal64,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_decimal64,
|
||||
.plugin.sort = lyplg_type_sort_decimal64,
|
||||
.plugin.print = lyplg_type_print_decimal64,
|
||||
|
|
|
@ -55,17 +55,6 @@ lyplg_type_store_hex_string(const struct ly_ctx *ctx, const struct lysc_type *ty
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* make a copy, it is needed for canonization */
|
||||
if ((format != LY_VALUE_CANON) && !(options & LYPLG_TYPE_STORE_DYNAMIC)) {
|
||||
value = strndup(value, value_len);
|
||||
|
@ -83,12 +72,28 @@ lyplg_type_store_hex_string(const struct ly_ctx *ctx, const struct lysc_type *ty
|
|||
ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
|
||||
options &= ~LYPLG_TYPE_STORE_DYNAMIC;
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* value may have been freed */
|
||||
value = storage->_canonical;
|
||||
} else {
|
||||
/* store directly */
|
||||
ret = lydict_insert(ctx, value_len ? value : "", value_len, &storage->_canonical);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* validate length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* validate pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (options & LYPLG_TYPE_STORE_DYNAMIC) {
|
||||
free((void *)value);
|
||||
|
|
|
@ -252,23 +252,14 @@ lyplg_type_validate_instanceid(const struct ly_ctx *ctx, const struct lysc_type
|
|||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
lyplg_type_compare_instanceid(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
|
||||
{
|
||||
return lyplg_type_compare_simple(ctx, val1, val2);
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF int
|
||||
lyplg_type_sort_instanceid(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
|
||||
{
|
||||
return lyplg_type_sort_simple(ctx, val1, val2);
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF const void *
|
||||
lyplg_type_print_instanceid(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *value, LY_VALUE_FORMAT format,
|
||||
lyplg_type_print_instanceid(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
|
||||
void *prefix_data, ly_bool *dynamic, size_t *value_len)
|
||||
{
|
||||
char *ret;
|
||||
char *ret = NULL;
|
||||
struct ly_path *p = NULL;
|
||||
const struct ly_path *target;
|
||||
struct ly_err_item *err;
|
||||
|
||||
if ((format == LY_VALUE_CANON) || (format == LY_VALUE_JSON) || (format == LY_VALUE_LYB)) {
|
||||
if (dynamic) {
|
||||
|
@ -280,14 +271,34 @@ lyplg_type_print_instanceid(const struct ly_ctx *UNUSED(ctx), const struct lyd_v
|
|||
return value->_canonical;
|
||||
}
|
||||
|
||||
/* print the value in the specific format */
|
||||
if (instanceid_path2str(value->target, format, prefix_data, &ret)) {
|
||||
return NULL;
|
||||
if (!value->target) {
|
||||
/* schema default value, compile it first */
|
||||
if (lyplg_type_lypath_new(ctx, value->_canonical, strlen(value->_canonical), 0, LY_VALUE_JSON, NULL, NULL,
|
||||
NULL, &p, &err)) {
|
||||
if (err) {
|
||||
ly_err_print(ctx, err);
|
||||
ly_err_free(err);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
target = p;
|
||||
} else {
|
||||
target = value->target;
|
||||
}
|
||||
|
||||
/* print the value in the specific format */
|
||||
if (instanceid_path2str(target, format, prefix_data, &ret)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*dynamic = 1;
|
||||
if (value_len) {
|
||||
*value_len = strlen(ret);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
ly_path_free(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -295,6 +306,7 @@ LIBYANG_API_DEF LY_ERR
|
|||
lyplg_type_dup_instanceid(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
|
||||
{
|
||||
LY_ERR ret;
|
||||
struct ly_err_item *err;
|
||||
|
||||
memset(dup, 0, sizeof *dup);
|
||||
|
||||
|
@ -302,9 +314,21 @@ lyplg_type_dup_instanceid(const struct ly_ctx *ctx, const struct lyd_value *orig
|
|||
ret = lydict_insert(ctx, original->_canonical, 0, &dup->_canonical);
|
||||
LY_CHECK_GOTO(ret, error);
|
||||
|
||||
/* copy path */
|
||||
ret = ly_path_dup(ctx, original->target, &dup->target);
|
||||
LY_CHECK_GOTO(ret, error);
|
||||
if (!original->target) {
|
||||
/* schema default value, needs to be compiled */
|
||||
if (lyplg_type_lypath_new(ctx, original->_canonical, strlen(original->_canonical), 0, LY_VALUE_JSON, NULL, NULL,
|
||||
NULL, &dup->target, &err)) {
|
||||
if (err) {
|
||||
ly_err_print(ctx, err);
|
||||
ly_err_free(err);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
/* copy path */
|
||||
ret = ly_path_dup(ctx, original->target, &dup->target);
|
||||
LY_CHECK_GOTO(ret, error);
|
||||
}
|
||||
|
||||
dup->realtype = original->realtype;
|
||||
return LY_SUCCESS;
|
||||
|
@ -319,7 +343,7 @@ lyplg_type_free_instanceid(const struct ly_ctx *ctx, struct lyd_value *value)
|
|||
{
|
||||
lydict_remove(ctx, value->_canonical);
|
||||
value->_canonical = NULL;
|
||||
ly_path_free(ctx, value->target);
|
||||
ly_path_free(value->target);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,8 +362,8 @@ const struct lyplg_type_record plugins_instanceid[] = {
|
|||
.plugin.id = "libyang 2 - instance-identifier, version 1",
|
||||
.plugin.store = lyplg_type_store_instanceid,
|
||||
.plugin.validate = lyplg_type_validate_instanceid,
|
||||
.plugin.compare = lyplg_type_compare_instanceid,
|
||||
.plugin.sort = lyplg_type_sort_instanceid,
|
||||
.plugin.compare = lyplg_type_compare_simple,
|
||||
.plugin.sort = lyplg_type_sort_simple,
|
||||
.plugin.print = lyplg_type_print_instanceid,
|
||||
.plugin.duplicate = lyplg_type_dup_instanceid,
|
||||
.plugin.free = lyplg_type_free_instanceid,
|
||||
|
|
|
@ -36,9 +36,6 @@
|
|||
* | 1/2/4/8 | yes | pointer to the specific integer type | little-endian integer value |
|
||||
*/
|
||||
|
||||
static LY_ERR lyplg_type_validate_int(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node), const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err);
|
||||
static LY_ERR lyplg_type_validate_uint(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node), const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err);
|
||||
|
||||
/**
|
||||
* @brief LYB value size of each integer type.
|
||||
*/
|
||||
|
@ -53,6 +50,7 @@ lyplg_type_store_int(const struct ly_ctx *ctx, const struct lysc_type *type, con
|
|||
const struct lysc_node *UNUSED(ctx_node), struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres),
|
||||
struct ly_err_item **err)
|
||||
{
|
||||
struct lysc_type_num *type_num = (struct lysc_type_num *)type;
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
int64_t num = 0;
|
||||
int base = 1;
|
||||
|
@ -157,9 +155,12 @@ lyplg_type_store_int(const struct ly_ctx *ctx, const struct lysc_type *type, con
|
|||
}
|
||||
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* validate value */
|
||||
ret = lyplg_type_validate_int(ctx, type, NULL, NULL, storage, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
/* validate range of the number */
|
||||
if (type_num->range) {
|
||||
ret = lyplg_type_validate_range(type->basetype, type_num->range, num, storage->_canonical,
|
||||
strlen(storage->_canonical), err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -173,48 +174,6 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_validate_clb for the signed interger types.
|
||||
*/
|
||||
static LY_ERR
|
||||
lyplg_type_validate_int(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node),
|
||||
const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret;
|
||||
struct lysc_type_num *type_num = (struct lysc_type_num *)type;
|
||||
int64_t num;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, type, storage, err, LY_EINVAL);
|
||||
*err = NULL;
|
||||
|
||||
/* set the value (matters for big-endian) and get the correct int64 number */
|
||||
switch (type->basetype) {
|
||||
case LY_TYPE_INT8:
|
||||
num = storage->int8;
|
||||
break;
|
||||
case LY_TYPE_INT16:
|
||||
num = storage->int16;
|
||||
break;
|
||||
case LY_TYPE_INT32:
|
||||
num = storage->int32;
|
||||
break;
|
||||
case LY_TYPE_INT64:
|
||||
num = storage->int64;
|
||||
break;
|
||||
default:
|
||||
return LY_EINVAL;
|
||||
}
|
||||
|
||||
/* validate range of the number */
|
||||
if (type_num->range) {
|
||||
ret = lyplg_type_validate_range(type->basetype, type_num->range, num, storage->_canonical,
|
||||
strlen(storage->_canonical), err);
|
||||
LY_CHECK_RET(ret);
|
||||
}
|
||||
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
lyplg_type_compare_int(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
|
||||
{
|
||||
|
@ -357,6 +316,7 @@ lyplg_type_store_uint(const struct ly_ctx *ctx, const struct lysc_type *type, co
|
|||
const struct lysc_node *UNUSED(ctx_node), struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres),
|
||||
struct ly_err_item **err)
|
||||
{
|
||||
struct lysc_type_num *type_num = (struct lysc_type_num *)type;
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
uint64_t num = 0;
|
||||
int base = 0;
|
||||
|
@ -441,9 +401,12 @@ lyplg_type_store_uint(const struct ly_ctx *ctx, const struct lysc_type *type, co
|
|||
}
|
||||
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* validate value */
|
||||
ret = lyplg_type_validate_uint(ctx, type, NULL, NULL, storage, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
/* validate range of the number */
|
||||
if (type_num->range) {
|
||||
ret = lyplg_type_validate_range(type->basetype, type_num->range, num, storage->_canonical,
|
||||
strlen(storage->_canonical), err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -457,48 +420,6 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_validate_clb for the unsigned interger types.
|
||||
*/
|
||||
static LY_ERR
|
||||
lyplg_type_validate_uint(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node),
|
||||
const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret;
|
||||
struct lysc_type_num *type_num = (struct lysc_type_num *)type;
|
||||
uint64_t num;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, type, storage, err, LY_EINVAL);
|
||||
*err = NULL;
|
||||
|
||||
/* set the value (matters for big-endian) and get the correct int64 number */
|
||||
switch (type->basetype) {
|
||||
case LY_TYPE_UINT8:
|
||||
num = storage->uint8;
|
||||
break;
|
||||
case LY_TYPE_UINT16:
|
||||
num = storage->uint16;
|
||||
break;
|
||||
case LY_TYPE_UINT32:
|
||||
num = storage->uint32;
|
||||
break;
|
||||
case LY_TYPE_UINT64:
|
||||
num = storage->uint64;
|
||||
break;
|
||||
default:
|
||||
return LY_EINVAL;
|
||||
}
|
||||
|
||||
/* validate range of the number */
|
||||
if (type_num->range) {
|
||||
ret = lyplg_type_validate_range(type->basetype, type_num->range, num, storage->_canonical,
|
||||
strlen(storage->_canonical), err);
|
||||
LY_CHECK_RET(ret);
|
||||
}
|
||||
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
lyplg_type_compare_uint(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *val1, const struct lyd_value *val2)
|
||||
{
|
||||
|
@ -646,7 +567,7 @@ const struct lyplg_type_record plugins_integer[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - integers, version 1",
|
||||
.plugin.store = lyplg_type_store_uint,
|
||||
.plugin.validate = lyplg_type_validate_uint,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_uint,
|
||||
.plugin.sort = lyplg_type_sort_uint,
|
||||
.plugin.print = lyplg_type_print_uint,
|
||||
|
@ -660,7 +581,7 @@ const struct lyplg_type_record plugins_integer[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - integers, version 1",
|
||||
.plugin.store = lyplg_type_store_uint,
|
||||
.plugin.validate = lyplg_type_validate_uint,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_uint,
|
||||
.plugin.sort = lyplg_type_sort_uint,
|
||||
.plugin.print = lyplg_type_print_uint,
|
||||
|
@ -674,7 +595,7 @@ const struct lyplg_type_record plugins_integer[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - integers, version 1",
|
||||
.plugin.store = lyplg_type_store_uint,
|
||||
.plugin.validate = lyplg_type_validate_uint,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_uint,
|
||||
.plugin.sort = lyplg_type_sort_uint,
|
||||
.plugin.print = lyplg_type_print_uint,
|
||||
|
@ -688,7 +609,7 @@ const struct lyplg_type_record plugins_integer[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - integers, version 1",
|
||||
.plugin.store = lyplg_type_store_uint,
|
||||
.plugin.validate = lyplg_type_validate_uint,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_uint,
|
||||
.plugin.sort = lyplg_type_sort_uint,
|
||||
.plugin.print = lyplg_type_print_uint,
|
||||
|
@ -702,7 +623,7 @@ const struct lyplg_type_record plugins_integer[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - integers, version 1",
|
||||
.plugin.store = lyplg_type_store_int,
|
||||
.plugin.validate = lyplg_type_validate_int,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_int,
|
||||
.plugin.sort = lyplg_type_sort_int,
|
||||
.plugin.print = lyplg_type_print_int,
|
||||
|
@ -716,7 +637,7 @@ const struct lyplg_type_record plugins_integer[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - integers, version 1",
|
||||
.plugin.store = lyplg_type_store_int,
|
||||
.plugin.validate = lyplg_type_validate_int,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_int,
|
||||
.plugin.sort = lyplg_type_sort_int,
|
||||
.plugin.print = lyplg_type_print_int,
|
||||
|
@ -730,7 +651,7 @@ const struct lyplg_type_record plugins_integer[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - integers, version 1",
|
||||
.plugin.store = lyplg_type_store_int,
|
||||
.plugin.validate = lyplg_type_validate_int,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_int,
|
||||
.plugin.sort = lyplg_type_sort_int,
|
||||
.plugin.print = lyplg_type_print_int,
|
||||
|
@ -744,7 +665,7 @@ const struct lyplg_type_record plugins_integer[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - integers, version 1",
|
||||
.plugin.store = lyplg_type_store_int,
|
||||
.plugin.validate = lyplg_type_validate_int,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_int,
|
||||
.plugin.sort = lyplg_type_sort_int,
|
||||
.plugin.print = lyplg_type_print_int,
|
||||
|
|
|
@ -171,17 +171,19 @@ lyplg_type_store_ipv4_address(const struct ly_ctx *ctx, const struct lysc_type *
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* get the network-byte order address */
|
||||
ret = ipv4address_str2ip(value, value_len, options, ctx, &val->addr, &val->zone, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
|
|
@ -57,7 +57,6 @@ lyplg_type_store_ipv4_address_no_zone(const struct ly_ctx *ctx, const struct lys
|
|||
struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
struct lysc_type_str *type_str = (struct lysc_type_str *)type;
|
||||
struct lyd_value_ipv4_address_no_zone *val;
|
||||
|
||||
/* init storage */
|
||||
|
@ -85,17 +84,6 @@ lyplg_type_store_ipv4_address_no_zone(const struct ly_ctx *ctx, const struct lys
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* we always need a dynamic value */
|
||||
if (!(options & LYPLG_TYPE_STORE_DYNAMIC)) {
|
||||
value = strndup(value, value_len);
|
||||
|
@ -104,7 +92,7 @@ lyplg_type_store_ipv4_address_no_zone(const struct ly_ctx *ctx, const struct lys
|
|||
options |= LYPLG_TYPE_STORE_DYNAMIC;
|
||||
}
|
||||
|
||||
/* get the network-byte order address */
|
||||
/* get the network-byte order address, validates the value */
|
||||
if (!inet_pton(AF_INET, value, &val->addr)) {
|
||||
ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL, "Failed to convert IPv4 address \"%s\".", (char *)value);
|
||||
goto cleanup;
|
||||
|
|
|
@ -156,17 +156,19 @@ lyplg_type_store_ipv4_prefix(const struct ly_ctx *ctx, const struct lysc_type *t
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* get the mask in network-byte order */
|
||||
ret = ipv4prefix_str2ip(value, value_len, &val->addr, &val->prefix, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
|
|
@ -172,17 +172,19 @@ lyplg_type_store_ipv6_address(const struct ly_ctx *ctx, const struct lysc_type *
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* get the network-byte order address */
|
||||
ret = ipv6address_str2ip(value, value_len, options, ctx, &val->addr, &val->zone, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
|
|
@ -96,7 +96,6 @@ lyplg_type_store_ipv6_address_no_zone(const struct ly_ctx *ctx, const struct lys
|
|||
struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
struct lysc_type_str *type_str = (struct lysc_type_str *)type;
|
||||
struct lyd_value_ipv6_address_no_zone *val;
|
||||
|
||||
/* init storage */
|
||||
|
@ -136,18 +135,7 @@ lyplg_type_store_ipv6_address_no_zone(const struct ly_ctx *ctx, const struct lys
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* get the network-byte order address */
|
||||
/* get the network-byte order address, validates the value */
|
||||
ret = ipv6addressnozone_str2ip(value, value_len, options, &val->addr, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
|
|
|
@ -170,17 +170,19 @@ lyplg_type_store_ipv6_prefix(const struct ly_ctx *ctx, const struct lysc_type *t
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* get the mask in network-byte order */
|
||||
ret = ipv6prefix_str2ip(value, value_len, &val->addr, &val->prefix, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
|
|
@ -41,19 +41,19 @@ lyplg_type_store_leafref(const struct ly_ctx *ctx, const struct lysc_type *type,
|
|||
uint32_t options, LY_VALUE_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;
|
||||
LY_ERR rc = LY_SUCCESS;
|
||||
struct lysc_type_leafref *type_lr = (struct lysc_type_leafref *)type;
|
||||
|
||||
assert(type_lr->realtype);
|
||||
|
||||
/* store the value as the real type of the leafref target */
|
||||
ret = type_lr->realtype->plugin->store(ctx, type_lr->realtype, value, value_len, options, format, prefix_data,
|
||||
rc = type_lr->realtype->plugin->store(ctx, type_lr->realtype, value, value_len, options, format, prefix_data,
|
||||
hints, ctx_node, storage, unres, err);
|
||||
if (ret == LY_EINCOMPLETE) {
|
||||
if (rc == LY_EINCOMPLETE) {
|
||||
/* it is irrelevant whether the target type needs some resolving */
|
||||
ret = LY_SUCCESS;
|
||||
rc = LY_SUCCESS;
|
||||
}
|
||||
LY_CHECK_RET(ret);
|
||||
LY_CHECK_RET(rc);
|
||||
|
||||
if (type_lr->require_instance) {
|
||||
/* needs to be resolved */
|
||||
|
@ -67,7 +67,7 @@ LIBYANG_API_DEF LY_ERR
|
|||
lyplg_type_validate_leafref(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)
|
||||
{
|
||||
LY_ERR ret;
|
||||
LY_ERR rc = LY_SUCCESS;
|
||||
struct lysc_type_leafref *type_lr = (struct lysc_type_leafref *)type;
|
||||
char *errmsg = NULL, *path;
|
||||
struct ly_set *targets = NULL;
|
||||
|
@ -80,24 +80,25 @@ lyplg_type_validate_leafref(const struct ly_ctx *ctx, const struct lysc_type *ty
|
|||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
ret = lyplg_type_resolve_leafref(type_lr, ctx_node, storage, tree, (ly_ctx_get_options(ctx) & LY_CTX_LEAFREF_LINKING) ? &targets : NULL, &errmsg);
|
||||
if (ret != LY_SUCCESS) {
|
||||
rc = lyplg_type_resolve_leafref(type_lr, ctx_node, storage, tree,
|
||||
(ly_ctx_get_options(ctx) & LY_CTX_LEAFREF_LINKING) ? &targets : NULL, &errmsg);
|
||||
if (rc) {
|
||||
path = lyd_path(ctx_node, LYD_PATH_STD, NULL, 0);
|
||||
ret = ly_err_new(err, LY_EVALID, LYVE_DATA, path, strdup("instance-required"), "%s", errmsg);
|
||||
rc = ly_err_new(err, LY_EVALID, LYVE_DATA, path, strdup("instance-required"), "%s", errmsg);
|
||||
free(errmsg);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ly_ctx_get_options(ctx) & LY_CTX_LEAFREF_LINKING) {
|
||||
for (i = 0; i < targets->count; ++i) {
|
||||
ret = lyd_link_leafref_node((struct lyd_node_term *)targets->dnodes[i], (struct lyd_node_term *)ctx_node);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
rc = lyd_link_leafref_node((struct lyd_node_term *)targets->dnodes[i], (struct lyd_node_term *)ctx_node);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
ly_set_free(targets, NULL);
|
||||
return ret;
|
||||
return rc;
|
||||
}
|
||||
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
|
|
|
@ -312,8 +312,8 @@ const struct lyplg_type_record plugins_node_instanceid[] = {
|
|||
.plugin.id = "libyang 2 - node-instance-identifier, version 1",
|
||||
.plugin.store = lyplg_type_store_node_instanceid,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_instanceid,
|
||||
.plugin.sort = lyplg_type_sort_instanceid,
|
||||
.plugin.compare = lyplg_type_compare_simple,
|
||||
.plugin.sort = lyplg_type_sort_simple,
|
||||
.plugin.print = lyplg_type_print_node_instanceid,
|
||||
.plugin.duplicate = lyplg_type_dup_instanceid,
|
||||
.plugin.free = lyplg_type_free_instanceid,
|
||||
|
@ -327,8 +327,8 @@ const struct lyplg_type_record plugins_node_instanceid[] = {
|
|||
.plugin.id = "libyang 2 - node-instance-identifier, version 1",
|
||||
.plugin.store = lyplg_type_store_node_instanceid,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_instanceid,
|
||||
.plugin.sort = lyplg_type_sort_instanceid,
|
||||
.plugin.compare = lyplg_type_compare_simple,
|
||||
.plugin.sort = lyplg_type_sort_simple,
|
||||
.plugin.print = lyplg_type_print_node_instanceid,
|
||||
.plugin.duplicate = lyplg_type_dup_instanceid,
|
||||
.plugin.free = lyplg_type_free_instanceid,
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
* | string length | yes | `char *` | string itself |
|
||||
*/
|
||||
|
||||
static LY_ERR lyplg_type_validate_string(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node), const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err);
|
||||
|
||||
/**
|
||||
* @brief Check string value for invalid characters.
|
||||
*
|
||||
|
@ -65,6 +63,7 @@ lyplg_type_store_string(const struct ly_ctx *ctx, const struct lysc_type *type,
|
|||
const struct lysc_node *UNUSED(ctx_node), struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres),
|
||||
struct ly_err_item **err)
|
||||
{
|
||||
struct lysc_type_str *type_str = (struct lysc_type_str *)type;
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
||||
/* init storage */
|
||||
|
@ -86,14 +85,24 @@ lyplg_type_store_string(const struct ly_ctx *ctx, const struct lysc_type *type,
|
|||
ret = lydict_insert_zc(ctx, (char *)value, &storage->_canonical);
|
||||
options &= ~LYPLG_TYPE_STORE_DYNAMIC;
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* value may have been freed */
|
||||
value = storage->_canonical;
|
||||
} else {
|
||||
ret = lydict_insert(ctx, value_len ? value : "", value_len, &storage->_canonical);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
|
||||
/* validate value */
|
||||
ret = lyplg_type_validate_string(ctx, type, NULL, NULL, storage, err);
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
|
@ -108,37 +117,6 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_validate_clb for the string type.
|
||||
*/
|
||||
static LY_ERR
|
||||
lyplg_type_validate_string(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node),
|
||||
const struct lyd_node *UNUSED(tree), struct lyd_value *storage, struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret;
|
||||
struct lysc_type_str *type_str = (struct lysc_type_str *)type;
|
||||
const void *value;
|
||||
size_t value_len;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, type, storage, err, LY_EINVAL);
|
||||
value = lyd_value_get_canonical(ctx, storage);
|
||||
value_len = strlen(value);
|
||||
*err = NULL;
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_RET(ret);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_RET(ret);
|
||||
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Plugin information for string type implementation.
|
||||
*
|
||||
|
@ -154,7 +132,7 @@ const struct lyplg_type_record plugins_string[] = {
|
|||
|
||||
.plugin.id = "libyang 2 - string, version 1",
|
||||
.plugin.store = lyplg_type_store_string,
|
||||
.plugin.validate = lyplg_type_validate_string,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_simple,
|
||||
.plugin.sort = lyplg_type_sort_simple,
|
||||
.plugin.print = lyplg_type_print_simple,
|
||||
|
|
100
src/plugins_types/time_period.c
Normal file
100
src/plugins_types/time_period.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @file time_period.c
|
||||
* @author Roman Janota <janota@cesnet.cz>
|
||||
* @brief libnetconf2-netconf-server time-period type plugin.
|
||||
*
|
||||
* Copyright (c) 2024 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
|
||||
*/
|
||||
|
||||
#include "plugins_types.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libyang.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "ly_common.h"
|
||||
#include "plugins_internal.h" /* LY_TYPE_*_STR */
|
||||
|
||||
/**
|
||||
* @page howtoDataLYB LYB Binary Format
|
||||
* @subsection howtoDataLYBTypesTimePeriod time-period (libnetconf2-netconf-server)
|
||||
*
|
||||
* | Size (B) | Mandatory | Type | Meaning |
|
||||
* | :------ | :-------: | :--: | :-----: |
|
||||
* | string length | yes | `char *` | time in either months, weeks, days, or hours |
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Implementation of ::lyplg_type_sort_clb for libnetconf2-netconf-server time-period type.
|
||||
*
|
||||
* The values are sorted in descending order, i.e. the longest expiration time comes first.
|
||||
*/
|
||||
static int
|
||||
lyplg_type_sort_time_period(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
|
||||
{
|
||||
const char *value1, *value2;
|
||||
char unit1, unit2;
|
||||
long v1, v2;
|
||||
|
||||
value1 = lyd_value_get_canonical(ctx, val1);
|
||||
value2 = lyd_value_get_canonical(ctx, val2);
|
||||
|
||||
/* get the units (last character) and the values (all characters except the last one) */
|
||||
unit1 = value1[strlen(value1) - 1];
|
||||
unit2 = value2[strlen(value2) - 1];
|
||||
v1 = strtol(value1, NULL, 10);
|
||||
v2 = strtol(value2, NULL, 10);
|
||||
|
||||
/* descending order */
|
||||
if (unit1 == unit2) {
|
||||
if (v1 > v2) {
|
||||
return -1;
|
||||
} else if (v1 == v2) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else if (unit1 == 'm') {
|
||||
return -1;
|
||||
} else if ((unit1 == 'w') && (unit2 != 'm')) {
|
||||
return -1;
|
||||
} else if ((unit1 == 'd') && (unit2 == 'h')) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Plugin information for time-period type implementation.
|
||||
*
|
||||
* Note that external plugins are supposed to use:
|
||||
*
|
||||
* LYPLG_TYPES = {
|
||||
*/
|
||||
const struct lyplg_type_record plugins_time_period[] = {
|
||||
{
|
||||
.module = "libnetconf2-netconf-server",
|
||||
.revision = "2024-07-09",
|
||||
.name = "time-period",
|
||||
|
||||
.plugin.id = "libyang 2 - time-period, version 1",
|
||||
.plugin.store = lyplg_type_store_string,
|
||||
.plugin.validate = NULL,
|
||||
.plugin.compare = lyplg_type_compare_simple,
|
||||
.plugin.sort = lyplg_type_sort_time_period,
|
||||
.plugin.print = lyplg_type_print_simple,
|
||||
.plugin.duplicate = lyplg_type_dup_simple,
|
||||
.plugin.free = lyplg_type_free_simple,
|
||||
.plugin.lyb_data_len = -1,
|
||||
},
|
||||
{0}
|
||||
};
|
|
@ -493,7 +493,7 @@ lyplg_type_compare_union(const struct ly_ctx *ctx, const struct lyd_value *val1,
|
|||
LIBYANG_API_DEF int
|
||||
lyplg_type_sort_union(const struct ly_ctx *ctx, const struct lyd_value *val1, const struct lyd_value *val2)
|
||||
{
|
||||
int ret;
|
||||
int rc = LY_SUCCESS;
|
||||
LY_ARRAY_COUNT_TYPE u;
|
||||
struct lysc_type **types;
|
||||
|
||||
|
@ -502,20 +502,19 @@ lyplg_type_sort_union(const struct ly_ctx *ctx, const struct lyd_value *val1, co
|
|||
}
|
||||
|
||||
/* compare according to the order of types */
|
||||
ret = 0;
|
||||
types = ((struct lysc_type_union *)val1->realtype)->types;
|
||||
LY_ARRAY_FOR(types, u) {
|
||||
if (types[u] == val1->subvalue->value.realtype) {
|
||||
ret = 1;
|
||||
rc = 1;
|
||||
break;
|
||||
} else if (types[u] == val2->subvalue->value.realtype) {
|
||||
ret = -1;
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(ret != 0);
|
||||
assert(rc != 0);
|
||||
|
||||
return ret;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -248,7 +248,6 @@ lyplg_type_store_xpath10(const struct ly_ctx *ctx, const struct lysc_type *type,
|
|||
struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
|
||||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
struct lysc_type_str *type_str = (struct lysc_type_str *)type;
|
||||
struct lyd_value_xpath10 *val;
|
||||
char *canon;
|
||||
|
||||
|
@ -262,17 +261,6 @@ lyplg_type_store_xpath10(const struct ly_ctx *ctx, const struct lysc_type *type,
|
|||
ret = lyplg_type_check_hints(hints, value, value_len, type->basetype, NULL, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* length restriction of the string */
|
||||
if (type_str->length) {
|
||||
/* value_len is in bytes, but we need number of characters here */
|
||||
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_len), value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
}
|
||||
|
||||
/* pattern restrictions */
|
||||
ret = lyplg_type_validate_patterns(type_str->patterns, value, value_len, err);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
||||
/* parse */
|
||||
ret = lyxp_expr_parse(ctx, value_len ? value : "", value_len, 1, &val->exp);
|
||||
LY_CHECK_GOTO(ret, cleanup);
|
||||
|
|
|
@ -1162,7 +1162,7 @@ yprp_inout(struct lys_ypr_ctx *pctx, const struct lysp_node_action_inout *inout,
|
|||
ly_print_(pctx->out, "%*s%s {\n", INDENT, inout->name);
|
||||
LEVEL++;
|
||||
|
||||
yprp_extension_instances(pctx, LY_STMT_MUST, 0, inout->exts, NULL);
|
||||
yprp_extension_instances(pctx, lyplg_ext_nodetype2stmt(inout->nodetype), 0, inout->exts, NULL);
|
||||
LY_ARRAY_FOR(inout->musts, u) {
|
||||
yprp_restr(pctx, &inout->musts[u], LY_STMT_MUST, NULL);
|
||||
}
|
||||
|
@ -2563,7 +2563,7 @@ lyplg_ext_print_info_extension_instance(struct lyspr_ctx *ctx, const struct lysc
|
|||
break;
|
||||
}
|
||||
|
||||
LY_LIST_FOR(*VOIDPTR2_C(ext->substmts[u].storage), node) {
|
||||
LY_LIST_FOR(*ext->substmts[u].storage_p, node) {
|
||||
ypr_open(pctx->out, flag);
|
||||
if (ext->substmts[u].stmt == LY_STMT_NOTIFICATION) {
|
||||
yprc_notification(pctx, (struct lysc_node_notif *)node);
|
||||
|
@ -2592,32 +2592,32 @@ lyplg_ext_print_info_extension_instance(struct lyspr_ctx *ctx, const struct lysc
|
|||
case LY_STMT_PRESENCE:
|
||||
case LY_STMT_REFERENCE:
|
||||
case LY_STMT_UNITS:
|
||||
if (*VOIDPTR2_C(ext->substmts[u].storage)) {
|
||||
if (*ext->substmts[u].storage_p) {
|
||||
ypr_open(pctx->out, flag);
|
||||
ypr_substmt(pctx, ext->substmts[u].stmt, 0, *VOIDPTR2_C(ext->substmts[u].storage), 0, ext->exts);
|
||||
ypr_substmt(pctx, ext->substmts[u].stmt, 0, *ext->substmts[u].storage_p, 0, ext->exts);
|
||||
}
|
||||
break;
|
||||
case LY_STMT_BIT:
|
||||
case LY_STMT_ENUM: {
|
||||
const struct lysc_type_bitenum_item *items = *VOIDPTR2_C(ext->substmts[u].storage);
|
||||
const struct lysc_type_bitenum_item *items = *ext->substmts[u].storage_p;
|
||||
|
||||
yprc_bits_enum(pctx, items, ext->substmts[u].stmt == LY_STMT_BIT ? LY_TYPE_BITS : LY_TYPE_ENUM, flag);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_CONFIG:
|
||||
ypr_config(pctx, *(uint16_t *)VOIDPTR2_C(ext->substmts[u].storage), ext->exts, flag);
|
||||
ypr_config(pctx, *(uint16_t *)ext->substmts[u].storage_p, ext->exts, flag);
|
||||
break;
|
||||
case LY_STMT_EXTENSION_INSTANCE:
|
||||
yprc_extension_instances(pctx, LY_STMT_EXTENSION_INSTANCE, 0, *VOIDPTR2_C(ext->substmts[u].storage), flag);
|
||||
yprc_extension_instances(pctx, LY_STMT_EXTENSION_INSTANCE, 0, *ext->substmts[u].storage_p, flag);
|
||||
break;
|
||||
case LY_STMT_FRACTION_DIGITS:
|
||||
if (*VOIDPTR2_C(ext->substmts[u].storage)) {
|
||||
if (*ext->substmts[u].storage_p) {
|
||||
ypr_unsigned(pctx, LY_STMT_FRACTION_DIGITS, 0, ext->exts,
|
||||
(long unsigned int)*VOIDPTR2_C(ext->substmts[u].storage), flag);
|
||||
(long unsigned int)*ext->substmts[u].storage_p, flag);
|
||||
}
|
||||
break;
|
||||
case LY_STMT_IDENTITY: {
|
||||
const struct lysc_ident *idents = *VOIDPTR2_C(ext->substmts[u].storage);
|
||||
const struct lysc_ident *idents = *ext->substmts[u].storage_p;
|
||||
|
||||
LY_ARRAY_FOR(idents, v) {
|
||||
yprc_identity(pctx, &idents[v]);
|
||||
|
@ -2625,15 +2625,15 @@ lyplg_ext_print_info_extension_instance(struct lyspr_ctx *ctx, const struct lysc
|
|||
break;
|
||||
}
|
||||
case LY_STMT_LENGTH:
|
||||
if (*VOIDPTR2_C(ext->substmts[u].storage)) {
|
||||
yprc_range(pctx, *VOIDPTR2_C(ext->substmts[u].storage), LY_TYPE_STRING, flag);
|
||||
if (*ext->substmts[u].storage_p) {
|
||||
yprc_range(pctx, *ext->substmts[u].storage_p, LY_TYPE_STRING, flag);
|
||||
}
|
||||
break;
|
||||
case LY_STMT_MANDATORY:
|
||||
ypr_mandatory(pctx, *(uint16_t *)VOIDPTR_C(ext->substmts[u].storage), ext->exts, flag);
|
||||
ypr_mandatory(pctx, *(uint16_t *)ext->substmts[u].storage_p, ext->exts, flag);
|
||||
break;
|
||||
case LY_STMT_MAX_ELEMENTS: {
|
||||
uint32_t max = *(uint32_t *)VOIDPTR_C(ext->substmts[u].storage);
|
||||
uint32_t max = *(uint32_t *)ext->substmts[u].storage_p;
|
||||
|
||||
if (max) {
|
||||
ypr_unsigned(pctx, LY_STMT_MAX_ELEMENTS, 0, ext->exts, max, flag);
|
||||
|
@ -2644,15 +2644,15 @@ lyplg_ext_print_info_extension_instance(struct lyspr_ctx *ctx, const struct lysc
|
|||
break;
|
||||
}
|
||||
case LY_STMT_MIN_ELEMENTS:
|
||||
ypr_unsigned(pctx, LY_STMT_MIN_ELEMENTS, 0, ext->exts, *(uint32_t *)VOIDPTR_C(ext->substmts[u].storage), flag);
|
||||
ypr_unsigned(pctx, LY_STMT_MIN_ELEMENTS, 0, ext->exts, *(uint32_t *)ext->substmts[u].storage_p, flag);
|
||||
break;
|
||||
case LY_STMT_ORDERED_BY:
|
||||
ypr_open(pctx->out, flag);
|
||||
ypr_substmt(pctx, LY_STMT_ORDERED_BY, 0,
|
||||
((*(uint16_t *)VOIDPTR_C(ext->substmts[u].storage)) & LYS_ORDBY_USER) ? "user" : "system", 0, ext->exts);
|
||||
((*(uint16_t *)ext->substmts[u].storage_p) & LYS_ORDBY_USER) ? "user" : "system", 0, ext->exts);
|
||||
break;
|
||||
case LY_STMT_MUST: {
|
||||
const struct lysc_must *musts = *VOIDPTR2_C(ext->substmts[u].storage);
|
||||
const struct lysc_must *musts = *ext->substmts[u].storage_p;
|
||||
|
||||
LY_ARRAY_FOR(musts, v) {
|
||||
yprc_must(pctx, &musts[v], flag);
|
||||
|
@ -2660,7 +2660,7 @@ lyplg_ext_print_info_extension_instance(struct lyspr_ctx *ctx, const struct lysc
|
|||
break;
|
||||
}
|
||||
case LY_STMT_PATTERN: {
|
||||
const struct lysc_pattern *patterns = *VOIDPTR2_C(ext->substmts[u].storage);
|
||||
const struct lysc_pattern *patterns = *ext->substmts[u].storage_p;
|
||||
|
||||
LY_ARRAY_FOR(patterns, v) {
|
||||
yprc_pattern(pctx, &patterns[v], flag);
|
||||
|
@ -2668,36 +2668,36 @@ lyplg_ext_print_info_extension_instance(struct lyspr_ctx *ctx, const struct lysc
|
|||
break;
|
||||
}
|
||||
case LY_STMT_POSITION:
|
||||
if (*VOIDPTR2_C(ext->substmts[u].storage)) {
|
||||
ypr_unsigned(pctx, ext->substmts[u].stmt, 0, ext->exts, *(int64_t *)VOIDPTR_C(ext->substmts[u].storage), flag);
|
||||
if (*ext->substmts[u].storage_p) {
|
||||
ypr_unsigned(pctx, ext->substmts[u].stmt, 0, ext->exts, *(int64_t *)ext->substmts[u].storage_p, flag);
|
||||
}
|
||||
break;
|
||||
case LY_STMT_VALUE:
|
||||
if (*VOIDPTR2_C(ext->substmts[u].storage)) {
|
||||
ypr_signed(pctx, ext->substmts[u].stmt, 0, ext->exts, *(int64_t *)VOIDPTR_C(ext->substmts[u].storage), flag);
|
||||
if (*ext->substmts[u].storage_p) {
|
||||
ypr_signed(pctx, ext->substmts[u].stmt, 0, ext->exts, *(int64_t *)ext->substmts[u].storage_p, flag);
|
||||
}
|
||||
break;
|
||||
case LY_STMT_RANGE:
|
||||
if (*VOIDPTR2_C(ext->substmts[u].storage)) {
|
||||
yprc_range(pctx, *VOIDPTR2_C(ext->substmts[u].storage), LY_TYPE_UINT64, flag);
|
||||
if (*ext->substmts[u].storage_p) {
|
||||
yprc_range(pctx, *ext->substmts[u].storage_p, LY_TYPE_UINT64, flag);
|
||||
}
|
||||
break;
|
||||
case LY_STMT_REQUIRE_INSTANCE:
|
||||
ypr_open(pctx->out, flag);
|
||||
ypr_substmt(pctx, LY_STMT_REQUIRE_INSTANCE, 0, *(uint8_t *)VOIDPTR_C(ext->substmts[u].storage) ? "true" : "false",
|
||||
ypr_substmt(pctx, LY_STMT_REQUIRE_INSTANCE, 0, *(uint8_t *)ext->substmts[u].storage_p ? "true" : "false",
|
||||
0, ext->exts);
|
||||
break;
|
||||
case LY_STMT_STATUS:
|
||||
ypr_status(pctx, *(uint16_t *)VOIDPTR_C(ext->substmts[u].storage), ext->exts, flag);
|
||||
ypr_status(pctx, *(uint16_t *)ext->substmts[u].storage_p, ext->exts, flag);
|
||||
break;
|
||||
case LY_STMT_TYPE:
|
||||
if (*VOIDPTR2_C(ext->substmts[u].storage)) {
|
||||
if (*ext->substmts[u].storage_p) {
|
||||
ypr_open(pctx->out, flag);
|
||||
yprc_type(pctx, *VOIDPTR2_C(ext->substmts[u].storage));
|
||||
yprc_type(pctx, *ext->substmts[u].storage_p);
|
||||
}
|
||||
break;
|
||||
case LY_STMT_WHEN:
|
||||
yprc_when(pctx, *VOIDPTR2_C(ext->substmts[u].storage), flag);
|
||||
yprc_when(pctx, *ext->substmts[u].storage_p, flag);
|
||||
break;
|
||||
case LY_STMT_AUGMENT:
|
||||
case LY_STMT_BASE:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @author Michal Vasko <mvasko@cesnet.cz>
|
||||
* @brief Schema compilation.
|
||||
*
|
||||
* Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
|
||||
* Copyright (c) 2015 - 2024 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.
|
||||
|
@ -172,7 +172,10 @@ lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *extp, struct lys
|
|||
/* compile extension if not already */
|
||||
LY_CHECK_GOTO(ret = lys_compile_extension(ctx, extp, &ext->def), cleanup);
|
||||
|
||||
/* compile */
|
||||
/* compile nested extensions */
|
||||
COMPILE_EXTS_GOTO(ctx, extp->exts, ext->exts, ext, ret, cleanup);
|
||||
|
||||
/* compile this extension */
|
||||
if (ext->def->plugin && ext->def->plugin->compile) {
|
||||
if (ext->argument) {
|
||||
lysc_update_path(ctx, ext->module, ext->argument);
|
||||
|
@ -218,7 +221,7 @@ lys_identity_precompile(struct lysc_ctx *ctx_sc, struct ly_ctx *ctx, struct lysp
|
|||
const struct lysp_ident *identities_p, struct lysc_ident **identities)
|
||||
{
|
||||
LY_ARRAY_COUNT_TYPE u;
|
||||
struct lysc_ctx cctx;
|
||||
struct lysc_ctx cctx = {0};
|
||||
struct lysc_ident *ident;
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
|
||||
|
@ -863,7 +866,7 @@ lys_compile_unres_leafref(struct lysc_ctx *ctx, const struct lysc_node *node, st
|
|||
|
||||
/* get the target node */
|
||||
target = p[LY_ARRAY_COUNT(p) - 1].node;
|
||||
ly_path_free(node->module->ctx, p);
|
||||
ly_path_free(p);
|
||||
|
||||
if (!(target->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
|
||||
LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid leafref path \"%s\" - target node is %s instead of leaf or leaf-list.",
|
||||
|
@ -960,6 +963,12 @@ lys_compile_unres_dflt(struct lysc_ctx *ctx, struct lysc_node *node, struct lysc
|
|||
}
|
||||
|
||||
LY_ATOMIC_INC_BARRIER(((struct lysc_type *)storage->realtype)->refcount);
|
||||
if (storage->realtype->basetype == LY_TYPE_INST) {
|
||||
/* ly_path includes references to other nodes, in case they are in foreign modules, the context would
|
||||
* need to be freed in specific order to avoid accessing freed memory, so just avoid storing it */
|
||||
ly_path_free(storage->target);
|
||||
storage->target = NULL;
|
||||
}
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1453,7 +1462,7 @@ resolve_all:
|
|||
ret = ly_path_compile_leafref(cctx.ctx, l->node, cctx.ext, lref->path,
|
||||
(l->node->flags & LYS_IS_OUTPUT) ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_MANY,
|
||||
LY_VALUE_SCHEMA_RESOLVED, lref->prefixes, &path);
|
||||
ly_path_free(l->node->module->ctx, path);
|
||||
ly_path_free(path);
|
||||
|
||||
assert(ret != LY_ERECOMPILE);
|
||||
if (ret) {
|
||||
|
@ -1468,7 +1477,7 @@ resolve_all:
|
|||
}
|
||||
|
||||
cleanup:
|
||||
lysf_ctx_erase(&cctx.free_ctx);
|
||||
assert(!cctx.free_ctx.ext_set.count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1548,8 +1557,8 @@ lys_compile_depset_r(struct ly_ctx *ctx, struct ly_set *dep_set, struct lys_glob
|
|||
}
|
||||
|
||||
cleanup:
|
||||
assert(!fctx.ext_set.count);
|
||||
lys_compile_unres_depset_erase(ctx, unres);
|
||||
lysf_ctx_erase(&fctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1693,7 +1702,7 @@ lys_compile_unres_mod_erase(struct lysc_ctx *ctx, ly_bool error)
|
|||
LY_ERR
|
||||
lys_compile(struct lys_module *mod, struct lys_depset_unres *unres)
|
||||
{
|
||||
struct lysc_ctx ctx;
|
||||
struct lysc_ctx ctx = {0};
|
||||
struct lysc_module *mod_c = NULL;
|
||||
struct lysp_module *sp;
|
||||
struct lysp_submodule *submod;
|
||||
|
@ -1814,7 +1823,7 @@ LY_ERR
|
|||
lys_compile_identities(struct lys_module *mod)
|
||||
{
|
||||
LY_ERR rc = LY_SUCCESS;
|
||||
struct lysc_ctx ctx;
|
||||
struct lysc_ctx ctx = {0};
|
||||
struct lysp_submodule *submod;
|
||||
LY_ARRAY_COUNT_TYPE u;
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@ struct lysc_ctx {
|
|||
* @param[in] CTX libyang context.
|
||||
*/
|
||||
#define LYSC_CTX_INIT_CTX(CCTX, CTX) \
|
||||
memset(&(CCTX), 0, sizeof (CCTX)); \
|
||||
(CCTX).ctx = (CTX); \
|
||||
(CCTX).path_len = 1; \
|
||||
(CCTX).path[0] = '/'; \
|
||||
|
@ -81,7 +80,6 @@ struct lysc_ctx {
|
|||
* @param[in] EXT Ancestor extension instance.
|
||||
*/
|
||||
#define LYSC_CTX_INIT_PMOD(CCTX, PMOD, EXT) \
|
||||
memset(&(CCTX), 0, sizeof (CCTX)); \
|
||||
(CCTX).ctx = (PMOD)->mod->ctx; \
|
||||
(CCTX).cur_mod = (PMOD)->mod; \
|
||||
(CCTX).pmod = (PMOD); \
|
||||
|
@ -164,9 +162,9 @@ struct lysc_unres_dflt {
|
|||
* @param[out] DUP Where to store the result.
|
||||
* @param[out] RET Where to store the return code.
|
||||
*/
|
||||
#define DUP_STRING(CTX, ORIG, DUP, RET) RET = lydict_insert(CTX, ORIG, 0, &(DUP))
|
||||
#define DUP_STRING_RET(CTX, ORIG, DUP) LY_CHECK_RET(lydict_insert(CTX, ORIG, 0, &(DUP)))
|
||||
#define DUP_STRING_GOTO(CTX, ORIG, DUP, RET, GOTO) LY_CHECK_GOTO(RET = lydict_insert(CTX, ORIG, 0, &(DUP)), GOTO)
|
||||
#define DUP_STRING(CTX, ORIG, DUP, RET) RET = lydict_dup(CTX, ORIG, &(DUP))
|
||||
#define DUP_STRING_RET(CTX, ORIG, DUP) LY_CHECK_RET(lydict_dup(CTX, ORIG, &(DUP)))
|
||||
#define DUP_STRING_GOTO(CTX, ORIG, DUP, RET, GOTO) LY_CHECK_GOTO(RET = lydict_dup(CTX, ORIG, &(DUP)), GOTO)
|
||||
|
||||
#define DUP_ARRAY(CTX, ORIG_ARRAY, NEW_ARRAY, DUP_FUNC) \
|
||||
if (ORIG_ARRAY) { \
|
||||
|
|
|
@ -2218,7 +2218,7 @@ lys_precompile_own_augments_mod(struct lysc_ctx *ctx, const struct lysp_module *
|
|||
aug_p = NULL;
|
||||
LY_ARRAY_FOR(pmod->exts[u].substmts, v) {
|
||||
if (pmod->exts[u].substmts[v].stmt == LY_STMT_AUGMENT) {
|
||||
aug_p = *VOIDPTR2_C(pmod->exts[u].substmts[v].storage);
|
||||
aug_p = *(pmod->exts[u].substmts[v].storage_p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2443,7 +2443,7 @@ lys_precompile_mod_augments_deviations(struct lysp_module *pmod, struct ly_set *
|
|||
{
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
LY_ARRAY_COUNT_TYPE u, v;
|
||||
struct lysc_ctx ctx;
|
||||
struct lysc_ctx ctx = {0};
|
||||
struct lys_module *m;
|
||||
struct lysp_node_augment *aug;
|
||||
struct ly_set set = {0};
|
||||
|
@ -2488,7 +2488,7 @@ lys_precompile_mod_augments_deviations(struct lysp_module *pmod, struct ly_set *
|
|||
aug = NULL;
|
||||
LY_ARRAY_FOR(pmod->exts[u].substmts, v) {
|
||||
if (pmod->exts[u].substmts[v].stmt == LY_STMT_AUGMENT) {
|
||||
aug = *VOIDPTR2_C(pmod->exts[u].substmts[v].storage);
|
||||
aug = *(pmod->exts[u].substmts[v].storage_p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1390,7 +1390,7 @@ lys_compile_type_patterns(struct lysc_ctx *ctx, const struct lysp_restr *pattern
|
|||
if (patterns_p[u].arg.str[0] == LYSP_RESTR_PATTERN_NACK) {
|
||||
(*pattern)->inverted = 1;
|
||||
}
|
||||
DUP_STRING_GOTO(ctx->ctx, &patterns_p[u].arg.str[1], (*pattern)->expr, ret, done);
|
||||
LY_CHECK_GOTO(ret = lydict_insert(ctx->ctx, &patterns_p[u].arg.str[1], 0, &(*pattern)->expr), done);
|
||||
DUP_STRING_GOTO(ctx->ctx, patterns_p[u].eapptag, (*pattern)->eapptag, ret, done);
|
||||
DUP_STRING_GOTO(ctx->ctx, patterns_p[u].emsg, (*pattern)->emsg, ret, done);
|
||||
DUP_STRING_GOTO(ctx->ctx, patterns_p[u].dsc, (*pattern)->dsc, ret, done);
|
||||
|
@ -2582,10 +2582,10 @@ lys_compile_node_connect(struct lysc_ctx *ctx, struct lysc_node *parent, struct
|
|||
}
|
||||
} else {
|
||||
/* top-level element */
|
||||
struct lysc_node **list;
|
||||
struct lysc_node **list = NULL;
|
||||
|
||||
if (ctx->ext) {
|
||||
lyplg_ext_get_storage_p(ctx->ext, LY_STMT_DATA_NODE_MASK, (uint64_t *)&list);
|
||||
lyplg_ext_get_storage_p(ctx->ext, LY_STMT_DATA_NODE_MASK, (void ***)&list);
|
||||
} else if (node->nodetype == LYS_RPC) {
|
||||
list = (struct lysc_node **)&ctx->cur_mod->compiled->rpcs;
|
||||
} else if (node->nodetype == LYS_NOTIF) {
|
||||
|
@ -2794,7 +2794,6 @@ lys_compile_node_action_inout(struct lysc_ctx *ctx, struct lysp_node *pnode, str
|
|||
struct lysc_node_action_inout *inout = (struct lysc_node_action_inout *)node;
|
||||
|
||||
COMPILE_ARRAY_GOTO(ctx, inout_p->musts, inout->musts, lys_compile_must, ret, done);
|
||||
COMPILE_EXTS_GOTO(ctx, inout_p->exts, inout->exts, inout, ret, done);
|
||||
ctx->compile_opts |= (inout_p->nodetype == LYS_INPUT) ? LYS_COMPILE_RPC_INPUT : LYS_COMPILE_RPC_OUTPUT;
|
||||
|
||||
LY_LIST_FOR(inout_p->child, child_p) {
|
||||
|
|
|
@ -105,7 +105,7 @@ lys_identity_iffeature_value(const struct lysc_ident *ident)
|
|||
const struct lysp_ident *idents_p, *found_ident = NULL;
|
||||
struct lysp_include *includes;
|
||||
|
||||
assert(ident);
|
||||
LY_CHECK_ARG_RET(NULL, ident, ident->module->parsed, LY_EINVAL);
|
||||
|
||||
/* Search parsed identity in the module. */
|
||||
idents_p = ident->module->parsed->identities;
|
||||
|
@ -146,6 +146,8 @@ lysp_feature_next(const struct lysp_feature *last, const struct lysp_module *pmo
|
|||
{
|
||||
struct lysp_feature *features;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, pmod, NULL);
|
||||
|
||||
if (!*idx) {
|
||||
/* module features */
|
||||
features = pmod->features;
|
||||
|
|
107
src/tree_data.c
107
src/tree_data.c
|
@ -1078,7 +1078,7 @@ lyd_insert_sibling(struct lyd_node *sibling, struct lyd_node *node, struct lyd_n
|
|||
{
|
||||
struct lyd_node *first_sibling;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, node, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(NULL, node, sibling != node, LY_EINVAL);
|
||||
|
||||
if (sibling) {
|
||||
LY_CHECK_RET(lyd_insert_check_schema(NULL, sibling->schema, node->schema));
|
||||
|
@ -2148,6 +2148,11 @@ lyd_dup_r(const struct lyd_node *node, const struct ly_ctx *trg_ctx, struct lyd_
|
|||
struct lyd_node *child;
|
||||
|
||||
if (options & LYD_DUP_RECURSIVE) {
|
||||
/* create a hash table with the size of the previous hash table (duplicate) */
|
||||
if (orig->children_ht) {
|
||||
((struct lyd_node_inner *)dup)->children_ht = lyht_new(orig->children_ht->size, sizeof(struct lyd_node *), lyd_hash_table_val_equal, NULL, 1);
|
||||
}
|
||||
|
||||
/* duplicate all the children */
|
||||
LY_LIST_FOR(orig->child, child) {
|
||||
LY_CHECK_GOTO(ret = lyd_dup_r(child, trg_ctx, dup, LYD_INSERT_NODE_LAST, NULL, options, NULL), error);
|
||||
|
@ -2178,58 +2183,6 @@ error:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Duplicate a (leaf-)list and connect it into @p parent (if present) or last of @p first siblings.
|
||||
*
|
||||
* @param[in] orig Node to duplicate.
|
||||
* @param[in] trg_ctx Target context for duplicated nodes.
|
||||
* @param[in] parent Parent to insert into, NULL for top-level sibling.
|
||||
* @param[in,out] first First sibling, NULL if no top-level sibling exist yet. Can be also NULL if @p parent is set.
|
||||
* @param[in] options Bitmask of options flags, see @ref dupoptions.
|
||||
* @param[out] dup_p Pointer where the created duplicated node is placed (besides connecting it to @p parent / @p first).
|
||||
* @return LY_ERR value.
|
||||
*/
|
||||
static LY_ERR
|
||||
lyd_dup_list(const struct lyd_node **orig, const struct ly_ctx *trg_ctx, struct lyd_node *parent,
|
||||
struct lyd_node **first, uint32_t options, struct lyd_node **dup_p)
|
||||
{
|
||||
LY_ERR rc;
|
||||
struct lyd_node *start, *leader, *dup;
|
||||
const struct lysc_node *schema;
|
||||
uint32_t insert_order;
|
||||
|
||||
/* duplicate leader */
|
||||
start = (*orig)->next;
|
||||
schema = (*orig)->schema;
|
||||
rc = lyd_dup_r(*orig, trg_ctx, parent, LYD_INSERT_NODE_DEFAULT, first, options, &leader);
|
||||
LY_CHECK_RET(rc);
|
||||
|
||||
if (!start || !start->schema || !LYD_NODE_IS_ALONE(leader)) {
|
||||
/* no other instances */
|
||||
if (dup_p) {
|
||||
*dup_p = leader;
|
||||
}
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
/* duplicate the rest of the nodes in the (leaf-)list */
|
||||
insert_order = leader->next ? LYD_INSERT_NODE_LAST_BY_SCHEMA : LYD_INSERT_NODE_LAST;
|
||||
LY_LIST_FOR(start, *orig) {
|
||||
if (schema != (*orig)->schema) {
|
||||
break;
|
||||
}
|
||||
rc = lyd_dup_r(*orig, trg_ctx, parent, insert_order, first, options, &dup);
|
||||
LY_CHECK_GOTO(rc, cleanup);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (dup_p) {
|
||||
*dup_p = leader;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a parent node to connect duplicated subtree to.
|
||||
*
|
||||
|
@ -2311,12 +2264,14 @@ lyd_dup(const struct lyd_node *node, const struct ly_ctx *trg_ctx, struct lyd_no
|
|||
ly_bool nosiblings, struct lyd_node **dup_p)
|
||||
{
|
||||
LY_ERR rc;
|
||||
const struct lyd_node *orig; /* original node to be duplicated */
|
||||
struct lyd_node *first_dup = NULL; /* the first duplicated node, this is returned */
|
||||
struct lyd_node *top = NULL; /* the most higher created node */
|
||||
struct lyd_node *local_parent = NULL; /* the direct parent node for the duplicated node(s) */
|
||||
struct lyd_node *dup = NULL; /* duplicate node */
|
||||
struct lyd_node *first_sibling = NULL; /* first sibling node */
|
||||
const struct lyd_node *orig; /* original node to be duplicated */
|
||||
struct lyd_node *first_dup = NULL; /* the first duplicated node, this is returned */
|
||||
struct lyd_node *top = NULL; /* the most higher created node */
|
||||
struct lyd_node *local_parent = NULL; /* the direct parent node for the duplicated node(s) */
|
||||
struct lyd_node *dup = NULL; /* duplicate node */
|
||||
struct lyd_node *first_sibling = NULL; /* first sibling node */
|
||||
const struct lyd_node *first_llist = NULL; /* first duplicated (leaf-)list node, if any */
|
||||
uint32_t insert_order;
|
||||
|
||||
assert(node && trg_ctx);
|
||||
|
||||
|
@ -2339,19 +2294,35 @@ lyd_dup(const struct lyd_node *node, const struct ly_ctx *trg_ctx, struct lyd_no
|
|||
rc = lyd_dup_r(orig, trg_ctx, NULL, LYD_INSERT_NODE_DEFAULT, &first_sibling, options, &dup);
|
||||
LY_CHECK_GOTO(rc, error);
|
||||
}
|
||||
} else if (!nosiblings && orig->schema && (orig->schema->nodetype & (LYS_LIST | LYS_LEAFLIST))) {
|
||||
/* duplicate the whole (leaf-)list */
|
||||
rc = lyd_dup_list(&orig, trg_ctx, local_parent, &first_sibling, options, &dup);
|
||||
LY_CHECK_GOTO(rc, error);
|
||||
} else {
|
||||
rc = lyd_dup_r(orig, trg_ctx, local_parent,
|
||||
options & LYD_DUP_NO_LYDS ? LYD_INSERT_NODE_LAST_BY_SCHEMA : LYD_INSERT_NODE_DEFAULT,
|
||||
&first_sibling, options, &dup);
|
||||
/* decide insert order */
|
||||
insert_order = (options & LYD_DUP_NO_LYDS) ? LYD_INSERT_NODE_LAST_BY_SCHEMA : LYD_INSERT_NODE_DEFAULT;
|
||||
if (first_llist) {
|
||||
if (orig->schema != first_llist->schema) {
|
||||
/* all the (leaf-)list instances duplicated */
|
||||
first_llist = NULL;
|
||||
} else {
|
||||
/* duplicating all the instances of a (leaf-)list, no need to change their order */
|
||||
insert_order = LYD_INSERT_NODE_LAST;
|
||||
}
|
||||
} else if (orig->schema && (orig->schema->nodetype & (LYS_LIST | LYS_LEAFLIST))) {
|
||||
/* duplicating the first (leaf-)list instance, duplicate the rest more efficiently */
|
||||
first_llist = orig;
|
||||
}
|
||||
|
||||
/* duplicate the node */
|
||||
rc = lyd_dup_r(orig, trg_ctx, local_parent, insert_order, &first_sibling, options, &dup);
|
||||
LY_CHECK_GOTO(rc, error);
|
||||
|
||||
if (first_llist && dup->next) {
|
||||
/* orig was not the last node (because we are inserting into a parent with some previous instances),
|
||||
* we must check find the order */
|
||||
first_llist = NULL;
|
||||
}
|
||||
}
|
||||
first_dup = first_dup ? first_dup : dup;
|
||||
|
||||
if (nosiblings || !orig) {
|
||||
if (nosiblings) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3624,7 +3595,7 @@ lyd_find_path(const struct lyd_node *ctx_node, const char *path, ly_bool output,
|
|||
|
||||
cleanup:
|
||||
lyxp_expr_free(LYD_CTX(ctx_node), expr);
|
||||
ly_path_free(LYD_CTX(ctx_node), lypath);
|
||||
ly_path_free(lypath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1656,10 +1656,11 @@ ly_time_str2time(const char *value, time_t *time, char **fractions_s)
|
|||
struct tm tm = {0};
|
||||
uint32_t i, frac_len;
|
||||
const char *frac;
|
||||
char *ptr;
|
||||
int64_t shift, shift_m;
|
||||
time_t t;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, value, time, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(NULL, value, strlen(value) > 17, time, LY_EINVAL);
|
||||
|
||||
tm.tm_year = atoi(&value[0]) - 1900;
|
||||
tm.tm_mon = atoi(&value[5]) - 1;
|
||||
|
@ -1698,6 +1699,10 @@ ly_time_str2time(const char *value, time_t *time, char **fractions_s)
|
|||
++i;
|
||||
frac = &value[i];
|
||||
for (frac_len = 0; isdigit(frac[frac_len]); ++frac_len) {}
|
||||
if (!frac_len) {
|
||||
LOGERR(NULL, LY_EINVAL, "Missing date-and-time fractions after '.'.");
|
||||
return LY_EINVAL;
|
||||
}
|
||||
|
||||
i += frac_len;
|
||||
} else {
|
||||
|
@ -1709,15 +1714,20 @@ ly_time_str2time(const char *value, time_t *time, char **fractions_s)
|
|||
/* zero shift */
|
||||
shift = 0;
|
||||
} else {
|
||||
shift = strtol(&value[i], NULL, 10);
|
||||
value += i;
|
||||
shift = strtol(value, &ptr, 10);
|
||||
if (shift > 23) {
|
||||
LOGERR(NULL, LY_EINVAL, "Invalid date-and-time timezone hour \"%" PRIi64 "\".", shift);
|
||||
return LY_EINVAL;
|
||||
} else if (ptr[0] != ':') {
|
||||
LOGERR(NULL, LY_EINVAL, "Invalid date-and-time timezone hour \"%s\".", value);
|
||||
return LY_EINVAL;
|
||||
}
|
||||
shift = shift * 60 * 60; /* convert from hours to seconds */
|
||||
|
||||
shift_m = strtol(&value[i + 4], NULL, 10);
|
||||
if (shift_m > 59) {
|
||||
value = ptr + 1;
|
||||
shift_m = strtol(value, NULL, 10);
|
||||
if ((shift_m < 0) || (shift_m > 59)) {
|
||||
LOGERR(NULL, LY_EINVAL, "Invalid date-and-time timezone minutes \"%" PRIi64 "\".", shift_m);
|
||||
return LY_EINVAL;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ lyd_hash(struct lyd_node *node)
|
|||
*
|
||||
* Implementation of ::lyht_value_equal_cb.
|
||||
*/
|
||||
static ly_bool
|
||||
ly_bool
|
||||
lyd_hash_table_val_equal(void *val1_p, void *val2_p, ly_bool mod, void *UNUSED(cb_data))
|
||||
{
|
||||
struct lyd_node *val1, *val2;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#ifndef LY_TREE_DATA_INTERNAL_H_
|
||||
#define LY_TREE_DATA_INTERNAL_H_
|
||||
|
||||
#include "compat.h"
|
||||
#include "log.h"
|
||||
#include "plugins_types.h"
|
||||
#include "tree_data.h"
|
||||
|
@ -600,6 +601,13 @@ LY_ERR ly_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node,
|
|||
*/
|
||||
LY_ERR lyd_hash(struct lyd_node *node);
|
||||
|
||||
/**
|
||||
* @brief Compare callback for values in hash table.
|
||||
*
|
||||
* Implementation of ::lyht_value_equal_cb.
|
||||
*/
|
||||
ly_bool lyd_hash_table_val_equal(void *val1_p, void *val2_p, ly_bool mod, void *cb_data);
|
||||
|
||||
/**
|
||||
* @brief Insert hash of the node into the hash table of its parent.
|
||||
*
|
||||
|
|
|
@ -885,7 +885,7 @@ lyd_new_term(struct lyd_node *parent, const struct lys_module *module, const cha
|
|||
return _lyd_new_term(parent, module, name, value, value ? strlen(value) : 0, options, node);
|
||||
}
|
||||
|
||||
LIBYANG_API_DECL LY_ERR
|
||||
LIBYANG_API_DEF LY_ERR
|
||||
lyd_new_term_bin(struct lyd_node *parent, const struct lys_module *module, const char *name,
|
||||
const void *value, size_t value_len, uint32_t options, struct lyd_node **node)
|
||||
{
|
||||
|
@ -1089,6 +1089,7 @@ lyd_new_opaq(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name
|
|||
const char *prefix, const char *module_name, struct lyd_node **node)
|
||||
{
|
||||
struct lyd_node *ret = NULL;
|
||||
uint32_t hints = 0;
|
||||
|
||||
LY_CHECK_ARG_RET(ctx, parent || ctx, parent || node, name, module_name, !prefix || !strcmp(prefix, module_name), LY_EINVAL);
|
||||
LY_CHECK_CTX_EQUAL_RET(ctx, parent ? LYD_CTX(parent) : NULL, LY_EINVAL);
|
||||
|
@ -1098,10 +1099,12 @@ lyd_new_opaq(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name
|
|||
}
|
||||
if (!value) {
|
||||
value = "";
|
||||
} else if (!strcmp(value, "[null]")) {
|
||||
hints |= LYD_VALHINT_EMPTY;
|
||||
}
|
||||
|
||||
LY_CHECK_RET(lyd_create_opaq(ctx, name, strlen(name), prefix, prefix ? strlen(prefix) : 0, module_name,
|
||||
strlen(module_name), value, strlen(value), NULL, LY_VALUE_JSON, NULL, 0, &ret));
|
||||
strlen(module_name), value, strlen(value), NULL, LY_VALUE_JSON, NULL, hints, &ret));
|
||||
if (parent) {
|
||||
lyd_insert_node(parent, NULL, ret, LYD_INSERT_NODE_LAST);
|
||||
}
|
||||
|
@ -1626,6 +1629,7 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
|
|||
ly_bool store_only = (options & LYD_NEW_VAL_STORE_ONLY) ? 1 : 0;
|
||||
LY_ARRAY_COUNT_TYPE path_idx = 0, orig_count = 0;
|
||||
LY_VALUE_FORMAT format;
|
||||
uint32_t hints;
|
||||
|
||||
assert(parent || ctx);
|
||||
assert(path && ((path[0] == '/') || parent));
|
||||
|
@ -1728,9 +1732,13 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
|
|||
}
|
||||
if (r && (r != LY_EINCOMPLETE)) {
|
||||
/* creating opaque leaf-list */
|
||||
hints = LYD_NODEHINT_LEAFLIST;
|
||||
if (value && (format == LY_VALUE_JSON) && !ly_strncmp("[null]", value, value_len)) {
|
||||
hints |= LYD_VALHINT_EMPTY;
|
||||
}
|
||||
LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), NULL, 0,
|
||||
schema->module->name, strlen(schema->module->name), value, value_len, NULL, format, NULL,
|
||||
LYD_NODEHINT_LEAFLIST, &node), cleanup);
|
||||
hints, &node), cleanup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1765,8 +1773,12 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
|
|||
}
|
||||
if (r && (r != LY_EINCOMPLETE)) {
|
||||
/* creating opaque leaf */
|
||||
hints = 0;
|
||||
if (value && (format == LY_VALUE_JSON) && !ly_strncmp("[null]", value, value_len)) {
|
||||
hints |= LYD_VALHINT_EMPTY;
|
||||
}
|
||||
LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), NULL, 0,
|
||||
schema->module->name, strlen(schema->module->name), value, value_len, NULL, format, NULL, 0, &node),
|
||||
schema->module->name, strlen(schema->module->name), value, value_len, NULL, format, NULL, hints, &node),
|
||||
cleanup);
|
||||
break;
|
||||
}
|
||||
|
@ -1811,7 +1823,7 @@ cleanup:
|
|||
LY_ARRAY_INCREMENT(p);
|
||||
}
|
||||
}
|
||||
ly_path_free(ctx, p);
|
||||
ly_path_free(p);
|
||||
if (!ret) {
|
||||
/* set out params only on success */
|
||||
if (new_parent) {
|
||||
|
|
|
@ -644,7 +644,7 @@ lys_find_path_atoms(const struct ly_ctx *ctx, const struct lysc_node *ctx_node,
|
|||
ret = lys_find_lypath_atoms(p, set);
|
||||
|
||||
cleanup:
|
||||
ly_path_free(ctx, p);
|
||||
ly_path_free(p);
|
||||
lyxp_expr_free(ctx, expr);
|
||||
return ret;
|
||||
}
|
||||
|
@ -679,7 +679,7 @@ lys_find_path(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const
|
|||
snode = p[LY_ARRAY_COUNT(p) - 1].node;
|
||||
|
||||
cleanup:
|
||||
ly_path_free(ctx, p);
|
||||
ly_path_free(p);
|
||||
lyxp_expr_free(ctx, expr);
|
||||
return snode;
|
||||
}
|
||||
|
@ -1179,7 +1179,7 @@ lys_set_implemented(struct lys_module *mod, const char **features)
|
|||
LY_ERR ret = LY_SUCCESS;
|
||||
struct lys_glob_unres *unres = &mod->ctx->unres;
|
||||
|
||||
LY_CHECK_ARG_RET(NULL, mod, LY_EINVAL);
|
||||
LY_CHECK_ARG_RET(NULL, mod, mod->parsed, LY_EINVAL);
|
||||
|
||||
/* implement */
|
||||
ret = _lys_set_implemented(mod, features, unres);
|
||||
|
|
|
@ -768,7 +768,7 @@ lys_parse_localfile(struct ly_ctx *ctx, const char *name, const char *revision,
|
|||
{
|
||||
struct ly_in *in;
|
||||
char *filepath = NULL;
|
||||
LYS_INFORMAT format;
|
||||
LYS_INFORMAT format = 0;
|
||||
void *mod = NULL;
|
||||
LY_ERR ret = LY_SUCCESS;
|
||||
struct lysp_load_module_check_data check_data = {0};
|
||||
|
@ -1829,7 +1829,7 @@ lysc_node_lref_target(const struct lysc_node *node)
|
|||
|
||||
/* get the target node */
|
||||
target = p[LY_ARRAY_COUNT(p) - 1].node;
|
||||
ly_path_free(node->module->ctx, p);
|
||||
ly_path_free(p);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,8 @@ lysp_ext_instance_free(struct lysf_ctx *ctx, struct lysp_ext_instance *ext)
|
|||
LY_LIST_FOR_SAFE(ext->child, next, stmt) {
|
||||
lysp_stmt_free(ctx->ctx, stmt);
|
||||
}
|
||||
|
||||
FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1360,7 +1362,7 @@ lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext
|
|||
ly_bool node_free;
|
||||
|
||||
LY_ARRAY_FOR(substmts, u) {
|
||||
if (!substmts[u].storage) {
|
||||
if (!substmts[u].storage_p) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1383,75 +1385,75 @@ lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext
|
|||
case LY_STMT_USES: {
|
||||
struct lysp_node *child, *child_next;
|
||||
|
||||
LY_LIST_FOR_SAFE(*VOIDPTR2_C(substmts[u].storage), child_next, child) {
|
||||
LY_LIST_FOR_SAFE(*substmts[u].storage_p, child_next, child) {
|
||||
node_free = (child->nodetype & (LYS_INPUT | LYS_OUTPUT)) ? 1 : 0;
|
||||
lysp_node_free(&fctx, child);
|
||||
if (node_free) {
|
||||
free(child);
|
||||
}
|
||||
}
|
||||
*VOIDPTR2_C(substmts[u].storage) = NULL;
|
||||
*substmts[u].storage_p = NULL;
|
||||
break;
|
||||
}
|
||||
case LY_STMT_BASE:
|
||||
/* multiple strings */
|
||||
FREE_ARRAY(ctx, **(const char ***)VOIDPTR2_C(substmts[u].storage), lydict_remove);
|
||||
FREE_ARRAY(ctx, **(const char ***)substmts[u].storage_p, lydict_remove);
|
||||
break;
|
||||
|
||||
case LY_STMT_BIT:
|
||||
case LY_STMT_ENUM:
|
||||
/* single enum */
|
||||
lysp_type_enum_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
|
||||
lysp_type_enum_free(&fctx, *substmts[u].storage_p);
|
||||
break;
|
||||
|
||||
case LY_STMT_DEVIATE:
|
||||
/* single deviate */
|
||||
lysp_deviate_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
|
||||
lysp_deviate_free(&fctx, *substmts[u].storage_p);
|
||||
break;
|
||||
|
||||
case LY_STMT_DEVIATION:
|
||||
/* single deviation */
|
||||
lysp_deviation_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
|
||||
lysp_deviation_free(&fctx, *substmts[u].storage_p);
|
||||
break;
|
||||
|
||||
case LY_STMT_EXTENSION:
|
||||
/* single extension */
|
||||
lysp_ext_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
|
||||
lysp_ext_free(&fctx, *substmts[u].storage_p);
|
||||
break;
|
||||
|
||||
case LY_STMT_EXTENSION_INSTANCE:
|
||||
/* multiple extension instances */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_ext_instance **)VOIDPTR2_C(substmts[u].storage), lysp_ext_instance_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_ext_instance **)substmts[u].storage_p, lysp_ext_instance_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_FEATURE:
|
||||
/* multiple features */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_feature **)VOIDPTR2_C(substmts[u].storage), lysp_feature_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_feature **)substmts[u].storage_p, lysp_feature_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_IDENTITY:
|
||||
/* multiple identities */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_ident **)VOIDPTR2_C(substmts[u].storage), lysp_ident_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_ident **)substmts[u].storage_p, lysp_ident_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_IMPORT:
|
||||
/* multiple imports */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_import **)VOIDPTR2_C(substmts[u].storage), lysp_import_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_import **)substmts[u].storage_p, lysp_import_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_INCLUDE:
|
||||
/* multiple includes */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_include **)VOIDPTR2_C(substmts[u].storage), lysp_include_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_include **)substmts[u].storage_p, lysp_include_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_REFINE:
|
||||
/* multiple refines */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_refine **)VOIDPTR2_C(substmts[u].storage), lysp_refine_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_refine **)substmts[u].storage_p, lysp_refine_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_REVISION:
|
||||
/* multiple revisions */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_revision **)VOIDPTR2_C(substmts[u].storage), lysp_revision_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_revision **)substmts[u].storage_p, lysp_revision_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_CONFIG:
|
||||
|
@ -1485,7 +1487,7 @@ lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext
|
|||
case LY_STMT_REVISION_DATE:
|
||||
case LY_STMT_UNITS:
|
||||
/* single string */
|
||||
lydict_remove(ctx, *VOIDPTR2_C(substmts[u].storage));
|
||||
lydict_remove(ctx, *substmts[u].storage_p);
|
||||
break;
|
||||
|
||||
case LY_STMT_LENGTH:
|
||||
|
@ -1493,34 +1495,34 @@ lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext
|
|||
case LY_STMT_PATTERN:
|
||||
case LY_STMT_RANGE:
|
||||
/* multiple restrictions */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_restr **)VOIDPTR2_C(substmts[u].storage), lysp_restr_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_restr **)substmts[u].storage_p, lysp_restr_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_WHEN:
|
||||
/* multiple whens */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_when **)VOIDPTR2_C(substmts[u].storage), lysp_when_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_when **)substmts[u].storage_p, lysp_when_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_PATH:
|
||||
/* single expression */
|
||||
lyxp_expr_free(ctx, *VOIDPTR2_C(substmts[u].storage));
|
||||
lyxp_expr_free(ctx, *substmts[u].storage_p);
|
||||
break;
|
||||
|
||||
case LY_STMT_DEFAULT:
|
||||
case LY_STMT_IF_FEATURE:
|
||||
case LY_STMT_UNIQUE:
|
||||
/* multiple qnames */
|
||||
FREE_ARRAY(ctx, *(struct lysp_qname **)VOIDPTR2_C(substmts[u].storage), lysp_qname_free);
|
||||
FREE_ARRAY(ctx, *(struct lysp_qname **)substmts[u].storage_p, lysp_qname_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_TYPEDEF:
|
||||
/* multiple typedefs */
|
||||
FREE_ARRAY(&fctx, *(struct lysp_tpdf **)VOIDPTR2_C(substmts[u].storage), lysp_tpdf_free);
|
||||
FREE_ARRAY(&fctx, *(struct lysp_tpdf **)substmts[u].storage_p, lysp_tpdf_free);
|
||||
break;
|
||||
|
||||
case LY_STMT_TYPE: {
|
||||
/* single type */
|
||||
struct lysp_type **type_p = VOIDPTR_C(substmts[u].storage);
|
||||
struct lysp_type **type_p = (struct lysp_type **)substmts[u].storage_p;
|
||||
|
||||
lysp_type_free(&fctx, *type_p);
|
||||
free(*type_p);
|
||||
|
@ -1529,7 +1531,7 @@ lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext
|
|||
case LY_STMT_MODULE:
|
||||
case LY_STMT_SUBMODULE:
|
||||
/* single (sub)module */
|
||||
lysp_module_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
|
||||
lysp_module_free(&fctx, *substmts[u].storage_p);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1548,7 +1550,7 @@ lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext
|
|||
ly_bool node_free;
|
||||
|
||||
LY_ARRAY_FOR(substmts, u) {
|
||||
if (!substmts[u].storage) {
|
||||
if (!substmts[u].storage_p) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1568,14 +1570,14 @@ lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext
|
|||
case LY_STMT_LIST: {
|
||||
struct lysc_node *child, *child_next;
|
||||
|
||||
LY_LIST_FOR_SAFE(*VOIDPTR2_C(substmts[u].storage), child_next, child) {
|
||||
LY_LIST_FOR_SAFE(*substmts[u].storage_p, child_next, child) {
|
||||
node_free = (child->nodetype & (LYS_INPUT | LYS_OUTPUT)) ? 1 : 0;
|
||||
lysc_node_free_(&fctx, child);
|
||||
if (node_free) {
|
||||
free(child);
|
||||
}
|
||||
}
|
||||
*VOIDPTR2_C(substmts[u].storage) = NULL;
|
||||
*substmts[u].storage_p = NULL;
|
||||
break;
|
||||
}
|
||||
case LY_STMT_USES:
|
||||
|
@ -1605,7 +1607,7 @@ lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext
|
|||
case LY_STMT_REFERENCE:
|
||||
case LY_STMT_UNITS: {
|
||||
/* single item */
|
||||
const char *str = *VOIDPTR2_C(substmts[u].storage);
|
||||
const char *str = *substmts[u].storage_p;
|
||||
|
||||
lydict_remove(ctx, str);
|
||||
break;
|
||||
|
@ -1613,7 +1615,7 @@ lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext
|
|||
case LY_STMT_BIT:
|
||||
case LY_STMT_ENUM: {
|
||||
/* sized array */
|
||||
struct lysc_type_bitenum_item *items = *VOIDPTR2_C(substmts[u].storage);
|
||||
struct lysc_type_bitenum_item *items = *substmts[u].storage_p;
|
||||
|
||||
FREE_ARRAY(&fctx, items, lysc_enum_item_free);
|
||||
break;
|
||||
|
@ -1621,47 +1623,47 @@ lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext
|
|||
case LY_STMT_LENGTH:
|
||||
case LY_STMT_RANGE: {
|
||||
/* single item */
|
||||
struct lysc_range *range = *VOIDPTR2_C(substmts[u].storage);
|
||||
struct lysc_range *range = *substmts[u].storage_p;
|
||||
|
||||
lysc_range_free(&fctx, range);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_MUST: {
|
||||
/* sized array */
|
||||
struct lysc_must *musts = *VOIDPTR2_C(substmts[u].storage);
|
||||
struct lysc_must *musts = *substmts[u].storage_p;
|
||||
|
||||
FREE_ARRAY(&fctx, musts, lysc_must_free);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_WHEN:
|
||||
/* single item, expects a pointer */
|
||||
lysc_when_free(&fctx, VOIDPTR_C(substmts[u].storage));
|
||||
lysc_when_free(&fctx, (struct lysc_when **)substmts[u].storage_p);
|
||||
break;
|
||||
|
||||
case LY_STMT_PATTERN: {
|
||||
/* sized array of pointers */
|
||||
struct lysc_pattern **patterns = *VOIDPTR2_C(substmts[u].storage);
|
||||
struct lysc_pattern **patterns = *substmts[u].storage_p;
|
||||
|
||||
FREE_ARRAY(&fctx, patterns, lysc_pattern_free);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_TYPE: {
|
||||
/* single item */
|
||||
struct lysc_type *type = *VOIDPTR2_C(substmts[u].storage);
|
||||
struct lysc_type *type = *substmts[u].storage_p;
|
||||
|
||||
lysc_type_free(&fctx, type);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_IDENTITY: {
|
||||
/* sized array */
|
||||
struct lysc_ident *idents = *VOIDPTR2_C(substmts[u].storage);
|
||||
struct lysc_ident *idents = *substmts[u].storage_p;
|
||||
|
||||
FREE_ARRAY(&fctx, idents, lysc_ident_free);
|
||||
break;
|
||||
}
|
||||
case LY_STMT_EXTENSION_INSTANCE: {
|
||||
/* sized array */
|
||||
struct lysc_ext_instance *exts = *VOIDPTR2_C(substmts[u].storage);
|
||||
struct lysc_ext_instance *exts = *substmts[u].storage_p;
|
||||
|
||||
FREE_ARRAY(&fctx, exts, lysc_ext_instance_free);
|
||||
break;
|
||||
|
|
|
@ -726,11 +726,11 @@ uint8_t lys_stmt_flags(enum ly_stmt stmt);
|
|||
* @param[in] ext Compiled ext instance.
|
||||
* @param[in] stmt Compiled statement. Can be a mask when the first match is returned, it is expected the storage is
|
||||
* the same for all the masked statements.
|
||||
* @param[out] storage_p Pointer to a compiled ext instance substatement storage, NULL if was not compiled.
|
||||
* @param[out] storage_pp Pointer to a compiled ext instance substatement storage, NULL if was not compiled.
|
||||
* @return LY_SUCCESS on success.
|
||||
* @return LY_ENOT if the substatement is not supported.
|
||||
*/
|
||||
LY_ERR lyplg_ext_get_storage_p(const struct lysc_ext_instance *ext, int stmt, uint64_t *storage_p);
|
||||
LY_ERR lyplg_ext_get_storage_p(const struct lysc_ext_instance *ext, int stmt, void ***storage_pp);
|
||||
|
||||
/**
|
||||
* @brief Warning if the filename does not match the expected module name and version
|
||||
|
|
|
@ -197,13 +197,14 @@ lyd_validate_node_when(const struct lyd_node *tree, const struct lyd_node *node,
|
|||
* @param[in] np_cont_diff Whether to put NP container into diff or only its children.
|
||||
* @param[in,out] node Optional current iteration node, update it if it is deleted.
|
||||
* @param[in,out] node_when Optional set with nodes with "when" conditions, may be removed from.
|
||||
* @param[in,out] node_types Optional set with unresolved type nodes, may be removed from.
|
||||
* @param[in,out] diff Validation diff.
|
||||
* @return 1 if @p node auto-deleted and updated to its next sibling.
|
||||
* @return 0 if @p node was not auto-deleted.
|
||||
*/
|
||||
static ly_bool
|
||||
lyd_validate_autodel_node_del(struct lyd_node **first, struct lyd_node *del, const struct lys_module *mod,
|
||||
int np_cont_diff, struct lyd_node **node, struct ly_set *node_types, struct lyd_node **diff)
|
||||
int np_cont_diff, struct lyd_node **node, struct ly_set *node_when, struct ly_set *node_types, struct lyd_node **diff)
|
||||
{
|
||||
struct lyd_node *iter;
|
||||
ly_bool node_autodel = 0;
|
||||
|
@ -228,6 +229,16 @@ lyd_validate_autodel_node_del(struct lyd_node **first, struct lyd_node *del, con
|
|||
}
|
||||
}
|
||||
|
||||
if (node_when && node_when->count) {
|
||||
/* remove nested from node_when set */
|
||||
LYD_TREE_DFS_BEGIN(del, iter) {
|
||||
if ((del != iter) && ly_set_contains(node_when, iter, &idx)) {
|
||||
ly_set_rm_index(node_when, idx, NULL);
|
||||
}
|
||||
LYD_TREE_DFS_END(del, iter);
|
||||
}
|
||||
}
|
||||
|
||||
if (node_types && node_types->count) {
|
||||
/* remove from node_types set */
|
||||
LYD_TREE_DFS_BEGIN(del, iter) {
|
||||
|
@ -264,7 +275,7 @@ lyd_validate_unres_when(struct lyd_node **tree, const struct lys_module *mod, st
|
|||
uint32_t xpath_options, struct ly_set *node_types, struct lyd_node **diff)
|
||||
{
|
||||
LY_ERR rc = LY_SUCCESS, r;
|
||||
uint32_t i;
|
||||
uint32_t i, count;
|
||||
const struct lysc_when *disabled;
|
||||
struct lyd_node *node = NULL;
|
||||
|
||||
|
@ -285,7 +296,12 @@ lyd_validate_unres_when(struct lyd_node **tree, const struct lys_module *mod, st
|
|||
/* when false */
|
||||
if (node->flags & LYD_WHEN_TRUE) {
|
||||
/* autodelete */
|
||||
lyd_validate_autodel_node_del(tree, node, mod, 1, NULL, node_types, diff);
|
||||
count = node_when->count;
|
||||
lyd_validate_autodel_node_del(tree, node, mod, 1, NULL, node_when, node_types, diff);
|
||||
if (count > node_when->count) {
|
||||
/* nested nodes removed, we lost the index */
|
||||
ly_set_contains(node_when, node, &i);
|
||||
}
|
||||
} else if (val_opts & LYD_VALIDATE_OPERATIONAL) {
|
||||
/* only a warning */
|
||||
LOGWRN(LYD_CTX(node), "When condition \"%s\" not satisfied.", disabled->cond->expr);
|
||||
|
@ -640,7 +656,7 @@ lyd_validate_autodel_leaflist_dflt(struct lyd_node **first, struct lyd_node **no
|
|||
LYD_LIST_FOR_INST_SAFE(*first, schema, next, iter) {
|
||||
if (iter->flags & LYD_DEFAULT) {
|
||||
/* default instance found, remove it */
|
||||
if (lyd_validate_autodel_node_del(first, iter, mod, 0, node, NULL, diff)) {
|
||||
if (lyd_validate_autodel_node_del(first, iter, mod, 0, node, NULL, NULL, diff)) {
|
||||
node_autodel = 1;
|
||||
}
|
||||
}
|
||||
|
@ -685,7 +701,7 @@ lyd_validate_autodel_cont_leaf_dflt(struct lyd_node **first, struct lyd_node **n
|
|||
LYD_LIST_FOR_INST_SAFE(*first, schema, next, iter) {
|
||||
if (iter->flags & LYD_DEFAULT) {
|
||||
/* default instance, remove it */
|
||||
if (lyd_validate_autodel_node_del(first, iter, mod, 0, node, NULL, diff)) {
|
||||
if (lyd_validate_autodel_node_del(first, iter, mod, 0, node, NULL, NULL, diff)) {
|
||||
node_autodel = 1;
|
||||
}
|
||||
}
|
||||
|
@ -695,7 +711,7 @@ lyd_validate_autodel_cont_leaf_dflt(struct lyd_node **first, struct lyd_node **n
|
|||
LYD_LIST_FOR_INST(*first, schema, iter) {
|
||||
if ((iter->flags & LYD_DEFAULT) && !(iter->flags & LYD_NEW)) {
|
||||
/* old default instance, remove it */
|
||||
if (lyd_validate_autodel_node_del(first, iter, mod, 0, node, NULL, diff)) {
|
||||
if (lyd_validate_autodel_node_del(first, iter, mod, 0, node, NULL, NULL, diff)) {
|
||||
node_autodel = 1;
|
||||
}
|
||||
break;
|
||||
|
@ -753,7 +769,7 @@ lyd_validate_autodel_case_dflt(struct lyd_node **first, struct lyd_node **node,
|
|||
if (!iter) {
|
||||
/* there are only default nodes of the case meaning it does not exist and neither should any default nodes
|
||||
* of the case, remove this one default node */
|
||||
if (lyd_validate_autodel_node_del(first, *node, mod, 0, node, NULL, diff)) {
|
||||
if (lyd_validate_autodel_node_del(first, *node, mod, 0, node, NULL, NULL, diff)) {
|
||||
node_autodel = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#ifndef LY_VERSION_H_
|
||||
#define LY_VERSION_H_
|
||||
|
||||
#include "ly_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -30,22 +32,61 @@ extern "C" {
|
|||
#define LY_PROJ_VERSION_MICRO @LIBYANG_MICRO_VERSION@ /**< project micro version number */
|
||||
#define LY_PROJ_VERSION "@LIBYANG_VERSION@" /**< project version string */
|
||||
|
||||
struct ly_version {
|
||||
uint32_t major; /**< Major version number */
|
||||
uint32_t minor; /**< Minor version number */
|
||||
uint32_t micro; /**< Micro version number */
|
||||
const char *str; /**< Version string */
|
||||
};
|
||||
/**
|
||||
* @brief Get libyang major SO version.
|
||||
*
|
||||
* @return LY version.
|
||||
*/
|
||||
LIBYANG_API_DECL uint32_t ly_version_so_major(void);
|
||||
|
||||
/**
|
||||
* @brief libyang SO version.
|
||||
* @brief Get libyang minor SO version.
|
||||
*
|
||||
* @return LY version.
|
||||
*/
|
||||
LIBYANG_API_DECL extern struct ly_version ly_version_so;
|
||||
LIBYANG_API_DECL uint32_t ly_version_so_minor(void);
|
||||
|
||||
/**
|
||||
* @brief libyang project version.
|
||||
* @brief Get libyang micro SO version.
|
||||
*
|
||||
* @return LY version.
|
||||
*/
|
||||
LIBYANG_API_DECL extern struct ly_version ly_version_proj;
|
||||
LIBYANG_API_DECL uint32_t ly_version_so_micro(void);
|
||||
|
||||
/**
|
||||
* @brief Get libyang string SO version.
|
||||
*
|
||||
* @return LY version.
|
||||
*/
|
||||
LIBYANG_API_DECL const char *ly_version_so_str(void);
|
||||
|
||||
/**
|
||||
* @brief Get libyang major project version.
|
||||
*
|
||||
* @return LY version.
|
||||
*/
|
||||
LIBYANG_API_DECL uint32_t ly_version_proj_major(void);
|
||||
|
||||
/**
|
||||
* @brief Get libyang minor project version.
|
||||
*
|
||||
* @return LY version.
|
||||
*/
|
||||
LIBYANG_API_DECL uint32_t ly_version_proj_minor(void);
|
||||
|
||||
/**
|
||||
* @brief Get libyang micro project version.
|
||||
*
|
||||
* @return LY version.
|
||||
*/
|
||||
LIBYANG_API_DECL uint32_t ly_version_proj_micro(void);
|
||||
|
||||
/**
|
||||
* @brief Get libyang string project version.
|
||||
*
|
||||
* @return LY version.
|
||||
*/
|
||||
LIBYANG_API_DECL const char *ly_version_proj_str(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -330,7 +330,7 @@ print_set_debug(struct lyxp_set *set)
|
|||
(lyd_child(item->node)->schema->nodetype == LYS_LEAF)) {
|
||||
LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ELEM %s (1st child val: %s)", i + 1, item->pos,
|
||||
item->node->schema->name, lyd_get_value(lyd_child(item->node)));
|
||||
} else if ((!item->node->schema && !lyd_child(item->node)) || (item->node->schema->nodetype == LYS_LEAFLIST)) {
|
||||
} else if (lyd_get_value(item->node)) {
|
||||
LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ELEM %s (val: %s)", i + 1, item->pos,
|
||||
LYD_NAME(item->node), lyd_get_value(item->node));
|
||||
} else {
|
||||
|
@ -4042,7 +4042,7 @@ xpath_deref(struct lyxp_set **args, uint32_t UNUSED(arg_count), struct lyxp_set
|
|||
if (!r) {
|
||||
/* get the target node */
|
||||
target = p[LY_ARRAY_COUNT(p) - 1].node;
|
||||
ly_path_free(set->ctx, p);
|
||||
ly_path_free(p);
|
||||
|
||||
LY_CHECK_RET(lyxp_set_scnode_insert_node(set, target, LYXP_NODE_ELEM, LYXP_AXIS_SELF, NULL));
|
||||
} /* else the target was found before but is disabled so it was removed */
|
||||
|
@ -8272,7 +8272,9 @@ cleanup:
|
|||
options &= ~LYXP_SKIP_EXPR;
|
||||
}
|
||||
lydict_remove(set->ctx, ncname_dict);
|
||||
ly_path_predicates_free(set->ctx, predicates);
|
||||
if (predicates) {
|
||||
ly_path_predicates_free(scnode->module->ctx, predicates);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ module notifications {
|
|||
}
|
||||
}
|
||||
|
||||
/*container notification {
|
||||
container notification {
|
||||
description "internal struct to start a notification";
|
||||
config false;
|
||||
|
||||
|
@ -90,6 +90,6 @@ module notifications {
|
|||
}
|
||||
|
||||
// eventType and any data content goes here
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -580,6 +580,9 @@ test_dup_siblings_to_empty(struct test_state *state, struct timespec *ts_start,
|
|||
|
||||
TEST_END(ts_end);
|
||||
|
||||
/* need to remove the duplicated nodes if the test is repeated */
|
||||
lyd_free_siblings(lyd_child(state->data1));
|
||||
|
||||
return LY_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -831,8 +831,8 @@ check_ext_instance_priv_parsed_is_set(struct lysc_ext_instance *ext)
|
|||
LY_ARRAY_FOR(ext, u) {
|
||||
substmts = ext[u].substmts;
|
||||
LY_ARRAY_FOR(substmts, v) {
|
||||
if (substmts && substmts[v].storage && (substmts[v].stmt & LY_STMT_DATA_NODE_MASK)) {
|
||||
cnode = *(struct lysc_node **)substmts[v].storage;
|
||||
if (substmts && substmts[v].storage_p && (substmts[v].stmt & LY_STMT_DATA_NODE_MASK)) {
|
||||
cnode = *(struct lysc_node **)substmts[v].storage_p;
|
||||
iter = check;
|
||||
assert_int_equal(LY_SUCCESS, lysc_tree_dfs_full(cnode, check_node_priv_parsed_is_set, &iter));
|
||||
}
|
||||
|
@ -850,8 +850,8 @@ check_ext_instance_priv_parsed_not_set(struct lysc_ext_instance *ext)
|
|||
LY_ARRAY_FOR(ext, u) {
|
||||
substmts = ext[u].substmts;
|
||||
LY_ARRAY_FOR(substmts, v) {
|
||||
if (substmts && substmts[v].storage && (substmts[v].stmt & LY_STMT_DATA_NODE_MASK)) {
|
||||
cnode = *(struct lysc_node **)substmts[v].storage;
|
||||
if (substmts && substmts[v].storage_p && (substmts[v].stmt & LY_STMT_DATA_NODE_MASK)) {
|
||||
cnode = *(struct lysc_node **)substmts[v].storage_p;
|
||||
if (cnode) {
|
||||
CHECK_POINTER((struct lysp_node *)cnode->priv, 0);
|
||||
}
|
||||
|
|
|
@ -193,6 +193,18 @@ test_anyxml(void **state)
|
|||
free(str);
|
||||
CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
|
||||
lyd_free_all(tree);
|
||||
|
||||
data = "<anyx xmlns=\"urn:tests:a\"><x>1</x><x>0</x><x>-1</x><x>4294967295</x><x>4294967296</x><x>-2147483648</x><x>-2147483649</x></anyx>";
|
||||
CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
|
||||
assert_non_null(tree);
|
||||
tree = tree->next;
|
||||
assert_int_equal(LY_SUCCESS, lyd_print_mem(&str, tree, LYD_XML, LYD_PRINT_SHRINK));
|
||||
CHECK_STRING(str, data);
|
||||
free(str);
|
||||
assert_int_equal(LY_SUCCESS, lyd_print_mem(&str, tree, LYD_JSON, LYD_PRINT_SHRINK));
|
||||
CHECK_STRING(str, "{\"a:anyx\":{\"x\":[1,0,-1,4294967295,\"4294967296\",-2147483648,\"-2147483649\"]}}");
|
||||
free(str);
|
||||
lyd_free_all(tree);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -349,7 +361,7 @@ test_opaq(void **state)
|
|||
" <c xmld:id=\"D\">1</c>\n"
|
||||
"</a>\n",
|
||||
LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
|
||||
CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "/a", 3);
|
||||
CHECK_LOG_CTX("Unknown XML prefix \"xmld\" at attribute \"id\".", "/a", 3);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -409,7 +409,7 @@ test_target(void **state)
|
|||
assert_string_equal(lyd_get_value(term->prev), "b");
|
||||
|
||||
lyd_free_all(tree);
|
||||
ly_path_free(UTEST_LYCTX, path);
|
||||
ly_path_free(path);
|
||||
lyxp_expr_free(UTEST_LYCTX, exp);
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,57 @@ test_insert_cont_leaflist(void **state)
|
|||
lyd_free_all(cont);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dup_sort(void **state)
|
||||
{
|
||||
const char *schema;
|
||||
struct lys_module *mod;
|
||||
struct lyd_node *cont, *cont2;
|
||||
char *str;
|
||||
|
||||
schema = "module a {namespace urn:tests:a;prefix a;yang-version 1.1;revision 2014-05-08;"
|
||||
"container cn { list lst {key \"k\"; leaf k {type uint32;}}}}";
|
||||
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
|
||||
|
||||
assert_int_equal(lyd_new_inner(NULL, mod, "cn", 0, &cont), LY_SUCCESS);
|
||||
assert_int_equal(lyd_new_list(cont, NULL, "lst", 0, NULL, "2"), LY_SUCCESS);
|
||||
assert_int_equal(lyd_new_list(cont, NULL, "lst", 0, NULL, "5"), LY_SUCCESS);
|
||||
assert_int_equal(lyd_new_list(cont, NULL, "lst", 0, NULL, "9"), LY_SUCCESS);
|
||||
|
||||
assert_int_equal(lyd_new_inner(NULL, mod, "cn", 0, &cont2), LY_SUCCESS);
|
||||
assert_int_equal(lyd_new_list(cont2, NULL, "lst", 0, NULL, "1"), LY_SUCCESS);
|
||||
assert_int_equal(lyd_new_list(cont2, NULL, "lst", 0, NULL, "3"), LY_SUCCESS);
|
||||
assert_int_equal(lyd_new_list(cont2, NULL, "lst", 0, NULL, "8"), LY_SUCCESS);
|
||||
|
||||
assert_int_equal(lyd_dup_siblings(lyd_child(cont2), (struct lyd_node_inner *)cont, 0, NULL), LY_SUCCESS);
|
||||
lyd_print_mem(&str, cont, LYD_XML, 0);
|
||||
assert_string_equal(str,
|
||||
"<cn xmlns=\"urn:tests:a\">\n"
|
||||
" <lst>\n"
|
||||
" <k>1</k>\n"
|
||||
" </lst>\n"
|
||||
" <lst>\n"
|
||||
" <k>2</k>\n"
|
||||
" </lst>\n"
|
||||
" <lst>\n"
|
||||
" <k>3</k>\n"
|
||||
" </lst>\n"
|
||||
" <lst>\n"
|
||||
" <k>5</k>\n"
|
||||
" </lst>\n"
|
||||
" <lst>\n"
|
||||
" <k>8</k>\n"
|
||||
" </lst>\n"
|
||||
" <lst>\n"
|
||||
" <k>9</k>\n"
|
||||
" </lst>\n"
|
||||
"</cn>\n");
|
||||
free(str);
|
||||
|
||||
lyd_free_all(cont);
|
||||
lyd_free_all(cont2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_try_user_order_func(void **state)
|
||||
{
|
||||
|
@ -1599,6 +1650,7 @@ main(void)
|
|||
UTEST(test_insert_top_level_leaflist),
|
||||
UTEST(test_insert_cont_list),
|
||||
UTEST(test_insert_cont_leaflist),
|
||||
UTEST(test_dup_sort),
|
||||
UTEST(test_try_user_order_func),
|
||||
UTEST(test_ordered_by_user),
|
||||
UTEST(test_remove),
|
||||
|
|
|
@ -1712,7 +1712,7 @@ test_extension_compile(void **state)
|
|||
LY_ARRAY_NEW_GOTO(UTEST_LYCTX, ext_p.substmts, substmtp, rc, cleanup);
|
||||
|
||||
substmtp->stmt = LY_STMT_ERROR_MESSAGE;
|
||||
substmtp->storage = (uintptr_t)(void *)&ext_p.parsed;
|
||||
substmtp->storage_p = &ext_p.parsed;
|
||||
/* fake parse */
|
||||
lydict_insert(UTEST_LYCTX, "my error", 0, (const char **)&ext_p.parsed);
|
||||
|
||||
|
@ -1721,7 +1721,7 @@ test_extension_compile(void **state)
|
|||
LY_ARRAY_NEW_GOTO(UTEST_LYCTX, ext_c.substmts, substmt, rc, cleanup);
|
||||
|
||||
substmt->stmt = LY_STMT_ERROR_MESSAGE;
|
||||
substmt->storage = (uintptr_t)(void *)&ext_c.compiled;
|
||||
substmt->storage_p = &ext_c.compiled;
|
||||
|
||||
/*
|
||||
* error-message
|
||||
|
|
|
@ -1233,6 +1233,7 @@ test_type_instanceid(void **state)
|
|||
{
|
||||
struct lys_module *mod;
|
||||
struct lysc_type *type;
|
||||
char *str;
|
||||
|
||||
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;typedef mytype {type instance-identifier {require-instance false;}}"
|
||||
"leaf l1 {type instance-identifier {require-instance true;}}"
|
||||
|
@ -1252,12 +1253,22 @@ test_type_instanceid(void **state)
|
|||
assert_int_equal(LY_TYPE_INST, type->basetype);
|
||||
assert_int_equal(1, ((struct lysc_type_instanceid *)type)->require_instance);
|
||||
|
||||
/* default value */
|
||||
str = "module b1 {namespace urn:b1;prefix b1;"
|
||||
"leaf l1 {type string;}}";
|
||||
ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, str);
|
||||
ly_ctx_set_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED);
|
||||
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b2 {namespace urn:b2;prefix b2;"
|
||||
"import b1 {prefix b1;}"
|
||||
"leaf l1 {type instance-identifier; default \"/b1:l1\";}}", LYS_IN_YANG, NULL));
|
||||
ly_ctx_set_options(UTEST_LYCTX, 0);
|
||||
|
||||
/* invalid cases */
|
||||
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type instance-identifier {require-instance yes;}}}", LYS_IN_YANG, &mod));
|
||||
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type instance-identifier {require-instance yes;}}}", LYS_IN_YANG, NULL));
|
||||
CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, 0);
|
||||
CHECK_LOG_CTX("Invalid value \"yes\" of \"require-instance\".", NULL, 1);
|
||||
|
||||
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type instance-identifier {fraction-digits 1;}}}", LYS_IN_YANG, &mod));
|
||||
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type instance-identifier {fraction-digits 1;}}}", LYS_IN_YANG, NULL));
|
||||
CHECK_LOG_CTX("Invalid type restrictions for instance-identifier type.", "/aa:l", 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -284,8 +284,6 @@ test_arg(void **state)
|
|||
|
||||
TEST_GET_ARGUMENT_SUCCESS("hello ", YCTX, Y_STR_ARG, "hello ", 5, " ", 1);
|
||||
|
||||
TEST_GET_ARGUMENT_SUCCESS("hello/*comment*/\n", YCTX, Y_STR_ARG, "hello/*comment*/\n", 5, "\n", 1);
|
||||
|
||||
TEST_GET_ARGUMENT_SUCCESS("\"hello\\n\\t\\\"\\\\\";", YCTX, Y_STR_ARG, "hello\n\t\"\\", 9, ";", 1);
|
||||
free(buf);
|
||||
|
||||
|
|
|
@ -112,14 +112,13 @@ test_data_xml(void **state)
|
|||
TEST_SUCCESS_XML("a", "l", "2021-02-29T00:00:00-00:00", STRING, "2021-03-01T00:00:00-00:00");
|
||||
|
||||
TEST_ERROR_XML("a", "l", "2005-05-31T23:15:15.-08:00", LY_EVALID);
|
||||
CHECK_LOG_CTX("Unsatisfied pattern - \"2005-05-31T23:15:15.-08:00\" does not conform to "
|
||||
"\"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[\\+\\-]\\d{2}:\\d{2})\".",
|
||||
CHECK_LOG_CTX("Missing date-and-time fractions after '.'.",
|
||||
"/a:l", 1);
|
||||
|
||||
TEST_ERROR_XML("a", "l", "2023-16-15T20:13:01+01:00", LY_EINVAL);
|
||||
TEST_ERROR_XML("a", "l", "2023-16-15T20:13:01+01:00", LY_EVALID);
|
||||
CHECK_LOG_CTX("Invalid date-and-time month \"15\".", "/a:l", 1);
|
||||
|
||||
TEST_ERROR_XML("a", "l", "2023-10-15T20:13:01+95:00", LY_EINVAL);
|
||||
TEST_ERROR_XML("a", "l", "2023-10-15T20:13:01+95:00", LY_EVALID);
|
||||
CHECK_LOG_CTX("Invalid date-and-time timezone hour \"95\".", "/a:l", 1);
|
||||
|
||||
/* hex-string */
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
|
||||
|
||||
set mdir $::env(YANG_MODULES_DIR)
|
||||
|
||||
test debug_dict {Check debug message DICT} {
|
||||
-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body {
|
||||
ly_cmd "verb debug"
|
||||
ly_cmd "debug dict"
|
||||
ly_cmd "load modleaf" "DICT"
|
||||
}}
|
||||
|
||||
test debug_xpath {Check debug message XPATH} {
|
||||
-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body {
|
||||
ly_cmd "verb debug"
|
||||
ly_cmd "debug xpath"
|
||||
ly_cmd "load modmust" "XPATH"
|
||||
}}
|
||||
|
||||
test debug_dep_sets {Check debug message DEPSETS} {
|
||||
-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body {
|
||||
ly_cmd "verb debug"
|
||||
ly_cmd "debug dep-sets"
|
||||
ly_cmd "load modleaf" "DEPSETS"
|
||||
}}
|
||||
|
||||
test debug_depsets_xpath {Check debug message DEPSETS and XPATH} {
|
||||
-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body {
|
||||
ly_cmd "verb debug"
|
||||
ly_cmd "debug dep-sets xpath"
|
||||
ly_cmd "load modmust" "DEPSETS.*XPATH"
|
||||
}}
|
||||
|
||||
cleanupTests
|
|
@ -65,17 +65,3 @@ proc ly_exit {} {
|
|||
send "exit\r"
|
||||
expect eof
|
||||
}
|
||||
|
||||
# Check if yanglint is configured as DEBUG.
|
||||
# Return 1 on success.
|
||||
proc yanglint_debug {} {
|
||||
global TUT
|
||||
# Call non-interactive yanglint with --help.
|
||||
set output [exec -- $TUT "-h"]
|
||||
# Find option --debug.
|
||||
if { [regexp -- "--debug=GROUPS" $output] } {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ get_schema_completion(const char *hint, char ***matches, unsigned int *match_cou
|
|||
uint32_t idx;
|
||||
const char *start;
|
||||
char *end, *module_name = NULL, *path = NULL;
|
||||
const struct lysc_node *parent, *last_node;
|
||||
const struct lysc_node *parent, *last_node = NULL;
|
||||
int rc = 0;
|
||||
size_t len;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue