Fix XML schema for mxmldoc.

Fix function and enumeration type processing in mxmldoc.

Add function type test file.

Add stub for new XML schema validation program.
This commit is contained in:
Michael R Sweet 2005-09-29 02:20:19 +00:00
parent 539f042f3d
commit 55177569a9
10 changed files with 425 additions and 118 deletions

View File

@ -1,8 +1,10 @@
CHANGES - 09/21/2005
CHANGES - 09/28/2005
--------------------
CHANGES IN Mini-XML 2.2.3
- Fixed function and enumeraion type bugs in mxmldoc.
- Fixed XML schema for mxmldoc.
- The mxmldoc program now supports --title and --intro
options.
- The mxmlLoad*() functions could leak a node on an error

View File

@ -1,3 +1,4 @@
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">

View File

@ -200,15 +200,10 @@ mxmlElementSetAttr(
<h4>Syntax</h4>
<pre>
int
mxmlEntityAddCallback(
int (*cb)(const char *name));
mxmlEntityAddCallback(void);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
<thead><tr><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td><tt>(*cb)(const char *name)</tt></td><td>Callback function to add</td></tr>
</tbody></table></p>
<p>None.</p>
<h4>Returns</h4>
<p>0 on success, -1 on failure</p>
<!-- NEW PAGE -->
@ -262,15 +257,10 @@ mxmlEntityGetValue(
<h4>Syntax</h4>
<pre>
void
mxmlEntityRemoveCallback(
int (*cb)(const char *name));
mxmlEntityRemoveCallback(void);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
<thead><tr><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td><tt>(*cb)(const char *name)</tt></td><td>Callback function to remove</td></tr>
</tbody></table></p>
<p>None.</p>
<h4>Returns</h4>
<p>Nothing.</p>
<!-- NEW PAGE -->
@ -452,8 +442,7 @@ child nodes of the specified type.</p>
<a href='#mxml_node_t'>mxml_node_t</a> *
mxmlLoadFd(
<a href='#mxml_node_t'>mxml_node_t</a> * top,
int fd,
mxml_type_t (*cb)(mxml_node_t *node));
int fd);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -461,7 +450,6 @@ mxmlLoadFd(
<tbody>
<tr><td><tt>top</tt></td><td>Top node</td></tr>
<tr><td><tt>fd</tt></td><td>File descriptor to read from</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node)</tt></td><td>Callback function or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>First node or NULL if the file could not be read.</p>
@ -486,8 +474,7 @@ child nodes of the specified type.</p>
<a href='#mxml_node_t'>mxml_node_t</a> *
mxmlLoadFile(
<a href='#mxml_node_t'>mxml_node_t</a> * top,
FILE * fp,
mxml_type_t (*cb)(mxml_node_t *node));
FILE * fp);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -495,7 +482,6 @@ mxmlLoadFile(
<tbody>
<tr><td><tt>top</tt></td><td>Top node</td></tr>
<tr><td><tt>fp</tt></td><td>File to read from</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node)</tt></td><td>Callback function or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>First node or NULL if the file could not be read.</p>
@ -520,8 +506,7 @@ child nodes of the specified type.</p>
<a href='#mxml_node_t'>mxml_node_t</a> *
mxmlLoadString(
<a href='#mxml_node_t'>mxml_node_t</a> * top,
const char * s,
mxml_type_t (*cb)(mxml_node_t *node));
const char * s);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -529,7 +514,6 @@ mxmlLoadString(
<tbody>
<tr><td><tt>top</tt></td><td>Top node</td></tr>
<tr><td><tt>s</tt></td><td>String to load</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node)</tt></td><td>Callback function or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>First node or NULL if the string has errors.</p>
@ -574,8 +558,7 @@ node is not dynamically allocated or is separately managed.</p>
<a href='#mxml_node_t'>mxml_node_t</a> *
mxmlNewCustom(
<a href='#mxml_node_t'>mxml_node_t</a> * parent,
void * data,
void (*destroy)(void *));
void * data);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -583,7 +566,6 @@ mxmlNewCustom(
<tbody>
<tr><td><tt>parent</tt></td><td>Parent node or MXML_NO_PARENT</td></tr>
<tr><td><tt>data</tt></td><td>Pointer to data</td></tr>
<tr><td><tt>(*destroy)(void *)</tt></td><td>Function to destroy data</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>New node</p>
@ -791,15 +773,13 @@ element tags.</p>
<pre>
char *
mxmlSaveAllocString(
<a href='#mxml_node_t'>mxml_node_t</a> * node,
const char * (*cb)(mxml_node_t *node, int ws));
<a href='#mxml_node_t'>mxml_node_t</a> * node);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
<thead><tr><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td><tt>node</tt></td><td>Node to write</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node, int ws)</tt></td><td>Whitespace callback or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>Allocated string or NULL</p>
@ -819,8 +799,7 @@ element tags.</p>
int
mxmlSaveFd(
<a href='#mxml_node_t'>mxml_node_t</a> * node,
int fd,
const char * (*cb)(mxml_node_t *node, int ws));
int fd);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -828,7 +807,6 @@ mxmlSaveFd(
<tbody>
<tr><td><tt>node</tt></td><td>Node to write</td></tr>
<tr><td><tt>fd</tt></td><td>File descriptor to write to</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node, int ws)</tt></td><td>Whitespace callback or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>0 on success, -1 on error.</p>
@ -848,8 +826,7 @@ element tags.</p>
int
mxmlSaveFile(
<a href='#mxml_node_t'>mxml_node_t</a> * node,
FILE * fp,
const char * (*cb)(mxml_node_t *node, int ws));
FILE * fp);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -857,7 +834,6 @@ mxmlSaveFile(
<tbody>
<tr><td><tt>node</tt></td><td>Node to write</td></tr>
<tr><td><tt>fp</tt></td><td>File to write to</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node, int ws)</tt></td><td>Whitespace callback or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>0 on success, -1 on error.</p>
@ -882,8 +858,7 @@ int
mxmlSaveString(
<a href='#mxml_node_t'>mxml_node_t</a> * node,
char * buffer,
int bufsize,
const char * (*cb)(mxml_node_t *node, int ws));
int bufsize);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -892,7 +867,6 @@ mxmlSaveString(
<tr><td><tt>node</tt></td><td>Node to write</td></tr>
<tr><td><tt>buffer</tt></td><td>String buffer</td></tr>
<tr><td><tt>bufsize</tt></td><td>Size of string buffer</td></tr>
<tr><td><tt>(*cb)(mxml_node_t *node, int ws)</tt></td><td>Whitespace callback or MXML_NO_CALLBACK</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>Size of string</p>
@ -931,8 +905,7 @@ The node is not changed if it is not a custom node.</p>
int
mxmlSetCustom(
<a href='#mxml_node_t'>mxml_node_t</a> * node,
void * data,
void (*destroy)(void *));
void * data);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -940,7 +913,6 @@ mxmlSetCustom(
<tbody>
<tr><td><tt>node</tt></td><td>Node to set</td></tr>
<tr><td><tt>data</tt></td><td>New data pointer</td></tr>
<tr><td><tt>(*destroy)(void *)</tt></td><td>New destructor function</td></tr>
</tbody></table></p>
<h4>Returns</h4>
<p>0 on success, -1 on failure</p>
@ -959,8 +931,8 @@ string on success and NULL on error.</p>
<pre>
void
mxmlSetCustomHandlers(
mxml_custom_load_cb_t load,
mxml_custom_save_cb_t save);
<a href='#mxml_custom_load_cb_t'>mxml_custom_load_cb_t</a> load,
<a href='#mxml_custom_save_cb_t'>mxml_custom_save_cb_t</a> save);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
@ -1002,15 +974,10 @@ mxmlSetElement(
<h4>Syntax</h4>
<pre>
void
mxmlSetErrorCallback(
void (*cb)(const char *));
mxmlSetErrorCallback(void);
</pre>
<h4>Arguments</h4>
<p class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' width='80%'>
<thead><tr><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td><tt>(*cb)(const char *)</tt></td><td>Error callback function</td></tr>
</tbody></table></p>
<p>None.</p>
<h4>Returns</h4>
<p>Nothing.</p>
<!-- NEW PAGE -->
@ -1338,6 +1305,8 @@ struct mxml_value_s
<h2><a name='_types'>Types</a></h2>
<ul>
<li><a href='#mxml_attr_t'><tt>mxml_attr_t</tt></a></li>
<li><a href='#mxml_custom_load_cb_t'><tt>mxml_custom_load_cb_t</tt></a></li>
<li><a href='#mxml_custom_save_cb_t'><tt>mxml_custom_save_cb_t</tt></a></li>
<li><a href='#mxml_custom_t'><tt>mxml_custom_t</tt></a></li>
<li><a href='#mxml_element_t'><tt>mxml_element_t</tt></a></li>
<li><a href='#mxml_index_t'><tt>mxml_index_t</tt></a></li>
@ -1355,6 +1324,24 @@ struct mxml_value_s
typedef struct <a href='#mxml_attr_s'>mxml_attr_s</a> mxml_attr_t;
</pre>
<!-- NEW PAGE -->
<h3><a name='mxml_custom_load_cb_t'>mxml_custom_load_cb_t</a></h3>
<hr noshade/>
<h4>Description</h4>
<p>Custom data load callback function</p>
<h4>Definition</h4>
<pre>
typedef int (*mxml_custom_load_cb_t)(<a href='#mxml_node_t'>mxml_node_t</a> *, const char *);
</pre>
<!-- NEW PAGE -->
<h3><a name='mxml_custom_save_cb_t'>mxml_custom_save_cb_t</a></h3>
<hr noshade/>
<h4>Description</h4>
<p>Custom data save callback function</p>
<h4>Definition</h4>
<pre>
typedef char * (*mxml_custom_save_cb_t)(<a href='#mxml_node_t'>mxml_node_t</a> *);
</pre>
<!-- NEW PAGE -->
<h3><a name='mxml_custom_t'>mxml_custom_t</a></h3>
<hr noshade/>
<h4>Description</h4>

View File

@ -7,6 +7,11 @@
<ul>
<li>Fixed function and enumeraion type bugs in
mxmldoc.</li>
<li>Fixed XML schema for mxmldoc.</li>
<li>The mxmldoc program now supports --title and --intro
options.</li>

45
mvalidate.c Normal file
View File

@ -0,0 +1,45 @@
/*
* "$Id$"
*
* XML Schema validation program 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.
*
* Contents:
*
*/
/*
* Include necessary headers...
*/
#include "config.h"
#include "mxml.h"
/*
* 'main()' - Main entry for schema validation program.
*/
int /* O - Exit status */
main(int argc, /* I - Number of command-line args */
char *argv[]) /* I - Command-line args */
{
return (0);
}
/*
* End of "$Id$".
*/

View File

@ -1,4 +1,7 @@
<?xml version="1.0"?><mxmldoc>
<?xml version="1.0"?><mxmldoc
xmlns="http://www.easysw.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.easysw.com/~mike/mxml/mxmldoc.xsd">
<function name="mxmlAdd">
<description>Add a node to a tree.
@ -79,10 +82,6 @@ not an element.</description>
<description>0 on success, -1 on failure</description>
</returnvalue>
<description>Add a callback to convert entities to Unicode.</description>
<argument name="(*cb)(const char *name)" direction="I">
<type>int</type>
<description>Callback function to add</description>
</argument>
</function>
<function name="mxmlEntityGetName">
<returnvalue>
@ -113,10 +112,6 @@ name is not known.</description>
</function>
<function name="mxmlEntityRemoveCallback">
<description>Remove a callback.</description>
<argument name="(*cb)(const char *name)" direction="I">
<type>int</type>
<description>Callback function to remove</description>
</argument>
</function>
<function name="mxmlFindElement">
<returnvalue>
@ -267,10 +262,6 @@ child nodes of the specified type.</description>
<type>int</type>
<description>File descriptor to read from</description>
</argument>
<argument name="(*cb)(mxml_node_t *node)" direction="I">
<type>mxml_type_t</type>
<description>Callback function or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlLoadFile">
<returnvalue>
@ -297,10 +288,6 @@ child nodes of the specified type.</description>
<type>FILE *</type>
<description>File to read from</description>
</argument>
<argument name="(*cb)(mxml_node_t *node)" direction="I">
<type>mxml_type_t</type>
<description>Callback function or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlLoadString">
<returnvalue>
@ -327,10 +314,6 @@ child nodes of the specified type.</description>
<type>const char *</type>
<description>String to load</description>
</argument>
<argument name="(*cb)(mxml_node_t *node)" direction="I">
<type>mxml_type_t</type>
<description>Callback function or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlNewCDATA">
<returnvalue>
@ -371,10 +354,6 @@ node is not dynamically allocated or is separately managed.</description>
<type>void *</type>
<description>Pointer to data</description>
</argument>
<argument name="(*destroy)(void *)" direction="I">
<type>void</type>
<description>Function to destroy data</description>
</argument>
</function>
<function name="mxmlNewElement">
<returnvalue>
@ -538,10 +517,6 @@ element tags.</description>
<type>mxml_node_t *</type>
<description>Node to write</description>
</argument>
<argument name="(*cb)(mxml_node_t *node, int ws)" direction="I">
<type>const char *</type>
<description>Whitespace callback or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlSaveFd">
<returnvalue>
@ -563,10 +538,6 @@ element tags.</description>
<type>int</type>
<description>File descriptor to write to</description>
</argument>
<argument name="(*cb)(mxml_node_t *node, int ws)" direction="I">
<type>const char *</type>
<description>Whitespace callback or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlSaveFile">
<returnvalue>
@ -588,10 +559,6 @@ element tags.</description>
<type>FILE *</type>
<description>File to write to</description>
</argument>
<argument name="(*cb)(mxml_node_t *node, int ws)" direction="I">
<type>const char *</type>
<description>Whitespace callback or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlSaveString">
<returnvalue>
@ -621,10 +588,6 @@ element tags.</description>
<type>int</type>
<description>Size of string buffer</description>
</argument>
<argument name="(*cb)(mxml_node_t *node, int ws)" direction="I">
<type>const char *</type>
<description>Whitespace callback or MXML_NO_CALLBACK</description>
</argument>
</function>
<function name="mxmlSetCDATA">
<returnvalue>
@ -659,10 +622,6 @@ The node is not changed if it is not a custom node.</description>
<type>void *</type>
<description>New data pointer</description>
</argument>
<argument name="(*destroy)(void *)" direction="I">
<type>void</type>
<description>New destructor function</description>
</argument>
</function>
<function name="mxmlSetCustomHandlers">
<description>Set the handling functions for custom data.
@ -700,10 +659,6 @@ 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)(const char *)" direction="I">
<type>void</type>
<description>Error callback function</description>
</argument>
</function>
<function name="mxmlSetInteger">
<returnvalue>
@ -862,6 +817,10 @@ the walk to the node's children.</description>
<type>struct mxml_attr_s</type>
<description>An XML element attribute value.</description>
</typedef>
<typedef name="mxml_custom_load_cb_t">
<type>int(*)(mxml_node_t *, const char *)</type>
<description>Custom data load callback function</description>
</typedef>
<struct name="mxml_custom_s">
<description>An XML custom value.</description>
<variable name="data">
@ -869,6 +828,12 @@ the walk to the node's children.</description>
<description>Pointer to (allocated) custom data</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 &quot;$Id$&quot;.</description>
</typedef>
<typedef name="mxml_custom_t">
<type>struct mxml_custom_s</type>
<description>An XML custom value.</description>

