Add prototype and definitions for string functions and array types.

This commit is contained in:
Michael R Sweet 2003-06-19 03:20:41 +00:00
parent 243f70768f
commit dd903644a5
7 changed files with 446 additions and 153 deletions

View File

@ -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
View File

@ -1,5 +1,4 @@
TODO - 06/15/2003 TODO - 06/18/2003
----------------- -----------------
- Dynamically allocate memory for attribute values.
- Add C++ class. - Add C++ class.

View File

@ -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 &lt;?xml&gt; 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>

View File

@ -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_write_node(mxml_node_t *node, FILE *fp, static int mxml_file_getc(void *p);
int (*cb)(mxml_node_t *, int), int col); static mxml_node_t *mxml_load_data(mxml_node_t *top, void *p,
static int mxml_write_string(const char *s, FILE *fp); mxml_type_t (*cb)(mxml_node_t *),
static int mxml_write_ws(mxml_node_t *node, FILE *fp, int (*getc_cb)(void *));
int (*cb)(mxml_node_t *, int), int ws, int col); 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,
int (*cb)(mxml_node_t *, int), int col);
static int mxml_write_string(const char *s, FILE *fp);
static int mxml_write_ws(mxml_node_t *node, FILE *fp,
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,27 +316,14 @@ 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)
{ {
/* mxmlNewText(parent, whitespace, "");
* Peek at the next character and only do this if we are starting whitespace = 0;
* an open tag...
*/
ch = getc(fp);
ungetc(ch, fp);
if (ch != '/')
{
mxmlNewText(parent, whitespace, "");
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 $".
*/ */

55
mxml.h
View File

@ -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,28 +68,42 @@ 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. ****/
{ {
char *name; /* Attribute name */ char *name; /* Attribute name */
char *value; /* Attribute value */ char *value; /* Attribute value */
} mxml_attr_t; } mxml_attr_t;
typedef struct mxml_value_s /**** An XML element value. ****/ typedef struct mxml_value_s /**** An XML element value. ****/
{ {
char *name; /* Name of element */ char *name; /* Name of element */
int num_attrs; /* Number of attributes */ int num_attrs; /* Number of attributes */
mxml_attr_t *attrs; /* Attributes */ mxml_attr_t *attrs; /* Attributes */
} mxml_element_t; } mxml_element_t;
typedef struct mxml_text_s /**** An XML text value. ****/ typedef struct mxml_text_s /**** An XML text value. ****/
{ {
int whitespace; /* Leading whitespace? */ int whitespace; /* Leading whitespace? */
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,19 +111,21 @@ 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. ****/
struct mxml_node_s /**** An XML node. ****/ struct mxml_node_s /**** An XML node. ****/
{ {
mxml_type_t type; /* Node type */ mxml_type_t type; /* Node type */
mxml_node_t *next; /* Next node under same parent */ mxml_node_t *next; /* Next node under same parent */
mxml_node_t *prev; /* Previous node under same parent */ mxml_node_t *prev; /* Previous node under same parent */
mxml_node_t *parent; /* Parent node */ mxml_node_t *parent; /* Parent node */
mxml_node_t *child; /* First child node */ mxml_node_t *child; /* First child node */
mxml_node_t *last_child; /* Last child node */ mxml_node_t *last_child; /* Last child node */
mxml_value_t value; /* Node value */ mxml_value_t value; /* Node value */
}; };
@ -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 $".
*/ */

View File

@ -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 &lt;?xml&gt; 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>

View File

@ -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,19 +232,23 @@ 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...
*/
/* tree = mxmlLoadFile(NULL, fp, type_cb);
* Read the file...
*/
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 $".
*/ */