mirror of
https://github.com/michaelrsweet/mxml.git
synced 2025-05-10 06:52:08 +00:00
Add prototype and definitions for string functions and array types.
This commit is contained in:
parent
243f70768f
commit
dd903644a5
4
CHANGES
4
CHANGES
@ -1,4 +1,4 @@
|
|||||||
README - 06/15/2003
|
README - 06/18/2003
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
CHANGES IN Mini-XML 1.0.1
|
CHANGES IN Mini-XML 1.0.1
|
||||||
@ -7,6 +7,8 @@ CHANGES IN Mini-XML 1.0.1
|
|||||||
allocated string buffers for element names, attribute
|
allocated string buffers for element names, attribute
|
||||||
names, and attribute values. Previously they were
|
names, and attribute values. Previously they were
|
||||||
capped at 16383, 255, and 255 bytes, respectively.
|
capped at 16383, 255, and 255 bytes, respectively.
|
||||||
|
- Added a new mxmlLoadString() function for loading an
|
||||||
|
XML node tree from a string.
|
||||||
|
|
||||||
|
|
||||||
CHANGES IN Mini-XML 1.0
|
CHANGES IN Mini-XML 1.0
|
||||||
|
3
TODO
3
TODO
@ -1,5 +1,4 @@
|
|||||||
TODO - 06/15/2003
|
TODO - 06/18/2003
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
- Dynamically allocate memory for attribute values.
|
|
||||||
- Add C++ class.
|
- Add C++ class.
|
||||||
|
@ -30,8 +30,10 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr><td><tt>MXML_ELEMENT</tt></td><td>XML element with attributes</td></tr>
|
<tr><td><tt>MXML_ELEMENT</tt></td><td>XML element with attributes</td></tr>
|
||||||
<tr><td><tt>MXML_INTEGER</tt></td><td>Integer value</td></tr>
|
<tr><td><tt>MXML_INTEGER</tt></td><td>Integer value</td></tr>
|
||||||
|
<tr><td><tt>MXML_INTEGER_ARRAY</tt></td><td>Integer array value</td></tr>
|
||||||
<tr><td><tt>MXML_OPAQUE</tt></td><td>Opaque string</td></tr>
|
<tr><td><tt>MXML_OPAQUE</tt></td><td>Opaque string</td></tr>
|
||||||
<tr><td><tt>MXML_REAL</tt></td><td>Real value</td></tr>
|
<tr><td><tt>MXML_REAL</tt></td><td>Real value</td></tr>
|
||||||
|
<tr><td><tt>MXML_REAL_ARRAY</tt></td><td>Real array value</td></tr>
|
||||||
<tr><td><tt>MXML_TEXT</tt></td><td>Text fragment</td></tr>
|
<tr><td><tt>MXML_TEXT</tt></td><td>Text fragment</td></tr>
|
||||||
</tbody></table></p>
|
</tbody></table></p>
|
||||||
<h1><a name="_functions">Functions</a></h1>
|
<h1><a name="_functions">Functions</a></h1>
|
||||||
@ -42,6 +44,7 @@
|
|||||||
<li><a href="#mxmlElementSetAttr"><tt>mxmlElementSetAttr()</tt></a></li>
|
<li><a href="#mxmlElementSetAttr"><tt>mxmlElementSetAttr()</tt></a></li>
|
||||||
<li><a href="#mxmlFindElement"><tt>mxmlFindElement()</tt></a></li>
|
<li><a href="#mxmlFindElement"><tt>mxmlFindElement()</tt></a></li>
|
||||||
<li><a href="#mxmlLoadFile"><tt>mxmlLoadFile()</tt></a></li>
|
<li><a href="#mxmlLoadFile"><tt>mxmlLoadFile()</tt></a></li>
|
||||||
|
<li><a href="#mxmlLoadString"><tt>mxmlLoadString()</tt></a></li>
|
||||||
<li><a href="#mxmlNewElement"><tt>mxmlNewElement()</tt></a></li>
|
<li><a href="#mxmlNewElement"><tt>mxmlNewElement()</tt></a></li>
|
||||||
<li><a href="#mxmlNewInteger"><tt>mxmlNewInteger()</tt></a></li>
|
<li><a href="#mxmlNewInteger"><tt>mxmlNewInteger()</tt></a></li>
|
||||||
<li><a href="#mxmlNewOpaque"><tt>mxmlNewOpaque()</tt></a></li>
|
<li><a href="#mxmlNewOpaque"><tt>mxmlNewOpaque()</tt></a></li>
|
||||||
@ -49,6 +52,7 @@
|
|||||||
<li><a href="#mxmlNewText"><tt>mxmlNewText()</tt></a></li>
|
<li><a href="#mxmlNewText"><tt>mxmlNewText()</tt></a></li>
|
||||||
<li><a href="#mxmlRemove"><tt>mxmlRemove()</tt></a></li>
|
<li><a href="#mxmlRemove"><tt>mxmlRemove()</tt></a></li>
|
||||||
<li><a href="#mxmlSaveFile"><tt>mxmlSaveFile()</tt></a></li>
|
<li><a href="#mxmlSaveFile"><tt>mxmlSaveFile()</tt></a></li>
|
||||||
|
<li><a href="#mxmlSaveString"><tt>mxmlSaveString()</tt></a></li>
|
||||||
<li><a href="#mxmlWalkNext"><tt>mxmlWalkNext()</tt></a></li>
|
<li><a href="#mxmlWalkNext"><tt>mxmlWalkNext()</tt></a></li>
|
||||||
<li><a href="#mxmlWalkPrev"><tt>mxmlWalkPrev()</tt></a></li>
|
<li><a href="#mxmlWalkPrev"><tt>mxmlWalkPrev()</tt></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -215,6 +219,34 @@ mxmlLoadFile(
|
|||||||
<h3>Returns</h3>
|
<h3>Returns</h3>
|
||||||
<p>First node or NULL if the file could not be read.</p>
|
<p>First node or NULL if the file could not be read.</p>
|
||||||
<hr noshade/>
|
<hr noshade/>
|
||||||
|
<h2><a name="mxmlLoadString">mxmlLoadString()</a></h2>
|
||||||
|
<p>Load a string into an XML node tree.
|
||||||
|
|
||||||
|
The nodes in the specified string are added to the specified top node.
|
||||||
|
If no top node is provided, the XML string MUST be well-formed with a
|
||||||
|
single parent node like <?xml> for the entire string. The callback
|
||||||
|
function returns the value type that should be used for child nodes.
|
||||||
|
If MXML_NO_CALLBACK is specified then all child nodes will be either
|
||||||
|
MXML_ELEMENT or MXML_TEXT nodes.</p>
|
||||||
|
<h3>Syntax</h3>
|
||||||
|
<pre>
|
||||||
|
<a href="#mxml_node_t">mxml_node_t</a> *
|
||||||
|
mxmlLoadString(
|
||||||
|
<a href="#mxml_node_t">mxml_node_t</a> * top,
|
||||||
|
const char * s,
|
||||||
|
<a href="#mxml_type_t">mxml_type_t</a> (*cb)(mxml_node_t *));
|
||||||
|
</pre>
|
||||||
|
<h3>Arguments</h3>
|
||||||
|
<p class="table"><table align="center" border="1" width="80%">
|
||||||
|
<thead><tr><th>Name</th><th>Description</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td><tt>top</tt></td><td>Top node</td></tr>
|
||||||
|
<tr><td><tt>s</tt></td><td>String to load</td></tr>
|
||||||
|
<tr><td><tt>(*cb)(mxml_node_t *)</tt></td><td>Callback function or MXML_NO_CALLBACK</td></tr>
|
||||||
|
</tbody></table></p>
|
||||||
|
<h3>Returns</h3>
|
||||||
|
<p>First node or NULL if the string has errors.</p>
|
||||||
|
<hr noshade/>
|
||||||
<h2><a name="mxmlNewElement">mxmlNewElement()</a></h2>
|
<h2><a name="mxmlNewElement">mxmlNewElement()</a></h2>
|
||||||
<p>Create a new element node.
|
<p>Create a new element node.
|
||||||
|
|
||||||
@ -382,6 +414,33 @@ mxmlSaveFile(
|
|||||||
<h3>Returns</h3>
|
<h3>Returns</h3>
|
||||||
<p>0 on success, -1 on error.</p>
|
<p>0 on success, -1 on error.</p>
|
||||||
<hr noshade/>
|
<hr noshade/>
|
||||||
|
<h2><a name="mxmlSaveString">mxmlSaveString()</a></h2>
|
||||||
|
<p>Save an XML node tree to a string.
|
||||||
|
|
||||||
|
This function returns the total number of bytes that would be
|
||||||
|
required for the string but only copies (bufsize - 1) characters
|
||||||
|
into the specified buffer.</p>
|
||||||
|
<h3>Syntax</h3>
|
||||||
|
<pre>
|
||||||
|
int
|
||||||
|
mxmlSaveString(
|
||||||
|
<a href="#mxml_node_t">mxml_node_t</a> * node,
|
||||||
|
char * buffer,
|
||||||
|
int bufsize,
|
||||||
|
int (*cb)(mxml_node_t *int));
|
||||||
|
</pre>
|
||||||
|
<h3>Arguments</h3>
|
||||||
|
<p class="table"><table align="center" border="1" width="80%">
|
||||||
|
<thead><tr><th>Name</th><th>Description</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td><tt>node</tt></td><td>Node to write</td></tr>
|
||||||
|
<tr><td><tt>buffer</tt></td><td>String buffer</td></tr>
|
||||||
|
<tr><td><tt>bufsize</tt></td><td>Size of string buffer</td></tr>
|
||||||
|
<tr><td><tt>(*cb)(mxml_node_t *int)</tt></td><td>Whitespace callback or MXML_NO_CALLBACK</td></tr>
|
||||||
|
</tbody></table></p>
|
||||||
|
<h3>Returns</h3>
|
||||||
|
<p>Size of string</p>
|
||||||
|
<hr noshade/>
|
||||||
<h2><a name="mxmlWalkNext">mxmlWalkNext()</a></h2>
|
<h2><a name="mxmlWalkNext">mxmlWalkNext()</a></h2>
|
||||||
<p>Walk to the next logical node in the tree.
|
<p>Walk to the next logical node in the tree.
|
||||||
|
|
||||||
@ -434,7 +493,9 @@ mxmlWalkPrev(
|
|||||||
<h1><a name="_structures">Structures</a></h1>
|
<h1><a name="_structures">Structures</a></h1>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#mxml_attr_s"><tt>mxml_attr_s</tt></a></li>
|
<li><a href="#mxml_attr_s"><tt>mxml_attr_s</tt></a></li>
|
||||||
|
<li><a href="#mxml_intarray_s"><tt>mxml_intarray_s</tt></a></li>
|
||||||
<li><a href="#mxml_node_s"><tt>mxml_node_s</tt></a></li>
|
<li><a href="#mxml_node_s"><tt>mxml_node_s</tt></a></li>
|
||||||
|
<li><a href="#mxml_realarray_s"><tt>mxml_realarray_s</tt></a></li>
|
||||||
<li><a href="#mxml_text_s"><tt>mxml_text_s</tt></a></li>
|
<li><a href="#mxml_text_s"><tt>mxml_text_s</tt></a></li>
|
||||||
<li><a href="#mxml_value_s"><tt>mxml_value_s</tt></a></li>
|
<li><a href="#mxml_value_s"><tt>mxml_value_s</tt></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -457,6 +518,24 @@ struct mxml_attr_s
|
|||||||
<tr><td><tt>value</tt></td><td>Attribute value</td></tr>
|
<tr><td><tt>value</tt></td><td>Attribute value</td></tr>
|
||||||
</tbody></table></p>
|
</tbody></table></p>
|
||||||
<hr noshade/>
|
<hr noshade/>
|
||||||
|
<h2><a name="mxml_intarray_s">mxml_intarray_s</a></h2>
|
||||||
|
<p>An XML integer array value.</p>
|
||||||
|
<h3>Definition</h3>
|
||||||
|
<pre>
|
||||||
|
struct mxml_intarray_s
|
||||||
|
{
|
||||||
|
int num_values;
|
||||||
|
int * values;
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
<h3>Members</h3>
|
||||||
|
<p class="table"><table align="center" border="1" width="80%">
|
||||||
|
<thead><tr><th>Name</th><th>Description</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td><tt>num_values</tt></td><td>Number of values</td></tr>
|
||||||
|
<tr><td><tt>values</tt></td><td>The array of values</td></tr>
|
||||||
|
</tbody></table></p>
|
||||||
|
<hr noshade/>
|
||||||
<h2><a name="mxml_node_s">mxml_node_s</a></h2>
|
<h2><a name="mxml_node_s">mxml_node_s</a></h2>
|
||||||
<p>Data types...</p>
|
<p>Data types...</p>
|
||||||
<h3>Definition</h3>
|
<h3>Definition</h3>
|
||||||
@ -485,6 +564,24 @@ struct mxml_node_s
|
|||||||
<tr><td><tt>value</tt></td><td>Node value</td></tr>
|
<tr><td><tt>value</tt></td><td>Node value</td></tr>
|
||||||
</tbody></table></p>
|
</tbody></table></p>
|
||||||
<hr noshade/>
|
<hr noshade/>
|
||||||
|
<h2><a name="mxml_realarray_s">mxml_realarray_s</a></h2>
|
||||||
|
<p>An XML real array value.</p>
|
||||||
|
<h3>Definition</h3>
|
||||||
|
<pre>
|
||||||
|
struct mxml_realarray_s
|
||||||
|
{
|
||||||
|
int num_values;
|
||||||
|
double * values;
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
<h3>Members</h3>
|
||||||
|
<p class="table"><table align="center" border="1" width="80%">
|
||||||
|
<thead><tr><th>Name</th><th>Description</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td><tt>num_values</tt></td><td>Number of values</td></tr>
|
||||||
|
<tr><td><tt>values</tt></td><td>The array of values</td></tr>
|
||||||
|
</tbody></table></p>
|
||||||
|
<hr noshade/>
|
||||||
<h2><a name="mxml_text_s">mxml_text_s</a></h2>
|
<h2><a name="mxml_text_s">mxml_text_s</a></h2>
|
||||||
<p>An XML text value.</p>
|
<p>An XML text value.</p>
|
||||||
<h3>Definition</h3>
|
<h3>Definition</h3>
|
||||||
@ -526,7 +623,9 @@ struct mxml_value_s
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a href="#mxml_attr_t"><tt>mxml_attr_t</tt></a></li>
|
<li><a href="#mxml_attr_t"><tt>mxml_attr_t</tt></a></li>
|
||||||
<li><a href="#mxml_element_t"><tt>mxml_element_t</tt></a></li>
|
<li><a href="#mxml_element_t"><tt>mxml_element_t</tt></a></li>
|
||||||
|
<li><a href="#mxml_intarray_t"><tt>mxml_intarray_t</tt></a></li>
|
||||||
<li><a href="#mxml_node_t"><tt>mxml_node_t</tt></a></li>
|
<li><a href="#mxml_node_t"><tt>mxml_node_t</tt></a></li>
|
||||||
|
<li><a href="#mxml_realarray_t"><tt>mxml_realarray_t</tt></a></li>
|
||||||
<li><a href="#mxml_text_t"><tt>mxml_text_t</tt></a></li>
|
<li><a href="#mxml_text_t"><tt>mxml_text_t</tt></a></li>
|
||||||
<li><a href="#mxml_type_t"><tt>mxml_type_t</tt></a></li>
|
<li><a href="#mxml_type_t"><tt>mxml_type_t</tt></a></li>
|
||||||
<li><a href="#mxml_value_t"><tt>mxml_value_t</tt></a></li>
|
<li><a href="#mxml_value_t"><tt>mxml_value_t</tt></a></li>
|
||||||
@ -546,6 +645,13 @@ typedef struct <a href="#mxml_attr_s">mxml_attr_s</a> mxml_attr_t;
|
|||||||
typedef struct <a href="#mxml_value_s">mxml_value_s</a> mxml_element_t;
|
typedef struct <a href="#mxml_value_s">mxml_value_s</a> mxml_element_t;
|
||||||
</pre>
|
</pre>
|
||||||
<hr noshade/>
|
<hr noshade/>
|
||||||
|
<h2><a name="mxml_intarray_t">mxml_intarray_t</a></h2>
|
||||||
|
<p>An XML integer array value.</p>
|
||||||
|
<h3>Definition</h3>
|
||||||
|
<pre>
|
||||||
|
typedef struct <a href="#mxml_intarray_s">mxml_intarray_s</a> mxml_intarray_t;
|
||||||
|
</pre>
|
||||||
|
<hr noshade/>
|
||||||
<h2><a name="mxml_node_t">mxml_node_t</a></h2>
|
<h2><a name="mxml_node_t">mxml_node_t</a></h2>
|
||||||
<p>An XML node.</p>
|
<p>An XML node.</p>
|
||||||
<h3>Definition</h3>
|
<h3>Definition</h3>
|
||||||
@ -553,6 +659,13 @@ typedef struct <a href="#mxml_value_s">mxml_value_s</a> mxml_element_t;
|
|||||||
typedef struct <a href="#mxml_node_s">mxml_node_s</a> mxml_node_t;
|
typedef struct <a href="#mxml_node_s">mxml_node_s</a> mxml_node_t;
|
||||||
</pre>
|
</pre>
|
||||||
<hr noshade/>
|
<hr noshade/>
|
||||||
|
<h2><a name="mxml_realarray_t">mxml_realarray_t</a></h2>
|
||||||
|
<p>An XML real array value.</p>
|
||||||
|
<h3>Definition</h3>
|
||||||
|
<pre>
|
||||||
|
typedef struct <a href="#mxml_realarray_s">mxml_realarray_s</a> mxml_realarray_t;
|
||||||
|
</pre>
|
||||||
|
<hr noshade/>
|
||||||
<h2><a name="mxml_text_t">mxml_text_t</a></h2>
|
<h2><a name="mxml_text_t">mxml_text_t</a></h2>
|
||||||
<p>An XML text value.</p>
|
<p>An XML text value.</p>
|
||||||
<h3>Definition</h3>
|
<h3>Definition</h3>
|
||||||
@ -585,9 +698,11 @@ typedef union <a href="#mxml_value_u">mxml_value_u</a> mxml_value_t;
|
|||||||
struct mxml_value_u
|
struct mxml_value_u
|
||||||
{
|
{
|
||||||
<a href="#mxml_element_t">mxml_element_t</a> element;
|
<a href="#mxml_element_t">mxml_element_t</a> element;
|
||||||
|
<a href="#mxml_intarray_t">mxml_intarray_t</a> intarray;
|
||||||
int integer;
|
int integer;
|
||||||
char * opaque;
|
char * opaque;
|
||||||
double real;
|
double real;
|
||||||
|
<a href="#mxml_realarray_t">mxml_realarray_t</a> realarray;
|
||||||
<a href="#mxml_text_t">mxml_text_t</a> text;
|
<a href="#mxml_text_t">mxml_text_t</a> text;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
@ -596,9 +711,11 @@ struct mxml_value_u
|
|||||||
<thead><tr><th>Name</th><th>Description</th></tr></thead>
|
<thead><tr><th>Name</th><th>Description</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td><tt>element</tt></td><td>Element</td></tr>
|
<tr><td><tt>element</tt></td><td>Element</td></tr>
|
||||||
|
<tr><td><tt>intarray</tt></td><td>Integer array</td></tr>
|
||||||
<tr><td><tt>integer</tt></td><td>Integer number</td></tr>
|
<tr><td><tt>integer</tt></td><td>Integer number</td></tr>
|
||||||
<tr><td><tt>opaque</tt></td><td>Opaque string</td></tr>
|
<tr><td><tt>opaque</tt></td><td>Opaque string</td></tr>
|
||||||
<tr><td><tt>real</tt></td><td>Real number</td></tr>
|
<tr><td><tt>real</tt></td><td>Real number</td></tr>
|
||||||
|
<tr><td><tt>realarray</tt></td><td>Real array</td></tr>
|
||||||
<tr><td><tt>text</tt></td><td>Text fragment</td></tr>
|
<tr><td><tt>text</tt></td><td>Text fragment</td></tr>
|
||||||
</tbody></table></p>
|
</tbody></table></p>
|
||||||
</body>
|
</body>
|
||||||
|
345
mxml-file.c
345
mxml-file.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* "$Id: mxml-file.c,v 1.11 2003/06/15 21:31:45 mike Exp $"
|
* "$Id: mxml-file.c,v 1.12 2003/06/19 03:20:41 mike Exp $"
|
||||||
*
|
*
|
||||||
* File loading code for mini-XML, a small XML-like file parsing library.
|
* File loading code for mini-XML, a small XML-like file parsing library.
|
||||||
*
|
*
|
||||||
@ -19,7 +19,12 @@
|
|||||||
*
|
*
|
||||||
* mxmlLoadFile() - Load a file into an XML node tree.
|
* mxmlLoadFile() - Load a file into an XML node tree.
|
||||||
* mxmlSaveFile() - Save an XML tree to a file.
|
* mxmlSaveFile() - Save an XML tree to a file.
|
||||||
|
* mxmlSaveString() - Save an XML node tree to a string.
|
||||||
|
* mxml_add_char() - Add a character to a buffer, expanding as needed.
|
||||||
|
* mxml_file_getc() - Get a character from a file.
|
||||||
|
* mxml_load_data() - Load data into an XML node tree.
|
||||||
* mxml_parse_element() - Parse an element for any attributes...
|
* mxml_parse_element() - Parse an element for any attributes...
|
||||||
|
* mxml_string_getc() - Get a character from a string.
|
||||||
* mxml_write_node() - Save an XML node to a file.
|
* mxml_write_node() - Save an XML node to a file.
|
||||||
* mxml_write_string() - Write a string, escaping & and < as needed.
|
* mxml_write_string() - Write a string, escaping & and < as needed.
|
||||||
* mxml_write_ws() - Do whitespace callback...
|
* mxml_write_ws() - Do whitespace callback...
|
||||||
@ -36,13 +41,42 @@
|
|||||||
* Local functions...
|
* Local functions...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int mxml_add_char(int ch, char **ptr, char **buffer, int *bufsize);
|
static int mxml_add_char(int ch, char **ptr, char **buffer,
|
||||||
static int mxml_parse_element(mxml_node_t *node, FILE *fp);
|
int *bufsize);
|
||||||
|
static int mxml_file_getc(void *p);
|
||||||
|
static mxml_node_t *mxml_load_data(mxml_node_t *top, void *p,
|
||||||
|
mxml_type_t (*cb)(mxml_node_t *),
|
||||||
|
int (*getc_cb)(void *));
|
||||||
|
static int mxml_parse_element(mxml_node_t *node, void *p,
|
||||||
|
int (*getc_cb)(void *));
|
||||||
|
static int mxml_string_getc(void *p);
|
||||||
static int mxml_write_node(mxml_node_t *node, FILE *fp,
|
static int mxml_write_node(mxml_node_t *node, FILE *fp,
|
||||||
int (*cb)(mxml_node_t *, int), int col);
|
int (*cb)(mxml_node_t *, int), int col);
|
||||||
static int mxml_write_string(const char *s, FILE *fp);
|
static int mxml_write_string(const char *s, FILE *fp);
|
||||||
static int mxml_write_ws(mxml_node_t *node, FILE *fp,
|
static int mxml_write_ws(mxml_node_t *node, FILE *fp,
|
||||||
int (*cb)(mxml_node_t *, int), int ws, int col);
|
int (*cb)(mxml_node_t *, int), int ws,
|
||||||
|
int col);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'mxmlLoadString()' - Load a string into an XML node tree.
|
||||||
|
*
|
||||||
|
* The nodes in the specified string are added to the specified top node.
|
||||||
|
* If no top node is provided, the XML string MUST be well-formed with a
|
||||||
|
* single parent node like <?xml> for the entire string. The callback
|
||||||
|
* function returns the value type that should be used for child nodes.
|
||||||
|
* If MXML_NO_CALLBACK is specified then all child nodes will be either
|
||||||
|
* MXML_ELEMENT or MXML_TEXT nodes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mxml_node_t * /* O - First node or NULL if the string has errors. */
|
||||||
|
mxmlLoadString(mxml_node_t *top, /* I - Top node */
|
||||||
|
const char *s, /* I - String to load */
|
||||||
|
mxml_type_t (*cb)(mxml_node_t *))
|
||||||
|
/* I - Callback function or MXML_NO_CALLBACK */
|
||||||
|
{
|
||||||
|
return (mxml_load_data(top, &s, cb, mxml_string_getc));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -61,6 +95,133 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
FILE *fp, /* I - File to read from */
|
FILE *fp, /* I - File to read from */
|
||||||
mxml_type_t (*cb)(mxml_node_t *))
|
mxml_type_t (*cb)(mxml_node_t *))
|
||||||
/* I - Callback function or MXML_NO_CALLBACK */
|
/* I - Callback function or MXML_NO_CALLBACK */
|
||||||
|
{
|
||||||
|
return (mxml_load_data(top, fp, cb, mxml_file_getc));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'mxmlSaveFile()' - Save an XML tree to a file.
|
||||||
|
*
|
||||||
|
* The callback argument specifies a function that returns a whitespace
|
||||||
|
* character or nul (0) before and after each element. If MXML_NO_CALLBACK
|
||||||
|
* is specified, whitespace will only be added before MXML_TEXT nodes
|
||||||
|
* with leading whitespace and before attribute names inside opening
|
||||||
|
* element tags.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int /* O - 0 on success, -1 on error. */
|
||||||
|
mxmlSaveFile(mxml_node_t *node, /* I - Node to write */
|
||||||
|
FILE *fp, /* I - File to write to */
|
||||||
|
int (*cb)(mxml_node_t *, int))
|
||||||
|
/* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||||
|
{
|
||||||
|
int col; /* Final column */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write the node...
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((col = mxml_write_node(node, fp, cb, 0)) < 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (col > 0)
|
||||||
|
if (putc('\n', fp) < 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 0 (success)...
|
||||||
|
*/
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'mxmlSaveString()' - Save an XML node tree to a string.
|
||||||
|
*
|
||||||
|
* This function returns the total number of bytes that would be
|
||||||
|
* required for the string but only copies (bufsize - 1) characters
|
||||||
|
* into the specified buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int /* O - Size of string */
|
||||||
|
mxmlSaveString(mxml_node_t *node, /* I - Node to write */
|
||||||
|
char *buffer, /* I - String buffer */
|
||||||
|
int bufsize, /* I - Size of string buffer */
|
||||||
|
int (*cb)(mxml_node_t *, int))
|
||||||
|
/* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'mxml_add_char()' - Add a character to a buffer, expanding as needed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int /* O - 0 on success, -1 on error */
|
||||||
|
mxml_add_char(int ch, /* I - Character to add */
|
||||||
|
char **bufptr, /* IO - Current position in buffer */
|
||||||
|
char **buffer, /* IO - Current buffer */
|
||||||
|
int *bufsize) /* IO - Current buffer size */
|
||||||
|
{
|
||||||
|
char *newbuffer; /* New buffer value */
|
||||||
|
|
||||||
|
|
||||||
|
if (*bufptr >= (*buffer + *bufsize - 1))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Increase the size of the buffer...
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (*bufsize < 1024)
|
||||||
|
(*bufsize) *= 2;
|
||||||
|
else
|
||||||
|
(*bufsize) += 1024;
|
||||||
|
|
||||||
|
if ((newbuffer = realloc(*buffer, *bufsize)) == NULL)
|
||||||
|
{
|
||||||
|
free(*buffer);
|
||||||
|
|
||||||
|
fprintf(stderr, "Unable to expand string buffer to %d bytes!\n",
|
||||||
|
*bufsize);
|
||||||
|
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*bufptr = newbuffer + (*bufptr - *buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
*(*bufptr)++ = ch;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'mxml_file_getc()' - Get a character from a file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int /* O - Character or EOF */
|
||||||
|
mxml_file_getc(void *p) /* I - Pointer to file */
|
||||||
|
{
|
||||||
|
return (getc((FILE *)p));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'mxml_load_data()' - Load data into an XML node tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static mxml_node_t * /* O - First node or NULL if the file could not be read. */
|
||||||
|
mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||||
|
void *p, /* I - Pointer to data */
|
||||||
|
mxml_type_t (*cb)(mxml_node_t *),
|
||||||
|
/* I - Callback function or MXML_NO_CALLBACK */
|
||||||
|
int (*getc_cb)(void *))
|
||||||
|
/* I - Read function */
|
||||||
{
|
{
|
||||||
mxml_node_t *node, /* Current node */
|
mxml_node_t *node, /* Current node */
|
||||||
*parent; /* Current parent node */
|
*parent; /* Current parent node */
|
||||||
@ -92,7 +253,7 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
else
|
else
|
||||||
type = MXML_TEXT;
|
type = MXML_TEXT;
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = (*getc_cb)(p)) != EOF)
|
||||||
{
|
{
|
||||||
if ((ch == '<' || (isspace(ch) && type != MXML_OPAQUE)) && bufptr > buffer)
|
if ((ch == '<' || (isspace(ch) && type != MXML_OPAQUE)) && bufptr > buffer)
|
||||||
{
|
{
|
||||||
@ -155,29 +316,16 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
whitespace = 1;
|
whitespace = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add lone whitespace node if we are starting a new element and have
|
* Add lone whitespace node if we have an element and existing
|
||||||
* existing whitespace...
|
* whitespace...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ch == '<' && whitespace && type == MXML_TEXT)
|
if (ch == '<' && whitespace && type == MXML_TEXT)
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Peek at the next character and only do this if we are starting
|
|
||||||
* an open tag...
|
|
||||||
*/
|
|
||||||
|
|
||||||
ch = getc(fp);
|
|
||||||
ungetc(ch, fp);
|
|
||||||
|
|
||||||
if (ch != '/')
|
|
||||||
{
|
{
|
||||||
mxmlNewText(parent, whitespace, "");
|
mxmlNewText(parent, whitespace, "");
|
||||||
whitespace = 0;
|
whitespace = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = '<';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch == '<')
|
if (ch == '<')
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -186,7 +334,7 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
|
|
||||||
bufptr = buffer;
|
bufptr = buffer;
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = (*getc_cb)(p)) != EOF)
|
||||||
if (isspace(ch) || ch == '>' || (ch == '/' && bufptr > buffer))
|
if (isspace(ch) || ch == '>' || (ch == '/' && bufptr > buffer))
|
||||||
break;
|
break;
|
||||||
else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))
|
else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))
|
||||||
@ -205,7 +353,7 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
* Gather rest of comment...
|
* Gather rest of comment...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = (*getc_cb)(p)) != EOF)
|
||||||
{
|
{
|
||||||
if (ch == '>' && bufptr > (buffer + 4) &&
|
if (ch == '>' && bufptr > (buffer + 4) &&
|
||||||
!strncmp(bufptr - 2, "--", 2))
|
!strncmp(bufptr - 2, "--", 2))
|
||||||
@ -257,7 +405,7 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ((ch = getc(fp)) != EOF);
|
while ((ch = (*getc_cb)(p)) != EOF);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Error out if we didn't get the whole declaration...
|
* Error out if we didn't get the whole declaration...
|
||||||
@ -315,7 +463,7 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
while (ch != '>' && ch != EOF)
|
while (ch != '>' && ch != EOF)
|
||||||
ch = getc(fp);
|
ch = (*getc_cb)(p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ascend into the parent and set the value type as needed...
|
* Ascend into the parent and set the value type as needed...
|
||||||
@ -346,10 +494,10 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isspace(ch))
|
if (isspace(ch))
|
||||||
ch = mxml_parse_element(node, fp);
|
ch = mxml_parse_element(node, p, getc_cb);
|
||||||
else if (ch == '/')
|
else if (ch == '/')
|
||||||
{
|
{
|
||||||
if ((ch = getc(fp)) != '>')
|
if ((ch = (*getc_cb)(p)) != '>')
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected > but got '%c' instead for element <%s/>!\n",
|
fprintf(stderr, "Expected > but got '%c' instead for element <%s/>!\n",
|
||||||
ch, buffer);
|
ch, buffer);
|
||||||
@ -391,7 +539,7 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
entity[0] = ch;
|
entity[0] = ch;
|
||||||
entptr = entity + 1;
|
entptr = entity + 1;
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = (*getc_cb)(p)) != EOF)
|
||||||
if (!isalnum(ch) && ch != '#')
|
if (!isalnum(ch) && ch != '#')
|
||||||
break;
|
break;
|
||||||
else if (entptr < (entity + sizeof(entity) - 1))
|
else if (entptr < (entity + sizeof(entity) - 1))
|
||||||
@ -544,94 +692,15 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 'mxmlSaveFile()' - Save an XML tree to a file.
|
|
||||||
*
|
|
||||||
* The callback argument specifies a function that returns a whitespace
|
|
||||||
* character or nul (0) before and after each element. If MXML_NO_CALLBACK
|
|
||||||
* is specified, whitespace will only be added before MXML_TEXT nodes
|
|
||||||
* with leading whitespace and before attribute names inside opening
|
|
||||||
* element tags.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on error. */
|
|
||||||
mxmlSaveFile(mxml_node_t *node, /* I - Node to write */
|
|
||||||
FILE *fp, /* I - File to write to */
|
|
||||||
int (*cb)(mxml_node_t *, int))
|
|
||||||
/* I - Whitespace callback or MXML_NO_CALLBACK */
|
|
||||||
{
|
|
||||||
int col; /* Final column */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write the node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((col = mxml_write_node(node, fp, cb, 0)) < 0)
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
if (col > 0)
|
|
||||||
if (putc('\n', fp) < 0)
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return 0 (success)...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 'mxml_add_char()' - Add a character to a buffer, expanding as needed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int /* O - 0 on success, -1 on error */
|
|
||||||
mxml_add_char(int ch, /* I - Character to add */
|
|
||||||
char **bufptr, /* IO - Current position in buffer */
|
|
||||||
char **buffer, /* IO - Current buffer */
|
|
||||||
int *bufsize) /* IO - Current buffer size */
|
|
||||||
{
|
|
||||||
char *newbuffer; /* New buffer value */
|
|
||||||
|
|
||||||
|
|
||||||
if (*bufptr >= (*buffer + *bufsize - 1))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Increase the size of the buffer...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (*bufsize < 1024)
|
|
||||||
(*bufsize) *= 2;
|
|
||||||
else
|
|
||||||
(*bufsize) += 1024;
|
|
||||||
|
|
||||||
if ((newbuffer = realloc(*buffer, *bufsize)) == NULL)
|
|
||||||
{
|
|
||||||
free(*buffer);
|
|
||||||
|
|
||||||
fprintf(stderr, "Unable to expand string buffer to %d bytes!\n",
|
|
||||||
*bufsize);
|
|
||||||
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
*bufptr = newbuffer + (*bufptr - *buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
*(*bufptr)++ = ch;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'mxml_parse_element()' - Parse an element for any attributes...
|
* 'mxml_parse_element()' - Parse an element for any attributes...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int /* O - Terminating character */
|
static int /* O - Terminating character */
|
||||||
mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
||||||
FILE *fp) /* I - File to read from */
|
void *p, /* I - Data to read from */
|
||||||
|
int (*getc_cb)(void *))
|
||||||
|
/* I - Data callback */
|
||||||
{
|
{
|
||||||
int ch, /* Current character in file */
|
int ch, /* Current character in file */
|
||||||
quote; /* Quoting character */
|
quote; /* Quoting character */
|
||||||
@ -667,7 +736,7 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
|||||||
* Loop until we hit a >, /, ?, or EOF...
|
* Loop until we hit a >, /, ?, or EOF...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = (*getc_cb)(p)) != EOF)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Skip leading whitespace...
|
* Skip leading whitespace...
|
||||||
@ -686,7 +755,7 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
|||||||
* Grab the > character and print an error if it isn't there...
|
* Grab the > character and print an error if it isn't there...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
quote = getc(fp);
|
quote = (*getc_cb)(p);
|
||||||
|
|
||||||
if (quote != '>')
|
if (quote != '>')
|
||||||
{
|
{
|
||||||
@ -707,7 +776,7 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
|||||||
name[0] = ch;
|
name[0] = ch;
|
||||||
ptr = name + 1;
|
ptr = name + 1;
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = (*getc_cb)(p)) != EOF)
|
||||||
if (isspace(ch) || ch == '=' || ch == '/' || ch == '>' || ch == '?')
|
if (isspace(ch) || ch == '=' || ch == '/' || ch == '>' || ch == '?')
|
||||||
break;
|
break;
|
||||||
else if (mxml_add_char(ch, &ptr, &name, &namesize))
|
else if (mxml_add_char(ch, &ptr, &name, &namesize))
|
||||||
@ -725,7 +794,7 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
|||||||
* Read the attribute value...
|
* Read the attribute value...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((ch = getc(fp)) == EOF)
|
if ((ch = (*getc_cb)(p)) == EOF)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Missing value for attribute '%s' in element %s!\n",
|
fprintf(stderr, "Missing value for attribute '%s' in element %s!\n",
|
||||||
name, node->value.element.name);
|
name, node->value.element.name);
|
||||||
@ -741,7 +810,7 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
|||||||
quote = ch;
|
quote = ch;
|
||||||
ptr = value;
|
ptr = value;
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = (*getc_cb)(p)) != EOF)
|
||||||
if (ch == quote)
|
if (ch == quote)
|
||||||
break;
|
break;
|
||||||
else if (mxml_add_char(ch, &ptr, &value, &valsize))
|
else if (mxml_add_char(ch, &ptr, &value, &valsize))
|
||||||
@ -762,7 +831,7 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
|||||||
value[0] = ch;
|
value[0] = ch;
|
||||||
ptr = value + 1;
|
ptr = value + 1;
|
||||||
|
|
||||||
while ((ch = getc(fp)) != EOF)
|
while ((ch = (*getc_cb)(p)) != EOF)
|
||||||
if (isspace(ch) || ch == '=' || ch == '/' || ch == '>')
|
if (isspace(ch) || ch == '=' || ch == '/' || ch == '>')
|
||||||
break;
|
break;
|
||||||
else if (mxml_add_char(ch, &ptr, &value, &valsize))
|
else if (mxml_add_char(ch, &ptr, &value, &valsize))
|
||||||
@ -782,8 +851,25 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
|||||||
* Save last character in case we need it...
|
* Save last character in case we need it...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ch == '/' || ch == '>' || ch == '?')
|
if (ch == '/' || ch == '?')
|
||||||
ungetc(ch, fp);
|
{
|
||||||
|
/*
|
||||||
|
* Grab the > character and print an error if it isn't there...
|
||||||
|
*/
|
||||||
|
|
||||||
|
quote = (*getc_cb)(p);
|
||||||
|
|
||||||
|
if (quote != '>')
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Expected '>' after '%c' for element %s, but got '%c'!\n",
|
||||||
|
ch, node->value.element.name, quote);
|
||||||
|
ch = EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (ch == '>')
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the attribute...
|
* Set the attribute...
|
||||||
@ -803,6 +889,29 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'mxml_string_getc()' - Get a character from a string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int /* O - Character or EOF */
|
||||||
|
mxml_string_getc(void *p) /* I - Pointer to file */
|
||||||
|
{
|
||||||
|
int ch; /* Character */
|
||||||
|
const char **s; /* Pointer to string pointer */
|
||||||
|
|
||||||
|
|
||||||
|
s = (const char **)p;
|
||||||
|
|
||||||
|
if ((ch = *s[0]) != 0)
|
||||||
|
{
|
||||||
|
(*s)++;
|
||||||
|
return (ch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return (EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'mxml_write_node()' - Save an XML node to a file.
|
* 'mxml_write_node()' - Save an XML node to a file.
|
||||||
*/
|
*/
|
||||||
@ -1109,5 +1218,5 @@ mxml_write_ws(mxml_node_t *node, /* I - Current node */
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of "$Id: mxml-file.c,v 1.11 2003/06/15 21:31:45 mike Exp $".
|
* End of "$Id: mxml-file.c,v 1.12 2003/06/19 03:20:41 mike Exp $".
|
||||||
*/
|
*/
|
||||||
|
27
mxml.h
27
mxml.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* "$Id: mxml.h,v 1.9 2003/06/14 23:56:47 mike Exp $"
|
* "$Id: mxml.h,v 1.10 2003/06/19 03:20:41 mike Exp $"
|
||||||
*
|
*
|
||||||
* Header file for mini-XML, a small XML-like file parsing library.
|
* Header file for mini-XML, a small XML-like file parsing library.
|
||||||
*
|
*
|
||||||
@ -68,7 +68,9 @@ typedef enum mxml_type_e /**** The XML node type. ****/
|
|||||||
MXML_INTEGER, /* Integer value */
|
MXML_INTEGER, /* Integer value */
|
||||||
MXML_OPAQUE, /* Opaque string */
|
MXML_OPAQUE, /* Opaque string */
|
||||||
MXML_REAL, /* Real value */
|
MXML_REAL, /* Real value */
|
||||||
MXML_TEXT /* Text fragment */
|
MXML_TEXT, /* Text fragment */
|
||||||
|
MXML_INTEGER_ARRAY, /* Integer array value */
|
||||||
|
MXML_REAL_ARRAY /* Real array value */
|
||||||
} mxml_type_t;
|
} mxml_type_t;
|
||||||
|
|
||||||
typedef struct mxml_attr_s /**** An XML element attribute value. ****/
|
typedef struct mxml_attr_s /**** An XML element attribute value. ****/
|
||||||
@ -90,6 +92,18 @@ typedef struct mxml_text_s /**** An XML text value. ****/
|
|||||||
char *string; /* Fragment string */
|
char *string; /* Fragment string */
|
||||||
} mxml_text_t;
|
} mxml_text_t;
|
||||||
|
|
||||||
|
typedef struct mxml_intarray_s /**** An XML integer array value. ****/
|
||||||
|
{
|
||||||
|
int num_values; /* Number of values */
|
||||||
|
int *values; /* The array of values */
|
||||||
|
} mxml_intarray_t;
|
||||||
|
|
||||||
|
typedef struct mxml_realarray_s /**** An XML real array value. ****/
|
||||||
|
{
|
||||||
|
int num_values; /* Number of values */
|
||||||
|
double *values; /* The array of values */
|
||||||
|
} mxml_realarray_t;
|
||||||
|
|
||||||
typedef union mxml_value_u /**** An XML node value. ****/
|
typedef union mxml_value_u /**** An XML node value. ****/
|
||||||
{
|
{
|
||||||
mxml_element_t element; /* Element */
|
mxml_element_t element; /* Element */
|
||||||
@ -97,6 +111,8 @@ typedef union mxml_value_u /**** An XML node value. ****/
|
|||||||
char *opaque; /* Opaque string */
|
char *opaque; /* Opaque string */
|
||||||
double real; /* Real number */
|
double real; /* Real number */
|
||||||
mxml_text_t text; /* Text fragment */
|
mxml_text_t text; /* Text fragment */
|
||||||
|
mxml_intarray_t intarray; /* Integer array */
|
||||||
|
mxml_realarray_t realarray; /* Real array */
|
||||||
} mxml_value_t;
|
} mxml_value_t;
|
||||||
|
|
||||||
typedef struct mxml_node_s mxml_node_t; /**** An XML node. ****/
|
typedef struct mxml_node_s mxml_node_t; /**** An XML node. ****/
|
||||||
@ -136,6 +152,8 @@ extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top,
|
|||||||
const char *value, int descend);
|
const char *value, int descend);
|
||||||
extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp,
|
extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp,
|
||||||
mxml_type_t (*cb)(mxml_node_t *));
|
mxml_type_t (*cb)(mxml_node_t *));
|
||||||
|
extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s,
|
||||||
|
mxml_type_t (*cb)(mxml_node_t *));
|
||||||
extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
|
extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
|
||||||
extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer);
|
extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer);
|
||||||
extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
|
extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
|
||||||
@ -145,6 +163,9 @@ extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace,
|
|||||||
extern void mxmlRemove(mxml_node_t *node);
|
extern void mxmlRemove(mxml_node_t *node);
|
||||||
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp,
|
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp,
|
||||||
int (*cb)(mxml_node_t *, int));
|
int (*cb)(mxml_node_t *, int));
|
||||||
|
extern int mxmlSaveString(mxml_node_t *node, char *buffer,
|
||||||
|
int bufsize,
|
||||||
|
int (*cb)(mxml_node_t *, int));
|
||||||
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
|
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
|
||||||
int descend);
|
int descend);
|
||||||
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
||||||
@ -162,5 +183,5 @@ extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of "$Id: mxml.h,v 1.9 2003/06/14 23:56:47 mike Exp $".
|
* End of "$Id: mxml.h,v 1.10 2003/06/19 03:20:41 mike Exp $".
|
||||||
*/
|
*/
|
||||||
|
41
mxml.xml
41
mxml.xml
@ -70,6 +70,20 @@ name="top" direction="I"><type>mxml_node_t *</type><description>Top node</descri
|
|||||||
<argument name="fp" direction="I"><type>FILE *</type><description>File to read from</description></argument>
|
<argument name="fp" direction="I"><type>FILE *</type><description>File to read from</description></argument>
|
||||||
<argument name="(*cb)(mxml_node_t *)" direction="I"><type>mxml_type_t</type><description>Callback function or MXML_NO_CALLBACK</description></argument>
|
<argument name="(*cb)(mxml_node_t *)" direction="I"><type>mxml_type_t</type><description>Callback function or MXML_NO_CALLBACK</description></argument>
|
||||||
</function>
|
</function>
|
||||||
|
<function name="mxmlLoadString"><returnvalue><description>First node or NULL if the string has errors.</description><type>mxml_node_t
|
||||||
|
*</type></returnvalue>
|
||||||
|
<description>Load a string into an XML node tree.
|
||||||
|
|
||||||
|
The nodes in the specified string are added to the specified top node.
|
||||||
|
If no top node is provided, the XML string MUST be well-formed with a
|
||||||
|
single parent node like <?xml> for the entire string. The callback
|
||||||
|
function returns the value type that should be used for child nodes.
|
||||||
|
If MXML_NO_CALLBACK is specified then all child nodes will be either
|
||||||
|
MXML_ELEMENT or MXML_TEXT nodes.</description><argument
|
||||||
|
name="top" direction="I"><type>mxml_node_t *</type><description>Top node</description></argument>
|
||||||
|
<argument name="s" direction="I"><type>const char *</type><description>String to load</description></argument>
|
||||||
|
<argument name="(*cb)(mxml_node_t *)" direction="I"><type>mxml_type_t</type><description>Callback function or MXML_NO_CALLBACK</description></argument>
|
||||||
|
</function>
|
||||||
<function name="mxmlNewElement"><returnvalue><description>New node</description><type>mxml_node_t
|
<function name="mxmlNewElement"><returnvalue><description>New node</description><type>mxml_node_t
|
||||||
*</type></returnvalue>
|
*</type></returnvalue>
|
||||||
<description>Create a new element node.
|
<description>Create a new element node.
|
||||||
@ -142,6 +156,17 @@ name="node" direction="I"><type>mxml_node_t *</type><description>Node to write</
|
|||||||
<argument name="fp" direction="I"><type>FILE *</type><description>File to write to</description></argument>
|
<argument name="fp" direction="I"><type>FILE *</type><description>File to write to</description></argument>
|
||||||
<argument name="(*cb)(mxml_node_t *int)" direction="I"><type>int</type><description>Whitespace callback or MXML_NO_CALLBACK</description></argument>
|
<argument name="(*cb)(mxml_node_t *int)" direction="I"><type>int</type><description>Whitespace callback or MXML_NO_CALLBACK</description></argument>
|
||||||
</function>
|
</function>
|
||||||
|
<function name="mxmlSaveString"><returnvalue><description>Size of string</description><type>int</type></returnvalue>
|
||||||
|
<description>Save an XML node tree to a string.
|
||||||
|
|
||||||
|
This function returns the total number of bytes that would be
|
||||||
|
required for the string but only copies (bufsize - 1) characters
|
||||||
|
into the specified buffer.</description><argument
|
||||||
|
name="node" direction="I"><type>mxml_node_t *</type><description>Node to write</description></argument>
|
||||||
|
<argument name="buffer" direction="I"><type>char *</type><description>String buffer</description></argument>
|
||||||
|
<argument name="bufsize" direction="I"><type>int</type><description>Size of string buffer</description></argument>
|
||||||
|
<argument name="(*cb)(mxml_node_t *int)" direction="I"><type>int</type><description>Whitespace callback or MXML_NO_CALLBACK</description></argument>
|
||||||
|
</function>
|
||||||
<function name="mxmlWalkNext"><returnvalue><description>Next node or NULL</description><type>mxml_node_t
|
<function name="mxmlWalkNext"><returnvalue><description>Next node or NULL</description><type>mxml_node_t
|
||||||
*</type></returnvalue>
|
*</type></returnvalue>
|
||||||
<description>Walk to the next logical node in the tree.
|
<description>Walk to the next logical node in the tree.
|
||||||
@ -172,6 +197,12 @@ name="name"><type>char *</type><description>Attribute name</description></variab
|
|||||||
mxml_attr_s</type></typedef>
|
mxml_attr_s</type></typedef>
|
||||||
<typedef name="mxml_element_t"><description>An XML element value.</description><type>struct
|
<typedef name="mxml_element_t"><description>An XML element value.</description><type>struct
|
||||||
mxml_value_s</type></typedef>
|
mxml_value_s</type></typedef>
|
||||||
|
<struct name="mxml_intarray_s"><description>An XML integer array value.</description><variable
|
||||||
|
name="num_values"><type>int</type><description>Number of values</description></variable>
|
||||||
|
<variable name="values"><type>int *</type><description>The array of values</description></variable>
|
||||||
|
</struct>
|
||||||
|
<typedef name="mxml_intarray_t"><description>An XML integer array value.</description><type>struct
|
||||||
|
mxml_intarray_s</type></typedef>
|
||||||
<struct name="mxml_node_s"><description>Data types...</description><variable
|
<struct name="mxml_node_s"><description>Data types...</description><variable
|
||||||
name="child"><type>mxml_node_t *</type><description>First child node</description></variable>
|
name="child"><type>mxml_node_t *</type><description>First child node</description></variable>
|
||||||
<variable name="last_child"><type>mxml_node_t *</type><description>Last child node</description></variable>
|
<variable name="last_child"><type>mxml_node_t *</type><description>Last child node</description></variable>
|
||||||
@ -182,6 +213,12 @@ name="child"><type>mxml_node_t *</type><description>First child node</descriptio
|
|||||||
<variable name="value"><type>mxml_value_t</type><description>Node value</description></variable>
|
<variable name="value"><type>mxml_value_t</type><description>Node value</description></variable>
|
||||||
</struct>
|
</struct>
|
||||||
<typedef name="mxml_node_t"><type>struct mxml_node_s</type><description>An XML node.</description><description>An XML node.</description></typedef>
|
<typedef name="mxml_node_t"><type>struct mxml_node_s</type><description>An XML node.</description><description>An XML node.</description></typedef>
|
||||||
|
<struct name="mxml_realarray_s"><description>An XML real array value.</description><variable
|
||||||
|
name="num_values"><type>int</type><description>Number of values</description></variable>
|
||||||
|
<variable name="values"><type>double *</type><description>The array of values</description></variable>
|
||||||
|
</struct>
|
||||||
|
<typedef name="mxml_realarray_t"><description>An XML real array value.</description><type>struct
|
||||||
|
mxml_realarray_s</type></typedef>
|
||||||
<struct name="mxml_text_s"><description>An XML text value.</description><variable
|
<struct name="mxml_text_s"><description>An XML text value.</description><variable
|
||||||
name="string"><type>char *</type><description>Fragment string</description></variable>
|
name="string"><type>char *</type><description>Fragment string</description></variable>
|
||||||
<variable name="whitespace"><type>int</type><description>Leading whitespace?</description></variable>
|
<variable name="whitespace"><type>int</type><description>Leading whitespace?</description></variable>
|
||||||
@ -191,8 +228,10 @@ mxml_text_s</type></typedef>
|
|||||||
<enumeration name="mxml_type_e"><description>The XML node type.</description><constant
|
<enumeration name="mxml_type_e"><description>The XML node type.</description><constant
|
||||||
name="MXML_ELEMENT"><description>XML element with attributes</description></constant>
|
name="MXML_ELEMENT"><description>XML element with attributes</description></constant>
|
||||||
<constant name="MXML_INTEGER"><description>Integer value</description></constant>
|
<constant name="MXML_INTEGER"><description>Integer value</description></constant>
|
||||||
|
<constant name="MXML_INTEGER_ARRAY"><description>Integer array value</description></constant>
|
||||||
<constant name="MXML_OPAQUE"><description>Opaque string</description></constant>
|
<constant name="MXML_OPAQUE"><description>Opaque string</description></constant>
|
||||||
<constant name="MXML_REAL"><description>Real value</description></constant>
|
<constant name="MXML_REAL"><description>Real value</description></constant>
|
||||||
|
<constant name="MXML_REAL_ARRAY"><description>Real array value</description></constant>
|
||||||
<constant name="MXML_TEXT"><description>Text fragment</description></constant>
|
<constant name="MXML_TEXT"><description>Text fragment</description></constant>
|
||||||
</enumeration>
|
</enumeration>
|
||||||
<typedef name="mxml_type_t"><description>The XML node type.</description><type>enum
|
<typedef name="mxml_type_t"><description>The XML node type.</description><type>enum
|
||||||
@ -206,8 +245,10 @@ name="attrs"><type>mxml_attr_t *</type><description>Attributes</description></va
|
|||||||
mxml_value_u</type></typedef>
|
mxml_value_u</type></typedef>
|
||||||
<union name="mxml_value_u"><description>An XML node value.</description><variable
|
<union name="mxml_value_u"><description>An XML node value.</description><variable
|
||||||
name="element"><type>mxml_element_t</type><description>Element</description></variable>
|
name="element"><type>mxml_element_t</type><description>Element</description></variable>
|
||||||
|
<variable name="intarray"><type>mxml_intarray_t</type><description>Integer array</description></variable>
|
||||||
<variable name="integer"><type>int</type><description>Integer number</description></variable>
|
<variable name="integer"><type>int</type><description>Integer number</description></variable>
|
||||||
<variable name="opaque"><type>char *</type><description>Opaque string</description></variable>
|
<variable name="opaque"><type>char *</type><description>Opaque string</description></variable>
|
||||||
<variable name="real"><type>double</type><description>Real number</description></variable>
|
<variable name="real"><type>double</type><description>Real number</description></variable>
|
||||||
|
<variable name="realarray"><type>mxml_realarray_t</type><description>Real array</description></variable>
|
||||||
<variable name="text"><type>mxml_text_t</type><description>Text fragment</description></variable>
|
<variable name="text"><type>mxml_text_t</type><description>Text fragment</description></variable>
|
||||||
</union>
|
</union>
|
||||||
|
12
testmxml.c
12
testmxml.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* "$Id: testmxml.c,v 1.8 2003/06/14 22:14:17 mike Exp $"
|
* "$Id: testmxml.c,v 1.9 2003/06/19 03:20:41 mike Exp $"
|
||||||
*
|
*
|
||||||
* Test program for mini-XML, a small XML-like file parsing library.
|
* Test program for mini-XML, a small XML-like file parsing library.
|
||||||
*
|
*
|
||||||
@ -232,12 +232,15 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
* Open the file...
|
* Open the file...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((fp = fopen(argv[1], "r")) == NULL)
|
if (argv[1][0] == '<')
|
||||||
|
tree = mxmlLoadString(NULL, argv[1], type_cb);
|
||||||
|
else if ((fp = fopen(argv[1], "r")) == NULL)
|
||||||
{
|
{
|
||||||
perror(argv[1]);
|
perror(argv[1]);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Read the file...
|
* Read the file...
|
||||||
*/
|
*/
|
||||||
@ -245,6 +248,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
tree = mxmlLoadFile(NULL, fp, type_cb);
|
tree = mxmlLoadFile(NULL, fp, type_cb);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
if (!tree)
|
if (!tree)
|
||||||
{
|
{
|
||||||
@ -379,5 +383,5 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of "$Id: testmxml.c,v 1.8 2003/06/14 22:14:17 mike Exp $".
|
* End of "$Id: testmxml.c,v 1.9 2003/06/19 03:20:41 mike Exp $".
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user