Skip to content

Commit 35274cf

Browse files
committed
parser yang UPDATE automatic parsing of nested extensions
Fixes #2265
1 parent 1849d4e commit 35274cf

File tree

5 files changed

+31
-6
lines changed

5 files changed

+31
-6
lines changed

src/parser_yang.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -982,8 +982,16 @@ parse_ext(struct lysp_yang_ctx *ctx, const char *ext_name, size_t ext_name_len,
982982
e->parent_stmt_index = parent_stmt_index;
983983

984984
YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
985-
LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, kw, word, word_len, &e->child), cleanup)
986-
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
985+
switch (kw) {
986+
case LY_STMT_EXTENSION_INSTANCE:
987+
LY_CHECK_GOTO(parse_ext(ctx, word, word_len, e, LY_STMT_EXTENSION_INSTANCE, 0, &e->exts), cleanup);
988+
break;
989+
default:
990+
/* just store all the statements */
991+
LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, kw, word, word_len, &e->child), cleanup)
992+
break;
993+
}
994+
YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, e->exts, ret, cleanup);
987995
}
988996

989997
cleanup:

src/parser_yin.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @author Michal Vasko <mvasko@cesnet.cz>
55
* @brief YIN parser.
66
*
7-
* Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
7+
* Copyright (c) 2015 - 2024 CESNET, z.s.p.o.
88
*
99
* This source code is licensed under BSD 3-Clause License (the "License").
1010
* You may not use this file except in compliance with the License.
@@ -3409,6 +3409,14 @@ yin_parse_extension_instance(struct lysp_yin_ctx *ctx, const void *parent, enum
34093409
if (ctx->xmlctx->ws_only) {
34103410
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
34113411
while (ctx->xmlctx->status == LYXML_ELEMENT) {
3412+
/* BUG nested extensions will not be parsed because we are not able to dinsguish between them
3413+
* and the argument of this extension, in case there is one and its 'yin-element' is 'true'
3414+
stmt = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
3415+
ctx->xmlctx->prefix_len, LY_STMT_EXTENSION_INSTANCE);
3416+
if (stmt == LY_STMT_EXTENSION_INSTANCE) {
3417+
LY_CHECK_RET(yin_parse_extension_instance(ctx, e, LY_STMT_EXTENSION_INSTANCE, 0, &e->exts));
3418+
} else { */
3419+
34123420
LY_CHECK_RET(yin_parse_element_generic(ctx, LY_STMT_EXTENSION_INSTANCE, &new_subelem));
34133421
if (!e->child) {
34143422
e->child = new_subelem;
@@ -3420,6 +3428,9 @@ yin_parse_extension_instance(struct lysp_yin_ctx *ctx, const void *parent, enum
34203428
assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
34213429
LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
34223430
}
3431+
3432+
/* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
3433+
LY_CHECK_RET(yin_unres_exts_add(ctx, e->exts));
34233434
} else if (ctx->xmlctx->value_len) {
34243435
/* invalid text content */
34253436
LOGVAL_PARSER(ctx, LYVE_SYNTAX, "Extension instance \"%s\" with unexpected text content \"%.*s\".", ext_name,

src/plugins_exts.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ extern "C" {
109109
/**
110110
* @brief Extensions API version
111111
*/
112-
#define LYPLG_EXT_API_VERSION 6
112+
#define LYPLG_EXT_API_VERSION 7
113113

114114
/**
115115
* @brief Mask for an operation statement.
@@ -419,6 +419,7 @@ struct lysp_ext_instance {
419419
parsed data ([sized array](@ref sizedarrays)) */
420420
void *parsed; /**< private plugin parsed data */
421421
struct lysp_stmt *child; /**< list of generic (unknown) YANG statements */
422+
struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
422423
};
423424

424425
/**

src/schema_compile.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @author Michal Vasko <mvasko@cesnet.cz>
55
* @brief Schema compilation.
66
*
7-
* Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
7+
* Copyright (c) 2015 - 2024 CESNET, z.s.p.o.
88
*
99
* This source code is licensed under BSD 3-Clause License (the "License").
1010
* You may not use this file except in compliance with the License.
@@ -172,7 +172,10 @@ lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *extp, struct lys
172172
/* compile extension if not already */
173173
LY_CHECK_GOTO(ret = lys_compile_extension(ctx, extp, &ext->def), cleanup);
174174

175-
/* compile */
175+
/* compile nested extensions */
176+
COMPILE_EXTS_GOTO(ctx, extp->exts, ext->exts, ext, ret, cleanup);
177+
178+
/* compile this extension */
176179
if (ext->def->plugin && ext->def->plugin->compile) {
177180
if (ext->argument) {
178181
lysc_update_path(ctx, ext->module, ext->argument);

src/tree_schema_free.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ lysp_ext_instance_free(struct lysf_ctx *ctx, struct lysp_ext_instance *ext)
8080
LY_LIST_FOR_SAFE(ext->child, next, stmt) {
8181
lysp_stmt_free(ctx->ctx, stmt);
8282
}
83+
84+
FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
8385
}
8486

8587
/**

0 commit comments

Comments
 (0)