schema parsers CHANGE check for prefix duplicity
diff --git a/src/log.h b/src/log.h
index d1b159e..b5d6834 100644
--- a/src/log.h
+++ b/src/log.h
@@ -161,6 +161,8 @@
LYVE_SUCCESS = 0, /**< no error */
LYVE_SYNTAX, /**< generic syntax error */
LYVE_SYNTAX_YANG, /**< YANG-related syntax error */
+ LYVE_REFERENCE, /**< invalid referencing or using an item */
+ LYVE_SEMANTICS /**< generic semantic error */
} LY_VECODE;
/**
diff --git a/src/parser_yang.c b/src/parser_yang.c
index f69a3bb..b098a45 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -27,12 +27,7 @@
#include "common.h"
#include "context.h"
#include "libyang.h"
-
-struct ly_parser_ctx {
- struct ly_ctx *ctx;
- uint64_t line; /* line number */
- uint64_t indent; /* current position on the line for indentation */
-};
+#include "tree_schema_internal.h"
/* Macro to check YANG's yang-char grammar rule */
#define is_yangutf8char(c) ((c >= 0x20 && c <= 0xd77) || c == 0x09 || c == 0x0a || c == 0x0d || \
@@ -1340,7 +1335,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_import(struct ly_parser_ctx *ctx, const char **data, struct lysp_import **imports)
+parse_import(struct ly_parser_ctx *ctx, const char **data, struct lysp_module *module)
{
LY_ERR ret = 0;
char *buf, *word;
@@ -1348,7 +1343,7 @@
enum yang_keyword kw;
struct lysp_import *imp;
- LYSP_ARRAY_NEW_RET(ctx, imports, imp, LY_EVALID);
+ LYSP_ARRAY_NEW_RET(ctx, &module->imports, imp, LY_EVALID);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -1361,6 +1356,7 @@
switch (kw) {
case YANG_PREFIX:
ret = parse_text_field(ctx, data, LYEXT_SUBSTMT_PREFIX, 0, &imp->prefix, Y_IDENTIF_ARG, &imp->exts);
+ LY_CHECK_RET(lysp_check_prefix(ctx, module, &imp->prefix), LY_EVALID);
break;
case YANG_DESCRIPTION:
ret = parse_text_field(ctx, data, LYEXT_SUBSTMT_DESCRIPTION, 0, &imp->dsc, Y_STR_ARG, &imp->exts);
@@ -4507,6 +4503,7 @@
break;
case YANG_PREFIX:
ret = parse_text_field(ctx, data, LYEXT_SUBSTMT_PREFIX, 0, &mod->prefix, Y_IDENTIF_ARG, &mod->exts);
+ LY_CHECK_RET(lysp_check_prefix(ctx, mod, &mod->prefix), LY_EVALID);
break;
case YANG_BELONGS_TO:
ret = parse_belongsto(ctx, data, &mod->belongsto, &mod->prefix, &mod->exts);
@@ -4517,7 +4514,7 @@
ret = parse_include(ctx, data, &mod->includes);
break;
case YANG_IMPORT:
- ret = parse_import(ctx, data, &mod->imports);
+ ret = parse_import(ctx, data, mod);
break;
/* meta */
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 489e965..1df393f 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -14,6 +14,7 @@
#include "libyang.h"
#include "common.h"
+#include "tree_schema_internal.h"
#define FREE_ARRAY(CTX, ARRAY, ITER, FUNC) LY_ARRAY_FOR(ARRAY, ITER){FUNC(CTX, &ARRAY[ITER]);}free(ARRAY);
#define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER);free(MEMBER);}
@@ -486,3 +487,25 @@
free(module);
}
+
+LY_ERR
+lysp_check_prefix(struct ly_parser_ctx *ctx, struct lysp_module *module, const char **value)
+{
+ unsigned int u;
+
+ if (module->prefix && &module->prefix != value && !strcmp(module->prefix, *value)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE,
+ "Prefix \"%s\" already used as module prefix.", *value);
+ return LY_EEXIST;
+ }
+ if (module->imports) {
+ LY_ARRAY_FOR(module->imports, u) {
+ if (module->imports[u].prefix && &module->imports[u].prefix != value && !strcmp(module->imports[u].prefix, *value)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE,
+ "Prefix \"%s\" already used to import \"%s\" module.", *value, module->imports[u].name);
+ return LY_EEXIST;
+ }
+ }
+ }
+ return LY_SUCCESS;
+}
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 6266427..ffd188a 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -17,6 +17,10 @@
#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* @defgroup schematree Schema Tree
* @{
@@ -745,4 +749,8 @@
/** @} */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* LY_TREE_SCHEMA_H_ */
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
new file mode 100644
index 0000000..dda9593
--- /dev/null
+++ b/src/tree_schema_internal.h
@@ -0,0 +1,37 @@
+/**
+ * @file tree_schema_internal.h
+ * @author Radek Krejci <rkrejci@cesnet.cz>
+ * @brief internal functions for YANG schema trees.
+ *
+ * Copyright (c) 2015 - 2018 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
+ */
+
+#ifndef LY_TREE_SCHEMA_INTERNAL_H_
+#define LY_TREE_SCHEMA_INTERNAL_H_
+
+/**
+ * @brief internal context for schema parsers
+ */
+struct ly_parser_ctx {
+ struct ly_ctx *ctx;
+ uint64_t line; /* line number */
+ uint64_t indent; /* current position on the line for YANG indentation */
+};
+
+/**
+ * @brief Check the currently present prefixes in the module for collision with the new one.
+ *
+ * @param[in] ctx yang parser context.
+ * @param[in] module Schema tree to check.
+ * @param[in] value Newly added prefix value (including its location to distinguish collision with itself).
+ * @return LY_EEXIST when prefix is already used in the module, LY_SUCCESS otherwise
+ */
+LY_ERR lysp_check_prefix(struct ly_parser_ctx *ctx, struct lysp_module *module, const char **value);
+
+#endif /* LY_TREE_SCHEMA_INTERNAL_H_ */