* Added linenumbers to all YANG symbols for better debug and errors

* Improved error messages for YANG identityref:s and leafref:s by adding original line numbers
This commit is contained in:
Olof hagsand 2021-08-03 12:53:37 +02:00
parent 4d265d63bd
commit 00645ee52b
11 changed files with 105 additions and 17 deletions

View file

@ -212,6 +212,10 @@ char *yang_when_xpath_get(yang_stmt *ys);
int yang_when_xpath_set(yang_stmt *ys, char *xpath);
cvec *yang_when_nsc_get(yang_stmt *ys);
int yang_when_nsc_set(yang_stmt *ys, cvec *nsc);
const char *yang_filename_get(yang_stmt *ys);
int yang_filename_set(yang_stmt *ys, const char *filename);
int yang_linenum_get(yang_stmt *ys);
int yang_linenum_set(yang_stmt *ys, int linenum);
/* Other functions */
yang_stmt *yspec_new(void);

View file

@ -119,7 +119,14 @@ validate_leafref(cxobj *xt,
if ((leafrefbody = xml_body(xt)) == NULL)
goto ok;
if ((ypath = yang_find(ytype, Y_PATH, NULL)) == NULL){
if (xret && netconf_missing_element_xml(xret, "application", yang_argument_get(ytype), "Leafref requires path statement") < 0)
if ((cberr = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
cprintf(cberr, "Leafref requires path statement");
if (xret && netconf_missing_element_xml(xret, "application",
yang_argument_get(ytype),
cbuf_get(cberr)) < 0)
goto done;
goto fail;
}
@ -142,7 +149,11 @@ validate_leafref(cxobj *xt,
goto done;
}
ymod = ys_module(ys);
cprintf(cberr, "Leafref validation failed: No leaf %s matching path %s in module %s", leafrefbody, path, yang_argument_get(ymod));
cprintf(cberr, "Leafref validation failed: No leaf %s matching path %s in %s.yang:%d",
leafrefbody,
path,
yang_argument_get(ymod),
yang_linenum_get(ys));
if (xret && netconf_bad_element_xml(xret, "application", leafrefbody, cbuf_get(cberr)) < 0)
goto done;
goto fail;
@ -241,8 +252,11 @@ validate_identityref(cxobj *xt,
#endif
}
if (ymod == NULL){
cprintf(cberr, "Identityref validation failed, %s not derived from %s",
node, yang_argument_get(ybaseid));
cprintf(cberr, "Identityref validation failed, %s not derived from %s in %s.yang:%d",
node,
yang_argument_get(ybaseid),
yang_argument_get(ys_module(ybaseid)),
yang_linenum_get(ybaseid));
if (xret && netconf_operation_failed_xml(xret, "application", cbuf_get(cberr)) < 0)
goto done;
goto fail;
@ -254,8 +268,11 @@ validate_identityref(cxobj *xt,
*/
idrefvec = yang_cvec_get(ybaseid);
if (cvec_find(idrefvec, idref) == NULL){
cprintf(cberr, "Identityref validation failed, %s not derived from %s",
node, yang_argument_get(ybaseid));
cprintf(cberr, "Identityref validation failed, %s not derived from %s in %s.yang:%d",
node,
yang_argument_get(ybaseid),
yang_argument_get(ys_module(ybaseid)),
yang_linenum_get(ybaseid));
if (xret && netconf_operation_failed_xml(xret, "application", cbuf_get(cberr)) < 0)
goto done;
goto fail;

View file

@ -416,6 +416,61 @@ yang_when_nsc_set(yang_stmt *ys,
return retval;
}
/*! Get yang filename for error/debug purpose
*
* @param[in] ys Yang statement
* @retval filename
* @note there maye not always be a "filename" in case the yang is read from memory
*/
const char *
yang_filename_get(yang_stmt *ys)
{
return ys->ys_filename;
}
/*! Set yang filename for error/debug purpose
*
* @param[in] ys Yang statement
* @param[in] filename
* @retval 0 OK
* @retval -1 Error
* @note there maye not always be a "filename" in case the yang is read from memory
*/
int
yang_filename_set(yang_stmt *ys,
const char *filename)
{
if ((ys->ys_filename = strdup(filename)) == NULL){
clicon_err(OE_UNIX, errno, "strdup");
return -1;
}
return 0;
}
/*! Get line number of yang filename for error/debug purpose
*
* @param[in] ys Yang statement
* @retval linenum
*/
int
yang_linenum_get(yang_stmt *ys)
{
return ys->ys_linenum;
}
/*! Set line number of yang filename for error/debug purpose
*
* @param[in] ys Yang statement
* @param[in] linenum
*/
int
yang_linenum_set(yang_stmt *ys,
int linenum)
{
ys->ys_linenum = linenum;
return 0;
}
/* End access functions */
/*! Create new yang specification
@ -498,6 +553,8 @@ ys_free1(yang_stmt *ys,
cvec_free(ys->ys_when_nsc);
if (ys->ys_stmt)
free(ys->ys_stmt);
if (ys->ys_filename)
free(ys->ys_filename);
if (self)
free(ys);
return 0;

View file

@ -93,7 +93,8 @@ struct yang_stmt{
char *ys_when_xpath; /* Special conditional for a "when"-associated augment/uses xpath */
cvec *ys_when_nsc; /* Special conditional for a "when"-associated augment/uses namespace ctx */
int _ys_vector_i; /* internal use: yn_each */
char *ys_filename; /* For debug/errors: filename (only (sub)modules) */
int ys_linenum; /* For debug/errors: line number (in ys_filename) */
};

View file

@ -318,6 +318,7 @@ ysp_add(clixon_yang_yacc *yy,
goto err;
if (ys_parse_sub(ys, extra) < 0) /* Check statement-specific syntax */
goto err2; /* dont free since part of tree */
yang_linenum_set(ys, yy->yy_linenum); /* For error/debugging */
// done:
return ys;
err:
@ -662,7 +663,7 @@ yin_element_stmt1 : K_YIN_ELEMENT bool_str stmtend {free($2);}
/* Identity */
identity_stmt : K_IDENTITY identifier_str ';'
{ if (ysp_add(_yy, Y_IDENTITY, $2, NULL) == NULL) _YYERROR("identity_stmt");
{ if (ysp_add(_yy, Y_IDENTITY, $2, NULL) == NULL) _YYERROR("identity_stmt");
_PARSE_DEBUG("identity-stmt -> IDENTITY string ;"); }
| K_IDENTITY identifier_str

View file

@ -773,6 +773,9 @@ yang_parse_str(char *str,
goto done;
}
ymod = yy.yy_module;
/* Add filename for debugging and errors, see also ys_linenum on (each symbol?) */
if (yang_filename_set(ymod, name) < 0)
goto done;
done:
ystack_pop(&yy);
if (yy.yy_stack)