Prep for 0.93 release.

This commit is contained in:
Michael R Sweet 2003-06-05 13:49:14 +00:00
parent 49065790fe
commit cbbef5124f
8 changed files with 734 additions and 91 deletions

View File

@ -1,12 +1,12 @@
README - 06/04/2003
README - 06/05/2003
-------------------
CHANGES IN Mini-XML 0.93
- New mxmldoc example program that is used to track code
documentation using XML and produce HTML reference
pages.
- New mxmldoc example program that is also used to
create and update code documentation using XML and
produce HTML reference pages.
- Added mxmlAdd() and mxmlRemove() functions to add and
remove nodes from a tree. This provides more
flexibility over where the nodes are inserted and

View File

@ -1,5 +1,5 @@
#
# "$Id: Makefile.in,v 1.4 2003/06/04 16:30:39 mike Exp $"
# "$Id: Makefile.in,v 1.5 2003/06/05 13:49:14 mike Exp $"
#
# Makefile for mini-XML, a small XML-like file parsing library.
#
@ -54,7 +54,7 @@ libdir = @libdir@
LIBOBJS = mxml-attr.o mxml-file.o mxml-node.o mxml-search.o
OBJS = mxmldoc.o testmxml.o $(LIBOBJS)
TARGETS = libmxml.a mxmldoc testmxml
TARGETS = libmxml.a mxmldoc testmxml mxml.xml
#
@ -158,6 +158,15 @@ testmxml: libmxml.a testmxml.o
testmxml.o: mxml.h
#
# mxml.xml
#
mxml.xml: mxmldoc mxml.h $(LIBOBJS:.o=.c)
rm -f mxml.xml
./mxmldoc mxml.xml mxml.h $(LIBOBJS:.o=.c) >documentation.html
#
# All object files depend on the makefile...
#
@ -166,5 +175,5 @@ $(OBJS): Makefile
#
# End of "$Id: Makefile.in,v 1.4 2003/06/04 16:30:39 mike Exp $".
# End of "$Id: Makefile.in,v 1.5 2003/06/05 13:49:14 mike Exp $".
#

18
README
View File

@ -1,4 +1,4 @@
README - 06/04/2003
README - 06/05/2003
-------------------
@ -49,11 +49,10 @@ BUILDING Mini-XML
./configure --prefix=/foo
Once you have configured the software, type "make" to do the
build and then run the test program to verify that things
are working, as follows:
build and run the test program to verify that things are
working, as follows:
make
./testmxml test.xml
INSTALLING Mini-XML
@ -69,11 +68,12 @@ INSTALLING Mini-XML
DOCUMENTATION
The documentation is currently just in this README file. At
some point I'll probably do some proper documentation, but
for now just read here and look at the testmxml.c source
file for an example of reading and printing the contents of
an XML file to stdout.
The documentation is currently a work in progress. Aside
from the information that follows, the "documentation.html"
page provides a handy reference and is automatically
generated using Mini-XML. You can also look at the
"testmxml.c" and "mxmldoc.c" source files for examples of
using Mini-XML.
Mini-XML provides a single header file which you include:

11
TODO Normal file
View File

@ -0,0 +1,11 @@
TODO - 06/05/2003
-----------------
- Finish up documentation generator, specifically:
- Structure/class/enumeration/typedef support.
- Support for argument names with type info,
e.g. "int (*cb)(mxml_node_t *)"
- Links at top to jump to specific sections?
- Code documentation cleanup to take advantage of mxmldoc...

338
documentation.html Normal file
View File

