structure FEATURE support for ietf-yang-structure-ext
Only for the structure itself, no augment yet.
diff --git a/src/tree_schema_common.c b/src/tree_schema_common.c
index 2dc47c8..fe7b741 100644
--- a/src/tree_schema_common.c
+++ b/src/tree_schema_common.c
@@ -125,39 +125,36 @@
}
}
-static const struct lysp_tpdf *
-lysp_type_match(const char *name, struct lysp_node *node)
+LY_ERR
+lysp_check_enum_name(struct lys_parser_ctx *ctx, const char *name, size_t name_len)
{
- const struct lysp_tpdf *typedefs;
- LY_ARRAY_COUNT_TYPE u;
-
- typedefs = lysp_node_typedefs(node);
- LY_ARRAY_FOR(typedefs, u) {
- if (!strcmp(name, typedefs[u].name)) {
- /* match */
- return &typedefs[u];
+ if (!name_len) {
+ LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Enum name must not be zero-length.");
+ return LY_EVALID;
+ } else if (isspace(name[0]) || isspace(name[name_len - 1])) {
+ LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Enum name must not have any leading or trailing whitespaces (\"%.*s\").",
+ (int)name_len, name);
+ return LY_EVALID;
+ } else {
+ for (size_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);
+ break;
+ }
}
}
- return NULL;
+ return LY_SUCCESS;
}
-static const struct lysp_node_grp *
-lysp_grouping_match(const char *name, struct lysp_node *node)
-{
- const struct lysp_node_grp *groupings, *grp_iter;
-
- groupings = lysp_node_groupings(node);
- LY_LIST_FOR(groupings, grp_iter) {
- if (!strcmp(name, grp_iter->name)) {
- /* match */
- return grp_iter;
- }
- }
-
- return NULL;
-}
-
+/**
+ * @brief Learn built-in type from its name.
+ *
+ * @param[in] name Type name.
+ * @param[in] len Length of @p name.
+ * @return Built-in data type, ::LY_TYPE_UNKNOWN if none matches.
+ */
static LY_DATA_TYPE
lysp_type_str2builtin(const char *name, size_t len)
{
@@ -232,12 +229,34 @@
return LY_TYPE_UNKNOWN;
}
+/**
+ * @brief Find a typedef in a sized array.
+ *
+ * @param[in] name Typedef name.
+ * @param[in] typedefs Sized array of typedefs.
+ * @return Found typedef, NULL if none.
+ */
+static const struct lysp_tpdf *
+lysp_typedef_match(const char *name, const struct lysp_tpdf *typedefs)
+{
+ LY_ARRAY_COUNT_TYPE u;
+
+ LY_ARRAY_FOR(typedefs, u) {
+ if (!strcmp(name, typedefs[u].name)) {
+ /* match */
+ return &typedefs[u];
+ }
+ }
+ return NULL;
+}
+
LY_ERR
lysp_type_find(const char *id, struct lysp_node *start_node, const struct lysp_module *start_module,
- LY_DATA_TYPE *type, const struct lysp_tpdf **tpdf, struct lysp_node **node)
+ const struct lysc_ext_instance *ext, LY_DATA_TYPE *type, const struct lysp_tpdf **tpdf, struct lysp_node **node)
{
const char *str, *name;
struct lysp_tpdf *typedefs;
+ const struct lysp_tpdf **ext_typedefs;
const struct lys_module *mod;
const struct lysp_module *local_module;
LY_ARRAY_COUNT_TYPE u, v;
@@ -267,16 +286,25 @@
}
LY_CHECK_RET(!local_module, LY_ENOTFOUND);
- if (start_node && (local_module == start_module)) {
- /* search typedefs in parent's nodes */
- *node = start_node;
- while (*node) {
- *tpdf = lysp_type_match(name, *node);
- if (*tpdf) {
+ if (local_module == start_module) {
+ if (start_node) {
+ /* search typedefs in parent's nodes */
+ for (*node = start_node; *node; *node = (*node)->parent) {
+ *tpdf = lysp_typedef_match(name, lysp_node_typedefs(*node));
+ if (*tpdf) {
+ /* match */
+ return LY_SUCCESS;
+ }
+ }
+ }
+
+ if (ext) {
+ /* search typedefs directly in the extension */
+ ext_typedefs = (void *)lys_compile_ext_instance_get_storage(ext, LY_STMT_TYPEDEF);
+ if (ext_typedefs && (*tpdf = lysp_typedef_match(name, *ext_typedefs))) {
/* match */
return LY_SUCCESS;
}
- *node = (*node)->parent;
}
}
@@ -309,29 +337,6 @@
return LY_ENOTFOUND;
}
-LY_ERR
-lysp_check_enum_name(struct lys_parser_ctx *ctx, const char *name, size_t name_len)
-{
- if (!name_len) {
- LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Enum name must not be zero-length.");
- return LY_EVALID;
- } else if (isspace(name[0]) || isspace(name[name_len - 1])) {
- LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Enum name must not have any leading or trailing whitespaces (\"%.*s\").",
- (int)name_len, name);
- return LY_EVALID;
- } else {
- for (size_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);
- break;
- }
- }
- }
-
- return LY_SUCCESS;
-}
-
/**
* @brief Insert @p name to hash table and if @p name has already
* been added, then log an error.
@@ -415,7 +420,7 @@
}
/* search typedefs in parent's nodes */
for (parent = node->parent; parent; parent = parent->parent) {
- if (lysp_type_match(name, parent)) {
+ if (lysp_typedef_match(name, lysp_node_typedefs(parent))) {
LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG,
"Duplicate identifier \"%s\" of typedef statement - name collision with another scoped type.", name);
return LY_EVALID;
@@ -491,6 +496,22 @@
return ret;
}
+static const struct lysp_node_grp *
+lysp_grouping_match(const char *name, struct lysp_node *node)
+{
+ const struct lysp_node_grp *groupings, *grp_iter;
+
+ groupings = lysp_node_groupings(node);
+ LY_LIST_FOR(groupings, grp_iter) {
+ if (!strcmp(name, grp_iter->name)) {
+ /* match */
+ return grp_iter;
+ }
+ }
+
+ return NULL;
+}
+
/**
* @brief Check name of a new grouping to avoid name collisions.
*
@@ -1838,17 +1859,6 @@
}
}
-struct lys_module *
-lysp_find_module(struct ly_ctx *ctx, const struct lysp_module *mod)
-{
- for (uint32_t u = 0; u < ctx->list.count; ++u) {
- if (((struct lys_module *)ctx->list.objs[u])->parsed == mod) {
- return (struct lys_module *)ctx->list.objs[u];
- }
- }
- return NULL;
-}
-
enum ly_stmt
lysp_match_kw(struct ly_in *in, uint64_t *indent)
{