Normalize MXML_DESCEND_ values.

Normalize MXML_ADD_ values.

Drop MXML_ADD_TO_PARENT.

Move MXML_TAB to mxml-private.h
This commit is contained in:
Michael R Sweet 2024-03-06 20:03:48 -05:00
parent 77d609e8e8
commit 2c62878254
No known key found for this signature in database
GPG Key ID: BE67C75EC81F3244
12 changed files with 197 additions and 115 deletions

View File

@ -769,24 +769,24 @@ wildcards, e.g.:
```c
/* Find the first "a" element */
node = mxmlFindElement(tree, tree, "a", NULL, NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
/* Find the first "a" element with "href" attribute */
node = mxmlFindElement(tree, tree, "a", "href", NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
/* Find the first "a" element with "href" to a URL */
node = mxmlFindElement(tree, tree, "a", "href",
"http://michaelrsweet.github.io/",
MXML_DESCEND);
MXML_DESCEND_ALL);
/* Find the first element with a "src" attribute*/
node = mxmlFindElement(tree, tree, NULL, "src", NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
/* Find the first element with a "src" = "foo.jpg" */
node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg",
MXML_DESCEND);
MXML_DESCEND_ALL);
```
You can also iterate with the same function:
@ -795,29 +795,29 @@ You can also iterate with the same function:
mxml_node_t *node;
for (node = mxmlFindElement(tree, tree, "element", NULL,
NULL, MXML_DESCEND);
NULL, MXML_DESCEND_ALL);
node != NULL;
node = mxmlFindElement(node, tree, "element", NULL,
NULL, MXML_DESCEND))
NULL, MXML_DESCEND_ALL))
{
... do something ...
}
```
The `descend` argument \(`MXML_DESCEND` in the examples above) can be one of
The `descend` argument \(`MXML_DESCEND_ALL` in the examples above) can be one of
three constants:
- `MXML_NO_DESCEND`: ignore child nodes in the element hierarchy, instead using
siblings (same level) or parent nodes (above) until the top (root) node is
reached.
- `MXML_DESCEND_NONE`: ignore child nodes in the element hierarchy, instead
using siblings (same level) or parent nodes (above) until the top (root) node
is reached.
- `MXML_DESCEND_FIRST`: start the search with the first child of the node, and
then search siblings. 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 previous example.
- `MXML_DESCEND`: search child nodes first, then sibling nodes, and then parent
nodes.
- `MXML_DESCEND_ALL`: search child nodes first, then sibling nodes, and then
parent nodes.
Iterating Nodes
@ -848,7 +848,7 @@ mxml_node_t *node;
for (node = xml;
node != NULL;
node = mxmlWalkNext(node, xml, MXML_DESCEND))
node = mxmlWalkNext(node, xml, MXML_DESCEND_ALL))
{
... do something ...
}
@ -1246,13 +1246,13 @@ doc = mxmlLoadFd(/*top*/NULL, /*fd*/0,
sax_cb, /*sax_cbdata*/NULL);
title = mxmlFindElement(doc, doc, "title", NULL, NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
if (title)
print_children(title);
body = mxmlFindElement(doc, doc, "body", NULL, NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
if (body)
{
@ -1300,6 +1300,8 @@ The following incompatible API changes were made in Mini-XML v4.0:
- The `mxmlSAXLoadXxx` functions have been removed in favor of passing the SAX
callback function and data pointers to the `mxmlLoadXxx` functions.
- Node types are now named `MXML_TYPE_foo` instead of `MXML_foo`.
- Descend values are now normalized to `MXML_DESCEND_ALL`, `MXML_DESCEND_FIRST`,
and `MXML_DESCEND_NONE`.
- Functions that returned `0` on success and `-1` on error now return `true` on
success and `false` on error.
- CDATA nodes ("`<![CDATA[...]]>`") now have their own type (`MXML_TYPE_CDATA`).

View File

@ -175,6 +175,30 @@ is used for a particular node or the entire tree:
mxmlDelete(tree);
.fi
.SH ENUMERATIONS
.SS mxml_add_e
\fImxmlAdd\fR add values
.TP 5
MXML_ADD_AFTER
.br
Add node after specified node
.TP 5
MXML_ADD_BEFORE
.br
Add node before specified node
.SS mxml_descend_e
\fImxmlFindElement\fR, \fImxmlWalkNext\fR, and \fImxmlWalkPrev\fR descend values
.TP 5
MXML_DESCEND_ALL
.br
Descend when finding/walking
.TP 5
MXML_DESCEND_FIRST
.br
Descend for first find
.TP 5
MXML_DESCEND_NONE
.br
Don't descend when finding/walking
.SS mxml_sax_event_e
SAX event type.
.TP 5
@ -284,7 +308,7 @@ Add a node to a tree.
.nf
void mxmlAdd (
mxml_node_t *parent,
int where,
mxml_add_t add,
mxml_node_t *child,
mxml_node_t *node
);
@ -292,10 +316,9 @@ void mxmlAdd (
.PP
Adds the specified node to the parent. If the child argument is not
\fBNULL\fR, puts the new node before or after the specified child depending
on the value of the where argument. If the child argument is \fBNULL\fR,
on the value of the \fBadd\fR argument. If the child argument is \fBNULL\fR,
puts the new node at the beginning of the child list (\fBMXML_ADD_BEFORE\fR)
or at the end of the child list (\fBMXML_ADD_AFTER\fR). The constant
\fBMXML_ADD_TO_PARENT\fR can be used to specify a \fBNULL\fR child pointer.
or at the end of the child list (\fBMXML_ADD_AFTER\fR).
.SS mxmlDelete
Delete a node and all of its children.
.PP
@ -385,7 +408,8 @@ Add a callback to convert entities to Unicode.
.PP
.nf
bool mxmlEntityAddCallback (
mxml_entity_cb_t cb
mxml_entity_cb_t cb,
void *cbdata
);
.fi
.SS mxmlEntityGetValue
@ -417,7 +441,7 @@ mxml_node_t * mxmlFindElement (
const char *element,
const char *attr,
const char *value,
int descend
mxml_descend_t descend
);
.fi
.PP
@ -1291,13 +1315,14 @@ bool mxmlSetCustom (
.fi
.PP
The node is not changed if it (or its first child) is not a custom node.
.SS mxmlSetCustomHandlers
.SS mxmlSetCustomCallbacks
Set the handling functions for custom data.
.PP
.nf
void mxmlSetCustomHandlers (
mxml_custom_load_cb_t load,
mxml_custom_save_cb_t save
void mxmlSetCustomCallbacks (
mxml_custom_load_cb_t load_cb,
mxml_custom_save_cb_t save_cb,
void *cbdata
);
.fi
.PP
@ -1360,7 +1385,8 @@ Set the error message callback.
.PP
.nf
void mxmlSetErrorCallback (
mxml_error_cb_t cb
mxml_error_cb_t cb,
void *cbdata
);
.fi
.SS mxmlSetInteger
@ -1459,7 +1485,7 @@ Walk to the next logical node in the tree.
mxml_node_t * mxmlWalkNext (
mxml_node_t *node,
mxml_node_t *top,
int descend
mxml_descend_t descend
);
.fi
.PP
@ -1473,7 +1499,7 @@ Walk to the previous logical node in the tree.
mxml_node_t * mxmlWalkPrev (
mxml_node_t *node,
mxml_node_t *top,
int descend
mxml_descend_t descend
);
.fi
.PP
@ -1481,6 +1507,12 @@ The descend argument controls whether the previous node's last child
is considered to be the previous node. The top node argument constrains
the walk to the node's children.
.SH TYPES
.SS mxml_add_t
\fImxmlAdd\fR add values
.PP
.nf
typedef enum mxml_add_e mxml_add_t;
.fi
.SS mxml_custom_destroy_cb_t
Custom data destructor
.PP
@ -1491,25 +1523,31 @@ typedef void(*)(void *) mxml_custom_destroy_cb_t;
Custom data load callback function
.PP
.nf
typedef bool(*)(mxml_node_t *node const char *s) mxml_custom_load_cb_t;
typedef bool(*)(void *cbdata mxml_node_t *node const char *s) mxml_custom_load_cb_t;
.fi
.SS mxml_custom_save_cb_t
Custom data save callback function
.PP
.nf
typedef char *(*)(mxml_node_t *node) mxml_custom_save_cb_t;
typedef char *(*)(void *cbdata mxml_node_t *node) mxml_custom_save_cb_t;
.fi
.SS mxml_descend_t
\fImxmlFindElement\fR, \fImxmlWalkNext\fR, and \fImxmlWalkPrev\fR descend values
.PP
.nf
typedef enum mxml_descend_e mxml_descend_t;
.fi
.SS mxml_entity_cb_t
Entity callback function
.PP
.nf
typedef int(*)(const char *name) mxml_entity_cb_t;
typedef int(*)(void *cbdata const char *name) mxml_entity_cb_t;
.fi
.SS mxml_error_cb_t
Error callback function
.PP
.nf
typedef void(*)(const char *) mxml_error_cb_t;
typedef void(*)(void *cbdata const char *message) mxml_error_cb_t;
.fi
.SS mxml_index_t
An XML node index.

Binary file not shown.

View File

@ -356,7 +356,7 @@ span.string {
<li><a href="#mxmlSetComment">mxmlSetComment</a></li>
<li><a href="#mxmlSetCommentf">mxmlSetCommentf</a></li>
<li><a href="#mxmlSetCustom">mxmlSetCustom</a></li>
<li><a href="#mxmlSetCustomHandlers">mxmlSetCustomHandlers</a></li>
<li><a href="#mxmlSetCustomCallbacks">mxmlSetCustomCallbacks</a></li>
<li><a href="#mxmlSetDeclaration">mxmlSetDeclaration</a></li>
<li><a href="#mxmlSetDeclarationf">mxmlSetDeclarationf</a></li>
<li><a href="#mxmlSetDirective">mxmlSetDirective</a></li>
@ -375,9 +375,11 @@ span.string {
<li><a href="#mxmlWalkPrev">mxmlWalkPrev</a></li>
</ul></li>
<li><a href="#TYPES">Data Types</a><ul class="subcontents">
<li><a href="#mxml_add_t">mxml_add_t</a></li>
<li><a href="#mxml_custom_destroy_cb_t">mxml_custom_destroy_cb_t</a></li>
<li><a href="#mxml_custom_load_cb_t">mxml_custom_load_cb_t</a></li>
<li><a href="#mxml_custom_save_cb_t">mxml_custom_save_cb_t</a></li>
<li><a href="#mxml_descend_t">mxml_descend_t</a></li>
<li><a href="#mxml_entity_cb_t">mxml_entity_cb_t</a></li>
<li><a href="#mxml_error_cb_t">mxml_error_cb_t</a></li>
<li><a href="#mxml_index_t">mxml_index_t</a></li>
@ -392,6 +394,8 @@ span.string {
<li><a href="#mxml_ws_t">mxml_ws_t</a></li>
</ul></li>
<li><a href="#ENUMERATIONS">Enumerations</a><ul class="subcontents">
<li><a href="#mxml_add_e">mxml_add_e</a></li>
<li><a href="#mxml_descend_e">mxml_descend_e</a></li>
<li><a href="#mxml_sax_event_e">mxml_sax_event_e</a></li>
<li><a href="#mxml_type_e">mxml_type_e</a></li>
<li><a href="#mxml_ws_e">mxml_ws_e</a></li>
@ -869,44 +873,44 @@ mxmlFindElement(mxml_node_t *node, mxml_node_t *top,
<p>The &quot;element&quot;, &quot;attr&quot;, and &quot;value&quot; arguments can be passed as <code>NULL</code> to act as wildcards, e.g.:</p>
<pre><code class="language-c"><span class="comment">/* Find the first &quot;a&quot; element */</span>
node = mxmlFindElement(tree, tree, <span class="string">&quot;a&quot;</span>, NULL, NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
<span class="comment">/* Find the first &quot;a&quot; element with &quot;href&quot; attribute */</span>
node = mxmlFindElement(tree, tree, <span class="string">&quot;a&quot;</span>, <span class="string">&quot;href&quot;</span>, NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
<span class="comment">/* Find the first &quot;a&quot; element with &quot;href&quot; to a URL */</span>
node = mxmlFindElement(tree, tree, <span class="string">&quot;a&quot;</span>, <span class="string">&quot;href&quot;</span>,
<span class="string">&quot;http://michaelrsweet.github.io/&quot;</span>,
MXML_DESCEND);
MXML_DESCEND_ALL);
<span class="comment">/* Find the first element with a &quot;src&quot; attribute*/</span>
node = mxmlFindElement(tree, tree, NULL, <span class="string">&quot;src&quot;</span>, NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
<span class="comment">/* Find the first element with a &quot;src&quot; = &quot;foo.jpg&quot; */</span>
node = mxmlFindElement(tree, tree, NULL, <span class="string">&quot;src&quot;</span>, <span class="string">&quot;foo.jpg&quot;</span>,
MXML_DESCEND);
MXML_DESCEND_ALL);
</code></pre>
<p>You can also iterate with the same function:</p>
<pre><code class="language-c">mxml_node_t *node;
<span class="reserved">for</span> (node = mxmlFindElement(tree, tree, <span class="string">&quot;element&quot;</span>, NULL,
NULL, MXML_DESCEND);
NULL, MXML_DESCEND_ALL);
node != NULL;
node = mxmlFindElement(node, tree, <span class="string">&quot;element&quot;</span>, NULL,
NULL, MXML_DESCEND))
NULL, MXML_DESCEND_ALL))
{
... <span class="reserved">do</span> something ...
}
</code></pre>
<p>The <code>descend</code> argument (<code>MXML_DESCEND</code> in the examples above) can be one of three constants:</p>
<p>The <code>descend</code> argument (<code>MXML_DESCEND_ALL</code> in the examples above) can be one of three constants:</p>
<ul>
<li><p><code>MXML_NO_DESCEND</code>: ignore child nodes in the element hierarchy, instead using siblings (same level) or parent nodes (above) until the top (root) node is reached.</p>
<li><p><code>MXML_DESCEND_NONE</code>: ignore child nodes in the element hierarchy, instead using siblings (same level) or parent nodes (above) until the top (root) node is reached.</p>
</li>
<li><p><code>MXML_DESCEND_FIRST</code>: start the search with the first child of the node, and then search siblings. You'll normally use this when iterating through direct children of a parent node, e.g. all of the &quot;node&quot; and &quot;group&quot; elements under the &quot;?xml&quot; parent node in the previous example.</p>
</li>
<li><p><code>MXML_DESCEND</code>: search child nodes first, then sibling nodes, and then parent nodes.</p>
<li><p><code>MXML_DESCEND_ALL</code>: search child nodes first, then sibling nodes, and then parent nodes.</p>
</li>
</ul>
<h3 class="title" id="iterating-nodes">Iterating Nodes</h3>
@ -924,7 +928,7 @@ mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
<span class="reserved">for</span> (node = xml;
node != NULL;
node = mxmlWalkNext(node, xml, MXML_DESCEND))
node = mxmlWalkNext(node, xml, MXML_DESCEND_ALL))
{
... <span class="reserved">do</span> something ...
}
@ -1219,13 +1223,13 @@ doc = mxmlLoadFd(<span class="comment">/*top*/</span>NULL, <span class="comment"
sax_cb, <span class="comment">/*sax_cbdata*/</span>NULL);
title = mxmlFindElement(doc, doc, <span class="string">&quot;title&quot;</span>, NULL, NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
<span class="reserved">if</span> (title)
print_children(title);
body = mxmlFindElement(doc, doc, <span class="string">&quot;body&quot;</span>, NULL, NULL,
MXML_DESCEND);
MXML_DESCEND_ALL);
<span class="reserved">if</span> (body)
{
@ -1269,6 +1273,8 @@ print_children(mxml_node_t *parent)
</li>
<li><p>Node types are now named <code>MXML_TYPE_foo</code> instead of <code>MXML_foo</code>.</p>
</li>
<li><p>Descend values are now normalized to <code>MXML_DESCEND_ALL</code>, <code>MXML_DESCEND_FIRST</code>, and <code>MXML_DESCEND_NONE</code>.</p>
</li>
<li><p>Functions that returned <code>0</code> on success and <code>-1</code> on error now return <code>true</code> on success and <code>false</code> on error.</p>
</li>
<li><p>CDATA nodes (&quot;<code>&lt;![CDATA[...]]&gt;</code>&quot;) now have their own type (<code>MXML_TYPE_CDATA</code>).</p>
@ -1288,12 +1294,12 @@ print_children(mxml_node_t *parent)
<h3 class="function"><a id="mxmlAdd">mxmlAdd</a></h3>
<p class="description">Add a node to a tree.</p>
<p class="code">
void mxmlAdd(<a href="#mxml_node_t">mxml_node_t</a> *parent, int where, <a href="#mxml_node_t">mxml_node_t</a> *child, <a href="#mxml_node_t">mxml_node_t</a> *node);</p>
void mxmlAdd(<a href="#mxml_node_t">mxml_node_t</a> *parent, <a href="#mxml_add_t">mxml_add_t</a> add, <a href="#mxml_node_t">mxml_node_t</a> *child, <a href="#mxml_node_t">mxml_node_t</a> *node);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>parent</th>
<td class="description">Parent node</td></tr>
<tr><th>where</th>
<tr><th>add</th>
<td class="description">Where to add, <code>MXML_ADD_BEFORE</code> or <code>MXML_ADD_AFTER</code></td></tr>
<tr><th>child</th>
<td class="description">Child node for where or <code>MXML_ADD_TO_PARENT</code></td></tr>
@ -1303,10 +1309,9 @@ void mxmlAdd(<a href="#mxml_node_t">mxml_node_t</a> *parent, int where, <a href=
<h4 class="discussion">Discussion</h4>
<p class="discussion">Adds the specified node to the parent. If the child argument is not
<code>NULL</code>, puts the new node before or after the specified child depending
on the value of the where argument. If the child argument is <code>NULL</code>,
on the value of the <code>add</code> argument. If the child argument is <code>NULL</code>,
puts the new node at the beginning of the child list (<code>MXML_ADD_BEFORE</code>)
or at the end of the child list (<code>MXML_ADD_AFTER</code>). The constant
<code>MXML_ADD_TO_PARENT</code> can be used to specify a <code>NULL</code> child pointer.</p>
or at the end of the child list (<code>MXML_ADD_AFTER</code>).</p>
<h3 class="function"><a id="mxmlDelete">mxmlDelete</a></h3>
<p class="description">Delete a node and all of its children.</p>
<p class="code">
@ -1416,11 +1421,13 @@ is not an element.</p>
<h3 class="function"><a id="mxmlEntityAddCallback">mxmlEntityAddCallback</a></h3>
<p class="description">Add a callback to convert entities to Unicode.</p>
<p class="code">
bool mxmlEntityAddCallback(<a href="#mxml_entity_cb_t">mxml_entity_cb_t</a> cb);</p>
bool mxmlEntityAddCallback(<a href="#mxml_entity_cb_t">mxml_entity_cb_t</a> cb, void *cbdata);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>cb</th>
<td class="description">Callback function to add</td></tr>
<tr><th>cbdata</th>
<td class="description">Callback data</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
@ -1450,7 +1457,7 @@ void mxmlEntityRemoveCallback(<a href="#mxml_entity_cb_t">mxml_entity_cb_t</a> c
<h3 class="function"><a id="mxmlFindElement">mxmlFindElement</a></h3>
<p class="description">Find the named element.</p>
<p class="code">
<a href="#mxml_node_t">mxml_node_t</a> *mxmlFindElement(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, const char *element, const char *attr, const char *value, int descend);</p>
<a href="#mxml_node_t">mxml_node_t</a> *mxmlFindElement(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, const char *element, const char *attr, const char *value, <a href="#mxml_descend_t">mxml_descend_t</a> descend);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>node</th>
@ -1464,7 +1471,7 @@ void mxmlEntityRemoveCallback(<a href="#mxml_entity_cb_t">mxml_entity_cb_t</a> c
<tr><th>value</th>
<td class="description">Attribute value, or <code>NULL</code> for any</td></tr>
<tr><th>descend</th>
<td class="description">Descend into tree - <code>MXML_DESCEND</code>, <code>MXML_NO_DESCEND</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
<td class="description">Descend into tree - <code>MXML_DESCEND_ALL</code>, <code>MXML_DESCEND_NONE</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Element node or <code>NULL</code></p>
@ -2593,16 +2600,18 @@ bool mxmlSetCustom(<a href="#mxml_node_t">mxml_node_t</a> *node, void *data, <a
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">The node is not changed if it (or its first child) is not a custom node.</p>
<h3 class="function"><a id="mxmlSetCustomHandlers">mxmlSetCustomHandlers</a></h3>
<h3 class="function"><a id="mxmlSetCustomCallbacks">mxmlSetCustomCallbacks</a></h3>
<p class="description">Set the handling functions for custom data.</p>
<p class="code">
void mxmlSetCustomHandlers(<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);</p>
void mxmlSetCustomCallbacks(<a href="#mxml_custom_load_cb_t">mxml_custom_load_cb_t</a> load_cb, <a href="#mxml_custom_save_cb_t">mxml_custom_save_cb_t</a> save_cb, void *cbdata);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>load</th>
<td class="description">Load function</td></tr>
<tr><th>save</th>
<td class="description">Save function</td></tr>
<tr><th>load_cb</th>
<td class="description">Load callback function</td></tr>
<tr><th>save_cb</th>
<td class="description">Save callback function</td></tr>
<tr><th>cbdata</th>
<td class="description">Callback data</td></tr>
</tbody></table>
<h4 class="discussion">Discussion</h4>
<p class="discussion">The load function accepts a node pointer and a data string and must
@ -2684,11 +2693,13 @@ bool mxmlSetElement(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *na
<h3 class="function"><a id="mxmlSetErrorCallback">mxmlSetErrorCallback</a></h3>
<p class="description">Set the error message callback.</p>
<p class="code">
void mxmlSetErrorCallback(<a href="#mxml_error_cb_t">mxml_error_cb_t</a> cb);</p>
void mxmlSetErrorCallback(<a href="#mxml_error_cb_t">mxml_error_cb_t</a> cb, void *cbdata);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>cb</th>
<td class="description">Error callback function</td></tr>
<tr><th>cbdata</th>
<td class="description">Error callback data</td></tr>
</tbody></table>
<h3 class="function"><a id="mxmlSetInteger">mxmlSetInteger</a></h3>
<p class="description">Set the value of an integer node.</p>
@ -2815,7 +2826,7 @@ void mxmlSetWrapMargin(int column);</p>
<h3 class="function"><a id="mxmlWalkNext">mxmlWalkNext</a></h3>
<p class="description">Walk to the next logical node in the tree.</p>
<p class="code">
<a href="#mxml_node_t">mxml_node_t</a> *mxmlWalkNext(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, int descend);</p>
<a href="#mxml_node_t">mxml_node_t</a> *mxmlWalkNext(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, <a href="#mxml_descend_t">mxml_descend_t</a> descend);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>node</th>
@ -2823,7 +2834,7 @@ void mxmlSetWrapMargin(int column);</p>
<tr><th>top</th>
<td class="description">Top node</td></tr>
<tr><th>descend</th>
<td class="description">Descend into tree - <code>MXML_DESCEND</code>, <code>MXML_NO_DESCEND</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
<td class="description">Descend into tree - <code>MXML_DESCEND_ALL</code>, <code>MXML_DESCEND_NONE</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Next node or <code>NULL</code></p>
@ -2834,7 +2845,7 @@ the node's children.</p>
<h3 class="function"><a id="mxmlWalkPrev">mxmlWalkPrev</a></h3>
<p class="description">Walk to the previous logical node in the tree.</p>
<p class="code">
<a href="#mxml_node_t">mxml_node_t</a> *mxmlWalkPrev(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, int descend);</p>
<a href="#mxml_node_t">mxml_node_t</a> *mxmlWalkPrev(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, <a href="#mxml_descend_t">mxml_descend_t</a> descend);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>node</th>
@ -2842,7 +2853,7 @@ the node's children.</p>
<tr><th>top</th>
<td class="description">Top node</td></tr>
<tr><th>descend</th>
<td class="description">Descend into tree - <code>MXML_DESCEND</code>, <code>MXML_NO_DESCEND</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
<td class="description">Descend into tree - <code>MXML_DESCEND_ALL</code>, <code>MXML_DESCEND_NONE</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Previous node or <code>NULL</code></p>
@ -2851,6 +2862,11 @@ the node's children.</p>
is considered to be the previous node. The top node argument constrains
the walk to the node's children.</p>
<h2 class="title"><a id="TYPES">Data Types</a></h2>
<h3 class="typedef"><a id="mxml_add_t">mxml_add_t</a></h3>
<p class="description"><a href="#mxmlAdd"><code>mxmlAdd</code></a> add values</p>
<p class="code">
typedef enum <a href="#mxml_add_e">mxml_add_e</a> mxml_add_t;
</p>
<h3 class="typedef"><a id="mxml_custom_destroy_cb_t">mxml_custom_destroy_cb_t</a></h3>
<p class="description">Custom data destructor</p>
<p class="code">
@ -2859,22 +2875,27 @@ typedef void (*mxml_custom_destroy_cb_t)(void *);
<h3 class="typedef"><a id="mxml_custom_load_cb_t">mxml_custom_load_cb_t</a></h3>
<p class="description">Custom data load callback function</p>
<p class="code">
typedef bool (*mxml_custom_load_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *node const char *s);
typedef bool (*mxml_custom_load_cb_t)(void *cbdata <a href="#mxml_node_t">mxml_node_t</a> *node const char *s);
</p>
<h3 class="typedef"><a id="mxml_custom_save_cb_t">mxml_custom_save_cb_t</a></h3>
<p class="description">Custom data save callback function</p>
<p class="code">
typedef char *(*mxml_custom_save_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *node);
typedef char *(*mxml_custom_save_cb_t)(void *cbdata <a href="#mxml_node_t">mxml_node_t</a> *node);
</p>
<h3 class="typedef"><a id="mxml_descend_t">mxml_descend_t</a></h3>
<p class="description"><a href="#mxmlFindElement"><code>mxmlFindElement</code></a>, <a href="#mxmlWalkNext"><code>mxmlWalkNext</code></a>, and <a href="#mxmlWalkPrev"><code>mxmlWalkPrev</code></a> descend values</p>
<p class="code">
typedef enum <a href="#mxml_descend_e">mxml_descend_e</a> mxml_descend_t;
</p>
<h3 class="typedef"><a id="mxml_entity_cb_t">mxml_entity_cb_t</a></h3>
<p class="description">Entity callback function</p>
<p class="code">
typedef int (*mxml_entity_cb_t)(const char *name);
typedef int (*mxml_entity_cb_t)(void *cbdata const char *name);
</p>
<h3 class="typedef"><a id="mxml_error_cb_t">mxml_error_cb_t</a></h3>
<p class="description">Error callback function</p>
<p class="code">
typedef void (*mxml_error_cb_t)(const char *);
typedef void (*mxml_error_cb_t)(void *cbdata const char *message);
</p>
<h3 class="typedef"><a id="mxml_index_t">mxml_index_t</a></h3>
<p class="description">An XML node index.</p>
@ -2927,6 +2948,21 @@ typedef ssize_t (*mxml_write_cb_t)(void *cbdata const void *buffer size_t bytes)
typedef enum <a href="#mxml_ws_e">mxml_ws_e</a> mxml_ws_t;
</p>
<h2 class="title"><a id="ENUMERATIONS">Constants</a></h2>
<h3 class="enumeration"><a id="mxml_add_e">mxml_add_e</a></h3>
<p class="description"><a href="#mxmlAdd"><code>mxmlAdd</code></a> add values</p>
<h4 class="constants">Constants</h4>
<table class="list"><tbody>
<tr><th>MXML_ADD_AFTER </th><td class="description">Add node after specified node</td></tr>
<tr><th>MXML_ADD_BEFORE </th><td class="description">Add node before specified node</td></tr>
</tbody></table>
<h3 class="enumeration"><a id="mxml_descend_e">mxml_descend_e</a></h3>
<p class="description"><a href="#mxmlFindElement"><code>mxmlFindElement</code></a>, <a href="#mxmlWalkNext"><code>mxmlWalkNext</code></a>, and <a href="#mxmlWalkPrev"><code>mxmlWalkPrev</code></a> descend values</p>
<h4 class="constants">Constants</h4>
<table class="list"><tbody>
<tr><th>MXML_DESCEND_ALL </th><td class="description">Descend when finding/walking</td></tr>
<tr><th>MXML_DESCEND_FIRST </th><td class="description">Descend for first find</td></tr>
<tr><th>MXML_DESCEND_NONE </th><td class="description">Don't descend when finding/walking</td></tr>
</tbody></table>
<h3 class="enumeration"><a id="mxml_sax_event_e">mxml_sax_event_e</a></h3>
<p class="description">SAX event type.</p>
<h4 class="constants">Constants</h4>

View File

@ -402,6 +402,8 @@ _mxml_entity_cb(void *cbdata, // I - Callback data (unused)
};
(void)cbdata;
// Do a linear search for the named entity...
for (i = 0; i < (sizeof(entities) / sizeof(entities[0])); i ++)
{

View File

@ -1932,15 +1932,16 @@ mxml_strtod(_mxml_global_t *global, // I - Global data
// Copy leading sign, numbers, period, and then numbers...
tempptr = temp;
temp[sizeof(temp) - 1] = '\0';
bufptr = buffer;
if (*bufptr == '-' || *bufptr == '+')
*tempptr++ = *bufptr++;
for (bufptr = buffer; *bufptr && isdigit(*bufptr & 255); bufptr ++)
while (*bufptr && isdigit(*bufptr & 255))
{
if (tempptr < (temp + sizeof(temp) - 1))
{
*tempptr++ = *bufptr;
*tempptr++ = *bufptr++;
}
else
{

View File

@ -239,7 +239,7 @@ mxmlIndexNew(mxml_node_t *node, // I - XML node tree
if (!element && !attr)
current = node;
else
current = mxmlFindElement(node, node, element, attr, NULL, MXML_DESCEND);
current = mxmlFindElement(node, node, element, attr, NULL, MXML_DESCEND_ALL);
while (current)
{
@ -259,7 +259,7 @@ mxmlIndexNew(mxml_node_t *node, // I - XML node tree
ind->nodes[ind->num_nodes ++] = current;
current = mxmlFindElement(current, node, element, attr, NULL, MXML_DESCEND);
current = mxmlFindElement(current, node, element, attr, NULL, MXML_DESCEND_ALL);
}
// Sort nodes based upon the search criteria...

View File

@ -25,19 +25,18 @@ static mxml_node_t *mxml_new(mxml_node_t *parent, mxml_type_t type);
//
// Adds the specified node to the parent. If the child argument is not
// `NULL`, puts the new node before or after the specified child depending
// on the value of the where argument. If the child argument is `NULL`,
// on the value of the `add` argument. If the child argument is `NULL`,
// puts the new node at the beginning of the child list (`MXML_ADD_BEFORE`)
// or at the end of the child list (`MXML_ADD_AFTER`). The constant
// `MXML_ADD_TO_PARENT` can be used to specify a `NULL` child pointer.
// or at the end of the child list (`MXML_ADD_AFTER`).
//
void
mxmlAdd(mxml_node_t *parent, // I - Parent node
int where, // I - Where to add, `MXML_ADD_BEFORE` or `MXML_ADD_AFTER`
mxml_add_t add, // I - Where to add, `MXML_ADD_BEFORE` or `MXML_ADD_AFTER`
mxml_node_t *child, // I - Child node for where or `MXML_ADD_TO_PARENT`
mxml_node_t *node) // I - Node to add
{
MXML_DEBUG("mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent, where, child, node);
MXML_DEBUG("mxmlAdd(parent=%p, add=%d, child=%p, node=%p)\n", parent, add, child, node);
// Range check input...
if (!parent || !node)
@ -50,7 +49,7 @@ mxmlAdd(mxml_node_t *parent, // I - Parent node
// Reset pointers...
node->parent = parent;
switch (where)
switch (add)
{
case MXML_ADD_BEFORE :
if (!child || child == parent->child || child->parent != parent)
@ -933,7 +932,7 @@ mxml_new(mxml_node_t *parent, // I - Parent node
// Add to the parent if present...
if (parent)
mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
mxmlAdd(parent, MXML_ADD_AFTER, /*child*/NULL, node);
// Return the new node...
return (node);

View File

@ -25,6 +25,7 @@
# else
# define MXML_DEBUG(...)
# endif // DEBUG
# define MXML_TAB 8 // Tabs every N columns
//

View File

@ -26,12 +26,12 @@
//
mxml_node_t * // O - Element node or `NULL`
mxmlFindElement(mxml_node_t *node, // I - Current node
mxml_node_t *top, // I - Top node
const char *element, // I - Element name or `NULL` for any
const char *attr, // I - Attribute name, or `NULL` for none
const char *value, // I - Attribute value, or `NULL` for any
int descend) // I - Descend into tree - `MXML_DESCEND`, `MXML_NO_DESCEND`, or `MXML_DESCEND_FIRST`
mxmlFindElement(mxml_node_t *node, // I - Current node
mxml_node_t *top, // I - Top node
const char *element,// I - Element name or `NULL` for any
const char *attr, // I - Attribute name, or `NULL` for none
const char *value, // I - Attribute value, or `NULL` for any
mxml_descend_t descend) // I - Descend into tree - `MXML_DESCEND_ALL`, `MXML_DESCEND_NONE`, or `MXML_DESCEND_FIRST`
{
const char *temp; // Current attribute value
@ -63,8 +63,8 @@ mxmlFindElement(mxml_node_t *node, // I - Current node
}
// No match, move on to the next node...
if (descend == MXML_DESCEND)
node = mxmlWalkNext(node, top, MXML_DESCEND);
if (descend == MXML_DESCEND_ALL)
node = mxmlWalkNext(node, top, MXML_DESCEND_ALL);
else
node = node->next;
}
@ -91,7 +91,7 @@ mxmlFindPath(mxml_node_t *top, // I - Top node
mxml_node_t *node; // Current node
char element[256]; // Current element name
const char *pathsep; // Separator in path
int descend; // mxmlFindElement option
mxml_descend_t descend; // mxmlFindElement option
// Range check input...
@ -106,7 +106,7 @@ mxmlFindPath(mxml_node_t *top, // I - Top node
if (!strncmp(path, "*/", 2))
{
path += 2;
descend = MXML_DESCEND;
descend = MXML_DESCEND_ALL;
}
else
{
@ -150,15 +150,15 @@ mxmlFindPath(mxml_node_t *top, // I - Top node
//
mxml_node_t * // O - Next node or `NULL`
mxmlWalkNext(mxml_node_t *node, // I - Current node
mxml_node_t *top, // I - Top node
int descend) // I - Descend into tree - `MXML_DESCEND`, `MXML_NO_DESCEND`, or `MXML_DESCEND_FIRST`
mxmlWalkNext(mxml_node_t *node, // I - Current node
mxml_node_t *top, // I - Top node
mxml_descend_t descend) // I - Descend into tree - `MXML_DESCEND_ALL`, `MXML_DESCEND_NONE`, or `MXML_DESCEND_FIRST`
{
if (!node)
{
return (NULL);
}
else if (node->child && descend)
else if (node->child && descend != MXML_DESCEND_NONE)
{
return (node->child);
}
@ -200,9 +200,9 @@ mxmlWalkNext(mxml_node_t *node, // I - Current node
//
mxml_node_t * // O - Previous node or `NULL`
mxmlWalkPrev(mxml_node_t *node, // I - Current node
mxml_node_t *top, // I - Top node
int descend) // I - Descend into tree - `MXML_DESCEND`, `MXML_NO_DESCEND`, or `MXML_DESCEND_FIRST`
mxmlWalkPrev(mxml_node_t *node, // I - Current node
mxml_node_t *top, // I - Top node
mxml_descend_t descend) // I - Descend into tree - `MXML_DESCEND_ALL`, `MXML_DESCEND_NONE`, or `MXML_DESCEND_FIRST`
{
if (!node || node == top)
{
@ -210,7 +210,7 @@ mxmlWalkPrev(mxml_node_t *node, // I - Current node
}
else if (node->prev)
{
if (node->prev->last_child && descend)
if (node->prev->last_child && descend != MXML_DESCEND_NONE)
{
// Find the last child under the previous node...
node = node->prev->last_child;

31
mxml.h
View File

@ -43,21 +43,24 @@ extern "C" {
# define MXML_FORMAT(a,b)
# endif // __GNUC__
# define MXML_TAB 8 // Tabs every N columns
# define MXML_DESCEND 1 // Descend when finding/walking
# define MXML_NO_DESCEND 0 // Don't descend when finding/walking
# define MXML_DESCEND_FIRST -1 // Descend for first find
# define MXML_ADD_BEFORE 0 // Add node before specified node
# define MXML_ADD_AFTER 1 // Add node after specified node
# define MXML_ADD_TO_PARENT NULL // Add node relative to parent
//
// Data types...
//
typedef enum mxml_add_e // @link mxmlAdd@ add values
{
MXML_ADD_BEFORE, // Add node before specified node
MXML_ADD_AFTER // Add node after specified node
} mxml_add_t;
typedef enum mxml_descend_e // @link mxmlFindElement@, @link mxmlWalkNext@, and @link mxmlWalkPrev@ descend values
{
MXML_DESCEND_FIRST = -1, // Descend for first find
MXML_DESCEND_NONE = 0, // Don't descend when finding/walking
MXML_DESCEND_ALL = 1 // Descend when finding/walking
} mxml_descend_t;
typedef enum mxml_sax_event_e // SAX event type.
{
MXML_SAX_EVENT_CDATA, // CDATA node
@ -132,7 +135,7 @@ typedef bool (*mxml_sax_cb_t)(void *cbdata, mxml_node_t *node, mxml_sax_event_t
// Prototypes...
//
extern void mxmlAdd(mxml_node_t *parent, int where, mxml_node_t *child, mxml_node_t *node);
extern void mxmlAdd(mxml_node_t *parent, mxml_add_t add, mxml_node_t *child, mxml_node_t *node);
extern void mxmlDelete(mxml_node_t *node);
@ -146,7 +149,7 @@ extern bool mxmlEntityAddCallback(mxml_entity_cb_t cb, void *cbdata);
extern int mxmlEntityGetValue(const char *name);
extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb);
extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, const char *element, const char *attr, const char *value, int descend);
extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, const char *element, const char *attr, const char *value, mxml_descend_t descend);
extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path);
extern const char *mxmlGetCDATA(mxml_node_t *node);
@ -230,8 +233,8 @@ extern bool mxmlSetTextf(mxml_node_t *node, bool whitespace, const char *format
extern bool mxmlSetUserData(mxml_node_t *node, void *data);
extern void mxmlSetWrapMargin(int column);
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, int descend);
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, int descend);
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, mxml_descend_t descend);
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, mxml_descend_t descend);
# ifdef __cplusplus

View File

@ -488,14 +488,14 @@ main(int argc, // I - Number of command-line args
if (!strcmp(argv[1], "test.xml"))
{
// Verify that mxmlFindElement() and indirectly mxmlWalkNext() work properly...
if ((node = mxmlFindElement(xml, xml, "choice", NULL, NULL, MXML_DESCEND)) == NULL)
if ((node = mxmlFindElement(xml, xml, "choice", NULL, NULL, MXML_DESCEND_ALL)) == NULL)
{
fputs("Unable to find first <choice> element in XML tree.\n", stderr);
mxmlDelete(tree);
return (1);
}
if (!mxmlFindElement(node, xml, "choice", NULL, NULL, MXML_NO_DESCEND))
if (!mxmlFindElement(node, xml, "choice", NULL, NULL, MXML_DESCEND_NONE))
{
fputs("Unable to find second <choice> element in XML tree.\n", stderr);
mxmlDelete(tree);