mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-08 13:39:58 +00:00
Save work on documentation.
Add SAX load APIs. Add man page output for mxmldoc. Add types for various callback functions.
This commit is contained in:
parent
0f8052e766
commit
bf73da6782
3
CHANGES
3
CHANGES
@ -1,10 +1,11 @@
|
||||
CHANGES - 2007-04-19
|
||||
CHANGES - 2007-04-22
|
||||
--------------------
|
||||
|
||||
CHANGES IN Mini-XML 2.3
|
||||
|
||||
- Added two exceptions to the LGPL to support static
|
||||
linking of applications against Mini-XML
|
||||
- The mxmldoc utility can now generate man pages, too.
|
||||
- Added a mxmlNewXML() function
|
||||
- Added a mxmlElementSetAttrf() function (STR #43)
|
||||
- Added snprintf() emulation function for test program (STR
|
||||
|
12
Makefile.in
12
Makefile.in
@ -113,7 +113,7 @@ all: Makefile config.h $(TARGETS)
|
||||
#
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) $(TARGETS)
|
||||
$(RM) $(OBJS) $(TARGETS) doc/mxml.man
|
||||
$(RM) mxmldoc-static libmxml.a
|
||||
|
||||
|
||||
@ -349,6 +349,16 @@ valgrind: mxmldoc-static
|
||||
>valgrind.html 2>valgrind.out
|
||||
|
||||
|
||||
#
|
||||
# doc/mxml.man
|
||||
#
|
||||
|
||||
doc/mxml.man: mxmldoc-static mxml.xml
|
||||
$(RM) doc/mxml.man
|
||||
./mxmldoc-static --man mxml --title "Mini-XML API" \
|
||||
--intro doc/intro.man mxml.xml >doc/mxml.man
|
||||
|
||||
|
||||
#
|
||||
# All object files depend on the makefile...
|
||||
#
|
||||
|
@ -346,6 +346,7 @@ function:</p>
|
||||
</pre>
|
||||
|
||||
|
||||
<!-- NEED 20 -->
|
||||
<h2>Changing Node Values</h2>
|
||||
|
||||
<p>All of the examples so far have concentrated on creating and
|
||||
@ -483,5 +484,147 @@ function:</p>
|
||||
mxmlIndexDelete(ind);
|
||||
</pre>
|
||||
|
||||
<h2>SAX (Stream) Loading of Documents</h2>
|
||||
|
||||
<p>Mini-XML supports an implementation of the Simple API for XML
|
||||
(SAX) which allows you to load and process an XML document as a
|
||||
stream of nodes. Aside from allowing you to process XML documents of
|
||||
any size, the Mini-XML implementation also allows you to retain
|
||||
portions of the document in memory for later processing.</p>
|
||||
|
||||
<p>The <a href='#mxmlSAXLoad'><tt>mxmlSAXLoadFd</tt></a>, <a
|
||||
href='#mxmlSAXLoadFile'><tt>mxmlSAXLoadFile</tt></a>, and <a
|
||||
href='#mxmlSAXLoadString'><tt>mxmlSAXLoadString</tt></a> functions
|
||||
provide the SAX loading APIs. Each function works like the
|
||||
corresponding <tt>mxmlLoad</tt> function but uses a callback to
|
||||
process each node as it is read.</p>
|
||||
|
||||
<p>The callback function receives the node, an event code, and
|
||||
a user data pointer you supply:</p>
|
||||
|
||||
<pre>
|
||||
void
|
||||
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The event will be one of the following:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>MXML_SAX_CDATA</tt> - CDATA was just read</li>
|
||||
|
||||
<li><tt>MXML_SAX_COMMENT</tt> - A comment was just read</li>
|
||||
|
||||
<li><tt>MXML_SAX_DATA</tt> - Data (custom, integer, opaque, real, or text) was just read</li>
|
||||
|
||||
<li><tt>MXML_SAX_DIRECTIVE</tt> - A processing directive was just read</li>
|
||||
|
||||
<li><tt>MXML_SAX_ELEMENT_CLOSE</tt> - An open element was just read (<tt><element></tt>)</li>
|
||||
|
||||
<li><tt>MXML_SAX_ELEMENT_OPEN</tt> - A close element was just read (<tt></element></tt>)</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p>Elements are <em>released</em> after the close element is
|
||||
processed. All other nodes are released after they are processed.
|
||||
The SAX callback can <em>retain</em> the node using the <a
|
||||
href='#mxmlRetain'><tt>mxmlRetain</tt></a> function. For example,
|
||||
the following SAX callback will retain all nodes, effectively
|
||||
simulating a normal in-memory load:</p>
|
||||
|
||||
<pre>
|
||||
void
|
||||
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
if (event != MXML_SAX_ELEMENT_CLOSE)
|
||||
mxmlRetain(node);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>More typically the SAX callback will only retain a small portion
|
||||
of the document that is needed for post-processing. For example, the
|
||||
following SAX callback will retain the title and headings in an
|
||||
XHTML file. It also retains the (parent) elements like <tt><html></tt>, <tt><head></tt>, and <tt><body></tt>, and processing
|
||||
directives like <tt><?xml ... ?></tt> and <tt><!DOCTYPE ... ></tt>:</p>
|
||||
|
||||
<!-- NEED 10 -->
|
||||
<pre>
|
||||
void
|
||||
sax_cb(mxml_node_t *node,
|
||||
mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
if (event == MXML_SAX_ELEMENT_OPEN)
|
||||
{
|
||||
/*
|
||||
* Retain headings and titles...
|
||||
*/
|
||||
|
||||
const char *name = node->value.element.name;
|
||||
|
||||
if (!strcmp(name, "html") ||
|
||||
!strcmp(name, "head") ||
|
||||
!strcmp(name, "title") ||
|
||||
!strcmp(name, "body") ||
|
||||
!strcmp(name, "h1") ||
|
||||
!strcmp(name, "h2") ||
|
||||
!strcmp(name, "h3") ||
|
||||
!strcmp(name, "h4") ||
|
||||
!strcmp(name, "h5") ||
|
||||
!strcmp(name, "h6"))
|
||||
mxmlRetain(node);
|
||||
}
|
||||
else if (event == MXML_SAX_DIRECTIVE)
|
||||
mxmlRetain(node);
|
||||
else if (event == MXML_SAX_DATA &&
|
||||
node->parent->ref_count > 1)
|
||||
{
|
||||
/*
|
||||
* If the parent was retained, then retain
|
||||
* this data node as well.
|
||||
*/
|
||||
|
||||
mxmlRetain(node);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The resulting skeleton document tree can then be searched just
|
||||
like one loaded using the <tt>mxmlLoad</tt> functions. For example,
|
||||
a filter that reads an XHTML document from stdin and then shows the
|
||||
title and headings in the document would look like:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *doc, *title, *body, *heading;
|
||||
|
||||
doc = mxmlSAXLoadFd(NULL, 0,
|
||||
MXML_TEXT_CALLBACK,
|
||||
<b>sax_cb</b>, NULL);
|
||||
|
||||
title = mxmlFindElement(doc, doc, "title",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
|
||||
if (title)
|
||||
print_children(title);
|
||||
|
||||
body = mxmlFindElement(doc, doc, "body",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
|
||||
if (body)
|
||||
{
|
||||
for (heading = body->child;
|
||||
heading;
|
||||
heading = heading->next)
|
||||
print_children(heading);
|
||||
}
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -417,27 +417,31 @@ three constants:</p>
|
||||
<li><tt>MXML_NO_DESCEND</tt> means to not to look at any
|
||||
child nodes in the element hierarchy, just look at
|
||||
siblings at the same level or parent nodes until the top
|
||||
node or top-of-tree is reached. The previous node from
|
||||
"group" would be the "node" element to the left, while
|
||||
the next node from "group" would be the "node" element
|
||||
to the right.<br><br></li>
|
||||
node or top-of-tree is reached.
|
||||
|
||||
<li><tt>MXML_DESCEND_FIRST</tt> means that it is OK to
|
||||
descend to the first child of a node, but not to descend
|
||||
further when searching. You'll normally use this when
|
||||
iterating through direct children of a parent node, e.g.
|
||||
all of the "node" elements under the "?xml" parent node
|
||||
in the example above. This mode is only applicable to
|
||||
the search function; the walk functions treat this as
|
||||
<tt>MXML_DESCEND</tt> since every call is a first
|
||||
time.<br><br></li>
|
||||
<p>The previous node from "group" would be the "node"
|
||||
element to the left, while the next node from "group" would
|
||||
be the "node" element to the right.<br><br></p></li>
|
||||
|
||||
<li><tt>MXML_DESCEND_FIRST</tt> means that it is OK to
|
||||
descend to the first child of a node, but not to descend
|
||||
further when searching. You'll normally use this when
|
||||
iterating through direct children of a parent node, e.g. all
|
||||
of the "node" and "group" elements under the "?xml" parent
|
||||
node in the example above.
|
||||
|
||||
<p>This mode is only applicable to the search function; the
|
||||
walk functions treat this as <tt>MXML_DESCEND</tt> since
|
||||
every call is a first time.<br><br></p></li>
|
||||
|
||||
<li><tt>MXML_DESCEND</tt> means to keep descending until
|
||||
you hit the bottom of the tree. The previous node from
|
||||
"group" would be the "val3" node and the next node would
|
||||
be the first node element under "group". If you were to
|
||||
walk from the root node "?xml" to the end of the tree
|
||||
with <tt>mxmlWalkNext()</tt>, the order would be:
|
||||
be the first node element under "group".
|
||||
|
||||
<p>If you were to walk from the root node "?xml" to the end
|
||||
of the tree with <tt>mxmlWalkNext()</tt>, the order would
|
||||
be:</p>
|
||||
|
||||
<p><tt>?xml data node val1 node val2 node val3 group node
|
||||
val4 node val5 node val6 node val7 node val8</tt></p>
|
||||
|
@ -148,9 +148,9 @@ appendices:</p>
|
||||
<tt>mxmldoc(1)</tt> program to generate software
|
||||
documentation.</li>
|
||||
|
||||
<li>Appendix A, "<a href='#LICENSE'>GNU
|
||||
Library General Public License</a>", provides the terms
|
||||
and conditions for using and distributing Mini-XML.</li>
|
||||
<li>Appendix A, "<a href='#LICENSE'>Mini-XML License</a>",
|
||||
provides the terms and conditions for using and distributing
|
||||
Mini-XML.</li>
|
||||
|
||||
<li>Appendix B, "<a href='#RELNOTES'>Release Notes</a>",
|
||||
lists the changes in each release of Mini-XML.</li>
|
||||
|
@ -1,23 +1,3 @@
|
||||
.\"
|
||||
.\" "$Id$"
|
||||
.\"
|
||||
.\" mxml man page for mini-XML, a small XML-like file parsing library.
|
||||
.\"
|
||||
.\" Copyright 2003-2005 by Michael Sweet.
|
||||
.\"
|
||||
.\" This program 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, or (at your option) any later version.
|
||||
.\"
|
||||
.\" This program 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 General Public License for more details.
|
||||
.\"
|
||||
.TH mxml 3 "mini-XML" "2 December 2005" "Michael Sweet"
|
||||
.SH NAME
|
||||
mxml \- mini-xml library
|
||||
.SH INCLUDE FILE
|
||||
#include <mxml.h>
|
||||
.SH LIBRARY
|
||||
@ -171,7 +151,4 @@ is used for a particular node or the entire tree:
|
||||
.SH SEE ALSO
|
||||
mxmldoc(1), Mini-XML Programmers Manual, http://www.easysw.com/~mike/mxml/
|
||||
.SH COPYRIGHT
|
||||
Copyright 2003-2005 by Michael Sweet.
|
||||
.\"
|
||||
.\" End of "$Id$".
|
||||
.\"
|
||||
Copyright 2003-2007 by Michael Sweet.
|
@ -3,8 +3,6 @@
|
||||
|
||||
<h1 align='right'><a name='LICENSE'>A - Mini-XML License</a></h1>
|
||||
|
||||
<p align='center'>October 18, 2005</p>
|
||||
|
||||
<p>The Mini-XML library and included programs are provided under
|
||||
the terms of the GNU Library General Public License (LGPL) with
|
||||
the following exceptions:</p>
|
||||
@ -32,9 +30,9 @@ the following exceptions:</p>
|
||||
|
||||
</ol>
|
||||
|
||||
<hr noshade>
|
||||
<!-- NEW PAGE -->
|
||||
|
||||
<p align=center><big>GNU LIBRARY GENERAL PUBLIC LICENSE</big></p>
|
||||
<p align=center><b>GNU LIBRARY GENERAL PUBLIC LICENSE</b></p>
|
||||
<p align='center'>Version 2, June 1991
|
||||
<br />Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
<br />59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
@ -43,7 +41,7 @@ this license document, but changing it is not allowed.
|
||||
<br />[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]</p>
|
||||
|
||||
<p><big>Preamble</big></p>
|
||||
<p><b>Preamble</b></p>
|
||||
|
||||
<p>The licenses for most software are designed to take away your freedom
|
||||
to share and change it. By contrast, the GNU General Public Licenses
|
||||
@ -145,8 +143,8 @@ library.</p>
|
||||
ordinary General Public License rather than by this special
|
||||
one.</p>
|
||||
|
||||
<p align='center'><big>TERMS AND CONDITIONS FOR COPYING,
|
||||
DISTRIBUTION AND MODIFICATION</big></p>
|
||||
<p align='center'><b>TERMS AND CONDITIONS FOR COPYING,
|
||||
DISTRIBUTION AND MODIFICATION</b></p>
|
||||
|
||||
<p><strong>0.</strong> This License Agreement applies to any
|
||||
software library which contains a notice placed by the copyright
|
||||
@ -511,7 +509,7 @@ by the two goals of preserving the free status of all
|
||||
derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.</p>
|
||||
|
||||
<p align='center'><big>NO WARRANTY</big></p>
|
||||
<p align='center'><b>NO WARRANTY</b></p>
|
||||
|
||||
<p><strong>15.</strong> BECAUSE THE LIBRARY IS LICENSED FREE OF
|
||||
CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT
|
||||
@ -537,54 +535,61 @@ OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.</p>
|
||||
|
||||
<p align='center'><big>END OF TERMS AND CONDITIONS</big></p>
|
||||
<p align='center'><b>END OF TERMS AND CONDITIONS</b></p>
|
||||
|
||||
<p><big>How to Apply These Terms to Your New Libraries</big></p>
|
||||
<p><b>How to Apply These Terms to Your New Libraries</b></p>
|
||||
|
||||
<p>If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
<p>If you develop a new library, and you want it to be of the
|
||||
greatest possible use to the public, we recommend making it free
|
||||
software that everyone can redistribute and change. You can do so
|
||||
by permitting redistribution under these terms (or, alternatively,
|
||||
under the terms of the ordinary General Public License).
|
||||
|
||||
<p>To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
<p>To apply these terms, attach the following notices to the
|
||||
library. It is safest to attach them to the start of each source
|
||||
file to most effectively convey the exclusion of warranty; and each
|
||||
file should have at least the "copyright" line and a pointer to
|
||||
where the full notice is found.
|
||||
|
||||
<pre>
|
||||
<var>one line to give the library's name and an idea of what it does.</var>
|
||||
<ul>
|
||||
|
||||
<p><var>one line to give the library's name and an idea of what it
|
||||
does.</var><br>
|
||||
Copyright (C) <var>year</var> <var>name of author</var>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
<p>This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation; either version 2.1 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
<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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
<p>You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
</pre>
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA
|
||||
|
||||
</ul>
|
||||
|
||||
<p>Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
<p>You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
<p>You should also get your employer (if you work as a programmer)
|
||||
or your school, if any, to sign a "copyright disclaimer" for the
|
||||
library, if necessary. Here is a sample; alter the names:
|
||||
|
||||
<pre>
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||
the library `Frob' (a library for tweaking knobs) written
|
||||
by James Random Hacker.
|
||||
<ul>
|
||||
|
||||
<var>signature of Ty Coon</var>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
</pre>
|
||||
<p>Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James
|
||||
Random Hacker.
|
||||
|
||||
<p><var>signature of Ty Coon</var>, 1 April 1990 Ty Coon, President
|
||||
of Vice
|
||||
|
||||
</ul>
|
||||
|
||||
<p>That's all there is to it!
|
||||
|
||||
|
@ -1,36 +1,26 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html>
|
||||
<!-- SECTION: Man Pages -->
|
||||
<head>
|
||||
<style type='text/css'><!--
|
||||
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: 2em; }
|
||||
h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
|
||||
--></style>
|
||||
<title>mxmldoc</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- NEW PAGE -->
|
||||
<h2 class='title'><a name='mxmldoc.1'>mxmldoc(1)</a></h2>
|
||||
<h3 _hd_omit_toc>Name</h3>
|
||||
mxmldoc - mini-xml documentation generator
|
||||
<h3 _hd_omit_toc>Synopsis</h3>
|
||||
<b>mxmldoc
|
||||
</b>[ --intro
|
||||
<i>introfile.html
|
||||
</i>] [ --section
|
||||
<i>section
|
||||
</i>] [ --title
|
||||
<i>title
|
||||
</i>] [
|
||||
<i>filename.xml
|
||||
</i>] [
|
||||
<i>source file(s)
|
||||
</i>] >
|
||||
<i>filename.html
|
||||
</i><h3 _hd_omit_toc>Description</h3>
|
||||
<i>mxmldoc</i> scans the specified C and C++ source files to
|
||||
|
||||
<h1 align='right'><a name='MXMLDOC'>4 - Using the mxmldoc
|
||||
Utility</a></h1>
|
||||
|
||||
<p>Originally developed to generate the Mini-XML and CUPS API
|
||||
documentation, the <tt>mxmldoc(1)</tt> program converts C and C++
|
||||
source files into an intermediate XML format and uses in-line
|
||||
comments rather than comment headers to annotate functions, types,
|
||||
and constants. This chapter describes how to use it.</p>
|
||||
|
||||
<h2>The Basics</h2>
|
||||
|
||||
<h2>Commenting Your Code</h2>
|
||||
|
||||
<h2>Creating HTML Documentation</h2>
|
||||
|
||||
<h2>Creating Man Pages</h2>
|
||||
|
||||
<h2>The XML Schema</h2>
|
||||
|
||||
<p><i>mxmldoc</i> scans the specified C and C++ source files to
|
||||
produce an XML representation of globally accessible classes,
|
||||
constants, enumerations, functions, structures, typedefs,
|
||||
unions, and variables. The XML file is updated as necessary and
|
||||
|
@ -3,7 +3,7 @@
|
||||
.\"
|
||||
.\" mxmldoc man page for mini-XML, a small XML-like file parsing library.
|
||||
.\"
|
||||
.\" Copyright 2003-2005 by Michael Sweet.
|
||||
.\" Copyright 2003-2007 by Michael Sweet.
|
||||
.\"
|
||||
.\" This program is free software; you can redistribute it and/or
|
||||
.\" modify it under the terms of the GNU Library General Public
|
||||
@ -15,13 +15,20 @@
|
||||
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
.\" GNU General Public License for more details.
|
||||
.\"
|
||||
.TH mxmldoc 1 "mini-XML" "2 December 2005" "Michael Sweet"
|
||||
.TH mxmldoc 1 "Mini-XML" "22 April 2007" "Michael Sweet"
|
||||
.SH NAME
|
||||
mxmldoc \- mini-xml documentation generator
|
||||
.SH SYNOPSIS
|
||||
.B mxmldoc
|
||||
--no-output [
|
||||
.I filename.xml
|
||||
]
|
||||
.I source file(s)
|
||||
]
|
||||
.br
|
||||
.B mxmldoc
|
||||
[ --intro
|
||||
.I introfile.html
|
||||
.I introfile
|
||||
] [ --section
|
||||
.I section
|
||||
] [ --title
|
||||
@ -32,26 +39,53 @@ mxmldoc \- mini-xml documentation generator
|
||||
.I source file(s)
|
||||
] >
|
||||
.I filename.html
|
||||
.br
|
||||
.B mxmldoc
|
||||
--man
|
||||
.I manpage
|
||||
[ --intro
|
||||
.I introfile
|
||||
] [ --section
|
||||
.I section
|
||||
] [ --title
|
||||
.I title
|
||||
] [
|
||||
.I filename.xml
|
||||
] [
|
||||
.I source file(s)
|
||||
] >
|
||||
.I filename.man
|
||||
.SH DESCRIPTION
|
||||
\fImxmldoc\fR scans the specified C and C++ source files to
|
||||
produce an XML representation of globally accessible classes,
|
||||
constants, enumerations, functions, structures, typedefs,
|
||||
unions, and variables. The XML file is updated as necessary and
|
||||
a HTML representation of the XML file is written to the standard
|
||||
output. If no source files are specified then the current XML
|
||||
file is converted to HTML on the standard output.
|
||||
\fImxmldoc\fR scans the specified C and C++ source files to produce
|
||||
an XML representation of globally accessible classes, constants,
|
||||
enumerations, functions, structures, typedefs, unions, and variables
|
||||
- the XML file is updated as necessary. By default, a HTML
|
||||
representation of the XML file is written to the standard output.
|
||||
Use the \fI--no-output\fR option to disable the HTML output.
|
||||
.PP
|
||||
In general, any C or C++ source code is handled by
|
||||
\fImxmldoc\fR, however it was specifically written to handle
|
||||
code with documentation that is formatted according to the CUPS
|
||||
Configuration Management Plan which is available at
|
||||
"http://www.cups.org/documentation.php".
|
||||
Man page source can be generated using the \fI--man\fR option.
|
||||
.PP
|
||||
If no source files are specified then the current XML file is
|
||||
converted to the standard output.
|
||||
.PP
|
||||
In general, any C or C++ source code is handled by \fImxmldoc\fR,
|
||||
however it was specifically written to handle code with
|
||||
documentation that is formatted according to the CUPS Developer
|
||||
Guide which is available at "http://www.cups.org/documentation.php".
|
||||
.SH OPTIONS
|
||||
.TP 5
|
||||
\--intro introfile.html
|
||||
\--intro introfile
|
||||
.br
|
||||
Inserts the specified file at the top of the output documentation.
|
||||
.TP 5
|
||||
\--man manpage
|
||||
.br
|
||||
Generated a man page instead of HTML documentation.
|
||||
.TP 5
|
||||
\--no-output
|
||||
.br
|
||||
Disables generation of documentation on the standard output.
|
||||
.TP 5
|
||||
\--section section
|
||||
.br
|
||||
Sets the section/keywords in the output documentation.
|
||||
@ -62,7 +96,7 @@ Sets the title of the output documentation.
|
||||
.SH SEE ALSO
|
||||
mxml(3), Mini-XML Programmers Manual, http://www.easysw.com/~mike/mxml/
|
||||
.SH COPYRIGHT
|
||||
Copyright 2003-2005 by Michael Sweet.
|
||||
Copyright 2003-2007 by Michael Sweet.
|
||||
.\"
|
||||
.\" End of "$Id$".
|
||||
.\"
|
||||
|
1154
doc/reference.html
1154
doc/reference.html
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,9 @@
|
||||
<li>Added two exceptions to the LGPL to support static
|
||||
linking of applications against Mini-XML</li>
|
||||
|
||||
<li>The mxmldoc utility can now generate man pages,
|
||||
too.</li>
|
||||
|
||||
<li>Added a mxmlNewXML() function</li>
|
||||
|
||||
<li>Added a mxmlElementSetAttrf() function (STR #43)</li>
|
||||
|
@ -145,6 +145,8 @@ mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */
|
||||
* is replaced by the new formatted string. The formatted string value is
|
||||
* copied into the element node. This function does nothing if the node
|
||||
* is not an element.
|
||||
*
|
||||
* @since Mini-XML 2.3@
|
||||
*/
|
||||
|
||||
void
|
||||
|
416
mxml-file.c
416
mxml-file.c
@ -24,6 +24,12 @@
|
||||
* mxmlSaveFd() - Save an XML tree to a file descriptor.
|
||||
* mxmlSaveFile() - Save an XML tree to a file.
|
||||
* mxmlSaveString() - Save an XML node tree to a string.
|
||||
* mxmlSAXLoadFd() - Load a file descriptor into an XML node tree
|
||||
* using a SAX callback.
|
||||
* mxmlSAXLoadFile() - Load a file into an XML node tree
|
||||
* using a SAX callback.
|
||||
* mxmlSAXLoadString() - Load a string into an XML node tree
|
||||
* using a SAX callback.
|
||||
* mxmlSetCustomHandlers() - Set the handling functions for custom data.
|
||||
* mxmlSetErrorCallback() - Set the error message callback.
|
||||
* mxmlSetWrapMargin() - Set the the wrap margin when saving XML data.
|
||||
@ -75,16 +81,19 @@
|
||||
|
||||
|
||||
/*
|
||||
* Structures...
|
||||
* Types and structures...
|
||||
*/
|
||||
|
||||
typedef struct mxml_fdbuf_s /**** File descriptor buffer (@private@) ****/
|
||||
typedef int (*_mxml_getc_cb_t)(void *, int *);
|
||||
typedef int (*_mxml_putc_cb_t)(int, void *);
|
||||
|
||||
typedef struct _mxml_fdbuf_s /**** File descriptor buffer ****/
|
||||
{
|
||||
int fd; /* File descriptor */
|
||||
unsigned char *current, /* Current position in buffer */
|
||||
*end, /* End of buffer */
|
||||
buffer[8192]; /* Character buffer */
|
||||
} mxml_fdbuf_t;
|
||||
} _mxml_fdbuf_t;
|
||||
|
||||
|
||||
/*
|
||||
@ -117,32 +126,32 @@ static int mxml_add_char(int ch, char **ptr, char **buffer,
|
||||
int *bufsize);
|
||||
static int mxml_fd_getc(void *p, int *encoding);
|
||||
static int mxml_fd_putc(int ch, void *p);
|
||||
static int mxml_fd_read(mxml_fdbuf_t *buf);
|
||||
static int mxml_fd_write(mxml_fdbuf_t *buf);
|
||||
static int mxml_fd_read(_mxml_fdbuf_t *buf);
|
||||
static int mxml_fd_write(_mxml_fdbuf_t *buf);
|
||||
static int mxml_file_getc(void *p, int *encoding);
|
||||
static int mxml_file_putc(int ch, void *p);
|
||||
static int mxml_get_entity(mxml_node_t *parent, void *p,
|
||||
int *encoding,
|
||||
int (*getc_cb)(void *, int *));
|
||||
_mxml_getc_cb_t getc_cb);
|
||||
static mxml_node_t *mxml_load_data(mxml_node_t *top, void *p,
|
||||
mxml_type_t (*cb)(mxml_node_t *),
|
||||
int (*getc_cb)(void *, int *));
|
||||
mxml_load_cb_t cb,
|
||||
_mxml_getc_cb_t getc_cb,
|
||||
mxml_sax_cb_t sax_cb, void *sax_data);
|
||||
static int mxml_parse_element(mxml_node_t *node, void *p,
|
||||
int *encoding,
|
||||
int (*getc_cb)(void *, int *));
|
||||
_mxml_getc_cb_t getc_cb);
|
||||
static int mxml_string_getc(void *p, int *encoding);
|
||||
static int mxml_string_putc(int ch, void *p);
|
||||
static int mxml_write_name(const char *s, void *p,
|
||||
int (*putc_cb)(int, void *));
|
||||
_mxml_putc_cb_t putc_cb);
|
||||
static int mxml_write_node(mxml_node_t *node, void *p,
|
||||
const char *(*cb)(mxml_node_t *, int),
|
||||
int col,
|
||||
int (*putc_cb)(int, void *));
|
||||
mxml_save_cb_t cb, int col,
|
||||
_mxml_putc_cb_t putc_cb);
|
||||
static int mxml_write_string(const char *s, void *p,
|
||||
int (*putc_cb)(int, void *));
|
||||
_mxml_putc_cb_t putc_cb);
|
||||
static int mxml_write_ws(mxml_node_t *node, void *p,
|
||||
const char *(*cb)(mxml_node_t *, int), int ws,
|
||||
int col, int (*putc_cb)(int, void *));
|
||||
mxml_save_cb_t cb, int ws,
|
||||
int col, _mxml_putc_cb_t putc_cb);
|
||||
|
||||
|
||||
/*
|
||||
@ -161,12 +170,11 @@ static int mxml_write_ws(mxml_node_t *node, void *p,
|
||||
*/
|
||||
|
||||
mxml_node_t * /* O - First node or NULL if the file could not be read. */
|
||||
mxmlLoadFd(mxml_node_t *top, /* I - Top node */
|
||||
int fd, /* I - File descriptor to read from */
|
||||
mxml_type_t (*cb)(mxml_node_t *node))
|
||||
/* I - Callback function or MXML_NO_CALLBACK */
|
||||
mxmlLoadFd(mxml_node_t *top, /* I - Top node */
|
||||
int fd, /* I - File descriptor to read from */
|
||||
mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */
|
||||
{
|
||||
mxml_fdbuf_t buf; /* File descriptor buffer */
|
||||
_mxml_fdbuf_t buf; /* File descriptor buffer */
|
||||
|
||||
|
||||
/*
|
||||
@ -181,7 +189,7 @@ mxmlLoadFd(mxml_node_t *top, /* I - Top node */
|
||||
* Read the XML data...
|
||||
*/
|
||||
|
||||
return (mxml_load_data(top, &buf, cb, mxml_fd_getc));
|
||||
return (mxml_load_data(top, &buf, cb, mxml_fd_getc, MXML_NO_CALLBACK, NULL));
|
||||
}
|
||||
|
||||
|
||||
@ -201,16 +209,15 @@ mxmlLoadFd(mxml_node_t *top, /* I - Top node */
|
||||
*/
|
||||
|
||||
mxml_node_t * /* O - First node or NULL if the file could not be read. */
|
||||
mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
FILE *fp, /* I - File to read from */
|
||||
mxml_type_t (*cb)(mxml_node_t *node))
|
||||
/* I - Callback function or MXML_NO_CALLBACK */
|
||||
mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
FILE *fp, /* I - File to read from */
|
||||
mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */
|
||||
{
|
||||
/*
|
||||
* Read the XML data...
|
||||
*/
|
||||
|
||||
return (mxml_load_data(top, fp, cb, mxml_file_getc));
|
||||
return (mxml_load_data(top, fp, cb, mxml_file_getc, MXML_NO_CALLBACK, NULL));
|
||||
}
|
||||
|
||||
|
||||
@ -230,16 +237,16 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
*/
|
||||
|
||||
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 *node))
|
||||
/* I - Callback function or MXML_NO_CALLBACK */
|
||||
mxmlLoadString(mxml_node_t *top, /* I - Top node */
|
||||
const char *s, /* I - String to load */
|
||||
mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */
|
||||
{
|
||||
/*
|
||||
* Read the XML data...
|
||||
*/
|
||||
|
||||
return (mxml_load_data(top, &s, cb, mxml_string_getc));
|
||||
return (mxml_load_data(top, &s, cb, mxml_string_getc, MXML_NO_CALLBACK,
|
||||
NULL));
|
||||
}
|
||||
|
||||
|
||||
@ -260,9 +267,9 @@ mxmlLoadString(mxml_node_t *top, /* I - Top node */
|
||||
*/
|
||||
|
||||
char * /* O - Allocated string or NULL */
|
||||
mxmlSaveAllocString(mxml_node_t *node, /* I - Node to write */
|
||||
const char *(*cb)(mxml_node_t *node, int ws))
|
||||
/* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||
mxmlSaveAllocString(
|
||||
mxml_node_t *node, /* I - Node to write */
|
||||
mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||
{
|
||||
int bytes; /* Required bytes */
|
||||
char buffer[8192]; /* Temporary buffer */
|
||||
@ -317,13 +324,12 @@ mxmlSaveAllocString(mxml_node_t *node, /* I - Node to write */
|
||||
*/
|
||||
|
||||
int /* O - 0 on success, -1 on error. */
|
||||
mxmlSaveFd(mxml_node_t *node, /* I - Node to write */
|
||||
int fd, /* I - File descriptor to write to */
|
||||
const char *(*cb)(mxml_node_t *node, int ws))
|
||||
/* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||
mxmlSaveFd(mxml_node_t *node, /* I - Node to write */
|
||||
int fd, /* I - File descriptor to write to */
|
||||
mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||
{
|
||||
int col; /* Final column */
|
||||
mxml_fdbuf_t buf; /* File descriptor buffer */
|
||||
_mxml_fdbuf_t buf; /* File descriptor buffer */
|
||||
|
||||
|
||||
/*
|
||||
@ -364,10 +370,9 @@ mxmlSaveFd(mxml_node_t *node, /* I - Node to write */
|
||||
*/
|
||||
|
||||
int /* O - 0 on success, -1 on error. */
|
||||
mxmlSaveFile(mxml_node_t *node, /* I - Node to write */
|
||||
FILE *fp, /* I - File to write to */
|
||||
const char *(*cb)(mxml_node_t *node, int ws))
|
||||
/* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||
mxmlSaveFile(mxml_node_t *node, /* I - Node to write */
|
||||
FILE *fp, /* I - File to write to */
|
||||
mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||
{
|
||||
int col; /* Final column */
|
||||
|
||||
@ -406,11 +411,10 @@ mxmlSaveFile(mxml_node_t *node, /* I - Node to write */
|
||||
*/
|
||||
|
||||
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 */
|
||||
const char *(*cb)(mxml_node_t *node, int ws))
|
||||
/* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||
mxmlSaveString(mxml_node_t *node, /* I - Node to write */
|
||||
char *buffer, /* I - String buffer */
|
||||
int bufsize, /* I - Size of string buffer */
|
||||
mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */
|
||||
{
|
||||
int col; /* Final column */
|
||||
char *ptr[2]; /* Pointers for putc_cb */
|
||||
@ -446,6 +450,130 @@ mxmlSaveString(mxml_node_t *node, /* I - Node to write */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlSAXLoadFd()' - Load a file descriptor into an XML node tree
|
||||
* using a SAX callback.
|
||||
*
|
||||
* The nodes in the specified file are added to the specified top node.
|
||||
* If no top node is provided, the XML file MUST be well-formed with a
|
||||
* single parent node like <?xml> for the entire file. 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.
|
||||
*
|
||||
* The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK,
|
||||
* MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading
|
||||
* child nodes of the specified type.
|
||||
*
|
||||
* The SAX callback must call mxmlRetain() for any nodes that need to
|
||||
* be kept for later use. Otherwise, nodes are deleted when the parent
|
||||
* node is closed or after each data, comment, CDATA, or directive node.
|
||||
*
|
||||
* @since Mini-XML 2.3@
|
||||
*/
|
||||
|
||||
mxml_node_t * /* O - First node or NULL if the file could not be read. */
|
||||
mxmlSAXLoadFd(mxml_node_t *top, /* I - Top node */
|
||||
int fd, /* I - File descriptor to read from */
|
||||
mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */
|
||||
mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */
|
||||
void *sax_data) /* I - SAX user data */
|
||||
{
|
||||
_mxml_fdbuf_t buf; /* File descriptor buffer */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the file descriptor buffer...
|
||||
*/
|
||||
|
||||
buf.fd = fd;
|
||||
buf.current = buf.buffer;
|
||||
buf.end = buf.buffer;
|
||||
|
||||
/*
|
||||
* Read the XML data...
|
||||
*/
|
||||
|
||||
return (mxml_load_data(top, &buf, cb, mxml_fd_getc, sax_cb, sax_data));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlSAXLoadFile()' - Load a file into an XML node tree
|
||||
* using a SAX callback.
|
||||
*
|
||||
* The nodes in the specified file are added to the specified top node.
|
||||
* If no top node is provided, the XML file MUST be well-formed with a
|
||||
* single parent node like <?xml> for the entire file. 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.
|
||||
*
|
||||
* The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK,
|
||||
* MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading
|
||||
* child nodes of the specified type.
|
||||
*
|
||||
* The SAX callback must call mxmlRetain() for any nodes that need to
|
||||
* be kept for later use. Otherwise, nodes are deleted when the parent
|
||||
* node is closed or after each data, comment, CDATA, or directive node.
|
||||
*
|
||||
* @since Mini-XML 2.3@
|
||||
*/
|
||||
|
||||
mxml_node_t * /* O - First node or NULL if the file could not be read. */
|
||||
mxmlSAXLoadFile(
|
||||
mxml_node_t *top, /* I - Top node */
|
||||
FILE *fp, /* I - File to read from */
|
||||
mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */
|
||||
mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */
|
||||
void *sax_data) /* I - SAX user data */
|
||||
{
|
||||
/*
|
||||
* Read the XML data...
|
||||
*/
|
||||
|
||||
return (mxml_load_data(top, fp, cb, mxml_file_getc, sax_cb, sax_data));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlSAXLoadString()' - Load a string into an XML node tree
|
||||
* using a SAX callback.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK,
|
||||
* MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading
|
||||
* child nodes of the specified type.
|
||||
*
|
||||
* The SAX callback must call mxmlRetain() for any nodes that need to
|
||||
* be kept for later use. Otherwise, nodes are deleted when the parent
|
||||
* node is closed or after each data, comment, CDATA, or directive node.
|
||||
*
|
||||
* @since Mini-XML 2.3@
|
||||
*/
|
||||
|
||||
mxml_node_t * /* O - First node or NULL if the string has errors. */
|
||||
mxmlSAXLoadString(
|
||||
mxml_node_t *top, /* I - Top node */
|
||||
const char *s, /* I - String to load */
|
||||
mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */
|
||||
mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */
|
||||
void *sax_data) /* I - SAX user data */
|
||||
{
|
||||
/*
|
||||
* Read the XML data...
|
||||
*/
|
||||
|
||||
return (mxml_load_data(top, &s, cb, mxml_string_getc, sax_cb, sax_data));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlSetCustomHandlers()' - Set the handling functions for custom data.
|
||||
*
|
||||
@ -458,10 +586,9 @@ mxmlSaveString(mxml_node_t *node, /* I - Node to write */
|
||||
*/
|
||||
|
||||
void
|
||||
mxmlSetCustomHandlers(mxml_custom_load_cb_t load,
|
||||
/* I - Load function */
|
||||
mxml_custom_save_cb_t save)
|
||||
/* I - Save function */
|
||||
mxmlSetCustomHandlers(
|
||||
mxml_custom_load_cb_t load, /* I - Load function */
|
||||
mxml_custom_save_cb_t save) /* I - Save function */
|
||||
{
|
||||
mxml_custom_load_cb = load;
|
||||
mxml_custom_save_cb = save;
|
||||
@ -473,8 +600,7 @@ mxmlSetCustomHandlers(mxml_custom_load_cb_t load,
|
||||
*/
|
||||
|
||||
void
|
||||
mxmlSetErrorCallback(void (*cb)(const char *))
|
||||
/* I - Error callback function */
|
||||
mxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */
|
||||
{
|
||||
mxml_error_cb = cb;
|
||||
}
|
||||
@ -586,7 +712,7 @@ static int /* O - Character or EOF */
|
||||
mxml_fd_getc(void *p, /* I - File descriptor buffer */
|
||||
int *encoding) /* IO - Encoding */
|
||||
{
|
||||
mxml_fdbuf_t *buf; /* File descriptor buffer */
|
||||
_mxml_fdbuf_t *buf; /* File descriptor buffer */
|
||||
int ch, /* Current character */
|
||||
temp; /* Temporary character */
|
||||
|
||||
@ -595,7 +721,7 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */
|
||||
* Grab the next character in the buffer...
|
||||
*/
|
||||
|
||||
buf = (mxml_fdbuf_t *)p;
|
||||
buf = (_mxml_fdbuf_t *)p;
|
||||
|
||||
if (buf->current >= buf->end)
|
||||
if (mxml_fd_read(buf) < 0)
|
||||
@ -873,7 +999,7 @@ static int /* O - 0 on success, -1 on error */
|
||||
mxml_fd_putc(int ch, /* I - Character */
|
||||
void *p) /* I - File descriptor buffer */
|
||||
{
|
||||
mxml_fdbuf_t *buf; /* File descriptor buffer */
|
||||
_mxml_fdbuf_t *buf; /* File descriptor buffer */
|
||||
|
||||
|
||||
/*
|
||||
@ -881,7 +1007,7 @@ mxml_fd_putc(int ch, /* I - Character */
|
||||
* 4 characters at the end so that we can avoid a lot of extra tests...
|
||||
*/
|
||||
|
||||
buf = (mxml_fdbuf_t *)p;
|
||||
buf = (_mxml_fdbuf_t *)p;
|
||||
|
||||
if (buf->current >= buf->end)
|
||||
if (mxml_fd_write(buf) < 0)
|
||||
@ -939,7 +1065,7 @@ mxml_fd_putc(int ch, /* I - Character */
|
||||
*/
|
||||
|
||||
static int /* O - 0 on success, -1 on error */
|
||||
mxml_fd_read(mxml_fdbuf_t *buf) /* I - File descriptor buffer */
|
||||
mxml_fd_read(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */
|
||||
{
|
||||
int bytes; /* Bytes read... */
|
||||
|
||||
@ -982,7 +1108,7 @@ mxml_fd_read(mxml_fdbuf_t *buf) /* I - File descriptor buffer */
|
||||
*/
|
||||
|
||||
static int /* O - 0 on success, -1 on error */
|
||||
mxml_fd_write(mxml_fdbuf_t *buf) /* I - File descriptor buffer */
|
||||
mxml_fd_write(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */
|
||||
{
|
||||
int bytes; /* Bytes written */
|
||||
unsigned char *ptr; /* Pointer into buffer */
|
||||
@ -1340,12 +1466,13 @@ mxml_get_entity(mxml_node_t *parent, /* I - Parent node */
|
||||
*/
|
||||
|
||||
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 *, int *))
|
||||
/* I - Read function */
|
||||
mxml_load_data(
|
||||
mxml_node_t *top, /* I - Top node */
|
||||
void *p, /* I - Pointer to data */
|
||||
mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */
|
||||
_mxml_getc_cb_t getc_cb, /* I - Read function */
|
||||
mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */
|
||||
void *sax_data) /* I - SAX user data */
|
||||
{
|
||||
mxml_node_t *node, /* Current node */
|
||||
*first, /* First node added */
|
||||
@ -1470,6 +1597,14 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_DATA, sax_data);
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
if (!first && node)
|
||||
first = node;
|
||||
}
|
||||
@ -1485,6 +1620,14 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
{
|
||||
node = mxmlNewText(parent, whitespace, "");
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_DATA, sax_data);
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
if (!first && node)
|
||||
first = node;
|
||||
|
||||
@ -1571,6 +1714,14 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
break;
|
||||
}
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_COMMENT, sax_data);
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
first = node;
|
||||
}
|
||||
@ -1620,6 +1771,14 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_CDATA, sax_data);
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
first = node;
|
||||
}
|
||||
@ -1651,14 +1810,13 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Otherwise add this as an element under the current parent...
|
||||
*/
|
||||
|
||||
*bufptr = '\0';
|
||||
|
||||
if ((parent = mxmlNewElement(parent, buffer)) == NULL)
|
||||
if ((node = mxmlNewElement(parent, buffer)) == NULL)
|
||||
{
|
||||
/*
|
||||
* Print error and return...
|
||||
@ -1669,11 +1827,24 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
first = parent;
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data);
|
||||
|
||||
if (cb)
|
||||
type = (*cb)(parent);
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
if (node)
|
||||
{
|
||||
parent = node;
|
||||
|
||||
if (!first)
|
||||
first = parent;
|
||||
|
||||
if (cb)
|
||||
type = (*cb)(parent);
|
||||
}
|
||||
}
|
||||
else if (buffer[0] == '!')
|
||||
{
|
||||
@ -1728,17 +1899,28 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
first = node;
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data);
|
||||
|
||||
/*
|
||||
* Descend into this node, setting the value type as needed...
|
||||
*/
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
parent = node;
|
||||
if (node)
|
||||
{
|
||||
/*
|
||||
* Descend into this node, setting the value type as needed...
|
||||
*/
|
||||
|
||||
if (cb)
|
||||
type = (*cb)(parent);
|
||||
if (!first)
|
||||
first = node;
|
||||
|
||||
parent = node;
|
||||
|
||||
if (cb)
|
||||
type = (*cb)(parent);
|
||||
}
|
||||
}
|
||||
else if (buffer[0] == '/')
|
||||
{
|
||||
@ -1764,12 +1946,20 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
while (ch != '>' && ch != EOF)
|
||||
ch = (*getc_cb)(p, &encoding);
|
||||
|
||||
node = parent;
|
||||
parent = parent->parent;
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data);
|
||||
|
||||
mxmlRelease(node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ascend into the parent and set the value type as needed...
|
||||
*/
|
||||
|
||||
parent = parent->parent;
|
||||
|
||||
if (cb && parent)
|
||||
type = (*cb)(parent);
|
||||
}
|
||||
@ -1790,9 +1980,6 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
first = node;
|
||||
|
||||
if (isspace(ch))
|
||||
ch = mxml_parse_element(node, p, &encoding, getc_cb);
|
||||
else if (ch == '/')
|
||||
@ -1808,6 +1995,12 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
ch = '/';
|
||||
}
|
||||
|
||||
if (sax_cb)
|
||||
(*sax_cb)(node, MXML_SAX_ELEMENT_OPEN, sax_data);
|
||||
|
||||
if (!first)
|
||||
first = node;
|
||||
|
||||
if (ch == EOF)
|
||||
break;
|
||||
|
||||
@ -1822,6 +2015,13 @@ mxml_load_data(mxml_node_t *top, /* I - Top node */
|
||||
if (cb && parent)
|
||||
type = (*cb)(parent);
|
||||
}
|
||||
else if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data);
|
||||
|
||||
if (!mxmlRelease(node) && first == node)
|
||||
first = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bufptr = buffer;
|
||||
@ -1899,12 +2099,11 @@ error:
|
||||
*/
|
||||
|
||||
static int /* O - Terminating character */
|
||||
mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
||||
void *p, /* I - Data to read from */
|
||||
int *encoding,
|
||||
/* IO - Encoding */
|
||||
int (*getc_cb)(void *, int *))
|
||||
/* I - Data callback */
|
||||
mxml_parse_element(
|
||||
mxml_node_t *node, /* I - Element node */
|
||||
void *p, /* I - Data to read from */
|
||||
int *encoding, /* IO - Encoding */
|
||||
_mxml_getc_cb_t getc_cb) /* I - Data callback */
|
||||
{
|
||||
int ch, /* Current character in file */
|
||||
quote; /* Quoting character */
|
||||
@ -2551,12 +2750,11 @@ mxml_write_name(const char *s, /* I - Name to write */
|
||||
*/
|
||||
|
||||
static int /* O - Column or -1 on error */
|
||||
mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
void *p, /* I - File to write to */
|
||||
const char *(*cb)(mxml_node_t *, int),
|
||||
/* I - Whitespace callback */
|
||||
int col, /* I - Current column */
|
||||
int (*putc_cb)(int, void *))
|
||||
mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
void *p, /* I - File to write to */
|
||||
mxml_save_cb_t cb, /* I - Whitespace callback */
|
||||
int col, /* I - Current column */
|
||||
_mxml_putc_cb_t putc_cb)/* I - Output callback */
|
||||
{
|
||||
int i, /* Looping var */
|
||||
width; /* Width of attr + value */
|
||||
@ -2832,10 +3030,10 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
*/
|
||||
|
||||
static int /* O - 0 on success, -1 on failure */
|
||||
mxml_write_string(const char *s, /* I - String to write */
|
||||
void *p, /* I - Write pointer */
|
||||
int (*putc_cb)(int, void *))
|
||||
/* I - Write callback */
|
||||
mxml_write_string(
|
||||
const char *s, /* I - String to write */
|
||||
void *p, /* I - Write pointer */
|
||||
_mxml_putc_cb_t putc_cb) /* I - Write callback */
|
||||
{
|
||||
const char *name; /* Entity name, if any */
|
||||
|
||||
@ -2872,14 +3070,12 @@ mxml_write_string(const char *s, /* I - String to write */
|
||||
*/
|
||||
|
||||
static int /* O - New column */
|
||||
mxml_write_ws(mxml_node_t *node, /* I - Current node */
|
||||
void *p, /* I - Write pointer */
|
||||
const char *(*cb)(mxml_node_t *, int),
|
||||
/* I - Callback function */
|
||||
int ws, /* I - Where value */
|
||||
int col, /* I - Current column */
|
||||
int (*putc_cb)(int, void *))
|
||||
/* I - Write callback */
|
||||
mxml_write_ws(mxml_node_t *node, /* I - Current node */
|
||||
void *p, /* I - Write pointer */
|
||||
mxml_save_cb_t cb, /* I - Callback function */
|
||||
int ws, /* I - Where value */
|
||||
int col, /* I - Current column */
|
||||
_mxml_putc_cb_t putc_cb) /* I - Write callback */
|
||||
{
|
||||
const char *s; /* Whitespace string */
|
||||
|
||||
|
@ -331,10 +331,10 @@ mxmlNewCDATA(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */
|
||||
*/
|
||||
|
||||
mxml_node_t * /* O - New node */
|
||||
mxmlNewCustom(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */
|
||||
void *data, /* I - Pointer to data */
|
||||
void (*destroy)(void *))
|
||||
/* I - Function to destroy data */
|
||||
mxmlNewCustom(
|
||||
mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */
|
||||
void *data, /* I - Pointer to data */
|
||||
mxml_custom_destroy_cb_t destroy) /* I - Function to destroy data */
|
||||
{
|
||||
mxml_node_t *node; /* New node */
|
||||
|
||||
|
10
mxml-set.c
10
mxml-set.c
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Node set functions for Mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
* Copyright 2003-2005 by Michael Sweet.
|
||||
* Copyright 2003-2007 by Michael Sweet.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -44,10 +44,10 @@
|
||||
*/
|
||||
|
||||
int /* O - 0 on success, -1 on failure */
|
||||
mxmlSetCustom(mxml_node_t *node, /* I - Node to set */
|
||||
void *data, /* I - New data pointer */
|
||||
void (*destroy)(void *))
|
||||
/* I - New destructor function */
|
||||
mxmlSetCustom(
|
||||
mxml_node_t *node, /* I - Node to set */
|
||||
void *data, /* I - New data pointer */
|
||||
mxml_custom_destroy_cb_t destroy) /* I - New destructor function */
|
||||
{
|
||||
/*
|
||||
* Range check input...
|
||||
|
52
mxml.h
52
mxml.h
@ -71,6 +71,16 @@
|
||||
* Data types...
|
||||
*/
|
||||
|
||||
typedef enum mxml_sax_event_e /**** SAX event type. ****/
|
||||
{
|
||||
MXML_SAX_CDATA, /* CDATA node */
|
||||
MXML_SAX_COMMENT, /* Comment node */
|
||||
MXML_SAX_DATA, /* Data node */
|
||||
MXML_SAX_DIRECTIVE, /* Processing directive node */
|
||||
MXML_SAX_ELEMENT_CLOSE, /* Element closed */
|
||||
MXML_SAX_ELEMENT_OPEN /* Element opened */
|
||||
} mxml_sax_event_t;
|
||||
|
||||
typedef enum mxml_type_e /**** The XML node type. ****/
|
||||
{
|
||||
MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */
|
||||
@ -82,6 +92,12 @@ typedef enum mxml_type_e /**** The XML node type. ****/
|
||||
MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */
|
||||
} mxml_type_t;
|
||||
|
||||
typedef void (*mxml_custom_destroy_cb_t)(void *);
|
||||
/**** Custom data destructor ****/
|
||||
|
||||
typedef void (*mxml_error_cb_t)(const char *);
|
||||
/**** Error callback function ****/
|
||||
|
||||
typedef struct mxml_attr_s /**** An XML element attribute value. ****/
|
||||
{
|
||||
char *name; /* Attribute name */
|
||||
@ -104,8 +120,7 @@ typedef struct mxml_text_s /**** An XML text value. ****/
|
||||
typedef struct mxml_custom_s /**** An XML custom value. @since Mini-XML 2.1@ ****/
|
||||
{
|
||||
void *data; /* Pointer to (allocated) custom data */
|
||||
void (*destroy)(void *);
|
||||
/* Pointer to destructor function */
|
||||
mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */
|
||||
} mxml_custom_t;
|
||||
|
||||
typedef union mxml_value_u /**** An XML node value. ****/
|
||||
@ -146,6 +161,15 @@ typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *);
|
||||
typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *);
|
||||
/**** Custom data save callback function ****/
|
||||
|
||||
typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *);
|
||||
/**** Load callback function ****/
|
||||
|
||||
typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int);
|
||||
/**** Save callback function ****/
|
||||
|
||||
typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *);
|
||||
/**** SAX callback function ****/
|
||||
|
||||
|
||||
/*
|
||||
* C++ support...
|
||||
@ -194,7 +218,7 @@ extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s,
|
||||
mxml_type_t (*cb)(mxml_node_t *));
|
||||
extern mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string);
|
||||
extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data,
|
||||
void (*destroy)(void *));
|
||||
mxml_custom_destroy_cb_t destroy);
|
||||
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 *mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
|
||||
@ -212,21 +236,29 @@ extern int mxmlRelease(mxml_node_t *node);
|
||||
extern void mxmlRemove(mxml_node_t *node);
|
||||
extern int mxmlRetain(mxml_node_t *node);
|
||||
extern char *mxmlSaveAllocString(mxml_node_t *node,
|
||||
const char *(*cb)(mxml_node_t *, int));
|
||||
mxml_save_cb_t cb);
|
||||
extern int mxmlSaveFd(mxml_node_t *node, int fd,
|
||||
const char *(*cb)(mxml_node_t *, int));
|
||||
mxml_save_cb_t cb);
|
||||
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp,
|
||||
const char *(*cb)(mxml_node_t *, int));
|
||||
mxml_save_cb_t cb);
|
||||
extern int mxmlSaveString(mxml_node_t *node, char *buffer,
|
||||
int bufsize,
|
||||
const char *(*cb)(mxml_node_t *, int));
|
||||
int bufsize, mxml_save_cb_t cb);
|
||||
extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd,
|
||||
mxml_type_t (*cb)(mxml_node_t *),
|
||||
mxml_sax_cb_t sax, void *sax_data);
|
||||
extern mxml_node_t *mxmlSAXLoadFile(mxml_node_t *top, FILE *fp,
|
||||
mxml_type_t (*cb)(mxml_node_t *),
|
||||
mxml_sax_cb_t sax, void *sax_data);
|
||||
extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s,
|
||||
mxml_type_t (*cb)(mxml_node_t *),
|
||||
mxml_sax_cb_t sax, void *sax_data);
|
||||
extern int mxmlSetCDATA(mxml_node_t *node, const char *data);
|
||||
extern int mxmlSetCustom(mxml_node_t *node, void *data,
|
||||
void (*destroy)(void *));
|
||||
mxml_custom_destroy_cb_t destroy);
|
||||
extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load,
|
||||
mxml_custom_save_cb_t save);
|
||||
extern int mxmlSetElement(mxml_node_t *node, const char *name);
|
||||
extern void mxmlSetErrorCallback(void (*cb)(const char *));
|
||||
extern void mxmlSetErrorCallback(mxml_error_cb_t cb);
|
||||
extern int mxmlSetInteger(mxml_node_t *node, int integer);
|
||||
extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque);
|
||||
extern int mxmlSetReal(mxml_node_t *node, double real);
|
||||
|
246
mxml.xml
246
mxml.xml
@ -82,7 +82,9 @@ not an element.</description>
|
||||
If the named attribute already exists, the value of the attribute
|
||||
is replaced by the new formatted string. The formatted string value is
|
||||
copied into the element node. This function does nothing if the node
|
||||
is not an element.</description>
|
||||
is not an element.
|
||||
|
||||
@since Mini-XML 2.3@</description>
|
||||
<argument name="node" direction="I">
|
||||
<type>mxml_node_t *</type>
|
||||
<description>Element node</description>
|
||||
@ -285,6 +287,10 @@ child nodes of the specified type.</description>
|
||||
<type>int</type>
|
||||
<description>File descriptor to read from</description>
|
||||
</argument>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_load_cb_t</type>
|
||||
<description>Callback function or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlLoadFile">
|
||||
<returnvalue>
|
||||
@ -311,6 +317,10 @@ child nodes of the specified type.</description>
|
||||
<type>FILE *</type>
|
||||
<description>File to read from</description>
|
||||
</argument>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_load_cb_t</type>
|
||||
<description>Callback function or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlLoadString">
|
||||
<returnvalue>
|
||||
@ -337,6 +347,10 @@ child nodes of the specified type.</description>
|
||||
<type>const char *</type>
|
||||
<description>String to load</description>
|
||||
</argument>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_load_cb_t</type>
|
||||
<description>Callback function or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlNewCDATA">
|
||||
<returnvalue>
|
||||
@ -381,6 +395,10 @@ node is not dynamically allocated or is separately managed.
|
||||
<type>void *</type>
|
||||
<description>Pointer to data</description>
|
||||
</argument>
|
||||
<argument name="destroy" direction="I">
|
||||
<type>mxml_custom_destroy_cb_t</type>
|
||||
<description>Function to destroy data</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlNewElement">
|
||||
<returnvalue>
|
||||
@ -567,6 +585,141 @@ This function does nothing if the node has no parent.</description>
|
||||
<description>Node</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSAXLoadFd">
|
||||
<returnvalue>
|
||||
<type>mxml_node_t *</type>
|
||||
<description>First node or NULL if the file could not be read.</description>
|
||||
</returnvalue>
|
||||
<description>Load a file descriptor into an XML node tree
|
||||
using a SAX callback.
|
||||
|
||||
The nodes in the specified file are added to the specified top node.
|
||||
If no top node is provided, the XML file MUST be well-formed with a
|
||||
single parent node like <?xml> for the entire file. 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.
|
||||
|
||||
The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK,
|
||||
MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading
|
||||
child nodes of the specified type.
|
||||
|
||||
The SAX callback must call mxmlRetain() for any nodes that need to
|
||||
be kept for later use. Otherwise, nodes are deleted when the parent
|
||||
node is closed or after each data, comment, CDATA, or directive node.
|
||||
|
||||
@since Mini-XML 2.3@</description>
|
||||
<argument name="top" direction="I">
|
||||
<type>mxml_node_t *</type>
|
||||
<description>Top node</description>
|
||||
</argument>
|
||||
<argument name="fd" direction="I">
|
||||
<type>int</type>
|
||||
<description>File descriptor to read from</description>
|
||||
</argument>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_load_cb_t</type>
|
||||
<description>Callback function or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
<argument name="sax_cb" direction="I">
|
||||
<type>mxml_sax_cb_t</type>
|
||||
<description>SAX callback or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
<argument name="sax_data" direction="I">
|
||||
<type>void *</type>
|
||||
<description>SAX user data</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSAXLoadFile">
|
||||
<returnvalue>
|
||||
<type>mxml_node_t *</type>
|
||||
<description>First node or NULL if the file could not be read.</description>
|
||||
</returnvalue>
|
||||
<description>Load a file into an XML node tree
|
||||
using a SAX callback.
|
||||
|
||||
The nodes in the specified file are added to the specified top node.
|
||||
If no top node is provided, the XML file MUST be well-formed with a
|
||||
single parent node like <?xml> for the entire file. 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.
|
||||
|
||||
The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK,
|
||||
MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading
|
||||
child nodes of the specified type.
|
||||
|
||||
The SAX callback must call mxmlRetain() for any nodes that need to
|
||||
be kept for later use. Otherwise, nodes are deleted when the parent
|
||||
node is closed or after each data, comment, CDATA, or directive node.
|
||||
|
||||
@since Mini-XML 2.3@</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_load_cb_t</type>
|
||||
<description>Callback function or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
<argument name="sax_cb" direction="I">
|
||||
<type>mxml_sax_cb_t</type>
|
||||
<description>SAX callback or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
<argument name="sax_data" direction="I">
|
||||
<type>void *</type>
|
||||
<description>SAX user data</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSAXLoadString">
|
||||
<returnvalue>
|
||||
<type>mxml_node_t *</type>
|
||||
<description>First node or NULL if the string has errors.</description>
|
||||
</returnvalue>
|
||||
<description>Load a string into an XML node tree
|
||||
using a SAX callback.
|
||||
|
||||
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.
|
||||
|
||||
The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK,
|
||||
MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading
|
||||
child nodes of the specified type.
|
||||
|
||||
The SAX callback must call mxmlRetain() for any nodes that need to
|
||||
be kept for later use. Otherwise, nodes are deleted when the parent
|
||||
node is closed or after each data, comment, CDATA, or directive node.
|
||||
|
||||
@since Mini-XML 2.3@</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" direction="I">
|
||||
<type>mxml_load_cb_t</type>
|
||||
<description>Callback function or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
<argument name="sax_cb" direction="I">
|
||||
<type>mxml_sax_cb_t</type>
|
||||
<description>SAX callback or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
<argument name="sax_data" direction="I">
|
||||
<type>void *</type>
|
||||
<description>SAX user data</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSaveAllocString">
|
||||
<returnvalue>
|
||||
<type>char *</type>
|
||||
@ -589,6 +742,10 @@ element tags.</description>
|
||||
<type>mxml_node_t *</type>
|
||||
<description>Node to write</description>
|
||||
</argument>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_save_cb_t</type>
|
||||
<description>Whitespace callback or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSaveFd">
|
||||
<returnvalue>
|
||||
@ -610,6 +767,10 @@ element tags.</description>
|
||||
<type>int</type>
|
||||
<description>File descriptor to write to</description>
|
||||
</argument>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_save_cb_t</type>
|
||||
<description>Whitespace callback or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSaveFile">
|
||||
<returnvalue>
|
||||
@ -631,6 +792,10 @@ element tags.</description>
|
||||
<type>FILE *</type>
|
||||
<description>File to write to</description>
|
||||
</argument>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_save_cb_t</type>
|
||||
<description>Whitespace callback or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSaveString">
|
||||
<returnvalue>
|
||||
@ -660,6 +825,10 @@ element tags.</description>
|
||||
<type>int</type>
|
||||
<description>Size of string buffer</description>
|
||||
</argument>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_save_cb_t</type>
|
||||
<description>Whitespace callback or MXML_NO_CALLBACK</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSetCDATA">
|
||||
<returnvalue>
|
||||
@ -698,6 +867,10 @@ The node is not changed if it is not a custom node.
|
||||
<type>void *</type>
|
||||
<description>New data pointer</description>
|
||||
</argument>
|
||||
<argument name="destroy" direction="I">
|
||||
<type>mxml_custom_destroy_cb_t</type>
|
||||
<description>New destructor function</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSetCustomHandlers">
|
||||
<description>Set the handling functions for custom data.
|
||||
@ -735,6 +908,10 @@ The node is not changed if it is not an element node.</description>
|
||||
</function>
|
||||
<function name="mxmlSetErrorCallback">
|
||||
<description>Set the error message callback.</description>
|
||||
<argument name="cb" direction="I">
|
||||
<type>mxml_error_cb_t</type>
|
||||
<description>Error callback function</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlSetInteger">
|
||||
<returnvalue>
|
||||
@ -904,6 +1081,10 @@ the walk to the node's children.</description>
|
||||
<type>struct mxml_attr_s</type>
|
||||
<description>Data types...</description>
|
||||
</typedef>
|
||||
<typedef name="mxml_custom_destroy_cb_t">
|
||||
<type>void(*)(void *)</type>
|
||||
<description>Custom data destructor</description>
|
||||
</typedef>
|
||||
<typedef name="mxml_custom_load_cb_t">
|
||||
<type>int(*)(mxml_node_t *, const char *)</type>
|
||||
<description>Custom data load callback function</description>
|
||||
@ -914,12 +1095,14 @@ the walk to the node's children.</description>
|
||||
<type>void *</type>
|
||||
<description>Pointer to (allocated) custom data</description>
|
||||
</variable>
|
||||
<variable name="destroy">
|
||||
<type>mxml_custom_destroy_cb_t</type>
|
||||
<description>Pointer to destructor function</description>
|
||||
</variable>
|
||||
</struct>
|
||||
<typedef name="mxml_custom_save_cb_t">
|
||||
<type>char *(*)(mxml_node_t *)</type>
|
||||
<description>Custom data save callback function</description>
|
||||
<description>C++ support...</description>
|
||||
<description>End of "$Id$".</description>
|
||||
</typedef>
|
||||
<typedef name="mxml_custom_t">
|
||||
<type>struct mxml_custom_s</type>
|
||||
@ -944,20 +1127,10 @@ the walk to the node's children.</description>
|
||||
<type>struct mxml_element_s</type>
|
||||
<description>An XML element value.</description>
|
||||
</typedef>
|
||||
<struct name="mxml_fdbuf_s">
|
||||
<description>File descriptor buffer (@private@)</description>
|
||||
<variable name="buffer[8192]">
|
||||
<type>unsigned char *current, *end,</type>
|
||||
<description>Character buffer</description>
|
||||
</variable>
|
||||
<variable name="fd">
|
||||
<type>int</type>
|
||||
<description>File descriptor</description>
|
||||
</variable>
|
||||
</struct>
|
||||
<typedef name="mxml_fdbuf_t">
|
||||
<type>struct mxml_fdbuf_s</type>
|
||||
<description>File descriptor buffer (@private@)</description>
|
||||
<typedef name="mxml_error_cb_t">
|
||||
<type>void(*)(const char *)</type>
|
||||
<description>Error callback function</description>
|
||||
<description>An XML element attribute value.</description>
|
||||
</typedef>
|
||||
<struct name="mxml_index_s">
|
||||
<description>An XML node index.</description>
|
||||
@ -986,6 +1159,10 @@ the walk to the node's children.</description>
|
||||
<type>struct mxml_index_s</type>
|
||||
<description>An XML node index.</description>
|
||||
</typedef>
|
||||
<typedef name="mxml_load_cb_t">
|
||||
<type>mxml_type_t(*)(mxml_node_t *)</type>
|
||||
<description>Load callback function</description>
|
||||
</typedef>
|
||||
<struct name="mxml_node_s">
|
||||
<description>An XML node.</description>
|
||||
<variable name="child">
|
||||
@ -1029,6 +1206,41 @@ the walk to the node's children.</description>
|
||||
<type>struct mxml_node_s</type>
|
||||
<description>An XML node.</description>
|
||||
</typedef>
|
||||
<typedef name="mxml_save_cb_t">
|
||||
<type>const char *(*)(mxml_node_t *, int)</type>
|
||||
<description>Save callback function</description>
|
||||
</typedef>
|
||||
<typedef name="mxml_sax_cb_t">
|
||||
<type>void(*)(mxml_node_t *, mxml_sax_event_t, void *)</type>
|
||||
<description>SAX callback function</description>
|
||||
<description>C++ support...</description>
|
||||
<description>End of "$Id$".</description>
|
||||
</typedef>
|
||||
<enumeration name="mxml_sax_event_e">
|
||||
<description>SAX event type.</description>
|
||||
<constant name="MXML_SAX_CDATA">
|
||||
<description>CDATA node</description>
|
||||
</constant>
|
||||
<constant name="MXML_SAX_COMMENT">
|
||||
<description>Comment node</description>
|
||||
</constant>
|
||||
<constant name="MXML_SAX_DATA">
|
||||
<description>Data node</description>
|
||||
</constant>
|
||||
<constant name="MXML_SAX_DIRECTIVE">
|
||||
<description>Processing directive node</description>
|
||||
</constant>
|
||||
<constant name="MXML_SAX_ELEMENT_CLOSE">
|
||||
<description>Element closed</description>
|
||||
</constant>
|
||||
<constant name="MXML_SAX_ELEMENT_OPEN">
|
||||
<description>Element opened</description>
|
||||
</constant>
|
||||
</enumeration>
|
||||
<typedef name="mxml_sax_event_t">
|
||||
<type>enum mxml_sax_event_e</type>
|
||||
<description>SAX event type.</description>
|
||||
</typedef>
|
||||
<struct name="mxml_text_s">
|
||||
<description>An XML text value.</description>
|
||||
<variable name="string">
|
||||
|
97
testmxml.c
97
testmxml.c
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Test program for Mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
* Copyright 2003-2005 by Michael Sweet.
|
||||
* Copyright 2003-2007 by Michael Sweet.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -18,6 +18,7 @@
|
||||
* Contents:
|
||||
*
|
||||
* main() - Main entry for test program.
|
||||
* sax_cb() - SAX callback.
|
||||
* type_cb() - XML data type callback for mxmlLoadFile()...
|
||||
* whitespace_cb() - Let the mxmlSaveFile() function know when to insert
|
||||
* newlines and tabs...
|
||||
@ -40,10 +41,18 @@
|
||||
#endif /* !O_BINARY */
|
||||
|
||||
|
||||
/*
|
||||
* Globals...
|
||||
*/
|
||||
|
||||
int event_counts[6];
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
void sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *data);
|
||||
mxml_type_t type_cb(mxml_node_t *node);
|
||||
const char *whitespace_cb(mxml_node_t *node, int where);
|
||||
|
||||
@ -523,6 +532,75 @@ main(int argc, /* I - Number of command-line args */
|
||||
mxmlDelete(tree);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test SAX methods...
|
||||
*/
|
||||
|
||||
memset(event_counts, 0, sizeof(event_counts));
|
||||
|
||||
if (argv[1][0] == '<')
|
||||
tree = mxmlSAXLoadString(NULL, argv[1], type_cb, sax_cb, NULL);
|
||||
else if ((fp = fopen(argv[1], "rb")) == NULL)
|
||||
{
|
||||
perror(argv[1]);
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Read the file...
|
||||
*/
|
||||
|
||||
tree = mxmlSAXLoadFile(NULL, fp, type_cb, sax_cb, NULL);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "test.xml"))
|
||||
{
|
||||
if (event_counts[MXML_SAX_CDATA] != 1)
|
||||
{
|
||||
fprintf(stderr, "MXML_SAX_CDATA seen %d times, expected 1 times!\n",
|
||||
event_counts[MXML_SAX_CDATA]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (event_counts[MXML_SAX_COMMENT] != 1)
|
||||
{
|
||||
fprintf(stderr, "MXML_SAX_COMMENT seen %d times, expected 1 times!\n",
|
||||
event_counts[MXML_SAX_COMMENT]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (event_counts[MXML_SAX_DATA] != 61)
|
||||
{
|
||||
fprintf(stderr, "MXML_SAX_DATA seen %d times, expected 61 times!\n",
|
||||
event_counts[MXML_SAX_DATA]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (event_counts[MXML_SAX_DIRECTIVE] != 1)
|
||||
{
|
||||
fprintf(stderr, "MXML_SAX_DIRECTIVE seen %d times, expected 1 times!\n",
|
||||
event_counts[MXML_SAX_DIRECTIVE]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (event_counts[MXML_SAX_ELEMENT_CLOSE] != 20)
|
||||
{
|
||||
fprintf(stderr, "MXML_SAX_ELEMENT_CLOSE seen %d times, expected 20 times!\n",
|
||||
event_counts[MXML_SAX_ELEMENT_CLOSE]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (event_counts[MXML_SAX_ELEMENT_OPEN] != 20)
|
||||
{
|
||||
fprintf(stderr, "MXML_SAX_ELEMENT_OPEN seen %d times, expected 20 times!\n",
|
||||
event_counts[MXML_SAX_ELEMENT_OPEN]);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return...
|
||||
*/
|
||||
@ -531,6 +609,23 @@ main(int argc, /* I - Number of command-line args */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'sax_cb()' - Process nodes via SAX.
|
||||
*/
|
||||
|
||||
void
|
||||
sax_cb(mxml_node_t *node, /* I - Current node */
|
||||
mxml_sax_event_t event, /* I - SAX event */
|
||||
void *data) /* I - SAX user data */
|
||||
{
|
||||
/*
|
||||
* This SAX callback just counts the different events.
|
||||
*/
|
||||
|
||||
event_counts[event] ++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'type_cb()' - XML data type callback for mxmlLoadFile()...
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user