summaryrefslogtreecommitdiffstats
path: root/src/tree_schema_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tree_schema_common.c')
-rw-r--r--src/tree_schema_common.c158
1 files changed, 101 insertions, 57 deletions
diff --git a/src/tree_schema_common.c b/src/tree_schema_common.c
index bbdd676..6d3b710 100644
--- a/src/tree_schema_common.c
+++ b/src/tree_schema_common.c
@@ -32,6 +32,7 @@
#include "in_internal.h"
#include "log.h"
#include "parser_schema.h"
+#include "path.h"
#include "schema_compile.h"
#include "schema_features.h"
#include "set.h"
@@ -104,7 +105,7 @@ lysp_check_date(struct lysp_ctx *ctx, const char *date, size_t date_len, const c
error:
if (stmt) {
- LOGVAL_PARSER(ctx, LY_VCODE_INVAL, date_len, date, stmt);
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, (int)date_len, date, stmt);
}
return LY_EINVAL;
}
@@ -140,10 +141,10 @@ lysp_check_enum_name(struct lysp_ctx *ctx, const char *name, size_t name_len)
(int)name_len, name);
return LY_EVALID;
} else {
- for (size_t u = 0; u < name_len; ++u) {
+ for (uint32_t u = 0; u < name_len; ++u) {
if (iscntrl(name[u])) {
- LOGWRN(PARSER_CTX(ctx), "Control characters in enum name should be avoided (\"%.*s\", character number %d).",
- (int)name_len, name, u + 1);
+ LOGWRN(PARSER_CTX(ctx), "Control characters in enum name should be avoided "
+ "(\"%.*s\", character number %" PRIu32 ").", (int)name_len, name, u + 1);
break;
}
}
@@ -350,19 +351,18 @@ lysp_type_find(const char *id, struct lysp_node *start_node, const struct lysp_m
* @param[in,out] ctx Context to log the error.
* @param[in,out] ht Hash table with top-level names.
* @param[in] name Inserted top-level identifier.
- * @param[in] statement The name of the statement type from which
- * @p name originated (eg typedef, feature, ...).
+ * @param[in] statement The name of the statement type from which @p name originated (eg typedef, feature, ...).
* @param[in] err_detail Optional error specification.
* @return LY_ERR, but LY_EEXIST is mapped to LY_EVALID.
*/
static LY_ERR
-lysp_check_dup_ht_insert(struct lysp_ctx *ctx, struct hash_table *ht,
- const char *name, const char *statement, const char *err_detail)
+lysp_check_dup_ht_insert(struct lysp_ctx *ctx, struct ly_ht *ht, const char *name, const char *statement,
+ const char *err_detail)
{
LY_ERR ret;
uint32_t hash;
- hash = dict_hash(name, strlen(name));
+ hash = lyht_hash(name, strlen(name));
ret = lyht_insert(ht, &name, hash, NULL);
if (ret == LY_EEXIST) {
if (err_detail) {
@@ -388,7 +388,7 @@ lysp_check_dup_ht_insert(struct lysp_ctx *ctx, struct hash_table *ht,
*/
static LY_ERR
lysp_check_dup_typedef(struct lysp_ctx *ctx, struct lysp_node *node, const struct lysp_tpdf *tpdf,
- struct hash_table *tpdfs_global)
+ struct ly_ht *tpdfs_global)
{
struct lysp_node *parent;
uint32_t hash;
@@ -434,7 +434,7 @@ lysp_check_dup_typedef(struct lysp_ctx *ctx, struct lysp_node *node, const struc
/* check collision with the top-level typedefs */
if (node) {
- hash = dict_hash(name, name_len);
+ hash = lyht_hash(name, name_len);
if (!lyht_find(tpdfs_global, &name, hash, NULL)) {
LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG,
"Duplicate identifier \"%s\" of typedef statement - scoped type collide with a top-level type.", name);
@@ -469,7 +469,7 @@ lysp_id_cmp(void *val1, void *val2, ly_bool UNUSED(mod), void *UNUSED(cb_data))
LY_ERR
lysp_check_dup_typedefs(struct lysp_ctx *ctx, struct lysp_module *mod)
{
- struct hash_table *ids_global;
+ struct ly_ht *ids_global;
const struct lysp_tpdf *typedefs;
LY_ARRAY_COUNT_TYPE u, v;
uint32_t i;
@@ -496,7 +496,7 @@ lysp_check_dup_typedefs(struct lysp_ctx *ctx, struct lysp_module *mod)
}
cleanup:
- lyht_free(ids_global);
+ lyht_free(ids_global, NULL);
return ret;
}
@@ -528,7 +528,7 @@ lysp_grouping_match(const char *name, struct lysp_node *node)
*/
static LY_ERR
lysp_check_dup_grouping(struct lysp_ctx *ctx, struct lysp_node *node, const struct lysp_node_grp *grp,
- struct hash_table *grps_global)
+ struct ly_ht *grps_global)
{
struct lysp_node *parent;
uint32_t hash;
@@ -567,7 +567,7 @@ lysp_check_dup_grouping(struct lysp_ctx *ctx, struct lysp_node *node, const stru
/* check collision with the top-level groupings */
if (node) {
- hash = dict_hash(name, name_len);
+ hash = lyht_hash(name, name_len);
if (!lyht_find(grps_global, &name, hash, NULL)) {
LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG,
"Duplicate identifier \"%s\" of grouping statement - scoped grouping collide with a top-level grouping.", name);
@@ -584,7 +584,7 @@ lysp_check_dup_grouping(struct lysp_ctx *ctx, struct lysp_node *node, const stru
LY_ERR
lysp_check_dup_groupings(struct lysp_ctx *ctx, struct lysp_module *mod)
{
- struct hash_table *ids_global;
+ struct ly_ht *ids_global;
const struct lysp_node_grp *groupings, *grp_iter;
LY_ARRAY_COUNT_TYPE u;
uint32_t i;
@@ -610,7 +610,7 @@ lysp_check_dup_groupings(struct lysp_ctx *ctx, struct lysp_module *mod)
}
cleanup:
- lyht_free(ids_global);
+ lyht_free(ids_global, NULL);
return ret;
}
@@ -626,7 +626,7 @@ LY_ERR
lysp_check_dup_features(struct lysp_ctx *ctx, struct lysp_module *mod)
{
LY_ARRAY_COUNT_TYPE u;
- struct hash_table *ht;
+ struct ly_ht *ht;
struct lysp_feature *f;
LY_ERR ret = LY_SUCCESS;
@@ -650,7 +650,7 @@ lysp_check_dup_features(struct lysp_ctx *ctx, struct lysp_module *mod)
}
cleanup:
- lyht_free(ht);
+ lyht_free(ht, NULL);
return ret;
}
@@ -658,7 +658,7 @@ LY_ERR
lysp_check_dup_identities(struct lysp_ctx *ctx, struct lysp_module *mod)
{
LY_ARRAY_COUNT_TYPE u;
- struct hash_table *ht;
+ struct ly_ht *ht;
struct lysp_ident *i;
LY_ERR ret = LY_SUCCESS;
@@ -682,7 +682,7 @@ lysp_check_dup_identities(struct lysp_ctx *ctx, struct lysp_module *mod)
}
cleanup:
- lyht_free(ht);
+ lyht_free(ht, NULL);
return ret;
}
@@ -697,9 +697,8 @@ static LY_ERR
lysp_load_module_check(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data)
{
struct lysp_load_module_check_data *info = data;
- const char *filename, *dot, *rev, *name;
+ const char *name;
uint8_t latest_revision;
- size_t len;
struct lysp_revision *revs;
name = mod ? mod->mod->name : submod->name;
@@ -740,29 +739,7 @@ lysp_load_module_check(const struct ly_ctx *ctx, struct lysp_module *mod, struct
}
}
if (info->path) {
- /* check that name and revision match filename */
- filename = strrchr(info->path, '/');
- if (!filename) {
- filename = info->path;
- } else {
- filename++;
- }
- /* name */
- len = strlen(name);
- rev = strchr(filename, '@');
- dot = strrchr(info->path, '.');
- if (strncmp(filename, name, len) ||
- ((rev && (rev != &filename[len])) || (!rev && (dot != &filename[len])))) {
- LOGWRN(ctx, "File name \"%s\" does not match module name \"%s\".", filename, name);
- }
- /* revision */
- if (rev) {
- len = dot - ++rev;
- if (!revs || (len != LY_REV_SIZE - 1) || strncmp(revs[0].date, rev, len)) {
- LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", filename,
- revs ? revs[0].date : "none");
- }
- }
+ ly_check_module_filename(ctx, name, revs ? revs[0].date : NULL, info->path);
}
return LY_SUCCESS;
}
@@ -921,7 +898,7 @@ lys_get_module_without_revision(struct ly_ctx *ctx, const char *name)
struct lys_module *mod, *mod_impl;
uint32_t index;
- /* Try to find module with LYS_MOD_IMPORTED_REV flag. */
+ /* try to find module with LYS_MOD_IMPORTED_REV flag */
index = 0;
while ((mod = ly_ctx_get_module_iter(ctx, &index))) {
if (!strcmp(mod->name, name) && (mod->latest_revision & LYS_MOD_IMPORTED_REV)) {
@@ -929,17 +906,19 @@ lys_get_module_without_revision(struct ly_ctx *ctx, const char *name)
}
}
- /* Try to find the implemented module. */
+ /* try to find the implemented module */
mod_impl = ly_ctx_get_module_implemented(ctx, name);
- if (mod && mod_impl) {
- LOGVRB("Implemented module \"%s@%s\" is not used for import, revision \"%s\" is imported instead.",
- mod_impl->name, mod_impl->revision, mod->revision);
+ if (mod) {
+ if (mod_impl && (mod != mod_impl)) {
+ LOGVRB("Implemented module \"%s@%s\" is not used for import, revision \"%s\" is imported instead.",
+ mod_impl->name, mod_impl->revision, mod->revision);
+ }
return mod;
} else if (mod_impl) {
return mod_impl;
}
- /* Try to find the latest module in the current context. */
+ /* try to find the latest module in the current context */
mod = ly_ctx_get_module_latest(ctx, name);
return mod;
@@ -949,10 +928,8 @@ lys_get_module_without_revision(struct ly_ctx *ctx, const char *name)
* @brief Check if a circular dependency exists between modules.
*
* @param[in] ctx libyang context for log an error.
- * @param[in,out] mod Examined module which is set to NULL
- * if the circular dependency is detected.
- * @return LY_SUCCESS if no circular dependecy is detected,
- * otherwise LY_EVALID.
+ * @param[in,out] mod Examined module which is set to NULL if the circular dependency is detected.
+ * @return LY_SUCCESS if no circular dependecy is detected, otherwise LY_EVALID.
*/
static LY_ERR
lys_check_circular_dependency(struct ly_ctx *ctx, struct lys_module **mod)
@@ -1184,7 +1161,6 @@ lysp_inject_submodule(struct lysp_ctx *pctx, struct lysp_include *inc)
DUP_STRING_RET(PARSER_CTX(pctx), inc->name, inc_new->name);
DUP_STRING_RET(PARSER_CTX(pctx), inc->dsc, inc_new->dsc);
DUP_STRING_RET(PARSER_CTX(pctx), inc->ref, inc_new->ref);
- /* TODO duplicate extensions */
memcpy(inc_new->rev, inc->rev, LY_REV_SIZE);
inc_new->injected = 1;
}
@@ -1826,6 +1802,36 @@ lysc_node_when(const struct lysc_node *node)
}
}
+LIBYANG_API_DEF const struct lysc_node *
+lysc_node_lref_target(const struct lysc_node *node)
+{
+ struct lysc_type_leafref *lref;
+ struct ly_path *p;
+ const struct lysc_node *target;
+
+ if (!node || !(node->nodetype & LYD_NODE_TERM)) {
+ return NULL;
+ }
+
+ lref = (struct lysc_type_leafref *)((struct lysc_node_leaf *)node)->type;
+ if (lref->basetype != LY_TYPE_LEAFREF) {
+ return NULL;
+ }
+
+ /* compile the path */
+ if (ly_path_compile_leafref(node->module->ctx, node, NULL, lref->path,
+ (node->flags & LYS_IS_OUTPUT) ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_MANY,
+ LY_VALUE_SCHEMA_RESOLVED, lref->prefixes, &p)) {
+ return NULL;
+ }
+
+ /* get the target node */
+ target = p[LY_ARRAY_COUNT(p) - 1].node;
+ ly_path_free(node->module->ctx, p);
+
+ return target;
+}
+
enum ly_stmt
lysp_match_kw(struct ly_in *in, uint64_t *indent)
{
@@ -2615,3 +2621,41 @@ lys_stmt_flags(enum ly_stmt stmt)
return 0;
}
+
+void
+ly_check_module_filename(const struct ly_ctx *ctx, const char *name, const char *revision, const char *filename)
+{
+ const char *basename, *rev, *dot;
+ size_t len;
+
+ /* check that name and revision match filename */
+ basename = strrchr(filename, '/');
+#ifdef _WIN32
+ const char *backslash = strrchr(filename, '\\');
+
+ if (!basename || (basename && backslash && (backslash > basename))) {
+ basename = backslash;
+ }
+#endif
+ if (!basename) {
+ basename = filename;
+ } else {
+ basename++; /* leading slash */
+ }
+ rev = strchr(basename, '@');
+ dot = strrchr(basename, '.');
+
+ /* name */
+ len = strlen(name);
+ if (strncmp(basename, name, len) ||
+ ((rev && (rev != &basename[len])) || (!rev && (dot != &basename[len])))) {
+ LOGWRN(ctx, "File name \"%s\" does not match module name \"%s\".", basename, name);
+ }
+ if (rev) {
+ len = dot - ++rev;
+ if (!revision || (len != LY_REV_SIZE - 1) || strncmp(revision, rev, len)) {
+ LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", basename,
+ revision ? revision : "none");
+ }
+ }
+}