71 #pragma warning( disable: 4996)
97 #define XML_INDENT " "
99 #if defined(__GNUC__) && !defined(__MAKECINT__)
100 # define MXML_GNUC_PRINTF( format_idx, arg_idx ) \
101 __attribute__((format (printf, format_idx, arg_idx)))
102 # define MXML_GNUC_SCANF( format_idx, arg_idx ) \
103 __attribute__((format (scanf, format_idx, arg_idx)))
104 # define MXML_GNUC_FORMAT( arg_idx ) \
105 __attribute__((format_arg (arg_idx)))
107 # define MXML_GNUC_PRINTF( format_idx, arg_idx )
108 # define MXML_GNUC_SCANF( format_idx, arg_idx )
109 # define MXML_GNUC_FORMAT( arg_idx )
116 static
void mxml_encode(
char* buf,
int buf_size, const
char *src,
int src_len,
int translate);
140 if (n != 0 && --n != 0) {
142 if ((*d++ = *s++) == 0)
154 return (s - src - 1);
162 snprintf(buf,
sizeof(buf),
"%d", i);
171 snprintf(buf,
sizeof(buf),
"errno %d (%s)", err, strerror(err));
186 return realloc(p, size);
200 int len = strlen(line);
212 return (
int)write(writer->
fh, line, len);
231 assert(writer->
buffer != NULL);
236 mxml_write_line(writer,
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
239 time_t now = time(NULL);
240 std::string str = ctime(&now);
242 std::string line =
"";
243 line +=
"<!-- created by MXML on ";
277 writer->
fh = open(file_name, O_RDWR | O_CREAT | O_TRUNC |
O_TEXT, 0644);
279 if (writer->
fh == -1) {
280 std::string line =
"";
281 line +=
"Unable to open file \"";
285 fprintf(stderr,
"%s\n", line.c_str());
291 mxml_write_line(writer,
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
293 time_t now = time(NULL);
294 std::string str = ctime(&now);
296 std::string line =
"";
297 line +=
"<!-- created by MXML on ";
315 void mxml_encode(
char* buf,
int buf_size,
const char *src,
int src_len,
int translate)
317 if (buf_size <= 6*src_len) {
318 printf(
"mxml_encode: buffer size too small\n");
323 for (ps = src ; *ps ; ps++) {
340 strcpy(pd,
""");
344 strcpy(pd,
"'");
380 while ((p = strchr(p,
'&')) != NULL) {
381 if (strncmp(p,
"<", 4) == 0) {
383 memmove(p, p+3, strlen(p+3) + 1);
385 else if (strncmp(p,
">", 4) == 0) {
387 memmove(p, p+3, strlen(p+3) + 1);
389 else if (strncmp(p,
"&", 5) == 0) {
391 memmove(p, p+4, strlen(p+4) + 1);
393 else if (strncmp(p,
""", 6) == 0) {
395 memmove(p, p+5, strlen(p+5) + 1);
397 else if (strncmp(p,
"'", 6) == 0) {
399 memmove(p, p+5, strlen(p+5) + 1);
438 std::string line =
"";
440 for (i=0 ; i<writer->
level ; i++)
444 unsigned len = strlen(name);
445 unsigned name_enc_size = len*6+10;
446 char* name_enc = (
char*)
mxml_malloc(name_enc_size);
451 if (writer->
level == 0)
487 if (writer->
level == 0)
495 if (writer->
level == 0)
497 const char* line =
"/>\n";
501 std::string line =
"";
503 for (i=0 ; i<writer->
level ; i++)
510 if (writer->
level == 0)
530 std::string line =
"";
557 unsigned len = strlen(data);
558 unsigned size = 6*len + 1000;
560 memcpy(buf, data, len+1);
599 std::string line =
"";
600 for (i=0 ; i<writer->
level ; i++)
644 for (i = 0 ; i<writer->
level ; i++)
668 for (i = 0 ; i<writer->
level ; i++)
686 strcpy(root->
name,
"root");
707 assert(parent->
child);
710 if (idx < parent->n_children)
716 pchild = parent->
child+i;
722 pnode = &parent->
child[idx];
730 if (value && *value) {
731 int len = strlen(value);
733 assert(pnode->
value);
734 memcpy(pnode->
value, value, len+1);
785 pchild = parent->
child;
788 if (parent->
child != pchild) {
791 pchild = parent->
child+i;
797 assert(parent->
child);
799 if (idx < parent->n_children)
806 pchild = parent->
child+j;
819 pchild = parent->
child+i;
853 int len = strlen(attrib_value);
881 if (idx < pnode->n_children)
882 return &pnode->
child[idx];
894 if (*xml_path == 0) {
900 (*nodelist)[*found] = node;
927 char *p3, node_name[256], condition[256];
930 int i, j, k, idx, num_cond;
931 int cond_satisfied,cond_index;
938 if (*p1 && *p1 ==
'/')
943 while (*p2 && *p2 !=
'/' && *p2 !=
'[')
945 len = (size_t)p2 - (
size_t)p1;
946 if (len >=
sizeof(node_name))
949 memcpy(node_name, p1, len);
954 cond_name[num_cond][0] = cond_value[num_cond][0] = cond_type[num_cond] = 0;
959 p2 = strchr(p2,
']');
965 while (*p2 && isspace((
unsigned char)*p2))
968 if (strchr(condition,
']'))
969 *strchr(condition,
']') = 0;
972 p2 = strchr(p2,
']')+1;
973 if ((p3 = strchr(condition,
'=')) != NULL) {
974 if (condition[0] ==
'@') {
975 cond_type[num_cond] = 1;
976 mxml_strlcpy(cond_name[num_cond], &condition[1],
sizeof(cond_name[num_cond]));
978 mxml_strlcpy(cond_name[num_cond], condition,
sizeof(cond_name[num_cond]));
981 *strchr(cond_name[num_cond],
'=') = 0;
982 while (cond_name[num_cond][0] && isspace(cond_name[num_cond][strlen(cond_name[num_cond])-1]))
983 cond_name[num_cond][strlen(cond_name[num_cond])-1] = 0;
986 while (*p3 && isspace(*p3))
989 mxml_strlcpy(cond_value[num_cond], p3+1,
sizeof(cond_value[num_cond]));
990 while (cond_value[num_cond][0] && isspace(cond_value[num_cond][strlen(cond_value[num_cond])-1]))
991 cond_value[num_cond][strlen(cond_value[num_cond])-1] = 0;
992 if (cond_value[num_cond][0] && cond_value[num_cond][strlen(cond_value[num_cond])-1] ==
'\"')
993 cond_value[num_cond][strlen(cond_value[num_cond])-1] = 0;
994 }
else if (*p3 ==
'\'') {
995 mxml_strlcpy(cond_value[num_cond], p3+1,
sizeof(cond_value[num_cond]));
996 while (cond_value[num_cond][0] && isspace(cond_value[num_cond][strlen(cond_value[num_cond])-1]))
997 cond_value[num_cond][strlen(cond_value[num_cond])-1] = 0;
998 if (cond_value[num_cond][0] && cond_value[num_cond][strlen(cond_value[num_cond])-1] ==
'\'')
999 cond_value[num_cond][strlen(cond_value[num_cond])-1] = 0;
1001 mxml_strlcpy(cond_value[num_cond], p3,
sizeof(cond_value[num_cond]));
1002 while (cond_value[num_cond][0] && isspace(cond_value[num_cond][strlen(cond_value[num_cond])-1]))
1003 cond_value[num_cond][strlen(cond_value[num_cond])-1] = 0;
1014 for (k=0;k<num_cond;k++) {
1017 if (strcmp(pnode->
child[i].
name, node_name) == 0)
1030 if (cond_satisfied==num_cond) {
1032 if (idx == 0 || cond_index == idx) {
1038 if (strcmp(pnode->
child[i].
name, node_name) == 0)
1039 if (idx == 0 || ++j == idx)
1048 pnode = &pnode->
child[i];
1062 int status, found = 0;
1114 return pnode->
value;
1159 int len = strlen(value);
1165 pnode->
value = NULL;
1168 memcpy(pnode->
value, value, len+1);
1189 if (strcmp(pnode->
child[i].
name, name) == 0)
1234 int len = strlen(attrib_value);
1255 if (&parent->
child[i] == pnode)
1261 if (i < parent->n_children) {
1308 #define HERE root, file_name, line_number, error, error_size, error_line
1316 if (file_name && file_name[0]) {
1317 msg +=
"XML read error in file \"";
1323 msg +=
"XML read error, line ";
1330 va_start(argptr, format);
1331 vsnprintf(str,
sizeof(str), (
char *) format, argptr);
1340 *error_line = line_number;
1357 char node_name[256], attrib_name[256], attrib_value[1000], quote;
1359 int i,j, line_number;
1363 char *file_name = NULL;
1375 end_element =
FALSE;
1379 while (*p && isspace(*p)) {
1387 if (strncmp(p,
"!--", 3) == 0) {
1398 if (strstr(p,
"-->") == NULL)
1401 while (strncmp(p,
"-->", 3) != 0) {
1407 len = (size_t)p - (
size_t)pv;
1409 memcpy(pnew->
value, pv, len);
1410 pnew->
value[len] = 0;
1416 }
else if (*p ==
'?') {
1424 if (strstr(p,
"?>") == NULL)
1427 while (strncmp(p,
"?>", 2) != 0) {
1433 len = (size_t)p - (
size_t)pv;
1435 memcpy(pnew->
value, pv, len);
1436 pnew->
value[len] = 0;
1442 }
else if (strncmp(p,
"!DOCTYPE", 8) == 0 ) {
1446 if (strstr(p,
">") == NULL)
1450 while (*p && (*p !=
'>' || j > 0)) {
1470 while (*p && isspace((
unsigned char)*p)) {
1482 while (*p && !isspace((
unsigned char)*p) && *p !=
'/' && *p !=
'>' && *p !=
'<')
1483 node_name[i++] = *p++;
1488 return read_error(
HERE,
"Unexpected \'<\' inside element \"%s\"", node_name);
1498 if (strcmp(ptree->
name, node_name) != 0)
1515 while (*p && isspace((
unsigned char)*p)) {
1523 while (*p !=
'>' && *p !=
'/') {
1527 while (*pv && !isspace((
unsigned char)*pv) && *pv !=
'=' && *pv !=
'<' && *pv !=
'>')
1531 if (*pv ==
'<' || *pv ==
'>')
1532 return read_error(
HERE,
"Unexpected \'%c\' inside element \"%s\"", *pv, node_name);
1535 len = (size_t)pv - (
size_t)p;
1536 if (len >
sizeof(attrib_name)-1)
1537 len =
sizeof(attrib_name)-1;
1538 memcpy(attrib_name, p, len);
1539 attrib_name[len] = 0;
1543 while (*p && isspace((
unsigned char)*p)) {
1554 while (*p && isspace((
unsigned char)*p)) {
1561 if (*p !=
'\"' && *p !=
'\'')
1568 while (*pv && *pv != quote)
1573 len = (size_t)pv - (
size_t)p;
1574 if (len >
sizeof(attrib_value)-1)
1575 len =
sizeof(attrib_value)-1;
1576 memcpy(attrib_value, p, len);
1577 attrib_value[len] = 0;
1584 while (*p && isspace((
unsigned char)*p)) {
1598 while (*p && isspace((
unsigned char)*p)) {
1616 while (*pv && isspace((
unsigned char)*pv)) {
1624 if (*pv ==
'<' && *(pv+1) !=
'/') {
1633 while (*pv && *pv !=
'<') {
1641 len = (size_t)pv - (
size_t)p;
1643 memcpy(pnew->
value, p, len);
1644 pnew->
value[len] = 0;
1656 while (*p && *p !=
'<') {
1673 int mxml_parse_entity(
char **buf,
const char *file_name,
char *error,
int error_size,
int *error_line)
1678 int i, j, k, line_number, status;
1693 entity_value[ip] = NULL;
1699 if (!buf || !(*buf) || !strlen(*buf))
1702 char directoryname[FILENAME_MAX];
1707 int len = strlen(*buf);
1709 if (buffer == NULL) {
1714 memcpy(buffer, *buf, len+1);
1716 p = strstr(buffer,
"!DOCTYPE");
1722 pv = strstr(p,
"[");
1739 while (*p && isspace((
unsigned char)*p)) {
1750 if (strncmp(p,
"!--", 3) == 0) {
1753 if (strstr(p,
"-->") == NULL) {
1759 while (strncmp(p,
"-->", 3) != 0) {
1767 else if (strncmp(p,
"!ENTITY", 7) == 0) {
1776 entity_line_number[nentity] = line_number;
1785 while (*p && isspace((
unsigned char)*p) && *p !=
'<' && *p !=
'>') {
1795 if (*p ==
'<' || *p ==
'>') {
1802 while (*pv && !isspace((
unsigned char)*pv) && *pv !=
'<' && *pv !=
'>')
1810 if (*pv ==
'<' || *pv ==
'>') {
1811 read_error(
HERE,
"Unexpected \'%c\' inside entity \"%s\"", *pv, &entity_name[nentity][1]);
1816 entity_name[nentity][0] =
'&';
1818 entity_name[nentity][i] = 0;
1819 while (*p && !isspace((
unsigned char)*p) && *p !=
'/' && *p !=
'>' && *p !=
'<' && i < 253)
1820 entity_name[nentity][i++] = *p++;
1821 entity_name[nentity][i++] =
';';
1822 entity_name[nentity][i] = 0;
1830 read_error(
HERE,
"Unexpected \'<\' inside entity \"%s\"", &entity_name[nentity][1]);
1836 while (*p && isspace((
unsigned char)*p)) {
1847 read_error(
HERE,
"Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
1853 if (strncmp(p,
"SYSTEM", 6) == 0) {
1861 while (*p && isspace((
unsigned char)*p)) {
1872 read_error(
HERE,
"Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
1877 if (*p !=
'\"' && *p !=
'\'') {
1878 read_error(
HERE,
"Replacement was not found for entity \"%s\"", &entity_name[nentity][1]);
1890 while (*pv && *pv != delimiter)
1899 read_error(
HERE,
"Unexpected \'%c\' inside entity \"%s\"", *pv, &entity_name[nentity][1]);
1904 len = (int)((
size_t) pv - (size_t) p);
1906 if (replacement == NULL) {
1912 memcpy(replacement, p, len);
1913 replacement[len] = 0;
1917 mxml_strlcpy(entity_reference_name[nentity], replacement,
sizeof(entity_reference_name[nentity]));
1919 int rlen = strlen(replacement);
1920 entity_value[nentity] = (
char *)
mxml_malloc(rlen+1);
1921 if (entity_value[nentity] == NULL) {
1926 memcpy(entity_value[nentity], replacement, rlen+1);
1931 while (*p && isspace((
unsigned char)*p)) {
1945 while (*p && *p !=
'<') {
1954 for (i = 0; i < nentity; i++) {
1956 std::string filename;
1958 filename = entity_reference_name[i];
1960 filename += directoryname;
1962 filename += entity_reference_name[i];
1964 fh = open(filename.c_str(), O_RDONLY |
O_TEXT, 0644);
1967 line_number = entity_line_number[i];
1972 length = (int)lseek(fh, 0, SEEK_END);
1973 lseek(fh, 0, SEEK_SET);
1976 if (entity_value[i] == NULL) {
1982 entity_value[i][0] = 0;
1985 if (entity_value[i] == NULL) {
1993 length = (int)read(fh, entity_value[i], length);
1994 entity_value[i][length - 1] = 0;
1998 if (
mxml_parse_entity(&entity_value[i], filename.c_str(), error, error_size, error_line) != 0) {
2008 length = (int)strlen(buffer);
2009 for (i = 0; i < nentity; i++) {
2011 entity_value_length[i] = (int)strlen(entity_value[i]);
2012 entity_name_length[i] = (int)strlen(entity_name[i]);
2014 pv = strstr(p, entity_name[i]);
2016 length += entity_value_length[i] - entity_name_length[i];
2038 for (j = 0; j < nentity; j++) {
2039 if (strncmp(p, entity_name[j], entity_name_length[j]) == 0) {
2040 for (k = 0; k < (int) entity_value_length[j]; k++)
2041 *pv++ = entity_value[j][k];
2042 p += entity_name_length[j];
2058 if (entity_value[ip] != NULL)
2075 int fh = open(file_name, O_RDONLY |
O_TEXT, 0644);
2078 std::string msg =
"";
2079 msg +=
"Cannot open file \"";
2087 off_t length = lseek(fh, 0, SEEK_END);
2088 lseek(fh, 0, SEEK_SET);
2093 std::string msg =
"";
2094 msg +=
"Cannot allocate buffer size ";
2096 msg +=
" for file \"";
2105 int rd = read(fh, buf, length);
2107 std::string msg =
"";
2108 msg +=
"Cannot read file \"";
2110 msg +=
"\", read of ";
2112 msg +=
" returned ";
2209 len = strlen(p) + 1;
2210 if (len > *buffer_size) {
2234 clone->
value = NULL;
2242 clone->
child = NULL;
2259 for (i=0 ; i<level ; i++)
2261 printf(
"Name: %s\n", tree->
name);
2262 for (i=0 ; i<level ; i++)
2264 printf(
"Valu: %s\n", tree->
value);
2265 for (i=0 ; i<level ; i++)
2268 for (i=0 ; i<level ; i++)
2271 for (i=0 ; i<level ; i++)
2276 for (i=0 ; i<level ; i++)
2282 for (i=0 ; i<level ; i++)
2284 printf(
"Addr: %08zX\n", (
size_t)tree);
2285 for (i=0 ; i<level ; i++)
2287 printf(
"Prnt: %08zX\n", (
size_t)tree->
parent);
2288 for (i=0 ; i<level ; i++)
2328 if (tree->
parent == NULL)
2378 char str[FILENAME_MAX];
2391 || *p ==
':' || *p ==
'\\'
2410 if (!path || strlen(path) == 0)
2413 p = strrchr(path,
'/');
2415 pv = strrchr(path,
':');
2418 pv = strrchr(path,
'\\');
2426 snprintf(path, FILENAME_MAX,
"%c", *p);
#define PROCESSING_INSTRUCTION_NODE
struct mxml_struct * PMXML_NODE
#define MXML_MAX_CONDITION
void mxml_free_tree(PMXML_NODE tree)
int mxml_write_comment(MXML_WRITER *writer, const char *string)
PMXML_NODE mxml_parse_file(const char *file_name, char *error, int error_size, int *error_line)
PMXML_NODE mxml_add_special_node(PMXML_NODE parent, int node_type, const char *node_name, const char *value)
int mxml_get_line_number_start(PMXML_NODE pnode)
int mxml_start_element(MXML_WRITER *writer, const char *name)
int mxml_add_attribute(PMXML_NODE pnode, const char *attrib_name, const char *attrib_value)
static std::string toStrerror(int err)
static void * mxml_realloc(void *p, size_t size)
int mxml_end_element(MXML_WRITER *writer)
int mxml_replace_subvalue(PMXML_NODE pnode, const char *name, const char *value)
void mxml_dirname(char *path)
static int mxml_start_element1(MXML_WRITER *writer, const char *name, int indent)
PMXML_NODE mxml_find_node(PMXML_NODE tree, const char *xml_path)
void mxml_suppress_date(int suppress)
static void * mxml_malloc(size_t size)
int mxml_delete_node(PMXML_NODE pnode)
static int mxml_write_line(MXML_WRITER *writer, const char *line)
int mxml_replace_node_value(PMXML_NODE pnode, const char *value)
MXML_WRITER * mxml_open_buffer(void)
int mxml_replace_attribute_name(PMXML_NODE pnode, const char *old_name, const char *new_name)
PMXML_NODE mxml_parse_buffer(const char *buf, char *error, int error_size, int *error_line)
static size_t mxml_strlcpy(char *dst, const char *src, size_t size)
MXML_WRITER * mxml_open_file(const char *file_name)
static int mxml_add_resultnode(PMXML_NODE node, const char *xml_path, PMXML_NODE **nodelist, int *found)
int mxml_write_tree(const char *file_name, PMXML_NODE tree)
int mxml_find_nodes(PMXML_NODE tree, const char *xml_path, PMXML_NODE **nodelist)
PMXML_NODE mxml_get_parent(PMXML_NODE pnode)
PMXML_NODE mxml_clone_tree(PMXML_NODE tree)
int mxml_close_file(MXML_WRITER *writer)
int mxml_write_attribute(MXML_WRITER *writer, const char *name, const char *value)
PMXML_NODE mxml_subnode(PMXML_NODE pnode, int idx)
static PMXML_NODE read_error(PMXML_NODE root, const char *file_name, int line_number, char *error, int error_size, int *error_line, const char *format,...) MXML_GNUC_PRINTF(7
static void mxml_decode(char *str)
int mxml_write_empty_line(MXML_WRITER *writer)
static int mxml_suppress_date_flag
int mxml_replace_node_name(PMXML_NODE pnode, const char *name)
int mxml_delete_attribute(PMXML_NODE pnode, const char *attrib_name)
PMXML_NODE mxml_add_node_at(PMXML_NODE parent, const char *node_name, const char *value, int idx)
PMXML_NODE mxml_create_root_node(void)
int mxml_add_tree_at(PMXML_NODE parent, PMXML_NODE tree, int idx)
int mxml_parse_entity(char **buf, const char *file_name, char *error, int error_size, int *error_line)
int mxml_write_value(MXML_WRITER *writer, const char *data)
void mxml_basename(char *path)
char * mxml_close_buffer(MXML_WRITER *writer)
static int mxml_write_subtree(MXML_WRITER *writer, PMXML_NODE tree, int indent)
PMXML_NODE mxml_get_node_at_line(PMXML_NODE tree, int line_number)
static PMXML_NODE static void mxml_encode(char *buf, int buf_size, const char *src, int src_len, int translate)
static int mxml_find_nodes1(PMXML_NODE tree, const char *xml_path, PMXML_NODE **nodelist, int *found)
int mxml_get_line_number_end(PMXML_NODE pnode)
#define MXML_GNUC_PRINTF(format_idx, arg_idx)
static void mxml_free(void *p)
int mxml_write_element(MXML_WRITER *writer, const char *name, const char *value)
static std::string toString(int i)
PMXML_NODE mxml_add_special_node_at(PMXML_NODE parent, int node_type, const char *node_name, const char *value, int idx)
int mxml_replace_attribute_value(PMXML_NODE pnode, const char *attrib_name, const char *attrib_value)
void mxml_debug_tree(PMXML_NODE tree, int level)
char * mxml_get_name(PMXML_NODE pnode)
int mxml_get_number_of_children(PMXML_NODE pnode)
int mxml_start_element_noindent(MXML_WRITER *writer, const char *name)
int mxml_print_tree(char *buffer, int *buffer_size, PMXML_NODE tree)
int mxml_add_tree(PMXML_NODE parent, PMXML_NODE tree)
PMXML_NODE mxml_add_node(PMXML_NODE parent, const char *node_name, const char *value)
char * mxml_get_attribute(PMXML_NODE pnode, const char *name)
char * mxml_get_value(PMXML_NODE pnode)
int mxml_set_translate(MXML_WRITER *writer, int flag)
char name[MXML_NAME_LENGTH]