mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-24 11:25:30 +00:00
Whitespace handling issues.
Unicode output issues. Comment/declaration handling fixes. Add mxmldoc to build.
This commit is contained in:
parent
bfc6a08cde
commit
438ded6568
13
CHANGES
13
CHANGES
@ -1,4 +1,4 @@
|
||||
README - 06/03/2003
|
||||
README - 06/04/2003
|
||||
-------------------
|
||||
|
||||
|
||||
@ -9,6 +9,17 @@ CHANGES IN Mini-XML 0.93
|
||||
character entities.
|
||||
- mxmlSaveFile() now uses newlines as whitespace
|
||||
when valid to do so.
|
||||
- mxmlFindElement() now also takes attribute name and
|
||||
attribute value string arguments to limit the search
|
||||
to specific elements with attributes and/or values.
|
||||
NULL pointers can be used as "wildcards".
|
||||
- Added uninstall target to makefile, and auto-reconfig
|
||||
if Makefile.in or configure.in are changed.
|
||||
- mxmlFindElement(), mxmlWalkNext(), and mxmlWalkPrev()
|
||||
now all provide "descend" arguments to control whether
|
||||
they descend into child nodes in the tree.
|
||||
- Fixed some whitespace issues in mxmlLoadFile().
|
||||
- Fixed Unicode output issues in mxmlSaveFile().
|
||||
|
||||
|
||||
CHANGES IN Mini-XML 0.92
|
||||
|
56
Makefile.in
56
Makefile.in
@ -1,5 +1,5 @@
|
||||
#
|
||||
# "$Id: Makefile.in,v 1.3 2003/06/04 00:25:59 mike Exp $"
|
||||
# "$Id: Makefile.in,v 1.4 2003/06/04 16:30:39 mike Exp $"
|
||||
#
|
||||
# Makefile for mini-XML, a small XML-like file parsing library.
|
||||
#
|
||||
@ -53,15 +53,15 @@ libdir = @libdir@
|
||||
#
|
||||
|
||||
LIBOBJS = mxml-attr.o mxml-file.o mxml-node.o mxml-search.o
|
||||
OBJS = testmxml.o $(LIBOBJS)
|
||||
TARGETS = libmxml.a testmxml
|
||||
OBJS = mxmldoc.o testmxml.o $(LIBOBJS)
|
||||
TARGETS = libmxml.a mxmldoc testmxml
|
||||
|
||||
|
||||
#
|
||||
# Make everything...
|
||||
#
|
||||
|
||||
all: $(TARGETS)
|
||||
all: Makefile configure $(TARGETS)
|
||||
|
||||
|
||||
#
|
||||
@ -86,6 +86,37 @@ install: $(TARGETS)
|
||||
cp mxml.h $(includedir)
|
||||
|
||||
|
||||
#
|
||||
# Uninstall everything...
|
||||
#
|
||||
|
||||
uninstall:
|
||||
rm -f $(libdir)/libmxml.a
|
||||
rm -f $(includedir)/mxml.h
|
||||
|
||||
|
||||
#
|
||||
# autoconf stuff...
|
||||
#
|
||||
|
||||
Makefile: configure Makefile.in
|
||||
if test -f config.status; then \
|
||||
./config.status --recheck; \
|
||||
./config.status; \
|
||||
else \
|
||||
./configure; \
|
||||
fi
|
||||
|
||||
configure: configure.in
|
||||
autoconf
|
||||
if test -f config.status; then \
|
||||
./config.status --recheck; \
|
||||
./config.status; \
|
||||
else \
|
||||
./configure; \
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# libmxml.a
|
||||
#
|
||||
@ -98,6 +129,16 @@ libmxml.a: $(LIBOBJS)
|
||||
$(LIBOBJS): mxml.h
|
||||
|
||||
|
||||
#
|
||||
# mxmldoc
|
||||
#
|
||||
|
||||
mxmldoc: libmxml.a mxmldoc.o
|
||||
$(CC) $(LDFLAGS) -o $@ mxmldoc.o libmxml.a
|
||||
|
||||
mxmldoc.o: mxml.h
|
||||
|
||||
|
||||
#
|
||||
# testmxml
|
||||
#
|
||||
@ -116,9 +157,14 @@ testmxml: libmxml.a testmxml.o
|
||||
|
||||
testmxml.o: mxml.h
|
||||
|
||||
|
||||
#
|
||||
# All object files depend on the makefile...
|
||||
#
|
||||
|
||||
$(OBJS): Makefile
|
||||
|
||||
|
||||
#
|
||||
# End of "$Id: Makefile.in,v 1.3 2003/06/04 00:25:59 mike Exp $".
|
||||
# End of "$Id: Makefile.in,v 1.4 2003/06/04 16:30:39 mike Exp $".
|
||||
#
|
||||
|
34
README
34
README
@ -1,11 +1,11 @@
|
||||
README - 06/03/2003
|
||||
README - 06/04/2003
|
||||
-------------------
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
|
||||
This README file describes the Mini-XML library version
|
||||
0.91.
|
||||
0.93.
|
||||
|
||||
Mini-XML is a small XML parsing library that you can use to
|
||||
read XML and XML-like data files in your application without
|
||||
@ -92,15 +92,39 @@ DOCUMENTATION
|
||||
You can find a named element/node using the
|
||||
"mxmlFindElement()" function:
|
||||
|
||||
mxml_node_t *node = mxmlFindElement(tree, tree, "name");
|
||||
mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr",
|
||||
"value", MXML_DESCEND);
|
||||
|
||||
The "name", "attr", and "value" arguments can be passed as
|
||||
NULL to act as wildcards, e.g.:
|
||||
|
||||
/* 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" 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" = "foo.jpg" */
|
||||
node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg",
|
||||
MXML_DESCEND);
|
||||
|
||||
You can also iterate with the same function:
|
||||
|
||||
mxml_node_t *node;
|
||||
|
||||
for (node = mxmlFindElement(tree, tree, "name");
|
||||
for (node = mxmlFindElement(tree, tree, "name", NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
node != NULL;
|
||||
node = mxmlFindElement(node, tree, "name"))
|
||||
node = mxmlFindElement(node, tree, "name", NULL, NULL,
|
||||
MXML_DESCEND))
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
|
211
index.html
211
index.html
@ -1,174 +1,199 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Mini-XML Home Page</TITLE>
|
||||
<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 { font-weight: bold; color: #7f0000; }
|
||||
--></STYLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<!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>Mini-XML Home Page</title>
|
||||
<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; }
|
||||
--></style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<P CLASS="title" ALIGN="CENTER">[ <A
|
||||
HREF="../index.html">Back to Home Page</A> ]</P>
|
||||
<p class="title" align="center">[ <a
|
||||
href="../index.html">Back to Home Page</a> ]</p>
|
||||
|
||||
<H1 CLASS="title" ALIGN="CENTER">Mini-XML Home Page</H1>
|
||||
<h1 class="title" align="center">Mini-XML Home Page</h1>
|
||||
|
||||
<P CLASS="title" ALIGN="CENTER">Current Release: v0.93 [ <A
|
||||
HREF="mxml-0.93.tar.gz">Download Source (.tar.gz 40k)</A> |
|
||||
<A HREF="CHANGES">View Change Log</A> ]</P>
|
||||
<p class="title" align="center">Current Release: v0.93 [ <a
|
||||
href="mxml-0.93.tar.gz">Download Source (.tar.gz 40k)</a> |
|
||||
<a href="CHANGES">View Change Log</a> ]</p>
|
||||
|
||||
<H2>Introduction</H2>
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<P>Mini-XML is a small XML parsing library that you can use to
|
||||
<p>Mini-XML is a small XML parsing library that you can use to
|
||||
read XML and XML-like data files in your application without
|
||||
requiring large non-standard libraries. Mini-XML only requires
|
||||
an ANSI C compatible compiler (GCC works, as do most vendors'
|
||||
ANSI C compilers) and a "make" program.</P>
|
||||
ANSI C compilers) and a "make" program.</p>
|
||||
|
||||
<P>Mini-XML was created to support the basic hierarchy provided
|
||||
<p>Mini-XML was created to support the basic hierarchy provided
|
||||
by XML and some simple data types, but doesn't do validation or
|
||||
other types of processing on the data.</P>
|
||||
other types of processing on the data.</p>
|
||||
|
||||
<H2>Building Mini-XML</H2>
|
||||
<h2>Building Mini-XML</h2>
|
||||
|
||||
<P>Mini-XML comes with an autoconf-based configure script; just
|
||||
type the following command to get things going:</P>
|
||||
<p>Mini-XML comes with an autoconf-based configure script; just
|
||||
type the following command to get things going:</p>
|
||||
|
||||
<PRE>
|
||||
<pre>
|
||||
./configure
|
||||
</PRE>
|
||||
</pre>
|
||||
|
||||
<P>The default install prefix is /usr/local, which can be
|
||||
overridden using the --prefix option:</P>
|
||||
<p>The default install prefix is /usr/local, which can be
|
||||
overridden using the --prefix option:</p>
|
||||
|
||||
<PRE>
|
||||
<pre>
|
||||
./configure --prefix=/foo
|
||||
</PRE>
|
||||
</pre>
|
||||
|
||||
<P>Once you have configured the software, type "make" to do the
|
||||
<p>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:</P>
|
||||
working, as follows:</p>
|
||||
|
||||
<PRE>
|
||||
<pre>
|
||||
make
|
||||
./testmxml test.xml
|
||||
</PRE>
|
||||
</pre>
|
||||
|
||||
<H2>Installing Mini-XML</H2>
|
||||
<h2>Installing Mini-XML</h2>
|
||||
|
||||
<P>The "install" target will install Mini-XML in the lib and
|
||||
include directories:</P>
|
||||
<p>The "install" target will install Mini-XML in the lib and
|
||||
include directories:</p>
|
||||
|
||||
<PRE>
|
||||
<pre>
|
||||
make install
|
||||
</PRE>
|
||||
</pre>
|
||||
|
||||
<P>Once you have installed it, use the "-lmxml" option to link
|
||||
your application against it.</P>
|
||||
<p>Once you have installed it, use the "-lmxml" option to link
|
||||
your application against it.</p>
|
||||
|
||||
<H2>Documentation</H2>
|
||||
<h2>Documentation</h2>
|
||||
|
||||
<P>The documentation is currently just in this page. At some
|
||||
<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 <A
|
||||
HREF="testmxml.c"><TT>testmxml.c</TT></A> source file for an
|
||||
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>
|
||||
stdout.</p>
|
||||
|
||||
<P>Mini-XML provides a single header file which you include:</P>
|
||||
<p>Mini-XML provides a single header file which you include:</p>
|
||||
|
||||
<PRE>
|
||||
<A HREF="mxml.h">#include <mxml.h></A>
|
||||
</PRE>
|
||||
<pre>
|
||||
<a href="mxml.h">#include <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,
|
||||
<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>
|
||||
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>
|
||||
|
||||
<P>You load an XML file using the <TT>mxmlLoadFile()</TT> function:</P>
|
||||
<p>You load an XML file using the <tt>mxmlLoadFile()</tt> function:</p>
|
||||
|
||||
<PRE>
|
||||
<pre>
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "r");
|
||||
tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
|
||||
fclose(fp);
|
||||
</PRE>
|
||||
</pre>
|
||||
|
||||
<P>Similarly, you save an XML file using the <TT>mxmlSaveFile()</TT>
|
||||
function:</P>
|
||||
<p>Similarly, you save an XML file using the <tt>mxmlSaveFile()</tt>
|
||||
function:</p>
|
||||
|
||||
<PRE>
|
||||
<pre>
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "w");
|
||||
mxmlSaveFile(tree, fp);
|
||||
fclose(fp);
|
||||
</PRE>
|
||||
</pre>
|
||||
|
||||
<P>You can find a named element/node using the
|
||||
<TT>mxmlFindElement()</TT> function:</P>
|
||||
<p>You can find a named element/node using the
|
||||
<tt>mxmlFindElement()</tt> function:</p>
|
||||
|
||||
<PRE>
|
||||
mxml_node_t *node = mxmlFindElement(tree, tree, "name");
|
||||
</PRE>
|
||||
<pre>
|
||||
mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr",
|
||||
"value", MXML_DESCEND);
|
||||
</pre>
|
||||
|
||||
<P>You can also iterate with the same function:
|
||||
<p>The <tt>name</tt>, <tt>attr</tt>, and <tt>value</tt>
|
||||
arguments can be passed as <tt>NULL</tt> to act as wildcards,
|
||||
e.g.:</p>
|
||||
|
||||
<PRE>
|
||||
<pre>
|
||||
/* 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" 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" = "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;
|
||||
|
||||
for (node = mxmlFindElement(tree, tree, "name");
|
||||
for (node = mxmlFindElement(tree, tree, "name", NULL, NULL, MXML_DESCEND);
|
||||
node != NULL;
|
||||
node = mxmlFindElement(node, tree, "name"))
|
||||
node = mxmlFindElement(node, tree, "name", NULL, NULL, MXML_DESCEND))
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
</PRE>
|
||||
</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
|
||||
<tt>mxmlDelete()</tt> function to recursively free the memory
|
||||
that is used for a particular node or the entire tree:</p>
|
||||
|
||||
<PRE>
|
||||
<pre>
|
||||
mxmlDelete(tree);
|
||||
</PRE>
|
||||
</pre>
|
||||
|
||||
<H2>Getting Help and Reporting Problems</H2>
|
||||
<h2>Getting Help and Reporting Problems</h2>
|
||||
|
||||
<P>You can email me at "mxml <I>at</I> easysw <I>dot</I> com" to
|
||||
<p>You can email me at "mxml <i>at</i> easysw <i>dot</i> com" to
|
||||
report problems and/or ask for help. Just don't expect an
|
||||
instant response, as I get a <I>lot</I> of email...</P>
|
||||
instant response, as I get a <i>lot</i> of email...</p>
|
||||
|
||||
<H2>Legal Stuff</H2>
|
||||
<h2>Legal Stuff</h2>
|
||||
|
||||
<P>The Mini-XML library is Copyright 2003 by Michael Sweet.</P>
|
||||
<p>The Mini-XML library is Copyright 2003 by Michael Sweet.</p>
|
||||
|
||||
<P>This library is free software; you can redistribute it
|
||||
<p>This library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Library General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any
|
||||
later version.</P>
|
||||
later version.</p>
|
||||
|
||||
<P>This library is distributed in the hope that it will be
|
||||
<p>This library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Library General Public License for
|
||||
more details.</P>
|
||||
more details.</p>
|
||||
|
||||
<P>You should have received a copy of the GNU Library General
|
||||
<p>You should have received a copy of the GNU Library General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
02139, USA.</P>
|
||||
02139, USA.</p>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
</body>
|
||||
</html>
|
||||
|
191
mxml-file.c
191
mxml-file.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml-file.c,v 1.5 2003/06/04 02:34:29 mike Exp $"
|
||||
* "$Id: mxml-file.c,v 1.6 2003/06/04 16:30:40 mike Exp $"
|
||||
*
|
||||
* File loading code for mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -131,6 +131,32 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (isspace(ch) && type == MXML_TEXT)
|
||||
whitespace = 1;
|
||||
|
||||
/*
|
||||
* Add lone whitespace node if we are starting a new element and have
|
||||
* existing whitespace...
|
||||
*/
|
||||
|
||||
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, "");
|
||||
whitespace = 0;
|
||||
}
|
||||
|
||||
ch = '<';
|
||||
}
|
||||
|
||||
if (ch == '<')
|
||||
{
|
||||
@ -144,40 +170,114 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
if (isspace(ch) || ch == '>' || (ch == '/' && bufptr > buffer))
|
||||
break;
|
||||
else if (bufptr < (buffer + sizeof(buffer) - 1))
|
||||
{
|
||||
*bufptr++ = ch;
|
||||
|
||||
if ((bufptr - buffer) == 3 && !strncmp(buffer, "!--", 3))
|
||||
break;
|
||||
}
|
||||
|
||||
*bufptr = '\0';
|
||||
bufptr = buffer;
|
||||
|
||||
if (!strcmp(buffer, "!--"))
|
||||
{
|
||||
/*
|
||||
* Skip comment...
|
||||
* Gather rest of comment...
|
||||
*/
|
||||
|
||||
buffer[3] = '\0';
|
||||
|
||||
while ((ch = getc(fp)) != EOF)
|
||||
{
|
||||
*bufptr++ = ch;
|
||||
|
||||
if ((bufptr - buffer) == 3)
|
||||
if (ch == '>' && bufptr > (buffer + 4) &&
|
||||
!strncmp(bufptr - 2, "--", 2))
|
||||
break;
|
||||
else if (bufptr < (buffer + sizeof(buffer) - 1))
|
||||
*bufptr++ = ch;
|
||||
else
|
||||
{
|
||||
if (!strcmp(buffer, "-->"))
|
||||
break;
|
||||
|
||||
buffer[0] = buffer[1];
|
||||
buffer[1] = buffer[2];
|
||||
bufptr --;
|
||||
fprintf(stderr, "Comment too long in file under parent <%s>!\n",
|
||||
parent ? parent->value.element.name : "null");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bufptr = buffer;
|
||||
/*
|
||||
* Error out if we didn't get the whole comment...
|
||||
*/
|
||||
|
||||
if (ch == EOF)
|
||||
if (ch != '>')
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Otherwise add this as an element under the current parent...
|
||||
*/
|
||||
|
||||
*bufptr = '\0';
|
||||
|
||||
if (!mxmlNewElement(parent, buffer))
|
||||
{
|
||||
/*
|
||||
* Just print error for now...
|
||||
*/
|
||||
|
||||
fprintf(stderr, "Unable to add comment node to parent <%s>!\n",
|
||||
parent ? parent->value.element.name : "null");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (buffer[0] == '!')
|
||||
{
|
||||
/*
|
||||
* Gather rest of declaration...
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
if (ch == '>')
|
||||
break;
|
||||
else if (bufptr < (buffer + sizeof(buffer) - 1))
|
||||
*bufptr++ = ch;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Declaration too long in file under parent <%s>!\n",
|
||||
parent ? parent->value.element.name : "null");
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ((ch = getc(fp)) != EOF);
|
||||
|
||||
/*
|
||||
* Error out if we didn't get the whole declaration...
|
||||
*/
|
||||
|
||||
if (ch != '>')
|
||||
break;
|
||||
|
||||
/*
|
||||
* Otherwise add this as an element under the current parent...
|
||||
*/
|
||||
|
||||
*bufptr = '\0';
|
||||
|
||||
node = mxmlNewElement(parent, buffer);
|
||||
if (!node)
|
||||
{
|
||||
/*
|
||||
* Just print error for now...
|
||||
*/
|
||||
|
||||
fprintf(stderr, "Unable to add declaration node to parent <%s>!\n",
|
||||
parent ? parent->value.element.name : "null");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Descend into this node, setting the value type as needed...
|
||||
*/
|
||||
|
||||
parent = node;
|
||||
|
||||
if (cb)
|
||||
type = (*cb)(parent);
|
||||
}
|
||||
else if (buffer[0] == '/')
|
||||
{
|
||||
@ -260,6 +360,8 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
type = (*cb)(parent);
|
||||
}
|
||||
}
|
||||
|
||||
bufptr = buffer;
|
||||
}
|
||||
else if (ch == '&')
|
||||
{
|
||||
@ -635,7 +737,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
if (node->child)
|
||||
{
|
||||
/*
|
||||
* The ?xml element is a special-case and has no end tag...
|
||||
* The ? and ! elements are special-cases and have no end tags...
|
||||
*/
|
||||
|
||||
if (node->value.element.name[0] == '?')
|
||||
@ -653,7 +755,8 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
if ((col = mxml_write_node(node->child, fp, col)) < 0)
|
||||
return (-1);
|
||||
|
||||
if (node->value.element.name[0] != '?')
|
||||
if (node->value.element.name[0] != '?' &&
|
||||
node->value.element.name[0] != '!')
|
||||
{
|
||||
if ((n = fprintf(fp, "</%s>", node->value.element.name)) < 0)
|
||||
return (-1);
|
||||
@ -661,6 +764,13 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
col += n;
|
||||
}
|
||||
}
|
||||
else if (node->value.element.name[0] == '!')
|
||||
{
|
||||
if (putc('>', fp) < 0)
|
||||
return (-1);
|
||||
else
|
||||
col ++;
|
||||
}
|
||||
else if (fputs("/>", fp) < 0)
|
||||
return (-1);
|
||||
else
|
||||
@ -772,6 +882,45 @@ mxml_write_string(const char *s, /* I - String to write */
|
||||
if (fputs("<", fp) < 0)
|
||||
return (-1);
|
||||
}
|
||||
else if (*s == '>')
|
||||
{
|
||||
if (fputs(">", fp) < 0)
|
||||
return (-1);
|
||||
}
|
||||
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...
|
||||
*/
|
||||
|
||||
if (fputs(" ", fp) < 0)
|
||||
return (-1);
|
||||
}
|
||||
else if (fprintf(fp, "&#x%x;", ch) < 0)
|
||||
return (-1);
|
||||
}
|
||||
else if (putc(*s, fp) < 0)
|
||||
return (-1);
|
||||
|
||||
@ -784,5 +933,5 @@ mxml_write_string(const char *s, /* I - String to write */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml-file.c,v 1.5 2003/06/04 02:34:29 mike Exp $".
|
||||
* End of "$Id: mxml-file.c,v 1.6 2003/06/04 16:30:40 mike Exp $".
|
||||
*/
|
||||
|
129
mxml-search.c
129
mxml-search.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml-search.c,v 1.2 2003/06/03 20:40:01 mike Exp $"
|
||||
* "$Id: mxml-search.c,v 1.3 2003/06/04 16:30:40 mike Exp $"
|
||||
*
|
||||
* Search/navigation functions for mini-XML, a small XML-like file
|
||||
* parsing library.
|
||||
@ -21,7 +21,6 @@
|
||||
* mxmlFindElement() - Find the named element.
|
||||
* mxmlWalkNext() - Walk to the next logical node in the tree.
|
||||
* mxmlWalkPrev() - Walk to the previous logical node in the tree.
|
||||
* mxml_walk_next() - Walk to the next logical node in the tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -31,14 +30,6 @@
|
||||
#include "mxml.h"
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
mxml_node_t *mxml_walk_next(mxml_node_t *node, mxml_node_t *top,
|
||||
int descend);
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlFindElement()' - Find the named element.
|
||||
*/
|
||||
@ -46,13 +37,26 @@ mxml_node_t *mxml_walk_next(mxml_node_t *node, mxml_node_t *top,
|
||||
mxml_node_t * /* O - Element node or NULL */
|
||||
mxmlFindElement(mxml_node_t *node, /* I - Current node */
|
||||
mxml_node_t *top, /* I - Top node */
|
||||
const char *name) /* I - Element name */
|
||||
const char *name, /* I - Element name or NULL for any */
|
||||
const char *attr, /* I - Attribute name, or NULL for none */
|
||||
const char *value, /* I - Attribute value, or NULL for any */
|
||||
int descend) /* I - Descend into tree? */
|
||||
{
|
||||
const char *temp; /* Current attribute value */
|
||||
|
||||
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
|
||||
if (!node || !top || (!attr && value))
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Start with the next node...
|
||||
*/
|
||||
|
||||
node = mxmlWalkNext(node, top);
|
||||
node = mxmlWalkNext(node, top, descend);
|
||||
|
||||
/*
|
||||
* Loop until we find a matching element...
|
||||
@ -66,14 +70,38 @@ mxmlFindElement(mxml_node_t *node, /* I - Current node */
|
||||
|
||||
if (node->type == MXML_ELEMENT &&
|
||||
node->value.element.name &&
|
||||
!strcmp(node->value.element.name, name))
|
||||
return (node);
|
||||
(!name || !strcmp(node->value.element.name, name)))
|
||||
{
|
||||
/*
|
||||
* See if we need to check for an attribute...
|
||||
*/
|
||||
|
||||
if (!attr)
|
||||
return (node); /* No attribute search, return it... */
|
||||
|
||||
/*
|
||||
* Check for the attribute...
|
||||
*/
|
||||
|
||||
if ((temp = mxmlElementGetAttr(node, attr)) != NULL)
|
||||
{
|
||||
/*
|
||||
* OK, we have the attribute, does it match?
|
||||
*/
|
||||
|
||||
if (!value || !strcmp(value, temp))
|
||||
return (node); /* Yes, return it... */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Nope, move on to the next...
|
||||
* No match, move on to the next node...
|
||||
*/
|
||||
|
||||
node = mxmlWalkNext(node, top);
|
||||
if (descend == MXML_DESCEND)
|
||||
node = mxmlWalkNext(node, top, MXML_DESCEND);
|
||||
else
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
@ -86,9 +114,29 @@ mxmlFindElement(mxml_node_t *node, /* I - Current node */
|
||||
|
||||
mxml_node_t * /* O - Next node or NULL */
|
||||
mxmlWalkNext(mxml_node_t *node, /* I - Current node */
|
||||
mxml_node_t *top) /* I - Top node */
|
||||
mxml_node_t *top, /* I - Top node */
|
||||
int descend) /* I - Descend into tree? */
|
||||
{
|
||||
return (mxml_walk_next(node, top, 1));
|
||||
if (!node)
|
||||
return (NULL);
|
||||
else if (node->child && descend)
|
||||
return (node->child);
|
||||
else if (node->next)
|
||||
return (node->next);
|
||||
else if (node->parent != top)
|
||||
{
|
||||
node = node->parent;
|
||||
|
||||
while (!node->next)
|
||||
if (node->parent == top)
|
||||
return (NULL);
|
||||
else
|
||||
node = node->parent;
|
||||
|
||||
return (node->next);
|
||||
}
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -98,12 +146,29 @@ mxmlWalkNext(mxml_node_t *node, /* I - Current node */
|
||||
|
||||
mxml_node_t * /* O - Previous node or NULL */
|
||||
mxmlWalkPrev(mxml_node_t *node, /* I - Current node */
|
||||
mxml_node_t *top) /* I - Top node */
|
||||
mxml_node_t *top, /* I - Top node */
|
||||
int descend) /* I - Descend into tree? */
|
||||
{
|
||||
if (!node)
|
||||
return (NULL);
|
||||
else if (node->prev)
|
||||
return (node->prev);
|
||||
{
|
||||
if (node->prev->last_child && descend)
|
||||
{
|
||||
/*
|
||||
* Find the last child under the previous node...
|
||||
*/
|
||||
|
||||
node = node->prev->last_child;
|
||||
|
||||
while (node->last_child)
|
||||
node = node->last_child;
|
||||
|
||||
return (node);
|
||||
}
|
||||
else
|
||||
return (node->prev);
|
||||
}
|
||||
else if (node->parent != top)
|
||||
return (node->parent);
|
||||
else
|
||||
@ -112,27 +177,5 @@ mxmlWalkPrev(mxml_node_t *node, /* I - Current node */
|
||||
|
||||
|
||||
/*
|
||||
* 'mxml_walk_next()' - Walk to the next logical node in the tree.
|
||||
*/
|
||||
|
||||
mxml_node_t * /* O - Next node or NULL */
|
||||
mxml_walk_next(mxml_node_t *node, /* I - Current node */
|
||||
mxml_node_t *top, /* I - Top node */
|
||||
int descend) /* I - 1 = descend, 0 = don't */
|
||||
{
|
||||
if (!node)
|
||||
return (NULL);
|
||||
else if (node->child && descend)
|
||||
return (node->child);
|
||||
else if (node->next)
|
||||
return (node->next);
|
||||
else if (node->parent != top)
|
||||
return (mxml_walk_next(node->parent, top, 0));
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml-search.c,v 1.2 2003/06/03 20:40:01 mike Exp $".
|
||||
* End of "$Id: mxml-search.c,v 1.3 2003/06/04 16:30:40 mike Exp $".
|
||||
*/
|
||||
|
21
mxml.h
21
mxml.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml.h,v 1.4 2003/06/04 02:34:30 mike Exp $"
|
||||
* "$Id: mxml.h,v 1.5 2003/06/04 16:30:40 mike Exp $"
|
||||
*
|
||||
* Header file for mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -31,6 +31,7 @@
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <ctype.h>
|
||||
# include <errno.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -38,7 +39,12 @@
|
||||
*/
|
||||
|
||||
# define MXML_NO_CALLBACK (mxml_type_t (*)(mxml_node_t *))0
|
||||
# define MXML_WRAP 72
|
||||
/* Don't use a type callback */
|
||||
# define MXML_WRAP 72 /* Wrap XML output at this column position */
|
||||
|
||||
# define MXML_DESCEND 1 /* Descend when finding/walking */
|
||||
# define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */
|
||||
# define MXML_DESCEND_FIRST -1 /* Descend for first find */
|
||||
|
||||
|
||||
/*
|
||||
@ -109,7 +115,8 @@ extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name);
|
||||
extern void mxmlElementSetAttr(mxml_node_t *node, const char *name,
|
||||
const char *value);
|
||||
extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top,
|
||||
const char *name);
|
||||
const char *name, const char *attr,
|
||||
const char *value, int descend);
|
||||
extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp,
|
||||
mxml_type_t (*cb)(mxml_node_t *));
|
||||
extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
|
||||
@ -119,8 +126,10 @@ extern mxml_node_t *mxmlNewReal(mxml_node_t *parent, double real);
|
||||
extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace,
|
||||
const char *string);
|
||||
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp);
|
||||
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top);
|
||||
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top);
|
||||
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
|
||||
int descend);
|
||||
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
||||
int descend);
|
||||
|
||||
|
||||
/*
|
||||
@ -134,5 +143,5 @@ extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top);
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml.h,v 1.4 2003/06/04 02:34:30 mike Exp $".
|
||||
* End of "$Id: mxml.h,v 1.5 2003/06/04 16:30:40 mike Exp $".
|
||||
*/
|
||||
|
269
mxmldoc.c
269
mxmldoc.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* "$Id: mxmldoc.c,v 1.1 2003/06/04 03:07:47 mike Exp $"
|
||||
* "$Id: mxmldoc.c,v 1.2 2003/06/04 16:30:40 mike Exp $"
|
||||
*
|
||||
* Documentation generator for mini-XML, a small XML-like file parsing
|
||||
* Documentation generator using mini-XML, a small XML-like file parsing
|
||||
* library.
|
||||
*
|
||||
* Copyright 2003 by Michael Sweet.
|
||||
@ -28,12 +28,83 @@
|
||||
#include "mxml.h"
|
||||
|
||||
|
||||
/*
|
||||
* This program scans source and header files and produces public API
|
||||
* documentation for code that conforms to the CUPS Configuration
|
||||
* Management Plan (CMP) coding standards. Please see the following web
|
||||
* page for details:
|
||||
*
|
||||
* http://www.cups.org/cmp.html
|
||||
*
|
||||
* Using Mini-XML, this program creates and maintains an XML representation
|
||||
* of the public API code documentation which can then be converted to HTML
|
||||
* as desired. The following is a poor-man's schema:
|
||||
*
|
||||
* <namespace name=""> [name is usually "std"...]
|
||||
* <constant name="">
|
||||
* <description>descriptive text</description>
|
||||
* </constant>
|
||||
*
|
||||
* <enumeration name="">
|
||||
* <constant name="">...</constant>
|
||||
* </enumeration>
|
||||
*
|
||||
* <typedef name="">
|
||||
* <description>descriptive text</description>
|
||||
* <type>type string</type>
|
||||
* </typedef>
|
||||
*
|
||||
* <function name="">
|
||||
* <description>descriptive text</description>
|
||||
* <iargument name="">
|
||||
* <description>descriptive text</description>
|
||||
* <type>type string</type>
|
||||
* </iargument>
|
||||
* <oargument name="">
|
||||
* <description>descriptive text</description>
|
||||
* <type>type string</type>
|
||||
* </oargument>
|
||||
* <ioargument name="">
|
||||
* <description>descriptive text</description>
|
||||
* <type>type string</type>
|
||||
* </ioargument>
|
||||
* <returnvalue>
|
||||
* <description>descriptive text</description>
|
||||
* <type>type string</type>
|
||||
* </returnvalue>
|
||||
* <seealso>function names separated by spaces</seealso>
|
||||
* </function>
|
||||
*
|
||||
* <variable name="">
|
||||
* <description>descriptive text</description>
|
||||
* <type>type string</type>
|
||||
* </variable>
|
||||
*
|
||||
* <struct name="">
|
||||
* <description>descriptive text</description>
|
||||
* <variable name="">...</variable>
|
||||
* <function name="">...</function>
|
||||
* </struct>
|
||||
*
|
||||
* <class name="" parent="">
|
||||
* <description>descriptive text</description>
|
||||
* <class name="">...</class>
|
||||
* <enumeration name="">...</enumeration>
|
||||
* <function name="">...</function>
|
||||
* <struct name="">...</struct>
|
||||
* <variable name="">...</variable>
|
||||
* </class>
|
||||
* </namespace>
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static void insert_func(mxml_node_t *tree, mxml_node_t *func);
|
||||
static int scan_file(const char *filename, mxml_node_t *tree);
|
||||
static void insert_node(mxml_node_t *tree, mxml_node_t *func);
|
||||
static int scan_file(const char *filename, FILE *fp,
|
||||
mxml_node_t *doc);
|
||||
|
||||
|
||||
/*
|
||||
@ -44,151 +115,184 @@ int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line args */
|
||||
char *argv[]) /* I - Command-line args */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
FILE *fp; /* File to read */
|
||||
mxml_node_t *tree, /* XML tree */
|
||||
*node; /* Node which should be in test.xml */
|
||||
mxml_node_t *doc; /* XML documentation tree */
|
||||
|
||||
|
||||
/*
|
||||
* Check arguments...
|
||||
*/
|
||||
|
||||
if (argc != 2)
|
||||
if (argc < 2)
|
||||
{
|
||||
fputs("Usage: testmxml filename.xml\n", stderr);
|
||||
fputs("Usage: mxmldoc filename.xml [source files] >filename.html\n", stderr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the file...
|
||||
* Read the XML documentation file, if it exists...
|
||||
*/
|
||||
|
||||
if ((fp = fopen(argv[1], "r")) == NULL)
|
||||
{
|
||||
perror(argv[1]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the file...
|
||||
*/
|
||||
|
||||
tree = mxmlLoadFile(NULL, fp, type_cb);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (!tree)
|
||||
{
|
||||
fputs("Unable to read XML file!\n", stderr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "test.xml"))
|
||||
if ((fp = fopen(argv[1], "r")) != NULL)
|
||||
{
|
||||
/*
|
||||
* Verify that mxmlFindElement() and indirectly mxmlWalkNext() work
|
||||
* properly...
|
||||
* Read the existing XML file...
|
||||
*/
|
||||
|
||||
if ((node = mxmlFindElement(tree, tree, "choice")) == NULL)
|
||||
{
|
||||
fputs("Unable to find first <choice> element in XML tree!\n", stderr);
|
||||
mxmlDelete(tree);
|
||||
return (1);
|
||||
}
|
||||
doc = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
|
||||
|
||||
if ((node = mxmlFindElement(node, tree, "choice")) == NULL)
|
||||
fclose(fp);
|
||||
|
||||
if (!doc)
|
||||
{
|
||||
fputs("Unable to find second <choice> element in XML tree!\n", stderr);
|
||||
mxmlDelete(tree);
|
||||
fprintf(stderr, "Unable to read the XML documentation file \"%s\"!\n",
|
||||
argv[1]);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Create an empty XML documentation file...
|
||||
*/
|
||||
|
||||
doc = mxmlNewElement(NULL, "namespace");
|
||||
|
||||
mxmlElementSetAttr(doc, "name", "std");
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the XML tree...
|
||||
* Loop through all of the source files...
|
||||
*/
|
||||
|
||||
mxmlSaveFile(tree, stdout);
|
||||
puts("");
|
||||
for (i = 2; i < argc; i ++)
|
||||
if ((fp = fopen(argv[i], "r")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Unable to open source file \"%s\": %s\n", argv[i],
|
||||
strerror(errno));
|
||||
mxmlDelete(doc);
|
||||
return (1);
|
||||
}
|
||||
else if (scan_file(argv[i], fp, doc))
|
||||
{
|
||||
fclose(fp);
|
||||
mxmlDelete(doc);
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
fclose(fp);
|
||||
|
||||
/*
|
||||
* Save the updated XML documentation file...
|
||||
*/
|
||||
|
||||
if ((fp = fopen(argv[1], "w")) != NULL)
|
||||
{
|
||||
/*
|
||||
* Write over the existing XML file...
|
||||
*/
|
||||
|
||||
if (mxmlSaveFile(doc, fp))
|
||||
{
|
||||
fprintf(stderr, "Unable to write the XML documentation file \"%s\": %s!\n",
|
||||
argv[1], strerror(errno));
|
||||
fclose(fp);
|
||||
mxmlDelete(doc);
|
||||
return (1);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unable to create the XML documentation file \"%s\": %s!\n",
|
||||
argv[1], strerror(errno));
|
||||
mxmlDelete(doc);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete the tree and return...
|
||||
*/
|
||||
|
||||
mxmlDelete(tree);
|
||||
mxmlDelete(doc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'insert_func()' - Insert a function into a tree.
|
||||
* 'insert_node()' - Insert a node into a tree.
|
||||
*/
|
||||
|
||||
static void
|
||||
insert_func(mxml_node_t *tree, /* I - Tree to insert into */
|
||||
mxml_node_t *func) /* I - Function to add */
|
||||
insert_node(mxml_node_t *tree, /* I - Tree to insert into */
|
||||
mxml_node_t *node) /* I - Node to add */
|
||||
{
|
||||
mxml_node_t *node; /* Current node */
|
||||
const char *funcname, /* Name of function */
|
||||
*nodename; /* Name of current node */
|
||||
int diff; /* Different between names */
|
||||
mxml_node_t *temp; /* Current node */
|
||||
const char *tempname, /* Name of current node */
|
||||
*nodename; /* Name of node */
|
||||
|
||||
|
||||
funcname = mxmlElementGetAttr(func, "name");
|
||||
/*
|
||||
* Get the node name...
|
||||
*/
|
||||
|
||||
for (node = tree->child; node; node = node->next)
|
||||
nodename = mxmlElementGetAttr(node, "name");
|
||||
|
||||
/*
|
||||
* Delete an existing definition, if one exists...
|
||||
*/
|
||||
|
||||
if ((temp = mxmlFindElement(tree, tree, node->value.element.name,
|
||||
"name", nodename, MXML_DESCEND_FIRST)) != NULL)
|
||||
mxmlDelete(temp);
|
||||
|
||||
/*
|
||||
* Insert the node into the tree...
|
||||
*/
|
||||
|
||||
for (temp = tree->child; temp; temp = temp->next)
|
||||
{
|
||||
if (node->type != MXML_ELEMENT ||
|
||||
strcmp(node->value.element.name, "function"))
|
||||
if ((tempname = mxmlElementGetAttr(temp, "name")) == NULL)
|
||||
continue;
|
||||
|
||||
if ((nodename = mxmlElementGetAttr(node, "name")) == NULL)
|
||||
continue;
|
||||
|
||||
if ((diff = strcmp(funcname, nodename)) == 0)
|
||||
{
|
||||
mxmlDelete(node);
|
||||
insert_func(tree, func);
|
||||
return;
|
||||
}
|
||||
|
||||
if (diff > 0)
|
||||
if (strcmp(nodename, tempname) > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (node)
|
||||
if (temp)
|
||||
{
|
||||
/*
|
||||
* Insert function before this node...
|
||||
* Insert node before this temp...
|
||||
*/
|
||||
|
||||
func->next = node;
|
||||
func->prev = node->prev;
|
||||
node->next = temp;
|
||||
node->prev = temp->prev;
|
||||
|
||||
if (node->prev)
|
||||
node->prev->next = func;
|
||||
if (temp->prev)
|
||||
temp->prev->next = node;
|
||||
else
|
||||
tree->child = func;
|
||||
tree->child = node;
|
||||
|
||||
node->prev = func;
|
||||
temp->prev = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Append function to the end...
|
||||
* Append node to the end...
|
||||
*/
|
||||
|
||||
func->prev = tree->last_child;
|
||||
node->prev = tree->last_child;
|
||||
|
||||
if (tree->last_child)
|
||||
tree->last_child->next = func;
|
||||
tree->last_child->next = node;
|
||||
else
|
||||
tree->last_child = func;
|
||||
tree->last_child = node;
|
||||
|
||||
if (!tree->child)
|
||||
tree->child = func;
|
||||
tree->child = node;
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,12 +302,13 @@ insert_func(mxml_node_t *tree, /* I - Tree to insert into */
|
||||
*/
|
||||
|
||||
static int /* O - 0 on success, -1 on error */
|
||||
scan_file(const char *filename, /* I - File to scan */
|
||||
scan_file(const char *filename, /* I - Filename */
|
||||
FILE *fp, /* I - File to scan */
|
||||
mxml_node_t *tree) /* I - Function tree */
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxmldoc.c,v 1.1 2003/06/04 03:07:47 mike Exp $".
|
||||
* End of "$Id: mxmldoc.c,v 1.2 2003/06/04 16:30:40 mike Exp $".
|
||||
*/
|
||||
|
13
testmxml.c
13
testmxml.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: testmxml.c,v 1.4 2003/06/04 01:23:21 mike Exp $"
|
||||
* "$Id: testmxml.c,v 1.5 2003/06/04 16:30:40 mike Exp $"
|
||||
*
|
||||
* Test program for mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -89,14 +89,16 @@ main(int argc, /* I - Number of command-line args */
|
||||
* properly...
|
||||
*/
|
||||
|
||||
if ((node = mxmlFindElement(tree, tree, "choice")) == NULL)
|
||||
if ((node = mxmlFindElement(tree, tree, "choice", NULL, NULL,
|
||||
MXML_DESCEND)) == NULL)
|
||||
{
|
||||
fputs("Unable to find first <choice> element in XML tree!\n", stderr);
|
||||
mxmlDelete(tree);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if ((node = mxmlFindElement(node, tree, "choice")) == NULL)
|
||||
if ((node = mxmlFindElement(node, tree, "choice", NULL, NULL,
|
||||
MXML_NO_DESCEND)) == NULL)
|
||||
{
|
||||
fputs("Unable to find second <choice> element in XML tree!\n", stderr);
|
||||
mxmlDelete(tree);
|
||||
@ -140,7 +142,8 @@ type_cb(mxml_node_t *node) /* I - Element node */
|
||||
|
||||
if (!strcmp(type, "integer"))
|
||||
return (MXML_INTEGER);
|
||||
else if (!strcmp(type, "opaque"))
|
||||
else if (!strcmp(type, "opaque") ||
|
||||
!strcmp(type, "pre") || !strcmp(type, "PRE"))
|
||||
return (MXML_OPAQUE);
|
||||
else if (!strcmp(type, "real"))
|
||||
return (MXML_REAL);
|
||||
@ -150,5 +153,5 @@ type_cb(mxml_node_t *node) /* I - Element node */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: testmxml.c,v 1.4 2003/06/04 01:23:21 mike Exp $".
|
||||
* End of "$Id: testmxml.c,v 1.5 2003/06/04 16:30:40 mike Exp $".
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user