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;
}
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)
goto done;
clicon_log(LOG_NOTICE, "%s debug:%d", __FUNCTION__, debug);
retval = 0;
done:
return retval;
}

View file

@ -125,7 +125,7 @@ backend_notify(clicon_handle h,
ce_next = ce->ce_next;
for (su = ce->ce_subscription; su; su = su->su_next)
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 (errno == ECONNRESET){
clicon_log(LOG_WARNING, "client %s reset", ce->ce_nr);
@ -142,6 +142,7 @@ backend_notify(clicon_handle h,
}
goto done;
}
}
}
}
/* Then go thru all global (handle) subscriptions and find matches */
@ -151,7 +152,9 @@ backend_notify(clicon_handle h,
continue;
if (strcmp(hs->hs_stream, stream))
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)
goto done;
}
@ -227,9 +230,10 @@ backend_notify_xml(clicon_handle h,
continue;
if (strcmp(hs->hs_stream, stream))
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)
goto done;
}
}
retval = 0;
done:
@ -319,7 +323,7 @@ subscription_add(clicon_handle h,
memset(hs, 0, sizeof(*hs));
hs->hs_stream = strdup(stream);
hs->hs_format = format;
hs->hs_filter = strdup(filter);
hs->hs_filter = filter?strdup(filter):NULL;
hs->hs_next = cb->cb_subscription;
hs->hs_fn = fn;
hs->hs_arg = arg;

View file

@ -95,6 +95,7 @@ int xml_addsub(cxobj *xp, cxobj *xc);
cxobj *xml_insert(cxobj *xt, char *tag);
int xml_purge(cxobj *xc);
int xml_child_rm(cxobj *xp, int i);
int xml_rm(cxobj *xc);
int xml_rootchild(cxobj *xp, int i, cxobj **xcp);
char *xml_body(cxobj *xn);

View file

@ -41,6 +41,7 @@ enum {
*/
int xml2txt(FILE *f, cxobj *x, int level);
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 xml_yang_validate(cxobj *xt, yang_stmt *ys) ;
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;
}
/*
* 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>