ext instance REFACTOR generic ext instance parsing
Stored in a format-independent format without
the need to update its name after compilation.
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 48ea1ea..411dc3a 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -11,6 +11,8 @@
*
* https://opensource.org/licenses/BSD-3-Clause
*/
+#define _GNU_SOURCE
+
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -22,6 +24,7 @@
#include <string.h>
#include "common.h"
+#include "compat.h"
#include "context.h"
#include "dict.h"
#include "in.h"
@@ -32,6 +35,7 @@
#include "path.h"
#include "set.h"
#include "tree.h"
+#include "tree_data_internal.h"
#include "tree_schema.h"
#include "tree_schema_internal.h"
#include "xml.h"
@@ -2933,50 +2937,6 @@
}
/**
- * @brief Get element name prefixed by full URI of xml namespace.
- *
- * @param[in] ctx YIN parser context used for logging and to get inormation about xml namespaces.
- * @param[in] name Name of element.
- * @param[in] name_len Length of element name.
- * @param[in] prefix Prefix of element.
- * @param[in] prefix_len Length of element prefix.
- *
- * @return Element name prefixed by URI on success, NULL on failure.
- */
-static const char *
-name2nsname(struct lys_yin_parser_ctx *ctx, const char *name, size_t name_len, const char *prefix, size_t prefix_len)
-{
- const char *ename = NULL;
- const struct lyxml_ns *ns = lyxml_ns_get(&ctx->xmlctx->ns, 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 */
- lydict_insert(ctx->xmlctx->ctx, name, name_len, &ename);
- return ename;
- }
- /* some statement in special namespace (extension instance) */
- size_t ns_len = strlen(ns->uri);
- size_t len = ns_len + name_len + 1; /* +1 because of ':' delimiter between ns and actual name */
-
- char *result;
- char *temp;
-
- temp = result = malloc(sizeof(*temp) * (len + 1)); /* +1 for '\0' terminator */
- LY_CHECK_ERR_RET(!temp, LOGMEM(ctx->xmlctx->ctx), NULL);
-
- strcpy(result, ns->uri);
- result[ns_len] = ':';
- temp = &result[ns_len + 1];
- strncpy(temp, name, name_len);
- result[len] = '\0';
-
- lydict_insert_zc(ctx->xmlctx->ctx, result, &ename);
- return ename;
-}
-
-/**
* @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.
@@ -3144,14 +3104,30 @@
{
LY_ERR ret = LY_SUCCESS;
struct lysp_stmt *last = NULL, *new = NULL;
+ char *id;
assert(ctx->xmlctx->status == LYXML_ELEMENT);
/* allocate new structure for element */
*element = calloc(1, sizeof(**element));
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);
+
+ /* store identifier */
+ if (ctx->xmlctx->prefix_len) {
+ if (asprintf(&id, "%.*s:%.*s", (int)ctx->xmlctx->prefix_len, ctx->xmlctx->prefix, (int)ctx->xmlctx->name_len,
+ ctx->xmlctx->name) == -1) {
+ LOGMEM(ctx->xmlctx->ctx);
+ ret = LY_EMEM;
+ goto cleanup;
+ }
+ LY_CHECK_GOTO(ret = lydict_insert_zc(ctx->xmlctx->ctx, id, &(*element)->stmt), cleanup);
+
+ /* store prefix data for the statement */
+ LY_CHECK_GOTO(ret = ly_store_prefix_data(ctx->xmlctx->ctx, (*element)->stmt, strlen((*element)->stmt), LY_PREF_XML,
+ &ctx->xmlctx->ns, &(*element)->format, &(*element)->prefix_data), cleanup);
+ } else {
+ LY_CHECK_GOTO(ret = lydict_insert(ctx->xmlctx->ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, &(*element)->stmt), cleanup);
+ }
(*element)->kw = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
ctx->xmlctx->prefix_len, parent);
@@ -3220,6 +3196,10 @@
if (ctx->xmlctx->value_len) {
INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, (*element)->arg);
LY_CHECK_ERR_GOTO(!(*element)->arg, ret = LY_EMEM, cleanup);
+
+ /* store prefix data for the argument as well */
+ LY_CHECK_GOTO(ret = ly_store_prefix_data(ctx->xmlctx->ctx, (*element)->arg, strlen((*element)->arg), LY_PREF_XML,
+ &ctx->xmlctx->ns, &(*element)->format, &(*element)->prefix_data), cleanup);
}
/* read closing tag */
@@ -3246,19 +3226,34 @@
{
struct lysp_ext_instance *e;
struct lysp_stmt *last_subelem = NULL, *new_subelem = NULL;
+ char *ext_name;
assert(ctx->xmlctx->status == LYXML_ELEMENT);
assert(exts);
LY_ARRAY_NEW_RET(ctx->xmlctx->ctx, *exts, e, LY_EMEM);
- e->yin = 0;
- /* store name and insubstmt info */
- 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);
+ if (!ctx->xmlctx->prefix_len) {
+ LOGVAL_PARSER(ctx, LYVE_SYNTAX, "Extension instance \"%*.s\" without the mandatory prefix.",
+ (int)ctx->xmlctx->name_len, ctx->xmlctx->name);
+ return LY_EVALID;
+ }
+
+ /* store prefixed name */
+ if (asprintf(&ext_name, "%.*s:%.*s", (int)ctx->xmlctx->prefix_len, ctx->xmlctx->prefix, (int)ctx->xmlctx->name_len,
+ ctx->xmlctx->name) == -1) {
+ LOGMEM(ctx->xmlctx->ctx);
+ return LY_EMEM;
+ }
+ LY_CHECK_RET(lydict_insert_zc(ctx->xmlctx->ctx, ext_name, &e->name));
+
+ /* store prefix data for the name */
+ LY_CHECK_RET(ly_store_prefix_data(ctx->xmlctx->ctx, e->name, strlen(e->name), LY_PREF_XML, &ctx->xmlctx->ns,
+ &e->format, &e->prefix_data));
+
e->insubstmt = subelem;
e->insubstmt_index = subelem_index;
- e->yin |= LYS_YIN;
+
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
/* store attributes as subelements */
@@ -3277,7 +3272,8 @@
LY_CHECK_RET(!last_subelem->stmt, LY_EMEM);
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
- INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, last_subelem->arg);
+ INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic,
+ last_subelem->arg);
LY_CHECK_RET(!last_subelem->arg, LY_EMEM);
} else {
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
@@ -3307,6 +3303,10 @@
INSERT_STRING_RET(ctx->xmlctx->ctx, ctx->xmlctx->value, ctx->xmlctx->value_len, ctx->xmlctx->dynamic, e->argument);
LY_CHECK_RET(!e->argument, LY_EMEM);
+ /* store prefix data for the argument as well */
+ LY_CHECK_RET(ly_store_prefix_data(ctx->xmlctx->ctx, e->argument, strlen(e->argument), LY_PREF_XML,
+ &ctx->xmlctx->ns, &e->format, &e->prefix_data));
+
/* parser next */
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
}