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

@ -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;
} }

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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,

View file

@ -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;

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] 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>