schema mount NEW initial schema mount code
diff --git a/src/context.c b/src/context.c
index 7602409..3d79958 100644
--- a/src/context.c
+++ b/src/context.c
@@ -51,6 +51,7 @@
#include "../models/ietf-inet-types@2013-07-15.h"
#include "../models/ietf-yang-library@2019-01-04.h"
#include "../models/ietf-yang-metadata@2016-08-05.h"
+#include "../models/ietf-yang-schema-mount@2019-01-14.h"
#include "../models/ietf-yang-types@2013-07-15.h"
#include "../models/yang@2021-04-07.h"
#define IETF_YANG_LIB_REV "2019-01-04"
@@ -66,6 +67,7 @@
{"yang", "2021-04-07", (const char *)yang_2021_04_07_yang, 1, LYS_IN_YANG},
{"ietf-inet-types", "2013-07-15", (const char *)ietf_inet_types_2013_07_15_yang, 0, LYS_IN_YANG},
{"ietf-yang-types", "2013-07-15", (const char *)ietf_yang_types_2013_07_15_yang, 0, LYS_IN_YANG},
+ {"ietf-yang-schema-mount", "2019-01-14", (const char *)ietf_yang_schema_mount_2019_01_14_yang, 1, LYS_IN_YANG},
/* ietf-datastores and ietf-yang-library must be right here at the end of the list! */
{"ietf-datastores", "2018-02-14", (const char *)ietf_datastores_2018_02_14_yang, 1, LYS_IN_YANG},
{"ietf-yang-library", IETF_YANG_LIB_REV, (const char *)ietf_yang_library_2019_01_04_yang, 1, LYS_IN_YANG}
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 276ccc1..fcfc8f9 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -24,6 +24,7 @@
#include "log.h"
#include "parser_data.h"
#include "parser_internal.h"
+#include "plugins_exts.h"
#include "set.h"
#include "tree.h"
#include "tree_data.h"
@@ -418,7 +419,10 @@
static LY_ERR
lydxml_subtree_r(struct lyd_xml_ctx *lydctx, struct lyd_node *parent, struct lyd_node **first_p, struct ly_set *parsed)
{
- LY_ERR ret = LY_SUCCESS;
+ LY_ERR ret = LY_SUCCESS, r;
+ LY_ARRAY_COUNT_TYPE u;
+
+ lyplg_ext_data_parse_clb ext_parse;
const char *prefix, *name, *val;
size_t prefix_len, name_len;
struct lyxml_ctx *xmlctx;
@@ -431,6 +435,7 @@
uint32_t prev_parse_opts, prev_int_opts;
struct lyd_node *node = NULL, *anchor;
void *val_prefix_data = NULL;
+ struct lysc_ext_instance *exts = NULL;
LY_VALUE_FORMAT format;
uint32_t getnext_opts;
@@ -481,6 +486,22 @@
snode = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
}
if (!snode) {
+ /* Check if data of an extension */
+ if (parent && parent->schema) {
+ exts = parent->schema->exts;
+ }
+ LY_ARRAY_FOR(exts, u) {
+ ext_parse = exts[u].def->plugin->parse;
+ r = ext_parse(xmlctx->in, LYD_XML, &exts[u], parent, lydctx->parse_opts,
+ lydctx->val_opts);
+ if (r == LY_SUCCESS) {
+ /* Data was from this module*/
+ return LY_SUCCESS;
+ } else if (r != LY_ENOT) {
+ /* Error while parsing */
+ }
+ /* Data was not from this module */
+ }
if (lydctx->parse_opts & LYD_PARSE_STRICT) {
if (parent) {
LOGVAL(ctx, LYVE_REFERENCE, "Node \"%.*s\" not found as a child of \"%s\" node.",
diff --git a/src/plugins.c b/src/plugins.c
index 2ea509b..67c072e 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -78,6 +78,7 @@
extern struct lyplg_ext_record plugins_metadata[];
extern struct lyplg_ext_record plugins_nacm[];
extern struct lyplg_ext_record plugins_yangdata[];
+extern struct lyplg_ext_record plugins_schema_mount[];
static pthread_mutex_t plugins_guard = PTHREAD_MUTEX_INITIALIZER;
@@ -458,6 +459,7 @@
LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_metadata), error);
LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_nacm), error);
LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_yangdata), error);
+ LY_CHECK_GOTO(ret = plugins_insert(LYPLG_EXTENSION, plugins_schema_mount), error);
#ifndef STATIC
/* external types */
diff --git a/src/plugins_exts.c b/src/plugins_exts.c
index 90fc70a..6558f3a 100644
--- a/src/plugins_exts.c
+++ b/src/plugins_exts.c
@@ -18,11 +18,6 @@
#include <stdint.h>
-extern struct lyplg_ext metadata_plugin; /* plugins_exts_metadata.c */
-extern struct lyplg_ext nacm_plugin; /* plugins_exts_nacm.c */
-extern struct lyplg_ext yangdata_plugin; /* plugins_exts_yangdata.c */
-
-/* internal libyang headers - do not make them accessible to the extension plugins in plugins_exts_*.c */
#include "common.h"
#include "printer_internal.h"
#include "schema_compile.h"
@@ -62,3 +57,15 @@
{
return &((struct lyspr_ctx *)ctx)->level;
}
+
+API const struct lys_module *
+lysc_ctx_get_cur_mod(const struct lysc_ctx *ctx)
+{
+ return ctx->cur_mod;
+}
+
+API struct lysp_module *
+lysc_ctx_get_pmod(const struct lysc_ctx *ctx)
+{
+ return ctx->pmod;
+}
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index 2a4594f..d856420 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -17,6 +17,7 @@
#include "log.h"
#include "plugins.h"
+#include "tree_data.h"
#include "tree_edit.h"
#include "tree_schema.h"
@@ -24,6 +25,7 @@
#include "plugins_exts_print.h"
struct ly_ctx;
+struct ly_in;
struct lyd_node;
struct lysc_ext_substmt;
struct lysp_ext_instance;
@@ -171,14 +173,31 @@
typedef LY_ERR (*lyplg_ext_schema_printer_clb)(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag);
/**
+ * @brief Callback to data according to extension specification.
+ *
+ * @param[in] in
+ * @param[in] format
+ * @param[in] ext
+ * @param[in] parent
+ * @param[in] parse_opts
+ * @param[in] val_opts
+ * @param[out] ly_err
+ */
+typedef LY_ERR (*lyplg_ext_data_parse_clb)(struct ly_in *in, LYD_FORMAT format,
+ struct lysc_ext_instance *ext, struct lyd_node *parent,
+ uint32_t parse_opts, uint32_t val_opts);
+
+/**
* @brief Extension plugin implementing various aspects of a YANG extension
*/
struct lyplg_ext {
const char *id; /**< Plugin identification (mainly for distinguish incompatible versions of the plugins for external tools) */
lyplg_ext_compile_clb compile; /**< Callback to compile extension instance from the parsed data */
- lyplg_ext_data_validation_clb validate; /**< Callback to decide if data instance is valid according to the schema. */
lyplg_ext_schema_printer_clb sprinter; /**< Callback to print the compiled content (info format) of the extension instance */
lyplg_ext_free_clb free; /**< Free the extension instance specific data created by ::lyplg_ext.compile callback */
+
+ lyplg_ext_data_parse_clb parse; /**< Callback to parse data instance according to the extension definition. */
+ lyplg_ext_data_validation_clb validate; /**< Callback to decide if data instance is valid according to the schema. */
};
struct lyplg_ext_record {
@@ -189,7 +208,7 @@
Instead, there should be defined multiple items in the plugins list, each with the
different revision, but all with the same pointer to the plugin functions. The
only valid use case for the NULL revision is the case the module has no revision. */
- const char *name; /**< name of the extension */
+ const char *name; /**< YANG name of the extension */
/* runtime data */
struct lyplg_ext plugin; /**< data to utilize plugin implementation */
diff --git a/src/plugins_exts/metadata.c b/src/plugins_exts/metadata.c
index ed7bc5b..2313090 100644
--- a/src/plugins_exts/metadata.c
+++ b/src/plugins_exts/metadata.c
@@ -161,6 +161,7 @@
.plugin.id = "libyang 2 - metadata, version 1",
.plugin.compile = &annotation_compile,
+ .plugin.parse = NULL,
.plugin.validate = NULL,
.plugin.sprinter = &annotation_schema_printer,
.plugin.free = annotation_free
diff --git a/src/plugins_exts/nacm.c b/src/plugins_exts/nacm.c
index 2381db1..a222dfe 100644
--- a/src/plugins_exts/nacm.c
+++ b/src/plugins_exts/nacm.c
@@ -158,6 +158,7 @@
.plugin.id = "libyang 2 - NACM, version 1",
.plugin.compile = &nacm_compile,
+ .plugin.parse = NULL,
.plugin.validate = NULL,
.plugin.sprinter = NULL,
.plugin.free = NULL
@@ -168,6 +169,7 @@
.plugin.id = "libyang 2 - NACM, version 1",
.plugin.compile = &nacm_compile,
+ .plugin.parse = NULL,
.plugin.validate = NULL,
.plugin.sprinter = NULL,
.plugin.free = NULL
@@ -178,6 +180,7 @@
.plugin.id = "libyang 2 - NACM, version 1",
.plugin.compile = &nacm_compile,
+ .plugin.parse = NULL,
.plugin.validate = NULL,
.plugin.sprinter = NULL,
.plugin.free = NULL
@@ -188,6 +191,7 @@
.plugin.id = "libyang 2 - NACM, version 1",
.plugin.compile = &nacm_compile,
+ .plugin.parse = NULL,
.plugin.validate = NULL,
.plugin.sprinter = NULL,
.plugin.free = NULL
diff --git a/src/plugins_exts/schema_mount.c b/src/plugins_exts/schema_mount.c
new file mode 100644
index 0000000..4b1c1cf
--- /dev/null
+++ b/src/plugins_exts/schema_mount.c
@@ -0,0 +1,208 @@
+/**
+ * @file schema_mount.c
+ * @author Tadeas Vintrlik <xvintr04@stud.fit.vutbr.cz>
+ * @brief libyang extension plugin - Schema Mount (RFC 8528)
+ *
+ * Copyright (c) 2021 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
+ */
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dict.h"
+#include "libyang.h"
+#include "log.h"
+#include "plugins_exts.h"
+#include "tree_data.h"
+#include "tree_schema.h"
+
+/**
+ * @brief Check if given mount point is unique among its' siblings
+ *
+ * @param cctx Compilation context.
+ * @param c_ext Compiled extension instance for checking uniqueness.
+ * @param p_ext Extension instance of the mount-point for comparison.
+ *
+ * @return LY_SUCCESS if is unique. LY_EINVAL otherwise.
+ */
+static LY_ERR
+schema_mount_unique_mount_point(struct lysc_ctx *cctx, const struct lysc_ext_instance *c_ext,
+ const struct lysp_ext_instance *p_ext)
+{
+ struct lysp_module *pmod;
+ struct lysp_ext_instance *exts;
+ LY_ARRAY_COUNT_TYPE u, v;
+ struct lysp_node *parent;
+ struct lysp_import *module;
+ char *ext_prefix, *ext_name;
+
+ /* Check if it is the only instance of the mount-point among its' siblings */
+ parent = (struct lysp_node *) c_ext->parent;
+ exts = parent->exts;
+ pmod = lysc_ctx_get_pmod(cctx);
+ LY_ARRAY_FOR(exts, u) {
+ /* Extract prefix and name of the extension */
+ ext_prefix = strdup(exts[u].name);
+ ext_name = strstr(exts[u].name, ":");
+ ext_name++;
+ ext_prefix[strstr(ext_prefix, ":") - ext_prefix] = '\0';
+
+ module = NULL;
+ LY_ARRAY_FOR(pmod->imports, v) {
+ if (!strcmp(pmod->imports[v].prefix, ext_prefix)) {
+ /* Found the matching module */
+ module = &pmod->imports[v];
+ break;
+ }
+ }
+ free(ext_prefix);
+ if ((&exts[u] != p_ext) && module && (!strcmp(module->name, "ietf-yang-schema-mount")) &&
+ (!strcmp(exts[u].name, "mount-point"))) {
+ /* Found another instance of mount-point only one allowed per node */
+ return LY_EINVAL;
+ }
+ }
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Schema mount compile.
+ *
+ * Checks if it can be a valid extension instance for yang schema mount.
+ *
+ * Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
+ */
+static LY_ERR
+schema_mount_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext,
+ struct lysc_ext_instance *c_ext)
+{
+ const struct lys_module *cur_mod;
+
+ /* Check if processing right callback */
+ assert(!strcmp(p_ext->name, "yangmnt:mount-point"));
+
+ /* Check if mount point was found in YANG version 1.1 module */
+ cur_mod = lysc_ctx_get_cur_mod(cctx);
+ if (cur_mod->parsed->version != LYS_VERSION_1_1) {
+ return LY_EINVAL;
+ }
+
+ /* Check if its' parent is a container or a list */
+ if ((p_ext->parent_stmt != LY_STMT_CONTAINER) && (p_ext->parent_stmt != LY_STMT_LIST)) {
+ return LY_EINVAL;
+ }
+
+ /* Check if the only mount-point among siblings */
+ if (schema_mount_unique_mount_point(cctx, c_ext, p_ext)) {
+ return LY_EINVAL;
+ }
+
+ (void)c_ext;
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Parse callback for schema mount.
+ *
+ * Check if data is valid for schema mount and inserts it to the parent.
+ */
+static LY_ERR
+schema_mount_parse(struct ly_in *in, LYD_FORMAT format, struct lysc_ext_instance *ext,
+ struct lyd_node *parent, uint32_t parse_opts, uint32_t val_opts)
+{
+ LY_ERR ret = LY_SUCCESS;
+ const struct ly_ctx *ctx;
+ struct lyd_node *subtree, *yanglib, *mount_point, *final = NULL;
+ struct ly_err_item *err;
+ ly_bool found_yanglib = 0, found_mount_point = 0;
+ uint32_t old_log_opts;
+
+ ctx = LYD_CTX(parent);
+
+ old_log_opts = ly_log_options(LY_LOSTORE_LAST);
+ /* Check if intended for schema-mount - had both required data nodes */
+ while (1) {
+ /* Parse by sub-trees */
+ if (lyd_parse_data(ctx, NULL, in, 0, parse_opts, val_opts, &subtree)) {
+ /* Either end or error - must check */
+ err = ly_err_first(ctx);
+ if (err->vecode == LYVE_SYNTAX_XML) {
+ /* Could just be EOF - check */
+ /* TODO: Search in error message if EOF then break */
+ lyd_insert_sibling(final, subtree, NULL);
+ break;
+ } else {
+ /* Other parsing error encountered */
+ ret = LY_EINVAL;
+ goto cleanup;
+ }
+ }
+
+ if (!final) {
+ /* If there was nothing inserted yet this subtree becomes the one to insert into */
+ final = subtree;
+ }
+
+ lyd_find_path(subtree, "/ietf-yang-library:yang-library", 0, &yanglib);
+ if (yanglib && !(yanglib->flags & LYD_DEFAULT)) {
+ /* Found and not created by flags */
+ found_yanglib = 1;
+ lyd_insert_sibling(final, yanglib, NULL);
+ continue;
+ }
+ lyd_find_path(subtree, "/ietf-yang-schema-mount:mount-points", 0, &mount_point);
+ if (mount_point && !(mount_point->flags & LYD_DEFAULT)) {
+ /* Was found and not created by flags */
+ found_mount_point = 1;
+ lyd_insert_sibling(final, mount_point, NULL);
+ continue;
+ }
+ }
+
+ if (found_mount_point && found_yanglib) {
+ /* It is valid data and can be inserted into the parent */
+ lyd_insert_child(parent, final);
+ } else {
+ /* It was not data for schema mount */
+ lyd_free_tree(final);
+ ret = LY_ENOT;
+ }
+
+cleanup:
+ ly_log_options(old_log_opts);
+ return ret;
+}
+
+/**
+ * @brief Plugin descriptions for the Yang Schema Mount extension.
+ *
+ * Note that external plugins are supposed to use:
+ *
+ * LYPLG_EXTENSIONS = {
+ */
+const struct lyplg_ext_record plugins_schema_mount[] = {
+ {
+ .module = "ietf-yang-schema-mount",
+ .revision = "2019-01-14",
+ .name = "mount-point",
+
+ .plugin.id = "libyang 2 - Schema Mount, version 1",
+ .plugin.compile = &schema_mount_compile,
+ .plugin.parse = &schema_mount_parse,
+ .plugin.validate = NULL,
+ .plugin.sprinter = NULL,
+ .plugin.free = NULL
+ },
+ {0} /* terminating zeroed item */
+};
diff --git a/src/plugins_exts/yangdata.c b/src/plugins_exts/yangdata.c
index 945e706..0c96a14 100644
--- a/src/plugins_exts/yangdata.c
+++ b/src/plugins_exts/yangdata.c
@@ -172,6 +172,7 @@
.plugin.id = "libyang 2 - yang-data, version 1",
.plugin.compile = &yangdata_compile,
+ .plugin.parse = NULL,
.plugin.validate = NULL,
.plugin.sprinter = &yangdata_schema_printer,
.plugin.free = yangdata_free
diff --git a/src/plugins_exts_compile.h b/src/plugins_exts_compile.h
index 1e14a20..fa2375f 100644
--- a/src/plugins_exts_compile.h
+++ b/src/plugins_exts_compile.h
@@ -91,6 +91,20 @@
LIBYANG_API_DECL const char *lysc_ctx_get_path(const struct lysc_ctx *ctx);
/**
+ * @brief YANG schema compilation context getter for current module.
+ * @param[in] ctx YANG schema compilation context.
+ * @return current module.
+ */
+const struct lys_module *lysc_ctx_get_cur_mod(const struct lysc_ctx *ctx);
+
+/**
+ * @brief YANG schema compilation context getter for currently processed module.
+ * @param[in] ctx YANG schema compilation context.
+ * @return Currently processed module.
+ */
+struct lysp_module *lysc_ctx_get_pmod(const struct lysc_ctx *ctx);
+
+/**
* @brief Compile substatements of an extension instance.
*
* Uses standard libyang schema compiler to transform YANG statements into the compiled schema structures. The plugins are
diff --git a/src/printer_tree.c b/src/printer_tree.c
index c0a1a11..3130a5b 100644
--- a/src/printer_tree.c
+++ b/src/printer_tree.c
@@ -181,11 +181,11 @@
*/
typedef enum {
TRD_INDENT_EMPTY = 0, /**< If the node is a case node, there is no space before the \<name\>. */
- TRD_INDENT_LONG_LINE_BREAK = 2, /**< The new line should be indented so that it starts below \<name\> with a whitespace offset of at least two characters. */
- TRD_INDENT_LINE_BEGIN = 2, /**< Indent below the keyword (module, augment ...). */
- TRD_INDENT_BTW_SIBLINGS = 2, /**< Indent between | and | characters. */
- TRD_INDENT_BEFORE_KEYS = 1, /**< "..."___\<keys\>. */
- TRD_INDENT_BEFORE_TYPE = 4, /**< "..."___\<type\>, but if mark is set then indent == 3. */
+ TRD_INDENT_LONG_LINE_BREAK = 2, /**< The new line should be indented so that it starts below \<name\> with a whitespace offset of at least two characters. */
+ TRD_INDENT_LINE_BEGIN = 2, /**< Indent below the keyword (module, augment ...). */
+ TRD_INDENT_BTW_SIBLINGS = 2, /**< Indent between | and | characters. */
+ TRD_INDENT_BEFORE_KEYS = 1, /**< "..."___\<keys\>. */
+ TRD_INDENT_BEFORE_TYPE = 4, /**< "..."___\<type\>, but if mark is set then indent == 3. */
TRD_INDENT_BEFORE_IFFEATURES = 1 /**< "..."___\<iffeatures\>. */
} trt_cnf_indent;
@@ -194,7 +194,7 @@
*/
typedef enum {
TRD_INDENT_IN_NODE_NORMAL = 0, /**< Node fits on one line. */
- TRD_INDENT_IN_NODE_DIVIDED, /**< The node must be split into multiple rows. */
+ TRD_INDENT_IN_NODE_DIVIDED, /**< The node must be split into multiple rows. */
TRD_INDENT_IN_NODE_FAILED /**< Cannot be crammed into one line. The condition for the maximum line length is violated. */
} trt_indent_in_node_type;
@@ -297,8 +297,8 @@
*/
typedef enum {
TRD_STATUS_TYPE_EMPTY = 0,
- TRD_STATUS_TYPE_CURRENT, /**< ::LYS_STATUS_CURR */
- TRD_STATUS_TYPE_DEPRECATED, /**< ::LYS_STATUS_DEPRC */
+ TRD_STATUS_TYPE_CURRENT, /**< ::LYS_STATUS_CURR */
+ TRD_STATUS_TYPE_DEPRECATED, /**< ::LYS_STATUS_DEPRC */
TRD_STATUS_TYPE_OBSOLETE /**< ::LYS_STATUS_OBSLT */
} trt_status_type;
@@ -313,12 +313,12 @@
*/
typedef enum {
TRD_FLAGS_TYPE_EMPTY = 0, /**< -- */
- TRD_FLAGS_TYPE_RW, /**< rw */
- TRD_FLAGS_TYPE_RO, /**< ro */
- TRD_FLAGS_TYPE_RPC_INPUT_PARAMS, /**< -w */
- TRD_FLAGS_TYPE_USES_OF_GROUPING, /**< -u */
- TRD_FLAGS_TYPE_RPC, /**< -x */
- TRD_FLAGS_TYPE_NOTIF, /**< -n */
+ TRD_FLAGS_TYPE_RW, /**< rw */
+ TRD_FLAGS_TYPE_RO, /**< ro */
+ TRD_FLAGS_TYPE_RPC_INPUT_PARAMS, /**< -w */
+ TRD_FLAGS_TYPE_USES_OF_GROUPING, /**< -u */
+ TRD_FLAGS_TYPE_RPC, /**< -x */
+ TRD_FLAGS_TYPE_NOTIF, /**< -n */
TRD_FLAGS_TYPE_MOUNT_POINT /**< mp */
} trt_flags_type;
@@ -338,15 +338,15 @@
*/
typedef enum {
TRD_NODE_ELSE = 0, /**< For some node which does not require special treatment. \<name\> */
- TRD_NODE_CASE, /**< For case node. :(\<name\>) */
- TRD_NODE_CHOICE, /**< For choice node. (\<name\>) */
- TRD_NODE_OPTIONAL_CHOICE, /**< For choice node with optional mark. (\<name\>)? */
- TRD_NODE_OPTIONAL, /**< For an optional leaf, anydata, or anyxml. \<name\>? */
- TRD_NODE_CONTAINER, /**< For a presence container. \<name\>! */
- TRD_NODE_LISTLEAFLIST, /**< For a leaf-list or list (without keys). \<name\>* */
- TRD_NODE_KEYS, /**< For a list's keys. \<name\>* [\<keys\>] */
- TRD_NODE_TOP_LEVEL1, /**< For a top-level data node in a mounted module. \<name\>/ */
- TRD_NODE_TOP_LEVEL2, /**< For a top-level data node of a module identified in a mount point parent reference. \<name\>@ */
+ TRD_NODE_CASE, /**< For case node. :(\<name\>) */
+ TRD_NODE_CHOICE, /**< For choice node. (\<name\>) */
+ TRD_NODE_OPTIONAL_CHOICE, /**< For choice node with optional mark. (\<name\>)? */
+ TRD_NODE_OPTIONAL, /**< For an optional leaf, anydata, or anyxml. \<name\>? */
+ TRD_NODE_CONTAINER, /**< For a presence container. \<name\>! */
+ TRD_NODE_LISTLEAFLIST, /**< For a leaf-list or list (without keys). \<name\>* */
+ TRD_NODE_KEYS, /**< For a list's keys. \<name\>* [\<keys\>] */
+ TRD_NODE_TOP_LEVEL1, /**< For a top-level data node in a mounted module. \<name\>/ */
+ TRD_NODE_TOP_LEVEL2, /**< For a top-level data node of a module identified in a mount point parent reference. \<name\>@ */
TRD_NODE_TRIPLE_DOT /**< For collapsed sibling nodes and their children. Special case which doesn't belong here very well. */
} trt_node_type;
@@ -392,8 +392,8 @@
*/
typedef enum {
TRD_TYPE_NAME = 0, /**< Type is just a name that does not require special treatment. */
- TRD_TYPE_TARGET, /**< Should have a form "-> TARGET", where TARGET is the leafref path. */
- TRD_TYPE_LEAFREF, /**< This type is set automatically by the 'trp' algorithm.
+ TRD_TYPE_TARGET, /**< Should have a form "-> TARGET", where TARGET is the leafref path. */
+ TRD_TYPE_LEAFREF, /**< This type is set automatically by the 'trp' algorithm.
So set type as ::TRD_TYPE_TARGET. */
TRD_TYPE_EMPTY /**< Type is not used at all. */
} trt_type_type;
@@ -500,12 +500,12 @@
*/
typedef enum {
TRD_KEYWORD_EMPTY = 0,
- TRD_KEYWORD_MODULE,
- TRD_KEYWORD_SUBMODULE,
- TRD_KEYWORD_AUGMENT,
- TRD_KEYWORD_RPC,
- TRD_KEYWORD_NOTIF,
- TRD_KEYWORD_GROUPING,
+ TRD_KEYWORD_MODULE,
+ TRD_KEYWORD_SUBMODULE,
+ TRD_KEYWORD_AUGMENT,
+ TRD_KEYWORD_RPC,
+ TRD_KEYWORD_NOTIF,
+ TRD_KEYWORD_GROUPING,
TRD_KEYWORD_YANG_DATA
} trt_keyword_type;
@@ -617,10 +617,10 @@
*/
typedef enum {
TRD_SECT_MODULE = 0, /**< The node belongs to the "module: <module_name>:" label. */
- TRD_SECT_AUGMENT, /**< The node belongs to some "augment <target-node>:" label. */
- TRD_SECT_RPCS, /**< The node belongs to the "rpcs:" label. */
- TRD_SECT_NOTIF, /**< The node belongs to the "notifications:" label. */
- TRD_SECT_GROUPING, /**< The node belongs to some "grouping <grouping-name>:" label. */
+ TRD_SECT_AUGMENT, /**< The node belongs to some "augment <target-node>:" label. */
+ TRD_SECT_RPCS, /**< The node belongs to the "rpcs:" label. */
+ TRD_SECT_NOTIF, /**< The node belongs to the "notifications:" label. */
+ TRD_SECT_GROUPING, /**< The node belongs to some "grouping <grouping-name>:" label. */
TRD_SECT_YANG_DATA /**< The node belongs to some "yang-data <yang-data-name>:" label. */
} trt_actual_section;
@@ -629,8 +629,8 @@
*/
typedef enum {
TRD_ANCESTOR_ELSE = 0, /**< Everything not listed. */
- TRD_ANCESTOR_RPC_INPUT, /**< ::LYS_INPUT */
- TRD_ANCESTOR_RPC_OUTPUT, /**< ::LYS_OUTPUT */
+ TRD_ANCESTOR_RPC_INPUT, /**< ::LYS_INPUT */
+ TRD_ANCESTOR_RPC_OUTPUT, /**< ::LYS_OUTPUT */
TRD_ANCESTOR_NOTIF /**< ::LYS_NOTIF */
} trt_ancestor_type;