parser xml CHANGE major refactorization
Completely new XML parser and also some
schema parser refactoring.
diff --git a/src/common.c b/src/common.c
index 0abfcd6..2372cee 100644
--- a/src/common.c
+++ b/src/common.c
@@ -183,9 +183,9 @@
}
LY_ERR
-ly_getutf8(const char **input, unsigned int *utf8_char, size_t *bytes_read)
+ly_getutf8(const char **input, uint32_t *utf8_char, size_t *bytes_read)
{
- unsigned int c, len;
+ uint32_t c, len;
int aux;
int i;
diff --git a/src/common.h b/src/common.h
index 2b58fbf..ab4aa13 100644
--- a/src/common.h
+++ b/src/common.h
@@ -304,6 +304,17 @@
* Generic useful functions.
*****************************************************************************/
+/**
+ * @brief Insert string into dictionary.
+ *
+ * @param[in] CTX libyang context.
+ * @param[in] STRING string to store.
+ * @param[in] LEN length of the string in WORD to store.
+ * @param[in,out] DYNAMIC Set to 1 if STR is dynamically allocated, 0 otherwise. If set to 1, zerocopy version of lydict_insert is used.
+ */
+#define INSERT_STRING(CTX, STRING, LEN, DYNAMIC) \
+ (DYNAMIC ? lydict_insert_zc(CTX, (char *)(STRING)) : lydict_insert(CTX, LEN ? (STRING) : "", LEN)); DYNAMIC = 0
+
#define FREE_STRING(CTX, STRING) if (STRING) {lydict_remove(CTX, STRING);}
/**
@@ -346,7 +357,7 @@
* @param[out] bytes_read Number of bytes used to encode the read utf8_char.
* @return LY_ERR value
*/
-LY_ERR ly_getutf8(const char **input, unsigned int *utf8_char, size_t *bytes_read);
+LY_ERR ly_getutf8(const char **input, uint32_t *utf8_char, size_t *bytes_read);
/**
* @brief Get number of characters in the @p str, taking multibyte characters into account.
diff --git a/src/context.h b/src/context.h
index a3c6366..53634cd 100644
--- a/src/context.h
+++ b/src/context.h
@@ -172,7 +172,7 @@
recursively). */
#define LY_CTX_PREFER_SEARCHDIRS 0x20 /**< When searching for schema, prefer searchdirs instead of user callback. */
-/**@} contextoptions */
+/** @} contextoptions */
/**
* @brief Create libyang context.
diff --git a/src/parser_stmt.c b/src/parser_stmt.c
index f282322..c9fe163 100644
--- a/src/parser_stmt.c
+++ b/src/parser_stmt.c
@@ -69,17 +69,17 @@
{
struct lysp_ext_instance *e;
- LY_ARRAY_NEW_RET(ctx->ctx, *exts, e, LY_EMEM);
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *exts, e, LY_EMEM);
/* store name and insubstmt info */
- e->name = lydict_insert(ctx->ctx, stmt->stmt, 0);
+ e->name = lydict_insert(PARSER_CTX(ctx), stmt->stmt, 0);
e->insubstmt = insubstmt;
e->insubstmt_index = insubstmt_index;
/* TODO (duplicate) e->child = stmt->child; */
/* get optional argument */
if (stmt->arg) {
- e->argument = lydict_insert(ctx->ctx, stmt->arg, 0);
+ e->argument = lydict_insert(PARSER_CTX(ctx), stmt->arg, 0);
}
return LY_SUCCESS;
@@ -111,7 +111,7 @@
}
LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
- *value = lydict_insert(ctx->ctx, stmt->arg, 0);
+ *value = lydict_insert(PARSER_CTX(ctx), stmt->arg, 0);
for (child = stmt->child; child; child = child->next) {
const char *s = child->stmt;
@@ -151,8 +151,8 @@
LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
/* allocate new pointer */
- LY_ARRAY_NEW_RET(ctx->ctx, *texts, item, LY_EMEM);
- *item = lydict_insert(ctx->ctx, stmt->arg, 0);
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *texts, item, LY_EMEM);
+ *item = lydict_insert(PARSER_CTX(ctx), stmt->arg, 0);
for (child = stmt->child; child; child = child->next) {
const char *s = child->stmt;
@@ -236,7 +236,7 @@
const struct lysp_stmt *child;
LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
- restr->arg = lydict_insert(ctx->ctx, stmt->arg, 0);
+ restr->arg = lydict_insert(PARSER_CTX(ctx), stmt->arg, 0);
for (child = stmt->child; child; child = child->next) {
const char *s = child->stmt;
@@ -281,7 +281,7 @@
{
struct lysp_restr *restr;
- LY_ARRAY_NEW_RET(ctx->ctx, *restrs, restr, LY_EMEM);
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *restrs, restr, LY_EMEM);
return lysp_stmt_restr(ctx, stmt, restr_kw, restr);
}
@@ -387,13 +387,13 @@
LY_CHECK_RET(lysp_stmt_validate_value(ctx, enum_kw == LY_STMT_ENUM ? Y_STR_ARG : Y_IDENTIF_ARG, stmt->arg));
- LY_ARRAY_NEW_RET(ctx->ctx, *enums, enm, LY_EMEM);
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *enums, enm, LY_EMEM);
if (enum_kw == LY_STMT_ENUM) {
LY_CHECK_RET(lysp_check_enum_name(ctx, stmt->arg, strlen(stmt->arg)));
} /* else nothing specific for YANG_BIT */
- enm->name = lydict_insert(ctx->ctx, stmt->arg, 0);
+ enm->name = lydict_insert(PARSER_CTX(ctx), stmt->arg, 0);
CHECK_UNIQUENESS(ctx, *enums, name, ly_stmt2str(enum_kw), enm->name);
for (child = stmt->child; child; child = child->next) {
@@ -574,13 +574,13 @@
/* replace the value in the dictionary */
buf = malloc(strlen(*pat) + 1);
- LY_CHECK_ERR_RET(!buf, LOGMEM(ctx->ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
strcpy(buf, *pat);
- lydict_remove(ctx->ctx, *pat);
+ lydict_remove(PARSER_CTX(ctx), *pat);
assert(buf[0] == 0x06);
buf[0] = 0x15;
- *pat = lydict_insert_zc(ctx->ctx, buf);
+ *pat = lydict_insert_zc(PARSER_CTX(ctx), buf);
for (child = stmt->child; child; child = child->next) {
const char *s = child->stmt;
@@ -616,16 +616,16 @@
struct lysp_restr *restr;
LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
- LY_ARRAY_NEW_RET(ctx->ctx, *patterns, restr, LY_EMEM);
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *patterns, restr, LY_EMEM);
arg_len = strlen(stmt->arg);
/* add special meaning first byte */
buf = malloc(arg_len + 2);
- LY_CHECK_ERR_RET(!buf, LOGMEM(ctx->ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
memmove(buf + 1, stmt->arg, arg_len);
buf[0] = 0x06; /* pattern's default regular-match flag */
buf[arg_len + 1] = '\0'; /* terminating NULL byte */
- restr->arg = lydict_insert_zc(ctx->ctx, buf);
+ restr->arg = lydict_insert_zc(PARSER_CTX(ctx), buf);
for (child = stmt->child; child; child = child->next) {
const char *s = child->stmt;
@@ -678,7 +678,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "type");
return LY_EVALID;
}
- type->name = lydict_insert(ctx->ctx, stmt->arg, 0);
+ type->name = lydict_insert(PARSER_CTX(ctx), stmt->arg, 0);
for (child = stmt->child; child; child = child->next) {
const char *s = child->stmt;
@@ -707,7 +707,7 @@
return LY_EVALID;
}
type->length = calloc(1, sizeof *type->length);
- LY_CHECK_ERR_RET(!type->length, LOGMEM(ctx->ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!type->length, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
LY_CHECK_RET(lysp_stmt_restr(ctx, child, kw, type->length));
type->flags |= LYS_SET_LENGTH;
@@ -726,7 +726,7 @@
return LY_EVALID;
}
type->range = calloc(1, sizeof *type->range);
- LY_CHECK_ERR_RET(!type->range, LOGMEM(ctx->ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!type->range, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
LY_CHECK_RET(lysp_stmt_restr(ctx, child, kw, type->range));
type->flags |= LYS_SET_RANGE;
@@ -736,7 +736,7 @@
/* LYS_SET_REQINST checked and set inside parse_type_reqinstance() */
break;
case LY_STMT_TYPE:
- LY_ARRAY_NEW_RET(ctx->ctx, type->types, nest_type, LY_EMEM);
+ LY_ARRAY_NEW_RET(PARSER_CTX(ctx), type->types, nest_type, LY_EMEM);
LY_CHECK_RET(lysp_stmt_type(ctx, child, nest_type));
type->flags |= LYS_SET_TYPE;
break;
@@ -755,8 +755,9 @@
lysp_stmt_parse(struct lysc_ctx *ctx, const struct lysp_stmt *stmt, enum ly_stmt kw, void **result, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- struct lys_parser_ctx pctx = {0};
+ struct lys_yang_parser_ctx pctx = {0};
+ pctx.format = LYS_IN_YANG;
pctx.ctx = ctx->ctx;
pctx.mod_version = ctx->mod->version;
pctx.pos_type = LY_VLOG_STR;
@@ -764,14 +765,14 @@
switch(kw) {
case LY_STMT_STATUS: {
- ret = lysp_stmt_status(&pctx, stmt, *(uint16_t**)result, exts);
+ ret = lysp_stmt_status((struct lys_parser_ctx *)&pctx, stmt, *(uint16_t**)result, exts);
break;
}
case LY_STMT_TYPE: {
struct lysp_type *type;
type = calloc(1, sizeof *type);
- ret = lysp_stmt_type(&pctx, stmt, type);
+ ret = lysp_stmt_type((struct lys_parser_ctx *)&pctx, stmt, type);
(*result) = type;
break;
}
diff --git a/src/parser_xml.c b/src/parser_xml.c
index e05f170..792d377 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -31,16 +31,10 @@
#include "validation.h"
/**
- * @brief internal context for XML YANG data parser.
- *
- * The leading part is compatible with the struct lyxml_context
+ * @brief Internal context for XML YANG data parser.
*/
struct lyd_xml_ctx {
- struct ly_ctx *ctx; /**< libyang context */
- uint64_t line; /**< number of the line being currently processed */
- enum LYXML_PARSER_STATUS status; /**< status providing information about the next expected object in input data */
- struct ly_set elements; /**< list of not-yet-closed elements */
- struct ly_set ns; /**< handled with LY_SET_OPT_USEASLIST */
+ struct lyxml_ctx *xmlctx; /**< XML context */
uint32_t options; /**< various @ref dataparseroptions. */
uint32_t path_len; /**< used bytes in the path buffer */
@@ -52,14 +46,14 @@
};
/**
- * @brief XML-parser's implementation of ly_type_resolve_prefix() callback to provide mapping between prefixes used in the values to the schema
- * via XML namespaces.
+ * @brief XML-parser's implementation of ly_type_resolve_prefix() callback to provide mapping between prefixes used
+ * in the values to the schema via XML namespaces.
*/
static const struct lys_module *
lydxml_resolve_prefix(const struct ly_ctx *ctx, const char *prefix, size_t prefix_len, void *parser)
{
const struct lyxml_ns *ns;
- struct lyxml_context *xmlctx = (struct lyxml_context*)parser;
+ struct lyxml_ctx *xmlctx = (struct lyxml_ctx *)parser;
ns = lyxml_ns_get(xmlctx, prefix, prefix_len);
if (!ns) {
@@ -69,101 +63,41 @@
return ly_ctx_get_module_implemented_ns(ctx, ns->uri);
}
-struct attr_data_s {
- const char *prefix;
- const char *name;
- char *value;
- size_t prefix_len;
- size_t name_len;
- size_t value_len;
- int dynamic;
-};
-
-/**
- * @brief Parse XML attributes of the XML element of YANG data.
- *
- * @param[in] xmlctx XML parser context.
- * @param[in,out] data Pointer to the XML string representation of the YANG data to parse.
- * @param[out] attributes Resulting list of the parsed attributes. XML namespace definitions are not parsed
- * as attributes, they are stored internally in the parser context.
- * @reutn LY_ERR value.
- */
static LY_ERR
-lydxml_attributes_parse(struct lyxml_context *xmlctx, const char **data, struct ly_set *attrs_data)
+lydxml_metadata(struct lyxml_ctx *xmlctx, const struct lysc_node *sparent, int strict, struct ly_set *type_meta_check,
+ struct lyd_meta **meta)
{
- LY_ERR ret = LY_SUCCESS;
- unsigned int u;
- const char *prefix, *name;
- size_t prefix_len, name_len;
- struct attr_data_s *attr_data;
-
- while (xmlctx->status == LYXML_ATTRIBUTE &&
- lyxml_get_attribute(xmlctx, data, &prefix, &prefix_len, &name, &name_len) == LY_SUCCESS) {
- char *buffer = NULL;
- size_t buffer_size = 0;
-
- if (!name) {
- /* seems like all the attrributes were internally processed as namespace definitions */
- continue;
- }
-
- /* auxiliary store the prefix information and value string, because we have to wait with resolving prefix
- * to the time when all the namespaces, defined in this element, are parsed. With the prefix we can find the
- * annotation definition for the attribute and correctly process the value */
- attr_data = malloc(sizeof *attr_data);
- attr_data->prefix = prefix;
- attr_data->name = name;
- attr_data->prefix_len = prefix_len;
- attr_data->name_len = name_len;
- ret = lyxml_get_string(xmlctx, data, &buffer, &buffer_size, &attr_data->value, &attr_data->value_len, &attr_data->dynamic);
- LY_CHECK_ERR_GOTO(ret, free(attr_data), error);
- ly_set_add(attrs_data, attr_data, LY_SET_OPT_USEASLIST);
- }
-
- return LY_SUCCESS;
-
-error:
- for (u = 0; u < attrs_data->count; ++u) {
- if (((struct attr_data_s*)attrs_data->objs[u])->dynamic) {
- free(((struct attr_data_s*)attrs_data->objs[u])->value);
- }
- }
- ly_set_erase(attrs_data, free);
- return ret;
-}
-
-static LY_ERR
-lydxml_metadata(struct lyxml_context *xmlctx, struct ly_set *attrs_data, const struct lysc_node *sparent, int strict,
- struct ly_set *type_meta_check, struct lyd_meta **meta)
-{
- LY_ERR ret = LY_EVALID, rc;
+ LY_ERR ret = LY_EVALID;
const struct lyxml_ns *ns;
struct lys_module *mod;
+ const char *name;
+ size_t name_len;
- for (unsigned int u = 0; u < attrs_data->count; ++u) {
- struct attr_data_s *attr_data = (struct attr_data_s*)attrs_data->objs[u];
+ *meta = NULL;
- if (!attr_data->prefix_len) {
+ while (xmlctx->status == LYXML_ATTRIBUTE) {
+ if (!xmlctx->prefix_len) {
/* in XML, all attributes must be prefixed
* TODO exception for NETCONF filters which are supposed to map to the ietf-netconf without prefix */
if (strict) {
LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Missing mandatory prefix for XML metadata \"%.*s\".",
- attr_data->name_len, attr_data->name);
+ xmlctx->name_len, xmlctx->name);
+ goto cleanup;
}
+
skip_attr:
- if (attr_data->dynamic) {
- free(attr_data->value);
- attr_data->dynamic = 0;
- }
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ assert(xmlctx->status == LYXML_ATTR_CONTENT);
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
continue;
}
/* get namespace of the attribute to find its annotation definition */
- ns = lyxml_ns_get(xmlctx, attr_data->prefix, attr_data->prefix_len);
+ ns = lyxml_ns_get(xmlctx, xmlctx->prefix, xmlctx->prefix_len);
if (!ns) {
/* unknown namespace, XML error */
LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
- attr_data->prefix_len, attr_data->prefix);
+ xmlctx->prefix_len, xmlctx->prefix);
goto cleanup;
}
mod = ly_ctx_get_module_implemented_ns(xmlctx->ctx, ns->uri);
@@ -172,57 +106,65 @@
if (strict) {
LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE,
"Unknown (or not implemented) YANG module with namespace \"%s\" for metadata \"%.*s%s%.*s\".",
- ns, attr_data->prefix_len, attr_data->prefix, attr_data->prefix_len ? ":" : "", attr_data->name_len,
- attr_data->name);
+ ns->uri, xmlctx->prefix_len, xmlctx->prefix, xmlctx->prefix_len ? ":" : "", xmlctx->name_len,
+ xmlctx->name);
+ goto cleanup;
}
goto skip_attr;
}
- rc = lyd_create_meta(NULL, meta, mod, attr_data->name, attr_data->name_len, attr_data->value, attr_data->value_len,
- &attr_data->dynamic, lydxml_resolve_prefix, xmlctx, LYD_XML, sparent);
- if (rc == LY_EINCOMPLETE) {
+ /* remember attr name and get its content */
+ name = xmlctx->name;
+ name_len = xmlctx->name_len;
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ assert(xmlctx->status == LYXML_ATTR_CONTENT);
+
+ /* create metadata */
+ ret = lyd_create_meta(NULL, meta, mod, name, name_len, xmlctx->value, xmlctx->value_len, &xmlctx->dynamic,
+ lydxml_resolve_prefix, xmlctx, LYD_XML, sparent);
+ if (ret == LY_EINCOMPLETE) {
if (type_meta_check) {
ly_set_add(type_meta_check, meta, LY_SET_OPT_USEASLIST);
}
- } else if (rc) {
- ret = rc;
+ } else if (ret) {
goto cleanup;
}
+
+ /* next attribute */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
}
ret = LY_SUCCESS;
cleanup:
- for (unsigned int u = 0; u < attrs_data->count; ++u) {
- if (((struct attr_data_s*)attrs_data->objs[u])->dynamic) {
- free(((struct attr_data_s*)attrs_data->objs[u])->value);
- }
+ if (ret) {
+ lyd_free_meta(xmlctx->ctx, *meta, 1);
+ *meta = NULL;
}
- ly_set_erase(attrs_data, free);
-
return ret;
}
static LY_ERR
-lydxml_attrs(struct lyxml_context *xmlctx, struct ly_set *attrs_data, struct ly_attr **attr)
+lydxml_attrs(struct lyxml_ctx *xmlctx, struct ly_attr **attr)
{
LY_ERR ret = LY_SUCCESS;
const struct lyxml_ns *ns;
struct ly_prefix *val_prefs;
struct ly_attr *attr2;
+ const char *name, *prefix;
+ size_t name_len, prefix_len;
assert(attr);
+ *attr = NULL;
- for (unsigned int u = 0; u < attrs_data->count; ++u) {
- struct attr_data_s *attr_data = (struct attr_data_s *)attrs_data->objs[u];
-
+ while (xmlctx->status == LYXML_ATTRIBUTE) {
ns = NULL;
- if (attr_data->prefix_len) {
+ if (xmlctx->prefix_len) {
/* get namespace of the attribute */
- ns = lyxml_ns_get(xmlctx, attr_data->prefix, attr_data->prefix_len);
+ ns = lyxml_ns_get(xmlctx, xmlctx->prefix, xmlctx->prefix_len);
if (!ns) {
LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
- attr_data->prefix_len, attr_data->prefix);
+ xmlctx->prefix_len, xmlctx->prefix);
ret = LY_EVALID;
goto cleanup;
}
@@ -234,42 +176,46 @@
attr2 = NULL;
}
+ /* remember attr prefix, name, and get its content */
+ prefix = xmlctx->prefix;
+ prefix_len = xmlctx->prefix_len;
+ name = xmlctx->name;
+ name_len = xmlctx->name_len;
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ assert(xmlctx->status == LYXML_ATTR_CONTENT);
+
/* get value prefixes */
- ret = lyxml_get_prefixes(xmlctx, attr_data->value, attr_data->value_len, &val_prefs);
- LY_CHECK_GOTO(ret, cleanup);
+ LY_CHECK_GOTO(ret = lyxml_get_prefixes(xmlctx, xmlctx->value, xmlctx->value_len, &val_prefs), cleanup);
/* attr2 is always changed to the created attribute */
- ret = ly_create_attr(NULL, &attr2, xmlctx->ctx, attr_data->name, attr_data->name_len, attr_data->value,
- attr_data->value_len, &attr_data->dynamic, LYD_XML, val_prefs, attr_data->prefix,
- attr_data->prefix_len, ns ? ns->uri : NULL);
+ ret = ly_create_attr(NULL, &attr2, xmlctx->ctx, name, name_len, xmlctx->value, xmlctx->value_len,
+ &xmlctx->dynamic, LYD_XML, val_prefs, prefix, prefix_len, ns ? ns->uri : NULL);
LY_CHECK_GOTO(ret, cleanup);
if (!*attr) {
*attr = attr2;
}
+
+ /* next attribute */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
}
cleanup:
- for (unsigned int u = 0; u < attrs_data->count; ++u) {
- if (((struct attr_data_s *)attrs_data->objs[u])->dynamic) {
- free(((struct attr_data_s *)attrs_data->objs[u])->value);
- }
+ if (ret) {
+ ly_free_attr(xmlctx->ctx, *attr, 1);
+ *attr = NULL;
}
- ly_set_erase(attrs_data, free);
return ret;
}
static LY_ERR
-lydxml_check_list(struct lyxml_context *xmlctx, const struct lysc_node *list, const char **data)
+lydxml_check_list(struct lyxml_ctx *xmlctx, const struct lysc_node *list)
{
- LY_ERR ret;
+ LY_ERR ret = LY_SUCCESS, r;
+ enum LYXML_PARSER_STATUS next;
struct ly_set key_set = {0};
const struct lysc_node *snode;
- const char *name;
- char *buffer = NULL, *value;
- size_t name_len, buffer_size = 0, value_len;
- int dynamic = 0;
- uint32_t i, parents_count = xmlctx->elements.count;
+ uint32_t i, parents_count;
assert(list && (list->nodetype == LYS_LIST));
@@ -279,64 +225,53 @@
ly_set_add(&key_set, (void *)snode, LY_SET_OPT_USEASLIST);
}
- while ((xmlctx->status == LYXML_ELEMENT) && key_set.count) {
- /* keys must be from the same module */
- LY_CHECK_GOTO(ret = lyxml_get_element(xmlctx, data, NULL, NULL, &name, &name_len), cleanup);
- if (!name) {
- /* closing previous element */
- if (xmlctx->elements.count < parents_count) {
- /* all siblings parsed */
- break;
- } else {
- continue;
- }
- }
-
+ while (xmlctx->status == LYXML_ELEMENT) {
/* find key definition */
for (i = 0; i < key_set.count; ++i) {
snode = (const struct lysc_node *)key_set.objs[i];
- if (!ly_strncmp(snode->name, name, name_len)) {
+ if (!ly_strncmp(snode->name, xmlctx->name, xmlctx->name_len)) {
break;
}
}
- if (i == key_set.count) {
- /* uninteresting, skip it */
- LY_CHECK_GOTO(ret = lyxml_skip_element(xmlctx, data), cleanup);
- continue;
- }
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
/* skip attributes */
while (xmlctx->status == LYXML_ATTRIBUTE) {
- LY_CHECK_GOTO(ret = lyxml_get_attribute(xmlctx, data, NULL, NULL, NULL, NULL), cleanup);
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ assert(xmlctx->status == LYXML_ATTR_CONTENT);
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
}
- /* get the value, if any */
- if (dynamic) {
- free(value);
- }
- value = "";
- value_len = 0;
- dynamic = 0;
- if (xmlctx->status == LYXML_ELEM_CONTENT) {
- ret = lyxml_get_string(xmlctx, data, &buffer, &buffer_size, &value, &value_len, &dynamic);
- if (ret && (ret != LY_EINVAL)) {
- goto cleanup;
+ assert(xmlctx->status == LYXML_ELEM_CONTENT);
+ if (i < key_set.count) {
+ /* validate the value */
+ r = lys_value_validate(NULL, snode, xmlctx->value, xmlctx->value_len, lydxml_resolve_prefix, xmlctx, LYD_XML);
+ if (!r) {
+ /* key with a valid value, remove from the set */
+ ly_set_rm_index(&key_set, i, NULL);
}
}
- /* validate it */
- LY_CHECK_GOTO(ret = lys_value_validate(NULL, snode, value, value_len, lydxml_resolve_prefix, xmlctx->ctx, LYD_XML), cleanup);
+ /* parser next */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
- /* key with a valid value, remove from the set */
- ly_set_rm_index(&key_set, i, NULL);
+ /* skip any children, resursively */
+ parents_count = xmlctx->elements.count;
+ while ((parents_count < xmlctx->elements.count) || (xmlctx->status == LYXML_ELEMENT)) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ }
+
+ /* parser next, but do not parse closing element of the list because it would remove its namespaces */
+ assert(xmlctx->status == LYXML_ELEM_CLOSE);
+ LY_CHECK_GOTO(ret = lyxml_ctx_peek(xmlctx, &next), cleanup);
+ if (next != LYXML_ELEM_CLOSE) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ }
}
if (key_set.count) {
- /* some keys missing */
+ /* some keys are missing/did not validate */
ret = LY_ENOT;
- } else {
- /* all keys found and validated */
- ret = LY_SUCCESS;
}
cleanup:
@@ -347,83 +282,95 @@
/**
* @brief Parse XML elements as YANG data node children the specified parent node.
*
- * @param[in] ctx XML YANG data parser context.
+ * @param[in] lydctx XML YANG data parser context.
* @param[in] parent Parent node where the children are inserted. NULL in case of parsing top-level elements.
* @param[in,out] data Pointer to the XML string representation of the YANG data to parse.
* @param[out] node Resulting list of the parsed nodes.
* @return LY_ERR value.
*/
static LY_ERR
-lydxml_data_r(struct lyd_xml_ctx *ctx, struct lyd_node_inner *parent, const char **data, struct lyd_node **first)
+lydxml_data_r(struct lyd_xml_ctx *lydctx, struct lyd_node_inner *parent, const char **data, struct lyd_node **first)
{
- LY_ERR ret = LY_SUCCESS, content_ret;
- const char *prefix, *name, *backup_data;
- char *buffer = NULL, *value;
- size_t prefix_len, name_len, buffer_size = 0, value_len;
- struct ly_set attrs_data = {0};
- struct lyxml_context backup_ctx;
+ LY_ERR ret = LY_SUCCESS;
+ enum LYXML_PARSER_STATUS prev_status;
+ const char *prefix, *name, *prev_input, *pname, *pprefix;
+ size_t prefix_len, name_len, pprefix_len, pname_len;
+ struct lyxml_ctx *xmlctx;
+ const struct ly_ctx *ctx;
const struct lyxml_ns *ns;
struct lyd_meta *meta = NULL, *meta2, *prev_meta;
struct ly_attr *attr = NULL;
const struct lysc_node *snode;
struct lys_module *mod;
- uint32_t prev_opts, parents_count = ctx->elements.count;
+ uint32_t prev_opts, parents_count;
struct lyd_node *cur = NULL, *anchor;
struct ly_prefix *val_prefs;
- int dynamic = 0;
- while (ctx->status == LYXML_ELEMENT) {
- ret = lyxml_get_element((struct lyxml_context *)ctx, data, &prefix, &prefix_len, &name, &name_len);
- LY_CHECK_GOTO(ret, cleanup);
- if (!name) {
- /* closing previous element */
- if (ctx->elements.count < parents_count) {
- /* all siblings parsed */
- break;
- } else {
- continue;
- }
- }
+ xmlctx = lydctx->xmlctx;
+ ctx = xmlctx->ctx;
- if (ctx->status == LYXML_ATTRIBUTE) {
- /* first parse all attributes so we have all the namespaces available */
- if (lydxml_attributes_parse((struct lyxml_context *)ctx, data, &attrs_data) != LY_SUCCESS) {
- ret = LY_EVALID;
- goto cleanup;
- }
- }
+ while (xmlctx->status == LYXML_ELEMENT) {
+ /* remember element prefix and name */
+ prefix = xmlctx->prefix;
+ prefix_len = xmlctx->prefix_len;
+ name = xmlctx->name;
+ name_len = xmlctx->name_len;
- ns = lyxml_ns_get((struct lyxml_context *)ctx, prefix, prefix_len);
+ /* get the element module */
+ ns = lyxml_ns_get(xmlctx, prefix, prefix_len);
if (!ns) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", prefix_len, prefix);
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
+ prefix_len, prefix);
ret = LY_EVALID;
goto cleanup;
}
- mod = ly_ctx_get_module_implemented_ns(ctx->ctx, ns->uri);
- if (!mod && (ctx->options & LYD_OPT_STRICT)) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE, "No module with namespace \"%s\" in the context.", ns->uri);
+ mod = ly_ctx_get_module_implemented_ns(ctx, ns->uri);
+ if (!mod && (lydctx->options & LYD_OPT_STRICT)) {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "No module with namespace \"%s\" in the context.", ns->uri);
ret = LY_EVALID;
goto cleanup;
}
+ /* get the schema node */
snode = NULL;
if (mod && (!parent || parent->schema)) {
/* leave if-feature check for validation */
snode = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, LYS_GETNEXT_NOSTATECHECK);
- if (!snode && (ctx->options & LYD_OPT_STRICT)) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE, "Element \"%.*s\" not found in the \"%s\" module.",
- name_len, name, mod->name);
- ret = LY_EVALID;
- goto cleanup;
+ if (!snode) {
+ if (lydctx->options & LYD_OPT_STRICT) {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Element \"%.*s\" not found in the \"%s\" module.",
+ name_len, name, mod->name);
+ ret = LY_EVALID;
+ goto cleanup;
+ } else if (!(lydctx->options & LYD_OPT_OPAQ)) {
+ /* remember current number of parents */
+ parents_count = xmlctx->elements.count;
+
+ /* skip after the content */
+ while (xmlctx->status != LYXML_ELEM_CONTENT) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ }
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+
+ /* skip all children elements, recursively, if any */
+ while (parents_count < xmlctx->elements.count) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ }
+
+ /* close element */
+ assert(xmlctx->status == LYXML_ELEM_CLOSE);
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ continue;
+ }
}
if (snode) {
- if ((ctx->options & LYD_OPT_NO_STATE) && (snode->flags & LYS_CONFIG_R)) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LY_VCODE_INSTATE, snode->name);
+ if ((lydctx->options & LYD_OPT_NO_STATE) && (snode->flags & LYS_CONFIG_R)) {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTATE, snode->name);
ret = LY_EVALID;
goto cleanup;
}
if (snode->nodetype & (LYS_ACTION | LYS_NOTIF)) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_DATA, "Unexpected %s element \"%.*s\".",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_DATA, "Unexpected %s element \"%.*s\".",
snode->nodetype == LYS_ACTION ? "RPC/action" : "notification", name_len, name);
ret = LY_EVALID;
goto cleanup;
@@ -431,108 +378,101 @@
}
}
- /* get the value, if any */
- value = "";
- value_len = 0;
- dynamic = 0;
- content_ret = LY_SUCCESS;
- if (ctx->status == LYXML_ELEM_CONTENT) {
- content_ret = lyxml_get_string((struct lyxml_context *)ctx, data, &buffer, &buffer_size, &value, &value_len, &dynamic);
- if (content_ret && (content_ret != LY_EINVAL)) {
- LOGINT(ctx->ctx);
- ret = LY_EINT;
- goto cleanup;
- }
- }
+ /* parser next */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
- if (snode && (ctx->options & LYD_OPT_OPAQ)) {
+ if (snode && (lydctx->options & LYD_OPT_OPAQ) && (snode->nodetype & (LYD_NODE_TERM | LYS_LIST))) {
+ /* backup parser */
+ prev_status = xmlctx->status;
+ pprefix = xmlctx->prefix;
+ pprefix_len = xmlctx->prefix_len;
+ pname = xmlctx->name;
+ pname_len = xmlctx->name_len;
+ prev_input = xmlctx->input;
+ if ((xmlctx->status == LYXML_ELEM_CONTENT) && xmlctx->dynamic) {
+ /* it was backed up, do not free */
+ xmlctx->dynamic = 0;
+ }
+
+ /* skip attributes */
+ while (xmlctx->status == LYXML_ATTRIBUTE) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+ }
+
if (snode->nodetype & LYD_NODE_TERM) {
/* value may not be valid in which case we parse it as an opaque node */
- if (lys_value_validate(NULL, snode, value, value_len, lydxml_resolve_prefix, ctx, LYD_XML)) {
+ if (lys_value_validate(NULL, snode, xmlctx->value, xmlctx->value_len, lydxml_resolve_prefix, xmlctx, LYD_XML)) {
snode = NULL;
}
- } else if (snode->nodetype == LYS_LIST) {
- /* use backup context and data pointer */
- backup_ctx.ctx = ctx->ctx;
- backup_ctx.line = ctx->line;
- backup_ctx.status = ctx->status;
- memset(&backup_ctx.elements, 0, sizeof backup_ctx.elements);
- for (uint32_t i = 0; i < ctx->elements.count; ++i) {
- ly_set_add(&backup_ctx.elements, lyxml_elem_dup(ctx->elements.objs[i]), LY_SET_OPT_USEASLIST);
- }
- memset(&backup_ctx.ns, 0, sizeof backup_ctx.ns);
- for (uint32_t i = 0; i < ctx->ns.count; ++i) {
- ly_set_add(&backup_ctx.ns, lyxml_ns_dup(ctx->ns.objs[i]), LY_SET_OPT_USEASLIST);
- }
- backup_data = *data;
+ } else {
+ /* skip content */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
- /* list may be missing some keys, parse as opaque if it does */
- if (lydxml_check_list(&backup_ctx, snode, &backup_data)) {
+ if (lydxml_check_list(xmlctx, snode)) {
+ /* invalid list, parse as opaque if it does */
snode = NULL;
}
-
- lyxml_context_clear(&backup_ctx);
}
+
+ /* restore parser */
+ if (xmlctx->dynamic) {
+ free((char *)xmlctx->value);
+ }
+ xmlctx->status = prev_status;
+ xmlctx->prefix = pprefix;
+ xmlctx->prefix_len = pprefix_len;
+ xmlctx->name = pname;
+ xmlctx->name_len = pname_len;
+ xmlctx->input = prev_input;
}
- /* create actual metadata so that prefixes are available in the context */
- if (attrs_data.count) {
+ /* create metadata/attributes */
+ if (xmlctx->status == LYXML_ATTRIBUTE) {
if (snode) {
- ret = lydxml_metadata((struct lyxml_context *)ctx, &attrs_data, snode, ctx->options & LYD_OPT_STRICT,
- &ctx->unres_meta_type, &meta);
- LY_CHECK_GOTO(ret, cleanup);
- } else if (ctx->options & LYD_OPT_OPAQ) {
- ret = lydxml_attrs((struct lyxml_context *)ctx, &attrs_data, &attr);
+ ret = lydxml_metadata(xmlctx, snode, lydctx->options & LYD_OPT_STRICT, &lydctx->unres_meta_type, &meta);
LY_CHECK_GOTO(ret, cleanup);
} else {
- /* free attr data */
- for (uint32_t u = 0; u < attrs_data.count; ++u) {
- if (((struct attr_data_s*)attrs_data.objs[u])->dynamic) {
- free(((struct attr_data_s*)attrs_data.objs[u])->value);
- }
- }
- ly_set_erase(&attrs_data, free);
+ assert(lydctx->options & LYD_OPT_OPAQ);
+ ret = lydxml_attrs(xmlctx, &attr);
+ LY_CHECK_GOTO(ret, cleanup);
}
}
+ assert(xmlctx->status == LYXML_ELEM_CONTENT);
if (!snode) {
- if (ctx->options & LYD_OPT_OPAQ) {
- /* get value prefixes */
- ret = lyxml_get_prefixes((struct lyxml_context *)ctx, value, value_len, &val_prefs);
- LY_CHECK_GOTO(ret, cleanup);
+ assert(lydctx->options & LYD_OPT_OPAQ);
- /* create node */
- ret = lyd_create_opaq(ctx->ctx, name, name_len, value, value_len, &dynamic, LYD_XML, val_prefs, prefix,
- prefix_len, ns->uri, &cur);
- LY_CHECK_GOTO(ret, cleanup);
-
- /* process children */
- if (ctx->status == LYXML_ELEMENT && parents_count != ctx->elements.count) {
- ret = lydxml_data_r(ctx, (struct lyd_node_inner *)cur, data, lyd_node_children_p(cur));
- LY_CHECK_GOTO(ret, cleanup);
- }
+ if (xmlctx->ws_only) {
+ /* ignore WS-only value */
+ xmlctx->value_len = 0;
+ val_prefs = NULL;
} else {
- /* skip element */
- ret = lyxml_skip_element((struct lyxml_context *)ctx, data);
+ /* get value prefixes */
+ ret = lyxml_get_prefixes(xmlctx, xmlctx->value, xmlctx->value_len, &val_prefs);
LY_CHECK_GOTO(ret, cleanup);
- break;
- }
- } else if (snode->nodetype & LYD_NODE_TERM) {
- if (content_ret == LY_EINVAL) {
- /* just indentation of a child element found */
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX, "Child element inside a terminal node \"%s\" found.",
- snode->name);
- ret = LY_EVALID;
- goto cleanup;
}
/* create node */
- ret = lyd_create_term(snode, value, value_len, &dynamic, lydxml_resolve_prefix, ctx, LYD_XML, &cur);
- /* buffer spent */
- buffer = NULL;
+ ret = lyd_create_opaq(ctx, name, name_len, xmlctx->value, xmlctx->value_len, &xmlctx->dynamic, LYD_XML,
+ val_prefs, prefix, prefix_len, ns->uri, &cur);
+ LY_CHECK_GOTO(ret, cleanup);
+
+ /* parser next */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+
+ /* process children */
+ if (xmlctx->status == LYXML_ELEMENT) {
+ ret = lydxml_data_r(lydctx, (struct lyd_node_inner *)cur, data, lyd_node_children_p(cur));
+ LY_CHECK_GOTO(ret, cleanup);
+ }
+ } else if (snode->nodetype & LYD_NODE_TERM) {
+ /* create node */
+ ret = lyd_create_term(snode, xmlctx->value, xmlctx->value_len, &xmlctx->dynamic, lydxml_resolve_prefix,
+ xmlctx, LYD_XML, &cur);
if (ret == LY_EINCOMPLETE) {
- if (!(ctx->options & LYD_OPT_PARSE_ONLY)) {
- ly_set_add(&ctx->unres_node_type, cur, LY_SET_OPT_USEASLIST);
+ if (!(lydctx->options & LYD_OPT_PARSE_ONLY)) {
+ ly_set_add(&lydctx->unres_node_type, cur, LY_SET_OPT_USEASLIST);
}
} else if (ret) {
goto cleanup;
@@ -542,33 +482,46 @@
/* check the key order, the anchor must always be the last child */
anchor = lyd_get_prev_key_anchor(parent->child, cur->schema);
if ((!anchor && parent->child) || (anchor && anchor->next)) {
- if (ctx->options & LYD_OPT_STRICT) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_DATA, "Invalid position of the key \"%s\" in a list.",
+ if (lydctx->options & LYD_OPT_STRICT) {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_DATA, "Invalid position of the key \"%s\" in a list.",
cur->schema->name);
ret = LY_EVALID;
goto cleanup;
} else {
- LOGWRN(ctx->ctx, "Invalid position of the key \"%s\" in a list.", cur->schema->name);
+ LOGWRN(ctx, "Invalid position of the key \"%s\" in a list.", cur->schema->name);
}
}
}
- } else if (snode->nodetype & LYD_NODE_INNER) {
- if (value_len) {
- /* value in inner node */
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX, "Text value inside an inner node \"%s\" found.",
+
+ /* parser next */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+
+ /* no children expected */
+ if (xmlctx->status == LYXML_ELEMENT) {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Child element inside a terminal node \"%s\" found.",
snode->name);
ret = LY_EVALID;
goto cleanup;
-
+ }
+ } else if (snode->nodetype & LYD_NODE_INNER) {
+ if (!xmlctx->ws_only) {
+ /* value in inner node */
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Text value inside an inner node \"%s\" found.",
+ snode->name);
+ ret = LY_EVALID;
+ goto cleanup;
}
/* create node */
ret = lyd_create_inner(snode, &cur);
LY_CHECK_GOTO(ret, cleanup);
+ /* parser next */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+
/* process children */
- if (ctx->status == LYXML_ELEMENT && parents_count != ctx->elements.count) {
- ret = lydxml_data_r(ctx, (struct lyd_node_inner *)cur, data, lyd_node_children_p(cur));
+ if (xmlctx->status == LYXML_ELEMENT) {
+ ret = lydxml_data_r(lydctx, (struct lyd_node_inner *)cur, data, lyd_node_children_p(cur));
LY_CHECK_GOTO(ret, cleanup);
}
@@ -577,14 +530,14 @@
LY_CHECK_GOTO(ret = lyd_parse_check_keys(cur), cleanup);
}
- if (!(ctx->options & LYD_OPT_PARSE_ONLY)) {
+ if (!(lydctx->options & LYD_OPT_PARSE_ONLY)) {
/* new node validation, autodelete CANNOT occur, all nodes are new */
ret = lyd_validate_new(lyd_node_children_p(cur), snode, NULL);
LY_CHECK_GOTO(ret, cleanup);
/* add any missing default children */
ret = lyd_validate_defaults_r((struct lyd_node_inner *)cur, lyd_node_children_p(cur), NULL, NULL,
- &ctx->unres_node_type, &ctx->when_check, ctx->options);
+ &lydctx->unres_node_type, &lydctx->when_check, lydctx->options);
LY_CHECK_GOTO(ret, cleanup);
}
@@ -593,23 +546,24 @@
lyd_hash(cur);
}
} else if (snode->nodetype & LYD_NODE_ANY) {
- /* just incorrect status */
- if (ctx->status == LYXML_ELEM_CONTENT) {
- LY_ERR r = lyxml_get_string((struct lyxml_context *)ctx, data, &buffer, &buffer_size, &value, &value_len, &dynamic);
- if (r != LY_EINVAL && (r != LY_SUCCESS || value_len != 0)) {
- LOGINT(ctx->ctx);
- ret = LY_EINT;
- goto cleanup;
- }
+ if (!xmlctx->ws_only) {
+ /* value in inner node */
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Text value inside an any node \"%s\" found.",
+ snode->name);
+ ret = LY_EVALID;
+ goto cleanup;
}
+ /* parser next */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
+
/* parse any data tree with correct options */
- prev_opts = ctx->options;
- ctx->options &= ~LYD_OPT_STRICT;
- ctx->options |= LYD_OPT_OPAQ;
+ prev_opts = lydctx->options;
+ lydctx->options &= ~LYD_OPT_STRICT;
+ lydctx->options |= LYD_OPT_OPAQ;
anchor = NULL;
- ret = lydxml_data_r(ctx, NULL, data, &anchor);
- ctx->options = prev_opts;
+ ret = lydxml_data_r(lydctx, NULL, data, &anchor);
+ lydctx->options = prev_opts;
LY_CHECK_GOTO(ret, cleanup);
/* create node */
@@ -620,15 +574,15 @@
/* correct flags */
if (snode) {
if (!(snode->nodetype & (LYS_ACTION | LYS_NOTIF)) && snode->when) {
- if (ctx->options & LYD_OPT_TRUSTED) {
+ if (lydctx->options & LYD_OPT_TRUSTED) {
/* just set it to true */
cur->flags |= LYD_WHEN_TRUE;
} else {
/* remember we need to evaluate this node's when */
- ly_set_add(&ctx->when_check, cur, LY_SET_OPT_USEASLIST);
+ ly_set_add(&lydctx->when_check, cur, LY_SET_OPT_USEASLIST);
}
}
- if (ctx->options & LYD_OPT_TRUSTED) {
+ if (lydctx->options & LYD_OPT_TRUSTED) {
/* node is valid */
cur->flags &= ~LYD_NEW;
}
@@ -645,7 +599,7 @@
} else {
meta = meta->next;
}
- lyd_free_meta(ctx->ctx, meta2, 0);
+ lyd_free_meta(ctx, meta2, 0);
break;
}
@@ -665,24 +619,20 @@
/* insert */
lyd_insert_node((struct lyd_node *)parent, first, cur);
-
cur = NULL;
+
+ /* parser next */
+ assert(xmlctx->status == LYXML_ELEM_CLOSE);
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
}
/* success */
ret = LY_SUCCESS;
cleanup:
- free(buffer);
- lyd_free_meta(ctx->ctx, meta, 1);
- ly_free_attr(ctx->ctx, attr, 1);
+ lyd_free_meta(ctx, meta, 1);
+ ly_free_attr(ctx, attr, 1);
lyd_free_tree(cur);
- for (uint32_t u = 0; u < attrs_data.count; ++u) {
- if (((struct attr_data_s *)attrs_data.objs[u])->dynamic) {
- free(((struct attr_data_s *)attrs_data.objs[u])->value);
- }
- }
- ly_set_erase(&attrs_data, free);
if (ret && *first) {
lyd_free_siblings(*first);
*first = NULL;
@@ -694,20 +644,18 @@
lyd_parse_xml_data(struct ly_ctx *ctx, const char *data, int options, struct lyd_node **tree)
{
LY_ERR ret = LY_SUCCESS;
- struct lyd_xml_ctx xmlctx = {0};
+ struct lyd_xml_ctx lydctx = {0};
uint32_t i = 0;
const struct lys_module *mod;
struct lyd_node *first, *next, **first2;
- xmlctx.options = options;
- xmlctx.ctx = ctx;
- xmlctx.line = 1;
-
- /* init */
+ /* init context and tree */
+ LY_CHECK_GOTO(ret = lyxml_ctx_new(ctx, data, &lydctx.xmlctx), cleanup);
+ lydctx.options = options;
*tree = NULL;
/* parse XML data */
- ret = lydxml_data_r(&xmlctx, NULL, &data, tree);
+ ret = lydxml_data_r(&lydctx, NULL, &data, tree);
LY_CHECK_GOTO(ret, cleanup);
if (!(options & LYD_OPT_PARSE_ONLY)) {
@@ -733,13 +681,13 @@
LY_CHECK_GOTO(ret, cleanup);
/* add all top-level defaults for this module */
- ret = lyd_validate_defaults_r(NULL, first2, NULL, mod, &xmlctx.unres_node_type, &xmlctx.when_check,
+ ret = lyd_validate_defaults_r(NULL, first2, NULL, mod, &lydctx.unres_node_type, &lydctx.when_check,
options & LYD_VALOPT_MASK);
LY_CHECK_GOTO(ret, cleanup);
/* finish incompletely validated terminal values/attributes and when conditions */
- ret = lyd_validate_unres(tree, &xmlctx.when_check, &xmlctx.unres_node_type, &xmlctx.unres_meta_type, LYD_XML,
- lydxml_resolve_prefix, ctx);
+ ret = lyd_validate_unres(tree, &lydctx.when_check, &lydctx.unres_node_type, &lydctx.unres_meta_type, LYD_XML,
+ lydxml_resolve_prefix, lydctx.xmlctx);
LY_CHECK_GOTO(ret, cleanup);
/* perform final validation that assumes the data tree is final */
@@ -750,100 +698,13 @@
cleanup:
/* there should be no unresolved types stored */
- assert(!(options & LYD_OPT_PARSE_ONLY) || (!xmlctx.unres_node_type.count && !xmlctx.unres_meta_type.count
- && !xmlctx.when_check.count));
+ assert(!(options & LYD_OPT_PARSE_ONLY) || (!lydctx.unres_node_type.count && !lydctx.unres_meta_type.count
+ && !lydctx.when_check.count));
- ly_set_erase(&xmlctx.unres_node_type, NULL);
- ly_set_erase(&xmlctx.unres_meta_type, NULL);
- ly_set_erase(&xmlctx.when_check, NULL);
- lyxml_context_clear((struct lyxml_context *)&xmlctx);
- if (ret) {
- lyd_free_all(*tree);
- *tree = NULL;
- }
- return ret;
-}
-
-static LY_ERR
-lydxml_rpc(struct lyd_xml_ctx *ctx, const char **data, struct ly_attr **attr)
-{
- const char *prefix, *name;
- size_t prefix_len, name_len;
- struct ly_set attrs_data = {0};
- const struct lyxml_ns *ns;
-
- LY_CHECK_RET(lyxml_get_element((struct lyxml_context *)ctx, data, &prefix, &prefix_len, &name, &name_len));
- if (ly_strncmp("rpc", name, name_len)) {
- /* not an rpc */
- return LY_ENOT;
- }
-
- if (ctx->status == LYXML_ATTRIBUTE) {
- LY_CHECK_RET(lydxml_attributes_parse((struct lyxml_context *)ctx, data, &attrs_data));
- }
-
- ns = lyxml_ns_get((struct lyxml_context *)ctx, prefix, prefix_len);
- if (!ns || strcmp(ns->uri, "urn:ietf:params:xml:ns:netconf:base:1.0")) {
- /* wrong namespace */
- return LY_ENOT;
- }
-
- /* all fine, just parse the rest of the attributes */
- if (attrs_data.count) {
- /* TODO parse into generic attribute structure, that will also be returned */
- //LY_CHECK_RET(lydxml_attributes(ctx, &attrs_data, NULL, meta));
- }
-
- return LY_SUCCESS;
-}
-
-static LY_ERR
-lydxml_action(struct lyd_xml_ctx *ctx, const char **data)
-{
- /* TODO */
- return LY_ENOT;
-}
-
-LY_ERR
-lyd_parse_xml_rpc(struct ly_ctx *ctx, const char *data, struct lyd_node **tree, struct ly_attr **attr,
- struct lyd_node **op)
-{
- LY_ERR ret = LY_SUCCESS;
- const char *data_p;
- struct lyd_xml_ctx xmlctx = {0};
-
- xmlctx.ctx = ctx;
- xmlctx.line = 1;
-
- /* init */
- *tree = NULL;
- data_p = data;
-
- /* parse optional "rpc" element */
- ret = lydxml_rpc(&xmlctx, &data_p, attr);
- if (ret == LY_ENOT) {
- /* reset data, nothing parsed */
- data_p = data;
- } else if (ret) {
- goto cleanup;
- } else {
- /* successfully parsed */
- data = data_p;
-
- /* parse optional "action" element */
- ret = lydxml_action(&xmlctx, &data_p);
- if (ret == LY_ENOT) {
- data_p = data;
- } else if (ret) {
- goto cleanup;
- }
- }
-
- /* parse the rest of data tree normally */
- ret = lydxml_data_r(&xmlctx, NULL, &data_p, tree);
- LY_CHECK_GOTO(ret, cleanup);
-
-cleanup:
+ ly_set_erase(&lydctx.unres_node_type, NULL);
+ ly_set_erase(&lydctx.unres_meta_type, NULL);
+ ly_set_erase(&lydctx.when_check, NULL);
+ lyxml_ctx_free(lydctx.xmlctx);
if (ret) {
lyd_free_all(*tree);
*tree = NULL;
diff --git a/src/parser_yang.c b/src/parser_yang.c
index f72dd2f..d831ee4 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -77,12 +77,12 @@
!ERR && (KW != LY_STMT_SYNTAX_RIGHT_BRACE); \
ERR = get_keyword(CTX, DATA, &KW, &WORD, &WORD_LEN))
-LY_ERR parse_container(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
-LY_ERR parse_uses(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
-LY_ERR parse_choice(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
-LY_ERR parse_case(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
-LY_ERR parse_list(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
-LY_ERR parse_grouping(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_grp **groupings);
+LY_ERR parse_container(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
+LY_ERR parse_uses(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
+LY_ERR parse_choice(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
+LY_ERR parse_case(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
+LY_ERR parse_list(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
+LY_ERR parse_grouping(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_grp **groupings);
/**
* @brief Add another character to dynamic buffer, a low-level function.
@@ -139,7 +139,7 @@
* @return LY_ERR values.
*/
LY_ERR
-buf_store_char(struct lys_parser_ctx *ctx, const char **input, enum yang_arg arg, char **word_p,
+buf_store_char(struct lys_yang_parser_ctx *ctx, const char **input, enum yang_arg arg, char **word_p,
size_t *word_len, char **word_b, size_t *buf_len, int need_buf, int *prefix)
{
unsigned int c;
@@ -162,14 +162,14 @@
/* check character validity */
switch (arg) {
case Y_IDENTIF_ARG:
- LY_CHECK_RET(lysp_check_identifierchar(ctx, c, !(*word_len), NULL));
+ LY_CHECK_RET(lysp_check_identifierchar((struct lys_parser_ctx *)ctx, c, !(*word_len), NULL));
break;
case Y_PREF_IDENTIF_ARG:
- LY_CHECK_RET(lysp_check_identifierchar(ctx, c, !(*word_len), prefix));
+ LY_CHECK_RET(lysp_check_identifierchar((struct lys_parser_ctx *)ctx, c, !(*word_len), prefix));
break;
case Y_STR_ARG:
case Y_MAYBE_STR_ARG:
- LY_CHECK_RET(lysp_check_stringchar(ctx, c));
+ LY_CHECK_RET(lysp_check_stringchar((struct lys_parser_ctx *)ctx, c));
break;
}
@@ -222,7 +222,7 @@
* @return LY_ERR values.
*/
LY_ERR
-skip_comment(struct lys_parser_ctx *ctx, const char **data, int comment)
+skip_comment(struct lys_yang_parser_ctx *ctx, const char **data, int comment)
{
/* internal statuses: 0 - comment ended,
* 1 - in line comment,
@@ -291,8 +291,8 @@
* @return LY_ERR values.
*/
static LY_ERR
-read_qstring(struct lys_parser_ctx *ctx, const char **data, enum yang_arg arg, char **word_p, char **word_b, size_t *word_len,
- size_t *buf_len)
+read_qstring(struct lys_yang_parser_ctx *ctx, const char **data, enum yang_arg arg, char **word_p, char **word_b,
+ size_t *word_len, size_t *buf_len)
{
/* string: 0 - string ended, 1 - string with ', 2 - string with ", 3 - string with " with last character \,
* 4 - string finished, now skipping whitespaces looking for +,
@@ -510,7 +510,7 @@
* @return LY_ERR values.
*/
LY_ERR
-get_argument(struct lys_parser_ctx *ctx, const char **data, enum yang_arg arg,
+get_argument(struct lys_yang_parser_ctx *ctx, const char **data, enum yang_arg arg,
uint16_t *flags, char **word_p, char **word_b, size_t *word_len)
{
size_t buf_len = 0;
@@ -629,7 +629,7 @@
* @return LY_ERR values.
*/
LY_ERR
-get_keyword(struct lys_parser_ctx *ctx, const char **data, enum ly_stmt *kw, char **word_p, size_t *word_len)
+get_keyword(struct lys_yang_parser_ctx *ctx, const char **data, enum ly_stmt *kw, char **word_p, size_t *word_len)
{
int prefix;
const char *word_start;
@@ -724,7 +724,7 @@
LOGVAL_PARSER(ctx, LY_VCODE_INCHAR, (*data)[-len]), LY_EVALID);
++ctx->indent;
/* check character validity */
- LY_CHECK_RET(lysp_check_identifierchar(ctx, c, *data - len == word_start ? 1 : 0, &prefix));
+ LY_CHECK_RET(lysp_check_identifierchar((struct lys_parser_ctx *)ctx, c, *data - len == word_start ? 1 : 0, &prefix));
}
if (!**data) {
LOGVAL_PARSER(ctx, LY_VCODE_EOF);
@@ -761,7 +761,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_ext_substmt(struct lys_parser_ctx *ctx, const char **data, enum ly_stmt kw, char *word, size_t word_len,
+parse_ext_substmt(struct lys_yang_parser_ctx *ctx, const char **data, enum ly_stmt kw, char *word, size_t word_len,
struct lysp_stmt **child)
{
char *buf;
@@ -814,7 +814,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_ext(struct lys_parser_ctx *ctx, const char **data, const char *ext_name, int ext_name_len, LYEXT_SUBSTMT insubstmt,
+parse_ext(struct lys_yang_parser_ctx *ctx, const char **data, const char *ext_name, int ext_name_len, LYEXT_SUBSTMT insubstmt,
uint32_t insubstmt_index, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
@@ -858,7 +858,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_text_field(struct lys_parser_ctx *ctx, const char **data, LYEXT_SUBSTMT substmt, uint32_t substmt_index,
+parse_text_field(struct lys_yang_parser_ctx *ctx, const char **data, LYEXT_SUBSTMT substmt, uint32_t substmt_index,
const char **value, enum yang_arg arg, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
@@ -901,7 +901,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_yangversion(struct lys_parser_ctx *ctx, const char **data, uint8_t *version, struct lysp_ext_instance **exts)
+parse_yangversion(struct lys_yang_parser_ctx *ctx, const char **data, uint8_t *version, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -952,7 +952,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_belongsto(struct lys_parser_ctx *ctx, const char **data, const char **belongsto, const char **prefix, struct lysp_ext_instance **exts)
+parse_belongsto(struct lys_yang_parser_ctx *ctx, const char **data, const char **belongsto, const char **prefix, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1003,7 +1003,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_revisiondate(struct lys_parser_ctx *ctx, const char **data, char *rev, struct lysp_ext_instance **exts)
+parse_revisiondate(struct lys_yang_parser_ctx *ctx, const char **data, char *rev, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1019,7 +1019,7 @@
LY_CHECK_RET(get_argument(ctx, data, Y_STR_ARG, NULL, &word, &buf, &word_len));
/* check value */
- if (lysp_check_date(ctx, word, word_len, "revision-date")) {
+ if (lysp_check_date((struct lys_parser_ctx *)ctx, word, word_len, "revision-date")) {
free(buf);
return LY_EVALID;
}
@@ -1052,7 +1052,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_include(struct lys_parser_ctx *ctx, const char *module_name, const char **data, struct lysp_include **includes)
+parse_include(struct lys_yang_parser_ctx *ctx, const char *module_name, const char **data, struct lysp_include **includes)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1109,7 +1109,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_import(struct lys_parser_ctx *ctx, const char *module_prefix, const char **data, struct lysp_import **imports)
+parse_import(struct lys_yang_parser_ctx *ctx, const char *module_prefix, const char **data, struct lysp_import **imports)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1127,7 +1127,7 @@
switch (kw) {
case LY_STMT_PREFIX:
LY_CHECK_RET(parse_text_field(ctx, data, LYEXT_SUBSTMT_PREFIX, 0, &imp->prefix, Y_IDENTIF_ARG, &imp->exts));
- LY_CHECK_RET(lysp_check_prefix(ctx, *imports, module_prefix, &imp->prefix), LY_EVALID);
+ LY_CHECK_RET(lysp_check_prefix((struct lys_parser_ctx *)ctx, *imports, module_prefix, &imp->prefix), LY_EVALID);
break;
case LY_STMT_DESCRIPTION:
PARSER_CHECK_STMTVER2_RET(ctx, "description", "import");
@@ -1166,7 +1166,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_revision(struct lys_parser_ctx *ctx, const char **data, struct lysp_revision **revs)
+parse_revision(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_revision **revs)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1180,7 +1180,7 @@
LY_CHECK_RET(get_argument(ctx, data, Y_STR_ARG, NULL, &word, &buf, &word_len));
/* check value */
- if (lysp_check_date(ctx, word, word_len, "revision")) {
+ if (lysp_check_date((struct lys_parser_ctx *)ctx, word, word_len, "revision")) {
free(buf);
return LY_EVALID;
}
@@ -1220,7 +1220,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_text_fields(struct lys_parser_ctx *ctx, const char **data, LYEXT_SUBSTMT substmt, const char ***texts, enum yang_arg arg,
+parse_text_fields(struct lys_yang_parser_ctx *ctx, const char **data, LYEXT_SUBSTMT substmt, const char ***texts, enum yang_arg arg,
struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
@@ -1260,7 +1260,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_config(struct lys_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_config(struct lys_yang_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1310,7 +1310,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_mandatory(struct lys_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_mandatory(struct lys_yang_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1360,7 +1360,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_restr(struct lys_parser_ctx *ctx, const char **data, enum ly_stmt restr_kw, struct lysp_restr *restr)
+parse_restr(struct lys_yang_parser_ctx *ctx, const char **data, enum ly_stmt restr_kw, struct lysp_restr *restr)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1370,7 +1370,7 @@
/* get value */
LY_CHECK_RET(get_argument(ctx, data, Y_STR_ARG, NULL, &word, &buf, &word_len));
- YANG_CHECK_NONEMPTY(ctx, word_len, ly_stmt2str(restr_kw));
+ CHECK_NONEMPTY(ctx, word_len, ly_stmt2str(restr_kw));
INSERT_WORD(ctx, buf, restr->arg, word, word_len);
YANG_READ_SUBSTMT_FOR(ctx, data, kw, word, word_len, ret,) {
switch (kw) {
@@ -1408,7 +1408,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_restrs(struct lys_parser_ctx *ctx, const char **data, enum ly_stmt restr_kw, struct lysp_restr **restrs)
+parse_restrs(struct lys_yang_parser_ctx *ctx, const char **data, enum ly_stmt restr_kw, struct lysp_restr **restrs)
{
struct lysp_restr *restr;
@@ -1427,7 +1427,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_status(struct lys_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_status(struct lys_yang_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1478,7 +1478,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_when(struct lys_parser_ctx *ctx, const char **data, struct lysp_when **when_p)
+parse_when(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_when **when_p)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1496,7 +1496,7 @@
/* get value */
LY_CHECK_ERR_RET(get_argument(ctx, data, Y_STR_ARG, NULL, &word, &buf, &word_len), free(when), LY_EMEM);
- YANG_CHECK_NONEMPTY(ctx, word_len, "when");
+ CHECK_NONEMPTY(ctx, word_len, "when");
INSERT_WORD(ctx, buf, when->cond, word, word_len);
*when_p = when;
@@ -1531,7 +1531,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_any(struct lys_parser_ctx *ctx, const char **data, enum ly_stmt kw, struct lysp_node *parent, struct lysp_node **siblings)
+parse_any(struct lys_yang_parser_ctx *ctx, const char **data, enum ly_stmt kw, struct lysp_node *parent, struct lysp_node **siblings)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1600,7 +1600,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_type_enum_value_pos(struct lys_parser_ctx *ctx, const char **data, enum ly_stmt val_kw, int64_t *value, uint16_t *flags,
+parse_type_enum_value_pos(struct lys_yang_parser_ctx *ctx, const char **data, enum ly_stmt val_kw, int64_t *value, uint16_t *flags,
struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
@@ -1682,7 +1682,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_type_enum(struct lys_parser_ctx *ctx, const char **data, enum ly_stmt enum_kw, struct lysp_type_enum **enums)
+parse_type_enum(struct lys_yang_parser_ctx *ctx, const char **data, enum ly_stmt enum_kw, struct lysp_type_enum **enums)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1695,7 +1695,7 @@
/* get value */
LY_CHECK_RET(get_argument(ctx, data, enum_kw == LY_STMT_ENUM ? Y_STR_ARG : Y_IDENTIF_ARG, NULL, &word, &buf, &word_len));
if (enum_kw == LY_STMT_ENUM) {
- ret = lysp_check_enum_name(ctx, (const char *)word, word_len);
+ ret = lysp_check_enum_name((struct lys_parser_ctx *)ctx, (const char *)word, word_len);
LY_CHECK_ERR_RET(ret, free(buf), ret);
} /* else nothing specific for YANG_BIT */
@@ -1749,7 +1749,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_type_fracdigits(struct lys_parser_ctx *ctx, const char **data, uint8_t *fracdig, struct lysp_ext_instance **exts)
+parse_type_fracdigits(struct lys_yang_parser_ctx *ctx, const char **data, uint8_t *fracdig, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word, *ptr;
@@ -1812,7 +1812,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_type_reqinstance(struct lys_parser_ctx *ctx, const char **data, uint8_t *reqinst, uint16_t *flags,
+parse_type_reqinstance(struct lys_yang_parser_ctx *ctx, const char **data, uint8_t *reqinst, uint16_t *flags,
struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
@@ -1862,7 +1862,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_type_pattern_modifier(struct lys_parser_ctx *ctx, const char **data, const char **pat, struct lysp_ext_instance **exts)
+parse_type_pattern_modifier(struct lys_yang_parser_ctx *ctx, const char **data, const char **pat, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1917,7 +1917,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_type_pattern(struct lys_parser_ctx *ctx, const char **data, struct lysp_restr **patterns)
+parse_type_pattern(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_restr **patterns)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -1982,7 +1982,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_type(struct lys_parser_ctx *ctx, const char **data, struct lysp_type *type)
+parse_type(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_type *type)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2077,7 +2077,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_leaf(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
+parse_leaf(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2165,7 +2165,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_maxelements(struct lys_parser_ctx *ctx, const char **data, uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_maxelements(struct lys_yang_parser_ctx *ctx, const char **data, uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word, *ptr;
@@ -2232,7 +2232,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_minelements(struct lys_parser_ctx *ctx, const char **data, uint32_t *min, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_minelements(struct lys_yang_parser_ctx *ctx, const char **data, uint32_t *min, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word, *ptr;
@@ -2295,7 +2295,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_orderedby(struct lys_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_orderedby(struct lys_yang_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2344,7 +2344,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_leaflist(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
+parse_leaflist(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2443,7 +2443,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_refine(struct lys_parser_ctx *ctx, const char **data, struct lysp_refine **refines)
+parse_refine(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_refine **refines)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2455,7 +2455,7 @@
/* get value */
LY_CHECK_RET(get_argument(ctx, data, Y_STR_ARG, NULL, &word, &buf, &word_len));
- YANG_CHECK_NONEMPTY(ctx, word_len, "refine");
+ CHECK_NONEMPTY(ctx, word_len, "refine");
INSERT_WORD(ctx, buf, rf->nodeid, word, word_len);
YANG_READ_SUBSTMT_FOR(ctx, data, kw, word, word_len, ret,) {
@@ -2512,7 +2512,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_typedef(struct lys_parser_ctx *ctx, struct lysp_node *parent, const char **data, struct lysp_tpdf **typedefs)
+parse_typedef(struct lys_yang_parser_ctx *ctx, struct lysp_node *parent, const char **data, struct lysp_tpdf **typedefs)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2582,7 +2582,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_inout(struct lys_parser_ctx *ctx, const char **data, enum ly_stmt inout_kw, struct lysp_node *parent, struct lysp_action_inout *inout_p)
+parse_inout(struct lys_yang_parser_ctx *ctx, const char **data, enum ly_stmt inout_kw, struct lysp_node *parent, struct lysp_action_inout *inout_p)
{
LY_ERR ret = LY_SUCCESS;
char *word;
@@ -2647,7 +2647,7 @@
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, inout_p->groupings, NULL, NULL, NULL));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, inout_p->groupings, NULL, NULL, NULL));
if (!inout_p->data) {
LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", ly_stmt2str(inout_kw));
@@ -2667,7 +2667,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_action(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_action **actions)
+parse_action(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_action **actions)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2722,7 +2722,7 @@
LY_CHECK_RET(ret);
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, act->groupings, NULL, NULL, NULL));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, act->groupings, NULL, NULL, NULL));
return ret;
}
@@ -2737,7 +2737,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_notif(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_notif **notifs)
+parse_notif(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_notif **notifs)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2814,7 +2814,7 @@
LY_CHECK_RET(ret);
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, notif->groupings, NULL, NULL, NULL));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, notif->groupings, NULL, NULL, NULL));
return ret;
}
@@ -2829,7 +2829,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_grouping(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_grp **groupings)
+parse_grouping(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_grp **groupings)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2907,7 +2907,7 @@
LY_CHECK_RET(ret);
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, grp->groupings, NULL, grp->actions, grp->notifs));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, grp->groupings, NULL, grp->actions, grp->notifs));
return ret;
}
@@ -2922,7 +2922,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_augment(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_augment **augments)
+parse_augment(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_augment **augments)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -2934,7 +2934,7 @@
/* get value */
LY_CHECK_RET(get_argument(ctx, data, Y_STR_ARG, NULL, &word, &buf, &word_len));
- YANG_CHECK_NONEMPTY(ctx, word_len, "augment");
+ CHECK_NONEMPTY(ctx, word_len, "augment");
INSERT_WORD(ctx, buf, aug->nodeid, word, word_len);
aug->nodetype = LYS_AUGMENT;
aug->parent = parent;
@@ -3004,7 +3004,7 @@
LY_CHECK_RET(ret);
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, NULL, NULL, aug->actions, aug->notifs));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, NULL, NULL, aug->actions, aug->notifs));
return ret;
}
@@ -3019,7 +3019,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_uses(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
+parse_uses(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3071,7 +3071,7 @@
}
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, NULL, uses->augments, NULL, NULL));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, NULL, uses->augments, NULL, NULL));
return ret;
}
@@ -3086,7 +3086,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_case(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
+parse_case(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3167,7 +3167,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_choice(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
+parse_choice(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3264,7 +3264,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_container(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
+parse_container(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
{
LY_ERR ret = 0;
char *buf, *word;
@@ -3358,7 +3358,7 @@
}
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, cont->groupings, NULL, cont->actions, cont->notifs));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, cont->groupings, NULL, cont->actions, cont->notifs));
return ret;
}
@@ -3372,7 +3372,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_list(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
+parse_list(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3479,7 +3479,7 @@
LY_CHECK_RET(ret);
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, list->groupings, NULL, list->actions, list->notifs));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, list->groupings, NULL, list->actions, list->notifs));
if (list->max && list->min > list->max) {
LOGVAL_PARSER(ctx, LYVE_SEMANTICS,
@@ -3502,7 +3502,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_yinelement(struct lys_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_yinelement(struct lys_yang_parser_ctx *ctx, const char **data, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3553,7 +3553,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_argument(struct lys_parser_ctx *ctx, const char **data, const char **argument, uint16_t *flags, struct lysp_ext_instance **exts)
+parse_argument(struct lys_yang_parser_ctx *ctx, const char **data, const char **argument, uint16_t *flags, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3595,7 +3595,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-parse_extension(struct lys_parser_ctx *ctx, const char **data, struct lysp_ext **extensions)
+parse_extension(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_ext **extensions)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3644,7 +3644,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_deviate(struct lys_parser_ctx *ctx, const char **data, struct lysp_deviate **deviates)
+parse_deviate(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_deviate **deviates)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3852,7 +3852,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_deviation(struct lys_parser_ctx *ctx, const char **data, struct lysp_deviation **deviations)
+parse_deviation(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_deviation **deviations)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3864,7 +3864,7 @@
/* get value */
LY_CHECK_RET(get_argument(ctx, data, Y_STR_ARG, NULL, &word, &buf, &word_len));
- YANG_CHECK_NONEMPTY(ctx, word_len, "deviation");
+ CHECK_NONEMPTY(ctx, word_len, "deviation");
INSERT_WORD(ctx, buf, dev->nodeid, word, word_len);
YANG_READ_SUBSTMT_FOR(ctx, data, kw, word, word_len, ret, goto checks) {
@@ -3907,7 +3907,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_feature(struct lys_parser_ctx *ctx, const char **data, struct lysp_feature **features)
+parse_feature(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_feature **features)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -3956,7 +3956,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_identity(struct lys_parser_ctx *ctx, const char **data, struct lysp_ident **identities)
+parse_identity(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_ident **identities)
{
LY_ERR ret = LY_SUCCESS;
char *buf, *word;
@@ -4013,7 +4013,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_module(struct lys_parser_ctx *ctx, const char **data, struct lysp_module *mod)
+parse_module(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_module *mod)
{
LY_ERR ret = 0;
char *buf, *word;
@@ -4191,7 +4191,7 @@
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, mod->groupings, mod->augments, mod->rpcs, mod->notifs));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, mod->groupings, mod->augments, mod->rpcs, mod->notifs));
/* mandatory substatements */
if (!mod->mod->ns) {
@@ -4223,7 +4223,7 @@
* @return LY_ERR values.
*/
LY_ERR
-parse_submodule(struct lys_parser_ctx *ctx, const char **data, struct lysp_submodule *submod)
+parse_submodule(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_submodule *submod)
{
LY_ERR ret = 0;
char *buf, *word;
@@ -4397,7 +4397,8 @@
checks:
/* finalize parent pointers to the reallocated items */
- LY_CHECK_RET(lysp_parse_finalize_reallocated(ctx, submod->groupings, submod->augments, submod->rpcs, submod->notifs));
+ LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, submod->groupings, submod->augments,
+ submod->rpcs, submod->notifs));
/* mandatory substatements */
if (!submod->belongsto) {
@@ -4417,7 +4418,8 @@
}
LY_ERR
-yang_parse_submodule(struct lys_parser_ctx **context, struct ly_ctx *ly_ctx, struct lys_parser_ctx *main_ctx, const char *data, struct lysp_submodule **submod)
+yang_parse_submodule(struct lys_yang_parser_ctx **context, struct ly_ctx *ly_ctx, struct lys_parser_ctx *main_ctx,
+ const char *data, struct lysp_submodule **submod)
{
LY_ERR ret = LY_SUCCESS;
char *word;
@@ -4428,6 +4430,7 @@
/* create context */
*context = calloc(1, sizeof **context);
LY_CHECK_ERR_RET(!(*context), LOGMEM(ly_ctx), LY_EMEM);
+ (*context)->format = LYS_IN_YANG;
(*context)->ctx = ly_ctx;
(*context)->pos_type = LY_VLOG_LINE;
(*context)->line = 1;
@@ -4474,7 +4477,7 @@
cleanup:
if (ret) {
lysp_submodule_free((*context)->ctx, mod_p);
- lys_parser_ctx_free(*context);
+ yang_parser_ctx_free(*context);
*context = NULL;
}
@@ -4482,7 +4485,7 @@
}
LY_ERR
-yang_parse_module(struct lys_parser_ctx **context, const char *data, struct lys_module *mod)
+yang_parse_module(struct lys_yang_parser_ctx **context, const char *data, struct lys_module *mod)
{
LY_ERR ret = LY_SUCCESS;
char *word;
@@ -4493,6 +4496,7 @@
/* create context */
*context = calloc(1, sizeof **context);
LY_CHECK_ERR_RET(!(*context), LOGMEM(mod->ctx), LY_EMEM);
+ (*context)->format = LYS_IN_YANG;
(*context)->ctx = mod->ctx;
(*context)->pos_type = LY_VLOG_LINE;
(*context)->line = 1;
@@ -4536,7 +4540,7 @@
cleanup:
if (ret) {
lysp_module_free(mod_p);
- lys_parser_ctx_free(*context);
+ yang_parser_ctx_free(*context);
*context = NULL;
}
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 997be07..28016a5 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -54,7 +54,7 @@
};
enum ly_stmt
-yin_match_keyword(struct yin_parser_ctx *ctx, const char *name, size_t name_len,
+yin_match_keyword(struct lys_yin_parser_ctx *ctx, const char *name, size_t name_len,
const char *prefix, size_t prefix_len, enum ly_stmt parrent)
{
const char *start = NULL;
@@ -65,7 +65,7 @@
return LY_STMT_NONE;
}
- ns = lyxml_ns_get(&ctx->xml_ctx, prefix, prefix_len);
+ ns = lyxml_ns_get(ctx->xmlctx, prefix, prefix_len);
if (ns) {
if (!IS_YIN_NS(ns->uri)) {
return LY_STMT_EXTENSION_INSTANCE;
@@ -157,13 +157,6 @@
return arg;
}
-void free_arg_rec(struct yin_parser_ctx *ctx, struct yin_arg_record *record) {
- (void)ctx; /* unused */
- if (record && record->dynamic_content) {
- free(record->content);
- }
-}
-
#define IS_NODE_ELEM(kw) (kw == LY_STMT_ANYXML || kw == LY_STMT_ANYDATA || kw == LY_STMT_LEAF || kw == LY_STMT_LEAF_LIST || \
kw == LY_STMT_TYPEDEF || kw == LY_STMT_USES || kw == LY_STMT_LIST || kw == LY_STMT_NOTIFICATION || \
kw == LY_STMT_GROUPING || kw == LY_STMT_CONTAINER || kw == LY_STMT_CASE || kw == LY_STMT_CHOICE || \
@@ -200,7 +193,7 @@
* @return LY_SUCCESS on success LY_EMEM on memmory allocation failure.
*/
static LY_ERR
-subelems_allocator(struct yin_parser_ctx *ctx, size_t count, struct lysp_node *parent,
+subelems_allocator(struct lys_yin_parser_ctx *ctx, size_t count, struct lysp_node *parent,
struct yin_subelement **result, ...)
{
va_list ap;
@@ -253,55 +246,26 @@
mem_err:
subelems_deallocator(count, *result);
- LOGMEM(ctx->xml_ctx.ctx);
+ LOGMEM(ctx->xmlctx->ctx);
return LY_EMEM;
}
LY_ERR
-yin_load_attributes(struct yin_parser_ctx *ctx, const char **data, struct yin_arg_record **attrs)
-{
- LY_ERR ret = LY_SUCCESS;
- struct yin_arg_record *argument_record = NULL;
- const char *prefix, *name;
- size_t prefix_len, name_len;
-
- /* load all attributes */
- while (ctx->xml_ctx.status == LYXML_ATTRIBUTE) {
- ret = lyxml_get_attribute(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
- LY_CHECK_GOTO(ret, cleanup);
-
- if (ctx->xml_ctx.status == LYXML_ATTR_CONTENT) {
- LY_ARRAY_NEW_GOTO(ctx->xml_ctx.ctx, *attrs, argument_record, ret, cleanup);
- argument_record->name = name;
- argument_record->name_len = name_len;
- argument_record->prefix = prefix;
- argument_record->prefix_len = prefix_len;
- ret = lyxml_get_string(&ctx->xml_ctx, data, &argument_record->content, &argument_record->content_len,
- &argument_record->content, &argument_record->content_len, &argument_record->dynamic_content);
- LY_CHECK_GOTO(ret, cleanup);
- }
- }
-
-cleanup:
- if (ret != LY_SUCCESS) {
- FREE_ARRAY(ctx, *attrs, free_arg_rec);
- *attrs = NULL;
- }
- return ret;
-}
-
-LY_ERR
-yin_validate_value(struct yin_parser_ctx *ctx, enum yang_arg val_type, char *val, size_t len)
+yin_validate_value(struct lys_yin_parser_ctx *ctx, enum yang_arg val_type)
{
int prefix = 0;
unsigned int c;
- size_t utf8_char_len;
- size_t already_read = 0;
- while (already_read < len) {
+ size_t utf8_char_len, already_read = 0;
+ const char *val;
+
+ assert((ctx->xmlctx->status == LYXML_ELEM_CONTENT) || (ctx->xmlctx->status == LYXML_ATTR_CONTENT));
+
+ val = ctx->xmlctx->value;
+ while (already_read < ctx->xmlctx->value_len) {
LY_CHECK_ERR_RET(ly_getutf8((const char **)&val, &c, &utf8_char_len),
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INCHAR, (val)[-utf8_char_len]), LY_EVALID);
already_read += utf8_char_len;
- LY_CHECK_ERR_RET(already_read > len, LOGINT(ctx->xml_ctx.ctx), LY_EINT);
+ LY_CHECK_ERR_RET(already_read > ctx->xmlctx->value_len, LOGINT(ctx->xmlctx->ctx), LY_EINT);
switch (val_type) {
case Y_IDENTIF_ARG:
@@ -321,10 +285,9 @@
}
/**
- * @brief Parse yin attribute.
+ * @brief Parse yin attributes.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs ([Sized array](@ref sizedarrays)) of attributes.
* @param[in] arg_type Type of argument that is expected in parsed element (use YIN_ARG_NONE for elements without
* special argument).
* @param[out] arg_val Where value of argument should be stored. Can be NULL iff arg_type is specified as YIN_ARG_NONE.
@@ -334,38 +297,48 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_attribute(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, enum yin_argument arg_type,
- const char **arg_val, enum yang_arg val_type, enum ly_stmt current_element)
+yin_parse_attribute(struct lys_yin_parser_ctx *ctx, enum yin_argument arg_type, const char **arg_val, enum yang_arg val_type,
+ enum ly_stmt current_element)
{
enum yin_argument arg = YIN_ARG_UNKNOWN;
- struct yin_arg_record *iter = NULL;
bool found = false;
/* validation of attributes */
- LY_ARRAY_FOR(attrs, struct yin_arg_record, iter) {
+ while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
/* yin arguments represented as attributes have no namespace, which in this case means no prefix */
- if (!iter->prefix) {
- arg = yin_match_argument_name(iter->name, iter->name_len);
+ if (!ctx->xmlctx->prefix) {
+ arg = yin_match_argument_name(ctx->xmlctx->name, ctx->xmlctx->name_len);
if (arg == YIN_ARG_NONE) {
- continue;
+ /* skip it */
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
} else if (arg == arg_type) {
LY_CHECK_ERR_RET(found, LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_DUP_ATTR,
yin_attr2str(arg), ly_stmt2str(current_element)), LY_EVALID);
found = true;
- LY_CHECK_RET(yin_validate_value(ctx, val_type, iter->content, iter->content_len));
- INSERT_STRING(ctx->xml_ctx.ctx, *arg_val, iter->dynamic_content, iter->content, iter->content_len);
- iter->dynamic_content = 0;
+
+ /* go to value */
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_validate_value(ctx, val_type));
+ *arg_val = INSERT_STRING(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic);
LY_CHECK_RET(!(*arg_val), LY_EMEM);
} else {
- LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_ATTR, iter->name_len, iter->name, ly_stmt2str(current_element));
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_ATTR, ctx->xmlctx->name_len,
+ ctx->xmlctx->name, ly_stmt2str(current_element));
return LY_EVALID;
}
+ } else {
+ /* skip it */
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
}
+
+ /* next attribute */
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
}
/* anything else than Y_MAYBE_STR_ARG is mandatory */
if (val_type != Y_MAYBE_STR_ARG && !found) {
- LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YIN, "Missing mandatory attribute %s of %s element.", yin_attr2str(arg_type), ly_stmt2str(current_element));
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YIN, "Missing mandatory attribute %s of %s element.",
+ yin_attr2str(arg_type), ly_stmt2str(current_element));
return LY_EVALID;
}
@@ -403,7 +376,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_check_subelem_mandatory_constraint(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info,
+yin_check_subelem_mandatory_constraint(struct lys_yin_parser_ctx *ctx, struct yin_subelement *subelem_info,
signed char subelem_info_size, enum ly_stmt current_element)
{
for (signed char i = 0; i < subelem_info_size; ++i) {
@@ -430,7 +403,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_check_subelem_first_constraint(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info,
+yin_check_subelem_first_constraint(struct lys_yin_parser_ctx *ctx, struct yin_subelement *subelem_info,
signed char subelem_info_size, enum ly_stmt current_element,
struct yin_subelement *exp_first)
{
@@ -450,45 +423,38 @@
* for example prefix or namespace element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] kw Type of current element.
* @param[out] value Where value of attribute should be stored.
* @param[in] arg_type Expected type of attribute.
* @param[in] arg_val_type Type of expected value of attribute.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_simple_element(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum ly_stmt kw,
- const char **value, enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
+yin_parse_simple_element(struct lys_yin_parser_ctx *ctx, enum ly_stmt kw, const char **value,
+ enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
{
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, arg_type, value, arg_val_type, kw));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, value, arg_val_type, kw));
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, 1, data, kw, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, kw, NULL, exts);
}
/**
* @brief Parse path element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] kw Type of current element.
* @param[out] type Type structure to store parsed value, flags and extension instances.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_path(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum ly_stmt kw,
- struct lysp_type *type)
+yin_parse_path(struct lys_yin_parser_ctx *ctx, enum ly_stmt kw, struct lysp_type *type)
{
- LY_CHECK_RET(yin_parse_simple_element(ctx, attrs, data, kw, &type->path,
- YIN_ARG_VALUE, Y_STR_ARG, &type->exts));
+ LY_CHECK_RET(yin_parse_simple_element(ctx, kw, &type->path, YIN_ARG_VALUE, Y_STR_ARG, &type->exts));
type->flags |= LYS_SET_PATH;
return LY_SUCCESS;
@@ -498,32 +464,29 @@
* @brief Parse pattern element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] type Type structure to store parsed value, flags and extension instances.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_pattern(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_type *type)
+yin_parse_pattern(struct lys_yin_parser_ctx *ctx, struct lysp_type *type)
{
const char *real_value = NULL;
char *saved_value = NULL;
struct lysp_restr *restr;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, type->patterns, restr, LY_EMEM);
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &real_value, Y_STR_ARG, LY_STMT_PATTERN));
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, type->patterns, restr, LY_EMEM);
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &real_value, Y_STR_ARG, LY_STMT_PATTERN));
size_t len = strlen(real_value);
saved_value = malloc(len + 2);
- LY_CHECK_ERR_RET(!saved_value, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!saved_value, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
memmove(saved_value + 1, real_value, len);
- FREE_STRING(ctx->xml_ctx.ctx, real_value);
+ FREE_STRING(ctx->xmlctx->ctx, real_value);
saved_value[0] = 0x06;
saved_value[len + 1] = '\0';
- restr->arg = lydict_insert_zc(ctx->xml_ctx.ctx, saved_value);
- LY_CHECK_ERR_RET(!restr->arg, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ restr->arg = lydict_insert_zc(ctx->xmlctx->ctx, saved_value);
+ LY_CHECK_ERR_RET(!restr->arg, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
type->flags |= LYS_SET_PATTERN;
struct yin_subelement subelems[6] = {
@@ -534,32 +497,29 @@
{LY_STMT_REFERENCE, &restr->ref, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, 6, data, LY_STMT_PATTERN, NULL, &restr->exts);
+ return yin_parse_content(ctx, subelems, 6, LY_STMT_PATTERN, NULL, &restr->exts);
}
/**
* @brief Parse fraction-digits element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] type Type structure to store value, flags and extension instances.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_fracdigits(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_type *type)
+yin_parse_fracdigits(struct lys_yin_parser_ctx *ctx, struct lysp_type *type)
{
const char *temp_val = NULL;
char *ptr;
unsigned long int num;
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_FRACTION_DIGITS));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_FRACTION_DIGITS));
if (temp_val[0] == '\0' || (temp_val[0] == '0') || !isdigit(temp_val[0])) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "fraction-digits");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
@@ -567,43 +527,41 @@
num = strtoul(temp_val, &ptr, 10);
if (*ptr != '\0') {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "fraction-digits");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
if ((errno == ERANGE) || (num > 18)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "fraction-digits");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
type->fraction_digits = num;
type->flags |= LYS_SET_FRDIGITS;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_FRACTION_DIGITS, NULL, &type->exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_FRACTION_DIGITS, NULL, &type->exts);
}
/**
* @brief Parse enum element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] type Type structure to store parsed value, flags and extension instances.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_enum(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, struct lysp_type *type)
+yin_parse_enum(struct lys_yin_parser_ctx *ctx, struct lysp_type *type)
{
struct lysp_type_enum *en;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, type->enums, en, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, type->enums, en, LY_EMEM);
type->flags |= LYS_SET_ENUM;
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &en->name, Y_STR_ARG, LY_STMT_ENUM));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &en->name, Y_STR_ARG, LY_STMT_ENUM));
LY_CHECK_RET(lysp_check_enum_name((struct lys_parser_ctx *)ctx, en->name, strlen(en->name)));
- YANG_CHECK_NONEMPTY((struct lys_parser_ctx *)ctx, strlen(en->name), "enum");
+ CHECK_NONEMPTY((struct lys_parser_ctx *)ctx, strlen(en->name), "enum");
CHECK_UNIQUENESS((struct lys_parser_ctx *)ctx, type->enums, name, "enum", en->name);
struct yin_subelement subelems[6] = {
@@ -614,28 +572,25 @@
{LY_STMT_VALUE, en, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, 6, data, LY_STMT_ENUM, NULL, &en->exts);
+ return yin_parse_content(ctx, subelems, 6, LY_STMT_ENUM, NULL, &en->exts);
}
/**
* @brief Parse bit element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] type Type structure to store parsed value, flags and extension instances.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_bit(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_type *type)
+yin_parse_bit(struct lys_yin_parser_ctx *ctx, struct lysp_type *type)
{
struct lysp_type_enum *en;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, type->bits, en, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, type->bits, en, LY_EMEM);
type->flags |= LYS_SET_BIT;
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &en->name, Y_IDENTIF_ARG, LY_STMT_BIT));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &en->name, Y_IDENTIF_ARG, LY_STMT_BIT));
CHECK_UNIQUENESS((struct lys_parser_ctx *)ctx, type->enums, name, "bit", en->name);
struct yin_subelement subelems[6] = {
@@ -646,7 +601,7 @@
{LY_STMT_STATUS, &en->flags, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, 6, data, LY_STMT_BIT, NULL, &en->exts);
+ return yin_parse_content(ctx, subelems, 6, LY_STMT_BIT, NULL, &en->exts);
}
/**
@@ -654,55 +609,50 @@
* more instances, such as base or if-feature.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] kw Type of current element.
* @param[out] values Parsed values to add to.
* @param[in] arg_type Expected type of attribute.
* @param[in] arg_val_type Type of expected value of attribute.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_simple_elements(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum ly_stmt kw,
- const char ***values, enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
+yin_parse_simple_elements(struct lys_yin_parser_ctx *ctx, enum ly_stmt kw, const char ***values, enum yin_argument arg_type,
+ enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
{
const char **value;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *values, value, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *values, value, LY_EMEM);
uint32_t index = LY_ARRAY_SIZE(*values) - 1;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, &index, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, arg_type, value, arg_val_type, kw));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, value, arg_val_type, kw));
- return yin_parse_content(ctx, subelems, 1, data, kw, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, kw, NULL, exts);
}
/**
* @brief Parse simple element without any special constraints and argument mapped to yin attribute.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] kw Type of current element.
* @param[in] subinfo Information about subelement, is used to determin which function should be called and where to store parsed value.
* @param[in] arg_type Expected type of attribute.
* @param[in] arg_val_type Type of expected value of attribute.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_simple_elem(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum ly_stmt kw,
- struct yin_subelement *subinfo, enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
+yin_parse_simple_elem(struct lys_yin_parser_ctx *ctx, enum ly_stmt kw, struct yin_subelement *subinfo,
+ enum yin_argument arg_type, enum yang_arg arg_val_type, struct lysp_ext_instance **exts)
{
if (subinfo->flags & YIN_SUBELEM_UNIQUE) {
- LY_CHECK_RET(yin_parse_simple_element(ctx, attrs, data, kw, (const char **)subinfo->dest,
+ LY_CHECK_RET(yin_parse_simple_element(ctx, kw, (const char **)subinfo->dest,
arg_type, arg_val_type, exts));
} else {
- LY_CHECK_RET(yin_parse_simple_elements(ctx, attrs, data, kw, (const char ***)subinfo->dest,
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, kw, (const char ***)subinfo->dest,
arg_type, arg_val_type, exts));
}
@@ -713,30 +663,26 @@
* @brief Parse base element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] parent Identification of parent element.
* @param[out] dest Where parsed values should be stored.
* @param[in,out] exts Extension instances to add to.
- *
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_base(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum ly_stmt parent,
- void *dest, struct lysp_ext_instance **exts)
+yin_parse_base(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, void *dest, struct lysp_ext_instance **exts)
{
struct lysp_type *type = NULL;
if (parent == LY_STMT_TYPE) {
type = (struct lysp_type *)dest;
- LY_CHECK_RET(yin_parse_simple_elements(ctx, attrs, data, LY_STMT_BASE, &type->bases, YIN_ARG_NAME,
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, LY_STMT_BASE, &type->bases, YIN_ARG_NAME,
Y_PREF_IDENTIF_ARG, exts));
type->flags |= LYS_SET_BASE;
} else if (parent == LY_STMT_IDENTITY) {
- LY_CHECK_RET(yin_parse_simple_elements(ctx, attrs, data, LY_STMT_BASE, (const char ***)dest,
+ LY_CHECK_RET(yin_parse_simple_elements(ctx, LY_STMT_BASE, (const char ***)dest,
YIN_ARG_NAME, Y_PREF_IDENTIF_ARG, exts));
} else {
- LOGINT(ctx->xml_ctx.ctx);
+ LOGINT(ctx->xmlctx->ctx);
return LY_EINT;
}
@@ -747,15 +693,11 @@
* @brief Parse require-instance element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
- * @prama[out] type Type structure to store value, flag and extensions.
- *
+ * @param[out] type Type structure to store value, flag and extensions.
* @return LY_ERR values.
*/
static LY_ERR
-yin_pasrse_reqinstance(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs,
- const char **data, struct lysp_type *type)
+yin_pasrse_reqinstance(struct lys_yin_parser_ctx *ctx, struct lysp_type *type)
{
const char *temp_val = NULL;
struct yin_subelement subelems[1] = {
@@ -763,34 +705,32 @@
};
type->flags |= LYS_SET_REQINST;
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_REQUIRE_INSTANCE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_REQUIRE_INSTANCE));
if (strcmp(temp_val, "true") == 0) {
type->require_instance = 1;
} else if (strcmp(temp_val, "false") != 0) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS2, temp_val, "value",
"require-instance", "true", "false");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_REQUIRE_INSTANCE, NULL, &type->exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_REQUIRE_INSTANCE, NULL, &type->exts);
}
/**
* @brief Parse modifier element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] pat Value to write to.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_modifier(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- const char **pat, struct lysp_ext_instance **exts)
+yin_parse_modifier(struct lys_yin_parser_ctx *ctx, const char **pat, struct lysp_ext_instance **exts)
{
assert(**pat == 0x06);
const char *temp_val;
@@ -799,40 +739,38 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MODIFIER));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MODIFIER));
if (strcmp(temp_val, "invert-match") != 0) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS1, temp_val, "value",
"modifier", "invert-match");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
- lydict_remove(ctx->xml_ctx.ctx, temp_val);
+ lydict_remove(ctx->xmlctx->ctx, temp_val);
/* allocate new value */
modified_val = malloc(strlen(*pat) + 1);
- LY_CHECK_ERR_RET(!modified_val, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!modified_val, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
strcpy(modified_val, *pat);
- lydict_remove(ctx->xml_ctx.ctx, *pat);
+ lydict_remove(ctx->xmlctx->ctx, *pat);
/* modify the new value */
modified_val[0] = 0x15;
- *pat = lydict_insert_zc(ctx->xml_ctx.ctx, modified_val);
+ *pat = lydict_insert_zc(ctx->xmlctx->ctx, modified_val);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_MODIFIER, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_MODIFIER, NULL, exts);
}
/**
* @brief Parse a restriction element (length, range or one instance of must).
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] restr_kw Identificaton of element that is being parsed, can be set to LY_STMT_MUST, LY_STMT_LENGTH or LY_STMT_RANGE.
* @param[in] restr Value to write to.
*/
static LY_ERR
-yin_parse_restriction(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- enum ly_stmt restr_kw, struct lysp_restr *restr)
+yin_parse_restriction(struct lys_yin_parser_ctx *ctx, enum ly_stmt restr_kw, struct lysp_restr *restr)
{
assert(restr_kw == LY_STMT_MUST || restr_kw == LY_STMT_LENGTH || restr_kw == LY_STMT_RANGE);
struct yin_subelement subelems[5] = {
@@ -844,28 +782,27 @@
};
/* argument of must is called condition, but argument of length and range is called value */
enum yin_argument arg_type = (restr_kw == LY_STMT_MUST) ? YIN_ARG_CONDITION : YIN_ARG_VALUE;
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, arg_type, &restr->arg, Y_STR_ARG, restr_kw));
- return yin_parse_content(ctx, subelems, 5, data, restr_kw, NULL, &restr->exts);
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, arg_type, &restr->arg, Y_STR_ARG, restr_kw));
+
+ return yin_parse_content(ctx, subelems, 5, restr_kw, NULL, &restr->exts);
}
/**
* @brief Parse range element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[out] type Type structure to store parsed value and flags.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_range(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs,
- const char **data, struct lysp_type *type)
+yin_parse_range(struct lys_yin_parser_ctx *ctx, struct lysp_type *type)
{
type->range = calloc(1, sizeof *type->range);
- LY_CHECK_ERR_RET(!type->range, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
- LY_CHECK_RET(yin_parse_restriction(ctx, attrs, data, LY_STMT_RANGE, type->range));
+ LY_CHECK_ERR_RET(!type->range, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
+ LY_CHECK_RET(yin_parse_restriction(ctx, LY_STMT_RANGE, type->range));
type->flags |= LYS_SET_RANGE;
return LY_SUCCESS;
@@ -875,19 +812,16 @@
* @brief Parse length element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[out] type Type structure to store parsed value and flags.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_length(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs,
- const char **data, struct lysp_type *type)
+yin_parse_length(struct lys_yin_parser_ctx *ctx, struct lysp_type *type)
{
type->length = calloc(1, sizeof *type->length);
- LY_CHECK_ERR_RET(!type->length, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
- LY_CHECK_RET(yin_parse_restriction(ctx, attrs, data, LY_STMT_LENGTH, type->length));
+ LY_CHECK_ERR_RET(!type->length, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
+ LY_CHECK_RET(yin_parse_restriction(ctx, LY_STMT_LENGTH, type->length));
type->flags |= LYS_SET_LENGTH;
return LY_SUCCESS;
@@ -897,35 +831,30 @@
* @brief Parse must element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] restrs Restrictions to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_must(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, struct lysp_restr **restrs)
+yin_parse_must(struct lys_yin_parser_ctx *ctx, struct lysp_restr **restrs)
{
struct lysp_restr *restr;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *restrs, restr, LY_EMEM);
- return yin_parse_restriction(ctx, attrs, data, LY_STMT_MUST, restr);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *restrs, restr, LY_EMEM);
+ return yin_parse_restriction(ctx, LY_STMT_MUST, restr);
}
/**
* @brief Parse position or value element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] kw Type of current element, can be set to LY_STMT_POSITION or LY_STMT_VALUE.
* @param[out] enm Enum structure to save value, flags and extension instances.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_value_pos(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- enum ly_stmt kw, struct lysp_type_enum *enm)
+yin_parse_value_pos(struct lys_yin_parser_ctx *ctx, enum ly_stmt kw, struct lysp_type_enum *enm)
{
assert(kw == LY_STMT_POSITION || kw == LY_STMT_VALUE);
const char *temp_val = NULL;
@@ -937,7 +866,8 @@
enm->flags |= LYS_SET_VALUE;
/* get attribute value */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, kw));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, kw));
if (!temp_val || temp_val[0] == '\0' || (temp_val[0] == '+') ||
((temp_val[0] == '0') && (temp_val[1] != '\0')) || ((kw == LY_STMT_POSITION) && !strcmp(temp_val, "-0"))) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", ly_stmt2str(kw));
@@ -974,42 +904,40 @@
} else {
enm->value = unum;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
/* parse subelements */
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, 1, data, kw, NULL, &enm->exts);
+ return yin_parse_content(ctx, subelems, 1, kw, NULL, &enm->exts);
error:
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
- return LY_EVALID;
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
+ return LY_EVALID;
}
-
/**
* @brief Parse belongs-to element.
*
* @param[in] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[out] submod Structure of submodule that is being parsed.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values
*/
static LY_ERR
-yin_parse_belongs_to(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_submodule *submod, struct lysp_ext_instance **exts)
+yin_parse_belongs_to(struct lys_yin_parser_ctx *ctx, struct lysp_submodule *submod, struct lysp_ext_instance **exts)
{
struct yin_subelement subelems[2] = {
{LY_STMT_PREFIX, &submod->prefix, YIN_SUBELEM_MANDATORY | YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_MODULE, &submod->belongsto, Y_IDENTIF_ARG, LY_STMT_BELONGS_TO));
- return yin_parse_content(ctx, subelems, 2, data, LY_STMT_BELONGS_TO, NULL, exts);
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, &submod->belongsto, Y_IDENTIF_ARG, LY_STMT_BELONGS_TO));
+
+ return yin_parse_content(ctx, subelems, 2, LY_STMT_BELONGS_TO, NULL, exts);
}
/**
@@ -1017,8 +945,6 @@
* text element as child.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] elem_type Type of element can be set to LY_STMT_ORGANIZATION or LY_STMT_CONTACT or LY_STMT_DESCRIPTION or LY_STMT_REFERENCE.
* @param[out] value Where the content of meta element should be stored.
* @param[in,out] exts Extension instances to add to.
@@ -1026,8 +952,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_meta(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- enum ly_stmt elem_type, const char **value, struct lysp_ext_instance **exts)
+yin_parse_meta(struct lys_yin_parser_ctx *ctx, enum ly_stmt elem_type, const char **value, struct lysp_ext_instance **exts)
{
assert(elem_type == LY_STMT_ORGANIZATION || elem_type == LY_STMT_CONTACT || elem_type == LY_STMT_DESCRIPTION || elem_type == LY_STMT_REFERENCE);
@@ -1036,26 +961,24 @@
{LY_STMT_ARG_TEXT, value, YIN_SUBELEM_MANDATORY | YIN_SUBELEM_UNIQUE | YIN_SUBELEM_FIRST}
};
/* check attributes */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, elem_type));
/* parse content */
- return yin_parse_content(ctx, subelems, 2, data, elem_type, NULL, exts);
+ return yin_parse_content(ctx, subelems, 2, elem_type, NULL, exts);
}
/**
* @brief Parse error-message element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from.
* @param[out] value Where the content of error-message element should be stored.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_err_msg(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- const char **value, struct lysp_ext_instance **exts)
+yin_parse_err_msg(struct lys_yin_parser_ctx *ctx, const char **value, struct lysp_ext_instance **exts)
{
struct yin_subelement subelems[2] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
@@ -1063,30 +986,28 @@
};
/* check attributes */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, LY_STMT_ERROR_MESSAGE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, LY_STMT_ERROR_MESSAGE));
- return yin_parse_content(ctx, subelems, 2, data, LY_STMT_ERROR_MESSAGE, NULL, exts);
+ return yin_parse_content(ctx, subelems, 2, LY_STMT_ERROR_MESSAGE, NULL, exts);
}
/**
* @brief Parse type element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] parent Identification of parent element.
* @param[in,out] type Type to write to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_type(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- enum ly_stmt parent, struct yin_subelement *subinfo)
+yin_parse_type(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, struct yin_subelement *subinfo)
{
struct lysp_type *type = NULL;
if (parent == LY_STMT_DEVIATE) {
*(struct lysp_type **)subinfo->dest = calloc(1, sizeof **(struct lysp_type **)subinfo->dest);
- LY_CHECK_ERR_RET(!(*(struct lysp_type **)subinfo->dest), LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!(*(struct lysp_type **)subinfo->dest), LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
type = *((struct lysp_type **)subinfo->dest);
} else {
type = (struct lysp_type *)subinfo->dest;
@@ -1094,7 +1015,7 @@
/* type as child of another type */
if (parent == LY_STMT_TYPE) {
struct lysp_type *nested_type = NULL;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, type->types, nested_type, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, type->types, nested_type, LY_EMEM);
type->flags |= LYS_SET_TYPE;
type = nested_type;
}
@@ -1111,16 +1032,16 @@
{LY_STMT_TYPE, type},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &type->name, Y_PREF_IDENTIF_ARG, LY_STMT_TYPE));
- return yin_parse_content(ctx, subelems, 11, data, LY_STMT_TYPE, NULL, &type->exts);
+
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &type->name, Y_PREF_IDENTIF_ARG, LY_STMT_TYPE));
+ return yin_parse_content(ctx, subelems, 11, LY_STMT_TYPE, NULL, &type->exts);
}
/**
* @brief Parse max-elements element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] max Value to write to.
* @param[in] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
@@ -1128,8 +1049,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_maxelements(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, uint32_t *max,
- uint16_t *flags, struct lysp_ext_instance **exts)
+yin_parse_maxelements(struct lys_yin_parser_ctx *ctx, uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *temp_val = NULL;
char *ptr;
@@ -1139,10 +1059,11 @@
};
*flags |= LYS_SET_MAX;
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MAX_ELEMENTS));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MAX_ELEMENTS));
if (!temp_val || temp_val[0] == '\0' || temp_val[0] == '0' || (temp_val[0] != 'u' && !isdigit(temp_val[0]))) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "max-elements");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
@@ -1151,26 +1072,24 @@
num = strtoul(temp_val, &ptr, 10);
if (*ptr != '\0') {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "max-elements");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
if ((errno == ERANGE) || (num > UINT32_MAX)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_OOB_YIN, temp_val, "value", "max-elements");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
*max = num;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_MAX_ELEMENTS, NULL, exts);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_MAX_ELEMENTS, NULL, exts);
}
/**
* @brief Parse min-elements element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] min Value to write to.
* @param[in] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
@@ -1178,8 +1097,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_minelements(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, uint32_t *min,
- uint16_t *flags, struct lysp_ext_instance **exts)
+yin_parse_minelements(struct lys_yin_parser_ctx *ctx, uint32_t *min, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *temp_val = NULL;
char *ptr;
@@ -1189,11 +1107,12 @@
};
*flags |= LYS_SET_MIN;
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MIN_ELEMENTS));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MIN_ELEMENTS));
if (!temp_val || temp_val[0] == '\0' || (temp_val[0] == '0' && temp_val[1] != '\0')) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "min-elements");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
@@ -1201,25 +1120,23 @@
num = strtoul(temp_val, &ptr, 10);
if (ptr[0] != 0) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN, temp_val, "value", "min-elements");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
if (errno == ERANGE || num > UINT32_MAX) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_OOB_YIN, temp_val, "value", "min-elements");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
*min = num;
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_MIN_ELEMENTS, NULL, exts);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_MIN_ELEMENTS, NULL, exts);
}
/**
* @brief Parse min-elements or max-elements element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] parent Identification of parent element.
* @param[in] current Identification of current element.
* @param[in] dest Where the parsed value and flags should be stored.
@@ -1227,8 +1144,7 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_minmax(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- enum ly_stmt parent, enum ly_stmt current, void *dest)
+yin_parse_minmax(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, enum ly_stmt current, void *dest)
{
assert(current == LY_STMT_MAX_ELEMENTS || current == LY_STMT_MIN_ELEMENTS);
assert(parent == LY_STMT_LEAF_LIST || parent == LY_STMT_REFINE || parent == LY_STMT_LIST || parent == LY_STMT_DEVIATE);
@@ -1255,9 +1171,9 @@
}
if (current == LY_STMT_MAX_ELEMENTS) {
- LY_CHECK_RET(yin_parse_maxelements(ctx, attrs, data, lim, flags, exts));
+ LY_CHECK_RET(yin_parse_maxelements(ctx, lim, flags, exts));
} else {
- LY_CHECK_RET(yin_parse_minelements(ctx, attrs, data, lim, flags, exts));
+ LY_CHECK_RET(yin_parse_minelements(ctx, lim, flags, exts));
}
return LY_SUCCESS;
@@ -1267,23 +1183,21 @@
* @brief Parse ordered-by element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[out] flags Flags to write to.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_orderedby(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- uint16_t *flags, struct lysp_ext_instance **exts)
+yin_parse_orderedby(struct lys_yin_parser_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *temp_val;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_ORDERED_BY));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_ORDERED_BY));
if (strcmp(temp_val, "system") == 0) {
*flags |= LYS_ORDBY_SYSTEM;
} else if (strcmp(temp_val, "user") == 0) {
@@ -1291,38 +1205,36 @@
} else {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS2, temp_val, "value",
"ordered-by", "system", "user");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_ORDERED_BY, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_ORDERED_BY, NULL, exts);
}
/**
* @brief Parse any-data or any-xml element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] any_kw Identification of current element, can be set to LY_STMT_ANYDATA or LY_STMT_ANYXML
* @param[in] node_meta Meta information about parent node and siblings to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_any(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- enum ly_stmt any_kw, struct tree_node_meta *node_meta)
+yin_parse_any(struct lys_yin_parser_ctx *ctx, enum ly_stmt any_kw, struct tree_node_meta *node_meta)
{
struct lysp_node_anydata *any;
/* create new sibling */
- LY_LIST_NEW_RET(ctx->xml_ctx.ctx, node_meta->nodes, any, next, LY_EMEM);
+ LY_LIST_NEW_RET(ctx->xmlctx->ctx, node_meta->nodes, any, next, LY_EMEM);
any->nodetype = (any_kw == LY_STMT_ANYDATA) ? LYS_ANYDATA : LYS_ANYXML;
any->parent = node_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &any->name, Y_IDENTIF_ARG, any_kw));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &any->name, Y_IDENTIF_ARG, any_kw));
struct yin_subelement subelems[9] = {
{LY_STMT_CONFIG, &any->flags, YIN_SUBELEM_UNIQUE},
@@ -1335,32 +1247,30 @@
{LY_STMT_WHEN, &any->when, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, 9, data, any_kw, NULL, &any->exts);
+ return yin_parse_content(ctx, subelems, 9, any_kw, NULL, &any->exts);
}
/**
* @brief parse leaf element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] node_meta Meta information about parent node and siblings to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_leaf(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *node_meta)
+yin_parse_leaf(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *node_meta)
{
struct lysp_node_leaf *leaf;
/* create structure new leaf */
- LY_LIST_NEW_RET(ctx->xml_ctx.ctx, node_meta->nodes, leaf, next, LY_EMEM);
+ LY_LIST_NEW_RET(ctx->xmlctx->ctx, node_meta->nodes, leaf, next, LY_EMEM);
leaf->nodetype = LYS_LEAF;
leaf->parent = node_meta->parent;
/* parser argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &leaf->name, Y_IDENTIF_ARG, LY_STMT_LEAF));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &leaf->name, Y_IDENTIF_ARG, LY_STMT_LEAF));
/* parse content */
struct yin_subelement subelems[12] = {
@@ -1377,32 +1287,30 @@
{LY_STMT_WHEN, &leaf->when, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, 12, data, LY_STMT_LEAF, NULL, &leaf->exts);
+ return yin_parse_content(ctx, subelems, 12, LY_STMT_LEAF, NULL, &leaf->exts);
}
/**
* @brief Parse leaf-list element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] node_meta Meta information about parent node and siblings to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_leaflist(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *node_meta)
+yin_parse_leaflist(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *node_meta)
{
struct lysp_node_leaflist *llist;
- LY_LIST_NEW_RET(ctx->xml_ctx.ctx, node_meta->nodes, llist, next, LY_EMEM);
+ LY_LIST_NEW_RET(ctx->xmlctx->ctx, node_meta->nodes, llist, next, LY_EMEM);
llist->nodetype = LYS_LEAFLIST;
llist->parent = node_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &llist->name, Y_IDENTIF_ARG, LY_STMT_LEAF_LIST));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &llist->name, Y_IDENTIF_ARG, LY_STMT_LEAF_LIST));
/* parse content */
struct yin_subelement subelems[14] = {
@@ -1421,7 +1329,7 @@
{LY_STMT_WHEN, &llist->when, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, 14, data, LY_STMT_LEAF_LIST, NULL, &llist->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, 14, LY_STMT_LEAF_LIST, NULL, &llist->exts));
/* check invalid combination of subelements */
if ((llist->min) && (llist->dflts)) {
@@ -1440,22 +1348,20 @@
* @brief Parse typedef element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] typedef_meta Meta information about parent node and typedefs to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_typedef(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *typedef_meta)
+yin_parse_typedef(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *typedef_meta)
{
struct lysp_tpdf *tpdf;
struct lysp_tpdf **tpdfs = (struct lysp_tpdf **)typedef_meta->nodes;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *tpdfs, tpdf, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *tpdfs, tpdf, LY_EMEM);
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &tpdf->name, Y_IDENTIF_ARG, LY_STMT_TYPEDEF));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &tpdf->name, Y_IDENTIF_ARG, LY_STMT_TYPEDEF));
/* parse content */
struct yin_subelement subelems[7] = {
@@ -1467,7 +1373,7 @@
{LY_STMT_UNITS, &tpdf->units, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, 7, data, LY_STMT_TYPEDEF, NULL, &tpdf->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, 7, LY_STMT_TYPEDEF, NULL, &tpdf->exts));
/* store data for collision check */
if (typedef_meta->parent && !(typedef_meta->parent->nodetype & (LYS_GROUPING | LYS_ACTION | LYS_INOUT | LYS_NOTIF))) {
@@ -1481,24 +1387,22 @@
* @brief Parse refine element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] refines Refines to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_refine(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_refine **refines)
+yin_parse_refine(struct lys_yin_parser_ctx *ctx, struct lysp_refine **refines)
{
struct lysp_refine *rf;
/* allocate new refine */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *refines, rf, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *refines, rf, LY_EMEM);
/* parse attribute */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_TARGET_NODE, &rf->nodeid, Y_STR_ARG, LY_STMT_REFINE));
- YANG_CHECK_NONEMPTY((struct lys_parser_ctx *)ctx, strlen(rf->nodeid), "refine");
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TARGET_NODE, &rf->nodeid, Y_STR_ARG, LY_STMT_REFINE));
+ CHECK_NONEMPTY(ctx, strlen(rf->nodeid), "refine");
/* parse content */
struct yin_subelement subelems[11] = {
@@ -1514,32 +1418,30 @@
{LY_STMT_REFERENCE, &rf->ref, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, 11, data, LY_STMT_REFINE, NULL, &rf->exts);
+ return yin_parse_content(ctx, subelems, 11, LY_STMT_REFINE, NULL, &rf->exts);
}
/**
* @brief Parse uses element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] node_meta Meta information about parent node and siblings to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_uses(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *node_meta)
+yin_parse_uses(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *node_meta)
{
struct lysp_node_uses *uses;
/* create new uses */
- LY_LIST_NEW_RET(ctx->xml_ctx.ctx, node_meta->nodes, uses, next, LY_EMEM);
+ LY_LIST_NEW_RET(ctx->xmlctx->ctx, node_meta->nodes, uses, next, LY_EMEM);
uses->nodetype = LYS_USES;
uses->parent = node_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &uses->name, Y_PREF_IDENTIF_ARG, LY_STMT_USES));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &uses->name, Y_PREF_IDENTIF_ARG, LY_STMT_USES));
/* parse content */
struct tree_node_meta augments = {(struct lysp_node *)uses, (struct lysp_node **)&uses->augments};
@@ -1553,7 +1455,7 @@
{LY_STMT_WHEN, &uses->when, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- LY_CHECK_RET(yin_parse_content(ctx, subelems, 8, data, LY_STMT_USES, NULL, &uses->exts));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, 8, LY_STMT_USES, NULL, &uses->exts));
LY_CHECK_RET(lysp_parse_finalize_reallocated((struct lys_parser_ctx *)ctx, NULL, uses->augments, NULL, NULL));
return LY_SUCCESS;
@@ -1563,31 +1465,29 @@
* @brief Parse revision element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] revs Parsed revisions to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_revision(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_revision **revs)
+yin_parse_revision(struct lys_yin_parser_ctx *ctx, struct lysp_revision **revs)
{
struct lysp_revision *rev;
const char *temp_date = NULL;
/* allocate new reivison */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *revs, rev, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *revs, rev, LY_EMEM);
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_DATE, &temp_date, Y_STR_ARG, LY_STMT_REVISION));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_DATE, &temp_date, Y_STR_ARG, LY_STMT_REVISION));
/* check value */
if (lysp_check_date((struct lys_parser_ctx *)ctx, temp_date, strlen(temp_date), "revision")) {
- FREE_STRING(ctx->xml_ctx.ctx, temp_date);
+ FREE_STRING(ctx->xmlctx->ctx, temp_date);
return LY_EVALID;
}
strcpy(rev->date, temp_date);
- FREE_STRING(ctx->xml_ctx.ctx, temp_date);
+ FREE_STRING(ctx->xmlctx->ctx, temp_date);
/* parse content */
struct yin_subelement subelems[3] = {
@@ -1595,34 +1495,32 @@
{LY_STMT_REFERENCE, &rev->ref, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, 3, data, LY_STMT_REVISION, NULL, &rev->exts);
+ return yin_parse_content(ctx, subelems, 3, LY_STMT_REVISION, NULL, &rev->exts);
}
/**
* @brief Parse include element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] inc_meta Meta informatinou about module/submodule name and includes to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_include(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct include_meta *inc_meta)
+yin_parse_include(struct lys_yin_parser_ctx *ctx, struct include_meta *inc_meta)
{
struct lysp_include *inc;
/* allocate new include */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *inc_meta->includes, inc, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *inc_meta->includes, inc, LY_EMEM);
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_MODULE, &inc->name, Y_IDENTIF_ARG, LY_STMT_INCLUDE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, &inc->name, Y_IDENTIF_ARG, LY_STMT_INCLUDE));
/* submodules share the namespace with the module names, so there must not be
* a module of the same name in the context, no need for revision matching */
- if (!strcmp(inc_meta->name, inc->name) || ly_ctx_get_module_latest(ctx->xml_ctx.ctx, inc->name)) {
+ if (!strcmp(inc_meta->name, inc->name) || ly_ctx_get_module_latest(ctx->xmlctx->ctx, inc->name)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_NAME_COL, inc->name);
return LY_EVALID;
}
@@ -1634,60 +1532,56 @@
{LY_STMT_REVISION_DATE, &inc->rev, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, 4, data, LY_STMT_INCLUDE, NULL, &inc->exts);
+ return yin_parse_content(ctx, subelems, 4, LY_STMT_INCLUDE, NULL, &inc->exts);
}
/**
* @brief Parse revision-date element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of revision-date element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] rev Array to store the parsed value in.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_revision_date(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, char *rev,
- struct lysp_ext_instance **exts)
+yin_parse_revision_date(struct lys_yin_parser_ctx *ctx, char *rev, struct lysp_ext_instance **exts)
{
const char *temp_rev;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_DATE, &temp_rev, Y_STR_ARG, LY_STMT_REVISION_DATE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_DATE, &temp_rev, Y_STR_ARG, LY_STMT_REVISION_DATE));
LY_CHECK_ERR_RET(lysp_check_date((struct lys_parser_ctx *)ctx, temp_rev, strlen(temp_rev), "revision-date") != LY_SUCCESS,
- FREE_STRING(ctx->xml_ctx.ctx, temp_rev), LY_EVALID);
+ FREE_STRING(ctx->xmlctx->ctx, temp_rev), LY_EVALID);
strcpy(rev, temp_rev);
- FREE_STRING(ctx->xml_ctx.ctx, temp_rev);
+ FREE_STRING(ctx->xmlctx->ctx, temp_rev);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_REVISION_DATE, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_REVISION_DATE, NULL, exts);
}
/**
* @brief Parse config element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of import element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_config(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, uint16_t *flags,
- struct lysp_ext_instance **exts)
+yin_parse_config(struct lys_yin_parser_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *temp_val = NULL;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_CONFIG));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_CONFIG));
if (strcmp(temp_val, "true") == 0) {
*flags |= LYS_CONFIG_W;
} else if (strcmp(temp_val, "false") == 0) {
@@ -1695,35 +1589,33 @@
} else {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS2, temp_val, "value", "config",
"true", "false");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_CONFIG, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_CONFIG, NULL, exts);
}
/**
* @brief Parse yang-version element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of yang-version element.
- * @param[in] data Data to read from, always moved to currently handled character.
* @param[out] version Storage for the parsed information.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_yangversion(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, uint8_t *version,
- struct lysp_ext_instance **exts)
+yin_parse_yangversion(struct lys_yin_parser_ctx *ctx, uint8_t *version, struct lysp_ext_instance **exts)
{
const char *temp_version = NULL;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_version, Y_STR_ARG, LY_STMT_YANG_VERSION));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_version, Y_STR_ARG, LY_STMT_YANG_VERSION));
if (strcmp(temp_version, "1.0") == 0) {
*version = LYS_VERSION_1_0;
} else if (strcmp(temp_version, "1.1") == 0) {
@@ -1731,31 +1623,29 @@
} else {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS2, temp_version, "value",
"yang-version", "1.0", "1.1");
- FREE_STRING(ctx->xml_ctx.ctx, temp_version);
+ FREE_STRING(ctx->xmlctx->ctx, temp_version);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_version);
+ FREE_STRING(ctx->xmlctx->ctx, temp_version);
ctx->mod_version = *version;
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_YANG_VERSION, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_YANG_VERSION, NULL, exts);
}
/**
* @brief Parse import element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of import element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] imp_meta Meta information about prefix and imports to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_import(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, struct import_meta *imp_meta)
+yin_parse_import(struct lys_yin_parser_ctx *ctx, struct import_meta *imp_meta)
{
struct lysp_import *imp;
/* allocate new element in sized array for import */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *imp_meta->imports, imp, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *imp_meta->imports, imp, LY_EMEM);
struct yin_subelement subelems[5] = {
{LY_STMT_DESCRIPTION, &imp->dsc, YIN_SUBELEM_UNIQUE},
@@ -1766,8 +1656,9 @@
};
/* parse import attributes */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_MODULE, &imp->name, Y_IDENTIF_ARG, LY_STMT_IMPORT));
- LY_CHECK_RET(yin_parse_content(ctx, subelems, 5, data, LY_STMT_IMPORT, NULL, &imp->exts));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, &imp->name, Y_IDENTIF_ARG, LY_STMT_IMPORT));
+ LY_CHECK_RET(yin_parse_content(ctx, subelems, 5, LY_STMT_IMPORT, NULL, &imp->exts));
/* check prefix validity */
LY_CHECK_RET(lysp_check_prefix((struct lys_parser_ctx *)ctx, *imp_meta->imports, imp_meta->prefix, &imp->prefix), LY_EVALID);
@@ -1778,23 +1669,21 @@
* @brief Parse mandatory element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of status element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_mandatory(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, uint16_t *flags,
- struct lysp_ext_instance **exts)
+yin_parse_mandatory(struct lys_yin_parser_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *temp_val = NULL;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MANDATORY));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_MANDATORY));
if (strcmp(temp_val, "true") == 0) {
*flags |= LYS_MAND_TRUE;
} else if (strcmp(temp_val, "false") == 0) {
@@ -1802,35 +1691,33 @@
} else {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS2, temp_val, "value",
"mandatory", "true", "false");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_MANDATORY, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_MANDATORY, NULL, exts);
}
/**
* @brief Parse status element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of status element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] flags Flags to add to.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_status(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, uint16_t *flags,
- struct lysp_ext_instance **exts)
+yin_parse_status(struct lys_yin_parser_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *value = NULL;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &value, Y_STR_ARG, LY_STMT_STATUS));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &value, Y_STR_ARG, LY_STMT_STATUS));
if (strcmp(value, "current") == 0) {
*flags |= LYS_STATUS_CURR;
} else if (strcmp(value, "deprecated") == 0) {
@@ -1840,31 +1727,30 @@
} else {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS3, value, "value",
"status", "current", "deprecated", "obsolete");
- FREE_STRING(ctx->xml_ctx.ctx, value);
+ FREE_STRING(ctx->xmlctx->ctx, value);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, value);
+ FREE_STRING(ctx->xmlctx->ctx, value);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_STATUS, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_STATUS, NULL, exts);
}
/**
* @brief Parse when element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of when element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[out] when_p When pointer to parse to.
*/
static LY_ERR
-yin_parse_when(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, struct lysp_when **when_p)
+yin_parse_when(struct lys_yin_parser_ctx *ctx, struct lysp_when **when_p)
{
struct lysp_when *when;
LY_ERR ret = LY_SUCCESS;
when = calloc(1, sizeof *when);
- LY_CHECK_ERR_RET(!when, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
- ret = yin_parse_attribute(ctx, attrs, YIN_ARG_CONDITION, &when->cond, Y_STR_ARG, LY_STMT_WHEN);
+ LY_CHECK_ERR_RET(!when, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ ret = yin_parse_attribute(ctx, YIN_ARG_CONDITION, &when->cond, Y_STR_ARG, LY_STMT_WHEN);
LY_CHECK_ERR_RET(ret, free(when), ret);
*when_p = when;
@@ -1874,14 +1760,13 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, 3, data, LY_STMT_WHEN, NULL, &when->exts);
+ return yin_parse_content(ctx, subelems, 3, LY_STMT_WHEN, NULL, &when->exts);
}
/**
* @brief Parse yin-elemenet element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of yin-element element.
* @param[in,out] data Data to read from, always moved to currently handled position.
* @param[in,out] flags Flags to add to.
* @prama[in,out] exts Extension instances to add to.
@@ -1889,15 +1774,15 @@
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_yin_element(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- uint16_t *flags, struct lysp_ext_instance **exts)
+yin_parse_yin_element(struct lys_yin_parser_ctx *ctx, uint16_t *flags, struct lysp_ext_instance **exts)
{
const char *temp_val = NULL;
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_YIN_ELEMENT));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_YIN_ELEMENT));
if (strcmp(temp_val, "true") == 0) {
*flags |= LYS_YINELEM_TRUE;
} else if (strcmp(temp_val, "false") == 0) {
@@ -1905,55 +1790,52 @@
} else {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS2, temp_val, "value",
"yin-element", "true", "false");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
- return yin_parse_content(ctx, subelems, 1, data, LY_STMT_YIN_ELEMENT, NULL, exts);
+ return yin_parse_content(ctx, subelems, 1, LY_STMT_YIN_ELEMENT, NULL, exts);
}
/**
* @brief Parse argument element.
*
- * @param[in,out] xml_ctx Xml context.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of argument element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
+ * @param[in,out] xmlctx Xml context.
* @param[in,out] arg_meta Meta information about destionation of parsed data.
* @param[in,out] exts Extension instances to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_argument(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct yin_argument_meta *arg_meta, struct lysp_ext_instance **exts)
+yin_parse_argument(struct lys_yin_parser_ctx *ctx, struct yin_argument_meta *arg_meta, struct lysp_ext_instance **exts)
{
struct yin_subelement subelems[2] = {
{LY_STMT_YIN_ELEMENT, arg_meta->flags, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, arg_meta->argument, Y_IDENTIF_ARG, LY_STMT_ARGUMENT));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, arg_meta->argument, Y_IDENTIF_ARG, LY_STMT_ARGUMENT));
- return yin_parse_content(ctx, subelems, 2, data, LY_STMT_ARGUMENT, NULL, exts);
+ return yin_parse_content(ctx, subelems, 2, LY_STMT_ARGUMENT, NULL, exts);
}
/**
* @brief Parse the extension statement.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of extension element.
- * @param[in,out] data Data to read from.
* @param[in,out] extensions Extensions to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_extension(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, struct lysp_ext **extensions)
+yin_parse_extension(struct lys_yin_parser_ctx *ctx, struct lysp_ext **extensions)
{
struct lysp_ext *ex;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *extensions, ex, LY_EMEM);
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &ex->name, Y_IDENTIF_ARG, LY_STMT_EXTENSION));
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *extensions, ex, LY_EMEM);
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &ex->name, Y_IDENTIF_ARG, LY_STMT_EXTENSION));
struct yin_argument_meta arg_info = {&ex->flags, &ex->argument};
struct yin_subelement subelems[5] = {
@@ -1964,30 +1846,28 @@
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- return yin_parse_content(ctx, subelems, 5, data, LY_STMT_EXTENSION, NULL, &ex->exts);
+ return yin_parse_content(ctx, subelems, 5, LY_STMT_EXTENSION, NULL, &ex->exts);
}
/**
* @brief Parse feature element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] features Features to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_feature(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_feature **features)
+yin_parse_feature(struct lys_yin_parser_ctx *ctx, struct lysp_feature **features)
{
struct lysp_feature *feat;
/* allocate new feature */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *features, feat, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *features, feat, LY_EMEM);
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &feat->name, Y_IDENTIF_ARG, LY_STMT_FEATURE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &feat->name, Y_IDENTIF_ARG, LY_STMT_FEATURE));
/* parse content */
struct yin_subelement subelems[5] = {
@@ -1997,30 +1877,28 @@
{LY_STMT_STATUS, &feat->flags, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, 5, data, LY_STMT_FEATURE, NULL, &feat->exts);
+ return yin_parse_content(ctx, subelems, 5, LY_STMT_FEATURE, NULL, &feat->exts);
}
/**
* @brief Parse identity element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] identities Identities to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_identity(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_ident **identities)
+yin_parse_identity(struct lys_yin_parser_ctx *ctx, struct lysp_ident **identities)
{
struct lysp_ident *ident;
/* allocate new identity */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *identities, ident, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *identities, ident, LY_EMEM);
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &ident->name, Y_IDENTIF_ARG, LY_STMT_IDENTITY));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &ident->name, Y_IDENTIF_ARG, LY_STMT_IDENTITY));
/* parse content */
struct yin_subelement subelems[6] = {
@@ -2031,33 +1909,31 @@
{LY_STMT_STATUS, &ident->flags, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, 6, data, LY_STMT_IDENTITY, NULL, &ident->exts);
+ return yin_parse_content(ctx, subelems, 6, LY_STMT_IDENTITY, NULL, &ident->exts);
}
/**
* @brief Parse list element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] node_meta Meta information about parent node and siblings to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_list(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *node_meta)
+yin_parse_list(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *node_meta)
{
struct lysp_node_list *list;
LY_ERR ret = LY_SUCCESS;
struct yin_subelement *subelems = NULL;
- LY_LIST_NEW_RET(ctx->xml_ctx.ctx, node_meta->nodes, list, next, LY_EMEM);
+ LY_LIST_NEW_RET(ctx->xmlctx->ctx, node_meta->nodes, list, next, LY_EMEM);
list->nodetype = LYS_LIST;
list->parent = node_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &list->name, Y_IDENTIF_ARG, LY_STMT_LIST));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &list->name, Y_IDENTIF_ARG, LY_STMT_LIST));
/* parse list content */
LY_CHECK_RET(subelems_allocator(ctx, 25, (struct lysp_node *)list, &subelems,
@@ -2087,7 +1963,7 @@
LY_STMT_WHEN, &list->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 25, data, LY_STMT_LIST, NULL, &list->exts);
+ ret = yin_parse_content(ctx, subelems, 25, LY_STMT_LIST, NULL, &list->exts);
subelems_deallocator(25, subelems);
LY_CHECK_RET(ret);
@@ -2106,15 +1982,12 @@
* @brief Parse notification element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] notif_meta Meta information about parent node and notifications to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_notification(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *notif_meta)
+yin_parse_notification(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *notif_meta)
{
struct lysp_notif *notif;
struct lysp_notif **notifs = (struct lysp_notif **)notif_meta->nodes;
@@ -2122,12 +1995,13 @@
struct yin_subelement *subelems = NULL;
/* allocate new notification */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *notifs, notif, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *notifs, notif, LY_EMEM);
notif->nodetype = LYS_NOTIF;
notif->parent = notif_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, ¬if->name, Y_IDENTIF_ARG, LY_STMT_NOTIFICATION));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, ¬if->name, Y_IDENTIF_ARG, LY_STMT_NOTIFICATION));
/* parse notification content */
LY_CHECK_RET(subelems_allocator(ctx, 16, (struct lysp_node *)notif, &subelems,
@@ -2149,7 +2023,7 @@
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 16, data, LY_STMT_NOTIFICATION, NULL, ¬if->exts);
+ ret = yin_parse_content(ctx, subelems, 16, LY_STMT_NOTIFICATION, NULL, ¬if->exts);
subelems_deallocator(16, subelems);
LY_CHECK_RET(ret);
@@ -2163,15 +2037,12 @@
* @brief Parse grouping element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in,out] gr_meta Meta information about parent node and groupings to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_grouping(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *gr_meta)
+yin_parse_grouping(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *gr_meta)
{
struct lysp_grp *grp;
struct lysp_grp **grps = (struct lysp_grp **)gr_meta->nodes;
@@ -2179,12 +2050,13 @@
struct yin_subelement *subelems = NULL;
/* create new grouping */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *grps, grp, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *grps, grp, LY_EMEM);
grp->nodetype = LYS_GROUPING;
grp->parent = gr_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &grp->name, Y_IDENTIF_ARG, LY_STMT_GROUPING));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &grp->name, Y_IDENTIF_ARG, LY_STMT_GROUPING));
/* parse grouping content */
LY_CHECK_RET(subelems_allocator(ctx, 16, (struct lysp_node *)grp, &subelems,
@@ -2205,7 +2077,7 @@
LY_STMT_USES, &grp->data, 0,
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 16, data, LY_STMT_GROUPING, NULL, &grp->exts);
+ ret = yin_parse_content(ctx, subelems, 16, LY_STMT_GROUPING, NULL, &grp->exts);
subelems_deallocator(16, subelems);
LY_CHECK_RET(ret);
@@ -2219,27 +2091,25 @@
* @brief Parse container element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] node_meta Meta information about parent node and siblings to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_container(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *node_meta)
+yin_parse_container(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *node_meta)
{
struct lysp_node_container *cont;
LY_ERR ret = LY_SUCCESS;
struct yin_subelement *subelems = NULL;
/* create new container */
- LY_LIST_NEW_RET(ctx->xml_ctx.ctx, node_meta->nodes, cont, next, LY_EMEM);
+ LY_LIST_NEW_RET(ctx->xmlctx->ctx, node_meta->nodes, cont, next, LY_EMEM);
cont->nodetype = LYS_CONTAINER;
cont->parent = node_meta->parent;
/* parse aegument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &cont->name, Y_IDENTIF_ARG, LY_STMT_CONTAINER));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &cont->name, Y_IDENTIF_ARG, LY_STMT_CONTAINER));
/* parse container content */
LY_CHECK_RET(subelems_allocator(ctx, 21, (struct lysp_node *)cont, &subelems,
@@ -2265,7 +2135,7 @@
LY_STMT_WHEN, &cont->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 21, data, LY_STMT_CONTAINER, NULL, &cont->exts);
+ ret = yin_parse_content(ctx, subelems, 21, LY_STMT_CONTAINER, NULL, &cont->exts);
subelems_deallocator(21, subelems);
LY_CHECK_RET(ret);
@@ -2278,27 +2148,25 @@
* @brief Parse case element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] node_meta Meta information about parent node and siblings to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_case(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *node_meta)
+yin_parse_case(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *node_meta)
{
struct lysp_node_case *cas;
LY_ERR ret = LY_SUCCESS;
struct yin_subelement *subelems = NULL;;
/* create new case */
- LY_LIST_NEW_RET(ctx->xml_ctx.ctx, node_meta->nodes, cas, next, LY_EMEM);
+ LY_LIST_NEW_RET(ctx->xmlctx->ctx, node_meta->nodes, cas, next, LY_EMEM);
cas->nodetype = LYS_CASE;
cas->parent = node_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &cas->name, Y_IDENTIF_ARG, LY_STMT_CASE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &cas->name, Y_IDENTIF_ARG, LY_STMT_CASE));
/* parse case content */
LY_CHECK_RET(subelems_allocator(ctx, 14, (struct lysp_node *)cas, &subelems,
@@ -2317,7 +2185,7 @@
LY_STMT_WHEN, &cas->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 14, data, LY_STMT_CASE, NULL, &cas->exts);
+ ret = yin_parse_content(ctx, subelems, 14, LY_STMT_CASE, NULL, &cas->exts);
subelems_deallocator(14, subelems);
return ret;
@@ -2327,28 +2195,26 @@
* @brief Parse choice element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] node_meta Meta information about parent node and siblings to add to.
*
* @return LY_ERR values.
*/
LY_ERR
-yin_parse_choice(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *node_meta)
+yin_parse_choice(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *node_meta)
{
LY_ERR ret = LY_SUCCESS;
struct yin_subelement *subelems = NULL;
struct lysp_node_choice *choice;
/* create new choice */
- LY_LIST_NEW_RET(ctx->xml_ctx.ctx, node_meta->nodes, choice, next, LY_EMEM);
+ LY_LIST_NEW_RET(ctx->xmlctx->ctx, node_meta->nodes, choice, next, LY_EMEM);
choice->nodetype = LYS_CHOICE;
choice->parent = node_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &choice->name, Y_IDENTIF_ARG, LY_STMT_CHOICE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &choice->name, Y_IDENTIF_ARG, LY_STMT_CHOICE));
/* parse choice content */
LY_CHECK_RET(subelems_allocator(ctx, 17, (struct lysp_node *)choice, &subelems,
@@ -2370,7 +2236,7 @@
LY_STMT_WHEN, &choice->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 17, data, LY_STMT_CHOICE, NULL, &choice->exts);
+ ret = yin_parse_content(ctx, subelems, 17, LY_STMT_CHOICE, NULL, &choice->exts);
subelems_deallocator(17, subelems);
return ret;
}
@@ -2379,16 +2245,13 @@
* @brief Parse input or output element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] inout_kw Identification of input/output element.
* @param[in] inout_meta Meta information about parent node and siblings and input/output pointer to write to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_inout(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum ly_stmt inout_kw,
- struct inout_meta *inout_meta)
+yin_parse_inout(struct lys_yin_parser_ctx *ctx, enum ly_stmt inout_kw, struct inout_meta *inout_meta)
{
LY_ERR ret = LY_SUCCESS;
struct yin_subelement *subelems = NULL;
@@ -2398,7 +2261,8 @@
inout_meta->inout_p->parent = inout_meta->parent;
/* check attributes */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, inout_kw));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, NULL, Y_MAYBE_STR_ARG, inout_kw));
/* parser input/output content */
LY_CHECK_RET(subelems_allocator(ctx, 12, (struct lysp_node *)inout_meta->inout_p, &subelems,
@@ -2415,7 +2279,7 @@
LY_STMT_USES, &inout_meta->inout_p->data, 0,
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 12, data, inout_kw, NULL, &inout_meta->inout_p->exts);
+ ret = yin_parse_content(ctx, subelems, 12, inout_kw, NULL, &inout_meta->inout_p->exts);
subelems_deallocator(12, subelems);
LY_CHECK_RET(ret);
@@ -2434,27 +2298,25 @@
* @brief Parse action element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] act_meta Meta information about parent node and actions to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_action(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *act_meta)
+yin_parse_action(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *act_meta)
{
struct lysp_action *act, **acts = (struct lysp_action **)act_meta->nodes;
LY_ERR ret = LY_SUCCESS;
struct yin_subelement *subelems = NULL;
/* create new action */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *acts, act, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *acts, act, LY_EMEM);
act->nodetype = LYS_ACTION;
act->parent = act_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, &act->name, Y_IDENTIF_ARG, LY_STMT_ACTION));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &act->name, Y_IDENTIF_ARG, LY_STMT_ACTION));
/* parse content */
LY_CHECK_RET(subelems_allocator(ctx, 9, (struct lysp_node *)act, &subelems,
@@ -2468,7 +2330,7 @@
LY_STMT_TYPEDEF, &act->typedefs, 0,
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = (yin_parse_content(ctx, subelems, 9, data, LY_STMT_ACTION, NULL, &act->exts));
+ ret = (yin_parse_content(ctx, subelems, 9, LY_STMT_ACTION, NULL, &act->exts));
subelems_deallocator(9, subelems);
LY_CHECK_RET(ret);
@@ -2481,15 +2343,12 @@
* @brief Parse augment element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] aug_meta Meta information about parent node and augments to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_augment(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct tree_node_meta *aug_meta)
+yin_parse_augment(struct lys_yin_parser_ctx *ctx, struct tree_node_meta *aug_meta)
{
struct lysp_augment *aug;
struct lysp_augment **augs = (struct lysp_augment **)aug_meta->nodes;
@@ -2497,13 +2356,14 @@
struct yin_subelement *subelems = NULL;
/* create new augment */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *augs, aug, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *augs, aug, LY_EMEM);
aug->nodetype = LYS_AUGMENT;
aug->parent = aug_meta->parent;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_TARGET_NODE, &aug->nodeid, Y_STR_ARG, LY_STMT_AUGMENT));
- YANG_CHECK_NONEMPTY((struct lys_parser_ctx *)ctx, strlen(aug->nodeid), "augment");
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TARGET_NODE, &aug->nodeid, Y_STR_ARG, LY_STMT_AUGMENT));
+ CHECK_NONEMPTY((struct lys_parser_ctx *)ctx, strlen(aug->nodeid), "augment");
/* parser augment content */
LY_CHECK_RET(subelems_allocator(ctx, 17, (struct lysp_node *)aug, &subelems,
@@ -2525,7 +2385,7 @@
LY_STMT_WHEN, &aug->when, YIN_SUBELEM_UNIQUE,
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 17, data, LY_STMT_AUGMENT, NULL, &aug->exts);
+ ret = yin_parse_content(ctx, subelems, 17, LY_STMT_AUGMENT, NULL, &aug->exts);
subelems_deallocator(17, subelems);
LY_CHECK_RET(ret);
@@ -2538,15 +2398,12 @@
* @brief Parse deviate element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] deviates Deviates to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_deviate(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_deviate **deviates)
+yin_parse_deviate(struct lys_yin_parser_ctx *ctx, struct lysp_deviate **deviates)
{
LY_ERR ret = LY_SUCCESS;
uint8_t dev_mod;
@@ -2557,7 +2414,8 @@
struct lysp_deviate_del *d_del = NULL;
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_DEVIATE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, &temp_val, Y_STR_ARG, LY_STMT_DEVIATE));
if (strcmp(temp_val, "not-supported") == 0) {
dev_mod = LYS_DEV_NOT_SUPPORTED;
@@ -2570,22 +2428,22 @@
} else {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INVAL_YIN VALID_VALS4, temp_val, "value", "deviate",
"not-supported", "add", "replace", "delete");
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
return LY_EVALID;
}
- FREE_STRING(ctx->xml_ctx.ctx, temp_val);
+ FREE_STRING(ctx->xmlctx->ctx, temp_val);
if (dev_mod == LYS_DEV_NOT_SUPPORTED) {
d = calloc(1, sizeof *d);
- LY_CHECK_ERR_RET(!d, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!d, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
struct yin_subelement subelems[1] = {
{LY_STMT_EXTENSION_INSTANCE, NULL, 0}
};
- ret = yin_parse_content(ctx, subelems, 1, data, LY_STMT_DEVIATE, NULL, &d->exts);
+ ret = yin_parse_content(ctx, subelems, 1, LY_STMT_DEVIATE, NULL, &d->exts);
} else if (dev_mod == LYS_DEV_ADD) {
d_add = calloc(1, sizeof *d_add);
- LY_CHECK_ERR_RET(!d_add, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!d_add, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
d = (struct lysp_deviate *)d_add;
struct minmax_dev_meta min = {&d_add->min, &d_add->flags, &d_add->exts};
struct minmax_dev_meta max = {&d_add->max, &d_add->flags, &d_add->exts};
@@ -2600,11 +2458,11 @@
{LY_STMT_UNITS, &d_add->units, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, 9, data, LY_STMT_DEVIATE, NULL, &d_add->exts);
+ ret = yin_parse_content(ctx, subelems, 9, LY_STMT_DEVIATE, NULL, &d_add->exts);
} else if (dev_mod == LYS_DEV_REPLACE) {
d_rpl = calloc(1, sizeof *d_rpl);
- LY_CHECK_ERR_RET(!d_rpl, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!d_rpl, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
d = (struct lysp_deviate *)d_rpl;
struct minmax_dev_meta min = {&d_rpl->min, &d_rpl->flags, &d_rpl->exts};
struct minmax_dev_meta max = {&d_rpl->max, &d_rpl->flags, &d_rpl->exts};
@@ -2618,11 +2476,11 @@
{LY_STMT_UNITS, &d_rpl->units, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, 8, data, LY_STMT_DEVIATE, NULL, &d_rpl->exts);
+ ret = yin_parse_content(ctx, subelems, 8, LY_STMT_DEVIATE, NULL, &d_rpl->exts);
} else {
d_del = calloc(1, sizeof *d_del);
- LY_CHECK_ERR_RET(!d_del, LOGMEM(ctx->xml_ctx.ctx), LY_EMEM);
+ LY_CHECK_ERR_RET(!d_del, LOGMEM(ctx->xmlctx->ctx), LY_EMEM);
d = (struct lysp_deviate *)d_del;
struct yin_subelement subelems[5] = {
{LY_STMT_DEFAULT, &d_del->dflts, 0},
@@ -2631,7 +2489,7 @@
{LY_STMT_UNITS, &d_del->units, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- ret = yin_parse_content(ctx, subelems, 5, data, LY_STMT_DEVIATE, NULL, &d_del->exts);
+ ret = yin_parse_content(ctx, subelems, 5, LY_STMT_DEVIATE, NULL, &d_del->exts);
}
LY_CHECK_GOTO(ret, cleanup);
@@ -2650,31 +2508,29 @@
* @brief Parse deviation element.
*
* @param[in,out] ctx YIN parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of current element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] deviations Deviations to add to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_deviation(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- struct lysp_deviation **deviations)
+yin_parse_deviation(struct lys_yin_parser_ctx *ctx, struct lysp_deviation **deviations)
{
struct lysp_deviation *dev;
/* create new deviation */
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *deviations, dev, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *deviations, dev, LY_EMEM);
/* parse argument */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_TARGET_NODE, &dev->nodeid, Y_STR_ARG, LY_STMT_DEVIATION));
- YANG_CHECK_NONEMPTY((struct lys_parser_ctx *)ctx, strlen(dev->nodeid), "deviation");
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TARGET_NODE, &dev->nodeid, Y_STR_ARG, LY_STMT_DEVIATION));
+ CHECK_NONEMPTY((struct lys_parser_ctx *)ctx, strlen(dev->nodeid), "deviation");
struct yin_subelement subelems[4] = {
{LY_STMT_DESCRIPTION, &dev->dsc, YIN_SUBELEM_UNIQUE},
{LY_STMT_DEVIATE, &dev->deviates, YIN_SUBELEM_MANDATORY},
{LY_STMT_REFERENCE, &dev->ref, YIN_SUBELEM_UNIQUE},
{LY_STMT_EXTENSION_INSTANCE, NULL, 0},
};
- return yin_parse_content(ctx, subelems, 4, data, LY_STMT_DEVIATION, NULL, &dev->exts);
+ return yin_parse_content(ctx, subelems, 4, LY_STMT_DEVIATION, NULL, &dev->exts);
}
/**
@@ -2767,7 +2623,7 @@
* @return LY_SUCCESS on success LY_EINT if kw can't be mapped to kw_group, should not happen if called correctly.
*/
static LY_ERR
-kw2kw_group(struct yin_parser_ctx *ctx, enum ly_stmt kw, enum yang_module_stmt *group)
+kw2kw_group(struct lys_yin_parser_ctx *ctx, enum ly_stmt kw, enum yang_module_stmt *group)
{
switch (kw) {
/* module header */
@@ -2816,7 +2672,7 @@
*group = Y_MOD_BODY;
break;
default:
- LOGINT(ctx->xml_ctx.ctx);
+ LOGINT(ctx->xmlctx->ctx);
return LY_EINT;
}
@@ -2835,7 +2691,7 @@
* @return LY_SUCCESS on success and LY_EVALID if relative order is invalid.
*/
static LY_ERR
-yin_check_relative_order(struct yin_parser_ctx *ctx, enum ly_stmt kw, enum ly_stmt next_kw, enum ly_stmt parrent)
+yin_check_relative_order(struct lys_yin_parser_ctx *ctx, enum ly_stmt kw, enum ly_stmt next_kw, enum ly_stmt parrent)
{
assert(parrent == LY_STMT_MODULE || parrent == LY_STMT_SUBMODULE);
enum yang_module_stmt gr, next_gr;
@@ -2863,14 +2719,14 @@
* @return Element name prefixed by URI on success, NULL on failure.
*/
static const char *
-name2nsname(struct yin_parser_ctx *ctx, const char *name, size_t name_len, const char *prefix, size_t prefix_len)
+name2nsname(struct lys_yin_parser_ctx *ctx, const char *name, size_t name_len, const char *prefix, size_t prefix_len)
{
- const struct lyxml_ns *ns = lyxml_ns_get(&ctx->xml_ctx, prefix, prefix_len);
- LY_CHECK_ERR_RET(!ns, LOGINT(ctx->xml_ctx.ctx), NULL);
+ const struct lyxml_ns *ns = lyxml_ns_get(ctx->xmlctx, prefix, prefix_len);
+ LY_CHECK_ERR_RET(!ns, LOGINT(ctx->xmlctx->ctx), NULL);
if (!strcmp(ns->uri, YIN_NS_URI)) {
/* standard YANG statement in YIN namespace - keep it unprefixed as in case of YANG */
- return lydict_insert(ctx->xml_ctx.ctx, name, name_len);
+ return lydict_insert(ctx->xmlctx->ctx, name, name_len);
}
/* some statement in special namespace (extension instance) */
size_t ns_len = strlen(ns->uri);
@@ -2879,7 +2735,7 @@
char *result;
char *temp;
temp = result = malloc(sizeof(*temp) * (len + 1)); /* +1 for '\0' terminator */
- LY_CHECK_ERR_RET(!temp, LOGMEM(ctx->xml_ctx.ctx), NULL);
+ LY_CHECK_ERR_RET(!temp, LOGMEM(ctx->xmlctx->ctx), NULL);
strcpy(result, ns->uri);
result[ns_len] = ':';
@@ -2887,321 +2743,322 @@
strncpy(temp, name, name_len);
result[len] = '\0';
- return lydict_insert_zc(ctx->xml_ctx.ctx, result);
+ return lydict_insert_zc(ctx->xmlctx->ctx, result);
}
LY_ERR
-yin_parse_content(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
- const char **data, enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts)
+yin_parse_content(struct lys_yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
+ enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts)
{
LY_ERR ret = LY_SUCCESS;
- char *out = NULL;
- const char *prefix, *name;
- size_t out_len = 0, prefix_len, name_len;
- int dynamic = 0;
- struct yin_arg_record *attrs = NULL;
+ enum LYXML_PARSER_STATUS next_status;
enum ly_stmt kw = LY_STMT_NONE, last_kw = LY_STMT_NONE;
struct yin_subelement *subelem = NULL;
- if (ctx->xml_ctx.status == LYXML_ELEM_CONTENT) {
- ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
- /* current element has subelements as content */
- if (ret == LY_EINVAL) {
- while (ctx->xml_ctx.status == LYXML_ELEMENT) {
- ret = lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
- LY_CHECK_GOTO(ret, cleanup);
- if (!name) {
- /* end of current element reached */
- break;
- }
- ret = yin_load_attributes(ctx, data, &attrs);
- LY_CHECK_GOTO(ret, cleanup);
- last_kw = kw;
- kw = yin_match_keyword(ctx, name, name_len, prefix, prefix_len, current_element);
+ assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
- /* check if this element can be child of current element */
- subelem = get_record(kw, subelem_info_size, subelem_info);
- if (!subelem) {
- if (current_element == LY_STMT_DEVIATE && isdevsub(kw)) {
- LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INDEV_YIN, ly_stmt2str(kw));
- } else {
- LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, name_len, name, ly_stmt2str(current_element));
- }
+ if (ctx->xmlctx->ws_only) {
+ /* check whether there are any children */
+ LY_CHECK_GOTO(ret = lyxml_ctx_peek(ctx->xmlctx, &next_status), cleanup);
+ } else {
+ /* we want to parse the value */
+ next_status = LYXML_ELEM_CLOSE;
+ }
+
+ if (next_status == LYXML_ELEMENT) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+
+ /* current element has subelements as content */
+ while (ctx->xmlctx->status == LYXML_ELEMENT) {
+ /* match keyword */
+ last_kw = kw;
+ kw = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
+ ctx->xmlctx->prefix_len, current_element);
+
+ /* check if this element can be child of current element */
+ subelem = get_record(kw, subelem_info_size, subelem_info);
+ if (!subelem) {
+ if (current_element == LY_STMT_DEVIATE && isdevsub(kw)) {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INDEV_YIN, ly_stmt2str(kw));
+ } else {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len,
+ ctx->xmlctx->name, ly_stmt2str(current_element));
+ }
+ ret = LY_EVALID;
+ goto cleanup;
+ }
+
+ /* relative order is required only in module and submodule sub-elements */
+ if (current_element == LY_STMT_MODULE || current_element == LY_STMT_SUBMODULE) {
+ ret = yin_check_relative_order(ctx, last_kw, kw, current_element);
+ LY_CHECK_GOTO(ret, cleanup);
+ }
+
+ /* flag check */
+ if ((subelem->flags & YIN_SUBELEM_UNIQUE) && (subelem->flags & YIN_SUBELEM_PARSED)) {
+ /* subelement uniquenes */
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_SUBELEM_REDEF, ly_stmt2str(kw), ly_stmt2str(current_element));
+ return LY_EVALID;
+ }
+ if (subelem->flags & YIN_SUBELEM_FIRST) {
+ /* subelement is supposed to be defined as first subelement */
+ ret = yin_check_subelem_first_constraint(ctx, subelem_info, subelem_info_size, current_element, subelem);
+ LY_CHECK_GOTO(ret, cleanup);
+ }
+ if (subelem->flags & YIN_SUBELEM_VER2) {
+ /* subelement is supported only in version 1.1 or higher */
+ if (ctx->mod_version < 2) {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INSUBELEM2, ly_stmt2str(kw), ly_stmt2str(current_element));
ret = LY_EVALID;
goto cleanup;
}
-
- /* relative order is required only in module and submodule sub-elements */
- if (current_element == LY_STMT_MODULE || current_element == LY_STMT_SUBMODULE) {
- ret = yin_check_relative_order(ctx, last_kw, kw, current_element);
- LY_CHECK_GOTO(ret, cleanup);
- }
-
- /* flag check */
- if ((subelem->flags & YIN_SUBELEM_UNIQUE) && (subelem->flags & YIN_SUBELEM_PARSED)) {
- /* subelement uniquenes */
- LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_SUBELEM_REDEF, ly_stmt2str(kw), ly_stmt2str(current_element));
- return LY_EVALID;
- }
- if (subelem->flags & YIN_SUBELEM_FIRST) {
- /* subelement is supposed to be defined as first subelement */
- ret = yin_check_subelem_first_constraint(ctx, subelem_info, subelem_info_size, current_element, subelem);
- LY_CHECK_GOTO(ret, cleanup);
- }
- if (subelem->flags & YIN_SUBELEM_VER2) {
- /* subelement is supported only in version 1.1 or higher */
- if (ctx->mod_version < 2) {
- LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_INSUBELEM2, ly_stmt2str(kw), ly_stmt2str(current_element));
- ret = LY_EVALID;
- goto cleanup;
- }
- }
- /* note that element was parsed for easy uniqueness check in next iterations */
- subelem->flags |= YIN_SUBELEM_PARSED;
-
- switch (kw) {
- /* call responsible function */
- case LY_STMT_EXTENSION_INSTANCE:
- ret = yin_parse_extension_instance(ctx, attrs, data, name, name_len, prefix, prefix_len,
- kw2lyext_substmt(current_element),
- (subelem->dest) ? *((uint32_t*)subelem->dest) : 0, exts);
- break;
- case LY_STMT_ACTION:
- case LY_STMT_RPC:
- ret = yin_parse_action(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_ANYDATA:
- case LY_STMT_ANYXML:
- ret = yin_parse_any(ctx, attrs, data, kw, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_ARGUMENT:
- ret = yin_parse_argument(ctx, attrs, data, (struct yin_argument_meta *)subelem->dest, exts);
- break;
- case LY_STMT_AUGMENT:
- ret = yin_parse_augment(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_BASE:
- ret = yin_parse_base(ctx, attrs, data, current_element, subelem->dest, exts);
- break;
- case LY_STMT_BELONGS_TO:
- ret = yin_parse_belongs_to(ctx, attrs, data, (struct lysp_submodule *)subelem->dest, exts);
- break;
- case LY_STMT_BIT:
- ret = yin_parse_bit(ctx, attrs, data, (struct lysp_type *)subelem->dest);
- break;
- case LY_STMT_CASE:
- ret = yin_parse_case(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_CHOICE:
- ret = yin_parse_choice(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_CONFIG:
- ret = yin_parse_config(ctx, attrs, data, (uint16_t *)subelem->dest, exts);
- break;
- case LY_STMT_CONTACT:
- case LY_STMT_DESCRIPTION:
- case LY_STMT_ORGANIZATION:
- case LY_STMT_REFERENCE:
- ret = yin_parse_meta(ctx, attrs, data, kw, (const char **)subelem->dest, exts);
- break;
- case LY_STMT_CONTAINER:
- ret = yin_parse_container(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_DEFAULT:
- case LY_STMT_ERROR_APP_TAG:
- case LY_STMT_KEY:
- case LY_STMT_PRESENCE:
- ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_VALUE, Y_STR_ARG, exts);
- break;
- case LY_STMT_DEVIATE:
- ret = yin_parse_deviate(ctx, attrs, data, (struct lysp_deviate **)subelem->dest);
- break;
- case LY_STMT_DEVIATION:
- ret = yin_parse_deviation(ctx, attrs, data, (struct lysp_deviation **)subelem->dest);
- break;
- case LY_STMT_ENUM:
- ret = yin_parse_enum(ctx, attrs, data, (struct lysp_type *)subelem->dest);
- break;
- case LY_STMT_ERROR_MESSAGE:
- ret = yin_parse_err_msg(ctx, attrs, data, (const char **)subelem->dest, exts);
- break;
- case LY_STMT_EXTENSION:
- ret = yin_parse_extension(ctx, attrs, data, (struct lysp_ext **)subelem->dest);
- break;
- case LY_STMT_FEATURE:
- ret = yin_parse_feature(ctx, attrs, data, (struct lysp_feature **)subelem->dest);
- break;
- case LY_STMT_FRACTION_DIGITS:
- ret = yin_parse_fracdigits(ctx, attrs, data, (struct lysp_type *)subelem->dest);
- break;
- case LY_STMT_GROUPING:
- ret = yin_parse_grouping(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_IDENTITY:
- ret = yin_parse_identity(ctx, attrs, data, (struct lysp_ident **)subelem->dest);
- break;
- case LY_STMT_IF_FEATURE:
- case LY_STMT_UNITS:
- ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_NAME, Y_STR_ARG, exts);
- break;
- case LY_STMT_IMPORT:
- ret = yin_parse_import(ctx, attrs, data, (struct import_meta *)subelem->dest);
- break;
- case LY_STMT_INCLUDE:
- ret = yin_parse_include(ctx, attrs, data, (struct include_meta *)subelem->dest);
- break;
- case LY_STMT_INPUT:
- case LY_STMT_OUTPUT:
- ret = yin_parse_inout(ctx, attrs, data, kw, (struct inout_meta *)subelem->dest);
- break;
- case LY_STMT_LEAF:
- ret = yin_parse_leaf(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_LEAF_LIST:
- ret = yin_parse_leaflist(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_LENGTH:
- ret = yin_parse_length(ctx, attrs, data, (struct lysp_type *)subelem->dest);
- break;
- case LY_STMT_LIST:
- ret = yin_parse_list(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_MANDATORY:
- ret = yin_parse_mandatory(ctx, attrs, data, (uint16_t *)subelem->dest, exts);
- break;
- case LY_STMT_MAX_ELEMENTS:
- case LY_STMT_MIN_ELEMENTS:
- ret = yin_parse_minmax(ctx, attrs, data, current_element, kw, subelem->dest);
- break;
- case LY_STMT_MODIFIER:
- ret = yin_parse_modifier(ctx, attrs, data, (const char **)subelem->dest, exts);
- break;
- case LY_STMT_MUST:
- ret = yin_parse_must(ctx, attrs, data, (struct lysp_restr **)subelem->dest);
- break;
- case LY_STMT_NAMESPACE:
- ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_URI, Y_STR_ARG, exts);
- break;
- case LY_STMT_NOTIFICATION:
- ret = yin_parse_notification(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_ORDERED_BY:
- ret = yin_parse_orderedby(ctx, attrs, data, (uint16_t *)subelem->dest, exts);
- break;
- case LY_STMT_PATH:
- ret = yin_parse_path(ctx, attrs, data, kw, (struct lysp_type *)subelem->dest);
- break;
- case LY_STMT_PATTERN:
- ret = yin_parse_pattern(ctx, attrs, data, (struct lysp_type *)subelem->dest);
- break;
- case LY_STMT_VALUE:
- case LY_STMT_POSITION:
- ret = yin_parse_value_pos(ctx, attrs, data, kw, (struct lysp_type_enum *)subelem->dest);
- break;
- case LY_STMT_PREFIX:
- ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_VALUE, Y_IDENTIF_ARG, exts);
- break;
- case LY_STMT_RANGE:
- ret = yin_parse_range(ctx, attrs, data, (struct lysp_type *)subelem->dest);
- break;
- case LY_STMT_REFINE:
- ret = yin_parse_refine(ctx, attrs, data, (struct lysp_refine **)subelem->dest);
- break;
- case LY_STMT_REQUIRE_INSTANCE:
- ret = yin_pasrse_reqinstance(ctx, attrs, data, (struct lysp_type *)subelem->dest);
- break;
- case LY_STMT_REVISION:
- ret = yin_parse_revision(ctx, attrs, data, (struct lysp_revision **)subelem->dest);
- break;
- case LY_STMT_REVISION_DATE:
- ret = yin_parse_revision_date(ctx, attrs, data, (char *)subelem->dest, exts);
- break;
- case LY_STMT_STATUS:
- ret = yin_parse_status(ctx, attrs, data, (uint16_t *)subelem->dest, exts);
- break;
- case LY_STMT_TYPE:
- ret = yin_parse_type(ctx, attrs, data, current_element, subelem);
- break;
- case LY_STMT_TYPEDEF:
- ret = yin_parse_typedef(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_UNIQUE:
- ret = yin_parse_simple_elem(ctx, attrs, data, kw, subelem, YIN_ARG_TAG, Y_STR_ARG, exts);
- break;
- case LY_STMT_USES:
- ret = yin_parse_uses(ctx, attrs, data, (struct tree_node_meta *)subelem->dest);
- break;
- case LY_STMT_WHEN:
- ret = yin_parse_when(ctx, attrs, data, (struct lysp_when **)subelem->dest);
- break;
- case LY_STMT_YANG_VERSION:
- ret = yin_parse_yangversion(ctx, attrs, data, (uint8_t *)subelem->dest, exts);
- break;
- case LY_STMT_YIN_ELEMENT:
- ret = yin_parse_yin_element(ctx, attrs, data, (uint16_t *)subelem->dest, exts);
- break;
- case LY_STMT_ARG_TEXT:
- case LY_STMT_ARG_VALUE:
- ret = yin_parse_content(ctx, NULL, 0, data, kw, (const char **)subelem->dest, NULL);
- break;
- default:
- LOGINT(ctx->xml_ctx.ctx);
- ret = LY_EINT;
- }
- LY_CHECK_GOTO(ret, cleanup);
- FREE_ARRAY(ctx, attrs, free_arg_rec);
- attrs = NULL;
- subelem = NULL;
}
- } else {
- LY_CHECK_RET(ret);
- /* elements with text or none content */
- /* save text content, if text_content isn't set, it's just ignored */
- /* no resources are allocated in this branch, no need to use cleanup label */
- LY_CHECK_RET(yin_validate_value(ctx, Y_STR_ARG, out, out_len));
- if (text_content) {
- INSERT_STRING(ctx->xml_ctx.ctx, *text_content, dynamic, out, out_len);
- LY_CHECK_RET(!*text_content, LY_EMEM);
+ /* note that element was parsed for easy uniqueness check in next iterations */
+ subelem->flags |= YIN_SUBELEM_PARSED;
+
+ switch (kw) {
+ /* call responsible function */
+ case LY_STMT_EXTENSION_INSTANCE:
+ ret = yin_parse_extension_instance(ctx, kw2lyext_substmt(current_element),
+ (subelem->dest) ? *((uint32_t*)subelem->dest) : 0, exts);
+ break;
+ case LY_STMT_ACTION:
+ case LY_STMT_RPC:
+ ret = yin_parse_action(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_ANYDATA:
+ case LY_STMT_ANYXML:
+ ret = yin_parse_any(ctx, kw, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_ARGUMENT:
+ ret = yin_parse_argument(ctx, (struct yin_argument_meta *)subelem->dest, exts);
+ break;
+ case LY_STMT_AUGMENT:
+ ret = yin_parse_augment(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_BASE:
+ ret = yin_parse_base(ctx, current_element, subelem->dest, exts);
+ break;
+ case LY_STMT_BELONGS_TO:
+ ret = yin_parse_belongs_to(ctx, (struct lysp_submodule *)subelem->dest, exts);
+ break;
+ case LY_STMT_BIT:
+ ret = yin_parse_bit(ctx, (struct lysp_type *)subelem->dest);
+ break;
+ case LY_STMT_CASE:
+ ret = yin_parse_case(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_CHOICE:
+ ret = yin_parse_choice(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_CONFIG:
+ ret = yin_parse_config(ctx, (uint16_t *)subelem->dest, exts);
+ break;
+ case LY_STMT_CONTACT:
+ case LY_STMT_DESCRIPTION:
+ case LY_STMT_ORGANIZATION:
+ case LY_STMT_REFERENCE:
+ ret = yin_parse_meta(ctx, kw, (const char **)subelem->dest, exts);
+ break;
+ case LY_STMT_CONTAINER:
+ ret = yin_parse_container(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_DEFAULT:
+ case LY_STMT_ERROR_APP_TAG:
+ case LY_STMT_KEY:
+ case LY_STMT_PRESENCE:
+ ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_VALUE, Y_STR_ARG, exts);
+ break;
+ case LY_STMT_DEVIATE:
+ ret = yin_parse_deviate(ctx, (struct lysp_deviate **)subelem->dest);
+ break;
+ case LY_STMT_DEVIATION:
+ ret = yin_parse_deviation(ctx, (struct lysp_deviation **)subelem->dest);
+ break;
+ case LY_STMT_ENUM:
+ ret = yin_parse_enum(ctx, (struct lysp_type *)subelem->dest);
+ break;
+ case LY_STMT_ERROR_MESSAGE:
+ ret = yin_parse_err_msg(ctx, (const char **)subelem->dest, exts);
+ break;
+ case LY_STMT_EXTENSION:
+ ret = yin_parse_extension(ctx, (struct lysp_ext **)subelem->dest);
+ break;
+ case LY_STMT_FEATURE:
+ ret = yin_parse_feature(ctx, (struct lysp_feature **)subelem->dest);
+ break;
+ case LY_STMT_FRACTION_DIGITS:
+ ret = yin_parse_fracdigits(ctx, (struct lysp_type *)subelem->dest);
+ break;
+ case LY_STMT_GROUPING:
+ ret = yin_parse_grouping(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_IDENTITY:
+ ret = yin_parse_identity(ctx, (struct lysp_ident **)subelem->dest);
+ break;
+ case LY_STMT_IF_FEATURE:
+ case LY_STMT_UNITS:
+ ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_NAME, Y_STR_ARG, exts);
+ break;
+ case LY_STMT_IMPORT:
+ ret = yin_parse_import(ctx, (struct import_meta *)subelem->dest);
+ break;
+ case LY_STMT_INCLUDE:
+ ret = yin_parse_include(ctx, (struct include_meta *)subelem->dest);
+ break;
+ case LY_STMT_INPUT:
+ case LY_STMT_OUTPUT:
+ ret = yin_parse_inout(ctx, kw, (struct inout_meta *)subelem->dest);
+ break;
+ case LY_STMT_LEAF:
+ ret = yin_parse_leaf(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_LEAF_LIST:
+ ret = yin_parse_leaflist(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_LENGTH:
+ ret = yin_parse_length(ctx, (struct lysp_type *)subelem->dest);
+ break;
+ case LY_STMT_LIST:
+ ret = yin_parse_list(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_MANDATORY:
+ ret = yin_parse_mandatory(ctx, (uint16_t *)subelem->dest, exts);
+ break;
+ case LY_STMT_MAX_ELEMENTS:
+ case LY_STMT_MIN_ELEMENTS:
+ ret = yin_parse_minmax(ctx, current_element, kw, subelem->dest);
+ break;
+ case LY_STMT_MODIFIER:
+ ret = yin_parse_modifier(ctx, (const char **)subelem->dest, exts);
+ break;
+ case LY_STMT_MUST:
+ ret = yin_parse_must(ctx, (struct lysp_restr **)subelem->dest);
+ break;
+ case LY_STMT_NAMESPACE:
+ ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_URI, Y_STR_ARG, exts);
+ break;
+ case LY_STMT_NOTIFICATION:
+ ret = yin_parse_notification(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_ORDERED_BY:
+ ret = yin_parse_orderedby(ctx, (uint16_t *)subelem->dest, exts);
+ break;
+ case LY_STMT_PATH:
+ ret = yin_parse_path(ctx, kw, (struct lysp_type *)subelem->dest);
+ break;
+ case LY_STMT_PATTERN:
+ ret = yin_parse_pattern(ctx, (struct lysp_type *)subelem->dest);
+ break;
+ case LY_STMT_VALUE:
+ case LY_STMT_POSITION:
+ ret = yin_parse_value_pos(ctx, kw, (struct lysp_type_enum *)subelem->dest);
+ break;
+ case LY_STMT_PREFIX:
+ ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_VALUE, Y_IDENTIF_ARG, exts);
+ break;
+ case LY_STMT_RANGE:
+ ret = yin_parse_range(ctx, (struct lysp_type *)subelem->dest);
+ break;
+ case LY_STMT_REFINE:
+ ret = yin_parse_refine(ctx, (struct lysp_refine **)subelem->dest);
+ break;
+ case LY_STMT_REQUIRE_INSTANCE:
+ ret = yin_pasrse_reqinstance(ctx, (struct lysp_type *)subelem->dest);
+ break;
+ case LY_STMT_REVISION:
+ ret = yin_parse_revision(ctx, (struct lysp_revision **)subelem->dest);
+ break;
+ case LY_STMT_REVISION_DATE:
+ ret = yin_parse_revision_date(ctx, (char *)subelem->dest, exts);
+ break;
+ case LY_STMT_STATUS:
+ ret = yin_parse_status(ctx, (uint16_t *)subelem->dest, exts);
+ break;
+ case LY_STMT_TYPE:
+ ret = yin_parse_type(ctx, current_element, subelem);
+ break;
+ case LY_STMT_TYPEDEF:
+ ret = yin_parse_typedef(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_UNIQUE:
+ ret = yin_parse_simple_elem(ctx, kw, subelem, YIN_ARG_TAG, Y_STR_ARG, exts);
+ break;
+ case LY_STMT_USES:
+ ret = yin_parse_uses(ctx, (struct tree_node_meta *)subelem->dest);
+ break;
+ case LY_STMT_WHEN:
+ ret = yin_parse_when(ctx, (struct lysp_when **)subelem->dest);
+ break;
+ case LY_STMT_YANG_VERSION:
+ ret = yin_parse_yangversion(ctx, (uint8_t *)subelem->dest, exts);
+ break;
+ case LY_STMT_YIN_ELEMENT:
+ ret = yin_parse_yin_element(ctx, (uint16_t *)subelem->dest, exts);
+ break;
+ case LY_STMT_ARG_TEXT:
+ case LY_STMT_ARG_VALUE:
+ /* TODO what to do with content/attributes? */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+ while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+ }
+ ret = yin_parse_content(ctx, NULL, 0, kw, (const char **)subelem->dest, NULL);
+ break;
+ default:
+ LOGINT(ctx->xmlctx->ctx);
+ ret = LY_EINT;
}
- /* load closing element */
- LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
+ LY_CHECK_GOTO(ret, cleanup);
+ subelem = NULL;
+
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
}
+ } else {
+ LY_CHECK_RET(ret);
+ /* elements with text or none content */
+ /* save text content, if text_content isn't set, it's just ignored */
+ /* no resources are allocated in this branch, no need to use cleanup label */
+ LY_CHECK_RET(yin_validate_value(ctx, Y_STR_ARG));
+ if (text_content) {
+ *text_content = INSERT_STRING(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic);
+ LY_CHECK_RET(!*text_content, LY_EMEM);
+ }
+
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
}
+
/* mandatory subelemnts are checked only after whole element was succesfully parsed */
LY_CHECK_RET(yin_check_subelem_mandatory_constraint(ctx, subelem_info, subelem_info_size, current_element));
cleanup:
- FREE_ARRAY(ctx, attrs, free_arg_rec);
return ret;
}
LY_ERR
-yin_parse_extension_instance(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- const char *ext_name, size_t ext_name_len, const char *ext_prefix, size_t ext_prefix_len,
- LYEXT_SUBSTMT subelem, uint32_t subelem_index, struct lysp_ext_instance **exts)
+yin_parse_extension_instance(struct lys_yin_parser_ctx *ctx, LYEXT_SUBSTMT subelem, uint32_t subelem_index,
+ struct lysp_ext_instance **exts)
{
- LY_ERR ret = LY_SUCCESS;
- char *out;
- const char *name, *prefix;
- size_t out_len, prefix_len, name_len;
- int dynamic;
struct lysp_ext_instance *e;
struct lysp_stmt *last_subelem = NULL, *new_subelem = NULL;
- struct yin_arg_record *iter;
- LY_ARRAY_NEW_RET(ctx->xml_ctx.ctx, *exts, e, LY_EMEM);
+ assert(ctx->xmlctx->status == LYXML_ELEMENT);
+
+ LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *exts, e, LY_EMEM);
e->yin = 0;
/* store name and insubstmt info */
- e->name = name2nsname(ctx, ext_name, ext_name_len, ext_prefix, ext_prefix_len);
+ e->name = name2nsname(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len);
LY_CHECK_RET(!e->name, LY_EMEM);
e->insubstmt = subelem;
e->insubstmt_index = subelem_index;
e->yin |= LYS_YIN;
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
/* store attributes as subelements */
- LY_ARRAY_FOR_ITER(attrs, struct yin_arg_record, iter) {
- if (!iter->prefix) {
+ while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
+ if (!ctx->xmlctx->prefix) {
new_subelem = calloc(1, sizeof(*new_subelem));
if (!e->child) {
e->child = new_subelem;
@@ -3211,45 +3068,42 @@
last_subelem = new_subelem;
last_subelem->flags |= LYS_YIN_ATTR;
- last_subelem->stmt = lydict_insert(ctx->xml_ctx.ctx, iter->name, iter->name_len);
+ last_subelem->stmt = lydict_insert(ctx->xmlctx->ctx, ctx->xmlctx->name, ctx->xmlctx->name_len);
LY_CHECK_RET(!last_subelem->stmt, LY_EMEM);
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- INSERT_STRING(ctx->xml_ctx.ctx, last_subelem->arg, iter->dynamic_content, iter->content, iter->content_len);
+ last_subelem->arg = INSERT_STRING(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic);
LY_CHECK_RET(!last_subelem->arg, LY_EMEM);
+ } else {
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
}
+
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
}
/* parse subelements */
- if (ctx->xml_ctx.status == LYXML_ELEM_CONTENT) {
- ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
- if (ret == LY_EINVAL) {
- while (ctx->xml_ctx.status == LYXML_ELEMENT) {
- LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
- if (!name) {
- /* end of extension instance reached */
- break;
- }
- LY_CHECK_RET(yin_parse_element_generic(ctx, name, name_len, prefix, prefix_len, LY_STMT_EXTENSION_INSTANCE, data, &new_subelem));
- if (!e->child) {
- e->child = new_subelem;
- } else {
- last_subelem->next = new_subelem;
- }
- last_subelem = new_subelem;
+ assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
+ if (ctx->xmlctx->ws_only) {
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ while (ctx->xmlctx->status == LYXML_ELEMENT) {
+ LY_CHECK_RET(yin_parse_element_generic(ctx, LY_STMT_EXTENSION_INSTANCE, &new_subelem));
+ if (!e->child) {
+ e->child = new_subelem;
+ } else {
+ last_subelem->next = new_subelem;
}
- } else {
- if (out_len != 0) {
- /* save text content */
- LY_CHECK_RET(ret);
+ last_subelem = new_subelem;
- INSERT_STRING(ctx->xml_ctx.ctx, e->argument, dynamic, out, out_len);
- LY_CHECK_RET(!e->argument, LY_EMEM);
-
- /* load closing element */
- LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
- LY_CHECK_RET(name, LY_EINT);
- }
+ assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
}
+ } else if (ctx->xmlctx->value_len) {
+ /* save text content */
+ e->argument = INSERT_STRING(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic);
+ LY_CHECK_RET(!e->argument, LY_EMEM);
+
+ /* parser next */
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
}
return LY_SUCCESS;
@@ -3259,24 +3113,18 @@
* @brief Parse argument of extension subelement that is classic yang keyword and not another instance of extension.
*
* @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of extension instance.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] elem_type Type of element that is currently being parsed.
* @param[out] arg Value to write to.
*
* @return LY_ERR values.
*/
static LY_ERR
-yin_parse_extension_instance_arg(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data, enum ly_stmt elem_type,
- const char **arg)
+yin_parse_extension_instance_arg(struct lys_yin_parser_ctx *ctx, enum ly_stmt elem_type, const char **arg)
{
- LY_ERR ret = LY_SUCCESS;
- char *out = NULL;
- const char *name, *prefix;
- size_t out_len, name_len, prefix_len;
- int dynamic;
enum ly_stmt child;
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+
switch (elem_type) {
case LY_STMT_ACTION:
case LY_STMT_ANYDATA:
@@ -3304,12 +3152,12 @@
case LY_STMT_TYPEDEF:
case LY_STMT_UNITS:
case LY_STMT_USES:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NAME, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, arg, Y_MAYBE_STR_ARG, elem_type));
break;
case LY_STMT_AUGMENT:
case LY_STMT_DEVIATION:
case LY_STMT_REFINE:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_TARGET_NODE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TARGET_NODE, arg, Y_MAYBE_STR_ARG, elem_type));
break;
case LY_STMT_CONFIG:
case LY_STMT_DEFAULT:
@@ -3334,30 +3182,30 @@
case LY_STMT_VALUE:
case LY_STMT_YANG_VERSION:
case LY_STMT_YIN_ELEMENT:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_VALUE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_VALUE, arg, Y_MAYBE_STR_ARG, elem_type));
break;
case LY_STMT_IMPORT:
case LY_STMT_INCLUDE:
case LY_STMT_BELONGS_TO:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_MODULE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_MODULE, arg, Y_MAYBE_STR_ARG, elem_type));
break;
case LY_STMT_INPUT:
case LY_STMT_OUTPUT:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
break;
case LY_STMT_MUST:
case LY_STMT_WHEN:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_CONDITION, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_CONDITION, arg, Y_MAYBE_STR_ARG, elem_type));
break;
case LY_STMT_NAMESPACE:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_URI, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_URI, arg, Y_MAYBE_STR_ARG, elem_type));
break;
case LY_STMT_REVISION:
case LY_STMT_REVISION_DATE:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_DATE, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_DATE, arg, Y_MAYBE_STR_ARG, elem_type));
break;
case LY_STMT_UNIQUE:
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_TAG, arg, Y_MAYBE_STR_ARG, elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_TAG, arg, Y_MAYBE_STR_ARG, elem_type));
break;
/* argument is mapped to yin element */
case LY_STMT_CONTACT:
@@ -3366,31 +3214,49 @@
case LY_STMT_REFERENCE:
case LY_STMT_ERROR_MESSAGE:
/* there shouldn't be any attribute, argument is supposed to be first subelement */
- LY_CHECK_RET(yin_parse_attribute(ctx, attrs, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
- ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
- LY_CHECK_ERR_RET(ret != LY_EINVAL, LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_FIRT_SUBELEM,
- elem_type == LY_STMT_ERROR_MESSAGE ? "value" : "text", ly_stmt2str(elem_type)),
- LY_EVALID);
- LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
- child = yin_match_keyword(ctx, name, name_len, prefix, prefix_len, elem_type);
- if ((elem_type == LY_STMT_ERROR_MESSAGE && child != LY_STMT_ARG_VALUE) ||
- (elem_type != LY_STMT_ERROR_MESSAGE && child != LY_STMT_ARG_TEXT)) {
- LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, name_len, name, ly_stmt2str(elem_type));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NONE, arg, Y_MAYBE_STR_ARG, elem_type));
+
+ /* no content */
+ assert(ctx->xmlctx->status == LYXML_ELEM_CONTENT);
+ if (ctx->xmlctx->ws_only) {
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ }
+ if (((ctx->xmlctx->status == LYXML_ELEM_CONTENT) && !ctx->xmlctx->ws_only) || (ctx->xmlctx->status != LYXML_ELEMENT)) {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_FIRT_SUBELEM,
+ elem_type == LY_STMT_ERROR_MESSAGE ? "value" : "text", ly_stmt2str(elem_type));
return LY_EVALID;
}
- /* load and save content */
- LY_CHECK_RET(lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic));
- INSERT_STRING(ctx->xml_ctx.ctx, *arg, dynamic, out, out_len);
- LY_CHECK_RET(!*arg, LY_EMEM);
- /* load closing tag of subelement */
- LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
- /* if only subelement was parsed as argument, load also closing tag */
- if (ctx->xml_ctx.status == LYXML_ELEMENT) {
- LY_CHECK_RET(lyxml_get_element(&ctx->xml_ctx, data, &prefix, &prefix_len, &name, &name_len));
+
+ /* parse child element */
+ child = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len, elem_type);
+ if ((elem_type == LY_STMT_ERROR_MESSAGE && child != LY_STMT_ARG_VALUE) ||
+ (elem_type != LY_STMT_ERROR_MESSAGE && child != LY_STMT_ARG_TEXT)) {
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len, ctx->xmlctx->name,
+ ly_stmt2str(elem_type));
+ return LY_EVALID;
}
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+
+ /* no attributes expected? TODO */
+ while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ }
+
+ /* load and save content */
+ *arg = INSERT_STRING(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic);
+ LY_CHECK_RET(!*arg, LY_EMEM);
+
+ /* load closing tag of subelement */
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+
+ /* if only subelement was parsed as argument, load also closing tag TODO what? */
+ /*if (ctx->xmlctx->status == LYXML_ELEMENT) {
+ LY_CHECK_RET(lyxml_get_element(&ctx->xmlctx, data, &prefix, &prefix_len, &name, &name_len));
+ }*/
break;
default:
- LOGINT(ctx->xml_ctx.ctx);
+ LOGINT(ctx->xmlctx->ctx);
return LY_EINT;
}
@@ -3398,45 +3264,40 @@
}
LY_ERR
-yin_parse_element_generic(struct yin_parser_ctx *ctx, const char *name, size_t name_len, const char *prefix, size_t prefix_len, enum ly_stmt parent,
- const char **data, struct lysp_stmt **element)
+yin_parse_element_generic(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, struct lysp_stmt **element)
{
LY_ERR ret = LY_SUCCESS;
- const char *temp_prefix, *temp_name;
- char *out = NULL;
- size_t out_len, temp_name_len, temp_prefix_len;
- int dynamic;
struct lysp_stmt *last = NULL, *new = NULL;
- struct yin_arg_record *attrs = NULL;
- struct yin_arg_record *iter = NULL;
- /* load all attributes for correct namespace evaluation */
- ret = yin_load_attributes(ctx, data, &attrs);
- LY_CHECK_GOTO(ret, cleanup);
+ assert(ctx->xmlctx->status == LYXML_ELEMENT);
/* allocate new structure for element */
*element = calloc(1, sizeof(**element));
- LY_CHECK_ERR_GOTO(!(*element), LOGMEM(ctx->xml_ctx.ctx); ret = LY_EMEM, cleanup);
- (*element)->stmt = name2nsname(ctx, name, name_len, prefix, prefix_len);
+ LY_CHECK_ERR_GOTO(!(*element), LOGMEM(ctx->xmlctx->ctx); ret = LY_EMEM, cleanup);
+ (*element)->stmt = name2nsname(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix, ctx->xmlctx->prefix_len);
LY_CHECK_ERR_GOTO(!(*element)->stmt, ret = LY_EMEM, cleanup);
- (*element)->kw = yin_match_keyword(ctx, name, name_len, prefix, prefix_len, parent);
+ (*element)->kw = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
+ ctx->xmlctx->prefix_len, parent);
last = (*element)->child;
if ((*element)->kw == LY_STMT_NONE) {
/* unrecognized element */
- LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, name_len, name, ly_stmt2str(parent));
+ LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LY_VCODE_UNEXP_SUBELEM, ctx->xmlctx->name_len, ctx->xmlctx->name,
+ ly_stmt2str(parent));
ret = LY_EVALID;
goto cleanup;
} else if ((*element)->kw != LY_STMT_EXTENSION_INSTANCE) {
/* element is known yang keyword, which means argument can be parsed correctly. */
- ret = yin_parse_extension_instance_arg(ctx, attrs, data, (*element)->kw, &(*element)->arg);
+ ret = yin_parse_extension_instance_arg(ctx, (*element)->kw, &(*element)->arg);
LY_CHECK_GOTO(ret, cleanup);
} else {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+
/* load attributes in generic way, save all attributes in linked list */
- LY_ARRAY_FOR(attrs, struct yin_arg_record, iter) {
+ while (ctx->xmlctx->status == LYXML_ATTRIBUTE) {
new = calloc(1, sizeof(*last));
- LY_CHECK_ERR_GOTO(!new, LOGMEM(ctx->xml_ctx.ctx); ret = LY_EMEM, cleanup);
+ LY_CHECK_ERR_GOTO(!new, LOGMEM(ctx->xmlctx->ctx); ret = LY_EMEM, cleanup);
if (!(*element)->child) {
/* save first */
(*element)->child = new;
@@ -3446,68 +3307,62 @@
last = new;
last->flags |= LYS_YIN_ATTR;
- last->stmt = lydict_insert(ctx->xml_ctx.ctx, iter->name, iter->name_len);
+ last->stmt = lydict_insert(ctx->xmlctx->ctx, ctx->xmlctx->name, ctx->xmlctx->name_len);
last->kw = LY_STMT_NONE;
/* attributes with prefix are ignored */
- if (!iter->prefix) {
- INSERT_STRING(ctx->xml_ctx.ctx, last->arg, iter->dynamic_content, iter->content, iter->content_len);
+ if (!ctx->xmlctx->prefix) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+
+ last->arg = INSERT_STRING(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic);
LY_CHECK_ERR_GOTO(!last->arg, ret = LY_EMEM, cleanup);
- /* string is no longer supposed to be freed when the array is freed */
- iter->dynamic_content = 0;
+ } else {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
}
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
}
}
- /* parse content of element if any */
- if (ctx->xml_ctx.status == LYXML_ELEM_CONTENT) {
- ret = lyxml_get_string(&ctx->xml_ctx, data, &out, &out_len, &out, &out_len, &dynamic);
- if (ret == LY_EINVAL) {
- while (ctx->xml_ctx.status == LYXML_ELEMENT) {
- /* parse subelements */
- ret = lyxml_get_element(&ctx->xml_ctx, data, &temp_prefix, &temp_prefix_len, &temp_name, &temp_name_len);
- LY_CHECK_GOTO(ret , cleanup);
- if (!temp_name) {
- /* end of element reached */
- break;
- }
- ret = yin_parse_element_generic(ctx, temp_name, temp_name_len, temp_prefix, temp_prefix_len, (*element)->kw, data, &new);
- LY_CHECK_GOTO(ret, cleanup);
- if (!(*element)->child) {
- /* save first */
- (*element)->child = new;
- } else {
- last->next = new;
- }
- last = new;
- }
- ret = LY_SUCCESS;
- } else {
+ if ((ctx->xmlctx->status != LYXML_ELEM_CONTENT) || ctx->xmlctx->ws_only) {
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
+ while (ctx->xmlctx->status == LYXML_ELEMENT) {
+ /* parse subelements */
+ ret = yin_parse_element_generic(ctx, (*element)->kw, &new);
LY_CHECK_GOTO(ret, cleanup);
- /* save element content */
- if (out_len != 0) {
- INSERT_STRING(ctx->xml_ctx.ctx, (*element)->arg, dynamic, out, out_len);
- LY_CHECK_ERR_GOTO(!(*element)->arg, ret = LY_EMEM, cleanup);
+ if (!(*element)->child) {
+ /* save first */
+ (*element)->child = new;
+ } else {
+ last->next = new;
}
+ last = new;
- /* read closing tag */
- ret = lyxml_get_element(&ctx->xml_ctx, data, &temp_prefix, &temp_prefix_len, &temp_name, &temp_name_len);
- LY_CHECK_GOTO(ret, cleanup);
+ assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
}
+ } else {
+ /* save element content */
+ if (ctx->xmlctx->value_len) {
+ (*element)->arg = INSERT_STRING(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic);
+ LY_CHECK_ERR_GOTO(!(*element)->arg, ret = LY_EMEM, cleanup);
+ }
+
+ /* read closing tag */
+ LY_CHECK_GOTO(ret = lyxml_ctx_next(ctx->xmlctx), cleanup);
}
cleanup:
- FREE_ARRAY(ctx, attrs, free_arg_rec);
return ret;
}
LY_ERR
-yin_parse_mod(struct yin_parser_ctx *ctx, struct yin_arg_record *mod_attrs, const char **data, struct lysp_module *mod)
+yin_parse_mod(struct lys_yin_parser_ctx *ctx, struct lysp_module *mod)
{
LY_ERR ret = LY_SUCCESS;
struct yin_subelement *subelems = NULL;
struct lysp_submodule *dup;
- LY_CHECK_RET(yin_parse_attribute(ctx, mod_attrs, YIN_ARG_NAME, &mod->mod->name, Y_IDENTIF_ARG, LY_STMT_MODULE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &mod->mod->name, Y_IDENTIF_ARG, LY_STMT_MODULE));
LY_CHECK_RET(subelems_allocator(ctx, 28, NULL, &subelems,
LY_STMT_ANYDATA, &mod->data, YIN_SUBELEM_VER2,
LY_STMT_ANYXML, &mod->data, 0,
@@ -3539,7 +3394,7 @@
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 28, data, LY_STMT_MODULE, NULL, &mod->exts);
+ ret = yin_parse_content(ctx, subelems, 28, LY_STMT_MODULE, NULL, &mod->exts);
subelems_deallocator(28, subelems);
LY_CHECK_RET(ret);
@@ -3548,7 +3403,7 @@
/* submodules share the namespace with the module names, so there must not be
* a submodule of the same name in the context, no need for revision matching */
- dup = ly_ctx_get_submodule(ctx->xml_ctx.ctx, NULL, mod->mod->name, NULL);
+ dup = ly_ctx_get_submodule(ctx->xmlctx->ctx, NULL, mod->mod->name, NULL);
if (dup) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YANG, "Name collision between module and submodule of name \"%s\".", mod->mod->name);
return LY_EVALID;
@@ -3558,13 +3413,14 @@
}
LY_ERR
-yin_parse_submod(struct yin_parser_ctx *ctx, struct yin_arg_record *mod_attrs, const char **data, struct lysp_submodule *submod)
+yin_parse_submod(struct lys_yin_parser_ctx *ctx, struct lysp_submodule *submod)
{
LY_ERR ret = LY_SUCCESS;
struct yin_subelement *subelems = NULL;
struct lysp_submodule *dup;
- LY_CHECK_RET(yin_parse_attribute(ctx, mod_attrs, YIN_ARG_NAME, &submod->name, Y_IDENTIF_ARG, LY_STMT_SUBMODULE));
+ LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
+ LY_CHECK_RET(yin_parse_attribute(ctx, YIN_ARG_NAME, &submod->name, Y_IDENTIF_ARG, LY_STMT_SUBMODULE));
LY_CHECK_RET(subelems_allocator(ctx, 27, NULL, &subelems,
LY_STMT_ANYDATA, &submod->data, YIN_SUBELEM_VER2,
LY_STMT_ANYXML, &submod->data, 0,
@@ -3595,7 +3451,7 @@
LY_STMT_EXTENSION_INSTANCE, NULL, 0
));
- ret = yin_parse_content(ctx, subelems, 27, data, LY_STMT_SUBMODULE, NULL, &submod->exts);
+ ret = yin_parse_content(ctx, subelems, 27, LY_STMT_SUBMODULE, NULL, &submod->exts);
subelems_deallocator(27, subelems);
LY_CHECK_RET(ret);
@@ -3604,7 +3460,7 @@
/* submodules share the namespace with the module names, so there must not be
* a submodule of the same name in the context, no need for revision matching */
- dup = ly_ctx_get_submodule(ctx->xml_ctx.ctx, NULL, submod->name, NULL);
+ dup = ly_ctx_get_submodule(ctx->xmlctx->ctx, NULL, submod->name, NULL);
if (dup && strcmp(dup->belongsto, submod->belongsto)) {
LOGVAL_PARSER((struct lys_parser_ctx *)ctx, LYVE_SYNTAX_YANG, "Name collision between submodules of name \"%s\".", dup->name);
return LY_EVALID;
@@ -3614,33 +3470,25 @@
}
LY_ERR
-yin_parse_submodule(struct yin_parser_ctx **yin_ctx, struct ly_ctx *ctx, struct lys_parser_ctx *main_ctx, const char *data, struct lysp_submodule **submod)
+yin_parse_submodule(struct lys_yin_parser_ctx **yin_ctx, struct ly_ctx *ctx, struct lys_parser_ctx *main_ctx, const char *data, struct lysp_submodule **submod)
{
enum ly_stmt kw = LY_STMT_NONE;
LY_ERR ret = LY_SUCCESS;
- const char *prefix, *name;
- size_t prefix_len, name_len;
- struct yin_arg_record *attrs = NULL;
struct lysp_submodule *mod_p = NULL;
/* create context */
*yin_ctx = calloc(1, sizeof **yin_ctx);
LY_CHECK_ERR_RET(!(*yin_ctx), LOGMEM(ctx), LY_EMEM);
- (*yin_ctx)->xml_ctx.ctx = ctx;
- (*yin_ctx)->pos_type = LY_VLOG_LINE;
- (*yin_ctx)->xml_ctx.line = 1;
+ (*yin_ctx)->format = LYS_IN_YIN;
+ LY_CHECK_RET(lyxml_ctx_new(ctx, data, &(*yin_ctx)->xmlctx));
/* map the typedefs and groupings list from main context to the submodule's context */
memcpy(&(*yin_ctx)->tpdfs_nodes, &main_ctx->tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
memcpy(&(*yin_ctx)->grps_nodes, &main_ctx->grps_nodes, sizeof main_ctx->grps_nodes);
/* check submodule */
- ret = lyxml_get_element(&(*yin_ctx)->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
- LY_CHECK_GOTO(ret, cleanup);
- ret = yin_load_attributes(*yin_ctx, &data, &attrs);
- LY_CHECK_GOTO(ret, cleanup);
- kw = yin_match_keyword(*yin_ctx, name, name_len, prefix, prefix_len, LY_STMT_NONE);
-
+ kw = yin_match_keyword(*yin_ctx, (*yin_ctx)->xmlctx->name, (*yin_ctx)->xmlctx->name_len, (*yin_ctx)->xmlctx->prefix,
+ (*yin_ctx)->xmlctx->prefix_len, LY_STMT_NONE);
if (kw == LY_STMT_MODULE) {
LOGERR(ctx, LY_EDENIED, "Input data contains module in situation when a submodule is expected.");
ret = LY_EINVAL;
@@ -3655,12 +3503,12 @@
LY_CHECK_ERR_GOTO(!mod_p, LOGMEM(ctx), cleanup);
mod_p->parsing = 1;
- ret = yin_parse_submod(*yin_ctx, attrs, &data, mod_p);
+ ret = yin_parse_submod(*yin_ctx, mod_p);
LY_CHECK_GOTO(ret, cleanup);
- name = NULL;
/* skip possible trailing whitespaces at end of the input */
- while(*data && isspace(*data)) {
+ data = (*yin_ctx)->xmlctx->input;
+ while (*data && isspace(*data)) {
data++;
}
if (*data) {
@@ -3678,34 +3526,25 @@
yin_parser_ctx_free(*yin_ctx);
*yin_ctx = NULL;
}
-
- FREE_ARRAY(*yin_ctx, attrs, free_arg_rec);
return ret;
}
LY_ERR
-yin_parse_module(struct yin_parser_ctx **yin_ctx, const char *data, struct lys_module *mod)
+yin_parse_module(struct lys_yin_parser_ctx **yin_ctx, const char *data, struct lys_module *mod)
{
LY_ERR ret = LY_SUCCESS;
enum ly_stmt kw = LY_STMT_NONE;
struct lysp_module *mod_p = NULL;
- const char *prefix, *name;
- size_t prefix_len, name_len;
- struct yin_arg_record *attrs = NULL;
/* create context */
*yin_ctx = calloc(1, sizeof **yin_ctx);
LY_CHECK_ERR_RET(!(*yin_ctx), LOGMEM(mod->ctx), LY_EMEM);
- (*yin_ctx)->xml_ctx.ctx = mod->ctx;
- (*yin_ctx)->pos_type = LY_VLOG_LINE;
- (*yin_ctx)->xml_ctx.line = 1;
+ (*yin_ctx)->format = LYS_IN_YIN;
+ LY_CHECK_RET(lyxml_ctx_new(mod->ctx, data, &(*yin_ctx)->xmlctx));
/* check module */
- ret = lyxml_get_element(&(*yin_ctx)->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
- LY_CHECK_GOTO(ret, cleanup);
- ret = yin_load_attributes(*yin_ctx, &data, &attrs);
- LY_CHECK_GOTO(ret, cleanup);
- kw = yin_match_keyword(*yin_ctx, name, name_len, prefix, prefix_len, LY_STMT_NONE);
+ kw = yin_match_keyword(*yin_ctx, (*yin_ctx)->xmlctx->name, (*yin_ctx)->xmlctx->name_len, (*yin_ctx)->xmlctx->prefix,
+ (*yin_ctx)->xmlctx->prefix_len, LY_STMT_NONE);
if (kw == LY_STMT_SUBMODULE) {
LOGERR(mod->ctx, LY_EDENIED, "Input data contains submodule which cannot be parsed directly without its main module.");
ret = LY_EINVAL;
@@ -3723,12 +3562,12 @@
mod_p->parsing = 1;
/* parse module substatements */
- ret = yin_parse_mod(*yin_ctx, attrs, &data, mod_p);
+ ret = yin_parse_mod(*yin_ctx, mod_p);
LY_CHECK_GOTO(ret, cleanup);
- name = NULL;
/* skip possible trailing whitespaces at end of the input */
- while(*data && isspace(*data)) {
+ data = (*yin_ctx)->xmlctx->input;
+ while (*data && isspace(*data)) {
data++;
}
if (*data) {
@@ -3746,6 +3585,5 @@
yin_parser_ctx_free(*yin_ctx);
*yin_ctx = NULL;
}
- FREE_ARRAY(*yin_ctx, attrs, free_arg_rec);
return ret;
}
diff --git a/src/parser_yin.h b/src/parser_yin.h
index 7faf7e1..9905581 100644
--- a/src/parser_yin.h
+++ b/src/parser_yin.h
@@ -36,19 +36,6 @@
kw == LY_STMT_MUST || kw == LY_STMT_TYPE || kw == LY_STMT_UNIQUE || \
kw == LY_STMT_UNITS || kw == LY_STMT_EXTENSION_INSTANCE)
-/**
- * @brief insert string into dictionary and store as target.
- *
- * @param[in] CTX libyang context.
- * @param[out] TARGET variable where to store the pointer to the inserted value.
- * @param[in] DYNAMIC Set to 1 if STR is dynamically allocated, 0 otherwise. If set to 1, zerocopy version of lydict_insert is used.
- * @param[in] STR string to store.
- * @param[in] LEN length of the string in WORD to store.
- */
-#define INSERT_STRING(CTX, TARGET, DYNAMIC, STR, LEN) \
- if (DYNAMIC) {(TARGET) = lydict_insert_zc(CTX, STR);} \
- else {(TARGET) = lydict_insert(CTX, LEN ? STR : "", LEN);}
-
enum yin_argument {
YIN_ARG_UNKNOWN = 0, /**< parsed argument can not be matched with any supported yin argument keyword */
YIN_ARG_NAME, /**< argument name */
@@ -63,19 +50,6 @@
YIN_ARG_NONE, /**< empty (special value) */
};
-/**
- * @brief structure to store instance of xml attribute
- */
-struct yin_arg_record {
- const char *prefix; /**< start of prefix */
- size_t prefix_len; /**< length of prefix */
- const char *name; /**< start of name */
- size_t name_len; /**< length of name */
- char *content; /**< start of content */
- size_t content_len; /**< length of content */
- int dynamic_content; /**< is set to 1 iff content is dynamically allocated 0 otherwise */
-};
-
/* flags to set constraints of subelements */
#define YIN_SUBELEM_MANDATORY 0x01 /**< is set when subelement is mandatory */
#define YIN_SUBELEM_UNIQUE 0x02 /**< is set when subelement is unique */
@@ -156,16 +130,14 @@
* @param[in,out] ctx Yin parser context for logging and to store current state.
* @param[in] subelem_info array of valid subelement types and meta information
* @param[in] subelem_info_size Size of subelem_info array.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[in] current_element Type of current element.
* @param[out] text_content Where the text content of element should be stored if any. Text content is ignored if set to NULL.
* @param[in,out] exts Extension instance to add to. Can be set to null if element cannot have extension as subelements.
*
* @return LY_ERR values.
*/
-LY_ERR yin_parse_content(struct yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
- const char **data, enum ly_stmt current_element, const char **text_content,
- struct lysp_ext_instance **exts);
+LY_ERR yin_parse_content(struct lys_yin_parser_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
+ enum ly_stmt current_element, const char **text_content, struct lysp_ext_instance **exts);
/**
* @brief Check that val is valid UTF8 character sequence of val_type.
@@ -173,12 +145,10 @@
*
* @param[in] ctx Yin parser context for logging.
* @param[in] val_type Type of the input string to select method of checking character validity.
- * @param[in] val Input to validate.
- * @param[in] len Length of input.
*
* @return LY_ERR values.
*/
-LY_ERR yin_validate_value(struct yin_parser_ctx *ctx, enum yang_arg val_type, char *val, size_t len);
+LY_ERR yin_validate_value(struct lys_yin_parser_ctx *ctx, enum yang_arg val_type);
/**
* @brief Match yang keyword from yin data.
@@ -192,91 +162,52 @@
*
* @return yang_keyword values.
*/
-enum ly_stmt yin_match_keyword(struct yin_parser_ctx *ctx, const char *name, size_t name_len,
+enum ly_stmt yin_match_keyword(struct lys_yin_parser_ctx *ctx, const char *name, size_t name_len,
const char *prefix, size_t prefix_len, enum ly_stmt parrent);
/**
- * @brief Load all attributes of element into ([sized array](@ref sizedarrays)). Caller is suposed to free the array.
- *
- * @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in,out] data Data to read from, always moved to currently handled character.
- * @param[out] attrs ([Sized array](@ref sizedarrays)) of attributes.
- *
- * @return LY_ERR values.
- */
-LY_ERR yin_load_attributes(struct yin_parser_ctx *ctx, const char **data, struct yin_arg_record **attrs);
-
-/**
* @brief Parse instance of extension.
*
* @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] attrs [Sized array](@ref sizedarrays) of attributes of extension instance.
- * @param[in,out] data Data to read from, always moved to currently handled character.
- * @param[in] name Name of the extension element.
- * @param[in] name_len Length of extension name.
- * @param[in] prefix Prefix of extension name.
- * @param[in] prefix_len Length of extension prefix.
* @param[in] subelem Type of the keyword this extension instance is a subelement of.
* @param[in] subelem_index Index of the keyword instance this extension instance is a subelement of
* @param[in,out] exts Extension instance to add to.
*
* @return LY_ERR values.
*/
-LY_ERR yin_parse_extension_instance(struct yin_parser_ctx *ctx, struct yin_arg_record *attrs, const char **data,
- const char *ext_name, size_t ext_name_len, const char *ext_prefix, size_t ext_prefix_len,
- LYEXT_SUBSTMT subelem, uint32_t subelem_index, struct lysp_ext_instance **exts);
+LY_ERR yin_parse_extension_instance(struct lys_yin_parser_ctx *ctx, LYEXT_SUBSTMT subelem, uint32_t subelem_index,
+ struct lysp_ext_instance **exts);
/**
* @brief Parse yin element into generic structure.
*
- * @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] name Name of element.
- * @param[in] name_len Length of elements Name.
- * @param[in] prefix Prefix of element.
- * @param[in] prefix_len Length of elements prefix.
+ * @param[in,out] ctx Yin parser context for XML context, logging, and to store current state.
* @param[in] parent Identification of parent element.
- * @param[in,out] data Data to read from, always moved to currently handled character.
* @param[out] element Where the element structure should be stored.
*
* @return LY_ERR values.
*/
-LY_ERR yin_parse_element_generic(struct yin_parser_ctx *ctx, const char *name, size_t name_len, const char *prefix,
- size_t prefix_len, enum ly_stmt parent, const char **data, struct lysp_stmt **element);
+LY_ERR yin_parse_element_generic(struct lys_yin_parser_ctx *ctx, enum ly_stmt parent, struct lysp_stmt **element);
/**
* @brief Parse module element.
*
* @param[in,out] ctx Yin parser context for logging and to store current state.
- * @param[in] mod_attrs Attributes of module element.
- * @param[in,out] data Data to read from.
* @param[out] mod Parsed module structure.
*
* @return LY_ERR values.
*/
-LY_ERR yin_parse_mod(struct yin_parser_ctx *ctx, struct yin_arg_record *mod_attrs,
- const char **data, struct lysp_module *mod);
-
+LY_ERR yin_parse_mod(struct lys_yin_parser_ctx *ctx, struct lysp_module *mod);
/**
* @brief Parse submodule element.
*
* @param[in,out] ctx Yin parser context for logging and to store current state.
* @param[in] mod_attrs Attributes of submodule element.
- * @param[in,out] data Data to read from.
* @param[out] submod Parsed submodule structure.
*
* @return LY_ERR values.
*/
-LY_ERR yin_parse_submod(struct yin_parser_ctx *ctx, struct yin_arg_record *mod_attrs,
- const char **data, struct lysp_submodule *submod);
-
-/**
- * @brief free argument record, content loaded from lyxml_get_string() can be
- * dynamically allocated in some cases so it must be also freed.
- *
- * @param ctx unused just to fulfill signature of callback for FREE_ARRAY.
- * @param[in] record Record to free.
- */
-void free_arg_rec(struct yin_parser_ctx *ctx, struct yin_arg_record *record);
+LY_ERR yin_parse_submod(struct lys_yin_parser_ctx *ctx, struct lysp_submodule *submod);
#endif /* LY_PARSER_YIN_H_*/
diff --git a/src/tree_data.h b/src/tree_data.h
index c9a0a9d..aaeabf9 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -470,18 +470,6 @@
* @{
*/
-#define LYD_OPT_DATA 0x0 /**< Default type of data - complete datastore content with configuration as well as
- state data. */
-#define LYD_OPT_CONFIG LYD_OPT_NO_STATE
- /**< A configuration datastore - complete datastore without state data. */
-#define LYD_OPT_GET LYD_OPT_PARSE_ONLY
- /**< Data content from a NETCONF reply message to the NETCONF \<get\> operation. */
-#define LYD_OPT_GETCONFIG LYD_OPT_PARSE_ONLY | LYD_OPT_NO_STATE
- /**< Data content from a NETCONF reply message to the NETCONF \<get-config\> operation. */
-#define LYD_OPT_EDIT LYD_OPT_OPAQ
- /**< Data content of a NETCONF RPC \<edit-config\> operation. */
-
-
#define LYD_OPT_PARSE_ONLY 0x0001 /**< Data will be only parsed and no validation will be performed. When statements
are kept unevaluated, union types may not be fully resolved, if-feature
statements are not checked, and default values are not added (only the ones
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index e319fb6..e064b06 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -271,13 +271,11 @@
*
* @param[in] ctx libyang context.
* @param[in] data Pointer to the XML data to parse.
- * @param[out] tree Parsed RPC/action data tree.
- * @param[out] attr Any found attributes on the rpc envelope.
+ * @param[out] tree Parsed full RPC/action tree.
* @param[out] op Pointer to the actual operation. Useful mainly for action.
* @return LY_ERR value.
*/
-LY_ERR lyd_parse_xml_rpc(struct ly_ctx *ctx, const char *data, struct lyd_node **tree, struct ly_attr **attr,
- struct lyd_node **op);
+//LY_ERR lyd_parse_xml_rpc(struct ly_ctx *ctx, const char *data, struct lyd_node **tree, struct lyd_node **op);
/**
* @defgroup datahash Data nodes hash manipulation
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 6850e16..096de34 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -625,22 +625,24 @@
struct lysp_submodule *
lys_parse_mem_submodule(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, struct lys_parser_ctx *main_ctx,
- LY_ERR (*custom_check)(struct ly_ctx*, struct lysp_module*, struct lysp_submodule*, void*), void *check_data)
+ LY_ERR (*custom_check)(const struct ly_ctx*, struct lysp_module*, struct lysp_submodule*, void*), void *check_data)
{
LY_ERR ret = LY_EINVAL;
struct lysp_submodule *submod = NULL, *latest_sp;
- struct lys_parser_ctx *context = NULL;
- struct yin_parser_ctx *yin_context = NULL;
+ struct lys_yang_parser_ctx *yangctx = NULL;
+ struct lys_yin_parser_ctx *yinctx = NULL;
+ struct lys_parser_ctx *pctx;
LY_CHECK_ARG_RET(ctx, ctx, data, NULL);
switch (format) {
case LYS_IN_YIN:
- ret = yin_parse_submodule(&yin_context, ctx, main_ctx, data, &submod);
- context = (struct lys_parser_ctx *)yin_context;
+ ret = yin_parse_submodule(&yinctx, ctx, main_ctx, data, &submod);
+ pctx = (struct lys_parser_ctx *)yinctx;
break;
case LYS_IN_YANG:
- ret = yang_parse_submodule(&context, ctx, main_ctx, data, &submod);
+ ret = yang_parse_submodule(&yangctx, ctx, main_ctx, data, &submod);
+ pctx = (struct lys_parser_ctx *)yangctx;
break;
default:
LOGERR(ctx, LY_EINVAL, "Invalid schema input format.");
@@ -652,7 +654,7 @@
lysp_sort_revisions(submod->revs);
/* decide the latest revision */
- latest_sp = ly_ctx_get_submodule((*context).ctx, submod->belongsto, submod->name, NULL);
+ latest_sp = ly_ctx_get_submodule(PARSER_CTX(pctx), submod->belongsto, submod->name, NULL);
if (latest_sp) {
if (submod->revs) {
if (!latest_sp->revs) {
@@ -673,7 +675,7 @@
}
if (custom_check) {
- LY_CHECK_GOTO(custom_check((*context).ctx, NULL, submod, check_data), error);
+ LY_CHECK_GOTO(custom_check(PARSER_CTX(pctx), NULL, submod, check_data), error);
}
if (latest_sp) {
@@ -681,29 +683,29 @@
}
/* remap possibly changed and reallocated typedefs and groupings list back to the main context */
- memcpy(&main_ctx->tpdfs_nodes, &(*context).tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
- memcpy(&main_ctx->grps_nodes, &(*context).grps_nodes, sizeof main_ctx->grps_nodes);
+ memcpy(&main_ctx->tpdfs_nodes, &pctx->tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
+ memcpy(&main_ctx->grps_nodes, &pctx->grps_nodes, sizeof main_ctx->grps_nodes);
if (format == LYS_IN_YANG) {
- lys_parser_ctx_free(context);
+ yang_parser_ctx_free(yangctx);
} else {
- yin_parser_ctx_free(yin_context);
+ yin_parser_ctx_free(yinctx);
}
return submod;
error:
lysp_submodule_free(ctx, submod);
if (format == LYS_IN_YANG) {
- lys_parser_ctx_free(context);
+ yang_parser_ctx_free(yangctx);
} else {
- yin_parser_ctx_free(yin_context);
+ yin_parser_ctx_free(yinctx);
}
return NULL;
}
struct lys_module *
lys_parse_mem_module(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, int implement,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
+ LY_ERR (*custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
void *check_data)
{
struct lys_module *mod = NULL, *latest, *mod_dup;
@@ -711,8 +713,9 @@
struct lysp_include *inc;
LY_ERR ret = LY_EINVAL;
unsigned int u, i;
- struct lys_parser_ctx *context = NULL;
- struct yin_parser_ctx *yin_context = NULL;
+ struct lys_yang_parser_ctx *yangctx = NULL;
+ struct lys_yin_parser_ctx *yinctx = NULL;
+ struct lys_parser_ctx *pctx;
LY_CHECK_ARG_RET(ctx, ctx, data, NULL);
@@ -722,11 +725,12 @@
switch (format) {
case LYS_IN_YIN:
- ret = yin_parse_module(&yin_context, data, mod);
- context = (struct lys_parser_ctx *)yin_context;
+ ret = yin_parse_module(&yinctx, data, mod);
+ pctx = (struct lys_parser_ctx *)yinctx;
break;
case LYS_IN_YANG:
- ret = yang_parse_module(&context, data, mod);
+ ret = yang_parse_module(&yangctx, data, mod);
+ pctx = (struct lys_parser_ctx *)yangctx;
break;
default:
LOGERR(ctx, LY_EINVAL, "Invalid schema input format.");
@@ -828,7 +832,7 @@
}
LY_ARRAY_FOR(mod->parsed->includes, u) {
inc = &mod->parsed->includes[u];
- if (!inc->submodule && lysp_load_submodule(context, mod->parsed, inc)) {
+ if (!inc->submodule && lysp_load_submodule(pctx, mod->parsed, inc)) {
goto error_ctx;
}
if (!mod->implemented) {
@@ -839,12 +843,12 @@
mod->parsed->parsing = 0;
/* check name collisions - typedefs and TODO groupings */
- LY_CHECK_GOTO(lysp_check_typedefs(context, mod->parsed), error_ctx);
+ LY_CHECK_GOTO(lysp_check_typedefs(pctx, mod->parsed), error_ctx);
if (format == LYS_IN_YANG) {
- lys_parser_ctx_free(context);
+ yang_parser_ctx_free(yangctx);
} else {
- yin_parser_ctx_free(yin_context);
+ yin_parser_ctx_free(yinctx);
}
return mod;
@@ -852,11 +856,11 @@
ly_set_rm(&ctx->list, mod, NULL);
error:
lys_module_free(mod, NULL);
- ly_set_erase(&context->tpdfs_nodes, NULL);
+ ly_set_erase(&pctx->tpdfs_nodes, NULL);
if (format == LYS_IN_YANG) {
- lys_parser_ctx_free(context);
+ yang_parser_ctx_free(yangctx);
} else {
- yin_parser_ctx_free(yin_context);
+ yin_parser_ctx_free(yinctx);
}
return NULL;
@@ -901,8 +905,7 @@
void *
lys_parse_fd_(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, int implement, struct lys_parser_ctx *main_ctx,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
- void *check_data)
+ lys_custom_check custom_check, void *check_data)
{
void *result;
struct lys_module *mod = NULL;
@@ -944,8 +947,7 @@
}
struct lys_module *
-lys_parse_fd_module(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, int implement,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
+lys_parse_fd_module(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, int implement, lys_custom_check custom_check,
void *check_data)
{
return (struct lys_module*)lys_parse_fd_(ctx, fd, format, implement, NULL, custom_check, check_data);
@@ -953,8 +955,7 @@
struct lysp_submodule *
lys_parse_fd_submodule(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, struct lys_parser_ctx *main_ctx,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
- void *check_data)
+ lys_custom_check custom_check, void *check_data)
{
assert(main_ctx);
return (struct lysp_submodule*)lys_parse_fd_(ctx, fd, format, 0, main_ctx, custom_check, check_data);
@@ -968,7 +969,7 @@
struct lys_module *
lys_parse_path_(struct ly_ctx *ctx, const char *path, LYS_INFORMAT format, int implement,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data), void *check_data)
+ lys_custom_check custom_check, void *check_data)
{
int fd;
struct lys_module *mod;
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 171e5e4..4bb2bf5 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -953,7 +953,7 @@
}
void
-lys_parser_ctx_free(struct lys_parser_ctx *ctx)
+yang_parser_ctx_free(struct lys_yang_parser_ctx *ctx)
{
if (ctx) {
free(ctx);
@@ -961,10 +961,10 @@
}
void
-yin_parser_ctx_free(struct yin_parser_ctx *ctx)
+yin_parser_ctx_free(struct lys_yin_parser_ctx *ctx)
{
if (ctx) {
- lyxml_context_clear(&ctx->xml_ctx);
+ lyxml_ctx_free(ctx->xmlctx);
free(ctx);
}
}
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 4c65540..b19990f 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -157,14 +157,12 @@
struct lysp_import *i;
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);
+ LOGVAL_PARSER(ctx, LYVE_REFERENCE, "Prefix \"%s\" already used as module prefix.", *value);
return LY_EEXIST;
}
LY_ARRAY_FOR(imports, struct lysp_import, i) {
if (i->prefix && &i->prefix != value && !strcmp(i->prefix, *value)) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE, "Prefix \"%s\" already used to import \"%s\" module.",
- *value, i->name);
+ LOGVAL_PARSER(ctx, LYVE_REFERENCE, "Prefix \"%s\" already used to import \"%s\" module.", *value, i->name);
return LY_EEXIST;
}
}
@@ -201,8 +199,8 @@
struct tm tm, tm_;
char *r;
- 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);
+ LY_CHECK_ARG_RET(ctx ? PARSER_CTX(ctx) : NULL, date, LY_EINVAL);
+ LY_CHECK_ERR_RET(date_len != LY_REV_SIZE - 1, LOGARG(ctx ? PARSER_CTX(ctx) : NULL, date_len), LY_EINVAL);
/* check format */
for (i = 0; i < date_len; i++) {
@@ -234,7 +232,7 @@
error:
if (stmt) {
if (ctx) {
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LY_VCODE_INVAL, date_len, date, stmt);
+ LOGVAL_PARSER(ctx, LY_VCODE_INVAL, date_len, date, stmt);
} else {
LOGVAL(NULL, LY_VLOG_NONE, NULL, LY_VCODE_INVAL, date_len, date, stmt);
}
@@ -438,7 +436,7 @@
} else {
for (size_t u = 0; u < name_len; ++u) {
if (iscntrl(name[u])) {
- LOGWRN(ctx->ctx, "Control characters in enum name should be avoided (\"%.*s\", character number %d).",
+ LOGWRN(PARSER_CTX(ctx), "Control characters in enum name should be avoided (\"%.*s\", character number %d).",
name_len, name, u + 1);
break;
}
@@ -448,7 +446,7 @@
return LY_SUCCESS;
}
-/*
+/**
* @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.
@@ -478,8 +476,7 @@
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);
+ LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Invalid name \"%s\" of typedef - name collision with a built-in type.", name);
return LY_EEXIST;
}
@@ -491,16 +488,14 @@
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);
+ LOGVAL_PARSER(ctx, 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 = parent->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);
+ LOGVAL_PARSER(ctx, LYVE_SYNTAX_YANG, "Invalid name \"%s\" of typedef - name collision with another scoped type.", name);
return LY_EEXIST;
}
}
@@ -511,14 +506,12 @@
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);
+ LOGVAL_PARSER(ctx, 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);
+ LOGVAL_PARSER(ctx, 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
@@ -675,7 +668,7 @@
};
static LY_ERR
-lysp_load_module_check(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data)
+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;
@@ -960,8 +953,9 @@
}
LY_ERR
-lysp_load_submodule(struct lys_parser_ctx *ctx, struct lysp_module *mod, struct lysp_include *inc)
+lysp_load_submodule(struct lys_parser_ctx *pctx, struct lysp_module *mod, struct lysp_include *inc)
{
+ struct ly_ctx *ctx = (struct ly_ctx *)(PARSER_CTX(pctx));
struct lysp_submodule *submod = NULL;
const char *submodule_data = NULL;
LYS_INFORMAT format = LYS_IN_UNKNOWN;
@@ -969,31 +963,31 @@
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)) {
+ if (!(ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
search_clb:
- if (ctx->ctx->imp_clb) {
- if (ctx->ctx->imp_clb(mod->mod->name, NULL, inc->name, inc->rev[0] ? inc->rev : NULL, ctx->ctx->imp_clb_data,
+ if (ctx->imp_clb) {
+ if (ctx->imp_clb(mod->mod->name, NULL, inc->name, inc->rev[0] ? inc->rev : NULL, 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->mod->name;
- submod = lys_parse_mem_submodule(ctx->ctx, submodule_data, format, ctx,
+ submod = lys_parse_mem_submodule(ctx, submodule_data, format, pctx,
lysp_load_module_check, &check_data);
if (submodule_data_free) {
- submodule_data_free((void*)submodule_data, ctx->ctx->imp_clb_data);
+ submodule_data_free((void*)submodule_data, ctx->imp_clb_data);
}
}
}
- if (!submod && !(ctx->ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
+ if (!submod && !(ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
goto search_file;
}
} else {
search_file:
- if (!(ctx->ctx->flags & LY_CTX_DISABLE_SEARCHDIRS)) {
+ if (!(ctx->flags & LY_CTX_DISABLE_SEARCHDIRS)) {
/* submodule 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, 0, ctx, mod->mod->name, 1, (void**)&submod);
+ lys_module_localfile(ctx, inc->name, inc->rev[0] ? inc->rev : NULL, 0, pctx, mod->mod->name, 1, (void**)&submod);
}
- if (!submod && (ctx->ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
+ if (!submod && (ctx->flags & LY_CTX_PREFER_SEARCHDIRS)) {
goto search_clb;
}
}
@@ -1007,7 +1001,7 @@
inc->submodule = submod;
}
if (!inc->submodule) {
- LOGVAL(ctx->ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Including \"%s\" submodule into \"%s\" failed.",
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Including \"%s\" submodule into \"%s\" failed.",
inc->name, mod->mod->name);
return LY_EVALID;
}
@@ -1426,7 +1420,7 @@
}
enum ly_stmt
-lysp_match_kw(struct lys_parser_ctx *ctx, const char **data)
+lysp_match_kw(struct lys_yang_parser_ctx *ctx, const char **data)
{
/**
* @brief Move the DATA pointer by COUNT items. Also updates the indent value in yang parser context
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 9b927e0..71b673d 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -24,8 +24,6 @@
#define YIN_NS_URI "urn:ietf:params:xml:ns:yang:yin:1"
-#define LOGVAL_PARSER(CTX, ...) LOGVAL((CTX)->ctx, (CTX)->pos_type, (CTX)->pos_type == LY_VLOG_LINE ? &(CTX)->line : (void*)(CTX)->path, __VA_ARGS__)
-
/**
* @brief Check module version is at least 2 (YANG 1.1) because of the keyword presence.
* Logs error message and returns LY_EVALID in case of module in YANG version 1.0.
@@ -73,9 +71,9 @@
} \
}
-#define YANG_CHECK_NONEMPTY(CTX, VALUE_LEN, STMT) \
+#define CHECK_NONEMPTY(CTX, VALUE_LEN, STMT) \
if (!VALUE_LEN) { \
- LOGWRN((CTX)->ctx, "Empty argument of %s statement does not make sense.", STMT); \
+ LOGWRN(PARSER_CTX(CTX), "Empty argument of %s statement does not make sense.", STMT); \
}
/**
@@ -99,10 +97,30 @@
Y_MAYBE_STR_ARG /**< optional YANG "string" rule */
};
+#define PARSER_CTX(CTX) (CTX)->format == LYS_IN_YANG ? ((struct lys_yang_parser_ctx *)CTX)->ctx : ((struct lys_yin_parser_ctx *)CTX)->xmlctx->ctx
+
+#define LOGVAL_PARSER(CTX, ...) (CTX)->format == LYS_IN_YANG ? LOGVAL_YANG(CTX, __VA_ARGS__) : LOGVAL_YIN(CTX, __VA_ARGS__)
+
+#define LOGVAL_YANG(CTX, ...) LOGVAL(PARSER_CTX(CTX), ((struct lys_yang_parser_ctx *)CTX)->pos_type, \
+ ((struct lys_yang_parser_ctx *)CTX)->pos_type == LY_VLOG_LINE ? \
+ (void *)&((struct lys_yang_parser_ctx *)CTX)->line : \
+ (void *)((struct lys_yang_parser_ctx *)CTX)->path, __VA_ARGS__)
+
+#define LOGVAL_YIN(CTX, ...) LOGVAL(PARSER_CTX(CTX), LY_VLOG_LINE, \
+ &((struct lys_yin_parser_ctx *)CTX)->xmlctx->line, __VA_ARGS__)
+
+struct lys_parser_ctx {
+ LYS_INFORMAT format; /**< parser format */
+ struct ly_set tpdfs_nodes; /**< set of typedef nodes */
+ struct ly_set grps_nodes; /**< set of grouping nodes */
+ uint8_t mod_version; /**< module's version */
+};
+
/**
* @brief Internal context for yang schema parser.
*/
-struct lys_parser_ctx {
+struct lys_yang_parser_ctx {
+ LYS_INFORMAT format; /**< parser format */
struct ly_set tpdfs_nodes; /**< set of typedef nodes */
struct ly_set grps_nodes; /**< set of grouping nodes */
uint8_t mod_version; /**< module's version */
@@ -118,17 +136,17 @@
/**
* @brief free lys parser context.
*/
-void lys_parser_ctx_free(struct lys_parser_ctx *ctx);
+void yang_parser_ctx_free(struct lys_yang_parser_ctx *ctx);
/**
* @brief Internal context for yin schema parser.
*/
-struct yin_parser_ctx {
+struct lys_yin_parser_ctx {
+ LYS_INFORMAT format; /**< parser format */
struct ly_set tpdfs_nodes; /**< set of typedef nodes */
struct ly_set grps_nodes; /**< set of grouping nodes */
uint8_t mod_version; /**< module's version */
- enum LY_VLOG_ELEM pos_type; /**< */
- struct lyxml_context xml_ctx; /**< context for xml parser */
+ struct lyxml_ctx *xmlctx; /**< context for xml parser */
};
/**
@@ -136,7 +154,7 @@
*
* @param[in] ctx Context to free.
*/
-void yin_parser_ctx_free(struct yin_parser_ctx *ctx);
+void yin_parser_ctx_free(struct lys_yin_parser_ctx *ctx);
struct lysc_incomplete_dflt {
struct lyd_value *dflt;
@@ -147,7 +165,7 @@
/**
* @brief Check that \p c is valid UTF8 code point for YANG string.
*
- * @param[in] ctx yang parser context for logging.
+ * @param[in] ctx parser context for logging.
* @param[in] c UTF8 code point of a character to check.
* @return LY_ERR values.
*/
@@ -156,7 +174,7 @@
/**
* @brief Check that \p c is valid UTF8 code point for YANG identifier.
*
- * @param[in] ctx yang parser context for logging.
+ * @param[in] ctx parser context for logging.
* @param[in] c UTF8 code point of a character to check.
* @param[in] first Flag to check the first character of an identifier, which is more restricted.
* @param[in,out] prefix Storage for internally used flag in case of possible prefixed identifiers:
@@ -296,7 +314,7 @@
* submodule is stored into this structure.
* @return LY_ERR value.
*/
-LY_ERR lysp_load_submodule(struct lys_parser_ctx *ctx, struct lysp_module *mod, struct lysp_include *inc);
+LY_ERR lysp_load_submodule(struct lys_parser_ctx *pctx, struct lysp_module *mod, struct lysp_include *inc);
/**
* @brief Compile printable schema into a validated schema linking all the references.
@@ -480,8 +498,10 @@
*/
const char *lys_datatype2str(LY_DATA_TYPE basetype);
+typedef LY_ERR (*lys_custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *check_data);
+
/**
- * @brief Parse YANG module from a string.
+ * @brief Parse module from a string.
*
* The modules are added into the context and the latest_revision flag is updated.
*
@@ -495,11 +515,10 @@
* @return Pointer to the data model structure or NULL on error.
*/
struct lys_module *lys_parse_mem_module(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, int implement,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *check_data),
- void *check_data);
+ lys_custom_check custom_check, void *check_data);
/**
- * @brief Parse YANG submodule from a string.
+ * @brief Parse submodule from a string.
*
* The latest_revision flag of submodule is updated.
*
@@ -513,11 +532,10 @@
* @return Pointer to the data model structure or NULL on error.
*/
struct lysp_submodule *lys_parse_mem_submodule(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, struct lys_parser_ctx *main_ctx,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *check_data),
- void *check_data);
+ lys_custom_check custom_check, void *check_data);
/**
- * @brief Parse YANG module or submodule from a file descriptor.
+ * @brief Parse module or submodule from a file descriptor.
*
* The modules are added into the context, submodules not. The latest_revision flag is updated in both cases.
*
@@ -535,8 +553,7 @@
* @return Pointer to the data model structure or NULL on error.
*/
void *lys_parse_fd_(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, int implement, struct lys_parser_ctx *main_ctx,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
- void *check_data);
+ lys_custom_check custom_check, void *check_data);
/**
* @brief Parse YANG module from a file descriptor.
@@ -555,11 +572,10 @@
* @return Pointer to the data model structure or NULL on error.
*/
struct lys_module *lys_parse_fd_module(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, int implement,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *check_data),
- void *check_data);
+ lys_custom_check custom_check, void *check_data);
/**
- * @brief Parse YANG submodule from a file descriptor.
+ * @brief Parse submodule from a file descriptor.
*
* The latest_revision flag of submodules is updated.
*
@@ -575,8 +591,7 @@
* @return Pointer to the data model structure or NULL on error.
*/
struct lysp_submodule *lys_parse_fd_submodule(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, struct lys_parser_ctx *main_ctx,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *check_data),
- void *check_data);
+ lys_custom_check custom_check, void *check_data);
/**
* @brief Parse YANG module from a filepath.
@@ -594,8 +609,7 @@
* @return Pointer to the data model structure or NULL on error.
*/
struct lys_module *lys_parse_path_(struct ly_ctx *ctx, const char *path, LYS_INFORMAT format, int implement,
- LY_ERR (*custom_check)(struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
- void *check_data);
+ lys_custom_check custom_check, void *check_data);
/**
* @brief Load the (sub)module into the context.
@@ -812,7 +826,7 @@
* @param[out] submod Pointer to the parsed submodule structure.
* @return LY_ERR value - LY_SUCCESS, LY_EINVAL or LY_EVALID.
*/
-LY_ERR yang_parse_submodule(struct lys_parser_ctx **context, struct ly_ctx *ly_ctx, struct lys_parser_ctx *main_ctx,
+LY_ERR yang_parse_submodule(struct lys_yang_parser_ctx **context, struct ly_ctx *ly_ctx, struct lys_parser_ctx *main_ctx,
const char *data, struct lysp_submodule **submod);
/**
@@ -823,7 +837,7 @@
* module structure, will be filled in.
* @return LY_ERR value - LY_SUCCESS, LY_EINVAL or LY_EVALID.
*/
-LY_ERR yang_parse_module(struct lys_parser_ctx **context, const char *data, struct lys_module *mod);
+LY_ERR yang_parse_module(struct lys_yang_parser_ctx **context, const char *data, struct lys_module *mod);
/**
* @brief Parse module from YIN data.
@@ -835,7 +849,7 @@
*
* @return LY_ERR values.
*/
-LY_ERR yin_parse_module(struct yin_parser_ctx **yin_ctx, const char *data, struct lys_module *mod);
+LY_ERR yin_parse_module(struct lys_yin_parser_ctx **yin_ctx, const char *data, struct lys_module *mod);
/**
* @brief Parse submodule from YIN data.
@@ -847,7 +861,7 @@
* @param[in,out] submod Submodule structure where the parsed information, will be filled in.
* @return LY_ERR values.
*/
-LY_ERR yin_parse_submodule(struct yin_parser_ctx **yin_ctx, struct ly_ctx *ctx, struct lys_parser_ctx *main_ctx,
+LY_ERR yin_parse_submodule(struct lys_yin_parser_ctx **yin_ctx, struct ly_ctx *ctx, struct lys_parser_ctx *main_ctx,
const char *data, struct lysp_submodule **submod);
@@ -868,7 +882,7 @@
* @param[in,out] data Data to read from, always moved to currently handled character.
* @return yang_keyword values.
*/
-enum ly_stmt lysp_match_kw(struct lys_parser_ctx *ctx, const char **data);
+enum ly_stmt lysp_match_kw(struct lys_yang_parser_ctx *ctx, const char **data);
/**
* @brief Generate path of the given node in the requested format.
diff --git a/src/xml.c b/src/xml.c
index d4b8a9e..8a9a3da 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -1,6 +1,7 @@
/**
* @file xml.c
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief Generic XML parser implementation for libyang
*
* Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
@@ -24,11 +25,14 @@
#include "xml.h"
#include "printer_internal.h"
-/* Move input p by s characters, if EOF log with lyxml_context c */
-#define move_input(c,p,s) p += s; LY_CHECK_ERR_RET(!p[0], LOGVAL(c->ctx, LY_VLOG_LINE, &c->line, LY_VCODE_EOF), LY_EVALID)
+/* Move input p by s characters, if EOF log with lyxml_ctx c */
+#define move_input(c,s) c->input += s; LY_CHECK_ERR_RET(!c->input[0], LOGVAL(c->ctx, LY_VLOG_LINE, &c->line, LY_VCODE_EOF), LY_EVALID)
/* Ignore whitespaces in the input string p */
-#define ign_xmlws(c,p) while (is_xmlws(*(p))) {if (*(p) == '\n') {++c->line;} ++p;}
+#define ign_xmlws(c) while (is_xmlws(*(c)->input)) {if (*(c)->input == '\n') {++c->line;} ++c->input;}
+
+static LY_ERR lyxml_next_attr_content(struct lyxml_ctx *xmlctx, const char **value, size_t *value_len, int *ws_only,
+ int *dynamic);
/**
* @brief Ignore any characters until the delim of the size delim_len is read
@@ -66,6 +70,257 @@
}
/**
+ * @brief Check/Get an XML identifier from the input string.
+ *
+ * The identifier must have at least one valid character complying the name start character constraints.
+ * The identifier is terminated by the first character, which does not comply to the name character constraints.
+ *
+ * See https://www.w3.org/TR/xml-names/#NT-NCName
+ *
+ * @param[in] xmlctx XML context.
+ * @param[out] start Pointer to the start of the identifier.
+ * @param[out] end Pointer ot the end of the identifier.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lyxml_parse_identifier(struct lyxml_ctx *xmlctx, const char **start, const char **end)
+{
+ const char *s, *in;
+ uint32_t c;
+ size_t parsed;
+ LY_ERR rc;
+
+ in = s = xmlctx->input;
+
+ /* check NameStartChar (minus colon) */
+ LY_CHECK_ERR_RET(ly_getutf8(&in, &c, &parsed),
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INCHAR, in[0]),
+ LY_EVALID);
+ LY_CHECK_ERR_RET(!is_xmlqnamestartchar(c),
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX,
+ "Identifier \"%s\" starts with an invalid character.", in - parsed),
+ LY_EVALID);
+
+ /* check rest of the identifier */
+ do {
+ /* move only successfully parsed bytes */
+ xmlctx->input += parsed;
+
+ rc = ly_getutf8(&in, &c, &parsed);
+ LY_CHECK_ERR_RET(rc, LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INCHAR, in[0]), LY_EVALID);
+ } while (is_xmlqnamechar(c));
+
+ *start = s;
+ *end = xmlctx->input;
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Add namespace definition into XML context.
+ *
+ * Namespaces from a single element are supposed to be added sequentially together (not interleaved by a namespace from other
+ * element). This mimic namespace visibility, since the namespace defined in element E is not visible from its parents or
+ * siblings. On the other hand, namespace from a parent element can be redefined in a child element. This is also reflected
+ * by lyxml_ns_get() which returns the most recent namespace definition for the given prefix.
+ *
+ * When leaving processing of a subtree of some element (after it is removed from xmlctx->elements), caller is supposed to call
+ * lyxml_ns_rm() to remove all the namespaces defined in such an element from the context.
+ *
+ * @param[in] xmlctx XML context to work with.
+ * @param[in] prefix Pointer to the namespace prefix. Can be NULL for default namespace.
+ * @param[in] prefix_len Length of the prefix.
+ * @param[in] uri Namespace URI (value) to store directly. Value is always spent.
+ * @return LY_ERR values.
+ */
+LY_ERR
+lyxml_ns_add(struct lyxml_ctx *xmlctx, const char *prefix, size_t prefix_len, char *uri)
+{
+ struct lyxml_ns *ns;
+
+ ns = malloc(sizeof *ns);
+ LY_CHECK_ERR_RET(!ns, LOGMEM(xmlctx->ctx), LY_EMEM);
+
+ /* we need to connect the depth of the element where the namespace is defined with the
+ * namespace record to be able to maintain (remove) the record when the parser leaves
+ * (to its sibling or back to the parent) the element where the namespace was defined */
+ ns->depth = xmlctx->elements.count;
+
+ ns->uri = uri;
+ if (prefix) {
+ ns->prefix = strndup(prefix, prefix_len);
+ LY_CHECK_ERR_RET(!ns->prefix, LOGMEM(xmlctx->ctx); free(ns->uri); free(ns), LY_EMEM);
+ } else {
+ ns->prefix = NULL;
+ }
+
+ LY_CHECK_ERR_RET(ly_set_add(&xmlctx->ns, ns, LY_SET_OPT_USEASLIST) == -1,
+ free(ns->prefix); free(ns->uri); free(ns), LY_EMEM);
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Remove all the namespaces defined in the element recently closed (removed from the xmlctx->elements).
+ *
+ * @param[in] xmlctx XML context to work with.
+ */
+void
+lyxml_ns_rm(struct lyxml_ctx *xmlctx)
+{
+ unsigned int u;
+
+ for (u = xmlctx->ns.count - 1; u + 1 > 0; --u) {
+ if (((struct lyxml_ns *)xmlctx->ns.objs[u])->depth != xmlctx->elements.count + 1) {
+ /* we are done, the namespaces from a single element are supposed to be together */
+ break;
+ }
+ /* remove the ns structure */
+ free(((struct lyxml_ns *)xmlctx->ns.objs[u])->prefix);
+ free(((struct lyxml_ns *)xmlctx->ns.objs[u])->uri);
+ free(xmlctx->ns.objs[u]);
+ --xmlctx->ns.count;
+ }
+
+ if (!xmlctx->ns.count) {
+ /* cleanup the xmlctx's namespaces storage */
+ ly_set_erase(&xmlctx->ns, NULL);
+ }
+}
+
+void *
+lyxml_elem_dup(void *item)
+{
+ struct lyxml_elem *dup;
+
+ dup = malloc(sizeof *dup);
+ memcpy(dup, item, sizeof *dup);
+
+ return dup;
+}
+
+void *
+lyxml_ns_dup(void *item)
+{
+ struct lyxml_ns *dup, *orig;
+
+ orig = (struct lyxml_ns *)item;
+ dup = malloc(sizeof *dup);
+ dup->prefix = orig->prefix ? strdup(orig->prefix) : NULL;
+ dup->uri = strdup(orig->uri);
+ dup->depth = orig->depth;
+
+ return dup;
+}
+
+const struct lyxml_ns *
+lyxml_ns_get(struct lyxml_ctx *xmlctx, const char *prefix, size_t prefix_len)
+{
+ unsigned int u;
+ struct lyxml_ns *ns;
+
+ for (u = xmlctx->ns.count - 1; u + 1 > 0; --u) {
+ ns = (struct lyxml_ns *)xmlctx->ns.objs[u];
+ if (prefix && prefix_len) {
+ if (ns->prefix && !ly_strncmp(ns->prefix, prefix, prefix_len)) {
+ return ns;
+ }
+ } else if (!ns->prefix) {
+ /* default namespace */
+ return ns;
+ }
+ }
+
+ return NULL;
+}
+
+static LY_ERR
+lyxml_skip_until_end_or_after_otag(struct lyxml_ctx *xmlctx)
+{
+ const struct ly_ctx *ctx = xmlctx->ctx; /* shortcut */
+ const char *in, *endtag, *sectname;
+ size_t endtag_len, newlines;
+
+ while (1) {
+ ign_xmlws(xmlctx);
+
+ if (xmlctx->input[0] == '\0') {
+ /* EOF */
+ if (xmlctx->elements.count) {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ return LY_EVALID;
+ }
+ return LY_SUCCESS;
+ } else if (xmlctx->input[0] != '<') {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->input),
+ xmlctx->input, "element tag start ('<')");
+ return LY_EVALID;
+ }
+ move_input(xmlctx, 1);
+
+ if (xmlctx->input[0] == '!') {
+ move_input(xmlctx, 1);
+ /* sections to ignore */
+ if (!strncmp(xmlctx->input, "--", 2)) {
+ /* comment */
+ move_input(xmlctx, 2);
+ sectname = "Comment";
+ endtag = "-->";
+ endtag_len = 3;
+ } else if (!strncmp(xmlctx->input, "[CDATA[", 7)) {
+ /* CDATA section */
+ move_input(xmlctx, 7);
+ sectname = "CData";
+ endtag = "]]>";
+ endtag_len = 3;
+ } else if (!strncmp(xmlctx->input, "DOCTYPE", 7)) {
+ /* Document type declaration - not supported */
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_NSUPP, "Document Type Declaration");
+ return LY_EVALID;
+ } else {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Unknown XML section \"%.20s\".", &xmlctx->input[-2]);
+ return LY_EVALID;
+ }
+ in = ign_todelim(xmlctx->input, endtag, endtag_len, &newlines);
+ LY_CHECK_ERR_RET(!in, LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_NTERM, sectname), LY_EVALID);
+ xmlctx->line += newlines;
+ xmlctx->input = in + endtag_len;
+ } else if (xmlctx->input[0] == '?') {
+ in = ign_todelim(xmlctx->input, "?>", 2, &newlines);
+ LY_CHECK_ERR_RET(!in, LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_NTERM, "Declaration"), LY_EVALID);
+ xmlctx->line += newlines;
+ xmlctx->input = in + 2;
+ } else {
+ /* other non-WS character */
+ break;
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
+static LY_ERR
+lyxml_parse_qname(struct lyxml_ctx *xmlctx, const char **prefix, size_t *prefix_len, const char **name, size_t *name_len)
+{
+ const char *start, *end;
+
+ *prefix = NULL;
+ *prefix_len = 0;
+
+ LY_CHECK_RET(lyxml_parse_identifier(xmlctx, &start, &end));
+ if (end[0] == ':') {
+ /* we have prefixed identifier */
+ *prefix = start;
+ *prefix_len = end - start;
+
+ move_input(xmlctx, 1);
+ LY_CHECK_RET(lyxml_parse_identifier(xmlctx, &start, &end));
+ }
+
+ *name = start;
+ *name_len = end - start;
+ return LY_SUCCESS;
+}
+
+/**
* Store UTF-8 character specified as 4byte integer into the dst buffer.
* Returns number of written bytes (4 max), expects that dst has enough space.
*
@@ -128,561 +383,85 @@
return LY_SUCCESS;
}
-/**
- * @brief Check/Get an XML qualified name from the input string.
- *
- * The identifier must have at least one valid character complying the name start character constraints.
- * The identifier is terminated by the first character, which does not comply to the name character constraints.
- *
- * See https://www.w3.org/TR/xml-names/#NT-NCName
- *
- * @param[in] context XML context to track lines or store errors into libyang context.
- * @param[in,out] input Input string to process, updated according to the processed/read data.
- * Note that the term_char is also read, so input points after the term_char at the end.
- * @param[out] term_char The first character in the input string which does not compy to the name constraints.
- * @param[out] term_char_len Number of bytes used to encode UTF8 term_char. Serves to be able to go back in input string.
- * @return LY_ERR value.
- */
static LY_ERR
-lyxml_check_qname(struct lyxml_context *context, const char **input, unsigned int *term_char, size_t *term_char_len)
+lyxml_parse_value(struct lyxml_ctx *xmlctx, char endchar, char **value, size_t *length, int *ws_only, int *dynamic)
{
- unsigned int c;
- const char *id = (*input);
- LY_ERR rc;
+#define BUFSIZE 24
+#define BUFSIZE_STEP 128
- /* check NameStartChar (minus colon) */
- LY_CHECK_ERR_RET(ly_getutf8(input, &c, NULL) != LY_SUCCESS,
- LOGVAL(context->ctx, LY_VLOG_LINE, &context->line, LY_VCODE_INCHAR, (*input)[0]), LY_EVALID);
- LY_CHECK_ERR_RET(!is_xmlqnamestartchar(c),
- LOGVAL(context->ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX,
- "Identifier \"%s\" starts with invalid character.", id),
- LY_EVALID);
-
- /* check rest of the identifier */
- for (rc = ly_getutf8(input, &c, term_char_len);
- rc == LY_SUCCESS && is_xmlqnamechar(c);
- rc = ly_getutf8(input, &c, term_char_len));
- LY_CHECK_ERR_RET(rc != LY_SUCCESS, LOGVAL(context->ctx, LY_VLOG_LINE, &context->line, LY_VCODE_INCHAR, (*input)[0]), LY_EVALID);
-
- (*term_char) = c;
- return LY_SUCCESS;
-}
-
-/**
- * @brief Add namespace definition into XML context.
- *
- * Namespaces from a single element are supposed to be added sequentially together (not interleaved by a namespace from other
- * element). This mimic namespace visibility, since the namespace defined in element E is not visible from its parents or
- * siblings. On the other hand, namespace from a parent element can be redefined in a child element. This is also reflected
- * by lyxml_ns_get() which returns the most recent namespace definition for the given prefix.
- *
- * When leaving processing of a subtree of some element (after it is removed from context->elements), caller is supposed to call
- * lyxml_ns_rm() to remove all the namespaces defined in such an element from the context.
- *
- * @param[in] context XML context to work with.
- * @param[in] prefix Pointer to the namespace prefix as taken from lyxml_get_attribute(). Can be NULL for default namespace.
- * @param[in] prefix_len Length of the prefix string (since it is not NULL-terminated when returned from lyxml_get_attribute()).
- * @param[in] uri Namespace URI (value) to store. Value can be obtained via lyxml_get_string() and caller is not supposed to
- * work with the pointer when the function succeeds. In case of error the value is freed.
- * @return LY_ERR values.
- */
-LY_ERR
-lyxml_ns_add(struct lyxml_context *context, const char *prefix, size_t prefix_len, char *uri)
-{
- struct lyxml_ns *ns;
-
- ns = malloc(sizeof *ns);
- LY_CHECK_ERR_RET(!ns, LOGMEM(context->ctx), LY_EMEM);
-
- /* we need to connect the depth of the element where the namespace is defined with the
- * namespace record to be able to maintain (remove) the record when the parser leaves
- * (to its sibling or back to the parent) the element where the namespace was defined */
- ns->depth = context->elements.count;
-
- ns->uri = uri;
- if (prefix) {
- ns->prefix = strndup(prefix, prefix_len);
- LY_CHECK_ERR_RET(!ns->prefix, LOGMEM(context->ctx); free(ns->uri); free(ns), LY_EMEM);
- } else {
- ns->prefix = NULL;
- }
-
- LY_CHECK_ERR_RET(ly_set_add(&context->ns, ns, LY_SET_OPT_USEASLIST) == -1,
- free(ns->prefix); free(ns->uri); free(ns), LY_EMEM);
- return LY_SUCCESS;
-}
-
-/**
- * @brief Remove all the namespaces defined in the element recently closed (removed from the context->elements).
- *
- * @param[in] context XML context to work with.
- */
-void
-lyxml_ns_rm(struct lyxml_context *context)
-{
- unsigned int u;
-
- for (u = context->ns.count - 1; u + 1 > 0; --u) {
- if (((struct lyxml_ns *)context->ns.objs[u])->depth != context->elements.count + 1) {
- /* we are done, the namespaces from a single element are supposed to be together */
- break;
- }
- /* remove the ns structure */
- free(((struct lyxml_ns *)context->ns.objs[u])->prefix);
- free(((struct lyxml_ns *)context->ns.objs[u])->uri);
- free(context->ns.objs[u]);
- --context->ns.count;
- }
-
- if (!context->ns.count) {
- /* cleanup the context's namespaces storage */
- ly_set_erase(&context->ns, NULL);
- }
-}
-
-void *
-lyxml_elem_dup(void *item)
-{
- struct lyxml_elem *dup;
-
- dup = malloc(sizeof *dup);
- memcpy(dup, item, sizeof *dup);
-
- return dup;
-}
-
-void *
-lyxml_ns_dup(void *item)
-{
- struct lyxml_ns *dup, *orig;
-
- orig = (struct lyxml_ns *)item;
- dup = malloc(sizeof *dup);
- dup->prefix = orig->prefix ? strdup(orig->prefix) : NULL;
- dup->uri = strdup(orig->uri);
- dup->depth = orig->depth;
-
- return dup;
-}
-
-const struct lyxml_ns *
-lyxml_ns_get(struct lyxml_context *context, const char *prefix, size_t prefix_len)
-{
- unsigned int u;
- struct lyxml_ns *ns;
-
- for (u = context->ns.count - 1; u + 1 > 0; --u) {
- ns = (struct lyxml_ns *)context->ns.objs[u];
- if (prefix && prefix_len) {
- if (ns->prefix && !ly_strncmp(ns->prefix, prefix, prefix_len)) {
- return ns;
- }
- } else if (!ns->prefix) {
- /* default namespace */
- return ns;
- }
- }
-
- return NULL;
-}
-
-static LY_ERR
-lyxml_parse_element_start(struct lyxml_context *context, const char **input, int *closing)
-{
- struct ly_ctx *ctx = context->ctx; /* shortcut */
- const char *in = (*input);
- const char *endtag;
- const char *sectname;
- size_t endtag_len, newlines;
-
- while (1) {
- ign_xmlws(context, in);
-
- if (in[0] == '\0') {
- /* EOF */
- if (context->elements.count) {
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_EOF);
- return LY_EVALID;
- }
- context->status = LYXML_END;
- (*input) = in;
- return LY_SUCCESS;
- } else if (in[0] != '<') {
- return LY_EINVAL;
- }
- move_input(context, in, 1);
-
- if (in[0] == '!') {
- move_input(context, in, 1);
- /* sections to ignore */
- if (!strncmp(in, "--", 2)) {
- /* comment */
- move_input(context, in, 2);
- sectname = "Comment";
- endtag = "-->";
- endtag_len = 3;
- } else if (!strncmp(in, "[CDATA[", 7)) {
- /* CDATA section */
- move_input(context, in, 7);
- sectname = "CData";
- endtag = "]]>";
- endtag_len = 3;
- } else if (!strncmp(in, "DOCTYPE", 7)) {
- /* Document type declaration - not supported */
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_NSUPP, "Document Type Declaration");
- return LY_EVALID;
- } else {
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX, "Unknown XML section \"%.20s\".", &in[-2]);
- return LY_EVALID;
- }
- in = ign_todelim(in, endtag, endtag_len, &newlines);
- LY_CHECK_ERR_RET(!in, LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_NTERM, sectname), LY_EVALID);
- context->line += newlines;
- in += endtag_len;
- } else if (in[0] == '?') {
- in = ign_todelim(in, "?>", 2, &newlines);
- LY_CHECK_ERR_RET(!in, LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_NTERM, "Declaration"), LY_EVALID);
- context->line += newlines;
- in += 2;
- } else if (in[0] == '/') {
- /* closing element tag */
- *closing = 1;
- ++in;
- goto element;
- } else {
- /* opening element tag */
- *closing = 0;
-element:
- ign_xmlws(context, in);
- LY_CHECK_ERR_RET(!in[0], LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_EOF), LY_EVALID);
-
- (*input) = in;
- return LY_SUCCESS;
- }
- }
-}
-
-static LY_ERR
-lyxml_parse_element_name(struct lyxml_context *context, const char **input, size_t *endtag_len, unsigned int *term_char,
- const char **prefix, size_t *prefix_len, const char **name, size_t *name_len)
-{
- LY_ERR rc;
- const char *in = (*input);
- const char *id;
- const char *endtag;
-
- id = in;
- rc = lyxml_check_qname(context, &in, term_char, endtag_len);
- LY_CHECK_RET(rc);
- if (*term_char == ':') {
- /* we have prefixed identifier */
- endtag = in - *endtag_len;
-
- rc = lyxml_check_qname(context, &in, term_char, endtag_len);
- LY_CHECK_RET(rc);
-
- (*prefix) = id;
- (*prefix_len) = endtag - id;
- id = endtag + 1;
- }
- if (!is_xmlws(*term_char) && *term_char != '/' && *term_char != '>') {
- (*input) = in - *endtag_len;
- LOGVAL(context->ctx, LY_VLOG_LINE, &context->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(*input), *input,
- "whitespace or element tag termination ('>' or '/>'");
- return LY_EVALID;
- }
- (*name) = id;
- (*name_len) = in - *endtag_len - id;
-
- if (is_xmlws(*term_char)) {
- /* go to the next meaningful input */
- ign_xmlws(context, in);
- LY_CHECK_ERR_RET(!in[0], LOGVAL(context->ctx, LY_VLOG_LINE, &context->line, LY_VCODE_EOF), LY_EVALID);
- *term_char = in[0];
- ++in;
- *endtag_len = 1;
- }
-
- (*input) = in;
- return LY_SUCCESS;
-}
-
-LY_ERR
-lyxml_get_element(struct lyxml_context *context, const char **input, const char **prefix_p, size_t *prefix_len_p,
- const char **name_p, size_t *name_len_p)
-{
- struct ly_ctx *ctx = context->ctx; /* shortcut */
- const char *in = (*input), *prefix = NULL, *name = NULL;
- size_t endtag_len, prefix_len = 0, name_len = 0;
- bool loop = true;
- int closing = 0;
- unsigned int c;
- LY_ERR rc;
- struct lyxml_elem *e;
-
- while (loop) {
- rc = lyxml_parse_element_start(context, &in, &closing);
- if (rc) {
- return rc;
- } else if (context->status == LYXML_END) {
- goto success;
- }
- /* we are at the begining of the element name, remember the identifier start before checking its format */
- LY_CHECK_RET(rc = lyxml_parse_element_name(context, &in, &endtag_len, &c, &prefix, &prefix_len, &name, &name_len));
-
- if (closing) {
- /* match opening and closing element tags */
- LY_CHECK_ERR_RET(
- !context->elements.count,
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX,
- "Opening and closing elements tag missmatch (\"%.*s\").", name_len, name),
- LY_EVALID);
- e = (struct lyxml_elem*)context->elements.objs[context->elements.count - 1];
- if (e->prefix_len != prefix_len || e->name_len != name_len
- || (prefix_len && strncmp(prefix, e->prefix, e->prefix_len)) || strncmp(name, e->name, e->name_len)) {
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX,
- "Opening and closing elements tag missmatch (\"%.*s\").", name_len, name);
- return LY_EVALID;
- }
- /* opening and closing element tags matches, remove record from the opening tags list */
- free(e);
- --context->elements.count;
-
- /* remove also the namespaces connected with the element */
- lyxml_ns_rm(context);
-
- /* clear closing element */
- name = prefix = NULL;
- name_len = prefix_len = 0;
-
- if (c == '>') {
- /* end of closing element */
- context->status = LYXML_ELEMENT;
- } else {
- in -= endtag_len;
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX, "Unexpected data \"%.*s\" in closing element tag.",
- LY_VCODE_INSTREXP_len(in), in);
- return LY_EVALID;
- }
- } else {
- if (c == '>') {
- /* end of opening element */
- context->status = LYXML_ELEM_CONTENT;
- } else if (c == '/' && in[0] == '>') {
- /* empty element closing */
- context->status = LYXML_ELEMENT;
- ++in;
- } else {
- /* attribute */
- context->status = LYXML_ATTRIBUTE;
- in -= endtag_len;
- }
-
- if (context->status != LYXML_ELEMENT) {
- /* store element opening tag information */
- e = malloc(sizeof *e);
- LY_CHECK_ERR_RET(!e, LOGMEM(ctx), LY_EMEM);
- e->name = name;
- e->prefix = prefix;
- e->name_len = name_len;
- e->prefix_len = prefix_len;
- ly_set_add(&context->elements, e, LY_SET_OPT_USEASLIST);
- }
- }
- loop = false;
- }
-
-success:
- /* check for end of input */
- if (in[0] == '\0') {
- /* EOF */
- if (context->elements.count) {
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_EOF);
- return LY_EVALID;
- }
- context->status = LYXML_END;
- }
- /* move caller's input */
- (*input) = in;
- /* return values */
- if (prefix_p) {
- *prefix_p = prefix;
- *prefix_len_p = prefix_len;
- }
- if (name_p) {
- *name_p = name;
- *name_len_p = name_len;
- }
- return LY_SUCCESS;
-}
-
-LY_ERR
-lyxml_skip_element(struct lyxml_context *context, const char **input)
-{
- LY_ERR ret;
- unsigned int parents_count = context->elements.count;
-
- while (context->elements.count >= parents_count) {
- /* skip attributes */
- while (context->status == LYXML_ATTRIBUTE) {
- LY_CHECK_RET(lyxml_get_attribute(context, input, NULL, NULL, NULL, NULL));
- }
-
- /* skip content */
- if (context->status == LYXML_ELEM_CONTENT) {
- ret = lyxml_get_string(context, input, NULL, NULL, NULL, NULL, NULL);
- if (ret && (ret != LY_EINVAL)) {
- return ret;
- }
- }
-
- if (context->status != LYXML_ELEMENT) {
- LOGINT(context->ctx);
- return LY_EINT;
- }
-
- /* nested element/closing element */
- LY_CHECK_RET(lyxml_get_element(context, input, NULL, NULL, NULL, NULL));
- }
-
- return LY_SUCCESS;
-}
-
-LY_ERR
-lyxml_get_string(struct lyxml_context *context, const char **input, char **buffer, size_t *buffer_size, char **output,
- size_t *length, int *dynamic)
-{
-#define BUFSIZE 4096
-#define BUFSIZE_STEP 4096
-#define BUFSIZE_CHECK(CTX, BUF, SIZE, CURR, NEED) \
- if (CURR+NEED >= SIZE) { \
- BUF = ly_realloc(BUF, SIZE + BUFSIZE_STEP); \
- LY_CHECK_ERR_RET(!BUF, LOGMEM(CTX), LY_EMEM); \
- SIZE += BUFSIZE_STEP; \
- }
-
- struct ly_ctx *ctx = context->ctx; /* shortcut */
- const char *in = (*input), *start;
- char *buf = NULL, delim;
+ const struct ly_ctx *ctx = xmlctx->ctx; /* shortcut */
+ const char *in = xmlctx->input, *start;
+ char *buf = NULL;
size_t offset; /* read offset in input buffer */
size_t len; /* length of the output string (write offset in output buffer) */
size_t size = 0; /* size of the output buffer */
void *p;
uint32_t n;
- size_t u, newlines;
- bool empty_content = false;
- LY_ERR rc = LY_SUCCESS;
+ size_t u;
+ int ws = 1;
- assert(context);
- assert(context->status == LYXML_ELEM_CONTENT || context->status == LYXML_ATTR_CONTENT);
+ assert(xmlctx);
- if (in[0] == '\'') {
- delim = '\'';
- ++in;
- } else if (in[0] == '"') {
- delim = '"';
- ++in;
- } else {
- delim = '<';
- empty_content = true;
- }
- start = in;
-
- if (empty_content) {
- /* only when processing element's content - try to ignore whitespaces used to format XML data
- * before element's child or closing tag */
- for (offset = newlines = 0; in[offset] && is_xmlws(in[offset]); ++offset) {
- if (in[offset] == '\n') {
- ++newlines;
- }
- }
- LY_CHECK_ERR_RET(!in[offset], LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_EOF), LY_EVALID);
- context->line += newlines;
- if (in[offset] == '<') {
- (*input) = in + offset;
-
- /* get know if it is child element (indentation) or closing element (whitespace-only content) */
- len = offset;
- offset = 0;
- in = *input;
- goto element_endtag_check;
- }
- }
/* init */
+ start = in;
offset = len = 0;
- empty_content = false;
-
- if (0) {
-getbuffer:
- /* prepare output buffer */
- if (*buffer) {
- buf = *buffer;
- size = *buffer_size;
- } else {
- buf = malloc(BUFSIZE);
- size = BUFSIZE;
- LY_CHECK_ERR_RET(!buf, LOGMEM(ctx), LY_EMEM);
- }
- }
/* parse */
while (in[offset]) {
if (in[offset] == '&') {
- if (output) {
- if (!buf) {
- /* it is necessary to modify the input, so we will need a dynamically allocated buffer */
- goto getbuffer;
- }
+ /* non WS */
+ ws = 0;
- if (offset) {
- /* store what we have so far */
- BUFSIZE_CHECK(ctx, buf, size, len, offset);
- memcpy(&buf[len], in, offset);
- len += offset;
- in += offset;
- offset = 0;
- }
- /* process reference */
- /* we will need 4 bytes at most since we support only the predefined
- * (one-char) entities and character references */
- BUFSIZE_CHECK(ctx, buf, size, len, 4);
+ if (!buf) {
+ /* prepare output buffer */
+ buf = malloc(BUFSIZE);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(ctx), LY_EMEM);
+ size = BUFSIZE;
}
+
+ /* allocate enough for the offset and next character,
+ * we will need 4 bytes at most since we support only the predefined
+ * (one-char) entities and character references */
+ if (len + offset + 4 >= size) {
+ buf = ly_realloc(buf, size + BUFSIZE_STEP);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(ctx), LY_EMEM);
+ size += BUFSIZE_STEP;
+ }
+
+ if (offset) {
+ /* store what we have so far */
+ memcpy(&buf[len], in, offset);
+ len += offset;
+ in += offset;
+ offset = 0;
+ }
+
++offset;
if (in[offset] != '#') {
/* entity reference - only predefined references are supported */
if (!strncmp(&in[offset], "lt;", 3)) {
- if (output) {
- buf[len++] = '<';
- }
+ buf[len++] = '<';
in += 4; /* < */
} else if (!strncmp(&in[offset], "gt;", 3)) {
- if (output) {
- buf[len++] = '>';
- }
+ buf[len++] = '>';
in += 4; /* > */
} else if (!strncmp(&in[offset], "amp;", 4)) {
- if (output) {
- buf[len++] = '&';
- }
+ buf[len++] = '&';
in += 5; /* & */
} else if (!strncmp(&in[offset], "apos;", 5)) {
- if (output) {
- buf[len++] = '\'';
- }
+ buf[len++] = '\'';
in += 6; /* ' */
} else if (!strncmp(&in[offset], "quot;", 5)) {
- if (output) {
- buf[len++] = '\"';
- }
+ buf[len++] = '\"';
in += 6; /* " */
} else {
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX,
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX,
"Entity reference \"%.*s\" not supported, only predefined references allowed.", 10, &in[offset-1]);
goto error;
}
offset = 0;
} else {
- p = (void*)&in[offset - 1];
+ p = (void *)&in[offset - 1];
/* character reference */
++offset;
if (isdigit(in[offset])) {
@@ -701,310 +480,548 @@
n = (16 * n) + u;
}
} else {
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX, "Invalid character reference \"%.*s\".", 12, p);
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Invalid character reference \"%.*s\".", 12, p);
goto error;
}
+
LY_CHECK_ERR_GOTO(in[offset] != ';',
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_INSTREXP,
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP,
LY_VCODE_INSTREXP_len(&in[offset]), &in[offset], ";"),
error);
++offset;
- if (output) {
- rc = lyxml_pututf8(&buf[len], n, &u);
- } else {
- char utf8[4];
- rc = lyxml_pututf8(&utf8[0], n, &u);
- }
- LY_CHECK_ERR_GOTO(rc, LOGVAL(ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX,
- "Invalid character reference \"%.*s\" (0x%08x).", 12, p, n),
+ LY_CHECK_ERR_GOTO(lyxml_pututf8(&buf[len], n, &u),
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX,
+ "Invalid character reference \"%.*s\" (0x%08x).", 12, p, n),
error);
len += u;
in += offset;
offset = 0;
}
- } else if (in[offset] == delim) {
+ } else if (in[offset] == endchar) {
/* end of string */
if (buf) {
- if (len + offset >= size) {
- buf = ly_realloc(buf, len + offset + 1);
- LY_CHECK_ERR_RET(!buf, LOGMEM(ctx), LY_EMEM);
- size = len + offset + 1;
- }
+ /* realloc exact size string */
+ buf = ly_realloc(buf, len + offset + 1);
+ LY_CHECK_ERR_RET(!buf, LOGMEM(ctx), LY_EMEM);
+ size = len + offset + 1;
memcpy(&buf[len], in, offset);
+
+ /* set terminating NULL byte */
+ buf[len + offset] = '\0';
}
len += offset;
- /* in case of element content, keep the leading <,
- * for attribute's value move after the terminating quotation mark */
-element_endtag_check:
- if (context->status == LYXML_ELEM_CONTENT) {
- const char *name = NULL, *prefix = NULL;
- size_t name_len = 0, prefix_len = 0;
- int closing = 0;
- /* use fake context to preserve real context (lines, status) since we don't want really parse the element tag here */
- struct lyxml_context fakecontext = {.ctx = context->ctx, .line = context->line, .status = context->status};
-
- in += offset;
-
- /* get know if it is child element (mixed content) or closing element (regular content) */
- /* We don't want actually to parse the closing element, we just need to check mixed content.
- * The closing element tag is preserved to keep the context for the data (returned string),
- * since it can contain data using XML prefixes defined in this element and the caller can
- * want to work with it */
- (*input) = in;
- rc = lyxml_parse_element_start(&fakecontext, &in, &closing);
- if (rc) {
- /* some parsing error */
- goto error;
- } else {
- size_t endtag_len;
- unsigned int c;
- struct lyxml_elem *e;
-
- LY_CHECK_GOTO(lyxml_parse_element_name(&fakecontext, &in, &endtag_len, &c, &prefix, &prefix_len, &name, &name_len), error);
-
- if (!closing) {
- if (empty_content) {
- /* the element here is not closing element, so we have the just indentation formatting before the child */
- context->status = LYXML_ELEMENT;
- return LY_EINVAL;
- } else {
- /* the element here is not closing element, so we have not allowed mixed content */
- struct lyxml_elem *e = (struct lyxml_elem*)context->elements.objs[--context->elements.count];
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LYVE_SYNTAX, "Mixed XML content is not allowed (%.*s).",
- offset + (in - (*input)), &(*input)[-offset]);
- free(e);
- goto error;
- }
- }
-
- /* closing element start - check the name if it matches the opening element tag */
- LY_CHECK_ERR_GOTO(!context->elements.count,
- LOGVAL(ctx, LY_VLOG_LINE, &fakecontext.line, LYVE_SYNTAX, "Opening and closing elements tag missmatch (\"%.*s\").",
- name_len, name),
- error);
- e = (struct lyxml_elem*)context->elements.objs[context->elements.count - 1];
- if (e->prefix_len != prefix_len || e->name_len != name_len
- || (prefix_len && strncmp(prefix, e->prefix, e->prefix_len)) || strncmp(name, e->name, e->name_len)) {
- LOGVAL(ctx, LY_VLOG_LINE, &fakecontext.line, LYVE_SYNTAX,
- "Opening and closing elements tag missmatch (\"%.*s\", expected \"%.*s\").",
- name_len, name, e->name_len, e->name);
- free(e);
- --context->elements.count;
- goto error;
- }
- /* opening and closing element tags matches */
- /* return input back */
- in = (*input);
- }
- } else {
- in += offset + 1;
- }
+ in += offset;
goto success;
} else {
+ if (!is_xmlws(in[offset])) {
+ /* non WS */
+ ws = 0;
+ }
+
/* log lines */
if (in[offset] == '\n') {
- ++context->line;
+ ++xmlctx->line;
}
/* continue */
++offset;
}
}
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_EOF);
+
+ /* EOF reached before endchar */
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+
error:
- if (!(*buffer)) {
- /* buffer not provided, buf is local */
- free(buf);
- } else if (buf) {
- /* buf is shared with caller via buffer, but buf could be reallocated, so update the provided buffer */
- (*buffer) = buf;
- (*buffer_size) = size;
- }
+ free(buf);
return LY_EVALID;
success:
if (buf) {
- if (!(*buffer) && size != len + 1) {
- /* not using provided buffer, so fit the allocated buffer to what we really have inside */
- p = realloc(buf, len + 1);
- /* ignore realloc fail because we are reducing the buffer,
- * so just return bigger buffer than needed */
- if (p) {
- size = len + 1;
- buf = p;
- }
- }
- /* set terminating NULL byte */
- buf[len] = '\0';
+ *value = buf;
+ *dynamic = 1;
+ } else {
+ *value = (char *)start;
+ *dynamic = 0;
}
+ *length = len;
+ *ws_only = ws;
- context->status -= 1;
- if (buf) {
- (*buffer) = buf;
- (*buffer_size) = size;
- (*output) = buf;
- (*dynamic) = 1;
- (*length) = len;
- } else if (output) {
- (*output) = (char*)start;
- (*dynamic) = 0;
- (*length) = len;
- }
-
- if (context->status == LYXML_ATTRIBUTE) {
- /* skip whitespaces after the value */
- ign_xmlws(context, in);
-
- if (in[0] == '>') {
- /* element terminated by > - termination of the opening tag */
- context->status = LYXML_ELEM_CONTENT;
- ++in;
- } else if (in[0] == '/' && in[1] == '>') {
- /* element terminated by /> - termination of an empty element */
- context->status = LYXML_ELEMENT;
- in += 2;
-
- /* remove the closed element record from the tags list */
- free(context->elements.objs[context->elements.count - 1]);
- --context->elements.count;
-
- /* remove also the namespaces conneted with the element */
- lyxml_ns_rm(context);
-
- if (!context->elements.count && in[0] == '\0') {
- /* EOF */
- context->status = LYXML_END;
- }
- } /* else another attribute */
- }
-
- (*input) = in;
- return rc;
+ xmlctx->input = in;
+ return LY_SUCCESS;
#undef BUFSIZE
#undef BUFSIZE_STEP
-#undef BUFSIZE_CHECK
}
-LY_ERR
-lyxml_get_attribute(struct lyxml_context *context, const char **input,
- const char **prefix, size_t *prefix_len, const char **name, size_t *name_len)
+static LY_ERR
+lyxml_close_element(struct lyxml_ctx *xmlctx, const char *prefix, size_t prefix_len, const char *name, size_t name_len,
+ int empty)
{
- struct ly_ctx *ctx = context->ctx; /* shortcut */
- const char *in = (*input);
- const char *id;
- const char *endtag;
- LY_ERR rc;
- unsigned int c;
- size_t endtag_len;
- int is_ns = 0;
- const char *ns_prefix;
- size_t ns_prefix_len;
+ struct lyxml_elem *e;
- /* initialize output variables */
- (*prefix) = (*name) = NULL;
- (*prefix_len) = (*name_len) = 0;
+ /* match opening and closing element tags */
+ if (!xmlctx->elements.count) {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
+ name_len, name);
+ return LY_EVALID;
+ }
- do {
- /* skip initial whitespaces */
- ign_xmlws(context, in);
+ e = (struct lyxml_elem *)xmlctx->elements.objs[xmlctx->elements.count - 1];
+ if ((e->prefix_len != prefix_len) || (e->name_len != name_len)
+ || (prefix_len && strncmp(prefix, e->prefix, e->prefix_len)) || strncmp(name, e->name, e->name_len)) {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX,
+ "Opening (\"%.*s%s%.*s\") and closing (\"%.*s%s%.*s\") elements tag mismatch.",
+ e->prefix_len, e->prefix ? e->prefix : "", e->prefix ? ":" : "", e->name_len, e->name,
+ prefix_len, prefix ? prefix : "", prefix ? ":" : "", name_len, name);
+ return LY_EVALID;
+ }
- if (in[0] == '\0') {
- /* EOF - not expected at this place */
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_EOF);
- return LY_EVALID;
- }
+ /* opening and closing element tags matches, remove record from the opening tags list */
+ ly_set_rm_index(&xmlctx->elements, xmlctx->elements.count - 1, free);
- /* remember the identifier start before checking its format */
- id = in;
- rc = lyxml_check_qname(context, &in, &c, &endtag_len);
- LY_CHECK_RET(rc);
- if (c == ':') {
- /* we have prefixed identifier */
- endtag = in - endtag_len;
+ /* remove also the namespaces connected with the element */
+ lyxml_ns_rm(xmlctx);
- rc = lyxml_check_qname(context, &in, &c, &endtag_len);
- LY_CHECK_RET(rc);
+ /* skip WS */
+ ign_xmlws(xmlctx);
- (*prefix) = id;
- (*prefix_len) = endtag - id;
- id = endtag + 1;
- }
- if (!is_xmlws(c) && c != '=') {
- in = in - endtag_len;
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(in), in, "whitespace or '='");
- return LY_EVALID;
- }
- in = in - endtag_len;
- (*name) = id;
- (*name_len) = in - id;
+ /* special "<elem/>" element */
+ if (empty && (xmlctx->input[0] == '/')) {
+ move_input(xmlctx, 1);
+ }
- /* eat '=' and stop at the value beginning */
- ign_xmlws(context, in);
- if (in[0] != '=') {
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(in), in, "'='");
- return LY_EVALID;
- }
- ++in;
- ign_xmlws(context, in);
- if (in[0] != '\'' && in[0] != '"') {
- LOGVAL(ctx, LY_VLOG_LINE, &context->line, LY_VCODE_INSTREXP,
- LY_VCODE_INSTREXP_len(in), in, "either single or double quotation mark");
- return LY_EVALID;
- }
- context->status = LYXML_ATTR_CONTENT;
+ /* parse closing tag */
+ if (xmlctx->input[0] != '>') {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->input),
+ xmlctx->input, "element tag termination ('>')");
+ return LY_EVALID;
+ }
- is_ns = 0;
- if (*prefix && *prefix_len == 5 && !strncmp(*prefix, "xmlns", 5)) {
- is_ns = 1;
- ns_prefix = *name;
- ns_prefix_len = *name_len;
- } else if (*name_len == 5 && !strncmp(*name, "xmlns", 5)) {
- is_ns = 1;
- ns_prefix = NULL;
- ns_prefix_len = 0;
- }
- if (is_ns) {
- /* instead of attribute, we have namespace specification,
- * so process it automatically and then move to another attribute (if any) */
- char *value = NULL;
- size_t value_len = 0;
- int dynamic = 0;
+ /* move after closing tag without checking for EOF */
+ ++xmlctx->input;
- LY_CHECK_RET(lyxml_get_string(context, &in, &value, &value_len, &value, &value_len, &dynamic));
- if ((rc = lyxml_ns_add(context, ns_prefix, ns_prefix_len, dynamic ? value : strndup(value, value_len)))) {
- if (dynamic) {
- free(value);
- return rc;
- }
- }
-
- /* do not return ns */
- (*prefix) = (*name) = NULL;
- (*prefix_len) = (*name_len) = 0;
- }
- } while (is_ns && (context->status == LYXML_ATTRIBUTE));
-
- /* move caller's input */
- (*input) = in;
return LY_SUCCESS;
}
-void
-lyxml_context_clear(struct lyxml_context *context)
+static LY_ERR
+lyxml_open_element(struct lyxml_ctx *xmlctx, const char *prefix, size_t prefix_len, const char *name, size_t name_len)
{
- unsigned int u;
+ LY_ERR ret = LY_SUCCESS;
+ struct lyxml_elem *e;
+ const char *prev_input;
+ char *value;
+ size_t parsed, value_len;
+ int ws_only, dynamic, is_ns;
+ uint32_t c;
- ly_set_erase(&context->elements, free);
- for (u = context->ns.count - 1; u + 1 > 0; --u) {
- /* remove the ns structure */
- free(((struct lyxml_ns *)context->ns.objs[u])->prefix);
- free(((struct lyxml_ns *)context->ns.objs[u])->uri);
- free(context->ns.objs[u]);
+ /* store element opening tag information */
+ e = malloc(sizeof *e);
+ LY_CHECK_ERR_RET(!e, LOGMEM(xmlctx->ctx), LY_EMEM);
+ e->name = name;
+ e->prefix = prefix;
+ e->name_len = name_len;
+ e->prefix_len = prefix_len;
+ ly_set_add(&xmlctx->elements, e, LY_SET_OPT_USEASLIST);
+
+ /* skip WS */
+ ign_xmlws(xmlctx);
+
+ /* parse and store all namespaces */
+ prev_input = xmlctx->input;
+ is_ns = 1;
+ while ((xmlctx->input[0] != '\0') && !ly_getutf8(&xmlctx->input, &c, &parsed) && is_xmlqnamestartchar(c)) {
+ xmlctx->input -= parsed;
+
+ /* parse attribute name */
+ LY_CHECK_GOTO(ret = lyxml_parse_qname(xmlctx, &prefix, &prefix_len, &name, &name_len), cleanup);
+
+ /* parse the value */
+ LY_CHECK_GOTO(ret = lyxml_next_attr_content(xmlctx, (const char **)&value, &value_len, &ws_only, &dynamic), cleanup);
+
+ /* store every namespace */
+ if ((prefix && !ly_strncmp("xmlns", prefix, prefix_len)) || (!prefix && !ly_strncmp("xmlns", name, name_len))) {
+ LY_CHECK_GOTO(ret = lyxml_ns_add(xmlctx, prefix ? name : NULL, prefix ? name_len : 0,
+ dynamic ? value : strndup(value, value_len)), cleanup);
+ dynamic = 0;
+ } else {
+ /* not a namespace */
+ is_ns = 0;
+ }
+ if (dynamic) {
+ free(value);
+ }
+
+ /* skip WS */
+ ign_xmlws(xmlctx);
+
+ if (is_ns) {
+ /* we can actually skip all the namespaces as there is no reason to parse them again */
+ prev_input = xmlctx->input;
+ }
}
- ly_set_erase(&context->ns, NULL);
- context->status = 0;
+
+cleanup:
+ if (!ret) {
+ xmlctx->input = prev_input;
+ }
+ return ret;
+}
+
+static LY_ERR
+lyxml_next_attr_content(struct lyxml_ctx *xmlctx, const char **value, size_t *value_len, int *ws_only, int *dynamic)
+{
+ char quot;
+
+ /* skip WS */
+ ign_xmlws(xmlctx);
+
+ /* skip '=' */
+ if (xmlctx->input[0] == '\0') {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ return LY_EVALID;
+ } else if (xmlctx->input[0] != '=') {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->input),
+ xmlctx->input, "'='");
+ return LY_EVALID;
+ }
+ move_input(xmlctx, 1);
+
+ /* skip WS */
+ ign_xmlws(xmlctx);
+
+ /* find quotes */
+ if (xmlctx->input[0] == '\0') {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ return LY_EVALID;
+ } else if ((xmlctx->input[0] != '\'') && (xmlctx->input[0] != '\"')) {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->input),
+ xmlctx->input, "either single or double quotation mark");
+ return LY_EVALID;
+ }
+
+ /* remember quote */
+ quot = xmlctx->input[0];
+ move_input(xmlctx, 1);
+
+ /* parse attribute value */
+ LY_CHECK_RET(lyxml_parse_value(xmlctx, quot, (char **)value, value_len, ws_only, dynamic));
+
+ /* move after ending quote (without checking for EOF) */
+ ++xmlctx->input;
+
+ return LY_SUCCESS;
+}
+
+static LY_ERR
+lyxml_next_attribute(struct lyxml_ctx *xmlctx, const char **prefix, size_t *prefix_len, const char **name, size_t *name_len)
+{
+ const char *in;
+ char *value;
+ uint32_t c;
+ size_t parsed, value_len;
+ int ws_only, dynamic;
+
+ /* skip WS */
+ ign_xmlws(xmlctx);
+
+ /* parse only possible attributes */
+ while ((xmlctx->input[0] != '>') && (xmlctx->input[0] != '/')) {
+ in = xmlctx->input;
+ if (in[0] == '\0') {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ return LY_EVALID;
+ } else if ((ly_getutf8(&in, &c, &parsed) || !is_xmlqnamestartchar(c))) {
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(in - parsed), in - parsed,
+ "element tag end ('>' or '/>') or an attribute");
+ return LY_EVALID;
+ }
+
+ /* parse attribute name */
+ LY_CHECK_RET(lyxml_parse_qname(xmlctx, prefix, prefix_len, name, name_len));
+
+ if ((!*prefix || ly_strncmp("xmlns", *prefix, *prefix_len)) && (*prefix || ly_strncmp("xmlns", *name, *name_len))) {
+ /* standard attribute */
+ break;
+ }
+
+ /* namespace, skip it */
+ LY_CHECK_RET(lyxml_next_attr_content(xmlctx, (const char **)&value, &value_len, &ws_only, &dynamic));
+ if (dynamic) {
+ free(value);
+ }
+
+ /* skip WS */
+ ign_xmlws(xmlctx);
+ }
+
+ return LY_SUCCESS;
+}
+
+static LY_ERR
+lyxml_next_element(struct lyxml_ctx *xmlctx, const char **prefix, size_t *prefix_len, const char **name, size_t *name_len,
+ int *closing)
+{
+ /* skip WS until EOF or after opening tag '<' */
+ LY_CHECK_RET(lyxml_skip_until_end_or_after_otag(xmlctx));
+ if (xmlctx->input[0] == '\0') {
+ /* set return values */
+ *prefix = *name = NULL;
+ *prefix_len = *name_len = 0;
+ return LY_SUCCESS;
+ }
+
+ if (xmlctx->input[0] == '/') {
+ move_input(xmlctx, 1);
+ *closing = 1;
+ } else {
+ *closing = 0;
+ }
+
+ /* skip WS */
+ ign_xmlws(xmlctx);
+
+ /* parse element name */
+ LY_CHECK_RET(lyxml_parse_qname(xmlctx, prefix, prefix_len, name, name_len));
+
+ return LY_SUCCESS;
+}
+
+LY_ERR
+lyxml_ctx_new(const struct ly_ctx *ctx, const char *input, struct lyxml_ctx **xmlctx_p)
+{
+ LY_ERR ret = LY_SUCCESS;
+ struct lyxml_ctx *xmlctx;
+ int closing;
+
+ /* new context */
+ xmlctx = calloc(1, sizeof *xmlctx);
+ LY_CHECK_ERR_RET(!xmlctx, LOGMEM(ctx), LY_EMEM);
+ xmlctx->ctx = ctx;
+ xmlctx->line = 1;
+ xmlctx->input = input;
+
+ /* parse next element, if any */
+ LY_CHECK_GOTO(ret = lyxml_next_element(xmlctx, &xmlctx->prefix, &xmlctx->prefix_len, &xmlctx->name,
+ &xmlctx->name_len, &closing), cleanup);
+
+ if (xmlctx->input[0] == '\0') {
+ /* update status */
+ xmlctx->status = LYXML_END;
+ } else if (closing) {
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
+ xmlctx->name_len, xmlctx->name);
+ ret = LY_EVALID;
+ goto cleanup;
+ } else {
+ /* open an element, also parses all enclosed namespaces */
+ LY_CHECK_GOTO(ret = lyxml_open_element(xmlctx, xmlctx->prefix, xmlctx->prefix_len, xmlctx->name, xmlctx->name_len), cleanup);
+
+ /* update status */
+ xmlctx->status = LYXML_ELEMENT;
+ }
+
+cleanup:
+ if (ret) {
+ lyxml_ctx_free(xmlctx);
+ } else {
+ *xmlctx_p = xmlctx;
+ }
+ return ret;
+}
+
+LY_ERR
+lyxml_ctx_next(struct lyxml_ctx *xmlctx)
+{
+ LY_ERR ret = LY_SUCCESS;
+ int closing;
+ struct lyxml_elem *e;
+
+ /* if the value was not used, free it */
+ if (((xmlctx->status == LYXML_ELEM_CONTENT) || (xmlctx->status == LYXML_ATTR_CONTENT)) && xmlctx->dynamic) {
+ free((char *)xmlctx->value);
+ xmlctx->value = NULL;
+ xmlctx->dynamic = 0;
+ }
+
+ switch (xmlctx->status) {
+ /* content |</elem> */
+ case LYXML_ELEM_CONTENT:
+ /* handle special case when empty content for "<elem/>" was returned */
+ if (xmlctx->input[0] == '/') {
+ assert(xmlctx->elements.count);
+ e = (struct lyxml_elem *)xmlctx->elements.objs[xmlctx->elements.count - 1];
+
+ /* close the element (parses closing tag) */
+ LY_CHECK_GOTO(ret = lyxml_close_element(xmlctx, e->prefix, e->prefix_len, e->name, e->name_len, 1), cleanup);
+
+ /* update status */
+ xmlctx->status = LYXML_ELEM_CLOSE;
+ break;
+ }
+ /* fallthrough */
+
+ /* </elem>| <elem2>* */
+ case LYXML_ELEM_CLOSE:
+ /* parse next element, if any */
+ LY_CHECK_GOTO(ret = lyxml_next_element(xmlctx, &xmlctx->prefix, &xmlctx->prefix_len, &xmlctx->name,
+ &xmlctx->name_len, &closing), cleanup);
+
+ if (xmlctx->input[0] == '\0') {
+ /* update status */
+ xmlctx->status = LYXML_END;
+ } else if (closing) {
+ /* close an element (parses also closing tag) */
+ LY_CHECK_GOTO(ret = lyxml_close_element(xmlctx, xmlctx->prefix, xmlctx->prefix_len, xmlctx->name, xmlctx->name_len, 0), cleanup);
+
+ /* update status */
+ xmlctx->status = LYXML_ELEM_CLOSE;
+ } else {
+ /* open an element, also parses all enclosed namespaces */
+ LY_CHECK_GOTO(ret = lyxml_open_element(xmlctx, xmlctx->prefix, xmlctx->prefix_len, xmlctx->name, xmlctx->name_len), cleanup);
+
+ /* update status */
+ xmlctx->status = LYXML_ELEMENT;
+ }
+ break;
+
+ /* <elem| attr='val'* > content */
+ case LYXML_ELEMENT:
+
+ /* attr='val'| attr='val'* > content */
+ case LYXML_ATTR_CONTENT:
+ /* parse attribute name, if any */
+ LY_CHECK_GOTO(ret = lyxml_next_attribute(xmlctx, &xmlctx->prefix, &xmlctx->prefix_len, &xmlctx->name, &xmlctx->name_len), cleanup);
+
+ if (xmlctx->input[0] == '>') {
+ /* no attributes but a closing tag */
+ move_input(xmlctx, 1);
+
+ /* parse element content */
+ LY_CHECK_GOTO(ret = lyxml_parse_value(xmlctx, '<', (char **)&xmlctx->value, &xmlctx->value_len, &xmlctx->ws_only,
+ &xmlctx->dynamic), cleanup);
+
+ if (!xmlctx->value_len) {
+ /* use empty value, easier to work with */
+ xmlctx->value = "";
+ assert(!xmlctx->dynamic);
+ }
+
+ /* update status */
+ xmlctx->status = LYXML_ELEM_CONTENT;
+ } else if (xmlctx->input[0] == '/') {
+ /* no content but we still return it */
+ xmlctx->value = "";
+ xmlctx->value_len = 0;
+ xmlctx->ws_only = 1;
+ xmlctx->dynamic = 0;
+
+ /* update status */
+ xmlctx->status = LYXML_ELEM_CONTENT;
+ } else {
+ /* update status */
+ xmlctx->status = LYXML_ATTRIBUTE;
+ }
+ break;
+
+ /* attr|='val' */
+ case LYXML_ATTRIBUTE:
+ /* skip formatting and parse value */
+ LY_CHECK_GOTO(ret = lyxml_next_attr_content(xmlctx, &xmlctx->value, &xmlctx->value_len, &xmlctx->ws_only,
+ &xmlctx->dynamic), cleanup);
+
+ /* update status */
+ xmlctx->status = LYXML_ATTR_CONTENT;
+ break;
+
+ /* </elem> |EOF */
+ case LYXML_END:
+ /* nothing to do */
+ break;
+ }
+
+cleanup:
+ if (ret) {
+ /* invalidate context */
+ xmlctx->status = LYXML_END;
+ }
+ return ret;
+}
+
+LY_ERR
+lyxml_ctx_peek(struct lyxml_ctx *xmlctx, enum LYXML_PARSER_STATUS *next)
+{
+ LY_ERR ret = LY_SUCCESS;
+ const char *prefix, *name, *prev_input;
+ size_t prefix_len, name_len;
+ int closing;
+
+ prev_input = xmlctx->input;
+
+ switch (xmlctx->status) {
+ case LYXML_ELEM_CONTENT:
+ if (xmlctx->input[0] == '/') {
+ *next = LYXML_ELEM_CLOSE;
+ break;
+ }
+ /* fallthrough */
+ case LYXML_ELEM_CLOSE:
+ /* parse next element, if any */
+ LY_CHECK_GOTO(ret = lyxml_next_element(xmlctx, &prefix, &prefix_len, &name, &name_len, &closing), cleanup);
+
+ if (xmlctx->input[0] == '\0') {
+ *next = LYXML_END;
+ } else if (closing) {
+ *next = LYXML_ELEM_CLOSE;
+ } else {
+ *next = LYXML_ELEMENT;
+ }
+ break;
+ case LYXML_ELEMENT:
+ case LYXML_ATTR_CONTENT:
+ /* parse attribute name, if any */
+ LY_CHECK_GOTO(ret = lyxml_next_attribute(xmlctx, &prefix, &prefix_len, &name, &name_len), cleanup);
+
+ if ((xmlctx->input[0] == '>') || (xmlctx->input[0] == '/')) {
+ *next = LYXML_ELEM_CONTENT;
+ } else {
+ *next = LYXML_ATTRIBUTE;
+ }
+ break;
+ case LYXML_ATTRIBUTE:
+ *next = LYXML_ATTR_CONTENT;
+ break;
+ case LYXML_END:
+ *next = LYXML_END;
+ break;
+ }
+
+cleanup:
+ xmlctx->input = prev_input;
+ return ret;
+}
+
+void
+lyxml_ctx_free(struct lyxml_ctx *xmlctx)
+{
+ uint32_t u;
+
+ if (!xmlctx) {
+ return;
+ }
+
+ if (((xmlctx->status == LYXML_ELEM_CONTENT) || (xmlctx->status == LYXML_ATTR_CONTENT)) && xmlctx->dynamic) {
+ free((char *)xmlctx->value);
+ }
+ ly_set_erase(&xmlctx->elements, free);
+ for (u = xmlctx->ns.count - 1; u + 1 > 0; --u) {
+ /* remove the ns structure */
+ free(((struct lyxml_ns *)xmlctx->ns.objs[u])->prefix);
+ free(((struct lyxml_ns *)xmlctx->ns.objs[u])->uri);
+ free(xmlctx->ns.objs[u]);
+ }
+ ly_set_erase(&xmlctx->ns, NULL);
+ free(xmlctx);
}
LY_ERR
@@ -1044,7 +1061,7 @@
}
LY_ERR
-lyxml_get_prefixes(struct lyxml_context *ctx, const char *value, size_t value_len, struct ly_prefix **val_prefs)
+lyxml_get_prefixes(struct lyxml_ctx *xmlctx, const char *value, size_t value_len, struct ly_prefix **val_prefs)
{
LY_ERR ret;
uint32_t u, c;
@@ -1064,7 +1081,7 @@
if (*stop == ':') {
/* we have a possible prefix */
len = stop - start;
- ns = lyxml_ns_get(ctx, start, len);
+ ns = lyxml_ns_get(xmlctx, start, len);
if (ns) {
struct ly_prefix *p = NULL;
@@ -1076,9 +1093,9 @@
}
}
if (!p) {
- LY_ARRAY_NEW_GOTO(ctx->ctx, prefixes, p, ret, error);
- p->pref = lydict_insert(ctx->ctx, start, len);
- p->ns = lydict_insert(ctx->ctx, ns->uri, 0);
+ LY_ARRAY_NEW_GOTO(xmlctx->ctx, prefixes, p, ret, error);
+ p->pref = lydict_insert(xmlctx->ctx, start, len);
+ p->ns = lydict_insert(xmlctx->ctx, ns->uri, 0);
} /* else the prefix already present */
}
}
@@ -1091,7 +1108,7 @@
error:
LY_ARRAY_FOR(prefixes, u) {
- lydict_remove(ctx->ctx, prefixes[u].pref);
+ lydict_remove(xmlctx->ctx, prefixes[u].pref);
}
LY_ARRAY_FREE(prefixes);
return ret;
diff --git a/src/xml.h b/src/xml.h
index 8e30478..2bbf5da 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -52,7 +52,7 @@
struct lyxml_ns {
char *prefix; /* prefix of the namespace, NULL for the default namespace */
char *uri; /* namespace URI */
- unsigned int depth; /* depth level of the element to maintain the list of accessible namespace definitions */
+ uint32_t depth; /* depth level of the element to maintain the list of accessible namespace definitions */
};
/* element tag identifier for matching opening and closing tags */
@@ -67,125 +67,58 @@
* @brief Status of the parser providing information what is expected next (which function is supposed to be called).
*/
enum LYXML_PARSER_STATUS {
- LYXML_ELEMENT = 0, /* expecting XML element, call lyxml_get_element() */
- LYXML_ELEM_CONTENT, /* expecting content of an element, call lyxml_get_string */
- LYXML_ATTRIBUTE, /* expecting XML attribute, call lyxml_get_attribute() */
- LYXML_ATTR_CONTENT, /* expecting value of an attribute, call lyxml_get_string */
+ LYXML_ELEMENT, /* opening XML element parsed */
+ LYXML_ELEM_CLOSE, /* closing XML element parsed */
+ LYXML_ELEM_CONTENT, /* XML element context parsed */
+ LYXML_ATTRIBUTE, /* XML attribute parsed */
+ LYXML_ATTR_CONTENT, /* XML attribute content parsed */
LYXML_END /* end of input data */
};
-struct lyxml_context {
- struct ly_ctx *ctx;
+struct lyxml_ctx {
+ enum LYXML_PARSER_STATUS status; /* status providing information about the last parsed object, following attributes
+ are filled based on it */
+ union {
+ const char *prefix; /* LYXML_ELEMENT, LYXML_ATTRIBUTE */
+ const char *value; /* LYXML_ELEM_CONTENT, LYXML_ATTR_CONTENT */
+ };
+ union {
+ size_t prefix_len; /* LYXML_ELEMENT, LYXML_ATTRIBUTE */
+ size_t value_len; /* LYXML_ELEM_CONTENT, LYXML_ATTR_CONTENT */
+ };
+ union {
+ const char *name; /* LYXML_ELEMENT, LYXML_ATTRIBUTE */
+ int ws_only; /* LYXML_ELEM_CONTENT, LYXML_ATTR_CONTENT */
+ };
+ union {
+ size_t name_len; /* LYXML_ELEMENT, LYXML_ATTRIBUTE */
+ int dynamic; /* LYXML_ELEM_CONTENT, LYXML_ATTR_CONTENT */
+ };
+
+ const struct ly_ctx *ctx;
uint64_t line;
- enum LYXML_PARSER_STATUS status; /* status providing information about the next expected object in input data */
+ const char *input;
struct ly_set elements; /* list of not-yet-closed elements */
- struct ly_set ns; /* handled with LY_SET_OPT_USEASLIST */
+ struct ly_set ns; /* handled with LY_SET_OPT_USEASLIST */
};
-/**
- * @brief Parse input expecting an XML element.
- *
- * Able to silently skip comments, PIs and CData. DOCTYPE is not parseable, so it is reported as LY_EVALID error.
- * If '<' is not found in input, LY_EINVAL is returned (but no error is logged), so it is possible to continue
- * with parsing input as text content.
- *
- * Input string is not being modified, so the returned values are not NULL-terminated, instead their length
- * is returned.
- *
- * @param[in] context XML context to track lines or store errors into libyang context.
- * @param[in,out] input Input string to process, updated according to the processed/read data.
- * @param[in] options Currently unused options to modify input processing.
- * @param[out] prefix_p Pointer to prefix if present in the element name, NULL otherwise.
- * @param[out] prefix_len_p Length of the prefix if any.
- * @param[out] name_p Element name. When LY_SUCCESS is returned but name is NULL, check context's status field:
- * - LYXML_END - end of input was reached
- * - LYXML_ELEMENT - closing element found, expecting now a sibling element so call lyxml_get_element() again
- * @param[out] name_len_p Length of the element name.
- * @return LY_ERR values.
- */
-LY_ERR lyxml_get_element(struct lyxml_context *context, const char **input, const char **prefix_p, size_t *prefix_len_p,
- const char **name_p, size_t *name_len_p);
+LY_ERR lyxml_ctx_new(const struct ly_ctx *ctx, const char *input, struct lyxml_ctx **xmlctx);
-/**
- * @brief Skip an element after its opening tag was parsed.
- *
- * @param[in] context XML context.
- * @param[in,out] input Input string to process, updated according to the read data.
- * @return LY_ERR values.
- */
-LY_ERR lyxml_skip_element(struct lyxml_context *context, const char **input);
+LY_ERR lyxml_ctx_next(struct lyxml_ctx *xmlctx);
-/**
- * @brief Parse input expecting an XML attribute (including XML namespace).
- *
- * Input string is not being modified, so the returned values are not NULL-terminated, instead their length
- * is returned.
- *
- * Namespace definitions are processed automatically and stored internally. To get namespace for a specific
- * prefix, use lyxml_get_ns(). This also means, that in case there are only the namespace definitions,
- * lyxml_get_attribute() can succeed, but nothing (name, prefix) is returned.
- *
- * The status member of the context is updated to provide information what the caller is supposed to call
- * after this function.
- *
- * @param[in] context XML context to track lines or store errors into libyang context.
- * @param[in,out] input Input string to process, updated according to the processed/read data so,
- * when succeeded, it points to the opening quote of the attribute's value.
- * @param[out] prefix Pointer to prefix if present in the attribute name, NULL otherwise.
- * @param[out] prefix_len Length of the prefix if any.
- * @param[out] name Attribute name. Can be NULL only in case there is actually no attribute, but namespaces.
- * @param[out] name_len Length of the element name.
- * @return LY_ERR values.
- */
-LY_ERR lyxml_get_attribute(struct lyxml_context *context, const char **input,
- const char **prefix, size_t *prefix_len, const char **name, size_t *name_len);
-
-/**
- * @brief Parse input as XML text (attribute's values and element's content).
- *
- * Mixed content of XML elements is not allowed. Formating whitespaces before child element are ignored,
- * LY_EINVAL is returned in such a case (output is not set, no error is printed) and input is moved
- * to the beginning of a child definition.
- *
- * In the case of attribute's values, the input string is expected to start on a quotation mark to
- * select which delimiter (single or double quote) is used. Otherwise, the element content is being
- * parsed expected to be terminated by '<' character.
- *
- * If function succeeds, the string in a dynamically allocated output buffer is always NULL-terminated.
- *
- * The dynamically allocated buffer is used only when necessary because of a character or the supported entity
- * reference which modify the input data. These constructs are replaced by their real value, so in case the output
- * string will be again printed as an XML data, it may be necessary to correctly encode such characters.
- *
- * Optionally, the buffer, buffer_size, output, length and dynamic arguments (altogether) can be NULL.
- * In such a case, the XML text in @p input is just checked, the @p input pointer is moved after the XML text, but nothing is stored.
- *
- * @param[in] context XML context to track lines or store errors into libyang context.
- * @param[in,out] input Input string to process, updated according to the processed/read data.
- * @param[in, out] buffer Storage for the output string. If the parameter points to NULL, the buffer is allocated if needed.
- * Otherwise, when needed, the buffer is used and enlarged when necessary. Whenever the buffer is used, the string is NULL-terminated.
- * @param[in, out] buffer_size Allocated size of the returned buffer. If a buffer is provided by a caller, it
- * is not being reduced even if the string is shorter. On the other hand, it can be enlarged if needed.
- * @param[out] output Returns pointer to the resulting string - to the provided/allocated buffer if it was necessary to modify
- * the input string or directly into the input string (see the \p dynamic parameter).
- * @param[out] length Length of the \p output string.
- * @param[out] dynamic Flag if a dynamically allocated memory (\p buffer) was used and caller is supposed to free it at the end.
- * In case the value is zero, the \p output points directly into the \p input string.
- * @return LY_ERR value.
- */
-LY_ERR lyxml_get_string(struct lyxml_context *context, const char **input, char **buffer, size_t *buffer_size, char **output, size_t *length, int *dynamic);
+LY_ERR lyxml_ctx_peek(struct lyxml_ctx *xmlctx, enum LYXML_PARSER_STATUS *next);
/**
* @brief Get a namespace record for the given prefix in the current context.
*
- * @param[in] context XML context to work with.
+ * @param[in] xmlctx XML context to work with.
* @param[in] prefix Pointer to the namespace prefix as taken from lyxml_get_attribute() or lyxml_get_element().
* Can be NULL for default namespace.
* @param[in] prefix_len Length of the prefix string (since it is not NULL-terminated when returned from lyxml_get_attribute() or
* lyxml_get_element()).
* @return The namespace record or NULL if the record for the specified prefix not found.
*/
-const struct lyxml_ns *lyxml_ns_get(struct lyxml_context *context, const char *prefix, size_t prefix_len);
+const struct lyxml_ns *lyxml_ns_get(struct lyxml_ctx *xmlctx, const char *prefix, size_t prefix_len);
/**
* @brief Print the given @p text as XML string which replaces some of the characters which cannot appear in XML data.
@@ -200,20 +133,20 @@
/**
* @brief Remove the allocated working memory of the context.
*
- * @param[in] context XML context to clear.
+ * @param[in] xmlctx XML context to clear.
*/
-void lyxml_context_clear(struct lyxml_context *context);
+void lyxml_ctx_free(struct lyxml_ctx *xmlctx);
/**
* @brief Find all possible prefixes in a value.
*
- * @param[in] ctx XML context to use.
+ * @param[in] xmlctx XML context to use.
* @param[in] value Value to check.
* @param[in] value_len Value length.
* @param[out] val_prefs Array of found prefixes.
* @return LY_ERR value.
*/
-LY_ERR lyxml_get_prefixes(struct lyxml_context *ctx, const char *value, size_t value_len, struct ly_prefix **val_prefs);
+LY_ERR lyxml_get_prefixes(struct lyxml_ctx *xmlctx, const char *value, size_t value_len, struct ly_prefix **val_prefs);
/**
* @brief Compare values and their prefix mappings.