parser yang BUGFIX checking if-feature in enum and bit statement
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 31b668e..667ed4e 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -230,7 +230,8 @@
}
int
-yang_read_if_feature(struct lys_module *module, void *ptr, char *value, struct unres_schema *unres, enum yytokentype type)
+yang_read_if_feature(struct lys_module *module, void *ptr, void *parent, char *value,
+ struct unres_schema *unres, enum yytokentype type)
{
const char *exp;
int ret;
@@ -265,15 +266,13 @@
i->iffeature_size++;
break;
case ENUM_KEYWORD:
- e = &((struct yang_type *)ptr)->type->info.enums.enm[((struct yang_type *)ptr)->type->info.enums.count - 1];
- ret = resolve_iffeature_compile(&e->iffeature[e->iffeature_size], exp,
- (struct lys_node *)((struct yang_type *)ptr)->type->parent, 0, unres);
+ e = (struct lys_type_enum *) ptr;
+ ret = resolve_iffeature_compile(&e->iffeature[e->iffeature_size], exp, (struct lys_node *) parent, 0, unres);
e->iffeature_size++;
break;
case BIT_KEYWORD:
- b = &((struct yang_type *)ptr)->type->info.bits.bit[((struct yang_type *)ptr)->type->info.bits.count - 1];
- ret = resolve_iffeature_compile(&b->iffeature[b->iffeature_size], exp,
- (struct lys_node *)((struct yang_type *)ptr)->type->parent, 0, unres);
+ b = (struct lys_type_bit *) ptr;
+ ret = resolve_iffeature_compile(&b->iffeature[b->iffeature_size], exp, (struct lys_node *) parent, 0, unres);
b->iffeature_size++;
break;
case REFINE_KEYWORD:
@@ -1427,6 +1426,7 @@
{
int i, j;
+ typ->base = LY_TYPE_ENUM;
if (!value[0]) {
LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
@@ -2918,6 +2918,50 @@
return EXIT_FAILURE;
}
+static int
+yang_check_type_iffeature(struct lys_module *module, struct unres_schema *unres, struct lys_type *type)
+{
+ uint i, j, size;
+ uint8_t iffeature_size;
+ LY_DATA_TYPE stype;
+
+ if (((struct yang_type *)type->der)->base == LY_TYPE_ENUM) {
+ stype = LY_TYPE_ENUM;
+ size = type->info.enums.count;
+ } else if (((struct yang_type *)type->der)->base == LY_TYPE_BITS) {
+ stype = LY_TYPE_ENUM;
+ size = type->info.enums.count;
+ } else {
+ return EXIT_SUCCESS;
+ }
+
+ for (i = 0; i < size; ++i) {
+ if (stype == LY_TYPE_ENUM) {
+ iffeature_size = type->info.enums.enm[i].iffeature_size;
+ type->info.enums.enm[i].iffeature_size = 0;
+ for (j = 0; j < iffeature_size; ++j) {
+ if (yang_read_if_feature(module, &type->info.enums.enm[i], type->parent,
+ (char *)type->info.enums.enm[i].iffeature[j].features, unres, ENUM_KEYWORD)) {
+ goto error;
+ }
+ }
+ } else {
+ iffeature_size = type->info.bits.bit[i].iffeature_size;
+ type->info.bits.bit[i].iffeature_size = 0;
+ for (j = 0; j < iffeature_size; ++j) {
+ if (yang_read_if_feature(module, &type->info.bits.bit[i], type->parent,
+ (char *)type->info.bits.bit[i].iffeature[j].features, unres, BIT_KEYWORD)) {
+ goto error;
+ }
+ }
+ }
+ }
+
+ return EXIT_SUCCESS;
+error:
+ return EXIT_FAILURE;
+}
+
int
yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
{
@@ -2935,6 +2979,10 @@
for (i = 0; i < tpdf_size; ++i) {
tpdf[i].type.parent = &tpdf[i];
+ if (yang_check_type_iffeature(module, unres, &tpdf[i].type)) {
+ ret = EXIT_FAILURE;
+ break;
+ }
if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
ret = EXIT_FAILURE;
break;
@@ -2973,7 +3021,7 @@
feature->iffeature_size = 0;
for (j = 0; j < size; ++j) {
s = (char *)feature->iffeature[j].features;
- if (yang_read_if_feature(module, feature, s, unres, FEATURE_KEYWORD)) {
+ if (yang_read_if_feature(module, feature, NULL, s, unres, FEATURE_KEYWORD)) {
goto error;
}
if (unres_schema_add_node(module, unres, feature, UNRES_FEATURE, NULL) == -1) {
diff --git a/src/parser_yang.h b/src/parser_yang.h
index c785b57..56c09ee 100644
--- a/src/parser_yang.h
+++ b/src/parser_yang.h
@@ -137,7 +137,7 @@
void yang_read_revision(struct lys_module *module, char *value, struct lys_revision *retval);
-int yang_read_if_feature(struct lys_module *module, void *ptr, char *value, struct unres_schema *unres, enum yytokentype type);
+int yang_read_if_feature(struct lys_module *module, void *ptr, void *parent, char *value, struct unres_schema *unres, enum yytokentype type);
void *yang_read_identity(struct lys_module *module, char *value);
diff --git a/src/yang.y.in b/src/yang.y.in
index 99868ae..115d6f5 100644
--- a/src/yang.y.in
+++ b/src/yang.y.in
@@ -913,7 +913,7 @@
}
}
| identity_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, actual, s, unres, IDENTITY_KEYWORD)) {
+ if (yang_read_if_feature(trg, actual, NULL, s, unres, IDENTITY_KEYWORD)) {
YYABORT;
}
s=NULL;
@@ -1274,7 +1274,6 @@
enum_specification: enum_stmt stmtsep enum_stmts { struct lys_type_enum * tmp;
- ((struct yang_type *)actual)->base = LY_TYPE_ENUM;
cnt_val = 0;
tmp = realloc(((struct yang_type *)actual)->type->info.enums.enm,
((struct yang_type *)actual)->type->info.enums.count * sizeof *tmp);
@@ -1684,7 +1683,7 @@
| container_opt_stmt when_stmt { actual = $1.container; actual_type = CONTAINER_KEYWORD; }
stmtsep
| container_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.container, s, unres, CONTAINER_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.container, NULL, s, unres, CONTAINER_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -1830,7 +1829,7 @@
| leaf_opt_stmt when_stmt { actual = $1.node.ptr_leaf; actual_type = LEAF_KEYWORD; }
stmtsep
| leaf_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.node.ptr_leaf, s, unres, LEAF_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.node.ptr_leaf, NULL, s, unres, LEAF_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -1982,7 +1981,7 @@
| leaf_list_opt_stmt when_stmt { actual = $1.node.ptr_leaflist; actual_type = LEAF_LIST_KEYWORD; }
stmtsep
| leaf_list_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.node.ptr_leaflist, s, unres, LEAF_LIST_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.node.ptr_leaflist, NULL, s, unres, LEAF_LIST_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -2175,7 +2174,7 @@
| list_opt_stmt when_stmt { actual = $1.node.ptr_list; actual_type = LIST_KEYWORD; }
stmtsep
| list_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.node.ptr_list, s, unres, LIST_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.node.ptr_list, NULL, s, unres, LIST_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -2366,7 +2365,7 @@
| choice_opt_stmt when_stmt { actual = $1.node.ptr_choice; actual_type = CHOICE_KEYWORD; }
stmtsep { $$ = $1; }
| choice_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.node.ptr_choice, s, unres, CHOICE_KEYWORD)) {
+ if (yang_read_if_feature(trg, $1.node.ptr_choice, NULL, s, unres, CHOICE_KEYWORD)) {
YYABORT;
}
s=NULL;
@@ -2516,7 +2515,7 @@
| case_opt_stmt when_stmt { actual = $1.cs; actual_type = CASE_KEYWORD; }
stmtsep
| case_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.cs, s, unres, CASE_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.cs, NULL, s, unres, CASE_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -2622,7 +2621,7 @@
}
stmtsep
| anyxml_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.node.ptr_anydata, s, unres, $1.node.flag)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.node.ptr_anydata, NULL, s, unres, $1.node.flag)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -2733,7 +2732,7 @@
| uses_opt_stmt when_stmt { actual = $1.uses; actual_type = USES_KEYWORD; }
stmtsep
| uses_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.uses, s, unres, USES_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.uses, NULL, s, unres, USES_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -2873,7 +2872,7 @@
}
}
| refine_body_opt_stmts if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, refine_parent, s, unres, REFINE_KEYWORD)) {
+ if (yang_read_if_feature(trg, refine_parent, NULL, s, unres, REFINE_KEYWORD)) {
YYABORT;
}
s=NULL;
@@ -3099,7 +3098,7 @@
| augment_opt_stmt when_stmt { actual = $1.node.ptr_augment; actual_type = AUGMENT_KEYWORD; }
stmtsep
| augment_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.node.ptr_augment, s, unres, AUGMENT_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.node.ptr_augment, NULL, s, unres, AUGMENT_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -3229,7 +3228,7 @@
}
}
| rpc_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.node.ptr_rpc, s, unres, RPC_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.node.ptr_rpc, NULL, s, unres, RPC_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;
@@ -3473,7 +3472,7 @@
}
stmtsep
| notification_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.notif, s, unres, NOTIFICATION_KEYWORD)) {YYABORT;}
+ if (yang_read_if_feature(trg, $1.notif, NULL, s, unres, NOTIFICATION_KEYWORD)) {YYABORT;}
s=NULL;
} else {
size_arrays->node[$1.index].if_features++;