when_xpath memory fixes and trimmed perf
This commit is contained in:
parent
911594ead1
commit
b0ec866544
5 changed files with 42 additions and 21 deletions
|
|
@ -281,8 +281,11 @@ check_body_namespace(cxobj *x0,
|
||||||
* @retval 1 OK
|
* @retval 1 OK
|
||||||
* @retval 0 Failed (cbret set)
|
* @retval 0 Failed (cbret set)
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* XXX this code is a mess. It tries multiple methods, one after the other. The solution
|
* XXX this code is a mess. It tries multiple methods, one after the other.
|
||||||
* is probably to make xpath evaluation namespace aware in combination with XML evaluation
|
* Observations:
|
||||||
|
* (1) is enough and required by clixon/controller tests
|
||||||
|
* (1+4+6) is required by some Arista machines
|
||||||
|
* The solution is probably to make xpath evaluation namespace aware in combination with XML evaluation
|
||||||
* (3+4)
|
* (3+4)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
|
@ -316,9 +319,10 @@ check_when_condition(cxobj *x0p,
|
||||||
goto done;
|
goto done;
|
||||||
if (nr != 0)
|
if (nr != 0)
|
||||||
goto ok;
|
goto ok;
|
||||||
|
/* 2. Try yang context for incoming xml */
|
||||||
if (xml_nsctx_node(x1p, &nnsc) < 0)
|
if (xml_nsctx_node(x1p, &nnsc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* 2. Try yang context for incoming xml */
|
#if 0
|
||||||
if ((nr = xpath_vec_bool(x1p, nsc, "%s", xpath)) < 0)
|
if ((nr = xpath_vec_bool(x1p, nsc, "%s", xpath)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (nr != 0)
|
if (nr != 0)
|
||||||
|
|
@ -328,18 +332,21 @@ check_when_condition(cxobj *x0p,
|
||||||
goto done;
|
goto done;
|
||||||
if (nr != 0)
|
if (nr != 0)
|
||||||
goto ok;
|
goto ok;
|
||||||
|
#endif
|
||||||
/* 4. Try xml context for existing xml */
|
/* 4. Try xml context for existing xml */
|
||||||
if ((nr = xpath_vec_bool(x0p, nnsc, "%s", xpath)) < 0) /* Try request */
|
if ((nr = xpath_vec_bool(x0p, nnsc, "%s", xpath)) < 0) /* Try request */
|
||||||
goto done;
|
goto done;
|
||||||
if (nr != 0)
|
if (nr != 0)
|
||||||
goto ok;
|
goto ok;
|
||||||
|
/* 5. Try yang canonical context for incoming xml */
|
||||||
if (yang_when_canonical_xpath_get(y, &cxpath, &cnsc) < 0)
|
if (yang_when_canonical_xpath_get(y, &cxpath, &cnsc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* 5. Try yang canonical context for incoming xml */
|
#if 0
|
||||||
if ((nr = xpath_vec_bool(x1p, cnsc, "%s", cxpath)) < 0)
|
if ((nr = xpath_vec_bool(x1p, cnsc, "%s", cxpath)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (nr != 0)
|
if (nr != 0)
|
||||||
goto ok;
|
goto ok;
|
||||||
|
#endif
|
||||||
/* 6. Try yang canonical context for existing xml */
|
/* 6. Try yang canonical context for existing xml */
|
||||||
if ((nr = xpath_vec_bool(x0p, cnsc, "%s", cxpath)) < 0)
|
if ((nr = xpath_vec_bool(x0p, cnsc, "%s", cxpath)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -361,12 +368,14 @@ check_when_condition(cxobj *x0p,
|
||||||
ok:
|
ok:
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
if (cxpath)
|
||||||
|
free(cxpath);
|
||||||
|
if (cnsc)
|
||||||
|
cvec_free(cnsc);
|
||||||
if (nsc)
|
if (nsc)
|
||||||
cvec_free(nsc);
|
cvec_free(nsc);
|
||||||
if (cberr)
|
if (cberr)
|
||||||
cbuf_free(cberr);
|
cbuf_free(cberr);
|
||||||
if (cxpath)
|
|
||||||
free(cxpath);
|
|
||||||
if (nnsc)
|
if (nnsc)
|
||||||
cvec_free(nnsc);
|
cvec_free(nnsc);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
@ -498,6 +507,8 @@ choice_other_match(cxobj *x0,
|
||||||
ok:
|
ok:
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
if (opstr)
|
||||||
|
free(opstr);
|
||||||
return retval;
|
return retval;
|
||||||
fail:
|
fail:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
|
||||||
|
|
@ -1239,6 +1239,7 @@ xml_yang_validate_all(clixon_handle h,
|
||||||
yang_stmt *yc; /* yang child */
|
yang_stmt *yc; /* yang child */
|
||||||
yang_stmt *ye; /* yang must error-message */
|
yang_stmt *ye; /* yang must error-message */
|
||||||
char *xpath;
|
char *xpath;
|
||||||
|
char *xpath1 = NULL;
|
||||||
int nr;
|
int nr;
|
||||||
int ret;
|
int ret;
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
|
|
@ -1283,8 +1284,8 @@ xml_yang_validate_all(clixon_handle h,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (yang_config(yt) != 0){
|
if (yang_config(yt) != 0){
|
||||||
ret = yang_check_when_xpath(xt, xml_parent(xt), yt, &hit, &nr, &xpath);
|
ret = yang_check_when_xpath(xt, xml_parent(xt), yt, &hit, &nr, &xpath1);
|
||||||
clixon_debug(CLIXON_DBG_XPATH|CLIXON_DBG_DETAIL, "nr:%d xpath:%s return:%d", nr, xpath, ret);
|
clixon_debug(CLIXON_DBG_XPATH|CLIXON_DBG_DETAIL, "nr:%d xpath:%s return:%d", nr, xpath1, ret);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
@ -1296,7 +1297,7 @@ xml_yang_validate_all(clixon_handle h,
|
||||||
cprintf(cb, "Failed WHEN condition of %s in module %s (WHEN xpath is %s)",
|
cprintf(cb, "Failed WHEN condition of %s in module %s (WHEN xpath is %s)",
|
||||||
xml_name(xt),
|
xml_name(xt),
|
||||||
yang_argument_get(ys_module(yt)),
|
yang_argument_get(ys_module(yt)),
|
||||||
xpath);
|
xpath1);
|
||||||
if (xret && netconf_operation_failed_xml(xret, "application",
|
if (xret && netconf_operation_failed_xml(xret, "application",
|
||||||
cbuf_get(cb)) < 0)
|
cbuf_get(cb)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1403,6 +1404,8 @@ xml_yang_validate_all(clixon_handle h,
|
||||||
ok:
|
ok:
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
if (xpath1)
|
||||||
|
free(xpath1);
|
||||||
if (cb)
|
if (cb)
|
||||||
cbuf_free(cb);
|
cbuf_free(cb);
|
||||||
if (nsc)
|
if (nsc)
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,6 @@ xml_default(yang_stmt *yt,
|
||||||
cxobj *xc;
|
cxobj *xc;
|
||||||
int top = 0; /* Top symbol (set default namespace) */
|
int top = 0; /* Top symbol (set default namespace) */
|
||||||
int create = 0;
|
int create = 0;
|
||||||
char *xpath;
|
|
||||||
int nr = 0;
|
int nr = 0;
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
|
|
@ -336,7 +335,7 @@ xml_default(yang_stmt *yt,
|
||||||
}
|
}
|
||||||
if (!cv_flag(cv, V_UNSET)){ /* Default value exists */
|
if (!cv_flag(cv, V_UNSET)){ /* Default value exists */
|
||||||
/* Check when condition */
|
/* Check when condition */
|
||||||
if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, &xpath) < 0)
|
if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (hit && nr == 0)
|
if (hit && nr == 0)
|
||||||
break; /* Do not create default if xpath fails */
|
break; /* Do not create default if xpath fails */
|
||||||
|
|
@ -351,7 +350,7 @@ xml_default(yang_stmt *yt,
|
||||||
case Y_CONTAINER:
|
case Y_CONTAINER:
|
||||||
if (yang_find(yc, Y_PRESENCE, NULL) == NULL){
|
if (yang_find(yc, Y_PRESENCE, NULL) == NULL){
|
||||||
/* Check when condition */
|
/* Check when condition */
|
||||||
if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, &xpath) < 0)
|
if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (hit && nr == 0)
|
if (hit && nr == 0)
|
||||||
break; /* Do not create default if xpath fails */
|
break; /* Do not create default if xpath fails */
|
||||||
|
|
|
||||||
|
|
@ -2068,7 +2068,7 @@ xml_copy_marked(cxobj *x0,
|
||||||
* @param[in] yn Yang node
|
* @param[in] yn Yang node
|
||||||
* @param[out] hit when statement found
|
* @param[out] hit when statement found
|
||||||
* @param[out] nrp 1: when stmt evaluates to true
|
* @param[out] nrp 1: when stmt evaluates to true
|
||||||
* @param[out] xpathp when stmts xpath
|
* @param[out] xpathp when stmts xpath, free after use
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* First variants of WHEN: Augmented and uses when using special info in node
|
* First variants of WHEN: Augmented and uses when using special info in node
|
||||||
|
|
@ -2088,24 +2088,26 @@ yang_check_when_xpath(cxobj *xn,
|
||||||
cxobj *x = NULL;
|
cxobj *x = NULL;
|
||||||
int nr = 0;
|
int nr = 0;
|
||||||
cvec *nsc = NULL;
|
cvec *nsc = NULL;
|
||||||
int xmalloc = 0; /* ugly help variable to clean temporary object */
|
int variant = 0; /* ugly help variable to clean temporary object */
|
||||||
|
|
||||||
/* First variant */
|
|
||||||
if (yang_when_canonical_xpath_get(yn, &xpath, &nsc) < 0)
|
if (yang_when_canonical_xpath_get(yn, &xpath, &nsc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xpath != NULL){
|
if (xpath != NULL){
|
||||||
x = xp;
|
x = xp;
|
||||||
*hit = 1;
|
*hit = 1;
|
||||||
}
|
}
|
||||||
/* Second variant */
|
|
||||||
else if ((yc = yang_find(yn, Y_WHEN, NULL)) != NULL){
|
else if ((yc = yang_find(yn, Y_WHEN, NULL)) != NULL){
|
||||||
xpath = yang_argument_get(yc); /* "when" has xpath argument */
|
/* "when" has xpath argument */
|
||||||
|
if ((xpath = strdup(yang_argument_get(yc))) == NULL){
|
||||||
|
clixon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* Create dummy */
|
/* Create dummy */
|
||||||
if (xn == NULL){
|
if (xn == NULL){
|
||||||
if ((x = xml_new(yang_argument_get(yn), xp, CX_ELMNT)) == NULL)
|
if ((x = xml_new(yang_argument_get(yn), xp, CX_ELMNT)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
xml_spec_set(x, yn);
|
xml_spec_set(x, yn);
|
||||||
xmalloc++;
|
variant = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
x = xn;
|
x = xn;
|
||||||
|
|
@ -2121,12 +2123,16 @@ yang_check_when_xpath(cxobj *xn,
|
||||||
}
|
}
|
||||||
if (nrp)
|
if (nrp)
|
||||||
*nrp = nr;
|
*nrp = nr;
|
||||||
if (xpathp)
|
if (xpathp){
|
||||||
*xpathp = xpath;
|
*xpathp = xpath;
|
||||||
|
xpath = NULL;
|
||||||
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (xmalloc)
|
if (variant)
|
||||||
xml_purge(x);
|
xml_purge(x);
|
||||||
|
if (xpath)
|
||||||
|
free(xpath);
|
||||||
if (nsc)
|
if (nsc)
|
||||||
xml_nsctx_free(nsc);
|
xml_nsctx_free(nsc);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -1147,7 +1147,7 @@ xpath_traverse_canonical(xpath_tree *xs,
|
||||||
* @param[in] nsc0 Input namespace context
|
* @param[in] nsc0 Input namespace context
|
||||||
* @param[in] yspec Yang spec containing all modules, associated with namespaces
|
* @param[in] yspec Yang spec containing all modules, associated with namespaces
|
||||||
* @param[in] exprstr Interpret strings as <prefix>:<name> (primaryexpr/literal/string)
|
* @param[in] exprstr Interpret strings as <prefix>:<name> (primaryexpr/literal/string)
|
||||||
* @param[out] xpath1 Output xpath. Free after use with free
|
* @param[out] xpath1 Output xpath. Free after use
|
||||||
* @param[out] nsc1 Output namespace context. Free after use with xml_nsctx_free
|
* @param[out] nsc1 Output namespace context. Free after use with xml_nsctx_free
|
||||||
* @param[out] cbreason reason if retval = 0
|
* @param[out] cbreason reason if retval = 0
|
||||||
* @retval 1 OK, xpath1 and nsc1 allocated
|
* @retval 1 OK, xpath1 and nsc1 allocated
|
||||||
|
|
@ -1239,6 +1239,8 @@ xpath2canonical1(const char *xpath0,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Backward compatible wrapper around xpath2canonical1
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
xpath2canonical(const char *xpath0,
|
xpath2canonical(const char *xpath0,
|
||||||
cvec *nsc0,
|
cvec *nsc0,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue