From a97a06d15a128747e3f3f94dd7b4fabef436a8db Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 24 Jan 2024 23:16:57 +0100 Subject: [PATCH] Fixed: [yang_enum_int_value() fails if no explicit values are assigned to enums](https://github.com/clicon/clixon/issues/483) --- CHANGELOG.md | 2 ++ lib/src/clixon_xml_map.c | 19 +++++++++----- lib/src/clixon_yang.c | 48 ++++++++++++++++++++++++++++++++-- lib/src/clixon_yang_internal.h | 1 + 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9221b96..5a6c2343 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,8 @@ Developers may need to change their code ### Corrected Bugs +* Fixed: [yang_enum_int_value() fails if no explicit values are assigned to enums](https://github.com/clicon/clixon/issues/483) + Remaining work: `yang_enum2valstr()` * Fixed: [show compare/diff problems with sorted-by user](https://github.com/clicon/clixon/issues/482) * Fixed: [Choice and Leafref](https://github.com/clicon/clixon/issues/469) * Fixed: [Problem deleting non-last list element if ordered-by user](https://github.com/clicon/clixon/issues/475) diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index f013f68f..4920fa1b 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -1519,6 +1519,9 @@ yang_valstr2enum(yang_stmt *ytype, * @retval 1 OK, result in valstr * @retval 0 Invalid, not found * @retval -1 Error + * @note does not handle implicit values + * @see yang_enum2int handles implicit values + * @note does not handle implicit values, see yang_enum_int_value which does */ int yang_enum2valstr(yang_stmt *ytype, @@ -1570,8 +1573,8 @@ yang_enum_int_value(cxobj *node, yang_stmt *ys; yang_stmt *ytype; yang_stmt *yrestype; /* resolved type */ - char *reason = NULL; - char *intstr = NULL; + yang_stmt *yenum; + cg_var *cv; if (node == NULL) goto done; @@ -1588,13 +1591,17 @@ yang_enum_int_value(cxobj *node, clixon_err(OE_YANG, 0, "result-type should not be NULL"); goto done; } - if (yrestype==NULL || strcmp(yang_argument_get(yrestype), "enumeration")) + if (strcmp(yang_argument_get(yrestype), "enumeration")) goto done; - if (yang_enum2valstr(yrestype, xml_body(node), &intstr) < 0) + if ((yenum = yang_find(yrestype, Y_ENUM, xml_body(node))) == NULL){ + clixon_err(OE_YANG, 0, "No such enum: %s", xml_body(node)); goto done; - /* reason is string containing why int could not be parsed */ - if (parse_int32(intstr, val, &reason) < 0) + } + if ((cv = yang_cv_get(yenum)) == NULL){ + clixon_err(OE_YANG, 0, "Enum lacks cv"); goto done; + } + *val = cv_int32_get(cv); retval = 0; done: return retval; diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index 0a614de9..b3a8d540 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -2563,6 +2563,47 @@ ys_populate_length(clixon_handle h, return retval; } +/*! Assign enum values + * + * @param[in] h Clixon handle + * @param[in] ys The yang statement (type) to populate. + * @retval 0 OK + * @retval -1 Error + */ +static int +ys_populate_type_enum(clixon_handle h, + yang_stmt *ys) +{ + int retval = -1; + + yang_stmt *yenum = NULL; + yang_stmt *yval; + char *valstr; + int v; + int i = 0; + cg_var *cv = NULL; + + yenum = NULL; + while ((yenum = yn_each(ys, yenum)) != NULL) { + if ((cv = cv_new(CGV_INT32)) == NULL){ + clixon_err(OE_YANG, errno, "cv_new"); + goto done; + } + if ((yval = yang_find(yenum, Y_VALUE, NULL)) != NULL){ + valstr = yang_argument_get(yval); + if (parse_int32(valstr, &v, NULL) < 0) + goto done; + if (v > i) + i = v; + } + cv_int32_set(cv, i++); + yang_cv_set(yenum, cv); + } + retval = 0; + done: + return retval; +} + /*! Sanity check yang type statement * * XXX: Replace with generic parent/child type-check @@ -2585,8 +2626,7 @@ ys_populate_type(clixon_handle h, goto done; } } - else - if (strcmp(ys->ys_argument, "identityref") == 0){ + else if (strcmp(ys->ys_argument, "identityref") == 0){ if ((ybase = yang_find(ys, Y_BASE, NULL)) == NULL){ clixon_err(OE_YANG, 0, "identityref type requires base sub-statement"); goto done; @@ -2597,6 +2637,10 @@ ys_populate_type(clixon_handle h, goto done; } } + else if (strcmp(ys->ys_argument, "enumeration") == 0){ + if (ys_populate_type_enum(h, ys) < 0) + goto done; + } retval = 0; done: return retval; diff --git a/lib/src/clixon_yang_internal.h b/lib/src/clixon_yang_internal.h index 16fbd815..28b8d0ad 100644 --- a/lib/src/clixon_yang_internal.h +++ b/lib/src/clixon_yang_internal.h @@ -91,6 +91,7 @@ struct yang_stmt{ revision (uint32) unknown-stmt (optional argument) spec: mount-point xpath + enum: value */ cvec *ys_cvec; /* List of stmt-specific variables Y_RANGE: range_min, range_max