Generalized template and variable substitution functions
Modified api-path-fmt to uri-encoded only =restval
This commit is contained in:
parent
278def125c
commit
01938b7a64
6 changed files with 153 additions and 85 deletions
|
|
@ -466,7 +466,7 @@ yang2api_path_fmt(yang_stmt *ys,
|
|||
* cvv: foo, bar
|
||||
* api_path: /subif-entry=foo,bar/subid
|
||||
*
|
||||
* "api-path" is "URI-encoded path expression" definition in RFC8040 3.5.3
|
||||
* "api-path" is "URI-encoded path expression" definition in RFC8040 3.5.3 (note only =%s)
|
||||
*/
|
||||
int
|
||||
api_path_fmt2api_path(const char *api_path_fmt,
|
||||
|
|
@ -476,7 +476,9 @@ api_path_fmt2api_path(const char *api_path_fmt,
|
|||
{
|
||||
int retval = -1;
|
||||
char c;
|
||||
int esc=0;
|
||||
char cprev;
|
||||
int esc = 0;
|
||||
int uri_encode = 0;
|
||||
cbuf *cb = NULL;
|
||||
int i;
|
||||
int j;
|
||||
|
|
@ -491,15 +493,13 @@ api_path_fmt2api_path(const char *api_path_fmt,
|
|||
}
|
||||
j = 1; /* j==0 is cli string */
|
||||
len = strlen(api_path_fmt);
|
||||
cprev = 0;
|
||||
for (i=0; i<len; i++){
|
||||
c = api_path_fmt[i];
|
||||
if (esc){
|
||||
esc = 0;
|
||||
if (c!='s')
|
||||
continue;
|
||||
if (j == cvec_len(cvv)) /* last element */
|
||||
;
|
||||
else{
|
||||
if (c == 's' && /* Only accept "%s" no other types */
|
||||
j != cvec_len(cvv)) { /* last element */
|
||||
if ((cv = cvec_i(cvv, j++)) == NULL){
|
||||
clixon_err(OE_XML, 0, "Number of elements in cvv does not match api_path_fmt string");
|
||||
goto done;
|
||||
|
|
@ -508,22 +508,35 @@ api_path_fmt2api_path(const char *api_path_fmt,
|
|||
clixon_err(OE_UNIX, errno, "cv2str_dup");
|
||||
goto done;
|
||||
}
|
||||
if (uri_percent_encode(&strenc, "%s", str) < 0)
|
||||
goto done;
|
||||
cprintf(cb, "%s", strenc);
|
||||
free(strenc); strenc = NULL;
|
||||
free(str); str = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (c == '%')
|
||||
esc++;
|
||||
else{
|
||||
if ((c == '=' || c == ',') && api_path_fmt[i+1]=='%' && j == cvec_len(cvv))
|
||||
; /* skip */
|
||||
if (uri_encode){
|
||||
/* Only if restval, ie =%s, not if eg /%s/ */
|
||||
if (uri_percent_encode(&strenc, "%s", str) < 0)
|
||||
goto done;
|
||||
cprintf(cb, "%s", strenc);
|
||||
if (strenc){
|
||||
free(strenc);
|
||||
strenc = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
cprintf(cb, "%c", c);
|
||||
cprintf(cb, "%s", str);
|
||||
if (str) {
|
||||
free(str);
|
||||
str = NULL;
|
||||
}
|
||||
}
|
||||
uri_encode = 0;
|
||||
}
|
||||
else if (c == '%'){
|
||||
esc++;
|
||||
if (cprev == '=')
|
||||
uri_encode++;
|
||||
}
|
||||
else if ((c == '=' || c == ',') && api_path_fmt[i+1]=='%' && j == cvec_len(cvv))
|
||||
; /* skip */
|
||||
else
|
||||
cprintf(cb, "%c", c);
|
||||
cprev = c;
|
||||
}
|
||||
if ((*api_path = strdup(cbuf_get(cb))) == NULL){
|
||||
clixon_err(OE_UNIX, errno, "strdup");
|
||||
|
|
|
|||
|
|
@ -1212,6 +1212,59 @@ clixon_unicode2utf8(char *ucstr,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Substitute ${var} in string with variables in cvv
|
||||
*
|
||||
* @param[in] str Input string
|
||||
* @param[in] cvv Variable name/value vector
|
||||
* @param[out] cb Result buffer
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
clixon_str_subst(char *str,
|
||||
cvec *cvv,
|
||||
cbuf *cb)
|
||||
{
|
||||
int retval = -1;
|
||||
char **vec = NULL;
|
||||
int nvec = 0;
|
||||
int i;
|
||||
cg_var *cv;
|
||||
char *var;
|
||||
char *varname;
|
||||
char *varval;
|
||||
|
||||
if (clixon_strsep2(str, "${", "}", &vec, &nvec) < 0)
|
||||
goto done;
|
||||
if (nvec > 1){
|
||||
i = 0;
|
||||
while (i < nvec){
|
||||
cprintf(cb, "%s", vec[i++]);
|
||||
if (i == nvec)
|
||||
break;
|
||||
var = vec[i++];
|
||||
cv = NULL;
|
||||
while ((cv = cvec_each(cvv, cv)) != NULL){
|
||||
if ((varname = cv_name_get(cv)) == NULL)
|
||||
continue;
|
||||
if (strcmp(varname, var) != 0)
|
||||
continue;
|
||||
varval = cv_string_get(cv);
|
||||
cprintf(cb, "%s", varval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cprintf(cb, "%s", str);
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (vec)
|
||||
free(vec);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! strndup() for systems without it, such as xBSD
|
||||
*/
|
||||
#ifndef HAVE_STRNDUP
|
||||
|
|
|
|||
|
|
@ -2107,12 +2107,16 @@ clixon_compare_xmls(cxobj *xc1,
|
|||
|
||||
/*! XML apply function: replace ${} variables with values from cligen variable vector
|
||||
*
|
||||
* Example: x=<a>${name}</a>, cvv=["name","bert"] --> <a>bert</a>
|
||||
* @param[in] x XML node
|
||||
* @param[in] arg cvv: vector of name/value pairs
|
||||
* @retval -1 Error, aborted at first error encounter, return -1 to end user
|
||||
* @retval 0 OK, continue
|
||||
* @retval 1 Abort, dont continue with others, return 1 to end user
|
||||
* @retval 2 Locally abort this subtree, continue with others
|
||||
* @retval 1 Abort, dont continue with others, return 1 to end user
|
||||
* @retval 0 OK, continue
|
||||
* @retval -1 Error, aborted at first error encounter, return -1 to end user
|
||||
* @code
|
||||
* xml_apply(xtmpl, CX_ELMNT, xml_template_apply, cvv);
|
||||
* @endcode
|
||||
*/
|
||||
int
|
||||
xml_template_apply(cxobj *x,
|
||||
|
|
@ -2122,50 +2126,20 @@ xml_template_apply(cxobj *x,
|
|||
cvec *cvv = (cvec *)arg;
|
||||
cxobj *xb;
|
||||
char *b;
|
||||
char *var;
|
||||
char *varname;
|
||||
char *varval;
|
||||
cbuf *cb = NULL;
|
||||
int i;
|
||||
char **vec = NULL;
|
||||
int nvec = 0;
|
||||
cg_var *cv = NULL;
|
||||
|
||||
if ((xb = xml_body_get(x)) != NULL &&
|
||||
(b = xml_value(xb)) != NULL){
|
||||
if (clixon_strsep2(b, "${", "}", &vec, &nvec) < 0)
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clixon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
assert(nvec%2 == 1); /* Must be odd */
|
||||
if (nvec > 1){
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clixon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
i = 0;
|
||||
while (i < nvec){
|
||||
cprintf(cb, "%s", vec[i++]);
|
||||
if (i == nvec)
|
||||
break;
|
||||
var = vec[i++];
|
||||
assert(i < nvec); /* Must be odd */
|
||||
cv = NULL;
|
||||
while ((cv = cvec_each(cvv, cv)) != NULL){
|
||||
if ((varname = cv_name_get(cv)) == NULL)
|
||||
continue;
|
||||
if (strcmp(varname, var) != 0)
|
||||
continue;
|
||||
varval = cv_string_get(cv);
|
||||
cprintf(cb, "%s", varval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
xml_value_set(xb, cbuf_get(cb));
|
||||
}
|
||||
if (clixon_str_subst(b, cvv, cb) < 0)
|
||||
goto done;
|
||||
xml_value_set(xb, cbuf_get(cb));
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (vec)
|
||||
free(vec);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
return retval;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue