xml rm self, debug backend, xml2json to cbuf
This commit is contained in:
parent
8bf95cab31
commit
20087932c5
9 changed files with 138 additions and 39 deletions
|
|
@ -624,11 +624,14 @@ from_client_debug(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
clicon_debug_init(level, NULL); /* 0: dont debug, 1:debug */
|
clicon_debug_init(level, NULL); /* 0: dont debug, 1:debug */
|
||||||
|
setlogmask(LOG_UPTO(level?LOG_DEBUG:LOG_INFO)); /* for syslog */
|
||||||
|
|
||||||
if (send_msg_ok(s) < 0)
|
if (send_msg_ok(s) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
clicon_log(LOG_NOTICE, "%s debug:%d", __FUNCTION__, debug);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ backend_notify(clicon_handle h,
|
||||||
ce_next = ce->ce_next;
|
ce_next = ce->ce_next;
|
||||||
for (su = ce->ce_subscription; su; su = su->su_next)
|
for (su = ce->ce_subscription; su; su = su->su_next)
|
||||||
if (strcmp(su->su_stream, stream) == 0){
|
if (strcmp(su->su_stream, stream) == 0){
|
||||||
if (fnmatch(su->su_filter, event, 0) == 0)
|
if (strlen(su->su_filter)==0 || fnmatch(su->su_filter, event, 0) == 0){
|
||||||
if (send_msg_notify(ce->ce_s, level, event) < 0){
|
if (send_msg_notify(ce->ce_s, level, event) < 0){
|
||||||
if (errno == ECONNRESET){
|
if (errno == ECONNRESET){
|
||||||
clicon_log(LOG_WARNING, "client %s reset", ce->ce_nr);
|
clicon_log(LOG_WARNING, "client %s reset", ce->ce_nr);
|
||||||
|
|
@ -142,6 +142,7 @@ backend_notify(clicon_handle h,
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Then go thru all global (handle) subscriptions and find matches */
|
/* Then go thru all global (handle) subscriptions and find matches */
|
||||||
|
|
@ -151,7 +152,9 @@ backend_notify(clicon_handle h,
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(hs->hs_stream, stream))
|
if (strcmp(hs->hs_stream, stream))
|
||||||
continue;
|
continue;
|
||||||
if (fnmatch(hs->hs_filter, event, 0) == 0)
|
if (hs->hs_filter==NULL ||
|
||||||
|
strlen(hs->hs_filter)==0 ||
|
||||||
|
fnmatch(hs->hs_filter, event, 0) == 0)
|
||||||
if ((*hs->hs_fn)(h, event, hs->hs_arg) < 0)
|
if ((*hs->hs_fn)(h, event, hs->hs_arg) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -227,9 +230,10 @@ backend_notify_xml(clicon_handle h,
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(hs->hs_stream, stream))
|
if (strcmp(hs->hs_stream, stream))
|
||||||
continue;
|
continue;
|
||||||
if (strlen(hs->hs_filter)==0 || xpath_first(x, hs->hs_filter) != NULL)
|
if (strlen(hs->hs_filter)==0 || xpath_first(x, hs->hs_filter) != NULL){
|
||||||
if ((*hs->hs_fn)(h, x, hs->hs_arg) < 0)
|
if ((*hs->hs_fn)(h, x, hs->hs_arg) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -319,7 +323,7 @@ subscription_add(clicon_handle h,
|
||||||
memset(hs, 0, sizeof(*hs));
|
memset(hs, 0, sizeof(*hs));
|
||||||
hs->hs_stream = strdup(stream);
|
hs->hs_stream = strdup(stream);
|
||||||
hs->hs_format = format;
|
hs->hs_format = format;
|
||||||
hs->hs_filter = strdup(filter);
|
hs->hs_filter = filter?strdup(filter):NULL;
|
||||||
hs->hs_next = cb->cb_subscription;
|
hs->hs_next = cb->cb_subscription;
|
||||||
hs->hs_fn = fn;
|
hs->hs_fn = fn;
|
||||||
hs->hs_arg = arg;
|
hs->hs_arg = arg;
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ int xml_addsub(cxobj *xp, cxobj *xc);
|
||||||
cxobj *xml_insert(cxobj *xt, char *tag);
|
cxobj *xml_insert(cxobj *xt, char *tag);
|
||||||
int xml_purge(cxobj *xc);
|
int xml_purge(cxobj *xc);
|
||||||
int xml_child_rm(cxobj *xp, int i);
|
int xml_child_rm(cxobj *xp, int i);
|
||||||
|
int xml_rm(cxobj *xc);
|
||||||
int xml_rootchild(cxobj *xp, int i, cxobj **xcp);
|
int xml_rootchild(cxobj *xp, int i, cxobj **xcp);
|
||||||
|
|
||||||
char *xml_body(cxobj *xn);
|
char *xml_body(cxobj *xn);
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ enum {
|
||||||
*/
|
*/
|
||||||
int xml2txt(FILE *f, cxobj *x, int level);
|
int xml2txt(FILE *f, cxobj *x, int level);
|
||||||
int xml2cli(FILE *f, cxobj *x, char *prepend, enum genmodel_type gt, const char *label);
|
int xml2cli(FILE *f, cxobj *x, char *prepend, enum genmodel_type gt, const char *label);
|
||||||
|
int xml2json_cbuf(cbuf *cb, cxobj *x, int level);
|
||||||
int xml2json(FILE *f, cxobj *x, int level);
|
int xml2json(FILE *f, cxobj *x, int level);
|
||||||
int xml_yang_validate(cxobj *xt, yang_stmt *ys) ;
|
int xml_yang_validate(cxobj *xt, yang_stmt *ys) ;
|
||||||
int xml2cvec(cxobj *xt, yang_stmt *ys, cvec **cvv0);
|
int xml2cvec(cxobj *xt, yang_stmt *ys, cvec **cvv0);
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,7 @@ clicon_log_register_callback(clicon_log_notify_t *cb,
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*! Mimic syslog and print a time on file f
|
||||||
* Mimic syslog and print a time on file f
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
flogtime(FILE *f)
|
flogtime(FILE *f)
|
||||||
|
|
|
||||||
|
|
@ -609,7 +609,7 @@ xml_purge(cxobj *xc)
|
||||||
return retval;
|
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] xp xml parent node
|
||||||
* @param[in] i Number of xml child node (to remove)
|
* @param[in] i Number of xml child node (to remove)
|
||||||
* @retval 0 OK
|
* @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)
|
* @note you should not remove xchild in loop (unless yoy keep track of xprev)
|
||||||
*
|
*
|
||||||
* @see xml_rootchild
|
* @see xml_rootchild
|
||||||
|
* @see xml_rm Remove the node itself from parent
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml_child_rm(cxobj *xp,
|
xml_child_rm(cxobj *xp,
|
||||||
|
|
@ -640,6 +641,38 @@ xml_child_rm(cxobj *xp,
|
||||||
return retval;
|
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
|
/*! 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
|
* 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.
|
* and return it, remove the parent and all other children.
|
||||||
|
|
@ -678,13 +711,12 @@ xml_rootchild(cxobj *xp,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Get the first sub-node which is an XML body.
|
/*! Get the first sub-node which is an XML body.
|
||||||
* @param[in] xn xml tree node
|
* @param[in] xn xml tree node
|
||||||
* @retval The returned body as a pointer to the name string
|
* @retval The returned body as a pointer to the name string
|
||||||
* @retval NULL if no such node or no body in found node
|
* @retval NULL if no such node or no body in found node
|
||||||
* Note, make a copy of the return value to use it properly
|
* Note, make a copy of the return value to use it properly
|
||||||
* See also xml_find_body
|
* @see xml_find_body
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
xml_body(cxobj *xn)
|
xml_body(cxobj *xn)
|
||||||
|
|
@ -817,9 +849,9 @@ xml_print(FILE *f,
|
||||||
|
|
||||||
#define XML_INDENT 3 /* maybve we should set this programmatically? */
|
#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] xn clicon xml tree
|
||||||
* @param[in] level how many spaces to insert before each line
|
* @param[in] level how many spaces to insert before each line
|
||||||
* @param[in] prettyprint insert \n and spaces tomake the xml more readable.
|
* @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);
|
* xml_free(cx);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @see clicon_xml_parse_file
|
* @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,....
|
* Update: with yacc parser I dont think it changes,....
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -1001,7 +1001,6 @@ xmldb_get_local(clicon_handle h,
|
||||||
* free(xvec);
|
* free(xvec);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @see xpath_vec
|
* @see xpath_vec
|
||||||
* @endcode
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmldb_get(clicon_handle h,
|
xmldb_get(clicon_handle h,
|
||||||
|
|
|
||||||
|
|
@ -262,11 +262,22 @@ xml2cli(FILE *f,
|
||||||
return retval;
|
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
|
* XXX ugly code could be cleaned up
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
xml2json1(FILE *f, cxobj *x, int level, int eq, int comma)
|
xml2json1_cbuf(cbuf *cb,
|
||||||
|
cxobj *x,
|
||||||
|
int level,
|
||||||
|
int eq,
|
||||||
|
int comma)
|
||||||
{
|
{
|
||||||
cxobj *xe = NULL;
|
cxobj *xe = NULL;
|
||||||
cxobj *x1;
|
cxobj *x1;
|
||||||
|
|
@ -279,23 +290,23 @@ xml2json1(FILE *f, cxobj *x, int level, int eq, int comma)
|
||||||
|
|
||||||
switch(xml_type(x)){
|
switch(xml_type(x)){
|
||||||
case CX_BODY:
|
case CX_BODY:
|
||||||
fprintf(f, "\"%s\"", xml_value(x));
|
cprintf(cb, "\"%s\"", xml_value(x));
|
||||||
break;
|
break;
|
||||||
case CX_ELMNT:
|
case CX_ELMNT:
|
||||||
if (eq == 2)
|
if (eq == 2)
|
||||||
fprintf(f, "%*s", 2*level2, "");
|
cprintf(cb, "%*s", 2*level2, "");
|
||||||
else{
|
else{
|
||||||
fprintf(f, "%*s", 2*level1, "");
|
cprintf(cb, "%*s", 2*level1, "");
|
||||||
fprintf(f, "\"%s\": ", xml_name(x));
|
cprintf(cb, "\"%s\": ", xml_name(x));
|
||||||
}
|
}
|
||||||
if (xml_body(x)!=NULL){
|
if (xml_body(x)!=NULL){
|
||||||
if (eq==1){
|
if (eq==1){
|
||||||
fprintf(f, "[\n");
|
cprintf(cb, "[\n");
|
||||||
fprintf(f, "%*s", 2*level2, "");
|
cprintf(cb, "%*s", 2*level2, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(f, "{\n");
|
cprintf(cb, "{\n");
|
||||||
}
|
}
|
||||||
xe = NULL;
|
xe = NULL;
|
||||||
n = xml_child_nr(x);
|
n = xml_child_nr(x);
|
||||||
|
|
@ -313,17 +324,17 @@ xml2json1(FILE *f, cxobj *x, int level, int eq, int comma)
|
||||||
eq1 = 2; /* last */
|
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;
|
goto done;
|
||||||
if (xml_body(xe)!=NULL){
|
if (xml_body(xe)!=NULL){
|
||||||
if (eq1 == 2){
|
if (eq1 == 2){
|
||||||
fprintf(f, "\n");
|
cprintf(cb, "\n");
|
||||||
fprintf(f, "%*s", 2*level2, "");
|
cprintf(cb, "%*s", 2*level2, "");
|
||||||
fprintf(f, "]");
|
cprintf(cb, "]");
|
||||||
}
|
}
|
||||||
if (i+1<n)
|
if (i+1<n)
|
||||||
fprintf(f, ",");
|
cprintf(cb, ",");
|
||||||
fprintf(f, "\n");
|
cprintf(cb, "\n");
|
||||||
}
|
}
|
||||||
if (eq1==2)
|
if (eq1==2)
|
||||||
eq1 = 0;
|
eq1 = 0;
|
||||||
|
|
@ -331,31 +342,80 @@ xml2json1(FILE *f, cxobj *x, int level, int eq, int comma)
|
||||||
if (tleaf(x)){
|
if (tleaf(x)){
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
fprintf(f, "%*s}", 2*level1, "");
|
cprintf(cb, "%*s}", 2*level1, "");
|
||||||
if (comma)
|
if (comma)
|
||||||
fprintf(f, ",");
|
cprintf(cb, ",");
|
||||||
fprintf(f, "\n");
|
cprintf(cb, "\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// cprintf(cb, "%*s", 2*level, "");
|
||||||
// fprintf(f, "%*s", 2*level, "");
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xml2json(FILE *f, cxobj *x, int level)
|
xml2json_cbuf(cbuf *cb,
|
||||||
|
cxobj *x,
|
||||||
|
int level)
|
||||||
{
|
{
|
||||||
int retval = 1;
|
int retval = 1;
|
||||||
|
|
||||||
fprintf(f, "{\n");
|
cprintf(cb, "{\n");
|
||||||
if (xml2json1(f, x, level, 0, 0) < 0)
|
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;
|
goto done;
|
||||||
fprintf(f, "}\n");
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -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] vec0 Vector or xml nodes that are checked. Not matched are filtered
|
||||||
* @param[in,out] vec0len Length of vector or matches
|
* @param[in,out] vec0len Length of vector or matches
|
||||||
* On input, vec0 contains a list of xml nodes to match.
|
* 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:
|
* The predicate expression is a subset of the standard, namely:
|
||||||
* - @<attr>=<value>
|
* - @<attr>=<value>
|
||||||
* - <number>
|
* - <number>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue