diff --git a/CHANGES b/CHANGES index 455037a..2893007 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,8 @@ CHANGES IN Mini-XML 2.7 specific data key on UNIX-based operating systems (STR #103) - mxmlLoad* did not error out on XML with multiple root nodes (STR #101) - Fixed an issue with the _mxml_vstrdupf function (STR #107) + - mxmlSave* no longer write all siblings of the passed node, just that + node and its children (STR #109) CHANGES IN Mini-XML 2.6 diff --git a/mxml-file.c b/mxml-file.c index 3476d4c..0a8f001 100644 --- a/mxml-file.c +++ b/mxml-file.c @@ -2739,257 +2739,253 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ char s[255]; /* Temporary string */ - while (node != NULL) + /* + * Print the node value... + */ + + switch (node->type) { - /* - * Print the node value... - */ + case MXML_ELEMENT : + col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_OPEN, col, putc_cb); - switch (node->type) - { - case MXML_ELEMENT : - col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_OPEN, col, putc_cb); + if ((*putc_cb)('<', p) < 0) + return (-1); + if (node->value.element.name[0] == '?' || + !strncmp(node->value.element.name, "!--", 3) || + !strncmp(node->value.element.name, "![CDATA[", 8)) + { + /* + * Comments, CDATA, and processing instructions do not + * use character entities. + */ - if ((*putc_cb)('<', p) < 0) - return (-1); - if (node->value.element.name[0] == '?' || - !strncmp(node->value.element.name, "!--", 3) || - !strncmp(node->value.element.name, "![CDATA[", 8)) - { - /* - * Comments, CDATA, and processing instructions do not - * use character entities. - */ - - const char *ptr; /* Pointer into name */ + const char *ptr; /* Pointer into name */ - for (ptr = node->value.element.name; *ptr; ptr ++) - if ((*putc_cb)(*ptr, p) < 0) - return (-1); - } - else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0) - return (-1); + for (ptr = node->value.element.name; *ptr; ptr ++) + if ((*putc_cb)(*ptr, p) < 0) + return (-1); + } + else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0) + return (-1); - col += strlen(node->value.element.name) + 1; + col += strlen(node->value.element.name) + 1; - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) + for (i = node->value.element.num_attrs, attr = node->value.element.attrs; + i > 0; + i --, attr ++) + { + width = strlen(attr->name); + + if (attr->value) + width += strlen(attr->value) + 3; + + if (global->wrap > 0 && (col + width) > global->wrap) { - width = strlen(attr->name); - - if (attr->value) - width += strlen(attr->value) + 3; - - if (global->wrap > 0 && (col + width) > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); - - col = 0; - } - else - { - if ((*putc_cb)(' ', p) < 0) - return (-1); - - col ++; - } - - if (mxml_write_name(attr->name, p, putc_cb) < 0) + if ((*putc_cb)('\n', p) < 0) return (-1); - if (attr->value) - { - if ((*putc_cb)('=', p) < 0) - return (-1); - if ((*putc_cb)('\"', p) < 0) - return (-1); - if (mxml_write_string(attr->value, p, putc_cb) < 0) - return (-1); - if ((*putc_cb)('\"', p) < 0) - return (-1); - } - - col += width; + col = 0; } - - if (node->child) - { - /* - * Write children... - */ - - if ((*putc_cb)('>', p) < 0) - return (-1); - else - col ++; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); - - if ((col = mxml_write_node(node->child, p, cb, col, putc_cb, - global)) < 0) - return (-1); - - /* - * The ? and ! elements are special-cases and have no end tags... - */ - - if (node->value.element.name[0] != '!' && - node->value.element.name[0] != '?') - { - col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_CLOSE, col, putc_cb); - - if ((*putc_cb)('<', p) < 0) - return (-1); - if ((*putc_cb)('/', p) < 0) - return (-1); - if (mxml_write_string(node->value.element.name, p, putc_cb) < 0) - return (-1); - if ((*putc_cb)('>', p) < 0) - return (-1); - - col += strlen(node->value.element.name) + 3; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_CLOSE, col, putc_cb); - } - } - else if (node->value.element.name[0] == '!' || - node->value.element.name[0] == '?') - { - /* - * The ? and ! elements are special-cases... - */ - - if ((*putc_cb)('>', p) < 0) - return (-1); - else - col ++; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); - } else { - if ((*putc_cb)(' ', p) < 0) - return (-1); - if ((*putc_cb)('/', p) < 0) - return (-1); - if ((*putc_cb)('>', p) < 0) + if ((*putc_cb)(' ', p) < 0) return (-1); - col += 3; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); - } - break; - - case MXML_INTEGER : - if (node->prev) - { - if (global->wrap > 0 && col > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); - - col = 0; - } - else if ((*putc_cb)(' ', p) < 0) - return (-1); - else - col ++; - } - - sprintf(s, "%d", node->value.integer); - if (mxml_write_string(s, p, putc_cb) < 0) - return (-1); - - col += strlen(s); - break; - - case MXML_OPAQUE : - if (mxml_write_string(node->value.opaque, p, putc_cb) < 0) - return (-1); - - col += strlen(node->value.opaque); - break; - - case MXML_REAL : - if (node->prev) - { - if (global->wrap > 0 && col > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); - - col = 0; - } - else if ((*putc_cb)(' ', p) < 0) - return (-1); - else - col ++; - } - - sprintf(s, "%f", node->value.real); - if (mxml_write_string(s, p, putc_cb) < 0) - return (-1); - - col += strlen(s); - break; - - case MXML_TEXT : - if (node->value.text.whitespace && col > 0) - { - if (global->wrap > 0 && col > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); - - col = 0; - } - else if ((*putc_cb)(' ', p) < 0) - return (-1); - else - col ++; - } - - if (mxml_write_string(node->value.text.string, p, putc_cb) < 0) - return (-1); - - col += strlen(node->value.text.string); - break; - - case MXML_CUSTOM : - if (global->custom_save_cb) - { - char *data; /* Custom data string */ - const char *newline; /* Last newline in string */ - - - if ((data = (*global->custom_save_cb)(node)) == NULL) - return (-1); - - if (mxml_write_string(data, p, putc_cb) < 0) - return (-1); - - if ((newline = strrchr(data, '\n')) == NULL) - col += strlen(data); - else - col = strlen(newline); - - free(data); - break; + col ++; } - default : /* Should never happen */ - return (-1); - } + if (mxml_write_name(attr->name, p, putc_cb) < 0) + return (-1); - /* - * Next node... - */ + if (attr->value) + { + if ((*putc_cb)('=', p) < 0) + return (-1); + if ((*putc_cb)('\"', p) < 0) + return (-1); + if (mxml_write_string(attr->value, p, putc_cb) < 0) + return (-1); + if ((*putc_cb)('\"', p) < 0) + return (-1); + } - node = node->next; + col += width; + } + + if (node->child) + { + /* + * Write children... + */ + + mxml_node_t *child; /* Current child */ + + + if ((*putc_cb)('>', p) < 0) + return (-1); + else + col ++; + + col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + + for (child = node->child; child; child = child->next) + { + if ((col = mxml_write_node(child, p, cb, col, putc_cb, global)) < 0) + return (-1); + } + + /* + * The ? and ! elements are special-cases and have no end tags... + */ + + if (node->value.element.name[0] != '!' && + node->value.element.name[0] != '?') + { + col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_CLOSE, col, putc_cb); + + if ((*putc_cb)('<', p) < 0) + return (-1); + if ((*putc_cb)('/', p) < 0) + return (-1); + if (mxml_write_string(node->value.element.name, p, putc_cb) < 0) + return (-1); + if ((*putc_cb)('>', p) < 0) + return (-1); + + col += strlen(node->value.element.name) + 3; + + col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_CLOSE, col, putc_cb); + } + } + else if (node->value.element.name[0] == '!' || + node->value.element.name[0] == '?') + { + /* + * The ? and ! elements are special-cases... + */ + + if ((*putc_cb)('>', p) < 0) + return (-1); + else + col ++; + + col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + } + else + { + if ((*putc_cb)(' ', p) < 0) + return (-1); + if ((*putc_cb)('/', p) < 0) + return (-1); + if ((*putc_cb)('>', p) < 0) + return (-1); + + col += 3; + + col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + } + break; + + case MXML_INTEGER : + if (node->prev) + { + if (global->wrap > 0 && col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col ++; + } + + sprintf(s, "%d", node->value.integer); + if (mxml_write_string(s, p, putc_cb) < 0) + return (-1); + + col += strlen(s); + break; + + case MXML_OPAQUE : + if (mxml_write_string(node->value.opaque, p, putc_cb) < 0) + return (-1); + + col += strlen(node->value.opaque); + break; + + case MXML_REAL : + if (node->prev) + { + if (global->wrap > 0 && col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col ++; + } + + sprintf(s, "%f", node->value.real); + if (mxml_write_string(s, p, putc_cb) < 0) + return (-1); + + col += strlen(s); + break; + + case MXML_TEXT : + if (node->value.text.whitespace && col > 0) + { + if (global->wrap > 0 && col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col ++; + } + + if (mxml_write_string(node->value.text.string, p, putc_cb) < 0) + return (-1); + + col += strlen(node->value.text.string); + break; + + case MXML_CUSTOM : + if (global->custom_save_cb) + { + char *data; /* Custom data string */ + const char *newline; /* Last newline in string */ + + + if ((data = (*global->custom_save_cb)(node)) == NULL) + return (-1); + + if (mxml_write_string(data, p, putc_cb) < 0) + return (-1); + + if ((newline = strrchr(data, '\n')) == NULL) + col += strlen(data); + else + col = strlen(newline); + + free(data); + break; + } + + default : /* Should never happen */ + return (-1); } return (col);