Go back to revision 44. The good modifications of rev. 45 and 46 will be added in the following commits. The reason for this is a bad commit in rev. 45.

This commit is contained in:
Matthias Schneebeli 2007-02-15 11:59:54 +00:00
parent d8db729ef2
commit e77b8b1116
2 changed files with 203 additions and 168 deletions

328
mxml.c
View File

@ -10,10 +10,10 @@
functions can be used: functions can be used:
writer = mxml_open_file(file_name); writer = mxml_open_file(file_name);
mxml_start_element(writer, name); mxml_start_element(writer, name);
mxml_write_attribute(writer, name, value); mxml_write_attribute(writer, name, value);
mxml_write_value(writer, value); mxml_write_value(writer, value);
mxml_end_element(writer); mxml_end_element(writer);
... ...
mxml_close_file(writer); mxml_close_file(writer);
@ -78,7 +78,15 @@
#define XML_INDENT " " #define XML_INDENT " "
static int mxml_suppress_date_flag = 0; /* suppress writing date at the top of file. */ /* local prototypes */
static PMXML_NODE read_error(PMXML_NODE root, const char *file_name, int line_number, char *error, int error_size, char *format, ...);
static void mxml_encode(char *src, int size, int translate);
static void mxml_decode(char *str);
static int mxml_write_subtree(MXML_WRITER *writer, PMXML_NODE tree, int indent);
static int mxml_write_line(MXML_WRITER *writer, const char *line);
static int mxml_start_element1(MXML_WRITER *writer, const char *name, int indent);
static int mxml_add_resultnode(PMXML_NODE node, const char *xml_path, PMXML_NODE **nodelist, int *found);
static int mxml_find_nodes1(PMXML_NODE tree, const char *xml_path, PMXML_NODE **nodelist, int *found);
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
@ -103,11 +111,12 @@ int mxml_write_line(MXML_WRITER *writer, const char *line)
return 0; return 0;
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* open a memory buffer and write XML header
*/
MXML_WRITER *mxml_open_buffer() MXML_WRITER *mxml_open_buffer()
/* open a file and write XML header */
{ {
char str[256], line[1000]; char str[256], line[1000];
time_t now; time_t now;
@ -129,8 +138,7 @@ MXML_WRITER *mxml_open_buffer()
strcpy(str, ctime(&now)); strcpy(str, ctime(&now));
str[24] = 0; str[24] = 0;
sprintf(line, "<!-- created by MXML on %s -->\n", str); sprintf(line, "<!-- created by MXML on %s -->\n", str);
if (mxml_suppress_date_flag == 0) mxml_write_line(writer, line);
mxml_write_line(writer, line);
/* initialize stack */ /* initialize stack */
writer->level = 0; writer->level = 0;
@ -141,16 +149,10 @@ MXML_WRITER *mxml_open_buffer()
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
void mxml_suppress_date(int suppress) /**
/* suppress writing date at the top of file. */ * open a file and write XML header
{ */
mxml_suppress_date_flag = suppress;
}
/*------------------------------------------------------------------*/
MXML_WRITER *mxml_open_file(const char *file_name) MXML_WRITER *mxml_open_file(const char *file_name)
/* open a file and write XML header */
{ {
char str[256], line[1000]; char str[256], line[1000];
time_t now; time_t now;
@ -176,8 +178,7 @@ MXML_WRITER *mxml_open_file(const char *file_name)
strcpy(str, ctime(&now)); strcpy(str, ctime(&now));
str[24] = 0; str[24] = 0;
sprintf(line, "<!-- created by MXML on %s -->\n", str); sprintf(line, "<!-- created by MXML on %s -->\n", str);
if (mxml_suppress_date_flag == 0) mxml_write_line(writer, line);
mxml_write_line(writer, line);
/* initialize stack */ /* initialize stack */
writer->level = 0; writer->level = 0;
@ -188,8 +189,10 @@ MXML_WRITER *mxml_open_file(const char *file_name)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* convert '<' '>' '&' '"' ''' into &xx;
*/
void mxml_encode(char *src, int size, int translate) void mxml_encode(char *src, int size, int translate)
/* convert '<' '>' '&' '"' ''' into &xx; */
{ {
char *ps, *pd; char *ps, *pd;
static char *buffer = NULL; static char *buffer = NULL;
@ -209,7 +212,7 @@ void mxml_encode(char *src, int size, int translate)
pd = buffer; pd = buffer;
for (ps = src ; *ps && (size_t)pd - (size_t)buffer < (size_t)(size-10) ; ps++) { for (ps = src ; *ps && (size_t)pd - (size_t)buffer < (size_t)(size-10) ; ps++) {
if (translate) { // tranlate "<", ">", "&", """, "'" if (translate) { /* tranlate "<", ">", "&", """, "'" */
switch (*ps) { switch (*ps) {
case '<': case '<':
strcpy(pd, "&lt;"); strcpy(pd, "&lt;");
@ -235,7 +238,7 @@ void mxml_encode(char *src, int size, int translate)
*pd++ = *ps; *pd++ = *ps;
} }
} else { } else {
switch (*ps) { // translate only illegal XML characters "<" and "&" switch (*ps) { /* translate only illegal XML characters "<" and "&" */
case '<': case '<':
strcpy(pd, "&lt;"); strcpy(pd, "&lt;");
pd += 4; pd += 4;
@ -256,8 +259,10 @@ void mxml_encode(char *src, int size, int translate)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* reverse of mxml_encode, strip leading or trailing '"'
*/
void mxml_decode(char *str) void mxml_decode(char *str)
/* reverse of mxml_encode, strip leading or trailing '"' */
{ {
char *p; char *p;
@ -292,8 +297,10 @@ void mxml_decode(char *str)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* set translation of <,>,",',&, on/off in writer
*/
int mxml_set_translate(MXML_WRITER *writer, int flag) int mxml_set_translate(MXML_WRITER *writer, int flag)
/* set translation of <,>,",',&, on/off in writer */
{ {
int old_flag; int old_flag;
@ -303,8 +310,10 @@ int mxml_set_translate(MXML_WRITER *writer, int flag)
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* start a new XML element, must be followed by mxml_end_elemnt
*/
int mxml_start_element1(MXML_WRITER *writer, const char *name, int indent) int mxml_start_element1(MXML_WRITER *writer, const char *name, int indent)
/* start a new XML element, must be followed by mxml_end_elemnt */
{ {
int i; int i;
char line[1000], name_enc[1000]; char line[1000], name_enc[1000];
@ -354,8 +363,10 @@ int mxml_start_element_noindent(MXML_WRITER *writer, const char *name)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* close an open XML element
*/
int mxml_end_element(MXML_WRITER *writer) int mxml_end_element(MXML_WRITER *writer)
/* close an open XML element */
{ {
int i; int i;
char line[1000]; char line[1000];
@ -393,10 +404,12 @@ int mxml_end_element(MXML_WRITER *writer)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* write an attribute to the currently open XML element
*/
int mxml_write_attribute(MXML_WRITER *writer, const char *name, const char *value) int mxml_write_attribute(MXML_WRITER *writer, const char *name, const char *value)
/* write an attribute to the currently open XML element */
{ {
char name_enc[4000], val_enc[4000], line[8000]; char name_enc[1000], val_enc[1000], line[2000];
if (!writer->element_is_open) if (!writer->element_is_open)
return FALSE; return FALSE;
@ -413,8 +426,10 @@ int mxml_write_attribute(MXML_WRITER *writer, const char *name, const char *valu
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* write value of an XML element, like <[name]>[value]</[name]>
*/
int mxml_write_value(MXML_WRITER *writer, const char *data) int mxml_write_value(MXML_WRITER *writer, const char *data)
/* write value of an XML element, like <[name]>[value]</[name]> */
{ {
static char *data_enc; static char *data_enc;
static int data_size = 0; static int data_size = 0;
@ -442,24 +457,10 @@ int mxml_write_value(MXML_WRITER *writer, const char *data)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_write_empty_line(MXML_WRITER *writer) /**
/* write empty line */ * write a comment to an XML file, enclosed in "<!--" and "-->"
{ */
if (writer->element_is_open) {
mxml_write_line(writer, ">\n");
writer->element_is_open = FALSE;
}
if (mxml_write_line(writer, "\n") != 1)
return FALSE;
return TRUE;
}
/*------------------------------------------------------------------*/
int mxml_write_comment(MXML_WRITER *writer, const char *string) int mxml_write_comment(MXML_WRITER *writer, const char *string)
/* write a comment to an XML file, enclosed in "<!--" and "-->" */
{ {
int i; int i;
char line[1000]; char line[1000];
@ -482,20 +483,12 @@ int mxml_write_comment(MXML_WRITER *writer, const char *string)
return TRUE; return TRUE;
} }
int mxml_write_element(MXML_WRITER *writer, const char *name, const char *value)
{
int i;
i = mxml_start_element(writer, name);
i += mxml_write_value(writer, value);
i += mxml_end_element(writer);
return i;
}
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* close a file opened with mxml_open_writer
*/
char *mxml_close_buffer(MXML_WRITER *writer) char *mxml_close_buffer(MXML_WRITER *writer)
/* close a file opened with mxml_open_writer */
{ {
int i; int i;
char *p; char *p;
@ -517,8 +510,10 @@ char *mxml_close_buffer(MXML_WRITER *writer)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* close a file opened with mxml_open_writer
*/
int mxml_close_file(MXML_WRITER *writer) int mxml_close_file(MXML_WRITER *writer)
/* close a file opened with mxml_open_writer */
{ {
int i; int i;
@ -539,8 +534,10 @@ int mxml_close_file(MXML_WRITER *writer)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* create root node of an XML tree
*/
PMXML_NODE mxml_create_root_node() PMXML_NODE mxml_create_root_node()
/* create root node of an XML tree */
{ {
PMXML_NODE root; PMXML_NODE root;
@ -553,8 +550,10 @@ PMXML_NODE mxml_create_root_node()
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
PMXML_NODE mxml_add_special_node_at(PMXML_NODE parent, int node_type, char *node_name, char *value, int index) /**
/* add a subnode (child) to an existing parent node as a specific position */ * add a subnode (child) to an existing parent node as a specific position
*/
PMXML_NODE mxml_add_special_node_at(PMXML_NODE parent, int node_type, const char *node_name, const char *value, int index)
{ {
PMXML_NODE pnode, pchild; PMXML_NODE pnode, pchild;
int i, j; int i, j;
@ -601,32 +600,40 @@ PMXML_NODE mxml_add_special_node_at(PMXML_NODE parent, int node_type, char *node
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
PMXML_NODE mxml_add_special_node(PMXML_NODE parent, int node_type, char *node_name, char *value) /**
/* add a subnode (child) to an existing parent node at the end */ * add a subnode (child) to an existing parent node at the end
*/
PMXML_NODE mxml_add_special_node(PMXML_NODE parent, int node_type, const char *node_name, const char *value)
{ {
return mxml_add_special_node_at(parent, node_type, node_name, value, parent->n_children); return mxml_add_special_node_at(parent, node_type, node_name, value, parent->n_children);
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
PMXML_NODE mxml_add_node(PMXML_NODE parent, char *node_name, char *value) /**
/* add a subnode (child) to an existing parent node at the end */ * write value of an XML element, like <[name]>[value]</[name]>
*/
PMXML_NODE mxml_add_node(PMXML_NODE parent, const char *node_name, const char *value)
{ {
return mxml_add_special_node_at(parent, ELEMENT_NODE, node_name, value, parent->n_children); return mxml_add_special_node_at(parent, ELEMENT_NODE, node_name, value, parent->n_children);
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
PMXML_NODE mxml_add_node_at(PMXML_NODE parent, char *node_name, char *value, int index) /**
/* add a subnode (child) to an existing parent node at the end */ * add a subnode (child) to an existing parent node at the end
*/
PMXML_NODE mxml_add_node_at(PMXML_NODE parent, const char *node_name, const char *value, int index)
{ {
return mxml_add_special_node_at(parent, ELEMENT_NODE, node_name, value, index); return mxml_add_special_node_at(parent, ELEMENT_NODE, node_name, value, index);
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* add a whole node tree to an existing parent node at a specific position
*/
int mxml_add_tree_at(PMXML_NODE parent, PMXML_NODE tree, int index) int mxml_add_tree_at(PMXML_NODE parent, PMXML_NODE tree, int index)
/* add a whole node tree to an existing parent node at a specific position */
{ {
PMXML_NODE pchild; PMXML_NODE pchild;
int i, j; int i, j;
@ -680,16 +687,20 @@ int mxml_add_tree_at(PMXML_NODE parent, PMXML_NODE tree, int index)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* add a whole node tree to an existing parent node at the end
*/
int mxml_add_tree(PMXML_NODE parent, PMXML_NODE tree) int mxml_add_tree(PMXML_NODE parent, PMXML_NODE tree)
/* add a whole node tree to an existing parent node at the end */
{ {
return mxml_add_tree_at(parent, tree, parent->n_children); return mxml_add_tree_at(parent, tree, parent->n_children);
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_add_attribute(PMXML_NODE pnode, char *attrib_name, char *attrib_value) /**
/* add an attribute to an existing node */ * add an attribute to an existing node
*/
int mxml_add_attribute(PMXML_NODE pnode, const char *attrib_name, const char *attrib_value)
{ {
if (pnode->n_attributes == 0) { if (pnode->n_attributes == 0) {
pnode->attribute_name = (char*)malloc(MXML_NAME_LENGTH); pnode->attribute_name = (char*)malloc(MXML_NAME_LENGTH);
@ -709,8 +720,10 @@ int mxml_add_attribute(PMXML_NODE pnode, char *attrib_name, char *attrib_value)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* return number of subnodes (children) of a node
*/
int mxml_get_number_of_children(PMXML_NODE pnode) int mxml_get_number_of_children(PMXML_NODE pnode)
/* return number of subnodes (children) of a node */
{ {
assert(pnode); assert(pnode);
return pnode->n_children; return pnode->n_children;
@ -718,8 +731,10 @@ int mxml_get_number_of_children(PMXML_NODE pnode)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* return number of subnodes (children) of a node
*/
PMXML_NODE mxml_subnode(PMXML_NODE pnode, int index) PMXML_NODE mxml_subnode(PMXML_NODE pnode, int index)
/* return number of subnodes (children) of a node */
{ {
assert(pnode); assert(pnode);
if (index < pnode->n_children) if (index < pnode->n_children)
@ -729,9 +744,8 @@ PMXML_NODE mxml_subnode(PMXML_NODE pnode, int index)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_find_nodes1(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist, int *found);
int mxml_add_resultnode(PMXML_NODE node, char *xml_path, PMXML_NODE **nodelist, int *found) int mxml_add_resultnode(PMXML_NODE node, const char *xml_path, PMXML_NODE **nodelist, int *found)
{ {
/* if at end of path, add this node */ /* if at end of path, add this node */
if (*xml_path == 0) { if (*xml_path == 0) {
@ -752,8 +766,7 @@ int mxml_add_resultnode(PMXML_NODE node, char *xml_path, PMXML_NODE **nodelist,
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_find_nodes1(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist, int *found) /**
/*
Return list of XML nodes with a subset of XPATH specifications. Return list of XML nodes with a subset of XPATH specifications.
Following elemets are possible Following elemets are possible
@ -764,9 +777,11 @@ int mxml_find_nodes1(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist, int
/<node>[<subnode>=<value>]/<node> Find subnode of the above /<node>[<subnode>=<value>]/<node> Find subnode of the above
/<node>[@<attrib>=<value>]/<node> Find a node which has a specific attribute /<node>[@<attrib>=<value>]/<node> Find a node which has a specific attribute
*/ */
int mxml_find_nodes1(PMXML_NODE tree, const char *xml_path, PMXML_NODE **nodelist, int *found)
{ {
PMXML_NODE pnode; PMXML_NODE pnode;
char *p1, *p2, *p3, node_name[256], condition[256]; const char *p1,*p2;
char *p3, node_name[256], condition[256];
char cond_name[MXML_MAX_CONDITION][256], cond_value[MXML_MAX_CONDITION][256]; char cond_name[MXML_MAX_CONDITION][256], cond_value[MXML_MAX_CONDITION][256];
int cond_type[MXML_MAX_CONDITION]; int cond_type[MXML_MAX_CONDITION];
int i, j, k, index, num_cond; int i, j, k, index, num_cond;
@ -804,7 +819,7 @@ int mxml_find_nodes1(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist, int
p2++; p2++;
} else { } else {
/* evaluate [<@attrib>/<subnode>=<value>] */ /* evaluate [<@attrib>/<subnode>=<value>] */
while (*p2 && isspace(*p2)) while (*p2 && isspace((unsigned char)*p2))
p2++; p2++;
strlcpy(condition, p2, sizeof(condition)); strlcpy(condition, p2, sizeof(condition));
if (strchr(condition, ']')) if (strchr(condition, ']'))
@ -813,12 +828,10 @@ int mxml_find_nodes1(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist, int
return 0; return 0;
p2 = strchr(p2, ']')+1; p2 = strchr(p2, ']')+1;
if ((p3 = strchr(condition, '=')) != NULL) { if ((p3 = strchr(condition, '=')) != NULL) {
if (condition[0] == '@') { if (condition[0] == '@') {
cond_type[num_cond] = 1; cond_type[num_cond] = 1;
strlcpy(cond_name[num_cond], &condition[1], sizeof(cond_name[num_cond]) - 1); strlcpy(cond_name[num_cond], &condition[1], sizeof(cond_name[num_cond]));
} } else {
else {
strlcpy(cond_name[num_cond], condition, sizeof(cond_name[num_cond])); strlcpy(cond_name[num_cond], condition, sizeof(cond_name[num_cond]));
} }
@ -901,7 +914,7 @@ int mxml_find_nodes1(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist, int
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_find_nodes(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist) int mxml_find_nodes(PMXML_NODE tree, const char *xml_path, PMXML_NODE **nodelist)
{ {
int status, found = 0; int status, found = 0;
@ -915,11 +928,11 @@ int mxml_find_nodes(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
PMXML_NODE mxml_find_node(PMXML_NODE tree, char *xml_path) /**
/* * Search for a specific XML node with a subset of XPATH specifications.
Search for a specific XML node with a subset of XPATH specifications. * Return first found node. For syntax see mxml_find_nodes()
Return first found node. For syntax see mxml_find_nodes() */
*/ PMXML_NODE mxml_find_node(PMXML_NODE tree, const char *xml_path)
{ {
PMXML_NODE *node, pnode; PMXML_NODE *node, pnode;
int n; int n;
@ -952,7 +965,7 @@ char *mxml_get_value(PMXML_NODE pnode)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
char *mxml_get_attribute(PMXML_NODE pnode, char *name) char *mxml_get_attribute(PMXML_NODE pnode, const char *name)
{ {
int i; int i;
@ -966,7 +979,7 @@ char *mxml_get_attribute(PMXML_NODE pnode, char *name)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_replace_node_name(PMXML_NODE pnode, char *name) int mxml_replace_node_name(PMXML_NODE pnode, const char *name)
{ {
strlcpy(pnode->name, name, sizeof(pnode->name)); strlcpy(pnode->name, name, sizeof(pnode->name));
return TRUE; return TRUE;
@ -974,7 +987,7 @@ int mxml_replace_node_name(PMXML_NODE pnode, char *name)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_replace_node_value(PMXML_NODE pnode, char *value) int mxml_replace_node_value(PMXML_NODE pnode, const char *value)
{ {
if (pnode->value) if (pnode->value)
pnode->value = (char *)realloc(pnode->value, strlen(value)+1); pnode->value = (char *)realloc(pnode->value, strlen(value)+1);
@ -991,8 +1004,7 @@ int mxml_replace_node_value(PMXML_NODE pnode, char *value)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_replace_subvalue(PMXML_NODE pnode, char *name, char *value) /**
/*
replace value os a subnode, like replace value os a subnode, like
<parent> <parent>
@ -1001,6 +1013,7 @@ int mxml_replace_subvalue(PMXML_NODE pnode, char *name, char *value)
if pnode=parent, and "name"="child", then "value" gets replaced if pnode=parent, and "name"="child", then "value" gets replaced
*/ */
int mxml_replace_subvalue(PMXML_NODE pnode, const char *name, const char *value)
{ {
int i; int i;
@ -1016,8 +1029,10 @@ int mxml_replace_subvalue(PMXML_NODE pnode, char *name, char *value)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_replace_attribute_name(PMXML_NODE pnode, char *old_name, char *new_name) /**
/* change the name of an attribute, keep its value */ * change the name of an attribute, keep its value
*/
int mxml_replace_attribute_name(PMXML_NODE pnode, const char *old_name, const char *new_name)
{ {
int i; int i;
@ -1034,8 +1049,10 @@ int mxml_replace_attribute_name(PMXML_NODE pnode, char *old_name, char *new_name
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_replace_attribute_value(PMXML_NODE pnode, char *attrib_name, char *attrib_value) /**
/* change the value of an attribute */ * change the value of an attribute
*/
int mxml_replace_attribute_value(PMXML_NODE pnode, const char *attrib_name, const char *attrib_value)
{ {
int i; int i;
@ -1053,8 +1070,10 @@ int mxml_replace_attribute_value(PMXML_NODE pnode, char *attrib_name, char *attr
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* free memory of a node and remove it from the parent's child list
*/
int mxml_delete_node(PMXML_NODE pnode) int mxml_delete_node(PMXML_NODE pnode)
/* free memory of a node and remove it from the parent's child list */
{ {
PMXML_NODE parent; PMXML_NODE parent;
int i, j; int i, j;
@ -1087,7 +1106,7 @@ int mxml_delete_node(PMXML_NODE pnode)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_delete_attribute(PMXML_NODE pnode, char *attrib_name) int mxml_delete_attribute(PMXML_NODE pnode, const char *attrib_name)
{ {
int i, j; int i, j;
@ -1119,8 +1138,10 @@ int mxml_delete_attribute(PMXML_NODE pnode, char *attrib_name)
#define HERE root, file_name, line_number, error, error_size #define HERE root, file_name, line_number, error, error_size
PMXML_NODE read_error(PMXML_NODE root, char *file_name, int line_number, char *error, int error_size, char *format, ...) /**
/* used inside mxml_parse_file for reporting errors */ * used inside mxml_parse_file for reporting errors
*/
PMXML_NODE read_error(PMXML_NODE root, const char *file_name, int line_number, char *error, int error_size, char *format, ...)
{ {
char *msg, str[1000]; char *msg, str[1000];
va_list argptr; va_list argptr;
@ -1145,18 +1166,20 @@ PMXML_NODE read_error(PMXML_NODE root, char *file_name, int line_number, char *e
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size) /**
/* parse a XML buffer and convert it into a tree of MXML_NODE's. Return NULL * Parse a XML buffer and convert it into a tree of MXML_NODE's.
in case of an error, return error description. Optional file_name is used * Return NULL in case of an error, return error description.
for error reporting if called from mxml_parse_file() */ * Optional file_name is used for error reporting if called from mxml_parse_file()
*/
PMXML_NODE mxml_parse_buffer(const char *buf, char *error, int error_size)
{ {
char node_name[256], attrib_name[256], attrib_value[1000]; char node_name[256], attrib_name[256], attrib_value[1000], quote;
char *p, *pv; const char *p, *pv;
int i,j, line_number; int i,j, line_number;
PMXML_NODE root, ptree, pnew; PMXML_NODE root, ptree, pnew;
int end_element; int end_element;
size_t len; size_t len;
char *file_name = NULL; // dummy for 'HERE' char *file_name = NULL; /* dummy for 'HERE' */
p = buf; p = buf;
line_number = 1; line_number = 1;
@ -1259,7 +1282,7 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
if (*p == '/') { if (*p == '/') {
end_element = TRUE; end_element = TRUE;
p++; p++;
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1271,7 +1294,7 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
/* extract node name */ /* extract node name */
i = 0; i = 0;
node_name[i] = 0; node_name[i] = 0;
while (*p && !isspace(*p) && *p != '/' && *p != '>' && *p != '<') while (*p && !isspace((unsigned char)*p) && *p != '/' && *p != '>' && *p != '<')
node_name[i++] = *p++; node_name[i++] = *p++;
node_name[i] = 0; node_name[i] = 0;
if (!*p) if (!*p)
@ -1301,7 +1324,7 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
/* allocate new element structure in parent tree */ /* allocate new element structure in parent tree */
pnew = mxml_add_node(ptree, node_name, NULL); pnew = mxml_add_node(ptree, node_name, NULL);
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1313,7 +1336,7 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
/* found attribute */ /* found attribute */
pv = p; pv = p;
while (*pv && !isspace(*pv) && *pv != '=' && *pv != '<' && *pv != '>') while (*pv && !isspace((unsigned char)*pv) && *pv != '=' && *pv != '<' && *pv != '>')
pv++; pv++;
if (!*pv) if (!*pv)
return read_error(HERE, "Unexpected end of file"); return read_error(HERE, "Unexpected end of file");
@ -1328,7 +1351,7 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
attrib_name[len] = 0; attrib_name[len] = 0;
p = pv; p = pv;
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1339,20 +1362,21 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
return read_error(HERE, "Expect \"=\" here"); return read_error(HERE, "Expect \"=\" here");
p++; p++;
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
} }
if (!*p) if (!*p)
return read_error(HERE, "Unexpected end of file"); return read_error(HERE, "Unexpected end of file");
if (*p != '\"') if (*p != '\"' && *p != '\'')
return read_error(HERE, "Expect \'\"\' here"); return read_error(HERE, "Expect \" or \' here");
quote = *p;
p++; p++;
/* extract attribute value */ /* extract attribute value */
pv = p; pv = p;
while (*pv && *pv != '\"') while (*pv && *pv != quote)
pv++; pv++;
if (!*pv) if (!*pv)
return read_error(HERE, "Unexpected end of file"); return read_error(HERE, "Unexpected end of file");
@ -1367,7 +1391,7 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
mxml_add_attribute(pnew, attrib_name, attrib_value); mxml_add_attribute(pnew, attrib_name, attrib_value);
p = pv+1; p = pv+1;
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1381,7 +1405,7 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
/* found empty node, like <node/>, just skip closing bracket */ /* found empty node, like <node/>, just skip closing bracket */
p++; p++;
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1399,7 +1423,7 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
/* check if we have sub-element or value */ /* check if we have sub-element or value */
pv = p; pv = p;
while (*pv && isspace(*pv)) { while (*pv && isspace((unsigned char)*pv)) {
if (*pv == '\n') if (*pv == '\n')
line_number++; line_number++;
pv++; pv++;
@ -1451,10 +1475,12 @@ PMXML_NODE mxml_parse_buffer(char *buf, char *error, int error_size)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size) /**
/* parse !ENTYTY entries of XML files and replace with references. Return 0 * parse !ENTYTY entries of XML files and replace with references.
in case of no errors, return error description. Optional file_name is used * Return 0 in case of no errors, return error description.
for error reporting if called from mxml_parse_file() */ * Optional file_name is used for error reporting if called from mxml_parse_file()
*/
int mxml_parse_entity(char **buf, const char *file_name, char *error, int error_size)
{ {
char *p; char *p;
char *pv; char *pv;
@ -1525,7 +1551,7 @@ int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
/* found new entity */ /* found new entity */
p++; p++;
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1575,7 +1601,7 @@ int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
/* extract entity name */ /* extract entity name */
p = pv; p = pv;
while (*p && isspace(*p) && *p != '<' && *p != '>') { while (*p && isspace((unsigned char)*p) && *p != '<' && *p != '>') {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1596,7 +1622,7 @@ int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
} }
pv = p; pv = p;
while (*pv && !isspace(*pv) && *pv != '<' && *pv != '>') while (*pv && !isspace((unsigned char)*pv) && *pv != '<' && *pv != '>')
pv++; pv++;
if (!*pv) { if (!*pv) {
@ -1619,7 +1645,7 @@ int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
entity_name[nentity][0] = '&'; entity_name[nentity][0] = '&';
i = 1; i = 1;
entity_name[nentity][i] = 0; entity_name[nentity][i] = 0;
while (*p && !isspace(*p) && *p != '/' && *p != '>' && *p != '<' && i < 253) while (*p && !isspace((unsigned char)*p) && *p != '/' && *p != '>' && *p != '<' && i < 253)
entity_name[nentity][i++] = *p++; entity_name[nentity][i++] = *p++;
entity_name[nentity][i++] = ';'; entity_name[nentity][i++] = ';';
entity_name[nentity][i] = 0; entity_name[nentity][i] = 0;
@ -1640,7 +1666,7 @@ int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
} }
/* extract replacement or SYSTEM */ /* extract replacement or SYSTEM */
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1669,7 +1695,7 @@ int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
} }
/* extract replacement */ /* extract replacement */
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1754,7 +1780,7 @@ int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
free(replacement); free(replacement);
p = pv; p = pv;
while (*p && isspace(*p)) { while (*p && isspace((unsigned char)*p)) {
if (*p == '\n') if (*p == '\n')
line_number++; line_number++;
p++; p++;
@ -1894,9 +1920,11 @@ int mxml_parse_entity(char **buf, char *file_name, char *error, int error_size)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size) /**
/* parse a XML file and convert it into a tree of MXML_NODE's. Return NULL * parse a XML file and convert it into a tree of MXML_NODE's.
in case of an error, return error description */ * Return NULL in case of an error, return error description
*/
PMXML_NODE mxml_parse_file(const char *file_name, char *error, int error_size)
{ {
char *buf, line[1000]; char *buf, line[1000];
int fh, length; int fh, length;
@ -1944,8 +1972,10 @@ PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* write complete subtree recursively into file opened with mxml_open_document()
*/
int mxml_write_subtree(MXML_WRITER *writer, PMXML_NODE tree, int indent) int mxml_write_subtree(MXML_WRITER *writer, PMXML_NODE tree, int indent)
/* write complete subtree recursively into file opened with mxml_open_document() */
{ {
int i; int i;
@ -1967,8 +1997,10 @@ int mxml_write_subtree(MXML_WRITER *writer, PMXML_NODE tree, int indent)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
int mxml_write_tree(char *file_name, PMXML_NODE tree) /**
/* write a complete XML tree to a file */ * write a complete XML tree to a file
*/
int mxml_write_tree(const char *file_name, PMXML_NODE tree)
{ {
MXML_WRITER *writer; MXML_WRITER *writer;
int i; int i;
@ -1979,7 +2011,7 @@ int mxml_write_tree(char *file_name, PMXML_NODE tree)
return FALSE; return FALSE;
for (i=0 ; i<tree->n_children ; i++) for (i=0 ; i<tree->n_children ; i++)
if (tree->child[i].node_type == ELEMENT_NODE) // skip PI and comments if (tree->child[i].node_type == ELEMENT_NODE) /* skip PI and comments */
if (!mxml_write_subtree(writer, &tree->child[i], TRUE)) if (!mxml_write_subtree(writer, &tree->child[i], TRUE))
return FALSE; return FALSE;
@ -2019,8 +2051,10 @@ PMXML_NODE mxml_clone_tree(PMXML_NODE tree)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* print XML tree for debugging
*/
void mxml_debug_tree(PMXML_NODE tree, int level) void mxml_debug_tree(PMXML_NODE tree, int level)
/* print XML tree for debugging */
{ {
int i, j; int i, j;
@ -2060,9 +2094,11 @@ void mxml_debug_tree(PMXML_NODE tree, int level)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/**
* free memory of XML tree, must be called after any
* mxml_create_root_node() or mxml_parse_file()
*/
void mxml_free_tree(PMXML_NODE tree) void mxml_free_tree(PMXML_NODE tree)
/* free memory of XML tree, must be called after any
mxml_create_root_node() or mxml_parse_file() */
{ {
int i; int i;
@ -2116,7 +2152,8 @@ void mxml_test()
*/ */
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* mxml_basename deletes any prefix ending with the last slash '/' character /**
mxml_basename deletes any prefix ending with the last slash '/' character
present in path. mxml_dirname deletes the filename portion, beginning with present in path. mxml_dirname deletes the filename portion, beginning with
the last slash '/' character to the end of path. Followings are examples the last slash '/' character to the end of path. Followings are examples
from these functions from these functions
@ -2129,7 +2166,8 @@ void mxml_test()
"path/to/test.txt" "path/to" "test.txt" "path/to/test.txt" "path/to" "test.txt"
"test.txt "." "test.txt" "test.txt "." "test.txt"
Under Windows, '\\' and ':' are recognized ad separator too. */ Under Windows, '\\' and ':' are recognized ad separator too.
*/
void mxml_basename(char *path) void mxml_basename(char *path)
{ {

43
mxml.h
View File

@ -73,53 +73,50 @@ extern "C" {
#endif #endif
#endif #endif
void mxml_suppress_date(int suppress);
MXML_WRITER *mxml_open_file(const char *file_name); MXML_WRITER *mxml_open_file(const char *file_name);
MXML_WRITER *mxml_open_buffer(void); MXML_WRITER *mxml_open_buffer(void);
int mxml_set_translate(MXML_WRITER *writer, int flag); int mxml_set_translate(MXML_WRITER *writer, int flag);
int mxml_start_element(MXML_WRITER *writer, const char *name); int mxml_start_element(MXML_WRITER *writer, const char *name);
int mxml_start_element_noindent(MXML_WRITER *writer, const char *name); int mxml_start_element_noindent(MXML_WRITER *writer, const char *name);
int mxml_end_element(MXML_WRITER *writer); int mxml_end_element(MXML_WRITER *writer);
int mxml_write_comment(MXML_WRITER *writer, const char *string); int mxml_write_comment(MXML_WRITER *writer, const char *string);
int mxml_write_element(MXML_WRITER *writer, const char *name, const char *value);
int mxml_write_attribute(MXML_WRITER *writer, const char *name, const char *value); int mxml_write_attribute(MXML_WRITER *writer, const char *name, const char *value);
int mxml_write_value(MXML_WRITER *writer, const char *value); int mxml_write_value(MXML_WRITER *writer, const char *value);
int mxml_write_empty_line(MXML_WRITER *writer);
char *mxml_close_buffer(MXML_WRITER *writer); char *mxml_close_buffer(MXML_WRITER *writer);
int mxml_close_file(MXML_WRITER *writer); int mxml_close_file(MXML_WRITER *writer);
int mxml_get_number_of_children(PMXML_NODE pnode); int mxml_get_number_of_children(PMXML_NODE pnode);
PMXML_NODE mxml_subnode(PMXML_NODE pnode, int index); PMXML_NODE mxml_subnode(PMXML_NODE pnode, int index);
PMXML_NODE mxml_find_node(PMXML_NODE tree, char *xml_path); PMXML_NODE mxml_find_node(PMXML_NODE tree, const char *xml_path);
int mxml_find_nodes(PMXML_NODE tree, char *xml_path, PMXML_NODE **nodelist); int mxml_find_nodes(PMXML_NODE tree, const char *xml_path, PMXML_NODE **nodelist);
char *mxml_get_name(PMXML_NODE pnode); char *mxml_get_name(PMXML_NODE pnode);
char *mxml_get_value(PMXML_NODE pnode); char *mxml_get_value(PMXML_NODE pnode);
char *mxml_get_attribute(PMXML_NODE pnode, char *name); char *mxml_get_attribute(PMXML_NODE pnode, const char *name);
int mxml_add_attribute(PMXML_NODE pnode, char *attrib_name, char *attrib_value); int mxml_add_attribute(PMXML_NODE pnode, const char *attrib_name, const char *attrib_value);
PMXML_NODE mxml_add_special_node(PMXML_NODE parent, int node_type, char *node_name, char *value); PMXML_NODE mxml_add_special_node(PMXML_NODE parent, int node_type, const char *node_name, const char *value);
PMXML_NODE mxml_add_special_node_at(PMXML_NODE parent, int node_type, char *node_name, char *value, int index); PMXML_NODE mxml_add_special_node_at(PMXML_NODE parent, int node_type, const char *node_name, const char *value, int index);
PMXML_NODE mxml_add_node(PMXML_NODE parent, char *node_name, char *value); PMXML_NODE mxml_add_node(PMXML_NODE parent, const char *node_name, const char *value);
PMXML_NODE mxml_add_node_at(PMXML_NODE parent, char *node_name, char *value, int index); PMXML_NODE mxml_add_node_at(PMXML_NODE parent, const char *node_name, const char *value, int index);
PMXML_NODE mxml_clone_tree(PMXML_NODE tree); PMXML_NODE mxml_clone_tree(PMXML_NODE tree);
int mxml_add_tree(PMXML_NODE parent, PMXML_NODE tree); int mxml_add_tree(PMXML_NODE parent, PMXML_NODE tree);
int mxml_add_tree_at(PMXML_NODE parent, PMXML_NODE tree, int index); int mxml_add_tree_at(PMXML_NODE parent, PMXML_NODE tree, int index);
int mxml_replace_node_name(PMXML_NODE pnode, char *new_name); int mxml_replace_node_name(PMXML_NODE pnode, const char *new_name);
int mxml_replace_node_value(PMXML_NODE pnode, char *value); int mxml_replace_node_value(PMXML_NODE pnode, const char *value);
int mxml_replace_subvalue(PMXML_NODE pnode, char *name, char *value); int mxml_replace_subvalue(PMXML_NODE pnode, const char *name, const char *value);
int mxml_replace_attribute_name(PMXML_NODE pnode, char *old_name, char *new_name); int mxml_replace_attribute_name(PMXML_NODE pnode, const char *old_name, const char *new_name);
int mxml_replace_attribute_value(PMXML_NODE pnode, char *attrib_name, char *attrib_value); int mxml_replace_attribute_value(PMXML_NODE pnode, const char *attrib_name, const char *attrib_value);
int mxml_delete_node(PMXML_NODE pnode); int mxml_delete_node(PMXML_NODE pnode);
int mxml_delete_attribute(PMXML_NODE, char *attrib_name); int mxml_delete_attribute(PMXML_NODE, const char *attrib_name);
PMXML_NODE mxml_create_root_node(); PMXML_NODE mxml_create_root_node();
PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size); PMXML_NODE mxml_parse_file(const char *file_name, char *error, int error_size);
PMXML_NODE mxml_parse_buffer(char *buffer, char *error, int error_size); PMXML_NODE mxml_parse_buffer(const char *buffer, char *error, int error_size);
int mxml_parse_entity(char **buf, char* file_name, char *error, int error_size); int mxml_parse_entity(char **buf, const char* file_name, char *error, int error_size);
int mxml_write_tree(char *file_name, PMXML_NODE tree); int mxml_write_tree(const char *file_name, PMXML_NODE tree);
void mxml_debug_tree(PMXML_NODE tree, int level); void mxml_debug_tree(PMXML_NODE tree, int level);
void mxml_free_tree(PMXML_NODE tree); void mxml_free_tree(PMXML_NODE tree);