* Date-and-time type now properly uses ISO 8601 UTC timezone designators.

* Renamed yang file `ietf-netconf-notification@2008-07-01.yang` to `clixon-rfc5277`.
* Cligen uses posix regex while yang uses XSD. It differs in some aspects. A translator function has been added for `\d` -> `[0-9]` translation, there may be more.
* [ietf-netconf-notification@2008-07-01.yang validation problem #62](https://github.com/clicon/clixon/issues/62)
This commit is contained in:
Olof hagsand 2019-01-11 17:30:08 +01:00
parent 207858e20d
commit f48c8f45c6
16 changed files with 105 additions and 63 deletions

View file

@ -88,6 +88,7 @@ const char *clicon_int2str(const map_str2int *mstab, int i);
int clicon_str2int(const map_str2int *mstab, char *str);
int nodeid_split(char *nodeid, char **prefix, char **id);
char *clixon_trim(char *str);
int regexp_xsd2posix(char *xsd, char **posix);
#ifndef HAVE_STRNDUP
char *clicon_strndup (const char *, size_t);
#endif /* ! HAVE_STRNDUP */

View file

@ -67,7 +67,7 @@ int yang2cv_type(char *ytype, enum cv_type *cv_type);
char *cv2yang_type(enum cv_type cv_type);
yang_stmt *yang_find_identity(yang_stmt *ys, char *identity);
int ys_cv_validate(cg_var *cv, yang_stmt *ys, char **reason);
int clicon_type2cv(char *type, char *rtype, enum cv_type *cvtype);
int clicon_type2cv(char *type, char *rtype, yang_stmt *ys, enum cv_type *cvtype);
int yang_type_get(yang_stmt *ys, char **otype, yang_stmt **restype,
int *options, cvec **cvv, char **pattern,
uint8_t *fraction_digits);

View file

@ -1032,7 +1032,7 @@ netconf_module_load(clicon_handle h)
/* Load yang spec */
if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0)
goto done;
if (yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec)< 0)
if (yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done;
retval = 0;
done:

View file

@ -548,7 +548,7 @@ stream_notify(clicon_handle h,
yang_spec *yspec = NULL;
char *str = NULL;
cbuf *cb = NULL;
char timestr[27];
char timestr[28];
struct timeval tv;
event_stream_t *es;
@ -622,7 +622,7 @@ stream_notify_xml(clicon_handle h,
yang_spec *yspec = NULL;
char *str = NULL;
cbuf *cb = NULL;
char timestr[27];
char timestr[28];
struct timeval tv;
event_stream_t *es;

View file

@ -634,6 +634,51 @@ clixon_trim(char *str)
return s;
}
/*! Transform from XSD regex to posix ERE
* The usecase is that Yang (RFC7950) supports XSD regexpressions but CLIgen supports
* Current translations:
* \d --> [0-9]
* POSIX ERE regexps according to man regex(3).
* @param[in] xsd Input regex string according XSD
* @param[out] posix Output (malloced) string according to POSIX ERE
* @see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028
* @note that the translation is ad-hoc, may need more translations
*/
int
regexp_xsd2posix(char *xsd,
char **posix)
{
int retval = -1;
char *x;
char *p = NULL;
int i;
int len;
len = strlen(xsd);
x = xsd;
while ((x = strstr(x, "\\d")) != NULL){
len += 3; /* \d --> [0-9] */
x += 2;
}
if ((p = malloc(len+1)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
memset(p, 0, len+1);
*posix = p;
for (i=0; i<strlen(xsd); i++){
if (strncmp(&xsd[i], "\\d", 2) == 0){
strcpy(p, "[0-9]");
p += 5; i++;
}
else
*p++ = xsd[i];
}
retval = 0;
done:
return retval;
}
/*! strndup() for systems without it, such as xBSD
*/
#ifndef HAVE_STRNDUP

View file

@ -1082,7 +1082,7 @@ ys_populate_leaf(yang_stmt *ys,
< 0)
goto done;
restype = yrestype?yrestype->ys_argument:NULL;
if (clicon_type2cv(type, restype, &cvtype) < 0) /* This handles non-resolved also */
if (clicon_type2cv(type, restype, ys, &cvtype) < 0) /* This handles non-resolved also */
goto done;
/* 2. Create the CV using cvtype and name it */
if ((cv = cv_new(cvtype)) == NULL){
@ -1230,7 +1230,7 @@ ys_populate_range(yang_stmt *ys,
restype = yrestype?yrestype->ys_argument:NULL;
origtype = yarg_id((yang_stmt*)yparent);
/* This handles non-resolved also */
if (clicon_type2cv(origtype, restype, &cvtype) < 0)
if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0)
goto done;
if ((vec = clicon_strsep(ys->ys_argument, "|", &nvec)) == NULL)
goto done;

View file

@ -254,35 +254,6 @@ yang2cv_type(char *ytype,
*cv_type = ret;
return 0;
}
/* special derived types */
if (strcmp("ipv4-address", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_IPV4ADDR;
return 0;
}
if (strcmp("ipv6-address", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_IPV6ADDR;
return 0;
}
if (strcmp("ipv4-prefix", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_IPV4PFX;
return 0;
}
if (strcmp("ipv6-prefix", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_IPV6PFX;
return 0;
}
if (strcmp("date-and-time", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_TIME;
return 0;
}
if (strcmp("mac-address", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_MACADDR;
return 0;
}
if (strcmp("uuid", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_UUID;
return 0;
}
return 0;
}
@ -330,12 +301,14 @@ cv2yang_type(enum cv_type cv_type)
* not true yang types
* @param[in] origtype Name of original type
* @param[in] restype Resolved type. May be null, in that case origtype is used
* @param[in] ys Yang stmt of original resolving node
* @param[out] cvtype Translation from resolved type
* @note Thereis a kludge for handling direct translations of native cligen types
*/
int
clicon_type2cv(char *origtype,
char *restype,
yang_stmt *ys,
enum cv_type *cvtype)
{
int retval = -1;
@ -344,7 +317,8 @@ clicon_type2cv(char *origtype,
if (restype != NULL){
yang2cv_type(restype, cvtype);
if (*cvtype == CGV_ERR){
clicon_err(OE_YANG, EINVAL, "\"%s\" type not translated", restype);
clicon_err(OE_YANG, 0, "%s: \"%s\" type not translated",
ys_module(ys)->ys_argument, restype);
goto done;
}
}
@ -355,7 +329,8 @@ clicon_type2cv(char *origtype,
*/
yang2cv_type(origtype, cvtype);
if (*cvtype == CGV_ERR){
clicon_err(OE_YANG, EINVAL, "\"%s\": type not resolved", origtype);
clicon_err(OE_YANG, 0, "%s:\"%s\": type not resolved",
ys_module(ys)->ys_argument, origtype);
goto done;
}
}
@ -543,10 +518,15 @@ cv_validate1(cg_var *cv,
}
}
if ((options & YANG_OPTIONS_PATTERN) != 0){
if ((retval2 = match_regexp(str, pattern)) < 0){
char *posix = NULL;
if (regexp_xsd2posix(pattern, &posix) < 0)
goto done;
if ((retval2 = match_regexp(str, posix)) < 0){
clicon_err(OE_DB, 0, "match_regexp: %s", pattern);
return -1;
}
if (posix)
free(posix);
if (retval2 == 0){
if (reason)
*reason = cligen_reason("regexp match fail: \"%s\" does not match %s",
@ -611,7 +591,7 @@ ys_cv_validate_union_one(yang_stmt *ys,
goto done;
}
else {
if (clicon_type2cv(type, restype, &cvtype) < 0)
if (clicon_type2cv(type, restype, ys, &cvtype) < 0)
goto done;
/* reparse value with the new type */
if ((cvt = cv_new(cvtype)) == NULL){
@ -718,7 +698,7 @@ ys_cv_validate(cg_var *cv,
&options, &cvv, &pattern, &fraction) < 0)
goto done;
restype = yrestype?yrestype->ys_argument:NULL;
if (clicon_type2cv(type, restype, &cvtype) < 0)
if (clicon_type2cv(type, restype, ys, &cvtype) < 0)
goto done;
if (cv_type_get(ycv) != cvtype){
@ -978,7 +958,7 @@ yang_type_resolve(yang_stmt *yorig,
break;
/* Did not find a matching typedef there, proceed to next level */
yn = ys->ys_parent;
if (yn && yn->yn_keyword == Y_SPEC)
if (yn && (yn->yn_keyword == Y_SPEC))
yn = NULL;
ys = (yang_stmt*)yn;
}