Merge remote-tracking branch 'upstream/libyang2' into libyang2
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 41a1adb..66fcf37 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -11,16 +11,136 @@
*
* https://opensource.org/licenses/BSD-3-Clause
*/
-#define _XOPEN_SOURCE
+#include "common.h"
#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
#include <limits.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <time.h>
#include "libyang.h"
-#include "common.h"
#include "tree_schema_internal.h"
+/**
+ * @brief Parse an identifier.
+ *
+ * ;; An identifier MUST NOT start with (('X'|'x') ('M'|'m') ('L'|'l'))
+ * identifier = (ALPHA / "_")
+ * *(ALPHA / DIGIT / "_" / "-" / ".")
+ *
+ * @param[in,out] id Identifier to parse. When returned, it points to the first character which is not part of the identifier.
+ * @return LY_ERR value: LY_SUCCESS or LY_EINVAL in case of invalid starting character.
+ */
+static LY_ERR
+lys_parse_id(const char **id)
+{
+ assert(id && *id);
+
+ if (!is_yangidentstartchar(**id)) {
+ return LY_EINVAL;
+ }
+ ++(*id);
+
+ while (is_yangidentchar(**id)) {
+ ++(*id);
+ }
+ return LY_SUCCESS;
+}
+
+LY_ERR
+lys_parse_nodeid(const char **id, const char **prefix, size_t *prefix_len, const char **name, size_t *name_len)
+{
+ assert(id && *id);
+ assert(prefix && prefix_len);
+ assert(name && name_len);
+
+ *prefix = *id;
+ *prefix_len = 0;
+ *name = NULL;
+ *name_len = 0;
+
+ LY_CHECK_RET(lys_parse_id(id));
+ if (**id == ':') {
+ /* there is prefix */
+ *prefix_len = *id - *prefix;
+ ++(*id);
+ *name = *id;
+
+ LY_CHECK_RET(lys_parse_id(id));
+ *name_len = *id - *name;
+ } else {
+ /* there is no prefix, so what we have as prefix now is actually the name */
+ *name = *prefix;
+ *name_len = *id - *name;
+ *prefix = NULL;
+ }
+
+ return LY_SUCCESS;
+}
+
+LY_ERR
+lys_resolve_descendant_schema_nodeid(struct lysc_ctx *ctx, const char *nodeid, size_t nodeid_len, const struct lysc_node *context_node,
+ int nodetype, const struct lysc_node **target)
+{
+ LY_ERR ret = LY_EVALID;
+ const char *name, *prefix, *id;
+ const struct lysc_node *context;
+ size_t name_len, prefix_len;
+ const struct lys_module *mod;
+
+ assert(nodeid);
+ assert(context_node);
+ assert(target);
+ *target = NULL;
+
+ id = nodeid;
+ context = context_node;
+ while (*id && (ret = lys_parse_nodeid(&id, &prefix, &prefix_len, &name, &name_len)) == LY_SUCCESS) {
+ if (prefix) {
+ mod = lys_module_find_prefix(context_node->module, prefix, prefix_len);
+ if (!mod) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+ "Invalid descendant-schema-nodeid value \"%.*s\" - prefix \"%.*s\" not defined in module \"%s\".",
+ id - nodeid, nodeid, prefix_len, prefix, context_node->module->compiled->name);
+ return LY_ENOTFOUND;
+ }
+ } else {
+ mod = context_node->module;
+ }
+ context = lys_child(context, mod, name, name_len, 0, LYS_GETNEXT_NOSTATECHECK | LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE);
+ if (!context) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+ "Invalid descendant-schema-nodeid value \"%.*s\" - target node not found.", id - nodeid, nodeid);
+ return LY_ENOTFOUND;
+ }
+ if (nodeid_len && ((size_t)(id - nodeid) >= nodeid_len)) {
+ break;
+ }
+ if (id && *id != '/') {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+ "Invalid descendant-schema-nodeid value \"%.*s\" - missing \"/\" as node-identifier separator.",
+ id - nodeid + 1, nodeid);
+ return LY_EVALID;
+ }
+ ++id;
+ }
+
+ if (ret == LY_SUCCESS) {
+ *target = context;
+ if (nodetype && !(context->nodetype & nodetype)) {
+ return LY_EDENIED;
+ }
+ }
+
+ return ret;
+}
+
LY_ERR
lysp_check_prefix(struct ly_parser_ctx *ctx, struct lysp_module *module, const char **value)
{
@@ -44,14 +164,37 @@
}
LY_ERR
-lysp_check_date(struct ly_ctx *ctx, const char *date, int date_len, const char *stmt)
+lysc_check_status(struct lysc_ctx *ctx,
+ uint16_t flags1, void *mod1, const char *name1,
+ uint16_t flags2, void *mod2, const char *name2)
+{
+ uint16_t flg1, flg2;
+
+ flg1 = (flags1 & LYS_STATUS_MASK) ? (flags1 & LYS_STATUS_MASK) : LYS_STATUS_CURR;
+ flg2 = (flags2 & LYS_STATUS_MASK) ? (flags2 & LYS_STATUS_MASK) : LYS_STATUS_CURR;
+
+ if ((flg1 < flg2) && (mod1 == mod2)) {
+ if (ctx) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+ "A %s definition \"%s\" is not allowed to reference %s definition \"%s\".",
+ flg1 == LYS_STATUS_CURR ? "current" : "deprecated", name1,
+ flg2 == LYS_STATUS_OBSLT ? "obsolete" : "deprecated", name2);
+ }
+ return LY_EVALID;
+ }
+
+ return LY_SUCCESS;
+}
+
+LY_ERR
+lysp_check_date(struct ly_parser_ctx *ctx, const char *date, int date_len, const char *stmt)
{
int i;
struct tm tm, tm_;
char *r;
- LY_CHECK_ARG_RET(ctx, date, LY_EINVAL);
- LY_CHECK_ERR_RET(date_len != LY_REV_SIZE - 1, LOGARG(ctx, date_len), LY_EINVAL);
+ LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, date, LY_EINVAL);
+ LY_CHECK_ERR_RET(date_len != LY_REV_SIZE - 1, LOGARG(ctx ? ctx->ctx : NULL, date_len), LY_EINVAL);
/* check format */
for (i = 0; i < date_len; i++) {
@@ -81,7 +224,13 @@
return LY_SUCCESS;
error:
- LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_INVAL, date_len, date, stmt);
+ if (stmt) {
+ if (ctx) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LY_VCODE_INVAL, date_len, date, stmt);
+ } else {
+ LOGVAL(NULL, LY_VLOG_NONE, NULL, LY_VCODE_INVAL, date_len, date, stmt);
+ }
+ }
return LY_EINVAL;
}
@@ -92,7 +241,7 @@
struct lysp_revision rev;
for (i = 1, r = 0; revs && i < LY_ARRAY_SIZE(revs); i++) {
- if (strcmp(revs[i].rev, revs[r].rev) > 0) {
+ if (strcmp(revs[i].date, revs[r].date) > 0) {
r = i;
}
}
@@ -105,213 +254,1078 @@
}
}
-struct lysc_module *
-lysc_module_find_prefix(struct lysc_module *mod, const char *prefix, size_t len)
+static const struct lysp_tpdf *
+lysp_type_match(const char *name, struct lysp_node *node)
{
- struct lysc_import *imp;
+ const struct lysp_tpdf *typedefs;
+ unsigned int u;
- assert(mod);
-
- if (!strncmp(mod->prefix, prefix, len) && mod->prefix[len] == '\0') {
- /* it is the prefix of the module itself */
- return mod;
- }
-
- /* search in imports */
- LY_ARRAY_FOR(mod->imports, struct lysc_import, imp) {
- if (!strncmp(imp->prefix, prefix, len) && mod->prefix[len] == '\0') {
- return imp->module;
+ typedefs = lysp_node_typedefs(node);
+ LY_ARRAY_FOR(typedefs, u) {
+ if (!strcmp(name, typedefs[u].name)) {
+ /* match */
+ return &typedefs[u];
}
}
return NULL;
}
+static LY_DATA_TYPE
+lysp_type_str2builtin(const char *name, size_t len)
+{
+ if (len >= 4) { /* otherwise it does not match any built-in type */
+ if (name[0] == 'b') {
+ if (name[1] == 'i') {
+ if (len == 6 && !strncmp(&name[2], "nary", 4)) {
+ return LY_TYPE_BINARY;
+ } else if (len == 4 && !strncmp(&name[2], "ts", 2)) {
+ return LY_TYPE_BITS;
+ }
+ } else if (len == 7 && !strncmp(&name[1], "oolean", 6)) {
+ return LY_TYPE_BOOL;
+ }
+ } else if (name[0] == 'd') {
+ if (len == 9 && !strncmp(&name[1], "ecimal64", 8)) {
+ return LY_TYPE_DEC64;
+ }
+ } else if (name[0] == 'e') {
+ if (len == 5 && !strncmp(&name[1], "mpty", 4)) {
+ return LY_TYPE_EMPTY;
+ } else if (len == 11 && !strncmp(&name[1], "numeration", 10)) {
+ return LY_TYPE_ENUM;
+ }
+ } else if (name[0] == 'i') {
+ if (name[1] == 'n') {
+ if (len == 4 && !strncmp(&name[2], "t8", 2)) {
+ return LY_TYPE_INT8;
+ } else if (len == 5) {
+ if (!strncmp(&name[2], "t16", 3)) {
+ return LY_TYPE_INT16;
+ } else if (!strncmp(&name[2], "t32", 3)) {
+ return LY_TYPE_INT32;
+ } else if (!strncmp(&name[2], "t64", 3)) {
+ return LY_TYPE_INT64;
+ }
+ } else if (len == 19 && !strncmp(&name[2], "stance-identifier", 17)) {
+ return LY_TYPE_INST;
+ }
+ } else if (len == 11 && !strncmp(&name[1], "dentityref", 10)) {
+ return LY_TYPE_IDENT;
+ }
+ } else if (name[0] == 'l') {
+ if (len == 7 && !strncmp(&name[1], "eafref", 6)) {
+ return LY_TYPE_LEAFREF;
+ }
+ } else if (name[0] == 's') {
+ if (len == 6 && !strncmp(&name[1], "tring", 5)) {
+ return LY_TYPE_STRING;
+ }
+ } else if (name[0] == 'u') {
+ if (name[1] == 'n') {
+ if (len == 5 && !strncmp(&name[2], "ion", 3)) {
+ return LY_TYPE_UNION;
+ }
+ } else if (name[1] == 'i' && name[2] == 'n' && name[3] == 't') {
+ if (len == 5 && name[4] == '8') {
+ return LY_TYPE_UINT8;
+ } else if (len == 6) {
+ if (!strncmp(&name[4], "16", 2)) {
+ return LY_TYPE_UINT16;
+ } else if (!strncmp(&name[4], "32", 2)) {
+ return LY_TYPE_UINT32;
+ } else if (!strncmp(&name[4], "64", 2)) {
+ return LY_TYPE_UINT64;
+ }
+ }
+ }
+ }
+ }
+
+ return LY_TYPE_UNKNOWN;
+}
+
+LY_ERR
+lysp_type_find(const char *id, struct lysp_node *start_node, struct lysp_module *start_module,
+ LY_DATA_TYPE *type, const struct lysp_tpdf **tpdf, struct lysp_node **node, struct lysp_module **module)
+{
+ const char *str, *name;
+ struct lysp_tpdf *typedefs;
+ unsigned int u, v;
+
+ assert(id);
+ assert(start_module);
+ assert(tpdf);
+ assert(node);
+ assert(module);
+
+ *node = NULL;
+ str = strchr(id, ':');
+ if (str) {
+ *module = lysp_module_find_prefix(start_module, id, str - id);
+ name = str + 1;
+ *type = LY_TYPE_UNKNOWN;
+ } else {
+ *module = start_module;
+ name = id;
+
+ /* check for built-in types */
+ *type = lysp_type_str2builtin(name, strlen(name));
+ if (*type) {
+ *tpdf = NULL;
+ return LY_SUCCESS;
+ }
+ }
+ LY_CHECK_RET(!(*module), LY_ENOTFOUND);
+
+ if (start_node && *module == start_module) {
+ /* search typedefs in parent's nodes */
+ *node = start_node;
+ while (*node) {
+ *tpdf = lysp_type_match(name, *node);
+ if (*tpdf) {
+ /* match */
+ return LY_SUCCESS;
+ }
+ *node = (*node)->parent;
+ }
+ }
+
+ /* search in top-level typedefs */
+ if ((*module)->typedefs) {
+ LY_ARRAY_FOR((*module)->typedefs, u) {
+ if (!strcmp(name, (*module)->typedefs[u].name)) {
+ /* match */
+ *tpdf = &(*module)->typedefs[u];
+ return LY_SUCCESS;
+ }
+ }
+ }
+
+ /* search in submodules' typedefs */
+ LY_ARRAY_FOR((*module)->includes, u) {
+ typedefs = (*module)->includes[u].submodule->typedefs;
+ LY_ARRAY_FOR(typedefs, v) {
+ if (!strcmp(name, typedefs[v].name)) {
+ /* match */
+ *tpdf = &typedefs[v];
+ return LY_SUCCESS;
+ }
+ }
+ }
+
+ return LY_ENOTFOUND;
+}
+
+/*
+ * @brief Check name of a new type to avoid name collisions.
+ *
+ * @param[in] ctx Parser context, module where the type is being defined is taken from here.
+ * @param[in] node Schema node where the type is being defined, NULL in case of a top-level typedef.
+ * @param[in] tpdf Typedef definition to check.
+ * @param[in,out] tpdfs_global Initialized hash table to store temporary data between calls. When the module's
+ * typedefs are checked, caller is supposed to free the table.
+ * @param[in,out] tpdfs_global Initialized hash table to store temporary data between calls. When the module's
+ * typedefs are checked, caller is supposed to free the table.
+ * @return LY_EEXIST in case of collision, LY_SUCCESS otherwise.
+ */
+static LY_ERR
+lysp_check_typedef(struct ly_parser_ctx *ctx, struct lysp_node *node, const struct lysp_tpdf *tpdf,
+ struct hash_table *tpdfs_global, struct hash_table *tpdfs_scoped)
+{
+ struct lysp_node *parent;
+ uint32_t hash;
+ size_t name_len;
+ const char *name;
+ unsigned int u;
+ const struct lysp_tpdf *typedefs;
+
+ assert(ctx);
+ assert(tpdf);
+
+ name = tpdf->name;
+ name_len = strlen(name);
+
+ if (lysp_type_str2builtin(name, name_len)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX_YANG,
+ "Invalid name \"%s\" of typedef - name collision with a built-in type.", name);
+ return LY_EEXIST;
+ }
+
+ /* check locally scoped typedefs (avoid name shadowing) */
+ if (node) {
+ typedefs = lysp_node_typedefs(node);
+ LY_ARRAY_FOR(typedefs, u) {
+ if (&typedefs[u] == tpdf) {
+ break;
+ }
+ if (!strcmp(name, typedefs[u].name)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX_YANG,
+ "Invalid name \"%s\" of typedef - name collision with sibling type.", name);
+ return LY_EEXIST;
+ }
+ }
+ /* search typedefs in parent's nodes */
+ for (parent = node->parent; parent; parent = node->parent) {
+ if (lysp_type_match(name, parent)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX_YANG,
+ "Invalid name \"%s\" of typedef - name collision with another scoped type.", name);
+ return LY_EEXIST;
+ }
+ }
+ }
+
+ /* check collision with the top-level typedefs */
+ hash = dict_hash(name, name_len);
+ if (node) {
+ lyht_insert(tpdfs_scoped, &name, hash, NULL);
+ if (!lyht_find(tpdfs_global, &name, hash, NULL)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX_YANG,
+ "Invalid name \"%s\" of typedef - scoped type collide with a top-level type.", name);
+ return LY_EEXIST;
+ }
+ } else {
+ if (lyht_insert(tpdfs_global, &name, hash, NULL)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX_YANG,
+ "Invalid name \"%s\" of typedef - name collision with another top-level type.", name);
+ return LY_EEXIST;
+ }
+ /* it is not necessary to test collision with the scoped types - in lysp_check_typedefs, all the
+ * top-level typedefs are inserted into the tables before the scoped typedefs, so the collision
+ * is detected in the first branch few lines above */
+ }
+
+ return LY_SUCCESS;
+}
+
+static int
+lysp_id_cmp(void *val1, void *val2, int UNUSED(mod), void *UNUSED(cb_data))
+{
+ return !strcmp(val1, val2);
+}
+
+LY_ERR
+lysp_check_typedefs(struct ly_parser_ctx *ctx)
+{
+ struct hash_table *ids_global;
+ struct hash_table *ids_scoped;
+ const struct lysp_tpdf *typedefs;
+ unsigned int i, u;
+ LY_ERR ret = LY_EVALID;
+
+ /* check name collisions - typedefs and groupings */
+ ids_global = lyht_new(8, sizeof(char*), lysp_id_cmp, NULL, 1);
+ ids_scoped = lyht_new(8, sizeof(char*), lysp_id_cmp, NULL, 1);
+ LY_ARRAY_FOR(ctx->mod->typedefs, i) {
+ if (lysp_check_typedef(ctx, NULL, &ctx->mod->typedefs[i], ids_global, ids_scoped)) {
+ goto cleanup;
+ }
+ }
+ LY_ARRAY_FOR(ctx->mod->includes, i) {
+ LY_ARRAY_FOR(ctx->mod->includes[i].submodule->typedefs, u) {
+ if (lysp_check_typedef(ctx, NULL, &ctx->mod->includes[i].submodule->typedefs[u], ids_global, ids_scoped)) {
+ goto cleanup;
+ }
+ }
+ }
+ for (u = 0; u < ctx->tpdfs_nodes.count; ++u) {
+ typedefs = lysp_node_typedefs((struct lysp_node *)ctx->tpdfs_nodes.objs[u]);
+ LY_ARRAY_FOR(typedefs, i) {
+ if (lysp_check_typedef(ctx, (struct lysp_node *)ctx->tpdfs_nodes.objs[u], &typedefs[i], ids_global, ids_scoped)) {
+ goto cleanup;
+ }
+ }
+ }
+ ret = LY_SUCCESS;
+cleanup:
+ lyht_free(ids_global);
+ lyht_free(ids_scoped);
+ ly_set_erase(&ctx->tpdfs_nodes, NULL);
+
+ return ret;
+}
+
+void
+lys_module_implement(struct lys_module *mod)
+{
+ assert(mod);
+ if (mod->parsed) {
+ mod->parsed->implemented = 1;
+ }
+ if (mod->compiled) {
+ mod->compiled->implemented = 1;
+ }
+}
+
+struct lysp_load_module_check_data {
+ const char *name;
+ const char *revision;
+ const char *path;
+ const char* submoduleof;
+};
+
+static LY_ERR
+lysp_load_module_check(struct ly_ctx *ctx, struct lysp_module *mod, void *data)
+{
+ struct lysp_load_module_check_data *info = data;
+ const char *filename, *dot, *rev;
+ size_t len;
+
+ if (info->name) {
+ /* check name of the parsed model */
+ if (strcmp(info->name, mod->name)) {
+ LOGERR(ctx, LY_EINVAL, "Unexpected module \"%s\" parsed instead of \"%s\").", mod->name, info->name);
+ return LY_EINVAL;
+ }
+ }
+ if (info->revision) {
+ /* check revision of the parsed model */
+ if (!mod->revs || strcmp(info->revision, mod->revs[0].date)) {
+ LOGERR(ctx, LY_EINVAL, "Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").", mod->name,
+ mod->revs[0].date, info->revision);
+ return LY_EINVAL;
+ }
+ }
+ if (info->submoduleof) {
+ /* check that we have really a submodule */
+ if (!mod->submodule) {
+ /* submodule is not a submodule */
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Included \"%s\" schema from \"%s\" is actually not a submodule.",
+ mod->name, info->submoduleof);
+ return LY_EVALID;
+ }
+ /* check that the submodule belongs-to our module */
+ if (strcmp(info->submoduleof, mod->belongsto)) {
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Included \"%s\" submodule from \"%s\" belongs-to a different module \"%s\".",
+ mod->name, info->submoduleof, mod->belongsto);
+ return LY_EVALID;
+ }
+ /* check circular dependency */
+ if (mod->parsing) {
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "A circular dependency (include) for module \"%s\".", mod->name);
+ return LY_EVALID;
+ }
+ }
+ if (info->path) {
+ /* check that name and revision match filename */
+ filename = strrchr(info->path, '/');
+ if (!filename) {
+ filename = info->path;
+ } else {
+ filename++;
+ }
+ /* name */
+ len = strlen(mod->name);
+ rev = strchr(filename, '@');
+ dot = strrchr(info->path, '.');
+ if (strncmp(filename, mod->name, len) ||
+ ((rev && rev != &filename[len]) || (!rev && dot != &filename[len]))) {
+ LOGWRN(ctx, "File name \"%s\" does not match module name \"%s\".", filename, mod->name);
+ }
+ /* revision */
+ if (rev) {
+ len = dot - ++rev;
+ if (!mod->revs || len != 10 || strncmp(mod->revs[0].date, rev, len)) {
+ LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", filename,
+ mod->revs ? mod->revs[0].date : "none");
+ }
+ }
+ }
+ return LY_SUCCESS;
+}
+
+LY_ERR
+lys_module_localfile(struct ly_ctx *ctx, const char *name, const char *revision, int implement, struct ly_parser_ctx *main_ctx,
+ struct lys_module **result)
+{
+ int fd;
+ char *filepath = NULL;
+ LYS_INFORMAT format;
+ struct lys_module *mod = NULL;
+ LY_ERR ret = LY_SUCCESS;
+ struct lysp_load_module_check_data check_data = {0};
+
+ LY_CHECK_RET(lys_search_localfile(ly_ctx_get_searchdirs(ctx), !(ctx->flags & LY_CTX_DISABLE_SEARCHDIR_CWD), name, revision,
+ &filepath, &format));
+ LY_CHECK_ERR_RET(!filepath, LOGERR(ctx, LY_ENOTFOUND, "Data model \"%s%s%s\" not found in local searchdirs.",
+ name, revision ? "@" : "", revision ? revision : ""), LY_ENOTFOUND);
+
+
+ LOGVRB("Loading schema from \"%s\" file.", filepath);
+
+ /* open the file */
+ fd = open(filepath, O_RDONLY);
+ LY_CHECK_ERR_GOTO(fd < 0, LOGERR(ctx, LY_ESYS, "Unable to open data model file \"%s\" (%s).",
+ filepath, strerror(errno)); ret = LY_ESYS, cleanup);
+
+ check_data.name = name;
+ check_data.revision = revision;
+ check_data.path = filepath;
+ mod = lys_parse_fd_(ctx, fd, format, implement, main_ctx,
+ lysp_load_module_check, &check_data);
+ close(fd);
+ LY_CHECK_ERR_GOTO(!mod, ly_errcode(ctx), cleanup);
+
+ if (!mod->parsed->filepath) {
+ char rpath[PATH_MAX];
+ if (realpath(filepath, rpath) != NULL) {
+ mod->parsed->filepath = lydict_insert(ctx, rpath, 0);
+ } else {
+ mod->parsed->filepath = lydict_insert(ctx, filepath, 0);
+ }
+ }
+
+ *result = mod;
+
+ /* success */
+cleanup:
+ free(filepath);
+ return ret;
+}
+
+LY_ERR
+lysp_load_module(struct ly_ctx *ctx, const char *name, const char *revision, int implement, int require_parsed, struct lys_module **mod)
+{
+ const char *module_data = NULL;
+ LYS_INFORMAT format = LYS_IN_UNKNOWN;
+ void (*module_data_free)(void *module_data, void *user_data) = NULL;
+ struct lysp_load_module_check_data check_data = {0};
+
+ /* try to get the module from the context */
+ if (revision) {
+ *mod = (struct lys_module*)ly_ctx_get_module(ctx, name, revision);
+ } else {
+ *mod = (struct lys_module*)ly_ctx_get_module_latest(ctx, name);
+ }
+
+ if (!(*mod) || (require_parsed && !(*mod)->parsed)) {
+ (*mod) = NULL;
+
+ /* check collision with other implemented revision */
+ if (implement && ly_ctx_get_module_implemented(ctx, name)) {
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE,
+ "Module \"%s\" is already present in other implemented revision.", name);
+ return LY_EDENIED;
+ }
+
+ /* module not present in the context, get the input data and parse it */
+ if (!(ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
+search_clb:
+ if (ctx->imp_clb) {
+ if (ctx->imp_clb(name, revision, NULL, NULL, ctx->imp_clb_data,
+ &format, &module_data, &module_data_free) == LY_SUCCESS) {
+ check_data.name = name;
+ check_data.revision = revision;
+ *mod = lys_parse_mem_(ctx, module_data, format, implement, NULL,
+ lysp_load_module_check, &check_data);
+ if (module_data_free) {
+ module_data_free((void*)module_data, ctx->imp_clb_data);
+ }
+ }
+ }
+ if (!(*mod) && !(ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
+ goto search_file;
+ }
+ } else {
+search_file:
+ if (!(ctx->flags & LY_CTX_DISABLE_SEARCHDIRS)) {
+ /* module was not received from the callback or there is no callback set */
+ lys_module_localfile(ctx, name, revision, implement, NULL, mod);
+ }
+ if (!(*mod) && (ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
+ goto search_clb;
+ }
+ }
+
+ if ((*mod) && !revision && ((*mod)->parsed->latest_revision == 1)) {
+ /* update the latest_revision flag - here we have selected the latest available schema,
+ * consider that even the callback provides correct latest revision */
+ (*mod)->parsed->latest_revision = 2;
+ }
+ } else {
+ /* we have module from the current context */
+ if (implement && (ly_ctx_get_module_implemented(ctx, name) != *mod)) {
+ /* check collision with other implemented revision */
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE,
+ "Module \"%s\" is already present in other implemented revision.", name);
+ *mod = NULL;
+ return LY_EDENIED;
+ }
+
+ /* circular check */
+ if ((*mod)->parsed && (*mod)->parsed->parsing) {
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "A circular dependency (import) for module \"%s\".", name);
+ *mod = NULL;
+ return LY_EVALID;
+ }
+ }
+ if (!(*mod)) {
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "%s \"%s\" module failed.", implement ? "Loading" : "Importing", name);
+ return LY_EVALID;
+ }
+
+ if (implement) {
+ /* mark the module implemented, check for collision was already done */
+ lys_module_implement(*mod);
+ }
+
+ return LY_SUCCESS;
+}
+
+LY_ERR
+lysp_load_submodule(struct ly_parser_ctx *ctx, struct lysp_module *mod, struct lysp_include *inc)
+{
+ struct lys_module *submod;
+ const char *submodule_data = NULL;
+ LYS_INFORMAT format = LYS_IN_UNKNOWN;
+ void (*submodule_data_free)(void *module_data, void *user_data) = NULL;
+ struct lysp_load_module_check_data check_data = {0};
+
+ /* submodule not present in the context, get the input data and parse it */
+ if (!(ctx->ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
+search_clb:
+ if (ctx->ctx->imp_clb) {
+ if (ctx->ctx->imp_clb(mod->name, NULL, inc->name, inc->rev[0] ? inc->rev : NULL, ctx->ctx->imp_clb_data,
+ &format, &submodule_data, &submodule_data_free) == LY_SUCCESS) {
+ check_data.name = inc->name;
+ check_data.revision = inc->rev[0] ? inc->rev : NULL;
+ check_data.submoduleof = mod->name;
+ submod = lys_parse_mem_(ctx->ctx, submodule_data, format, mod->implemented, ctx,
+ lysp_load_module_check, &check_data);
+ if (submodule_data_free) {
+ submodule_data_free((void*)submodule_data, ctx->ctx->imp_clb_data);
+ }
+ }
+ }
+ if (!submod && !(ctx->ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
+ goto search_file;
+ }
+ } else {
+search_file:
+ if (!(ctx->ctx->flags & LY_CTX_DISABLE_SEARCHDIRS)) {
+ /* module was not received from the callback or there is no callback set */
+ lys_module_localfile(ctx->ctx, inc->name, inc->rev[0] ? inc->rev : NULL, mod->implemented, ctx, &submod);
+ }
+ if (!submod && (ctx->ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
+ goto search_clb;
+ }
+ }
+ if (submod) {
+ if (!inc->rev[0] && (submod->parsed->latest_revision == 1)) {
+ /* update the latest_revision flag - here we have selected the latest available schema,
+ * consider that even the callback provides correct latest revision */
+ submod->parsed->latest_revision = 2;
+ }
+
+ inc->submodule = submod->parsed;
+ free(submod);
+ }
+ if (!inc->submodule) {
+ LOGVAL(ctx->ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Including \"%s\" submodule into \"%s\" failed.", inc->name, mod->name);
+ return LY_EVALID;
+ }
+
+ return LY_SUCCESS;
+}
+
+#define FIND_MODULE(TYPE, MOD, ID) \
+ TYPE *imp; \
+ if (!strncmp((MOD)->prefix, prefix, len) && (MOD)->prefix[len] == '\0') { \
+ /* it is the prefix of the module itself */ \
+ m = ly_ctx_get_module((MOD)->ctx, (MOD)->name, ((struct lysc_module*)(MOD))->revision); \
+ } \
+ /* search in imports */ \
+ if (!m) { \
+ LY_ARRAY_FOR((MOD)->imports, TYPE, imp) { \
+ if (!strncmp(imp->prefix, prefix, len) && (MOD)->prefix[len] == '\0') { \
+ m = imp->module; \
+ break; \
+ } \
+ } \
+ }
+
+struct lysc_module *
+lysc_module_find_prefix(const struct lysc_module *mod, const char *prefix, size_t len)
+{
+ const struct lys_module *m = NULL;
+
+ FIND_MODULE(struct lysc_import, mod, 1);
+ return m ? m->compiled : NULL;
+}
+
+struct lysp_module *
+lysp_module_find_prefix(const struct lysp_module *mod, const char *prefix, size_t len)
+{
+ const struct lys_module *m = NULL;
+
+ FIND_MODULE(struct lysp_import, mod, 1);
+ return m ? m->parsed : NULL;
+}
+
+struct lys_module *
+lys_module_find_prefix(const struct lys_module *mod, const char *prefix, size_t len)
+{
+ const struct lys_module *m = NULL;
+
+ if (mod->compiled) {
+ FIND_MODULE(struct lysc_import, mod->compiled, 1);
+ } else {
+ FIND_MODULE(struct lysp_import, mod->parsed, 2);
+ }
+ return (struct lys_module*)m;
+}
+
+const char *
+lys_nodetype2str(uint16_t nodetype)
+{
+ switch(nodetype) {
+ case LYS_CONTAINER:
+ return "container";
+ case LYS_CHOICE:
+ return "choice";
+ case LYS_LEAF:
+ return "leaf";
+ case LYS_LEAFLIST:
+ return "leaf-list";
+ case LYS_LIST:
+ return "list";
+ case LYS_ANYXML:
+ return "anyxml";
+ case LYS_ANYDATA:
+ return "anydata";
+ default:
+ return "unknown";
+ }
+}
+
+API const struct lysp_tpdf *
+lysp_node_typedefs(const struct lysp_node *node)
+{
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return ((struct lysp_node_container*)node)->typedefs;
+ case LYS_LIST:
+ return ((struct lysp_node_list*)node)->typedefs;
+ case LYS_GROUPING:
+ return ((struct lysp_grp*)node)->typedefs;
+ case LYS_ACTION:
+ return ((struct lysp_action*)node)->typedefs;
+ case LYS_INOUT:
+ return ((struct lysp_action_inout*)node)->typedefs;
+ case LYS_NOTIF:
+ return ((struct lysp_notif*)node)->typedefs;
+ default:
+ return NULL;
+ }
+}
+
+API const struct lysp_grp *
+lysp_node_groupings(const struct lysp_node *node)
+{
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return ((struct lysp_node_container*)node)->groupings;
+ case LYS_LIST:
+ return ((struct lysp_node_list*)node)->groupings;
+ case LYS_GROUPING:
+ return ((struct lysp_grp*)node)->groupings;
+ case LYS_ACTION:
+ return ((struct lysp_action*)node)->groupings;
+ case LYS_INOUT:
+ return ((struct lysp_action_inout*)node)->groupings;
+ case LYS_NOTIF:
+ return ((struct lysp_notif*)node)->groupings;
+ default:
+ return NULL;
+ }
+}
+
+struct lysp_action **
+lysp_node_actions_p(struct lysp_node *node)
+{
+ assert(node);
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return &((struct lysp_node_container*)node)->actions;
+ case LYS_LIST:
+ return &((struct lysp_node_list*)node)->actions;
+ case LYS_GROUPING:
+ return &((struct lysp_grp*)node)->actions;
+ case LYS_AUGMENT:
+ return &((struct lysp_augment*)node)->actions;
+ default:
+ return NULL;
+ }
+}
+
+API const struct lysp_action *
+lysp_node_actions(const struct lysp_node *node)
+{
+ struct lysp_action **actions;
+ actions = lysp_node_actions_p((struct lysp_node*)node);
+ if (actions) {
+ return *actions;
+ } else {
+ return NULL;
+ }
+}
+
+struct lysp_notif **
+lysp_node_notifs_p(struct lysp_node *node)
+{
+ assert(node);
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return &((struct lysp_node_container*)node)->notifs;
+ case LYS_LIST:
+ return &((struct lysp_node_list*)node)->notifs;
+ case LYS_GROUPING:
+ return &((struct lysp_grp*)node)->notifs;
+ case LYS_AUGMENT:
+ return &((struct lysp_augment*)node)->notifs;
+ default:
+ return NULL;
+ }
+}
+
+API const struct lysp_notif *
+lysp_node_notifs(const struct lysp_node *node)
+{
+ struct lysp_notif **notifs;
+ notifs = lysp_node_notifs_p((struct lysp_node*)node);
+ if (notifs) {
+ return *notifs;
+ } else {
+ return NULL;
+ }
+}
+
+struct lysp_node **
+lysp_node_children_p(struct lysp_node *node)
+{
+ assert(node);
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return &((struct lysp_node_container*)node)->child;
+ case LYS_CHOICE:
+ return &((struct lysp_node_choice*)node)->child;
+ case LYS_LIST:
+ return &((struct lysp_node_list*)node)->child;
+ case LYS_CASE:
+ return &((struct lysp_node_case*)node)->child;
+ case LYS_GROUPING:
+ return &((struct lysp_grp*)node)->data;
+ case LYS_AUGMENT:
+ return &((struct lysp_augment*)node)->child;
+ case LYS_INOUT:
+ return &((struct lysp_action_inout*)node)->data;
+ case LYS_NOTIF:
+ return &((struct lysp_notif*)node)->data;
+ default:
+ return NULL;
+ }
+}
+
+API const struct lysp_node *
+lysp_node_children(const struct lysp_node *node)
+{
+ struct lysp_node **children;
+ children = lysp_node_children_p((struct lysp_node*)node);
+ if (children) {
+ return *children;
+ } else {
+ return NULL;
+ }
+}
+
+struct lysc_action **
+lysc_node_actions_p(struct lysc_node *node)
+{
+ assert(node);
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return &((struct lysc_node_container*)node)->actions;
+ case LYS_LIST:
+ return &((struct lysc_node_list*)node)->actions;
+ default:
+ return NULL;
+ }
+}
+
+API const struct lysc_action *
+lysc_node_actions(const struct lysc_node *node)
+{
+ struct lysc_action **actions;
+ actions = lysc_node_actions_p((struct lysc_node*)node);
+ if (actions) {
+ return *actions;
+ } else {
+ return NULL;
+ }
+}
+
+struct lysc_notif **
+lysc_node_notifs_p(struct lysc_node *node)
+{
+ assert(node);
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return &((struct lysc_node_container*)node)->notifs;
+ case LYS_LIST:
+ return &((struct lysc_node_list*)node)->notifs;
+ default:
+ return NULL;
+ }
+}
+
+API const struct lysc_notif *
+lysc_node_notifs(const struct lysc_node *node)
+{
+ struct lysc_notif **notifs;
+ notifs = lysc_node_notifs_p((struct lysc_node*)node);
+ if (notifs) {
+ return *notifs;
+ } else {
+ return NULL;
+ }
+}
+
+struct lysc_node **
+lysc_node_children_p(const struct lysc_node *node)
+{
+ assert(node);
+ switch (node->nodetype) {
+ case LYS_CONTAINER:
+ return &((struct lysc_node_container*)node)->child;
+ case LYS_CHOICE:
+ if (((struct lysc_node_choice*)node)->cases) {
+ return &((struct lysc_node_choice*)node)->cases[0].child;
+ } else {
+ return NULL;
+ }
+ case LYS_LIST:
+ return &((struct lysc_node_list*)node)->child;
+/* TODO
+ case LYS_INOUT:
+ return &((struct lysc_action_inout*)node)->child;
+ case LYS_NOTIF:
+ return &((struct lysc_notif*)node)->child;
+*/
+ default:
+ return NULL;
+ }
+}
+
+API const struct lysc_node *
+lysc_node_children(const struct lysc_node *node)
+{
+ struct lysc_node **children;
+ children = lysc_node_children_p((struct lysc_node*)node);
+ if (children) {
+ return *children;
+ } else {
+ return NULL;
+ }
+}
+
+struct lys_module *
+lysp_find_module(struct ly_ctx *ctx, const struct lysp_module *mod)
+{
+ unsigned int u;
+
+ for (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 yang_keyword
-match_keyword(char *data)
+match_keyword(const char *data)
{
/* TODO make this function usable in get_keyword function */
-#define MOVE_INPUT(DATA, COUNT) (data)+=COUNT;
-#define IF_KW(STR, LEN, STMT) if (!strncmp((data), STR, LEN)) {MOVE_INPUT(data, LEN);kw=STMT;}
-#define IF_KW_PREFIX(STR, LEN) if (!strncmp((data), STR, LEN)) {MOVE_INPUT(data, LEN);
-#define IF_KW_PREFIX_END }
+#define MOVE_IN(DATA, COUNT) (data)+=COUNT;
+#define IF_KEYWORD(STR, LEN, STMT) if (!strncmp((data), STR, LEN)) {MOVE_IN(data, LEN);kw=STMT;}
+#define IF_KEYWORD_PREFIX(STR, LEN) if (!strncmp((data), STR, LEN)) {MOVE_IN(data, LEN);
+#define IF_KEYWORD_PREFIX_END }
enum yang_keyword kw = YANG_NONE;
/* read the keyword itself */
switch (*data) {
case 'a':
- MOVE_INPUT(data, 1);
- IF_KW("rgument", 7, YANG_ARGUMENT)
- else IF_KW("ugment", 6, YANG_AUGMENT)
- else IF_KW("ction", 5, YANG_ACTION)
- else IF_KW_PREFIX("ny", 2)
- IF_KW("data", 4, YANG_ANYDATA)
- else IF_KW("xml", 3, YANG_ANYXML)
- IF_KW_PREFIX_END
+ MOVE_IN(data, 1);
+ IF_KEYWORD("rgument", 7, YANG_ARGUMENT)
+ else IF_KEYWORD("ugment", 6, YANG_AUGMENT)
+ else IF_KEYWORD("ction", 5, YANG_ACTION)
+ else IF_KEYWORD_PREFIX("ny", 2)
+ IF_KEYWORD("data", 4, YANG_ANYDATA)
+ else IF_KEYWORD("xml", 3, YANG_ANYXML)
+ IF_KEYWORD_PREFIX_END
break;
case 'b':
- MOVE_INPUT(data, 1);
- IF_KW("ase", 3, YANG_BASE)
- else IF_KW("elongs-to", 9, YANG_BELONGS_TO)
- else IF_KW("it", 2, YANG_BIT)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("ase", 3, YANG_BASE)
+ else IF_KEYWORD("elongs-to", 9, YANG_BELONGS_TO)
+ else IF_KEYWORD("it", 2, YANG_BIT)
break;
case 'c':
- MOVE_INPUT(data, 1);
- IF_KW("ase", 3, YANG_CASE)
- else IF_KW("hoice", 5, YANG_CHOICE)
- else IF_KW_PREFIX("on", 2)
- IF_KW("fig", 3, YANG_CONFIG)
- else IF_KW_PREFIX("ta", 2)
- IF_KW("ct", 2, YANG_CONTACT)
- else IF_KW("iner", 4, YANG_CONTAINER)
- IF_KW_PREFIX_END
- IF_KW_PREFIX_END
+ MOVE_IN(data, 1);
+ IF_KEYWORD("ase", 3, YANG_CASE)
+ else IF_KEYWORD("hoice", 5, YANG_CHOICE)
+ else IF_KEYWORD_PREFIX("on", 2)
+ IF_KEYWORD("fig", 3, YANG_CONFIG)
+ else IF_KEYWORD_PREFIX("ta", 2)
+ IF_KEYWORD("ct", 2, YANG_CONTACT)
+ else IF_KEYWORD("iner", 4, YANG_CONTAINER)
+ IF_KEYWORD_PREFIX_END
+ IF_KEYWORD_PREFIX_END
break;
case 'd':
- MOVE_INPUT(data, 1);
- IF_KW_PREFIX("e", 1)
- IF_KW("fault", 5, YANG_DEFAULT)
- else IF_KW("scription", 9, YANG_DESCRIPTION)
- else IF_KW_PREFIX("viat", 4)
- IF_KW("e", 1, YANG_DEVIATE)
- else IF_KW("ion", 3, YANG_DEVIATION)
- IF_KW_PREFIX_END
- IF_KW_PREFIX_END
+ MOVE_IN(data, 1);
+ IF_KEYWORD_PREFIX("e", 1)
+ IF_KEYWORD("fault", 5, YANG_DEFAULT)
+ else IF_KEYWORD("scription", 9, YANG_DESCRIPTION)
+ else IF_KEYWORD_PREFIX("viat", 4)
+ IF_KEYWORD("e", 1, YANG_DEVIATE)
+ else IF_KEYWORD("ion", 3, YANG_DEVIATION)
+ IF_KEYWORD_PREFIX_END
+ IF_KEYWORD_PREFIX_END
break;
case 'e':
- MOVE_INPUT(data, 1);
- IF_KW("num", 3, YANG_ENUM)
- else IF_KW_PREFIX("rror-", 5)
- IF_KW("app-tag", 7, YANG_ERROR_APP_TAG)
- else IF_KW("message", 7, YANG_ERROR_MESSAGE)
- IF_KW_PREFIX_END
- else IF_KW("xtension", 8, YANG_EXTENSION)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("num", 3, YANG_ENUM)
+ else IF_KEYWORD_PREFIX("rror-", 5)
+ IF_KEYWORD("app-tag", 7, YANG_ERROR_APP_TAG)
+ else IF_KEYWORD("message", 7, YANG_ERROR_MESSAGE)
+ IF_KEYWORD_PREFIX_END
+ else IF_KEYWORD("xtension", 8, YANG_EXTENSION)
break;
case 'f':
- MOVE_INPUT(data, 1);
- IF_KW("eature", 6, YANG_FEATURE)
- else IF_KW("raction-digits", 14, YANG_FRACTION_DIGITS)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("eature", 6, YANG_FEATURE)
+ else IF_KEYWORD("raction-digits", 14, YANG_FRACTION_DIGITS)
break;
case 'g':
- MOVE_INPUT(data, 1);
- IF_KW("rouping", 7, YANG_GROUPING)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("rouping", 7, YANG_GROUPING)
break;
case 'i':
- MOVE_INPUT(data, 1);
- IF_KW("dentity", 7, YANG_IDENTITY)
- else IF_KW("f-feature", 9, YANG_IF_FEATURE)
- else IF_KW("mport", 5, YANG_IMPORT)
- else IF_KW_PREFIX("n", 1)
- IF_KW("clude", 5, YANG_INCLUDE)
- else IF_KW("put", 3, YANG_INPUT)
- IF_KW_PREFIX_END
+ MOVE_IN(data, 1);
+ IF_KEYWORD("dentity", 7, YANG_IDENTITY)
+ else IF_KEYWORD("f-feature", 9, YANG_IF_FEATURE)
+ else IF_KEYWORD("mport", 5, YANG_IMPORT)
+ else IF_KEYWORD_PREFIX("n", 1)
+ IF_KEYWORD("clude", 5, YANG_INCLUDE)
+ else IF_KEYWORD("put", 3, YANG_INPUT)
+ IF_KEYWORD_PREFIX_END
break;
case 'k':
- MOVE_INPUT(data, 1);
- IF_KW("ey", 2, YANG_KEY)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("ey", 2, YANG_KEY)
break;
case 'l':
- MOVE_INPUT(data, 1);
- IF_KW_PREFIX("e", 1)
- IF_KW("af-list", 7, YANG_LEAF_LIST)
- else IF_KW("af", 2, YANG_LEAF)
- else IF_KW("ngth", 4, YANG_LENGTH)
- IF_KW_PREFIX_END
- else IF_KW("ist", 3, YANG_LIST)
+ MOVE_IN(data, 1);
+ IF_KEYWORD_PREFIX("e", 1)
+ IF_KEYWORD("af-list", 7, YANG_LEAF_LIST)
+ else IF_KEYWORD("af", 2, YANG_LEAF)
+ else IF_KEYWORD("ngth", 4, YANG_LENGTH)
+ IF_KEYWORD_PREFIX_END
+ else IF_KEYWORD("ist", 3, YANG_LIST)
break;
case 'm':
- MOVE_INPUT(data, 1);
- IF_KW_PREFIX("a", 1)
- IF_KW("ndatory", 7, YANG_MANDATORY)
- else IF_KW("x-elements", 10, YANG_MAX_ELEMENTS)
- IF_KW_PREFIX_END
- else IF_KW("in-elements", 11, YANG_MIN_ELEMENTS)
- else IF_KW("ust", 3, YANG_MUST)
- else IF_KW_PREFIX("od", 2)
- IF_KW("ule", 3, YANG_MODULE)
- else IF_KW("ifier", 5, YANG_MODIFIER)
- IF_KW_PREFIX_END
+ MOVE_IN(data, 1);
+ IF_KEYWORD_PREFIX("a", 1)
+ IF_KEYWORD("ndatory", 7, YANG_MANDATORY)
+ else IF_KEYWORD("x-elements", 10, YANG_MAX_ELEMENTS)
+ IF_KEYWORD_PREFIX_END
+ else IF_KEYWORD("in-elements", 11, YANG_MIN_ELEMENTS)
+ else IF_KEYWORD("ust", 3, YANG_MUST)
+ else IF_KEYWORD_PREFIX("od", 2)
+ IF_KEYWORD("ule", 3, YANG_MODULE)
+ else IF_KEYWORD("ifier", 5, YANG_MODIFIER)
+ IF_KEYWORD_PREFIX_END
break;
case 'n':
- MOVE_INPUT(data, 1);
- IF_KW("amespace", 8, YANG_NAMESPACE)
- else IF_KW("otification", 11, YANG_NOTIFICATION)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("amespace", 8, YANG_NAMESPACE)
+ else IF_KEYWORD("otification", 11, YANG_NOTIFICATION)
break;
case 'o':
- MOVE_INPUT(data, 1);
- IF_KW_PREFIX("r", 1)
- IF_KW("dered-by", 8, YANG_ORDERED_BY)
- else IF_KW("ganization", 10, YANG_ORGANIZATION)
- IF_KW_PREFIX_END
- else IF_KW("utput", 5, YANG_OUTPUT)
+ MOVE_IN(data, 1);
+ IF_KEYWORD_PREFIX("r", 1)
+ IF_KEYWORD("dered-by", 8, YANG_ORDERED_BY)
+ else IF_KEYWORD("ganization", 10, YANG_ORGANIZATION)
+ IF_KEYWORD_PREFIX_END
+ else IF_KEYWORD("utput", 5, YANG_OUTPUT)
break;
case 'p':
- MOVE_INPUT(data, 1);
- IF_KW("ath", 3, YANG_PATH)
- else IF_KW("attern", 6, YANG_PATTERN)
- else IF_KW("osition", 7, YANG_POSITION)
- else IF_KW_PREFIX("re", 2)
- IF_KW("fix", 3, YANG_PREFIX)
- else IF_KW("sence", 5, YANG_PRESENCE)
- IF_KW_PREFIX_END
+ MOVE_IN(data, 1);
+ IF_KEYWORD("ath", 3, YANG_PATH)
+ else IF_KEYWORD("attern", 6, YANG_PATTERN)
+ else IF_KEYWORD("osition", 7, YANG_POSITION)
+ else IF_KEYWORD_PREFIX("re", 2)
+ IF_KEYWORD("fix", 3, YANG_PREFIX)
+ else IF_KEYWORD("sence", 5, YANG_PRESENCE)
+ IF_KEYWORD_PREFIX_END
break;
case 'r':
- MOVE_INPUT(data, 1);
- IF_KW("ange", 4, YANG_RANGE)
- else IF_KW_PREFIX("e", 1)
- IF_KW_PREFIX("f", 1)
- IF_KW("erence", 6, YANG_REFERENCE)
- else IF_KW("ine", 3, YANG_REFINE)
- IF_KW_PREFIX_END
- else IF_KW("quire-instance", 14, YANG_REQUIRE_INSTANCE)
- else IF_KW("vision-date", 11, YANG_REVISION_DATE)
- else IF_KW("vision", 6, YANG_REVISION)
- IF_KW_PREFIX_END
- else IF_KW("pc", 2, YANG_RPC)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("ange", 4, YANG_RANGE)
+ else IF_KEYWORD_PREFIX("e", 1)
+ IF_KEYWORD_PREFIX("f", 1)
+ IF_KEYWORD("erence", 6, YANG_REFERENCE)
+ else IF_KEYWORD("ine", 3, YANG_REFINE)
+ IF_KEYWORD_PREFIX_END
+ else IF_KEYWORD("quire-instance", 14, YANG_REQUIRE_INSTANCE)
+ else IF_KEYWORD("vision-date", 11, YANG_REVISION_DATE)
+ else IF_KEYWORD("vision", 6, YANG_REVISION)
+ IF_KEYWORD_PREFIX_END
+ else IF_KEYWORD("pc", 2, YANG_RPC)
break;
case 's':
- MOVE_INPUT(data, 1);
- IF_KW("tatus", 5, YANG_STATUS)
- else IF_KW("ubmodule", 8, YANG_SUBMODULE)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("tatus", 5, YANG_STATUS)
+ else IF_KEYWORD("ubmodule", 8, YANG_SUBMODULE)
break;
case 't':
- MOVE_INPUT(data, 1);
- IF_KW("ypedef", 6, YANG_TYPEDEF)
- else IF_KW("ype", 3, YANG_TYPE)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("ypedef", 6, YANG_TYPEDEF)
+ else IF_KEYWORD("ype", 3, YANG_TYPE)
break;
case 'u':
- MOVE_INPUT(data, 1);
- IF_KW_PREFIX("ni", 2)
- IF_KW("que", 3, YANG_UNIQUE)
- else IF_KW("ts", 2, YANG_UNITS)
- IF_KW_PREFIX_END
- else IF_KW("ses", 3, YANG_USES)
+ MOVE_IN(data, 1);
+ IF_KEYWORD_PREFIX("ni", 2)
+ IF_KEYWORD("que", 3, YANG_UNIQUE)
+ else IF_KEYWORD("ts", 2, YANG_UNITS)
+ IF_KEYWORD_PREFIX_END
+ else IF_KEYWORD("ses", 3, YANG_USES)
break;
case 'v':
- MOVE_INPUT(data, 1);
- IF_KW("alue", 4, YANG_VALUE)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("alue", 4, YANG_VALUE)
break;
case 'w':
- MOVE_INPUT(data, 1);
- IF_KW("hen", 3, YANG_WHEN)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("hen", 3, YANG_WHEN)
break;
case 'y':
- MOVE_INPUT(data, 1);
- IF_KW("ang-version", 11, YANG_YANG_VERSION)
- else IF_KW("in-element", 10, YANG_YIN_ELEMENT)
+ MOVE_IN(data, 1);
+ IF_KEYWORD("ang-version", 11, YANG_YANG_VERSION)
+ else IF_KEYWORD("in-element", 10, YANG_YIN_ELEMENT)
break;
case ';':
- MOVE_INPUT(data, 1);
+ MOVE_IN(data, 1);
kw = YANG_SEMICOLON;
//goto success;
break;
case '{':
- MOVE_INPUT(data, 1);
+ MOVE_IN(data, 1);
kw = YANG_LEFT_BRACE;
//goto success;
break;
case '}':
- MOVE_INPUT(data, 1);
+ MOVE_IN(data, 1);
kw = YANG_RIGHT_BRACE;
//goto success;
break;