|
|
|
@ -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); |
|
|
|
|
|
|
|
|
|
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. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
switch (node->type) |
|
|
|
|
{ |
|
|
|
|
case MXML_ELEMENT : |
|
|
|
|
col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_OPEN, col, putc_cb); |
|
|
|
|
const char *ptr; /* Pointer into name */ |
|
|
|
|
|
|
|
|
|
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 */ |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
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 (i = node->value.element.num_attrs, attr = node->value.element.attrs; |
|
|
|
|
i > 0; |
|
|
|
|
i --, attr ++) |
|
|
|
|
{ |
|
|
|
|
width = strlen(attr->name); |
|
|
|
|
|
|
|
|
|
col += strlen(node->value.element.name) + 1; |
|
|
|
|
if (attr->value) |
|
|
|
|
width += strlen(attr->value) + 3; |
|
|
|
|
|
|
|
|
|
for (i = node->value.element.num_attrs, attr = node->value.element.attrs; |
|
|
|
|
i > 0; |
|
|
|
|
i --, attr ++) |
|
|
|
|
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 ((*putc_cb)('\n', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
if (mxml_write_name(attr->name, p, putc_cb) < 0) |
|
|
|
|
col = 0; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if ((*putc_cb)(' ', 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 ++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (node->child) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* Write children... |
|
|
|
|
*/ |
|
|
|
|
if (mxml_write_name(attr->name, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
if ((*putc_cb)('>', p) < 0) |
|
|
|
|
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); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
if ((*putc_cb)('\"', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); |
|
|
|
|
col += width; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((col = mxml_write_node(node->child, p, cb, col, putc_cb, |
|
|
|
|
global)) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
if (node->child) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* Write children... |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The ? and ! elements are special-cases and have no end tags... |
|
|
|
|
*/ |
|
|
|
|
mxml_node_t *child; /* Current child */ |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
if ((*putc_cb)('>', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
|
|
|
|
|
col += strlen(node->value.element.name) + 3; |
|
|
|
|
col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); |
|
|
|
|
|
|
|
|
|
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] == '?') |
|
|
|
|
for (child = node->child; child; child = child->next) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* The ? and ! elements are special-cases... |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
if ((*putc_cb)('>', p) < 0) |
|
|
|
|
if ((col = mxml_write_node(child, p, cb, col, putc_cb, global)) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
/*
|
|
|
|
|
* The ? and ! elements are special-cases and have no end tags... |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
if (node->value.element.name[0] != '!' && |
|
|
|
|
node->value.element.name[0] != '?') |
|
|
|
|
{ |
|
|
|
|
if ((*putc_cb)(' ', p) < 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 ((*putc_cb)('/', p) < 0) |
|
|
|
|
if (mxml_write_string(node->value.element.name, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
if ((*putc_cb)('>', p) < 0) |
|
|
|
|
if ((*putc_cb)('>', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
col += 3; |
|
|
|
|
col += strlen(node->value.element.name) + 3; |
|
|
|
|
|
|
|
|
|
col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); |
|
|
|
|
col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_CLOSE, col, putc_cb); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
else if (node->value.element.name[0] == '!' || |
|
|
|
|
node->value.element.name[0] == '?') |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
* The ? and ! elements are special-cases... |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
case MXML_INTEGER : |
|
|
|
|
if (node->prev) |
|
|
|
|
{ |
|
|
|
|
if (global->wrap > 0 && col > global->wrap) |
|
|
|
|
{ |
|
|
|
|
if ((*putc_cb)('\n', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
if ((*putc_cb)('>', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
|
|
|
|
|
col = 0; |
|
|
|
|
} |
|
|
|
|
else if ((*putc_cb)(' ', p) < 0) |
|
|
|
|
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); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sprintf(s, "%d", node->value.integer); |
|
|
|
|
if (mxml_write_string(s, p, putc_cb) < 0) |
|
|
|
|
col = 0; |
|
|
|
|
} |
|
|
|
|
else if ((*putc_cb)(' ', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
col += strlen(s); |
|
|
|
|
break; |
|
|
|
|
sprintf(s, "%d", node->value.integer); |
|
|
|
|
if (mxml_write_string(s, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
case MXML_OPAQUE : |
|
|
|
|
if (mxml_write_string(node->value.opaque, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
col += strlen(s); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
col += strlen(node->value.opaque); |
|
|
|
|
break; |
|
|
|
|
case MXML_OPAQUE : |
|
|
|
|
if (mxml_write_string(node->value.opaque, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
case MXML_REAL : |
|
|
|
|
if (node->prev) |
|
|
|
|
{ |
|
|
|
|
if (global->wrap > 0 && col > global->wrap) |
|
|
|
|
{ |
|
|
|
|
if ((*putc_cb)('\n', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
col += strlen(node->value.opaque); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
col = 0; |
|
|
|
|
} |
|
|
|
|
else if ((*putc_cb)(' ', p) < 0) |
|
|
|
|
case MXML_REAL : |
|
|
|
|
if (node->prev) |
|
|
|
|
{ |
|
|
|
|
if (global->wrap > 0 && col > global->wrap) |
|
|
|
|
{ |
|
|
|
|
if ((*putc_cb)('\n', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sprintf(s, "%f", node->value.real); |
|
|
|
|
if (mxml_write_string(s, p, putc_cb) < 0) |
|
|
|
|
col = 0; |
|
|
|
|
} |
|
|
|
|
else if ((*putc_cb)(' ', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
col += strlen(s); |
|
|
|
|
break; |
|
|
|
|
sprintf(s, "%f", node->value.real); |
|
|
|
|
if (mxml_write_string(s, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
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 += strlen(s); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
col = 0; |
|
|
|
|
} |
|
|
|
|
else if ((*putc_cb)(' ', p) < 0) |
|
|
|
|
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); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mxml_write_string(node->value.text.string, p, putc_cb) < 0) |
|
|
|
|
col = 0; |
|
|
|
|
} |
|
|
|
|
else if ((*putc_cb)(' ', p) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
else |
|
|
|
|
col ++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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 (mxml_write_string(node->value.text.string, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
col += strlen(node->value.text.string); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
if ((data = (*global->custom_save_cb)(node)) == NULL) |
|
|
|
|
return (-1); |
|
|
|
|
case MXML_CUSTOM : |
|
|
|
|
if (global->custom_save_cb) |
|
|
|
|
{ |
|
|
|
|
char *data; /* Custom data string */ |
|
|
|
|
const char *newline; /* Last newline in string */ |
|
|
|
|
|
|
|
|
|
if (mxml_write_string(data, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
if ((newline = strrchr(data, '\n')) == NULL) |
|
|
|
|
col += strlen(data); |
|
|
|
|
else |
|
|
|
|
col = strlen(newline); |
|
|
|
|
if ((data = (*global->custom_save_cb)(node)) == NULL) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
free(data); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (mxml_write_string(data, p, putc_cb) < 0) |
|
|
|
|
return (-1); |
|
|
|
|
|
|
|
|
|
default : /* Should never happen */ |
|
|
|
|
return (-1); |
|
|
|
|
} |
|
|
|
|
if ((newline = strrchr(data, '\n')) == NULL) |
|
|
|
|
col += strlen(data); |
|
|
|
|
else |
|
|
|
|
col = strlen(newline); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Next node... |
|
|
|
|
*/ |
|
|
|
|
free(data); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
node = node->next; |
|
|
|
|
default : /* Should never happen */ |
|
|
|
|
return (-1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return (col); |
|
|
|
|