extension plugins FEATURE allow extension instance to be skipped.
Allow extension plugin to decide if the specific extension instance is supposed to be skipped/ignored.
diff --git a/src/extensions/libyang_ext_test.c b/src/extensions/libyang_ext_test.c
index 8a06115..2e3929c 100644
--- a/src/extensions/libyang_ext_test.c
+++ b/src/extensions/libyang_ext_test.c
@@ -45,6 +45,13 @@
return 0;
}
+int libyang_ext_skipped_position(const void * UNUSED(parent), LYEXT_PAR UNUSED(parent_type),
+ LYEXT_SUBSTMT UNUSED(substmt_type))
+{
+ /* skip extension instance */
+ return 2;
+}
+
struct lyext_substmt libyang_ext_test_substmt[] = {
{LY_STMT_ARGUMENT, 0, LY_STMT_CARD_OPT}, /* const char* + uint8_t */
{LY_STMT_BASE, 1 * sizeof(const char*) + 1 * sizeof(uint8_t), LY_STMT_CARD_OPT}, /* const char* */
@@ -225,6 +232,15 @@
.instance_size = (sizeof(struct lys_ext_instance_complex) - 1) + 5 * sizeof(void*) + sizeof(uint8_t) + sizeof(uint16_t)
};
+struct lyext_plugin libyang_ext_test_skipped = {
+ .type = LYEXT_FLAG,
+ .flags = 0,
+ .check_position = &libyang_ext_skipped_position,
+ .check_result = NULL,
+ .check_inherit = NULL,
+ .valid_data = NULL
+};
+
/**
* @brief list of all extension plugins implemented here
*
@@ -234,5 +250,6 @@
{"ext-def", "2017-01-18", "complex", (struct lyext_plugin*)&libyang_ext_test_p},
{"ext-def", "2017-01-18", "complex-arrays", (struct lyext_plugin*)&libyang_ext_test_arrays_p},
{"ext-def", "2017-01-18", "complex-mand", (struct lyext_plugin*)&libyang_ext_test_mand_p},
+ {"ext-def", "2017-01-18", "skipped", (struct lyext_plugin*)&libyang_ext_test_skipped},
{NULL, NULL, NULL, NULL} /* terminating item */
};
diff --git a/src/parser.c b/src/parser.c
index 0e6673d..db65bb8 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -3975,3 +3975,133 @@
return ret;
}
+
+int
+lyp_get_ext_list(struct ly_ctx *ctx, void *elem, LYEXT_PAR elem_type,
+ struct lys_ext_instance ****ext_list, uint8_t **ext_size, const char **stmt)
+{
+ const char *statement = NULL;
+
+ switch (elem_type) {
+ case LYEXT_PAR_MODULE:
+ *ext_size = &((struct lys_module *)elem)->ext_size;
+ *ext_list = &((struct lys_module *)elem)->ext;
+ statement = ((struct lys_module *)elem)->type ? "submodule" : "module";
+ break;
+ case LYEXT_PAR_IMPORT:
+ *ext_size = &((struct lys_import *)elem)->ext_size;
+ *ext_list = &((struct lys_import *)elem)->ext;
+ statement = "import";
+ break;
+ case LYEXT_PAR_INCLUDE:
+ *ext_size = &((struct lys_include *)elem)->ext_size;
+ *ext_list = &((struct lys_include *)elem)->ext;
+ statement = "include";
+ break;
+ case LYEXT_PAR_REVISION:
+ *ext_size = &((struct lys_revision *)elem)->ext_size;
+ *ext_list = &((struct lys_revision *)elem)->ext;
+ statement = "revision";
+ break;
+ case LYEXT_PAR_NODE:
+ *ext_size = &((struct lys_node *)elem)->ext_size;
+ *ext_list = &((struct lys_node *)elem)->ext;
+ statement = strnodetype(((struct lys_node *)elem)->nodetype);
+ break;
+ case LYEXT_PAR_IDENT:
+ *ext_size = &((struct lys_ident *)elem)->ext_size;
+ *ext_list = &((struct lys_ident *)elem)->ext;
+ statement = "identity";
+ break;
+ case LYEXT_PAR_TYPE:
+ *ext_size = &((struct lys_type *)elem)->ext_size;
+ *ext_list = &((struct lys_type *)elem)->ext;
+ statement = "type";
+ break;
+ case LYEXT_PAR_TYPE_BIT:
+ *ext_size = &((struct lys_type_bit *)elem)->ext_size;
+ *ext_list = &((struct lys_type_bit *)elem)->ext;
+ statement = "bit";
+ break;
+ case LYEXT_PAR_TYPE_ENUM:
+ *ext_size = &((struct lys_type_enum *)elem)->ext_size;
+ *ext_list = &((struct lys_type_enum *)elem)->ext;
+ statement = "enum";
+ break;
+ case LYEXT_PAR_TPDF:
+ *ext_size = &((struct lys_tpdf *)elem)->ext_size;
+ *ext_list = &((struct lys_tpdf *)elem)->ext;
+ statement = "typedef";
+ break;
+ case LYEXT_PAR_EXT:
+ *ext_size = &((struct lys_ext *)elem)->ext_size;
+ *ext_list = &((struct lys_ext *)elem)->ext;
+ statement = "extension";
+ break;
+ case LYEXT_PAR_EXTINST:
+ *ext_size = &((struct lys_ext_instance *)elem)->ext_size;
+ *ext_list = &((struct lys_ext_instance *)elem)->ext;
+ statement = "extension instance";
+ break;
+ case LYEXT_PAR_FEATURE:
+ *ext_size = &((struct lys_feature *)elem)->ext_size;
+ *ext_list = &((struct lys_feature *)elem)->ext;
+ statement = "feature";
+ break;
+ case LYEXT_PAR_REFINE:
+ *ext_size = &((struct lys_refine *)elem)->ext_size;
+ *ext_list = &((struct lys_refine *)elem)->ext;
+ statement = "refine";
+ break;
+ case LYEXT_PAR_RESTR:
+ *ext_size = &((struct lys_restr *)elem)->ext_size;
+ *ext_list = &((struct lys_restr *)elem)->ext;
+ statement = "YANG restriction";
+ break;
+ case LYEXT_PAR_WHEN:
+ *ext_size = &((struct lys_when *)elem)->ext_size;
+ *ext_list = &((struct lys_when *)elem)->ext;
+ statement = "when";
+ break;
+ case LYEXT_PAR_DEVIATE:
+ *ext_size = &((struct lys_deviate *)elem)->ext_size;
+ *ext_list = &((struct lys_deviate *)elem)->ext;
+ statement = "deviate";
+ break;
+ case LYEXT_PAR_DEVIATION:
+ *ext_size = &((struct lys_deviation *)elem)->ext_size;
+ *ext_list = &((struct lys_deviation *)elem)->ext;
+ statement = "deviation";
+ break;
+ default:
+ LOGERR(ctx, LY_EINT, "parent type %d", elem_type);
+ return -1;
+ }
+
+ if (stmt) {
+ *stmt = statement;
+ }
+
+ return 0;
+}
+
+inline void
+lyp_reduce_ext_list(struct lys_ext_instance ***ext, uint8_t new_size, uint8_t orig_size)
+{
+ struct lys_ext_instance **tmp;
+
+ if (new_size != orig_size) {
+ if (new_size == 0) {
+ free(*ext);
+ *ext = NULL;
+ } else {
+ tmp = realloc(*ext, new_size * sizeof(*tmp));
+ if (!tmp) {
+ /* we just reduce the size, so this failure is harmless. */
+ return;
+ }
+ *ext = tmp;
+ }
+ }
+}
+
diff --git a/src/parser.h b/src/parser.h
index b22f6b5..d890833 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -86,7 +86,7 @@
};
int lyp_yin_fill_ext(void *parent, LYEXT_PAR parent_type, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
struct lys_module *module, struct lyxml_elem *yin, struct lys_ext_instance ***ext,
- uint8_t ext_index, struct unres_schema *unres);
+ uint8_t *ext_size, struct unres_schema *unres);
int lyp_yin_parse_complex_ext(struct lys_module *mod, struct lys_ext_instance_complex *ext,
struct lyxml_elem *yin, struct unres_schema *unres);
@@ -163,6 +163,30 @@
void lyp_ext_instance_rm(struct ly_ctx *ctx, struct lys_ext_instance ***ext, uint8_t *size, uint8_t index);
/**
+ * @brief Get extension instances from given parent node
+ *
+ * @param[in] ctx Context with the modules
+ * @param[in] elem Parent of the extension instances
+ * @param[in] elem_type Parent type of the extension instances
+ * @param[out] ext_list Address of the extension instance pointer array
+ * @param[out] ext_size Address of size of the extension instance pointer array
+ * @param[out] stmt Short name of the extension instance parent
+ * @return 0 for success, -1 for failure
+ */
+int lyp_get_ext_list(struct ly_ctx *ctx, void *elem, LYEXT_PAR elem_type,
+ struct lys_ext_instance ****ext_list, uint8_t **ext_size, const char **stmt);
+
+/**
+ * @brief Reduce extension instance pointer array
+ *
+ * @param[in] ext Address of the extension instance pointer array
+ * @param[in] new_size New size of the extension instance pointer array
+ * @param[in] orig_size Origin size of the extension instance pointer array
+ * @return 0 for success, -1 for failure
+ */
+void lyp_reduce_ext_list(struct lys_ext_instance ***ext, uint8_t new_size, uint8_t orig_size);
+
+/**
* @brief Propagate imports and includes into the main module
*
* @param module Main module
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 35898b9..f894352 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -166,7 +166,7 @@
rc = lyp_check_import(module, exp, imp_new);
lydict_remove(module->ctx, exp);
module->imp_size++;
- if (rc || yang_check_ext_instance(module, &imp_new->ext, imp_new->ext_size, imp_new, unres)) {
+ if (rc || yang_check_ext_instance(module, &imp_new->ext, &imp_new->ext_size, imp_new, unres)) {
return EXIT_FAILURE;
}
@@ -2117,7 +2117,7 @@
if (!rc) {
/* success, copy the filled data into the final array */
memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
- if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
+ if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, &trg->inc[trg->inc_size].ext_size,
&trg->inc[trg->inc_size], unres)) {
ret = -1;
}
@@ -3334,28 +3334,41 @@
/* check function*/
int
-yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
+yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint8_t *size,
void *parent, struct unres_schema *unres)
{
struct unres_ext *info;
- uint i;
+ struct lys_ext_instance **ext_list = *ext;
+ uint8_t i = 0, orig_size = *size;
+ int rc;
- for (i = 0; i < size; ++i) {
+ while (i < *size) {
info = malloc(sizeof *info);
LY_CHECK_ERR_RETURN(!info, LOGMEM(module->ctx), EXIT_FAILURE);
- info->data.yang = (*ext)[i]->parent;
+ info->data.yang = ext_list[i]->parent;
info->datatype = LYS_IN_YANG;
info->parent = parent;
info->mod = module;
- info->parent_type = (*ext)[i]->parent_type;
- info->substmt = (*ext)[i]->insubstmt;
- info->substmt_index = (*ext)[i]->insubstmt_index;
+ info->parent_type = ext_list[i]->parent_type;
+ info->substmt = ext_list[i]->insubstmt;
+ info->substmt_index = ext_list[i]->insubstmt_index;
info->ext_index = i;
- if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
+
+ rc = unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info);
+ if (rc == -1) {
return EXIT_FAILURE;
}
+ if (!rc && !ext_list[i]) {
+ /* this extension is skipped, move all extensions after it */
+ memmove(ext_list + i, ext_list + i + 1, (*size - i - 1) * sizeof(*ext_list));
+ --(*size);
+ } else {
+ ++i;
+ }
}
+ lyp_reduce_ext_list(ext, *size, orig_size);
+
return EXIT_SUCCESS;
}
@@ -3463,7 +3476,7 @@
*ptr_size = size;
return EXIT_FAILURE;
}
- if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
+ if (yang_check_ext_instance(module, &iffeature[i].ext, &iffeature[i].ext_size, &iffeature[i], unres)) {
*ptr_size = size;
return EXIT_FAILURE;
}
@@ -3522,7 +3535,7 @@
unsigned int i, j;
type->parent = parent;
- if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
+ if (yang_check_ext_instance(module, &type->ext, &type->ext_size, type, unres)) {
return EXIT_FAILURE;
}
for (j = 0; j < type->ext_size; ++j) {
@@ -3538,7 +3551,7 @@
if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
return EXIT_FAILURE;
}
- if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
+ if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, &type->info.enums.enm[i].ext_size,
&type->info.enums.enm[i], unres)) {
return EXIT_FAILURE;
}
@@ -3555,7 +3568,7 @@
if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
return EXIT_FAILURE;
}
- if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
+ if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, &type->info.bits.bit[i].ext_size,
&type->info.bits.bit[i], unres)) {
return EXIT_FAILURE;
}
@@ -3575,7 +3588,7 @@
case LY_TYPE_STRING:
if (type->info.str.length) {
if (yang_check_ext_instance(module, &type->info.str.length->ext,
- type->info.str.length->ext_size, type->info.str.length, unres)) {
+ &type->info.str.length->ext_size, type->info.str.length, unres)) {
return EXIT_FAILURE;
}
for (j = 0; j < type->info.str.length->ext_size; ++j) {
@@ -3587,7 +3600,7 @@
}
for (i = 0; i < type->info.str.pat_count; ++i) {
- if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
+ if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, &type->info.str.patterns[i].ext_size,
&type->info.str.patterns[i], unres)) {
return EXIT_FAILURE;
}
@@ -3602,7 +3615,7 @@
case LY_TYPE_DEC64:
if (type->info.dec64.range) {
if (yang_check_ext_instance(module, &type->info.dec64.range->ext,
- type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
+ &type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
return EXIT_FAILURE;
}
for (j = 0; j < type->info.dec64.range->ext_size; ++j) {
@@ -3689,7 +3702,7 @@
if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
goto error;
}
- if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
+ if (yang_check_ext_instance(module, &tpdf[i].ext, &tpdf[i].ext_size, &tpdf[i], unres)) {
goto error;
}
for (j = 0; j < tpdf[i].ext_size; ++j) {
@@ -3744,7 +3757,7 @@
if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
goto error;
}
- if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
+ if (yang_check_ext_instance(module, &module->ident[i].ext, &module->ident[i].ext_size, &module->ident[i], unres)) {
goto error;
}
}
@@ -3765,7 +3778,7 @@
uint i;
for (i = 0; i < size; ++i) {
- if (yang_check_ext_instance(module, &must[i].ext, must[i].ext_size, &must[i], unres)) {
+ if (yang_check_ext_instance(module, &must[i].ext, &must[i].ext_size, &must[i], unres)) {
return EXIT_FAILURE;
}
}
@@ -3790,7 +3803,7 @@
}
*child = NULL;
- if (cont->when && yang_check_ext_instance(module, &cont->when->ext, cont->when->ext_size, cont->when, unres)) {
+ if (cont->when && yang_check_ext_instance(module, &cont->when->ext, &cont->when->ext_size, cont->when, unres)) {
goto error;
}
if (yang_check_must(module, cont->must, cont->must_size, unres)) {
@@ -3838,7 +3851,7 @@
goto error;
}
- if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, leaf->when->ext_size, leaf->when, unres)) {
+ if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, &leaf->when->ext_size, leaf->when, unres)) {
goto error;
}
if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
@@ -3905,7 +3918,7 @@
}
}
- if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, leaflist->when->ext_size, leaflist->when, unres)) {
+ if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, &leaflist->when->ext_size, leaflist->when, unres)) {
goto error;
}
if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
@@ -3973,7 +3986,7 @@
goto error;
}
- if (list->when && yang_check_ext_instance(module, &list->when->ext, list->when->ext_size, list->when, unres)) {
+ if (list->when && yang_check_ext_instance(module, &list->when->ext, &list->when->ext_size, list->when, unres)) {
goto error;
}
if (yang_check_must(module, list->must, list->must_size, unres)) {
@@ -4029,7 +4042,7 @@
free(value);
}
- if (choice->when && yang_check_ext_instance(module, &choice->when->ext, choice->when->ext_size, choice->when, unres)) {
+ if (choice->when && yang_check_ext_instance(module, &choice->when->ext, &choice->when->ext_size, choice->when, unres)) {
goto error;
}
@@ -4142,11 +4155,11 @@
goto error;
}
- if (yang_check_ext_instance(module, &augment->ext, augment->ext_size, augment, unres)) {
+ if (yang_check_ext_instance(module, &augment->ext, &augment->ext_size, augment, unres)) {
goto error;
}
- if (augment->when && yang_check_ext_instance(module, &augment->when->ext, augment->when->ext_size, augment->when, unres)) {
+ if (augment->when && yang_check_ext_instance(module, &augment->when->ext, &augment->when->ext_size, augment->when, unres)) {
goto error;
}
@@ -4188,7 +4201,7 @@
if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
goto error;
}
- if (yang_check_ext_instance(module, &uses->refine[i].ext, uses->refine[i].ext_size, &uses->refine[i], unres)) {
+ if (yang_check_ext_instance(module, &uses->refine[i].ext, &uses->refine[i].ext_size, &uses->refine[i], unres)) {
goto error;
}
}
@@ -4204,7 +4217,7 @@
goto error;
}
- if (uses->when && yang_check_ext_instance(module, &uses->when->ext, uses->when->ext_size, uses->when, unres)) {
+ if (uses->when && yang_check_ext_instance(module, &uses->when->ext, &uses->when->ext_size, uses->when, unres)) {
goto error;
}
@@ -4244,7 +4257,7 @@
}
*child = NULL;
- if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, anydata->when->ext_size, anydata->when, unres)) {
+ if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, &anydata->when->ext_size, anydata->when, unres)) {
goto error;
}
if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
@@ -4297,7 +4310,7 @@
store_config_flag(node->parent, options);
}
store_config_flag(node, options);
- if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
+ if (yang_check_ext_instance(module, &node->ext, &node->ext_size, node, unres)) {
goto error;
}
for (i = 0; i < node->ext_size; ++i) {
@@ -4360,7 +4373,7 @@
}
if (((struct lys_node_case *)node)->when) {
if (yang_check_ext_instance(module, &((struct lys_node_case *)node)->when->ext,
- ((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
+ &((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
goto error;
}
/* check XPath dependencies */
@@ -4447,7 +4460,7 @@
struct lys_tpdf *tmp_parent;
int i, j;
- if (yang_check_ext_instance(module, &deviate->ext, deviate->ext_size, deviate, unres)) {
+ if (yang_check_ext_instance(module, &deviate->ext, &deviate->ext_size, deviate, unres)) {
goto error;
}
if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
@@ -4635,7 +4648,7 @@
unres_schema_free(dev_target->module, &tmp_unres, 1);
}
- if (yang_check_ext_instance(module, &dev->ext, dev->ext_size, dev, unres)) {
+ if (yang_check_ext_instance(module, &dev->ext, &dev->ext_size, dev, unres)) {
i = 0;
goto free_type_error;
}
@@ -4724,20 +4737,20 @@
goto error;
}
- if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
+ if (yang_check_ext_instance(module, &module->ext, &module->ext_size, module, unres)) {
goto error;
}
/* check extension in revision */
for (i = 0; i < module->rev_size; ++i) {
- if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
+ if (yang_check_ext_instance(module, &module->rev[i].ext, &module->rev[i].ext_size, &module->rev[i], unres)) {
goto error;
}
}
/* check extension in definition of extension */
for (i = 0; i < module->extensions_size; ++i) {
- if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
+ if (yang_check_ext_instance(module, &module->extensions[i].ext, &module->extensions[i].ext_size, &module->extensions[i], unres)) {
goto error;
}
}
@@ -4747,7 +4760,7 @@
if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
goto error;
}
- if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
+ if (yang_check_ext_instance(module, &module->features[i].ext, &module->features[i].ext_size, &module->features[i], unres)) {
goto error;
}
diff --git a/src/parser_yang.h b/src/parser_yang.h
index 7e69297..5ef67d9 100644
--- a/src/parser_yang.h
+++ b/src/parser_yang.h
@@ -170,7 +170,7 @@
void *yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance);
-int yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
+int yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint8_t *size,
void *parent, struct unres_schema *unres);
int yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
diff --git a/src/parser_yang_bis.c b/src/parser_yang_bis.c
index 894fee5..3e5c53f 100644
--- a/src/parser_yang_bis.c
+++ b/src/parser_yang_bis.c
@@ -7865,7 +7865,7 @@
if (yang_fill_type(trg, &tpdf->type, (struct yang_type *)tpdf->type.der, tpdf, param->unres)) {
yang_type_free(trg->ctx, &tpdf->type);
}
- if (yang_check_ext_instance(trg, &tpdf->ext, tpdf->ext_size, tpdf, param->unres)) {
+ if (yang_check_ext_instance(trg, &tpdf->ext, &tpdf->ext_size, tpdf, param->unres)) {
YYABORT;
}
if (unres_schema_add_node(trg, param->unres, &tpdf->type, UNRES_TYPE_DER_TPDF, (struct lys_node *)ext_instance) == -1) {
@@ -8052,7 +8052,7 @@
if (yang_fill_iffeature(trg, iffeature, ext_instance, s, param->unres, 0)) {
YYABORT;
}
- if (yang_check_ext_instance(trg, &iffeature->ext, iffeature->ext_size, iffeature, param->unres)) {
+ if (yang_check_ext_instance(trg, &iffeature->ext, &iffeature->ext_size, iffeature, param->unres)) {
YYABORT;
}
s = NULL;
@@ -8061,7 +8061,7 @@
break;
case 823:
- { if (yang_check_ext_instance(trg, &((struct lys_restr *)(yyvsp[-2].v))->ext, ((struct lys_restr *)(yyvsp[-2].v))->ext_size, (yyvsp[-2].v), param->unres)) {
+ { if (yang_check_ext_instance(trg, &((struct lys_restr *)(yyvsp[-2].v))->ext, &((struct lys_restr *)(yyvsp[-2].v))->ext_size, (yyvsp[-2].v), param->unres)) {
YYABORT;
}
actual = ext_instance;
@@ -8069,7 +8069,7 @@
break;
case 824:
- { if (yang_check_ext_instance(trg, &(*(struct lys_when **)(yyvsp[-2].v))->ext, (*(struct lys_when **)(yyvsp[-2].v))->ext_size,
+ { if (yang_check_ext_instance(trg, &(*(struct lys_when **)(yyvsp[-2].v))->ext, &(*(struct lys_when **)(yyvsp[-2].v))->ext_size,
*(struct lys_when **)(yyvsp[-2].v), param->unres)) {
YYABORT;
}
@@ -8086,7 +8086,7 @@
break;
}
}
- if (yang_check_ext_instance(trg, &(yyvsp[-2].revisions).revision[(yyvsp[-2].revisions).index]->ext, (yyvsp[-2].revisions).revision[(yyvsp[-2].revisions).index]->ext_size,
+ if (yang_check_ext_instance(trg, &(yyvsp[-2].revisions).revision[(yyvsp[-2].revisions).index]->ext, &(yyvsp[-2].revisions).revision[(yyvsp[-2].revisions).index]->ext_size,
&(yyvsp[-2].revisions).revision[(yyvsp[-2].revisions).index], param->unres)) {
YYABORT;
}
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 62f6857..d545a6d 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -91,9 +91,10 @@
int
lyp_yin_fill_ext(void *parent, LYEXT_PAR parent_type, LYEXT_SUBSTMT substmt, uint8_t substmt_index,
struct lys_module *module, struct lyxml_elem *yin, struct lys_ext_instance ***ext,
- uint8_t ext_index, struct unres_schema *unres)
+ uint8_t *ext_size, struct unres_schema *unres)
{
struct unres_ext *info;
+ int rc;
info = malloc(sizeof *info);
LY_CHECK_ERR_RETURN(!info, LOGMEM(module->ctx), EXIT_FAILURE);
@@ -105,13 +106,16 @@
info->parent_type = parent_type;
info->substmt = substmt;
info->substmt_index = substmt_index;
- info->ext_index = ext_index;
+ info->ext_index = *ext_size;
- if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
- return EXIT_FAILURE;
+ rc = unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info);
+ if (!rc && !(*ext)[*ext_size]) {
+ /* extension instance is skipped */
+ } else {
+ ++(*ext_size);
}
- return EXIT_SUCCESS;
+ return rc == -1 ? EXIT_FAILURE : EXIT_SUCCESS;
}
/* logs directly */
@@ -144,101 +148,8 @@
uint8_t *ext_size;
const char *statement;
- switch (elem_type) {
- case LYEXT_PAR_MODULE:
- ext_size = &((struct lys_module *)elem)->ext_size;
- ext = &((struct lys_module *)elem)->ext;
- statement = ((struct lys_module *)elem)->type ? "submodule" : "module";
- break;
- case LYEXT_PAR_IMPORT:
- ext_size = &((struct lys_import *)elem)->ext_size;
- ext = &((struct lys_import *)elem)->ext;
- statement = "import";
- break;
- case LYEXT_PAR_INCLUDE:
- ext_size = &((struct lys_include *)elem)->ext_size;
- ext = &((struct lys_include *)elem)->ext;
- statement = "include";
- break;
- case LYEXT_PAR_REVISION:
- ext_size = &((struct lys_revision *)elem)->ext_size;
- ext = &((struct lys_revision *)elem)->ext;
- statement = "revision";
- break;
- case LYEXT_PAR_NODE:
- ext_size = &((struct lys_node *)elem)->ext_size;
- ext = &((struct lys_node *)elem)->ext;
- statement = strnodetype(((struct lys_node *)elem)->nodetype);
- break;
- case LYEXT_PAR_IDENT:
- ext_size = &((struct lys_ident *)elem)->ext_size;
- ext = &((struct lys_ident *)elem)->ext;
- statement = "identity";
- break;
- case LYEXT_PAR_TYPE:
- ext_size = &((struct lys_type *)elem)->ext_size;
- ext = &((struct lys_type *)elem)->ext;
- statement = "type";
- break;
- case LYEXT_PAR_TYPE_BIT:
- ext_size = &((struct lys_type_bit *)elem)->ext_size;
- ext = &((struct lys_type_bit *)elem)->ext;
- statement = "bit";
- break;
- case LYEXT_PAR_TYPE_ENUM:
- ext_size = &((struct lys_type_enum *)elem)->ext_size;
- ext = &((struct lys_type_enum *)elem)->ext;
- statement = "enum";
- break;
- case LYEXT_PAR_TPDF:
- ext_size = &((struct lys_tpdf *)elem)->ext_size;
- ext = &((struct lys_tpdf *)elem)->ext;
- statement = " typedef";
- break;
- case LYEXT_PAR_EXT:
- ext_size = &((struct lys_ext *)elem)->ext_size;
- ext = &((struct lys_ext *)elem)->ext;
- statement = "extension";
- break;
- case LYEXT_PAR_EXTINST:
- ext_size = &((struct lys_ext_instance *)elem)->ext_size;
- ext = &((struct lys_ext_instance *)elem)->ext;
- statement = "extension instance";
- break;
- case LYEXT_PAR_FEATURE:
- ext_size = &((struct lys_feature *)elem)->ext_size;
- ext = &((struct lys_feature *)elem)->ext;
- statement = "feature";
- break;
- case LYEXT_PAR_REFINE:
- ext_size = &((struct lys_refine *)elem)->ext_size;
- ext = &((struct lys_refine *)elem)->ext;
- statement = "refine";
- break;
- case LYEXT_PAR_RESTR:
- ext_size = &((struct lys_restr *)elem)->ext_size;
- ext = &((struct lys_restr *)elem)->ext;
- statement = "YANG restriction";
- break;
- case LYEXT_PAR_WHEN:
- ext_size = &((struct lys_when *)elem)->ext_size;
- ext = &((struct lys_when *)elem)->ext;
- statement = "when";
- break;
- case LYEXT_PAR_DEVIATE:
- ext_size = &((struct lys_deviate *)elem)->ext_size;
- ext = &((struct lys_deviate *)elem)->ext;
- statement = "deviate";
- break;
- case LYEXT_PAR_DEVIATION:
- ext_size = &((struct lys_deviation *)elem)->ext_size;
- ext = &((struct lys_deviation *)elem)->ext;
- statement = "deviation";
- break;
- default:
- LOGERR(mod->ctx, LY_EINT, "parent type %d", elem_type);
- return EXIT_FAILURE;
- }
+ r = lyp_get_ext_list(mod->ctx, elem, elem_type, &ext, &ext_size, &statement);
+ LY_CHECK_RETURN(r, EXIT_FAILURE);
if (type == LYEXT_SUBSTMT_SELF) {
/* parse for the statement self, not for the substatement */
@@ -270,12 +181,13 @@
(*ext)[(*ext_size)] = NULL;
/* parse YIN data */
- r = lyp_yin_fill_ext(elem, elem_type, type, i, mod, child, &(*ext), (*ext_size), unres);
- (*ext_size)++;
+ r = lyp_yin_fill_ext(elem, elem_type, type, i, mod, child, ext, ext_size, unres);
if (r) {
return EXIT_FAILURE;
}
+ lyp_reduce_ext_list(ext, *ext_size, 1 + (*ext_size));
+
/* done - do not free the child, it is unlinked in lyp_yin_fill_ext */
}
@@ -329,12 +241,13 @@
LY_TREE_FOR_SAFE(yin->child, next, node) {
/* extensions */
r = lyp_yin_fill_ext(iffeat, LYEXT_PAR_IDENT, 0, 0, parent->module, node,
- &iffeat->ext, iffeat->ext_size, unres);
- iffeat->ext_size++;
+ &iffeat->ext, &iffeat->ext_size, unres);
if (r) {
return EXIT_FAILURE;
}
}
+
+ lyp_reduce_ext_list(&iffeat->ext, iffeat->ext_size, c_ext + iffeat->ext_size);
}
return EXIT_SUCCESS;
@@ -410,8 +323,7 @@
LY_TREE_FOR_SAFE(yin->child, next, node) {
if (strcmp(node->ns->value, LY_NSYIN)) {
/* extension */
- rc = lyp_yin_fill_ext(ident, LYEXT_PAR_IDENT, 0, 0, module, node, &ident->ext, ident->ext_size, unres);
- ident->ext_size++;
+ rc = lyp_yin_fill_ext(ident, LYEXT_PAR_IDENT, 0, 0, module, node, &ident->ext, &ident->ext_size, unres);
if (rc) {
goto error;
}
@@ -436,6 +348,8 @@
}
}
+ lyp_reduce_ext_list(&ident->ext, ident->ext_size, c_ext + ident->ext_size);
+
return EXIT_SUCCESS;
error:
@@ -631,12 +545,13 @@
LY_CHECK_ERR_GOTO(!type->ext, LOGMEM(ctx), error);
LY_TREE_FOR_SAFE(exts.child, next, node) {
- rc = lyp_yin_fill_ext(type, LYEXT_PAR_TYPE, 0, 0, module, node, &type->ext, type->ext_size, unres);
- type->ext_size++;
+ rc = lyp_yin_fill_ext(type, LYEXT_PAR_TYPE, 0, 0, module, node, &type->ext, &type->ext_size, unres);
if (rc) {
goto error;
}
}
+
+ lyp_reduce_ext_list(&type->ext, type->ext_size, c_ext + type->ext_size);
}
switch (type->base) {
@@ -1737,12 +1652,13 @@
memset(&tpdf->ext[tpdf->ext_size], 0, c_ext * sizeof *tpdf->ext);
LY_TREE_FOR_SAFE(yin->child, next, node) {
- rc = lyp_yin_fill_ext(tpdf, LYEXT_PAR_TYPE, 0, 0, module, node, &tpdf->ext, tpdf->ext_size, unres);
- tpdf->ext_size++;
+ rc = lyp_yin_fill_ext(tpdf, LYEXT_PAR_TYPE, 0, 0, module, node, &tpdf->ext, &tpdf->ext_size, unres);
if (rc) {
goto error;
}
}
+
+ lyp_reduce_ext_list(&tpdf->ext, tpdf->ext_size, c_ext + tpdf->ext_size);
}
for (i = 0; i < tpdf->ext_size; ++i) {
@@ -1829,12 +1745,13 @@
/* process the extension instances of the extension itself */
LY_TREE_FOR_SAFE(yin->child, next, node) {
- rc = lyp_yin_fill_ext(ext, LYEXT_PAR_EXT, 0, 0, module, node, &ext->ext, ext->ext_size, unres);
- ext->ext_size++;
+ rc = lyp_yin_fill_ext(ext, LYEXT_PAR_EXT, 0, 0, module, node, &ext->ext, &ext->ext_size, unres);
if (rc) {
goto error;
}
}
+
+ lyp_reduce_ext_list(&ext->ext, ext->ext_size, c_ext + ext->ext_size);
}
/* search for plugin */
@@ -1898,8 +1815,7 @@
LY_TREE_FOR_SAFE(yin->child, next, child) {
if (strcmp(child->ns->value, LY_NSYIN)) {
/* extension */
- ret = lyp_yin_fill_ext(f, LYEXT_PAR_FEATURE, 0, 0, module, child, &f->ext, f->ext_size, unres);
- f->ext_size++;
+ ret = lyp_yin_fill_ext(f, LYEXT_PAR_FEATURE, 0, 0, module, child, &f->ext, &f->ext_size, unres);
if (ret) {
goto error;
}
@@ -1912,6 +1828,8 @@
}
}
+ lyp_reduce_ext_list(&f->ext, f->ext_size, c_ext + f->ext_size);
+
/* check for circular dependencies */
if (f->iffeature_size) {
if (unres_schema_add_node(module, unres, f, UNRES_FEATURE, NULL) == -1) {
@@ -2193,7 +2111,7 @@
{
const char *value, **stritem;
struct lyxml_elem *next, *next2, *child, *develem;
- int c_dev = 0, c_must, c_uniq, c_dflt, c_ext = 0;
+ int c_dev = 0, c_must, c_uniq, c_dflt, c_ext = 0, c_ext2;
int f_min = 0, f_max = 0; /* flags */
int i, j, k = 0, rc;
unsigned int u;
@@ -2307,8 +2225,7 @@
LY_TREE_FOR_SAFE(yin->child, next, develem) {
if (strcmp(develem->ns->value, LY_NSYIN)) {
/* deviation's extension */
- rc = lyp_yin_fill_ext(dev, LYEXT_PAR_DEVIATION, 0, 0, module, develem, &dev->ext, dev->ext_size, unres);
- dev->ext_size++;
+ rc = lyp_yin_fill_ext(dev, LYEXT_PAR_DEVIATION, 0, 0, module, develem, &dev->ext, &dev->ext_size, unres);
if (rc) {
goto error;
}
@@ -2322,7 +2239,7 @@
c_must = 0;
c_uniq = 0;
c_dflt = 0;
- c_ext = 0;
+ c_ext2 = 0;
/* get deviation type */
GETVAL(ctx, value, develem, "value");
@@ -2408,8 +2325,8 @@
continue;
} else if (strcmp(child->ns->value, LY_NSYIN)) {
/* extensions */
- YIN_CHECK_ARRAY_OVERFLOW_GOTO(ctx, c_ext, d->ext_size, "extensions", "deviate", error);
- c_ext++;
+ YIN_CHECK_ARRAY_OVERFLOW_GOTO(ctx, c_ext2, d->ext_size, "extensions", "deviate", error);
+ c_ext2++;
} else if (d->mod == LY_DEVIATE_NO) {
/* no YIN substatement expected in this case */
LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, child->name);
@@ -2845,14 +2762,14 @@
d->dflt = calloc(c_dflt, sizeof *d->dflt);
LY_CHECK_ERR_GOTO(!d->dflt, LOGMEM(ctx), error);
}
- if (c_ext) {
+ if (c_ext2) {
/* some extensions may be already present from the substatements */
- reallocated = realloc(d->ext, (c_ext + d->ext_size) * sizeof *d->ext);
+ reallocated = realloc(d->ext, (c_ext2 + d->ext_size) * sizeof *d->ext);
LY_CHECK_ERR_GOTO(!reallocated, LOGMEM(ctx), error);
d->ext = reallocated;
/* init memory */
- memset(&d->ext[d->ext_size], 0, c_ext * sizeof *d->ext);
+ memset(&d->ext[d->ext_size], 0, c_ext2 * sizeof *d->ext);
}
/* process deviation properties with 0..n cardinality */
@@ -2860,10 +2777,9 @@
LY_TREE_FOR_SAFE(develem->child, next2, child) {
if (strcmp(child->ns->value, LY_NSYIN)) {
/* extension */
- if (lyp_yin_fill_ext(d, LYEXT_PAR_DEVIATE, 0, 0, module, child, &d->ext, d->ext_size, unres)) {
+ if (lyp_yin_fill_ext(d, LYEXT_PAR_DEVIATE, 0, 0, module, child, &d->ext, &d->ext_size, unres)) {
goto error;
}
- d->ext_size++;
} else if (!strcmp(child->name, "must")) {
if (d->mod == LY_DEVIATE_DEL) {
if (fill_yin_must(module, child, &d->must[d->must_size], unres)) {
@@ -3110,6 +3026,8 @@
}
}
+ lyp_reduce_ext_list(&d->ext, d->ext_size, c_ext2 + d->ext_size);
+
if (c_dflt && dev_target->nodetype == LYS_LEAFLIST && d->mod == LY_DEVIATE_DEL) {
/* consolidate the final list in the target after removing items from it */
llist = (struct lys_node_leaflist *)dev_target;
@@ -3123,6 +3041,8 @@
}
}
+ lyp_reduce_ext_list(&dev->ext, dev->ext_size, c_ext + dev->ext_size);
+
/* now check whether default value, if any, matches the type */
if (!(ctx->models.flags & LY_CTX_TRUSTED)) {
for (u = 0; u < dflt_check->number; ++u) {
@@ -3278,8 +3198,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- ret = lyp_yin_fill_ext(aug, LYEXT_PAR_NODE, 0, 0, module, sub, &aug->ext, aug->ext_size, unres);
- aug->ext_size++;
+ ret = lyp_yin_fill_ext(aug, LYEXT_PAR_NODE, 0, 0, module, sub, &aug->ext, &aug->ext_size, unres);
if (ret) {
goto error;
}
@@ -3293,6 +3212,8 @@
}
}
+ lyp_reduce_ext_list(&aug->ext, aug->ext_size, c_ext + aug->ext_size);
+
/* aug->child points to the parsed nodes, they must now be
* connected to the tree and adjusted (if possible right now).
* However, if this is augment in a uses (parent is NULL), it gets resolved
@@ -3655,8 +3576,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(rfn, LYEXT_PAR_REFINE, 0, 0, module, sub, &rfn->ext, rfn->ext_size, unres);
- rfn->ext_size++;
+ r = lyp_yin_fill_ext(rfn, LYEXT_PAR_REFINE, 0, 0, module, sub, &rfn->ext, &rfn->ext_size, unres);
if (r) {
goto error;
}
@@ -3687,6 +3607,8 @@
}
}
+ lyp_reduce_ext_list(&rfn->ext, rfn->ext_size, c_ext + rfn->ext_size);
+
return EXIT_SUCCESS;
error:
@@ -3788,12 +3710,13 @@
LY_TREE_FOR_SAFE(exts.child, next, child) {
/* extension */
- r = lyp_yin_fill_ext(imp, LYEXT_PAR_IMPORT, 0, 0, module, child, &imp->ext, imp->ext_size, unres);
- imp->ext_size++;
+ r = lyp_yin_fill_ext(imp, LYEXT_PAR_IMPORT, 0, 0, module, child, &imp->ext, &imp->ext_size, unres);
if (r) {
goto error;
}
}
+
+ lyp_reduce_ext_list(&imp->ext, imp->ext_size, c_ext + imp->ext_size);
}
GETVAL(ctx, value, yin, "module");
@@ -3890,12 +3813,13 @@
LY_TREE_FOR_SAFE(exts.child, next, child) {
/* extension */
- r = lyp_yin_fill_ext(inc, LYEXT_PAR_INCLUDE, 0, 0, module, child, &inc->ext, inc->ext_size, unres);
- inc->ext_size++;
+ r = lyp_yin_fill_ext(inc, LYEXT_PAR_INCLUDE, 0, 0, module, child, &inc->ext, &inc->ext_size, unres);
if (r) {
goto error;
}
}
+
+ lyp_reduce_ext_list(&inc->ext, inc->ext_size, c_ext + inc->ext_size);
}
GETVAL(ctx, value, yin, "module");
@@ -4228,8 +4152,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- ret = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ ret = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (ret) {
goto error;
}
@@ -4243,6 +4166,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* last part - process data nodes */
LY_TREE_FOR_SAFE(root.child, next, sub) {
if (!strcmp(sub->name, "container")) {
@@ -4447,8 +4372,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- ret = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ ret = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (ret) {
goto error;
}
@@ -4461,6 +4385,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* check - default is prohibited in combination with mandatory */
if (dflt && (choice->flags & LYS_MAND_TRUE)) {
LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, retval, "default", "choice");
@@ -4610,8 +4536,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -4630,6 +4555,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* check XPath dependencies */
if (!(ctx->models.flags & LY_CTX_TRUSTED) && (anyxml->when || anyxml->must)) {
if (options & LYS_PARSE_OPT_INGRP) {
@@ -4817,8 +4744,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -4837,6 +4763,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* finalize type parsing */
if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, retval) == -1) {
leaf->type.der = NULL;
@@ -5106,8 +5034,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -5141,6 +5068,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* finalize type parsing */
if (unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DER, retval) == -1) {
llist->type.der = NULL;
@@ -5445,8 +5374,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -5471,6 +5399,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* last part - process data nodes */
LY_TREE_FOR_SAFE(root.child, next, sub) {
if (!strcmp(sub->name, "container")) {
@@ -5698,8 +5628,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -5724,6 +5653,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* last part - process data nodes */
LY_TREE_FOR_SAFE(root.child, next, sub) {
if (!strcmp(sub->name, "container")) {
@@ -5873,8 +5804,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -5888,6 +5818,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* last part - process data nodes */
if (!root.child) {
LOGWRN(ctx, "Grouping \"%s\" without children.", retval->name);
@@ -6037,8 +5969,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -6057,6 +5988,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* last part - process data nodes */
options |= LYS_PARSE_OPT_CFG_IGNORE;
LY_TREE_FOR_SAFE(root.child, next, sub) {
@@ -6211,8 +6144,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -6237,6 +6169,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* last part - process data nodes */
options |= LYS_PARSE_OPT_CFG_IGNORE;
LY_TREE_FOR_SAFE(root.child, next, sub) {
@@ -6396,8 +6330,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -6416,6 +6349,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
/* last part - process data nodes */
LY_TREE_FOR_SAFE(root.child, next, sub) {
if (!strcmp(sub->name, "grouping")) {
@@ -6540,8 +6475,7 @@
LY_TREE_FOR_SAFE(yin->child, next, sub) {
if (strcmp(sub->ns->value, LY_NSYIN)) {
/* extension */
- r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, retval->ext_size, unres);
- retval->ext_size++;
+ r = lyp_yin_fill_ext(retval, LYEXT_PAR_NODE, 0, 0, module, sub, &retval->ext, &retval->ext_size, unres);
if (r) {
goto error;
}
@@ -6566,6 +6500,8 @@
}
}
+ lyp_reduce_ext_list(&retval->ext, retval->ext_size, c_ext + retval->ext_size);
+
if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
goto error;
}
@@ -7172,12 +7108,13 @@
memset(&trg->ext[trg->ext_size], 0, c_extinst * sizeof *trg->ext);
LY_TREE_FOR_SAFE(exts.child, next, child) {
- r = lyp_yin_fill_ext(trg, LYEXT_PAR_MODULE, 0, 0, trg, child, &trg->ext, trg->ext_size, unres);
- trg->ext_size++;
+ r = lyp_yin_fill_ext(trg, LYEXT_PAR_MODULE, 0, 0, trg, child, &trg->ext, &trg->ext_size, unres);
if (r) {
goto error;
}
}
+
+ lyp_reduce_ext_list(&trg->ext, trg->ext_size, c_ext + trg->ext_size);
}
/* process data nodes. Start with groupings to allow uses
diff --git a/src/resolve.c b/src/resolve.c
index 6cf1091..e8b3c2a 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -4852,6 +4852,7 @@
struct lys_ext_instance *tmp_ext;
struct ly_ctx *ctx = NULL;
LYEXT_TYPE etype;
+ int rt = 0;
switch (info->parent_type) {
case LYEXT_PAR_NODE:
@@ -4907,10 +4908,14 @@
if (e->plugin && e->plugin->check_position) {
/* common part - we have plugin with position checking function, use it first */
- if ((*e->plugin->check_position)(info->parent, info->parent_type, info->substmt)) {
+ rt = (*e->plugin->check_position)(info->parent, info->parent_type, info->substmt);
+ if (rt == 1) {
/* extension is not allowed here */
LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, e->name);
return -1;
+ } else if (rt == 2) {
+ *ext = NULL;
+ return EXIT_SUCCESS;
}
}
@@ -5066,10 +5071,18 @@
if (e->plugin && e->plugin->check_position) {
/* common part - we have plugin with position checking function, use it first */
- if ((*e->plugin->check_position)(info->parent, info->parent_type, info->substmt)) {
+ rt = (*e->plugin->check_position)(info->parent, info->parent_type, info->substmt);
+ if (rt == 1) {
/* extension is not allowed here */
LOGVAL(ctx, LYE_INSTMT, vlog_type, vlog_node, e->name);
goto error;
+ } else if (rt == 2) {
+ lys_extension_instances_free(ctx, (*ext)->ext, (*ext)->ext_size, NULL);
+ lydict_remove(ctx, (*ext)->arg_value);
+ free(*ext);
+ *ext = NULL;
+ free(ext_prefix);
+ return EXIT_SUCCESS;
}
}
@@ -5131,9 +5144,10 @@
goto error;
}
- if (yang_check_ext_instance(info->mod, &(*ext)->ext, (*ext)->ext_size, *ext, unres)) {
+ if (yang_check_ext_instance(info->mod, &(*ext)->ext, &(*ext)->ext_size, *ext, unres)) {
goto error;
}
+
free(ext_prefix);
}
@@ -6885,6 +6899,21 @@
return type->der->has_union_leafref;
}
+static void
+free_ext_data(struct ly_ctx *ctx, struct unres_ext *ext_data)
+{
+ /* cleanup on success or fatal error */
+ if (ext_data->datatype == LYS_IN_YIN) {
+ /* YIN */
+ lyxml_free(ctx, ext_data->data.yin);
+ } else {
+ /* YANG */
+ yang_free_ext_data(ext_data->data.yang);
+ }
+
+ free(ext_data);
+}
+
/**
* @brief Resolve a single unres schema item. Logs indirectly.
*
@@ -7130,7 +7159,7 @@
ext_data = (struct unres_ext *)str_snode;
extlist = &(*(struct lys_ext_instance ***)item)[ext_data->ext_index];
rc = resolve_extension(ext_data, extlist, unres);
- if (!rc) {
+ if (!rc && extlist[0]) {
/* success */
/* is there a callback to be done to finalize the extension? */
eplugin = extlist[0]->def->plugin;
@@ -7148,17 +7177,6 @@
}
}
}
- if (!rc || rc == -1) {
- /* cleanup on success or fatal error */
- if (ext_data->datatype == LYS_IN_YIN) {
- /* YIN */
- lyxml_free(ctx, ext_data->data.yin);
- } else {
- /* YANG */
- yang_free_ext_data(ext_data->data.yang);
- }
- free(ext_data);
- }
break;
case UNRES_EXT_FINALIZE:
u = (uint8_t *)str_snode;
@@ -7348,6 +7366,73 @@
}
}
+/**
+ * @brief Save extension instance parent for Compacting later.
+ *
+ * @param[in] ext_parents Extension instance parent set
+ * @param[in] ext_par_types Extension instance parent type list, same size with ext_parents
+ * @param[in] ext_list Extension instance array
+ * @param[in] ext_data Unsolved extension instance data
+ *
+ * @return 0 on success, -1 on failure.
+ */
+static int
+save_skipped_ext_parent(struct ly_set *ext_parents, struct ly_set *ext_par_types,
+ struct lys_ext_instance **ext_list, struct unres_ext *ext_data)
+{
+ int rt;
+
+ if(!ext_list[ext_data->ext_index]) {
+ rt = ly_set_add(ext_parents, ext_data->parent, 0);
+ LY_CHECK_RETURN(rt == -1, rt);
+ if (ext_parents->number != ext_par_types->number) {
+ // a new skipped extension instance parent
+ rt = ly_set_add(ext_par_types, (void *)ext_data->datatype, 1);
+ LY_CHECK_RETURN(rt == -1, rt);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Remove all NULL items from the extension instance array of given parent.
+ *
+ * @param[in] ctx Context with the modules
+ * @param[in] elem Extension instance parent
+ * @param[in] elem_type Extension instance parent type
+ *
+ * @return 0 on success, -1 on failure.
+ */
+static int
+compact_ext_list(struct ly_ctx *ctx, void *elem, LYEXT_PAR elem_type)
+{
+ int rt;
+ uint8_t *ext_size = 0, orig_size, i = 0, j = 0;
+ struct lys_ext_instance ***ext_list = NULL;
+
+ rt = lyp_get_ext_list(ctx, elem, elem_type, &ext_list, &ext_size, NULL);
+ LY_CHECK_RETURN(rt, -1);
+
+ orig_size = *ext_size;
+
+ while (i < *ext_size) {
+ if (!(*ext_list)[i]) {
+ /* this extension is skipped, move all extensions after it */
+ for (j = i; j < *ext_size - 1; j++) {
+ (*ext_list)[j] = (*ext_list)[j + 1];
+ }
+ --(*ext_size);
+ } else {
+ ++i;
+ }
+ }
+
+ lyp_reduce_ext_list(ext_list, *ext_size, orig_size);
+
+ return 0;
+}
+
static int
resolve_unres_schema_types(struct unres_schema *unres, enum UNRES_ITEM types, struct ly_ctx *ctx, int forward_ref,
int print_all_errors, uint32_t *resolved)
@@ -7356,7 +7441,8 @@
int ret = 0, rc;
struct ly_err_item *prev_eitem;
enum int_log_opts prev_ilo;
- LY_ERR prev_ly_errno;
+ LY_ERR prev_ly_errno = LY_SUCCESS;
+ struct ly_set *ext_parents = NULL, *ext_par_types = NULL;
/* if there can be no forward references, every failure is final, so we can print it directly */
if (forward_ref) {
@@ -7364,6 +7450,12 @@
ly_ilo_change(ctx, ILO_STORE, &prev_ilo, &prev_eitem);
}
+ if ((types & UNRES_EXT)) {
+ ext_parents = ly_set_new();
+ ext_par_types = ly_set_new();
+ LY_CHECK_ERR_GOTO(!ext_parents || !ext_par_types, ret = -1, finish);
+ }
+
do {
unres_count = 0;
res_count = 0;
@@ -7379,6 +7471,19 @@
/* to avoid double free */
unres->type[i] = UNRES_RESOLVED;
}
+
+ if (unres->type[i] == UNRES_EXT) {
+ if (!rc) {
+ ret = save_skipped_ext_parent(ext_parents, ext_par_types,
+ *(struct lys_ext_instance***) unres->item[i],
+ (struct unres_ext*) unres->str_snode[i]);
+ }
+ if (!rc || rc == -1) {
+ free_ext_data(ctx, unres->str_snode[i]);
+ }
+ LY_CHECK_GOTO(ret, finish);
+ }
+
if (!rc || (unres->type[i] == UNRES_XPATH)) {
/* invalid XPath can never cause an error, only a warning */
if (unres->type[i] == UNRES_LIST_UNIQ) {
@@ -7387,6 +7492,7 @@
}
unres->type[i] = UNRES_RESOLVED;
+
++(*resolved);
++res_count;
} else if ((rc == EXIT_FAILURE) && forward_ref) {
@@ -7400,7 +7506,8 @@
if (forward_ref) {
ly_ilo_restore(ctx, prev_ilo, prev_eitem, 1);
}
- return -1;
+ ret = -1;
+ goto finish;
}
}
}
@@ -7416,7 +7523,8 @@
resolve_unres_schema_item(unres->module[i], unres->item[i], unres->type[i], unres->str_snode[i], unres);
}
}
- return -1;
+ ret = -1;
+ goto finish;
}
if (forward_ref) {
@@ -7425,6 +7533,17 @@
ly_errno = prev_ly_errno;
}
+ if ((types & UNRES_EXT)) {
+ assert(ext_parents->number == ext_par_types->number);
+ for (i = 0; i < ext_parents->number; ++i) {
+ ret = compact_ext_list(ctx, ext_parents->set.g[i], (LYEXT_PAR)ext_parents->set.g[i]);
+ LY_CHECK_GOTO(ret == -1, finish);
+ }
+ }
+
+finish:
+ ly_set_free(ext_parents);
+ ly_set_free(ext_par_types);
return ret;
}
@@ -7552,6 +7671,9 @@
rc = resolve_unres_schema_item(mod, item, type, snode, unres);
if (rc != EXIT_FAILURE) {
+ if (type == UNRES_EXT) {
+ free_ext_data(mod->ctx, (struct unres_ext*)snode);
+ }
ly_ilo_restore(ctx, prev_ilo, prev_eitem, rc == -1 ? 1 : 0);
if (rc != -1) {
/* print warnings here so that they are actually printed */
diff --git a/src/yang.y.in b/src/yang.y.in
index 5886e4c..99b2bf6 100644
--- a/src/yang.y.in
+++ b/src/yang.y.in
@@ -4646,7 +4646,7 @@
if (yang_fill_type(trg, &tpdf->type, (struct yang_type *)tpdf->type.der, tpdf, param->unres)) {
yang_type_free(trg->ctx, &tpdf->type);
}
- if (yang_check_ext_instance(trg, &tpdf->ext, tpdf->ext_size, tpdf, param->unres)) {
+ if (yang_check_ext_instance(trg, &tpdf->ext, &tpdf->ext_size, tpdf, param->unres)) {
YYABORT;
}
if (unres_schema_add_node(trg, param->unres, &tpdf->type, UNRES_TYPE_DER_TPDF, (struct lys_node *)ext_instance) == -1) {
@@ -4796,7 +4796,7 @@
if (yang_fill_iffeature(trg, iffeature, ext_instance, s, param->unres, 0)) {
YYABORT;
}
- if (yang_check_ext_instance(trg, &iffeature->ext, iffeature->ext_size, iffeature, param->unres)) {
+ if (yang_check_ext_instance(trg, &iffeature->ext, &iffeature->ext_size, iffeature, param->unres)) {
YYABORT;
}
s = NULL;
@@ -4804,13 +4804,13 @@
}
| ext_substatements argument_stmt stmtsep
| ext_substatements restriction_ext_alloc restriction_ext_stmt stmtsep
- { if (yang_check_ext_instance(trg, &((struct lys_restr *)$2)->ext, ((struct lys_restr *)$2)->ext_size, $2, param->unres)) {
+ { if (yang_check_ext_instance(trg, &((struct lys_restr *)$2)->ext, &((struct lys_restr *)$2)->ext_size, $2, param->unres)) {
YYABORT;
}
actual = ext_instance;
}
| ext_substatements when_ext_alloc when_stmt stmtsep
- { if (yang_check_ext_instance(trg, &(*(struct lys_when **)$2)->ext, (*(struct lys_when **)$2)->ext_size,
+ { if (yang_check_ext_instance(trg, &(*(struct lys_when **)$2)->ext, &(*(struct lys_when **)$2)->ext_size,
*(struct lys_when **)$2, param->unres)) {
YYABORT;
}
@@ -4825,7 +4825,7 @@
break;
}
}
- if (yang_check_ext_instance(trg, &$2.revision[$2.index]->ext, $2.revision[$2.index]->ext_size,
+ if (yang_check_ext_instance(trg, &$2.revision[$2.index]->ext, &$2.revision[$2.index]->ext_size,
&$2.revision[$2.index], param->unres)) {
YYABORT;
}
diff --git a/tests/schema/test_extensions.c b/tests/schema/test_extensions.c
index f79d07a..2c3f166 100644
--- a/tests/schema/test_extensions.c
+++ b/tests/schema/test_extensions.c
@@ -4340,6 +4340,121 @@
}
}
+
+void
+test_extension_skipped_yin(void **state)
+{
+ struct state *st = (*state);
+ const struct lys_module *mod;
+ const char *yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<module name=\"ext\"\n"
+ " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
+ " xmlns:x=\"urn:ext\"\n"
+ " xmlns:e=\"urn:ext-def\">\n"
+ " <yang-version value=\"1.1\"/>\n"
+ " <namespace uri=\"urn:ext\"/>\n"
+ " <prefix value=\"x\"/>\n"
+ " <import module=\"ext-def\">\n"
+ " <prefix value=\"e\"/>\n"
+ " </import>\n"
+ " <e:a/>\n"
+ " <e:skipped value=\"111\"/>\n"
+ " <e:b x=\"111\"/>\n"
+ " <container name=\"A\">\n"
+ " <e:skipped value=\"222\"/>\n"
+ " <e:a/>\n"
+ " <e:skipped value=\"222\"/>\n"
+ " <e:b x=\"222\"/>\n"
+ " <e:skipped value=\"222\">\n"
+ " <e:a/>\n"
+ " </e:skipped>\n"
+ " <leaf name=\"f\">\n"
+ " <type name=\"string\"/>\n"
+ " <e:skipped value=\"333\"/>\n"
+ " </leaf>\n"
+ " </container>\n"
+ "</module>\n";
+ const char *yin_skipped = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<module name=\"ext\"\n"
+ " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
+ " xmlns:x=\"urn:ext\"\n"
+ " xmlns:e=\"urn:ext-def\">\n"
+ " <yang-version value=\"1.1\"/>\n"
+ " <namespace uri=\"urn:ext\"/>\n"
+ " <prefix value=\"x\"/>\n"
+ " <import module=\"ext-def\">\n"
+ " <prefix value=\"e\"/>\n"
+ " </import>\n"
+ " <e:a/>\n"
+ " <e:b x=\"111\"/>\n"
+ " <container name=\"A\">\n"
+ " <e:a/>\n"
+ " <e:b x=\"222\"/>\n"
+ " <leaf name=\"f\">\n"
+ " <type name=\"string\"/>\n"
+ " </leaf>\n"
+ " </container>\n"
+ "</module>\n";
+
+ mod = lys_parse_mem(st->ctx, yin, LYS_IN_YIN);
+ assert_ptr_not_equal(mod, NULL);
+
+ lys_print_mem(&st->str1, mod, LYS_OUT_YIN, NULL, 0, 0);
+ assert_ptr_not_equal(st->str1, NULL);
+ assert_string_equal(st->str1, yin_skipped);
+}
+
+void
+test_extension_skipped_yang(void **state)
+{
+ struct state *st = (*state);
+ const struct lys_module *mod;
+ const char *yang = "module ext {\n"
+ " yang-version 1.1;\n"
+ " namespace \"urn:ext\";\n"
+ " prefix x;\n\n"
+ " import ext-def {\n prefix e;\n }\n\n"
+ " e:a;\n"
+ " e:skipped \"111\";\n"
+ " e:b \"111\";\n\n"
+ " container A {\n"
+ " e:skipped \"222\";\n"
+ " e:a;\n"
+ " e:skipped \"222\";\n"
+ " e:b \"222\";\n"
+ " e:skipped \"222\" {\n"
+ " e:a;\n"
+ " }\n"
+ " leaf f {\n"
+ " type string;\n"
+ " e:skipped \"333\";\n"
+ " }\n"
+ " }\n"
+ "}\n";
+ const char *yang_skipped = "module ext {\n"
+ " yang-version 1.1;\n"
+ " namespace \"urn:ext\";\n"
+ " prefix x;\n\n"
+ " import ext-def {\n prefix e;\n }\n\n"
+ " e:a;\n"
+ " e:b \"111\";\n\n"
+ " container A {\n"
+ " e:a;\n"
+ " e:b \"222\";\n"
+ " leaf f {\n"
+ " type string;\n"
+ " }\n"
+ " }\n"
+ "}\n";
+
+ mod = lys_parse_mem(st->ctx, yang, LYS_IN_YANG);
+ assert_ptr_not_equal(mod, NULL);
+
+ lys_print_mem(&st->str1, mod, LYS_OUT_YANG, NULL, 0, 0);
+ assert_ptr_not_equal(st->str1, NULL);
+ assert_string_equal(st->str1, yang_skipped);
+}
+
int
main(void)
{
@@ -4362,6 +4477,7 @@
cmocka_unit_test_setup_teardown(test_complex_many_instace_yin, setup_ctx_yin, teardown_ctx),
cmocka_unit_test_setup_teardown(test_complex_arrays_str_yin, setup_ctx_yin, teardown_ctx),
cmocka_unit_test_setup_teardown(test_extension_yang_data_yin, setup_ctx_yin, teardown_ctx),
+ cmocka_unit_test_setup_teardown(test_extension_skipped_yin, setup_ctx_yin, teardown_ctx),
cmocka_unit_test_setup_teardown(test_module_sub_yang, setup_ctx_yang, teardown_ctx),
cmocka_unit_test_setup_teardown(test_container_sub_yang, setup_ctx_yang, teardown_ctx),
@@ -4380,7 +4496,8 @@
cmocka_unit_test_setup_teardown(test_complex_mand_yang, setup_ctx_yang, teardown_ctx),
cmocka_unit_test_setup_teardown(test_complex_many_instace_yang, setup_ctx_yang, teardown_ctx),
cmocka_unit_test_setup_teardown(test_complex_arrays_str_yang, setup_ctx_yang, teardown_ctx),
- cmocka_unit_test_setup_teardown(test_extension_yang_data_yang, setup_ctx_yang, teardown_ctx)
+ cmocka_unit_test_setup_teardown(test_extension_yang_data_yang, setup_ctx_yang, teardown_ctx),
+ cmocka_unit_test_setup_teardown(test_extension_skipped_yang, setup_ctx_yang, teardown_ctx)
};
return cmocka_run_group_tests(cmut, NULL, NULL);
diff --git a/tests/schema/yang/files/ext-def.yang b/tests/schema/yang/files/ext-def.yang
index a46b69f..4753d55 100644
--- a/tests/schema/yang/files/ext-def.yang
+++ b/tests/schema/yang/files/ext-def.yang
@@ -23,6 +23,10 @@
extension complex-mand;
+ extension skipped {
+ argument value;
+ }
+
typedef mystring {
type string;
}
diff --git a/tests/schema/yin/files/ext-def.yin b/tests/schema/yin/files/ext-def.yin
index f1c1606..7cf36b2 100644
--- a/tests/schema/yin/files/ext-def.yin
+++ b/tests/schema/yin/files/ext-def.yin
@@ -18,6 +18,9 @@
<extension name="complex"/>
<extension name="complex-arrays"/>
<extension name="complex-mand"/>
+ <extension name="skipped">
+ <argument name="value"/>
+ </extension>
<typedef name="mystring">
<type name="string"/>
</typedef>