Duplicated extensions in rpc input/output
The extensions appear twice in the compiled schema node for rpc input and output. The following code can be used to reproduce the issue:
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <libyang/libyang.h>
const char *yang = "module my-mod {\n"
" yang-version 1.1;\n"
" namespace \"http://example.com/my-mod\";\n"
" prefix my-mod;\n"
"\n"
" extension my-ext {\n"
" argument arg;\n"
" description \"my desc\";\n"
" }\n"
"\n"
" extension my-ext2 {\n"
" description \"my desc\";\n"
" }\n"
"\n"
" rpc my-rpc {\n"
" my-mod:my-ext arg-rpc;\n"
" input {\n"
" my-mod:my-ext arg-input;\n"
" my-mod:my-ext2;\n"
" leaf in-value {\n"
" my-mod:my-ext arg-in-value;\n"
" type uint32;\n"
" }\n"
" }\n"
" output {\n"
" my-mod:my-ext arg-output;\n"
" leaf out-value {\n"
" my-mod:my-ext arg-out-value;\n"
" type uint32;\n"
" }\n"
" }\n"
" }\n"
"}\n";
static void
print_extensions(const struct lysc_node *snode)
{
const struct lysc_ext_instance *ext_table = snode->exts;
const struct lysc_node *iter;
size_t i;
printf("%s: %ld extensions\n", snode->name, LY_ARRAY_COUNT(ext_table));
for (i = 0; i < LY_ARRAY_COUNT(ext_table); i++) {
const struct lysc_ext_instance *ext = ext_table + i;
printf(" %s %s\n", ext->def->name, ext->argument);
}
LY_LIST_FOR(lysc_node_child(snode), iter) {
print_extensions(iter);
}
}
int main(int argc, char **argv)
{
const struct lysc_node *snode = NULL;
struct lys_module *mod = NULL;
struct ly_ctx *ctx = NULL;
int exit_code = 1;
int ret;
(void)argc;
(void)argv;
ret = ly_ctx_new(NULL, 0, &ctx);
if (ret != LY_SUCCESS) {
fprintf(stderr, "ly_ctx_new() failed: %s\n", ly_strerrcode(ret));
goto fail;
}
ret = lys_parse_mem(ctx, yang, LYS_IN_YANG, &mod);
if (ret != LY_SUCCESS) {
fprintf(stderr, "lys_parse_mem() failed: %s\n", ly_strerrcode(ret));
goto fail;
}
while ((snode = lys_getnext(snode, NULL, mod->compiled, 0)) != NULL) {
print_extensions(snode);
}
exit_code = 0;
fail:
ly_ctx_destroy(ctx);
return exit_code;
}
The output of this program compiled with latest libyang (3.1.3) is:
my-rpc: 1 extensions
my-ext arg-rpc
input: 4 extensions
my-ext arg-input
my-ext2 (null)
my-ext arg-input
my-ext2 (null)
in-value: 1 extensions
my-ext arg-in-value
output: 2 extensions
my-ext arg-output
my-ext arg-output
out-value: 1 extensions
my-ext arg-out-value
The extensions of input and output are duplicated.
Note that initially I started to write this example code to reproduce another issue of my application where an extension does not appear at all on an rpc input schema node (node->exts is NULL). I don't know if these 2 issues are related or not.
After some analysis, it appears that the extensions are compiled once in lys_compile_node_action_inout(), then another time in lys_compile_node_(), which adds the same extensions again.
I don't know if it's the proper fix, but removing COMPILE_EXTS_GOTO() from lys_compile_node_action_inout() seems to solve the issue. I'll submit a pull request for this.
About the second issue (node->exts is NULL), it's not related so I'm opening a new issue.