123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- /*
- * ------------------------------------------------------
- * shell_roxml.c
- *
- * This file implements the means to read an XML encoded file
- * and populate the CLI tree based on the contents. It implements
- * the kxml_ API using roxml
- * ------------------------------------------------------
- */
- #include <errno.h>
- #include <roxml.h>
- #include <string.h>
- #include <faux/faux.h>
- #include <faux/str.h>
- #include <klish/kxml.h>
- bool_t kxml_doc_start(void)
- {
- return BOOL_TRUE;
- }
- bool_t kxml_doc_stop(void)
- {
- return BOOL_TRUE;
- }
- kxml_doc_t *kxml_doc_read(const char *filename)
- {
- node_t *doc = roxml_load_doc((char *)filename);
- return (kxml_doc_t *)doc;
- }
- void kxml_doc_release(kxml_doc_t *doc)
- {
- if (!doc)
- return;
- roxml_release(RELEASE_ALL);
- roxml_close((node_t *)doc);
- }
- bool_t kxml_doc_is_valid(const kxml_doc_t *doc)
- {
- return (bool_t)(doc != NULL);
- }
- /*
- int kxml_doc_error_caps(kxml_doc_t *doc)
- {
- return kxml_ERR_NOCAPS;
- }
- int kxml_doc_get_err_line(kxml_doc_t *doc)
- {
- return -1;
- }
- int kxml_doc_get_err_col(kxml_doc_t *doc)
- {
- return -1;
- }
- const char *kxml_doc_get_err_msg(kxml_doc_t *doc)
- {
- return "";
- }
- */
- kxml_nodetype_e kxml_node_type(const kxml_node_t *node)
- {
- int type = 0;
- if (!node)
- return KXML_NODE_UNKNOWN;
- type = roxml_get_type((node_t *)node);
- switch (type) {
- case ROXML_ELM_NODE:
- return KXML_NODE_ELM;
- case ROXML_TXT_NODE:
- return KXML_NODE_TEXT;
- case ROXML_CMT_NODE:
- return KXML_NODE_COMMENT;
- case ROXML_PI_NODE:
- return KXML_NODE_PI;
- case ROXML_ATTR_NODE:
- return KXML_NODE_ATTR;
- default:
- break;
- }
- return KXML_NODE_UNKNOWN;
- }
- kxml_node_t *kxml_doc_root(const kxml_doc_t *doc)
- {
- node_t *root = NULL;
- char *name = NULL;
- if (!doc)
- return NULL;
- root = roxml_get_root((node_t *)doc);
- if (!root)
- return NULL;
- /* The root node is always documentRoot since libroxml-2.2.2. */
- /* It's good but not compatible with another XML parsers. */
- name = roxml_get_name(root, NULL, 0);
- if (0 == strcmp(name, "documentRoot"))
- root = roxml_get_chld(root, NULL, 0);
- roxml_release(name);
- return (kxml_node_t *)root;
- }
- kxml_node_t *kxml_node_parent(const kxml_node_t *node)
- {
- node_t *roxn = (node_t *)node;
- node_t *root = NULL;
- if (!node)
- return NULL;
- root = roxml_get_root(roxn);
- if (roxn != root)
- return (kxml_node_t *)roxml_get_parent(roxn);
- return NULL;
- }
- const kxml_node_t *kxml_node_next_child(const kxml_node_t *parent,
- const kxml_node_t *curchild)
- {
- node_t *roxc = (node_t *)curchild;
- node_t *roxp = (node_t *)parent;
- node_t *child = NULL;
- int count = 0;
- if (!parent)
- return NULL;
- if (roxc)
- return (kxml_node_t *)
- roxml_get_next_sibling(roxc);
- count = roxml_get_chld_nb(roxp);
- if (count)
- child = roxml_get_chld(roxp, NULL, 0);
- return (kxml_node_t *)child;
- }
- static int i_is_needle(char *src, const char *needle)
- {
- int nlen = strlen(needle);
- int slen = strlen(src);
- if (slen >= nlen) {
- if (strncmp(src, needle, nlen) == 0)
- return 1;
- }
- return 0;
- }
- /* warning: dst == src is valid */
- static void i_decode_and_copy(char *dst, char *src)
- {
- while (*src) {
- if (*src == '&') {
- if (i_is_needle(src, "<")) {
- *dst++ = '<';
- src += 4;
- } else if (i_is_needle(src, ">")) {
- *dst++ = '>';
- src += 4;
- } else if (i_is_needle(src, "&")) {
- *dst++ = '&';
- src += 5;
- } else {
- *dst++ = *src++;
- }
- } else {
- *dst++ = *src++;
- }
- }
- *dst++ = 0;
- }
- char *kxml_node_attr(const kxml_node_t *node,
- const char *attrname)
- {
- node_t *roxn = (node_t *)node;
- node_t *attr = NULL;
- char *content = NULL;
- if (!node || !attrname)
- return NULL;
- attr = roxml_get_attr(roxn, (char *)attrname, 0);
- content = roxml_get_content(attr, NULL, 0, NULL);
- if (content)
- i_decode_and_copy(content, content);
- return content;
- }
- void kxml_node_attr_free(char *str)
- {
- if (!str)
- return;
- roxml_release(str);
- }
- char *kxml_node_content(const kxml_node_t *node)
- {
- char *content = NULL;
- if (!node)
- return NULL;
- content = roxml_get_content((node_t *)node, NULL, 0, NULL);
- if (content)
- i_decode_and_copy(content, content);
- return content;
- }
- void kxml_node_content_free(char *str)
- {
- if (!str)
- return;
- roxml_release(str);
- }
- char *kxml_node_name(const kxml_node_t *node)
- {
- if (!node)
- return NULL;
- return roxml_get_name((node_t *)node, NULL, 0);
- }
- void kxml_node_name_free(char *str)
- {
- if (!str)
- return;
- roxml_release(str);
- }
|