diff --git a/src/parser_yin.c b/src/parser_yin.c index 6c009c633..c8047b08a 100644 --- a/src/parser_yin.c +++ b/src/parser_yin.c @@ -1154,18 +1154,22 @@ deviate_minmax(struct lys_node *target, struct lyxml_elem *node, struct lys_devi value++; } - /* convert it to uint32_t */ - errno = 0; - endptr = NULL; - val = strtoul(value, &endptr, 10); - if (*endptr || value[0] == '-' || errno || val > UINT32_MAX) { - LOGVAL(LYE_INARG, LOGLINE(node), value, node->name); - goto error; - } - if (type) { - d->max = (uint32_t)val; + if (type && !strcmp(value, "unbounded")) { + d->max = val = 0; } else { - d->min = (uint32_t)val; + /* convert it to uint32_t */ + errno = 0; + endptr = NULL; + val = strtoul(value, &endptr, 10); + if (*endptr || value[0] == '-' || errno || val > UINT32_MAX) { + LOGVAL(LYE_INARG, LOGLINE(node), value, node->name); + goto error; + } + if (type) { + d->max = (uint32_t)val; + } else { + d->min = (uint32_t)val; + } } if (d->mod == LY_DEVIATE_ADD) { @@ -1206,7 +1210,7 @@ fill_yin_deviation(struct lys_module *module, struct lyxml_elem *yin, struct lys const char *value, **stritem; struct lyxml_elem *next, *child, *develem; int c_dev = 0, c_must, c_uniq; - int f_min = 0; /* flags */ + int f_min = 0, f_max = 0; /* flags */ int i, j, rc; struct ly_ctx *ctx; struct lys_deviate *d = NULL; @@ -1292,6 +1296,7 @@ fill_yin_deviation(struct lys_module *module, struct lyxml_elem *yin, struct lys LY_TREE_FOR(yin->child, develem) { /* init */ f_min = 0; + f_max = 0; c_must = 0; c_uniq = 0; @@ -1517,10 +1522,11 @@ fill_yin_deviation(struct lys_module *module, struct lyxml_elem *yin, struct lys goto error; } } else if (!strcmp(child->name, "max-elements")) { - if (d->max) { + if (f_max) { LOGVAL(LYE_TOOMANY, LOGLINE(child), child->name, yin->name); goto error; } + f_max = 1; if (deviate_minmax(dev_target, child, d, 1)) { goto error; @@ -2130,15 +2136,19 @@ fill_yin_refine(struct lys_module *module, struct lyxml_elem *yin, struct lys_re value++; } - /* convert it to uint32_t */ - errno = 0; - endptr = NULL; - val = strtoul(value, &endptr, 10); - if (*endptr || value[0] == '-' || errno || val == 0 || val > UINT32_MAX) { - LOGVAL(LYE_INARG, LOGLINE(sub), value, sub->name); - goto error; + if (!strcmp(value, "unbounded")) { + rfn->mod.list.max = 0; + } else { + /* convert it to uint32_t */ + errno = 0; + endptr = NULL; + val = strtoul(value, &endptr, 10); + if (*endptr || value[0] == '-' || errno || val == 0 || val > UINT32_MAX) { + LOGVAL(LYE_INARG, LOGLINE(sub), value, sub->name); + goto error; + } + rfn->mod.list.max = (uint32_t) val; } - rfn->mod.list.max = (uint32_t) val; /* magic - bit 4 in flags means min set */ rfn->flags |= 0x08; @@ -3368,15 +3378,19 @@ read_yin_leaflist(struct lys_module *module, struct lys_node *parent, struct lyx value++; } - /* convert it to uint32_t */ - errno = 0; - endptr = NULL; - val = strtoul(value, &endptr, 10); - if (*endptr || value[0] == '-' || errno || val == 0 || val > UINT32_MAX) { - LOGVAL(LYE_INARG, LOGLINE(sub), value, sub->name); - goto error; + if (!strcmp(value, "unbounded")) { + llist->max = 0; + } else { + /* convert it to uint32_t */ + errno = 0; + endptr = NULL; + val = strtoul(value, &endptr, 10); + if (*endptr || value[0] == '-' || errno || val == 0 || val > UINT32_MAX) { + LOGVAL(LYE_INARG, LOGLINE(sub), value, sub->name); + goto error; + } + llist->max = (uint32_t) val; } - llist->max = (uint32_t) val; } else if (!strcmp(sub->name, "when")) { if (llist->when) { LOGVAL(LYE_TOOMANY, LOGLINE(sub), sub->name, yin->name); @@ -3612,15 +3626,19 @@ read_yin_list(struct lys_module *module, struct lys_node *parent, struct lyxml_e value++; } - /* convert it to uint32_t */ - errno = 0; - auxs = NULL; - val = strtoul(value, &auxs, 10); - if (*auxs || value[0] == '-' || errno || val == 0 || val > UINT32_MAX) { - LOGVAL(LYE_INARG, LOGLINE(sub), value, sub->name); - goto error; + if (!strcmp(value, "unbounded")) { + list->max = 0;; + } else { + /* convert it to uint32_t */ + errno = 0; + auxs = NULL; + val = strtoul(value, &auxs, 10); + if (*auxs || value[0] == '-' || errno || val == 0 || val > UINT32_MAX) { + LOGVAL(LYE_INARG, LOGLINE(sub), value, sub->name); + goto error; + } + list->max = (uint32_t) val; } - list->max = (uint32_t) val; lyxml_free(module->ctx, sub); } else if (!strcmp(sub->name, "when")) { if (list->when) { diff --git a/src/printer_yang.c b/src/printer_yang.c index 57345b0ae..bbf13bd6b 100644 --- a/src/printer_yang.c +++ b/src/printer_yang.c @@ -460,11 +460,16 @@ yang_print_refine(struct lyout *out, int level, const struct lys_module *module, yang_print_text(out, level, "presence", refine->mod.presence, 1); } } else if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) { - if (refine->mod.list.min > 0) { + /* magic - bit 3 in flags means min set, bit 4 says max set */ + if (refine->flags & 0x04) { ly_print(out, "%*smin-elements %u;\n", LEVEL, INDENT, refine->mod.list.min); } - if (refine->mod.list.max > 0) { - ly_print(out, "%*smax-elements %u;\n", LEVEL, INDENT, refine->mod.list.max); + if (refine->flags & 0x08) { + if (refine->mod.list.max) { + ly_print(out, "%*smax-elements %u;\n", LEVEL, INDENT, refine->mod.list.max); + } else { + ly_print(out, "%*smax-elements \"unbounded\";\n", LEVEL, INDENT); + } } } @@ -520,11 +525,15 @@ yang_print_deviation(struct lyout *out, int level, const struct lys_module *modu ly_print(out, "%*sdefault %s;\n", LEVEL, INDENT, deviation->deviate[i].dflt); } - if (deviation->deviate[i].min) { + if (deviation->deviate[i].min_set) { ly_print(out, "%*smin-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].min); } - if (deviation->deviate[i].max) { - ly_print(out, "%*smax-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].max); + if (deviation->deviate[i].max_set) { + if (deviation->deviate[i].max) { + ly_print(out, "%*smax-elements %u;\n", LEVEL, INDENT, deviation->deviate[i].max); + } else { + ly_print(out, "%*smax-elements \"unbounded\";\n", LEVEL, INDENT); + } } for (j = 0; j < deviation->deviate[i].must_size; ++j) { diff --git a/src/printer_yin.c b/src/printer_yin.c index 37ea69dc8..2f126948a 100644 --- a/src/printer_yin.c +++ b/src/printer_yin.c @@ -526,11 +526,15 @@ yin_print_refine(struct lyout *out, int level, const struct lys_module *module, yin_print_open(out, "presence", "value", refine->mod.presence, level, 1); } } else if (refine->target_type & (LYS_LIST | LYS_LEAFLIST)) { - if (refine->mod.list.min > 0) { + if (refine->flags & 0x04) { yin_print_unsigned(out, "min-elements", "value", refine->mod.list.min, level); } - if (refine->mod.list.max > 0) { - yin_print_unsigned(out, "max-elements", "value", refine->mod.list.max, level); + if (refine->flags & 0x08) { + if (refine->mod.list.max) { + yin_print_unsigned(out, "max-elements", "value", refine->mod.list.max, level); + } else { + yin_print_open(out, "max-elements", "value", "unbounded", level, 1); + } } } level--; @@ -586,11 +590,15 @@ yin_print_deviation(struct lyout *out, int level, const struct lys_module *modul yin_print_open(out, "default", "value", deviation->deviate[i].dflt, level, 1); } - if (deviation->deviate[i].min) { + if (deviation->deviate[i].min_set) { yin_print_unsigned(out, "min-elements", "value", deviation->deviate[i].min, level); } - if (deviation->deviate[i].max) { - yin_print_unsigned(out, "max-elements", "value", deviation->deviate[i].max, level); + if (deviation->deviate[i].max_set) { + if (deviation->deviate[1].max) { + yin_print_unsigned(out, "max-elements", "value", deviation->deviate[1].max, level); + } else { + yin_print_open(out, "max-elements", "value", "unbounded", level, 1); + } } for (j = 0; j < deviation->deviate[i].must_size; ++j) { diff --git a/src/tree_schema.h b/src/tree_schema.h index 3367baf3c..a4cdb20b4 100644 --- a/src/tree_schema.h +++ b/src/tree_schema.h @@ -1098,6 +1098,8 @@ struct lys_deviate { const char *dflt; /**< Properties: default (both type and choice represented as string value */ uint32_t min; /**< Properties: min-elements */ uint32_t max; /**< Properties: max-elements */ + uint8_t min_set; /**< Since min can be 0, this flag says if it is default value or 0 was set */ + uint8_t max_set; /**< Since max can be 0, this flag says if it is default value or 0 (unbounded) was set */ uint8_t must_size; /**< Properties: must - number of elements in the #must array */ uint8_t unique_size; /**< Properties: unique - number of elements in the #unique array */ struct lys_restr *must; /**< Properties: must - array of must constraints */