xml rm self, debug backend, xml2json to cbuf

This commit is contained in:
Olof Hagsand 2016-08-07 15:42:14 +02:00
parent 8bf95cab31
commit 20087932c5
9 changed files with 138 additions and 39 deletions

View file

@ -96,8 +96,7 @@ clicon_log_register_callback(clicon_log_notify_t *cb,
return old;
}
/*
* Mimic syslog and print a time on file f
/*! Mimic syslog and print a time on file f
*/
static int
flogtime(FILE *f)

View file

@ -609,7 +609,7 @@ xml_purge(cxobj *xc)
return retval;
}
/*! Remove xml node from parent xml node. No freeing and child is new own root
/*! Remove child xml node from parent xml node. No free and child is root
* @param[in] xp xml parent node
* @param[in] i Number of xml child node (to remove)
* @retval 0 OK
@ -617,6 +617,7 @@ xml_purge(cxobj *xc)
* @note you should not remove xchild in loop (unless yoy keep track of xprev)
*
* @see xml_rootchild
* @see xml_rm Remove the node itself from parent
*/
int
xml_child_rm(cxobj *xp,
@ -640,6 +641,38 @@ xml_child_rm(cxobj *xp,
return retval;
}
/*! Remove this xml node from parent xml node. No freeing and node is new root
* @param[in] xc xml child node to be removed
* @retval 0 OK
* @retval -1
* @note you should not remove xchild in loop (unless yoy keep track of xprev)
*
* @see xml_child_rm Remove a child of a node
*/
int
xml_rm(cxobj *xc)
{
int retval = 0;
cxobj *xp;
cxobj *x;
int i;
if ((xp = xml_parent(xc)) == NULL)
goto done;
retval = -1;
/* Find child in parent */
x = NULL; i = 0;
while ((x = xml_child_each(xp, x, -1)) != NULL) {
if (x == xc)
break;
i++;
}
if (x != NULL)
retval = xml_child_rm(xp, i);
done:
return retval;
}
/*! Return a child sub-tree, while removing parent and all other children
* Given a root xml node, and the i:th child, remove the child from its parent
* and return it, remove the parent and all other children.
@ -678,13 +711,12 @@ xml_rootchild(cxobj *xp,
return retval;
}
/*! Get the first sub-node which is an XML body.
* @param[in] xn xml tree node
* @retval The returned body as a pointer to the name string
* @retval NULL if no such node or no body in found node
* Note, make a copy of the return value to use it properly
* See also xml_find_body
* @see xml_find_body
*/
char *
xml_body(cxobj *xn)
@ -817,9 +849,9 @@ xml_print(FILE *f,
#define XML_INDENT 3 /* maybve we should set this programmatically? */
/*! Print an XML tree structure to a clicon buffer
/*! Print an XML tree structure to a cligen buffer
*
* @param[in,out] cb Clicon buffer to write to
* @param[in,out] cb Cligen buffer to write to
* @param[in] xn clicon xml tree
* @param[in] level how many spaces to insert before each line
* @param[in] prettyprint insert \n and spaces tomake the xml more readable.
@ -1027,7 +1059,7 @@ clicon_xml_parse_file(int fd,
* xml_free(cx);
* @endcode
* @see clicon_xml_parse_file
* Note, you need to free the xml parse tree after use, using xml_free()
* @note you need to free the xml parse tree after use, using xml_free()
* Update: with yacc parser I dont think it changes,....
*/
int

View file

@ -1001,7 +1001,6 @@ xmldb_get_local(clicon_handle h,
* free(xvec);
* @endcode
* @see xpath_vec
* @endcode
*/
int
xmldb_get(clicon_handle h,

View file

@ -262,11 +262,22 @@ xml2cli(FILE *f,
return retval;
}
/*! Translate from xml tree to JSON
/*! Internal function to translate from xml tree to JSON
* @param[in,out] cb Cligen buffer to write to
* @param[in] x XML tree to translate from
* @param[in] level Indentation level
* @param[in] eq
* @param[in] comma
* @retval 0 OK
* @retval -1 Error
* XXX ugly code could be cleaned up
*/
int
xml2json1(FILE *f, cxobj *x, int level, int eq, int comma)
static int
xml2json1_cbuf(cbuf *cb,
cxobj *x,
int level,
int eq,
int comma)
{
cxobj *xe = NULL;
cxobj *x1;
@ -279,23 +290,23 @@ xml2json1(FILE *f, cxobj *x, int level, int eq, int comma)
switch(xml_type(x)){
case CX_BODY:
fprintf(f, "\"%s\"", xml_value(x));
cprintf(cb, "\"%s\"", xml_value(x));
break;
case CX_ELMNT:
if (eq == 2)
fprintf(f, "%*s", 2*level2, "");
cprintf(cb, "%*s", 2*level2, "");
else{
fprintf(f, "%*s", 2*level1, "");
fprintf(f, "\"%s\": ", xml_name(x));
cprintf(cb, "%*s", 2*level1, "");
cprintf(cb, "\"%s\": ", xml_name(x));
}
if (xml_body(x)!=NULL){
if (eq==1){
fprintf(f, "[\n");
fprintf(f, "%*s", 2*level2, "");
cprintf(cb, "[\n");
cprintf(cb, "%*s", 2*level2, "");
}
}
else {
fprintf(f, "{\n");
cprintf(cb, "{\n");
}
xe = NULL;
n = xml_child_nr(x);
@ -313,17 +324,17 @@ xml2json1(FILE *f, cxobj *x, int level, int eq, int comma)
eq1 = 2; /* last */
}
}
if (xml2json1(f, xe, level1, eq1, (i+1<n)) < 0)
if (xml2json1_cbuf(cb, xe, level1, eq1, (i+1<n)) < 0)
goto done;
if (xml_body(xe)!=NULL){
if (eq1 == 2){
fprintf(f, "\n");
fprintf(f, "%*s", 2*level2, "");
fprintf(f, "]");
cprintf(cb, "\n");
cprintf(cb, "%*s", 2*level2, "");
cprintf(cb, "]");
}
if (i+1<n)
fprintf(f, ",");
fprintf(f, "\n");
cprintf(cb, ",");
cprintf(cb, "\n");
}
if (eq1==2)
eq1 = 0;
@ -331,31 +342,80 @@ xml2json1(FILE *f, cxobj *x, int level, int eq, int comma)
if (tleaf(x)){
}
else{
fprintf(f, "%*s}", 2*level1, "");
cprintf(cb, "%*s}", 2*level1, "");
if (comma)
fprintf(f, ",");
fprintf(f, "\n");
cprintf(cb, ",");
cprintf(cb, "\n");
}
break;
default:
break;
}
// fprintf(f, "%*s", 2*level, "");
// cprintf(cb, "%*s", 2*level, "");
retval = 0;
done:
return retval;
}
/*! Translate an XML tree to JSON in a CLIgen buffer
*
* @param[in,out] cb Cligen buffer to write to
* @param[in] x XML tree to translate from
* @param[in] level Indentation level
* @retval 0 OK
* @retval -1 Error
*
* @code
* cbuf *cb;
* cb = cbuf_new();
* if (xml2json_cbuf(cb, xn, 0, 1) < 0)
* goto err;
* cbuf_free(cb);
* @endcode
* See also xml2json
*/
int
xml2json(FILE *f, cxobj *x, int level)
xml2json_cbuf(cbuf *cb,
cxobj *x,
int level)
{
int retval = 1;
fprintf(f, "{\n");
if (xml2json1(f, x, level, 0, 0) < 0)
cprintf(cb, "{\n");
if (xml2json1_cbuf(cb, x, level, 0, 0) < 0)
goto done;
cprintf(cb, "}\n");
retval = 0;
done:
return retval;
}
/*! Translate from xml tree to JSON and print to file
* @param[in] f File to print to
* @param[in] x XML tree to translate from
* @param[in] level Indentation level
* @retval 0 OK
* @retval -1 Error
*
* @code
* if (xml2json(stderr, xn, 0) < 0)
* goto err;
* @endcode
*/
int
xml2json(FILE *f,
cxobj *x,
int level)
{
int retval = 1;
cbuf *cb;
if ((cb = cbuf_new()) ==NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
if (xml2json_cbuf(cb, x, level) < 0)
goto done;
fprintf(f, "}\n");
retval = 0;
done:
return retval;

View file

@ -403,7 +403,7 @@ recursive_find(cxobj *xn,
* @param[in,out] vec0 Vector or xml nodes that are checked. Not matched are filtered
* @param[in,out] vec0len Length of vector or matches
* On input, vec0 contains a list of xml nodes to match.
* On output, vec0 contains only the subset that matched the epxression.
* On output, vec0 contains only the subset that matched the expression.
* The predicate expression is a subset of the standard, namely:
* - @<attr>=<value>
* - <number>