@ -0,0 +1,338 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Documentation</title>
<style><!--
h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
pre { font-weight: bold; color: #7f0000; margin-left: 5em; }
--></style>
</head>
<body>
<h1>Functions</h1>
<ul>
<li><a href="#mxmlAdd"><tt>mxmlAdd()</tt></a></li>
<li><a href="#mxmlDelete"><tt>mxmlDelete()</tt></a></li>
<li><a href="#mxmlElementGetAttr"><tt>mxmlElementGetAttr()</tt></a></li>
<li><a href="#mxmlElementSetAttr"><tt>mxmlElementSetAttr()</tt></a></li>
<li><a href="#mxmlFindElement"><tt>mxmlFindElement()</tt></a></li>
<li><a href="#mxmlLoadFile"><tt>mxmlLoadFile()</tt></a></li>
<li><a href="#mxmlNewElement"><tt>mxmlNewElement()</tt></a></li>
<li><a href="#mxmlNewInteger"><tt>mxmlNewInteger()</tt></a></li>
<li><a href="#mxmlNewOpaque"><tt>mxmlNewOpaque()</tt></a></li>
<li><a href="#mxmlNewReal"><tt>mxmlNewReal()</tt></a></li>
<li><a href="#mxmlNewText"><tt>mxmlNewText()</tt></a></li>
<li><a href="#mxmlRemove"><tt>mxmlRemove()</tt></a></li>
<li><a href="#mxmlSaveFile"><tt>mxmlSaveFile()</tt></a></li>
<li><a href="#mxmlWalkNext"><tt>mxmlWalkNext()</tt></a></li>
<li><a href="#mxmlWalkPrev"><tt>mxmlWalkPrev()</tt></a></li>
</ul>
<hr noshade/>
<h2><a name="mxmlAdd">mxmlAdd()</a></h2>
<p>Add a node to a tree.</p>
<h3>Syntax</h3>
<pre>
void
mxmlAdd(
mxml_node_t * parent,
int where,
mxml_node_t * child,
mxml_node_t * node);
</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>parent</tt></td><td>Parent node</td></tr>
<tr><td><tt>where</tt></td><td>Where to add</td></tr>
<tr><td><tt>child</tt></td><td>Child node for where</td></tr>
<tr><td><tt>node</tt></td><td>Node to add</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>Nothing.</p>
<hr noshade/>
<h2><a name="mxmlDelete">mxmlDelete()</a></h2>
<p>Delete a node and all of its children.</p>
<h3>Syntax</h3>
<pre>
void
mxmlDelete(
mxml_node_t * node);
</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</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>Nothing.</p>
<hr noshade/>
<h2><a name="mxmlElementGetAttr">mxmlElementGetAttr()</a></h2>
<p>Get an attribute.</p>
<h3>Syntax</h3>
<pre>
const char *
mxmlElementGetAttr(
mxml_node_t * node,
const char * name);
</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>Element node</td></tr>
<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>Attribute value or NULL</p>
<hr noshade/>
<h2><a name="mxmlElementSetAttr">mxmlElementSetAttr()</a></h2>
<p>Set an attribute.</p>
<h3>Syntax</h3>
<pre>
void
mxmlElementSetAttr(
mxml_node_t * node,
const char * name,
const char * value);
</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>Element node</td></tr>
<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
<tr><td><tt>value</tt></td><td>Attribute value</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>Nothing.</p>
<hr noshade/>
<h2><a name="mxmlFindElement">mxmlFindElement()</a></h2>
<p>Find the named element.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlFindElement(
mxml_node_t * node,
mxml_node_t * top,
const char * name,
const char * attr,
const char * value,
int descend);
</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>Current node</td></tr>
<tr><td><tt>top</tt></td><td>Top node</td></tr>
<tr><td><tt>name</tt></td><td>Element name or NULL for any</td></tr>
<tr><td><tt>attr</tt></td><td>Attribute name, or NULL for none</td></tr>
<tr><td><tt>value</tt></td><td>Attribute value, or NULL for any</td></tr>
<tr><td><tt>descend</tt></td><td>Descend into tree?</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>Element node or NULL</p>
<hr noshade/>
<h2><a name="mxmlLoadFile">mxmlLoadFile()</a></h2>
<p>Load a file into an XML node tree.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlLoadFile(
mxml_node_t * top,
FILE * fp,
mxml_type_t * cb);
</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>fp</tt></td><td>File to read from</td></tr>
<tr><td><tt>cb</tt></td><td>Callback function</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>First node</p>
<hr noshade/>
<h2><a name="mxmlNewElement">mxmlNewElement()</a></h2>
<p>Create a new element node.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlNewElement(
mxml_node_t * parent,
const char * name);
</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>parent</tt></td><td>Parent node</td></tr>
<tr><td><tt>name</tt></td><td>Name of element</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>New node</p>
<hr noshade/>
<h2><a name="mxmlNewInteger">mxmlNewInteger()</a></h2>
<p>Create a new integer node.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlNewInteger(
mxml_node_t * parent,
int integer);
</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>parent</tt></td><td>Parent node</td></tr>
<tr><td><tt>integer</tt></td><td>Integer value</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>New node</p>
<hr noshade/>
<h2><a name="mxmlNewOpaque">mxmlNewOpaque()</a></h2>
<p>Create a new opaque string.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlNewOpaque(
mxml_node_t * parent,
const char * opaque);
</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>parent</tt></td><td>Parent node</td></tr>
<tr><td><tt>opaque</tt></td><td>Opaque string</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>New node</p>
<hr noshade/>
<h2><a name="mxmlNewReal">mxmlNewReal()</a></h2>
<p>Create a new real number node.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlNewReal(
mxml_node_t * parent,
double real);
</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>parent</tt></td><td>Parent node</td></tr>
<tr><td><tt>real</tt></td><td>Real number value</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>New node</p>
<hr noshade/>
<h2><a name="mxmlNewText">mxmlNewText()</a></h2>
<p>Create a new text fragment node.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlNewText(
mxml_node_t * parent,
int whitespace,
const char * string);
</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>parent</tt></td><td>Parent node</td></tr>
<tr><td><tt>whitespace</tt></td><td>Leading whitespace?</td></tr>
<tr><td><tt>string</tt></td><td>String</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>New node</p>
<hr noshade/>
<h2><a name="mxmlRemove">mxmlRemove()</a></h2>
<p>Remove a node from its parent.</p>
<h3>Syntax</h3>
<pre>
void
mxmlRemove(
mxml_node_t * node);
</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 remove</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>Nothing.</p>
<hr noshade/>
<h2><a name="mxmlSaveFile">mxmlSaveFile()</a></h2>
<p>Save an XML tree to a file.</p>
<h3>Syntax</h3>
<pre>
int
mxmlSaveFile(
mxml_node_t * node,
FILE * fp,
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>fp</tt></td><td>File to write to</td></tr>
<tr><td><tt>cb</tt></td><td></td></tr>
<tr><td><tt>int</tt></td><td>Whitespace callback</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>0 on success, -1 on error</p>
<hr noshade/>
<h2><a name="mxmlWalkNext">mxmlWalkNext()</a></h2>
<p>Walk to the next logical node in the tree.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlWalkNext(
mxml_node_t * node,
mxml_node_t * top,
int descend);
</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>Current node</td></tr>
<tr><td><tt>top</tt></td><td>Top node</td></tr>
<tr><td><tt>descend</tt></td><td>Descend into tree?</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>Next node or NULL</p>
<hr noshade/>
<h2><a name="mxmlWalkPrev">mxmlWalkPrev()</a></h2>
<p>Walk to the previous logical node in the tree.</p>
<h3>Syntax</h3>
<pre>
mxml_node_t *
mxmlWalkPrev(
mxml_node_t * node,
mxml_node_t * top,
int descend);
</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>Current node</td></tr>
<tr><td><tt>top</tt></td><td>Top node</td></tr>
<tr><td><tt>descend</tt></td><td>Descend into tree?</td></tr>
</tbody></table></p>
<h3>Returns</h3>
<p>Previous node or NULL</p>
</body>
</html>

View File

@ -5,7 +5,8 @@
<style><!--
h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
h1.title, p.title { font-family: sans-serif; text-align: center; }
tt, pre, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
pre { font-weight: bold; color: #7f0000; margin-left: 5em; }
--></style>
</head>
<body>
@ -57,23 +58,22 @@ not a conforming XML consumer/client.</p>
type the following command to get things going:</p>
<pre>
./configure
./configure
</pre>
<p>The default install prefix is /usr/local, which can be
overridden using the --prefix option:</p>
<pre>
./configure --prefix=/foo
./configure --prefix=/foo
</pre>
<p>Once you have configured the software, type "make" to do the
build and then run the test program to verify that things are
build and run the test program to verify that things are
working, as follows:</p>
<pre>
make
./testmxml test.xml
make
</pre>
<h2>Installing Mini-XML</h2>
@ -82,7 +82,7 @@ working, as follows:</p>
include directories:</p>
<pre>
make install
make install
</pre>
<p>Once you have installed it, use the "-lmxml" option to link
@ -90,57 +90,71 @@ your application against it.</p>
<h2>Documentation</h2>
<p>The documentation is currently just in this page. At some
point I'll probably do some proper documentation, but for now
just read here and look at the <tt><a
href="testmxml.c">testmxml.c</a></tt> source file for an
example of reading and printing the contents of an XML file to
stdout.</p>
<p>The documentation is currently a work in progress. Aside from
the information that follows, the <a
href="documentation.html">documentation</a> page provides a
handy reference and is automatically generated using Mini-XML.
You can also look at the <tt><a
href="testmxml.c">testmxml.c</a></tt> and <tt><a
href="mxmldoc.c">mxmldoc.c</a></tt> source files for examples of
using Mini-XML.</p>
<p>Mini-XML provides a single header file which you include:</p>
<pre>
<a href="mxml.h">#include &lt;mxml.h></a>
<a href="mxml.h">#include &lt;mxml.h></a>
</pre>
<p>Nodes are defined by the <tt>mxml_node_t</tt> structure; the
<tt>type</tt> member defines the node type (element, integer,
opaque, real, or text) which determines which value you want to
look at in the <tt>value</tt> union. New nodes can be created
using the <tt>mxmlNewElement()</tt>, <tt>mxmlNewInteger()</tt>,
<tt>mxmlNewOpaque()</tt>, <tt>mxmlNewReal()</tt>, and
<tt>mxmlNewText()</tt> functions. Only elements can have child
nodes, and the top node must be an element, usually "?xml".</p>
using the <a
href="documentation.html#mxmlNewElement"><tt>mxmlNewElement()</tt></a>,
<a
href="documentation.html#mxmlNewInteger"><tt>mxmlNewInteger()</tt></a>,
<a
href="documentation.html#mxmlNewOpaque"><tt>mxmlNewOpaque()</tt></a>,
<a
href="documentation.html#mxmlNewReal"><tt>mxmlNewReal()</tt></a>,
and <a
href="documentation.html#mxmlNewText"><tt>mxmlNewText()</tt></a>
functions. Only elements can have child nodes, and the top node
must be an element, usually "?xml".</p>
<p>You load an XML file using the <tt>mxmlLoadFile()</tt> function:</p>
<pre>
FILE *fp;
mxml_node_t *tree;
fp = fopen("filename.xml", "r");
tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
fclose(fp);
</pre>
<p>Similarly, you save an XML file using the <tt>mxmlSaveFile()</tt>
<p>You load an XML file using the <a
href="documentation.html#mxmlLoadFile"><tt>mxmlLoadFile()</tt></a>
function:</p>
<pre>
FILE *fp;
mxml_node_t *tree;
FILE *fp;
mxml_node_t *tree;
fp = fopen("filename.xml", "w");
mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
fclose(fp);
fp = fopen("filename.xml", "r");
tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
fclose(fp);
</pre>
<p>You can find a named element/node using the
<tt>mxmlFindElement()</tt> function:</p>
<p>Similarly, you save an XML file using the <a
href="documentation.html#mxmlSaveFile"><tt>mxmlSaveFile()</tt></a>
function:</p>
<pre>
mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr",
"value", MXML_DESCEND);
FILE *fp;
mxml_node_t *tree;
fp = fopen("filename.xml", "w");
mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
fclose(fp);
</pre>
<p>You can find a named element/node using the <a
href="documentation.html#mxmlFindElement"><tt>mxmlFindElement()</tt></a>
function:</p>
<pre>
mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr",
"value", MXML_DESCEND);
</pre>
<p>The <tt>name</tt>, <tt>attr</tt>, and <tt>value</tt>
@ -148,42 +162,43 @@ arguments can be passed as <tt>NULL</tt> to act as wildcards,
e.g.:</p>
<pre>
/* Find the first "a" element */
node = mxmlFindElement(tree, tree, "a", NULL, NULL, MXML_DESCEND);
/* Find the first "a" element */
node = mxmlFindElement(tree, tree, "a", NULL, NULL, MXML_DESCEND);
/* Find the first "a" element with "href" attribute */
node = mxmlFindElement(tree, tree, "a", "href", NULL, MXML_DESCEND);
/* Find the first "a" element with "href" attribute */
node = mxmlFindElement(tree, tree, "a", "href", NULL, MXML_DESCEND);
/* Find the first "a" element with "href" to a URL */
node = mxmlFindElement(tree, tree, "a", "href",
"http://www.easysw.com/~mike/mxml/", MXML_DESCEND);
/* Find the first "a" element with "href" to a URL */
node = mxmlFindElement(tree, tree, "a", "href",
"http://www.easysw.com/~mike/mxml/", MXML_DESCEND);
/* Find the first element with a "src" attribute*/
node = mxmlFindElement(tree, tree, NULL, "src", NULL, MXML_DESCEND);
/* Find the first element with a "src" attribute*/
node = mxmlFindElement(tree, tree, NULL, "src", NULL, MXML_DESCEND);
/* Find the first element with a "src" = "foo.jpg" */
node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg", MXML_DESCEND);
/* Find the first element with a "src" = "foo.jpg" */
node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg", MXML_DESCEND);
</pre>
<p>You can also iterate with the same function:</p>
<pre>
mxml_node_t *node;
mxml_node_t *node;
for (node = mxmlFindElement(tree, tree, "name", NULL, NULL, MXML_DESCEND);
node != NULL;
node = mxmlFindElement(node, tree, "name", NULL, NULL, MXML_DESCEND))
{
... do something ...
}
for (node = mxmlFindElement(tree, tree, "name", NULL, NULL, MXML_DESCEND);
node != NULL;
node = mxmlFindElement(node, tree, "name", NULL, NULL, MXML_DESCEND))
{
... do something ...
}
</pre>
<p>Finally, once you are done with the XML data, use the
<tt>mxmlDelete()</tt> function to recursively free the memory
that is used for a particular node or the entire tree:</p>
<p>Finally, once you are done with the XML data, use the <a
href="documentation.html#mxmlDelete"><tt>mxmlDelete()</tt></a>
function to recursively free the memory that is used for a
particular node or the entire tree:</p>
<pre>
mxmlDelete(tree);
mxmlDelete(tree);
</pre>
<h2>Getting Help and Reporting Problems</h2>

102
mxml.xml Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0"?>
<variable name="fp"><type>FILE *</type><description>File to write to</description><description>Callback function</description></variable>
<function name="mxmlAdd"><description>Add a node to a tree.</description><argument
name="parent" direction="I"><type>mxml_node_t *</type><description>Parent node</description></argument>
<argument name="where" direction="I"><type>int</type><description>Where to add</description></argument>
<argument name="child" direction="I"><type>mxml_node_t *</type><description>Child node for where</description></argument>
<argument name="node" direction="I"><type>mxml_node_t *</type><description>Node to add</description></argument>
</function>
<function name="mxmlDelete"><description>Delete a node and all of its children.</description><argument
name="node" direction="I"><type>mxml_node_t *</type><description>Node</description></argument>
</function>
<function name="mxmlElementGetAttr"><returnvalue><description>Attribute value or NULL</description><type>const
char *</type></returnvalue>
<description>Get an attribute.</description><argument name="node"
direction="I"><type>mxml_node_t *</type><description>Element node</description></argument>
<argument name="name" direction="I"><type>const char *</type><description>Name of attribute</description></argument>
</function>
<function name="mxmlElementSetAttr"><description>Set an attribute.</description><argument
name="node" direction="I"><type>mxml_node_t *</type><description>Element node</description></argument>
<argument name="name" direction="I"><type>const char *</type><description>Name of attribute</description></argument>
<argument name="value" direction="I"><type>const char *</type><description>Attribute value</description></argument>
</function>
<function name="mxmlFindElement"><returnvalue><description>Element node or NULL</description><type>mxml_node_t
*</type></returnvalue>
<description>Find the named element.</description><argument name="node"
direction="I"><type>mxml_node_t *</type><description>Current node</description></argument>
<argument name="top" direction="I"><type>mxml_node_t *</type><description>Top node</description></argument>
<argument name="name" direction="I"><type>const char *</type><description>Element name or NULL for any</description></argument>
<argument name="attr" direction="I"><type>const char *</type><description>Attribute name, or NULL for none</description></argument>
<argument name="value" direction="I"><type>const char *</type><description>Attribute value, or NULL for any</description></argument>
<argument name="descend" direction="I"><type>int</type><description>Descend into tree?</description></argument>
</function>
<function name="mxmlLoadFile"><returnvalue><description>First node</description><type>mxml_node_t
*</type></returnvalue>
<description>Load a file into an XML node tree.</description><argument
name="top" direction="I"><type>mxml_node_t *</type><description>Top node</description></argument>
<argument name="fp" direction="I"><type>FILE *</type><description>File to read from</description></argument>
<argument name="cb" direction="I"><type>mxml_type_t *</type><description>Callback function</description></argument>
</function>
<function name="mxmlNewElement"><returnvalue><description>New node</description><type>mxml_node_t
*</type></returnvalue>
<description>Create a new element node.</description><argument
name="parent" direction="I"><type>mxml_node_t *</type><description>Parent node</description></argument>
<argument name="name" direction="I"><type>const char *</type><description>Name of element</description></argument>
</function>
<function name="mxmlNewInteger"><returnvalue><description>New node</description><type>mxml_node_t
*</type></returnvalue>
<description>Create a new integer node.</description><argument
name="parent" direction="I"><type>mxml_node_t *</type><description>Parent node</description></argument>
<argument name="integer" direction="I"><type>int</type><description>Integer value</description></argument>
</function>
<function name="mxmlNewOpaque"><returnvalue><description>New node</description><type>mxml_node_t
*</type></returnvalue>
<description>Create a new opaque string.</description><argument
name="parent" direction="I"><type>mxml_node_t *</type><description>Parent node</description></argument>
<argument name="opaque" direction="I"><type>const char *</type><description>Opaque string</description></argument>
</function>
<function name="mxmlNewReal"><returnvalue><description>New node</description><type>mxml_node_t
*</type></returnvalue>
<description>Create a new real number node.</description><argument
name="parent" direction="I"><type>mxml_node_t *</type><description>Parent node</description></argument>
<argument name="real" direction="I"><type>double</type><description>Real number value</description></argument>
</function>
<function name="mxmlNewText"><returnvalue><description>New node</description><type>mxml_node_t
*</type></returnvalue>
<description>Create a new text fragment node.</description><argument
name="parent" direction="I"><type>mxml_node_t *</type><description>Parent node</description></argument>
<argument name="whitespace" direction="I"><type>int</type><description>Leading whitespace?</description></argument>
<argument name="string" direction="I"><type>const char *</type><description>String</description></argument>
</function>
<function name="mxmlRemove"><description>Remove a node from its parent.</description><argument
name="node" direction="I"><type>mxml_node_t *</type><description>Node to remove</description></argument>
</function>
<function name="mxmlSaveFile"><returnvalue><description>0 on success, -1 on error</description><type>int</type></returnvalue>
<description>Save an XML tree to a file.</description><argument
name="node" direction="I"><type>mxml_node_t *</type><description>Node to write</description></argument>
<argument name="fp" direction="I"><type>FILE *</type><description>File to write to</description></argument>
<argument name="cb"><type>int *</type></argument>
<argument name="int" direction="I"><type>mxml_node_t *</type><description>Whitespace callback</description></argument>
</function>
<function name="mxmlWalkNext"><returnvalue><description>Next node or NULL</description><type>mxml_node_t
*</type></returnvalue>
<description>Walk to the next logical node in the tree.</description><argument
name="node" direction="I"><type>mxml_node_t *</type><description>Current node</description></argument>
<argument name="top" direction="I"><type>mxml_node_t *</type><description>Top node</description></argument>
<argument name="descend" direction="I"><type>int</type><description>Descend into tree?</description></argument>
</function>
<function name="mxmlWalkPrev"><returnvalue><description>Previous node or NULL</description><type>mxml_node_t
*</type></returnvalue>
<description>Walk to the previous logical node in the tree.</description><argument
name="node" direction="I"><type>mxml_node_t *</type><description>Current node</description></argument>
<argument name="top" direction="I"><type>mxml_node_t *</type><description>Top node</description></argument>
<argument name="descend" direction="I"><type>int</type><description>Descend into tree?</description></argument>
</function>
<variable name="mxml_attr_t"><type/></variable>
<variable name="mxml_element_t"><type/></variable>
<variable name="mxml_node_t"><type>typedef struct mxml_node_str</type></variable>
<variable name="mxml_type_t"><type/></variable>
<variable name="node"><type>mxml_node_t *</type><description>Current node</description></variable>
<variable name="parent"><type>mxml_node_t *</type><description>Parent node</description><description>Node type</description></variable>
<variable name="s"><type>const char *</type><description>String to write</description><description>File to write to</description></variable>
<variable name="ws"><type>int * cb mxml_node_t * int int</type><description>Where value</description><description>Current column</description></variable>

196
mxmldoc.c
View File

@ -1,5 +1,5 @@
/*
* "$Id: mxmldoc.c,v 1.7 2003/06/05 12:11:53 mike Exp $"
* "$Id: mxmldoc.c,v 1.8 2003/06/05 13:49:14 mike Exp $"
*
* Documentation generator using mini-XML, a small XML-like file parsing
* library.
@ -100,6 +100,8 @@ static void sort_node(mxml_node_t *tree, mxml_node_t *func);
static void update_comment(mxml_node_t *parent,
mxml_node_t *comment);
static void write_documentation(mxml_node_t *doc);
static void write_element(mxml_node_t *element);
static void write_string(const char *s);
static int ws_cb(mxml_node_t *node, int where);
@ -542,6 +544,23 @@ scan_file(const char *filename, /* I - Filename */
if (type->child &&
!strcmp(type->child->value.text.string, "extern"))
{
/*
* Remove external declarations...
*/
mxmlDelete(type);
type = NULL;
break;
}
if (type->child &&
!strcmp(type->child->value.text.string, "static") &&
!strcmp(parent->value.element.name, "?xml"))
{
/*
* Remove static functions...
*/
mxmlDelete(type);
type = NULL;
break;
@ -772,16 +791,18 @@ write_documentation(mxml_node_t *doc) /* I - XML documentation */
*description, /* Description of function/var */
*type; /* Type of returnvalue/var */
const char *name; /* Name of function/type */
char prefix; /* Prefix character */
puts("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
puts("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">");
puts("<head>");
puts("\t<title>Mini-XML Home Page</title>");
puts("\t<title>Documentation</title>");
puts("\t<style><!--");
puts("\th1, h2, h3, p { font-family: sans-serif; text-align: justify; }");
puts("\ttt, pre, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }");
puts("\ttt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }");
puts("\tpre { font-weight: bold; color: #7f0000; margin-left: 5em; }");
puts("\t--></style>");
puts("</head>");
puts("<body>");
@ -808,23 +829,89 @@ write_documentation(mxml_node_t *doc) /* I - XML documentation */
MXML_NO_DESCEND))
{
name = mxmlElementGetAttr(function, "name");
puts("<hr noshade/>");
printf("<h2><a name=\"%s\">%s()</a></h2>\n", name, name);
description = mxmlFindElement(function, function, "description", NULL,
NULL, MXML_DESCEND_FIRST);
fputs("<p>", stdout);
for (node = mxmlWalkNext(description, description, MXML_DESCEND);
node;
node = mxmlWalkNext(node, description, MXML_DESCEND))
if (node->type == MXML_TEXT)
{
if (node->value.text.whitespace)
putchar(' ');
if (description)
{
fputs("<p>", stdout);
write_element(description);
puts("</p>");
}
fputs(node->value.text.string, stdout);
puts("<h3>Syntax</h3>");
puts("<pre>");
arg = mxmlFindElement(function, function, "returnvalue", NULL,
NULL, MXML_DESCEND_FIRST);
if (arg)
write_element(mxmlFindElement(arg, arg, "type", NULL,
NULL, MXML_DESCEND_FIRST));
else
fputs("void", stdout);
printf("\n%s", name);
for (arg = mxmlFindElement(function, function, "argument", NULL, NULL,
MXML_DESCEND_FIRST), prefix = '(';
arg;
arg = mxmlFindElement(arg, function, "argument", NULL, NULL,
MXML_NO_DESCEND), prefix = ',')
{
printf("%c\n ", prefix);
write_element(mxmlFindElement(arg, arg, "type", NULL,
NULL, MXML_DESCEND_FIRST));
printf(" %s", mxmlElementGetAttr(arg, "name"));
}
if (prefix == '(')
puts("(void);\n</pre>");
else
puts(");\n</pre>");
puts("<h3>Arguments</h3>");
if (prefix == '(')
puts("<p>None.</p>");
else
{
puts("<p class=\"table\"><table align=\"center\" border=\"1\" width=\"80%\">");
puts("<thead><tr><th>Name</th><th>Description</th></tr></thead>");
puts("<tbody>");
for (arg = mxmlFindElement(function, function, "argument", NULL, NULL,
MXML_DESCEND_FIRST);
arg;
arg = mxmlFindElement(arg, function, "argument", NULL, NULL,
MXML_NO_DESCEND))
{
printf("<tr><td><tt>%s</tt></td><td>", mxmlElementGetAttr(arg, "name"));
write_element(mxmlFindElement(arg, arg, "description", NULL,
NULL, MXML_DESCEND_FIRST));
puts("</td></tr>");
}
puts("</p>");
puts("</tbody></table></p>");
}
puts("<h3>Returns</h3>");
arg = mxmlFindElement(function, function, "returnvalue", NULL,
NULL, MXML_DESCEND_FIRST);
if (!arg)
puts("<p>Nothing.</p>");
else
{
fputs("<p>", stdout);
write_element(mxmlFindElement(arg, arg, "description", NULL,
NULL, MXML_DESCEND_FIRST));
puts("</p>");
}
}
puts("</body>");
@ -833,6 +920,87 @@ write_documentation(mxml_node_t *doc) /* I - XML documentation */
}
/*
* 'write_element()' - Write an element's text nodes.
*/
static void
write_element(mxml_node_t *element) /* I - Element to write */
{
mxml_node_t *node; /* Current node */
for (node = mxmlWalkNext(element, element, MXML_DESCEND);
node;
node = mxmlWalkNext(node, element, MXML_DESCEND))
if (node->type == MXML_TEXT)
{
if (node->value.text.whitespace)
putchar(' ');
write_string(node->value.text.string);
}
}
/*
* 'write_string()' - Write a string, quoting XHTML special chars as needed...
*/
static void
write_string(const char *s) /* I - String to write */
{
while (*s)
{
if (*s == '&')
fputs("&amp;", stdout);
else if (*s == '<')
fputs("&lt;", stdout);
else if (*s == '>')
fputs("&gt;", stdout);
else if (*s == '\"')
fputs("&quot;", stdout);
else if (*s & 128)
{
/*
* Convert UTF-8 to Unicode constant...
*/
int ch; /* Unicode character */
ch = *s & 255;
if ((ch & 0xe0) == 0xc0)
{
ch = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
s ++;
}
else if ((ch & 0xf0) == 0xe0)
{
ch = ((((ch * 0x0f) << 6) | (s[1] & 0x3f)) << 6) | (s[2] & 0x3f);
s += 2;
}
if (ch == 0xa0)
{
/*
* Handle non-breaking space as-is...
*/
fputs("&nbsp;", stdout);
}
else
printf("&#x%x;", ch);
}
else
putchar(*s);
s ++;
}
}
/*
* 'ws_cb()' - Whitespace callback for saving.
*/
@ -859,5 +1027,5 @@ ws_cb(mxml_node_t *node, /* I - Element node */
/*
* End of "$Id: mxmldoc.c,v 1.7 2003/06/05 12:11:53 mike Exp $".
* End of "$Id: mxmldoc.c,v 1.8 2003/06/05 13:49:14 mike Exp $".
*/