142
mxmldoc.c
View File

@ -479,18 +479,11 @@ new_documentation(mxml_node_t **mxmldoc)/* O - mxmldoc node */
*mxmldoc = mxmlNewElement(doc, "mxmldoc");
#ifdef MXML_INCLUDE_SCHEMA
/*
* Currently we don't include the schema/namespace stuff with the
* XML output since some validators don't seem to like it...
*/
mxmlElementSetAttr(*mxmldoc, "xmlns", "http://www.easysw.com");
mxmlElementSetAttr(*mxmldoc, "xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
mxmlElementSetAttr(*mxmldoc, "xsi:schemaLocation",
"http://www.easysw.com/~mike/mxml/mxmldoc.xsd");
#endif /* MXML_INCLUDE_SCHEMA */
return (doc);
}
@ -559,7 +552,7 @@ scan_file(const char *filename, /* I - Filename */
#ifdef DEBUG
fprintf(stderr, "scan_file(filename=\"%s\", fp=%p, tree=%p)\n", filename,
fp, tree);
#endif // DEBUG
#endif /* DEBUG */
/*
* Initialize the finite state machine...
@ -929,9 +922,6 @@ scan_file(const char *filename, /* I - Filename */
break;
case ')' :
if (parens > 0)
parens --;
if (type && parens)
{
#ifdef DEBUG
@ -945,6 +935,9 @@ scan_file(const char *filename, /* I - Filename */
variable = add_variable(function, "argument", type);
type = NULL;
}
if (parens > 0)
parens --;
break;
case ';' :
@ -971,6 +964,43 @@ scan_file(const char *filename, /* I - Filename */
if (type)
{
/*
* See if we have a function typedef...
*/
if (type->child &&
!strcmp(type->child->value.text.string, "typedef"))
{
/*
* Yes, add it!
*/
typedefnode = mxmlNewElement(MXML_NO_PARENT, "typedef");
for (node = type->child->next->next; node; node = node->next)
if (strcmp(node->value.text.string, "(") &&
strcmp(node->value.text.string, "*"))
break;
if (node)
{
mxmlElementSetAttr(typedefnode, "name",
node->value.text.string);
sort_node(tree, typedefnode);
mxmlDelete(type->child);
mxmlDelete(node);
if (type->child)
type->child->value.text.whitespace = 0;
mxmlAdd(typedefnode, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
type);
type = NULL;
break;
}
}
mxmlDelete(type);
type = NULL;
}
@ -999,6 +1029,17 @@ scan_file(const char *filename, /* I - Filename */
}
break;
case ',' :
if (type && !enumeration)
{
#ifdef DEBUG
fputs("Identifier: <<<< , >>>\n", stderr);
#endif /* DEBUG */
ch = type->last_child->value.text.string[0];
mxmlNewText(type, 0, ",");
}
break;
case '&' :
if (type)
{
@ -1357,7 +1398,8 @@ scan_file(const char *filename, /* I - Filename */
case STATE_IDENTIFIER : /* Inside a keyword or identifier */
if (isalnum(ch) || ch == '_' || ch == '[' || ch == ']' ||
(ch == ',' && parens > 1) || ch == ':' || ch == '.' || ch == '~')
(ch == ',' && (parens > 1 || (type && !enumeration && !function))) ||
ch == ':' || ch == '.' || ch == '~')
{
if (bufptr < (buffer + sizeof(buffer) - 1))
*bufptr++ = ch;
@ -2572,9 +2614,79 @@ write_documentation(
fputs("<h4>Definition</h4>\n"
"<pre>\n"
"typedef ", stdout);
write_element(doc, mxmlFindElement(scut, scut, "type", NULL,
NULL, MXML_DESCEND_FIRST));
printf(" %s;\n</pre>\n", name);
type = mxmlFindElement(scut, scut, "type", NULL, NULL,
MXML_DESCEND_FIRST);
for (type = type->child; type; type = type->next)
if (!strcmp(type->value.text.string, "("))
break;
else
{
if (type->value.text.whitespace)
putchar(' ');
if (mxmlFindElement(doc, doc, "class", "name",
type->value.text.string, MXML_DESCEND) ||
mxmlFindElement(doc, doc, "enumeration", "name",
type->value.text.string, MXML_DESCEND) ||
mxmlFindElement(doc, doc, "struct", "name",
type->value.text.string, MXML_DESCEND) ||
mxmlFindElement(doc, doc, "typedef", "name",
type->value.text.string, MXML_DESCEND) ||
mxmlFindElement(doc, doc, "union", "name",
type->value.text.string, MXML_DESCEND))
{
printf("<a href='#");
write_string(type->value.text.string);
printf("'>");
write_string(type->value.text.string);
printf("</a>");
}
else
write_string(type->value.text.string);
}
if (type)
{
/*
* Output function type...
*/
printf(" (*%s", name);
for (type = type->next->next; type; type = type->next)
{
if (type->value.text.whitespace)
putchar(' ');
if (mxmlFindElement(doc, doc, "class", "name",
type->value.text.string, MXML_DESCEND) ||
mxmlFindElement(doc, doc, "enumeration", "name",
type->value.text.string, MXML_DESCEND) ||
mxmlFindElement(doc, doc, "struct", "name",
type->value.text.string, MXML_DESCEND) ||
mxmlFindElement(doc, doc, "typedef", "name",
type->value.text.string, MXML_DESCEND) ||
mxmlFindElement(doc, doc, "union", "name",
type->value.text.string, MXML_DESCEND))
{
printf("<a href='#");
write_string(type->value.text.string);
printf("'>");
write_string(type->value.text.string);
printf("</a>");
}
else
write_string(type->value.text.string);
}
puts(";");
}
else
printf(" %s;\n", name);
puts("</pre>");
}
}

View File

@ -7,7 +7,7 @@ else
fi
rm -f test.xml
../mxmldoc test.xml $files >test.html 2>test.log
#valgrind --logfile-fd=3 --leak-check=yes ../mxmldoc test.xml \
# $files >test.html 2>test.log 3>test.valgrind
#../mxmldoc-static test.xml $files >test.html 2>test.log
valgrind --log-fd=3 --leak-check=yes ../mxmldoc-static test.xml \
$files >test.html 2>test.log 3>test.valgrind

1
test/functype.cxx Normal file
View File

@ -0,0 +1 @@
typedef int (*foo_func_t)(void *foo, int bar); /**** Foo function type ****/

189
www/mxmldoc.xsd Normal file
View File

@ -0,0 +1,189 @@
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Mini-XML 2.2 documentation schema for mxmldoc output.
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.
</xsd:documentation>
</xsd:annotation>
<!-- basic element definitions -->
<xsd:element name="argument" type="argumentType"/>
<xsd:element name="class" type="classType"/>
<xsd:element name="constant" type="constantType"/>
<xsd:element name="description" type="xsd:string"/>
<xsd:element name="enumeration" type="enumerationType"/>
<xsd:element name="function" type="functionType"/>
<xsd:element name="mxmldoc" type="mxmldocType"/>
<xsd:element name="namespace" type="namespaceType"/>
<xsd:element name="returnvalue" type="returnvalueType"/>
<xsd:element name="seealso" type="identifierList"/>
<xsd:element name="struct" type="structType"/>
<xsd:element name="typedef" type="typedefType"/>
<xsd:element name="type" type="xsd:string"/>
<xsd:element name="union" type="unionType"/>
<xsd:element name="variable" type="variableType"/>
<!-- descriptions of complex elements -->
<xsd:complexType name="argumentType">
<xsd:sequence>
<xsd:element ref="type" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="default" type="xsd:string" use="optional"/>
<xsd:attribute name="name" type="identifier" use="required"/>
<xsd:attribute name="direction" type="direction" use="optional" default="I"/>
</xsd:complexType>
<xsd:complexType name="classType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="class"/>
<xsd:element ref="enumeration"/>
<xsd:element ref="function"/>
<xsd:element ref="struct"/>
<xsd:element ref="typedef"/>
<xsd:element ref="union"/>
<xsd:element ref="variable"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
<xsd:attribute name="parent" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="constantType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>
<xsd:complexType name="enumerationType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="constant" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>
<xsd:complexType name="functionType">
<xsd:sequence>
<xsd:element ref="returnvalue" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="argument" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element ref="seealso" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
<xsd:attribute name="scope" type="scope" use="optional"/>
</xsd:complexType>
<xsd:complexType name="mxmldocType">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="class"/>
<xsd:element ref="enumeration"/>
<xsd:element ref="function"/>
<xsd:element ref="namespace"/>
<xsd:element ref="struct"/>
<xsd:element ref="typedef"/>
<xsd:element ref="union"/>
<xsd:element ref="variable"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="namespaceType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="class"/>
<xsd:element ref="enumeration"/>
<xsd:element ref="function"/>
<xsd:element ref="struct"/>
<xsd:element ref="typedef"/>
<xsd:element ref="union"/>
<xsd:element ref="variable"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>
<xsd:complexType name="returnvalueType">
<xsd:sequence>
<xsd:element ref="type" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="structType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="variable"/>
<xsd:element ref="function"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>
<xsd:complexType name="typedefType">
<xsd:sequence>
<xsd:element ref="type" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>
<xsd:complexType name="unionType">
<xsd:sequence>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="variable" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>
<xsd:complexType name="variableType">
<xsd:sequence>
<xsd:element ref="type" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="description" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="identifier" use="required"/>
</xsd:complexType>
<!-- data types -->
<xsd:simpleType name="direction">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="I"/>
<xsd:enumeration value="O"/>
<xsd:enumeration value="IO"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="identifier">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[a-zA-Z_(.]([a-zA-Z_(.,)* 0-9])*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="identifierList">
<xsd:list itemType="identifier"/>
</xsd:simpleType>
<xsd:simpleType name="scope">
<xsd:restriction base="xsd:string">
<xsd:enumeration value=""/>
<xsd:enumeration value="private"/>
<xsd:enumeration value="protected"/>
<xsd:enumeration value="public"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>