mirror of
https://github.com/michaelrsweet/mxml.git
synced 2025-05-10 06:52:08 +00:00
Updated comment and processing instruction handling - no entity support per XML specification. Added checking for invalid comment termination ("--->" is not allowed) Fixed test program to work with new ?xml handling.
This commit is contained in:
parent
0d83a3513c
commit
f5971df74b
11
CHANGES
11
CHANGES
@ -1,6 +1,15 @@
|
||||
CHANGES - 11/13/2004
|
||||
CHANGES - 01/29/2005
|
||||
--------------------
|
||||
|
||||
CHANGES IN Mini-XML 2.1.1
|
||||
|
||||
- Added support for CDATA (STR #14, STR #15)
|
||||
- Updated comment and processing instruction handling -
|
||||
no entity support per XML specification.
|
||||
- Added checking for invalid comment termination ("--->"
|
||||
is not allowed)
|
||||
|
||||
|
||||
CHANGES IN Mini-XML 2.1
|
||||
|
||||
- Added support for custom data nodes (STR #6)
|
||||
|
@ -1,5 +1,5 @@
|
||||
dnl
|
||||
dnl "$Id: configure.in,v 1.13 2004/11/13 18:26:32 mike Exp $"
|
||||
dnl "$Id$"
|
||||
dnl
|
||||
dnl Configuration script for Mini-XML, a small XML-like file parsing library.
|
||||
dnl
|
||||
@ -23,7 +23,7 @@ dnl Set the name of the config header file...
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Version number...
|
||||
VERSION=2.1
|
||||
VERSION=2.2
|
||||
AC_SUBST(VERSION)
|
||||
AC_DEFINE_UNQUOTED(MXML_VERSION, "Mini-XML v$VERSION")
|
||||
|
||||
@ -188,5 +188,5 @@ dnl Output the makefile, etc...
|
||||
AC_OUTPUT(Makefile mxml.list mxml.pc)
|
||||
|
||||
dnl
|
||||
dnl End of "$Id: configure.in,v 1.13 2004/11/13 18:26:32 mike Exp $".
|
||||
dnl End of "$Id$".
|
||||
dnl
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
|
||||
<head>
|
||||
<title>Documentation</title>
|
||||
<meta name='creator' content='Mini-XML v2.1'/>
|
||||
<meta name='creator' content='Mini-XML v2.2'/>
|
||||
<style><!--
|
||||
h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
|
||||
tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
|
||||
|
200
mxml-file.c
200
mxml-file.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml-file.c,v 1.37 2004/10/28 02:58:00 mike Exp $"
|
||||
* "$Id$"
|
||||
*
|
||||
* File loading code for Mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -37,6 +37,7 @@
|
||||
* mxml_load_data() - Load data into an XML node tree.
|
||||
* mxml_parse_element() - Parse an element for any attributes...
|
||||
* mxml_string_getc() - Get a character from a string.
|
||||
* mxml_string_putc() - Write a character to a string.
|
||||
* mxml_write_name() - Write a name string.
|
||||
* mxml_write_node() - Save an XML node to a file.
|
||||
* mxml_write_string() - Write a string, escaping & and < as needed.
|
||||
@ -984,8 +985,14 @@ mxml_file_getc(void *p, /* I - Pointer to file */
|
||||
*/
|
||||
|
||||
if (!(ch & 0x80))
|
||||
{
|
||||
#if DEBUG > 1
|
||||
printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
return (ch);
|
||||
else if (ch == 0xfe)
|
||||
}
|
||||
else if (ch == 0xfe)
|
||||
{
|
||||
/*
|
||||
* UTF-16 big-endian BOM?
|
||||
@ -1119,6 +1126,10 @@ mxml_file_getc(void *p, /* I - Pointer to file */
|
||||
break;
|
||||
}
|
||||
|
||||
#if DEBUG > 1
|
||||
printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
@ -1392,7 +1403,9 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
}
|
||||
else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))
|
||||
goto error;
|
||||
else if ((bufptr - buffer) == 3 && !strncmp(buffer, "!--", 3))
|
||||
else if (((bufptr - buffer) == 1 && buffer[0] == '?') ||
|
||||
((bufptr - buffer) == 3 && !strncmp(buffer, "!--", 3)) ||
|
||||
((bufptr - buffer) == 8 && !strncmp(buffer, "![CDATA[", 8)))
|
||||
break;
|
||||
|
||||
*bufptr = '\0';
|
||||
@ -1406,17 +1419,10 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
while ((ch = (*getc_cb)(p, &encoding)) != EOF)
|
||||
{
|
||||
if (ch == '>' && bufptr > (buffer + 4) &&
|
||||
!strncmp(bufptr - 2, "--", 2))
|
||||
bufptr[-3] != '-' && bufptr[-2] == '-' && bufptr[-1] == '-')
|
||||
break;
|
||||
else
|
||||
{
|
||||
if (ch == '&')
|
||||
if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF)
|
||||
goto error;
|
||||
|
||||
if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))
|
||||
goto error;
|
||||
}
|
||||
else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1443,6 +1449,85 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(buffer, "![CDATA["))
|
||||
{
|
||||
/*
|
||||
* Gather CDATA section...
|
||||
*/
|
||||
|
||||
while ((ch = (*getc_cb)(p, &encoding)) != EOF)
|
||||
{
|
||||
if (ch == '>' && !strncmp(bufptr - 2, "]]", 2))
|
||||
break;
|
||||
else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Error out if we didn't get the whole comment...
|
||||
*/
|
||||
|
||||
if (ch != '>')
|
||||
break;
|
||||
|
||||
/*
|
||||
* Otherwise add this as an element under the current parent...
|
||||
*/
|
||||
|
||||
*bufptr = '\0';
|
||||
|
||||
if (!mxmlNewElement(parent, buffer))
|
||||
{
|
||||
/*
|
||||
* Just print error for now...
|
||||
*/
|
||||
|
||||
mxml_error("Unable to add comment node to parent <%s>!",
|
||||
parent ? parent->value.element.name : "null");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (buffer[0] == '?')
|
||||
{
|
||||
/*
|
||||
* Gather rest of processing instruction...
|
||||
*/
|
||||
|
||||
while ((ch = (*getc_cb)(p, &encoding)) != EOF)
|
||||
{
|
||||
if (ch == '>' && bufptr > buffer && bufptr[-1] == '?')
|
||||
break;
|
||||
else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Error out if we didn't get the whole comment...
|
||||
*/
|
||||
|
||||
if (ch != '>')
|
||||
break;
|
||||
|
||||
/*
|
||||
* Otherwise add this as an element under the current parent...
|
||||
*/
|
||||
|
||||
*bufptr = '\0';
|
||||
|
||||
if (!(parent = mxmlNewElement(parent, buffer)))
|
||||
{
|
||||
/*
|
||||
* Just print error for now...
|
||||
*/
|
||||
|
||||
mxml_error("Unable to add comment node to parent <%s>!",
|
||||
parent ? parent->value.element.name : "null");
|
||||
break;
|
||||
}
|
||||
|
||||
if (cb)
|
||||
type = (*cb)(parent);
|
||||
}
|
||||
else if (buffer[0] == '!')
|
||||
{
|
||||
/*
|
||||
@ -1496,7 +1581,7 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
|
||||
parent = node;
|
||||
|
||||
if (cb && parent)
|
||||
if (cb)
|
||||
type = (*cb)(parent);
|
||||
}
|
||||
else if (buffer[0] == '/')
|
||||
@ -1921,7 +2006,13 @@ mxml_string_getc(void *p, /* I - Pointer to file */
|
||||
{
|
||||
case ENCODE_UTF8 :
|
||||
if (!(ch & 0x80))
|
||||
{
|
||||
#if DEBUG > 1
|
||||
printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
return (ch);
|
||||
}
|
||||
else if (ch == 0xfe)
|
||||
{
|
||||
/*
|
||||
@ -1966,6 +2057,10 @@ mxml_string_getc(void *p, /* I - Pointer to file */
|
||||
if (ch < 0x80)
|
||||
return (EOF);
|
||||
|
||||
#if DEBUG > 1
|
||||
printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
return (ch);
|
||||
}
|
||||
else if ((ch & 0xf0) == 0xe0)
|
||||
@ -1985,6 +2080,10 @@ mxml_string_getc(void *p, /* I - Pointer to file */
|
||||
if (ch < 0x800)
|
||||
return (EOF);
|
||||
|
||||
#if DEBUG > 1
|
||||
printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
return (ch);
|
||||
}
|
||||
else if ((ch & 0xf8) == 0xf0)
|
||||
@ -2006,6 +2105,10 @@ mxml_string_getc(void *p, /* I - Pointer to file */
|
||||
if (ch < 0x10000)
|
||||
return (EOF);
|
||||
|
||||
#if DEBUG > 1
|
||||
printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
return (ch);
|
||||
}
|
||||
else
|
||||
@ -2040,6 +2143,10 @@ mxml_string_getc(void *p, /* I - Pointer to file */
|
||||
ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000;
|
||||
}
|
||||
|
||||
#if DEBUG > 1
|
||||
printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
return (ch);
|
||||
|
||||
case ENCODE_UTF16LE :
|
||||
@ -2078,6 +2185,10 @@ mxml_string_getc(void *p, /* I - Pointer to file */
|
||||
ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000;
|
||||
}
|
||||
|
||||
#if DEBUG > 1
|
||||
printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);
|
||||
#endif /* DEBUG > 1 */
|
||||
|
||||
return (ch);
|
||||
}
|
||||
}
|
||||
@ -2266,7 +2377,30 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
|
||||
if ((*putc_cb)('<', p) < 0)
|
||||
return (-1);
|
||||
if (mxml_write_name(node->value.element.name, p, putc_cb) < 0)
|
||||
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);
|
||||
|
||||
/*
|
||||
* Prefer a newline for whitespace after ?xml...
|
||||
*/
|
||||
|
||||
if (!strncmp(node->value.element.name, "?xml", 4))
|
||||
col = MXML_WRAP;
|
||||
}
|
||||
else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0)
|
||||
return (-1);
|
||||
|
||||
col += strlen(node->value.element.name) + 1;
|
||||
@ -2316,21 +2450,10 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
if (node->child)
|
||||
{
|
||||
/*
|
||||
* The ? and ! elements are special-cases and have no end tags...
|
||||
* Write children...
|
||||
*/
|
||||
|
||||
if (node->value.element.name[0] == '?')
|
||||
{
|
||||
if ((*putc_cb)('?', p) < 0)
|
||||
return (-1);
|
||||
if ((*putc_cb)('>', p) < 0)
|
||||
return (-1);
|
||||
if ((*putc_cb)('\n', p) < 0)
|
||||
return (-1);
|
||||
|
||||
col = 0;
|
||||
}
|
||||
else if ((*putc_cb)('>', p) < 0)
|
||||
if ((*putc_cb)('>', p) < 0)
|
||||
return (-1);
|
||||
else
|
||||
col ++;
|
||||
@ -2340,8 +2463,12 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
if ((col = mxml_write_node(node->child, p, cb, col, putc_cb)) < 0)
|
||||
return (-1);
|
||||
|
||||
if (node->value.element.name[0] != '?' &&
|
||||
node->value.element.name[0] != '!')
|
||||
/*
|
||||
* 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);
|
||||
|
||||
@ -2359,8 +2486,13 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_CLOSE, col, putc_cb);
|
||||
}
|
||||
}
|
||||
else if (node->value.element.name[0] == '!')
|
||||
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
|
||||
@ -2370,12 +2502,14 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*putc_cb)(' ', p) < 0)
|
||||
return (-1);
|
||||
if ((*putc_cb)('/', p) < 0)
|
||||
return (-1);
|
||||
if ((*putc_cb)('>', p) < 0)
|
||||
return (-1);
|
||||
|
||||
col += 2;
|
||||
col += 3;
|
||||
|
||||
col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb);
|
||||
}
|
||||
@ -2575,5 +2709,5 @@ mxml_write_ws(mxml_node_t *node, /* I - Current node */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml-file.c,v 1.37 2004/10/28 02:58:00 mike Exp $".
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml-node.c,v 1.14 2004/10/28 02:58:00 mike Exp $"
|
||||
* "$Id$"
|
||||
*
|
||||
* Node support code for Mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -674,5 +674,5 @@ mxml_new(mxml_node_t *parent, /* I - Parent node */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml-node.c,v 1.14 2004/10/28 02:58:00 mike Exp $".
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
8
mxml.xml
8
mxml.xml
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<mxmldoc>
|
||||
<?xml
|
||||
version="1.0"><mxmldoc>
|
||||
<function name="mxmlAdd">
|
||||
<description>Add a node to a tree.
|
||||
|
||||
@ -484,7 +484,7 @@ string must be nul-terminated and is formatted into the new node.</description>
|
||||
<description>Printf-style frmat string</description>
|
||||
</argument>
|
||||
<argument name="..." direction="I">
|
||||
<type/> <description>Additional args as needed</description>
|
||||
<type /> <description>Additional args as needed</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlRemove">
|
||||
@ -762,7 +762,7 @@ The node is not changed if it is not a text node.</description>
|
||||
<description>Printf-style format string</description>
|
||||
</argument>
|
||||
<argument name="..." direction="I">
|
||||
<type/> <description>Additional arguments as needed</description>
|
||||
<type /> <description>Additional arguments as needed</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlWalkNext">
|
||||
|
49
test.xml
49
test.xml
@ -1,24 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<option>
|
||||
<keyword type="opaque">InputSlot</keyword>
|
||||
<default type="opaque">Auto</default>
|
||||
<text>Media Source</text>
|
||||
<order type="real">10.000000</order>
|
||||
<choice>
|
||||
<keyword type="opaque">Auto</keyword>
|
||||
<text>Auto Tray Selection</text>
|
||||
<code type="opaque"/>
|
||||
</choice>
|
||||
<choice>
|
||||
<keyword type="opaque">Upper</keyword>
|
||||
<text>Tray 1</text>
|
||||
<code type="opaque"><</MediaPosition 0>>setpagedevice</code>
|
||||
</choice>
|
||||
<choice>
|
||||
<keyword type="opaque">Lower</keyword>
|
||||
<text>Tray 2</text>
|
||||
<code type="opaque"><</MediaPosition 1>>setpagedevice</code>
|
||||
</choice>
|
||||
</option>
|
||||
<integer>123</integer>
|
||||
<string>Now is the time for all good men to come to the aid of their country.</string>
|
||||
<group>
|
||||
<option>
|
||||
<keyword type="opaque">InputSlot</keyword>
|
||||
<default type="opaque">Auto</default>
|
||||
<text>Media Source</text>
|
||||
<order type="real">10.000000</order>
|
||||
<choice>
|
||||
<keyword type="opaque">Auto</keyword>
|
||||
<text>Auto Tray Selection</text>
|
||||
<code type="opaque" />
|
||||
</choice>
|
||||
<choice>
|
||||
<keyword type="opaque">Upper</keyword>
|
||||
<text>Tray 1</text>
|
||||
<code type="opaque"><</MediaPosition 0>>setpagedevice</code>
|
||||
</choice>
|
||||
<choice>
|
||||
<keyword type="opaque">Lower</keyword>
|
||||
<text>Tray 2</text>
|
||||
<code type="opaque"><</MediaPosition 1>>setpagedevice</code>
|
||||
</choice>
|
||||
</option>
|
||||
<integer>123</integer>
|
||||
<string>Now is the time for all good men to come to the aid of their
|
||||
country.</string>
|
||||
</group>
|
||||
|
27
testmxml.c
27
testmxml.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: testmxml.c,v 1.18 2004/07/11 13:14:07 mike Exp $"
|
||||
* "$Id$"
|
||||
*
|
||||
* Test program for Mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -614,19 +614,9 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
else if (!strcmp(name, "option"))
|
||||
{
|
||||
if (where == MXML_WS_AFTER_OPEN || where == MXML_WS_AFTER_CLOSE)
|
||||
return ("\n");
|
||||
}
|
||||
else if (!strcmp(name, "choice"))
|
||||
{
|
||||
if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_BEFORE_CLOSE)
|
||||
return ("\t");
|
||||
else
|
||||
return ("\n");
|
||||
}
|
||||
else if (where == MXML_WS_BEFORE_OPEN)
|
||||
else if (where == MXML_WS_BEFORE_OPEN ||
|
||||
((!strcmp(name, "choice") || !strcmp(name, "option")) &&
|
||||
where == MXML_WS_BEFORE_CLOSE))
|
||||
{
|
||||
for (level = -1, parent = node->parent;
|
||||
parent;
|
||||
@ -634,10 +624,15 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
|
||||
|
||||
if (level > 8)
|
||||
level = 8;
|
||||
else if (level < 0)
|
||||
level = 0;
|
||||
|
||||
return (tabs + 8 - level);
|
||||
}
|
||||
else if (where == MXML_WS_AFTER_CLOSE)
|
||||
else if (where == MXML_WS_AFTER_CLOSE ||
|
||||
((!strcmp(name, "group") || !strcmp(name, "option") ||
|
||||
!strcmp(name, "choice")) &&
|
||||
where == MXML_WS_AFTER_OPEN))
|
||||
return ("\n");
|
||||
else if (!strcmp(name, "code") && where == MXML_WS_AFTER_OPEN && !node->child)
|
||||
return ("\n");
|
||||
@ -651,5 +646,5 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: testmxml.c,v 1.18 2004/07/11 13:14:07 mike Exp $".
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user