resolve BUGFIX derived type resolution
Check that resolved types are resolved
themselves first. If not, we need to
store away an unparsed YIN segment,
unfortunately. lyxml_* bugfixes included.
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 12e74b0..362073e 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -469,12 +469,11 @@
return EXIT_FAILURE;
}
-/* logs directly */
-static int
+/* logs directly, returns EXIT_SUCCESS, EXIT_FAILURE, -1 */
+int
fill_yin_type(struct lys_module *module, struct lys_node *parent, struct lyxml_elem *yin, struct lys_type *type,
struct unres_schema *unres)
{
-#define REGEX_ERR_LEN 128
const char *value, *name, *err_ptr;
struct lyxml_elem *next, *node;
struct lys_restr **restr;
@@ -493,6 +492,7 @@
i = parse_identifier(value);
if (i < 1) {
LOGVAL(LYE_INCHAR, LOGLINE(yin), value[-i], &value[-i]);
+ lydict_remove(module->ctx, value);
goto error;
}
/* module name */
@@ -501,24 +501,21 @@
value += i;
if ((value[0] != ':') || (parse_identifier(value + 1) < 1)) {
LOGVAL(LYE_INCHAR, LOGLINE(yin), value[0], value);
+ lydict_remove(module->ctx, value);
goto error;
}
++value;
}
rc = resolve_superior_type(value, type->module_name, module, parent, &type->der);
+ lydict_remove(module->ctx, value);
if (rc == -1) {
LOGVAL(LYE_INMOD, LOGLINE(yin), type->module_name);
goto error;
+
+ /* the type could not be resolved or it was resolved to an unresolved typedef */
} else if (rc == EXIT_FAILURE) {
- /* HACK for unres */
- type->der = (struct lys_tpdf *)parent;
- rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_DER, value, LOGLINE(yin));
- if (rc == -1) {
- goto error;
- } else {
- return EXIT_SUCCESS;
- }
+ return EXIT_FAILURE;
}
type->base = type->der->type.base;
@@ -939,7 +936,7 @@
continue;
}
- if (!strcmp(node->name, "path")) {
+ if (!strcmp(node->name, "path") && !type->der->type.der) {
if (type->info.lref.path) {
LOGVAL(LYE_TOOMANY, LOGLINE(node), node->name, yin->name);
goto error;
@@ -961,11 +958,7 @@
}
}
- if (!type->info.lref.path) {
- if (type->der->type.der) {
- /* this is just a derived type with no path specified/required */
- break;
- }
+ if (!type->info.lref.path && !type->der->type.der) {
LOGVAL(LYE_MISSSTMT2, LOGLINE(yin), "path", "type");
goto error;
}
@@ -1056,7 +1049,7 @@
if (!i) {
if (type->der->type.der) {
- /* this is just a derived type with no base specified/required */
+ /* this is just a derived type with no additional type specified/required */
break;
}
LOGVAL(LYE_MISSSTMT2, LOGLINE(yin), "type", "(union) type");
@@ -1067,40 +1060,56 @@
type->info.uni.types = calloc(i, sizeof *type->info.uni.types);
/* ... and fill the structures */
LY_TREE_FOR(yin->child, node) {
- if (fill_yin_type(module, parent, node, &type->info.uni.types[type->info.uni.count], unres)) {
+ rc = fill_yin_type(module, parent, node, &type->info.uni.types[type->info.uni.count], unres);
+ if (!rc) {
+ type->info.uni.count++;
+
+ /* union's type cannot be empty or leafref */
+ if (type->info.uni.types[type->info.uni.count - 1].base == LY_TYPE_EMPTY) {
+ LOGVAL(LYE_INARG, LOGLINE(node), "empty", node->name);
+ rc = -1;
+ } else if (type->info.uni.types[type->info.uni.count - 1].base == LY_TYPE_LEAFREF) {
+ LOGVAL(LYE_INARG, LOGLINE(node), "leafref", node->name);
+ rc = -1;
+ }
+ }
+ if (rc) {
+ /* even if we got EXIT_FAILURE, throw it all away, too much trouble doing something else */
+ for (i = 0; i < type->info.uni.count; ++i) {
+ lys_type_free(module->ctx, &type->info.uni.types[i]);
+ }
+ free(type->info.uni.types);
+ type->info.uni.types = NULL;
+ type->info.uni.count = 0;
+
+ if (rc == EXIT_FAILURE) {
+ return EXIT_FAILURE;
+ }
goto error;
}
- type->info.uni.count++;
+ }
+ break;
- /* union's type cannot be empty or leafref */
- if (type->info.uni.types[type->info.uni.count - 1].base == LY_TYPE_EMPTY) {
- LOGVAL(LYE_INARG, LOGLINE(node), "empty", node->name);
- goto error;
- } else if (type->info.uni.types[type->info.uni.count - 1].base == LY_TYPE_LEAFREF) {
- LOGVAL(LYE_INARG, LOGLINE(node), "leafref", node->name);
+ case LY_TYPE_BOOL:
+ case LY_TYPE_EMPTY:
+ /* no sub-statement allowed */
+ LY_TREE_FOR(yin->child, node) {
+ if (node->ns && !strcmp(node->ns->value, LY_NSYIN)) {
+ LOGVAL(LYE_INSTMT, LOGLINE(node), node->name);
goto error;
}
}
break;
default:
- /* no sub-statement allowed in:
- * LY_TYPE_BOOL, LY_TYPE_EMPTY
- */
- LY_TREE_FOR(yin->child, node) {
- if (node->ns && !strcmp(node->ns->value, LY_NSYIN)) {
- LOGVAL(LYE_INSTMT, LOGLINE(yin->child), yin->child->name);
- goto error;
- }
- }
- break;
+ LOGINT;
+ goto error;
}
return EXIT_SUCCESS;
error:
-
- return EXIT_FAILURE;
+ return -1;
}
/* logs directly */
@@ -1108,7 +1117,7 @@
fill_yin_typedef(struct lys_module *module, struct lys_node *parent, struct lyxml_elem *yin, struct lys_tpdf *tpdf, struct unres_schema *unres)
{
const char *value;
- struct lyxml_elem *node;
+ struct lyxml_elem *node, *next;
int has_type = 0, dflt_line;
GETVAL(value, yin, "name");
@@ -1122,7 +1131,7 @@
goto error;
}
- LY_TREE_FOR(yin->child, node) {
+ LY_TREE_FOR_SAFE(yin->child, next, node) {
if (!node->ns || strcmp(node->ns->value, LY_NSYIN)) {
/* garbage */
continue;
@@ -1133,7 +1142,9 @@
LOGVAL(LYE_TOOMANY, LOGLINE(node), node->name, yin->name);
goto error;
}
- if (fill_yin_type(module, parent, node, &tpdf->type, unres)) {
+ /* HACK for unres */
+ tpdf->type.der = (struct lys_tpdf *)node;
+ if (unres_schema_add_node(module, unres, &tpdf->type, UNRES_TYPE_DER, parent, LOGLINE(node))) {
goto error;
}
has_type = 1;
@@ -1255,7 +1266,8 @@
}
static int
-fill_yin_unique(struct lys_module *module, struct lys_node *parent, struct lyxml_elem *yin, struct lys_unique *unique, struct unres_schema *unres)
+fill_yin_unique(struct lys_module *module, struct lys_node *parent, struct lyxml_elem *yin, struct lys_unique *unique,
+ struct unres_schema *unres)
{
int i, j;
const char *value, *vaux;
@@ -1397,7 +1409,8 @@
/* logs directly */
static int
-fill_yin_deviation(struct lys_module *module, struct lyxml_elem *yin, struct lys_deviation *dev)
+fill_yin_deviation(struct lys_module *module, struct lyxml_elem *yin, struct lys_deviation *dev,
+ struct unres_schema *unres)
{
const char *value, **stritem;
struct lyxml_elem *next, *child, *develem;
@@ -1752,7 +1765,9 @@
lys_type_free(dev->target->module->ctx, t);
/* ... and replace it with the value specified in deviation */
- if (fill_yin_type(module, dev->target, child, t, NULL)) {
+ /* HACK for unres */
+ t->der = (struct lys_tpdf *)child;
+ if (unres_schema_add_node(module, unres, t, UNRES_TYPE_DER, dev->target, LOGLINE(child))) {
goto error;
}
d->type = t;
@@ -1812,7 +1827,7 @@
goto error;
}
- lyxml_free_elem(module->ctx, child);
+ /* do not free sub, it could have been unlinked and stored in unres */
}
if (c_must) {
@@ -3200,7 +3215,10 @@
LOGVAL(LYE_TOOMANY, LOGLINE(sub), sub->name, yin->name);
goto error;
}
- if (fill_yin_type(module, parent, sub, &leaf->type, unres)) {
+ /* HACK for unres */
+ leaf->type.der = (struct lys_tpdf *)sub;
+ if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, parent, LOGLINE(sub))) {
+ leaf->type.der = NULL;
goto error;
}
has_type = 1;
@@ -3264,7 +3282,7 @@
goto error;
}
- lyxml_free_elem(module->ctx, sub);
+ /* do not free sub, it could have been unlinked and stored in unres */
}
/* check mandatory parameters */
@@ -3361,7 +3379,10 @@
LOGVAL(LYE_TOOMANY, LOGLINE(sub), sub->name, yin->name);
goto error;
}
- if (fill_yin_type(module, parent, sub, &llist->type, unres)) {
+ /* HACK for unres */
+ llist->type.der = (struct lys_tpdf *)sub;
+ if (unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DER, parent, LOGLINE(sub))) {
+ llist->type.der = NULL;
goto error;
}
has_type = 1;
@@ -3465,7 +3486,7 @@
goto error;
}
- lyxml_free_elem(module->ctx, sub);
+ /* do not free sub, it could have been unlinked and stored in unres */
}
/* check constraints */
@@ -4965,7 +4986,7 @@
}
} else if (!strcmp(child->name, "deviation")) {
- r = fill_yin_deviation(module, child, &module->deviation[module->deviation_size]);
+ r = fill_yin_deviation(module, child, &module->deviation[module->deviation_size], unres);
module->deviation_size++;
if (r) {