diff options
Diffstat (limited to 'src/tree_schema_common.c')
-rw-r--r-- | src/tree_schema_common.c | 158 |
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"); + } + } +} |