Skip to content

Commit

Permalink
schema parsers BUGFIX handle "unbounded" as a valid value for max-ele…
Browse files Browse the repository at this point in the history
…ments

Fixes #25
  • Loading branch information
rkrejci authored and PavolVican committed Feb 21, 2016
1 parent 2f94aa0 commit 1f0482e
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 49 deletions.
92 changes: 55 additions & 37 deletions src/parser_yin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
21 changes: 15 additions & 6 deletions src/printer_yang.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}

Expand Down Expand Up @@ -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) {
Expand Down
20 changes: 14 additions & 6 deletions src/printer_yin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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--;
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions src/tree_schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit 1f0482e

Please sign in to comment.