diff options
85 files changed, 4180 insertions, 2839 deletions
diff --git a/docs/html/annotated.html b/docs/html/annotated.html index 92baeb6..88d563b 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -30,7 +30,7 @@ <tr><td class="indexkey"><a class="el" href="classpugi_1_1xpath__node__set.html">pugi::xpath_node_set</a></td><td class="indexvalue">Not necessarily ordered constant collection of XPath nodes </td></tr> <tr><td class="indexkey"><a class="el" href="classpugi_1_1xpath__query.html">pugi::xpath_query</a></td><td class="indexvalue">A class that holds compiled XPath query and allows to evaluate query result </td></tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__attribute-members.html b/docs/html/classpugi_1_1xml__attribute-members.html index 83c136c..62a2ff9 100644 --- a/docs/html/classpugi_1_1xml__attribute-members.html +++ b/docs/html/classpugi_1_1xml__attribute-members.html @@ -45,7 +45,7 @@ <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__attribute.html#a555fccff52247e39f823d564a31e4d8">xml_attribute</a>()</td><td><a class="el" href="classpugi_1_1xml__attribute.html">pugi::xml_attribute</a></td><td></td></tr> <tr bgcolor="#f0f0f0"><td><b>xml_attribute_iterator</b> (defined in <a class="el" href="classpugi_1_1xml__attribute.html">pugi::xml_attribute</a>)</td><td><a class="el" href="classpugi_1_1xml__attribute.html">pugi::xml_attribute</a></td><td><code> [friend]</code></td></tr> <tr bgcolor="#f0f0f0"><td><b>xml_node</b> (defined in <a class="el" href="classpugi_1_1xml__attribute.html">pugi::xml_attribute</a>)</td><td><a class="el" href="classpugi_1_1xml__attribute.html">pugi::xml_attribute</a></td><td><code> [friend]</code></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__attribute.html b/docs/html/classpugi_1_1xml__attribute.html index 840a4a7..5a64c72 100644 --- a/docs/html/classpugi_1_1xml__attribute.html +++ b/docs/html/classpugi_1_1xml__attribute.html @@ -874,7 +874,7 @@ Get attribute value. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__attribute__coll__graph.png b/docs/html/classpugi_1_1xml__attribute__coll__graph.png Binary files differindex 92a5dc0..d9c013c 100644 --- a/docs/html/classpugi_1_1xml__attribute__coll__graph.png +++ b/docs/html/classpugi_1_1xml__attribute__coll__graph.png diff --git a/docs/html/classpugi_1_1xml__attribute__iterator-members.html b/docs/html/classpugi_1_1xml__attribute__iterator-members.html index 48c5720..0083263 100644 --- a/docs/html/classpugi_1_1xml__attribute__iterator-members.html +++ b/docs/html/classpugi_1_1xml__attribute__iterator-members.html @@ -30,7 +30,7 @@ <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__attribute__iterator.html#4595648e3aa06a3209f200c69805ed47">xml_attribute_iterator</a>(const xml_attribute &node)</td><td><a class="el" href="classpugi_1_1xml__attribute__iterator.html">pugi::xml_attribute_iterator</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__attribute__iterator.html#c99270b894dd2faeab9fc6eb3832dc94">xml_attribute_iterator</a>(xml_attribute_struct *ref, xml_attribute_struct *prev)</td><td><a class="el" href="classpugi_1_1xml__attribute__iterator.html">pugi::xml_attribute_iterator</a></td><td></td></tr> <tr bgcolor="#f0f0f0"><td><b>xml_node</b> (defined in <a class="el" href="classpugi_1_1xml__attribute__iterator.html">pugi::xml_attribute_iterator</a>)</td><td><a class="el" href="classpugi_1_1xml__attribute__iterator.html">pugi::xml_attribute_iterator</a></td><td><code> [friend]</code></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:43 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__attribute__iterator.html b/docs/html/classpugi_1_1xml__attribute__iterator.html index 81b80cb..7a06993 100644 --- a/docs/html/classpugi_1_1xml__attribute__iterator.html +++ b/docs/html/classpugi_1_1xml__attribute__iterator.html @@ -22,7 +22,7 @@ <h1>pugi::xml_attribute_iterator Class Reference</h1><!-- doxytag: class="pugi::xml_attribute_iterator" --><!-- doxytag: inherits="std::iterator" -->Inheritance diagram for pugi::xml_attribute_iterator:<p><center><img src="classpugi_1_1xml__attribute__iterator__inherit__graph.png" border="0" usemap="#pugi_1_1xml__attribute__iterator__inherit__map" alt="Inheritance graph"></center> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center>Collaboration diagram for pugi::xml_attribute_iterator:<p><center><img src="classpugi_1_1xml__attribute__iterator__coll__graph.png" border="0" usemap="#pugi_1_1xml__attribute__iterator__coll__map" alt="Collaboration graph"></center> <map name="pugi_1_1xml__attribute__iterator__coll__map"> -<area href="classpugi_1_1xml__attribute.html" shape="rect" coords="394,98,528,125" alt=""> +<area href="classpugi_1_1xml__attribute.html" shape="rect" coords="392,96,525,123" alt=""> </map> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center><a href="classpugi_1_1xml__attribute__iterator-members.html">List of all members.</a><hr><a name="_details"></a><h2>Detailed Description</h2> Attribute iterator. @@ -407,7 +407,7 @@ Post-decrement operator. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:43 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__attribute__iterator__coll__graph.map b/docs/html/classpugi_1_1xml__attribute__iterator__coll__graph.map index 8ab0214..0b58566 100644 --- a/docs/html/classpugi_1_1xml__attribute__iterator__coll__graph.map +++ b/docs/html/classpugi_1_1xml__attribute__iterator__coll__graph.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xml__attribute.html 394,98 528,125 +rect $classpugi_1_1xml__attribute.html 392,96 525,123 diff --git a/docs/html/classpugi_1_1xml__attribute__iterator__coll__graph.png b/docs/html/classpugi_1_1xml__attribute__iterator__coll__graph.png Binary files differindex d188df2..994b03c 100644 --- a/docs/html/classpugi_1_1xml__attribute__iterator__coll__graph.png +++ b/docs/html/classpugi_1_1xml__attribute__iterator__coll__graph.png diff --git a/docs/html/classpugi_1_1xml__attribute__iterator__inherit__graph.png b/docs/html/classpugi_1_1xml__attribute__iterator__inherit__graph.png Binary files differindex 8b08b13..295de20 100644 --- a/docs/html/classpugi_1_1xml__attribute__iterator__inherit__graph.png +++ b/docs/html/classpugi_1_1xml__attribute__iterator__inherit__graph.png diff --git a/docs/html/classpugi_1_1xml__document-members.html b/docs/html/classpugi_1_1xml__document-members.html index e25d78d..862eac9 100644 --- a/docs/html/classpugi_1_1xml__document-members.html +++ b/docs/html/classpugi_1_1xml__document-members.html @@ -96,7 +96,7 @@ <tr bgcolor="#f0f0f0"><td><b>xml_node</b>(xml_node_struct *p) (defined in <a class="el" href="classpugi_1_1xml__node.html">pugi::xml_node</a>)</td><td><a class="el" href="classpugi_1_1xml__node.html">pugi::xml_node</a></td><td><code> [explicit, protected]</code></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__node.html#1db6c67c97cddd74f59d872057987432">xml_node</a>()</td><td><a class="el" href="classpugi_1_1xml__node.html">pugi::xml_node</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__document.html#16c086e679286271b0ccd4541d1c1290">~xml_document</a>()</td><td><a class="el" href="classpugi_1_1xml__document.html">pugi::xml_document</a></td><td></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__document.html b/docs/html/classpugi_1_1xml__document.html index c3a4bd4..2d3359a 100644 --- a/docs/html/classpugi_1_1xml__document.html +++ b/docs/html/classpugi_1_1xml__document.html @@ -21,11 +21,11 @@ <a class="el" href="namespacepugi.html">pugi</a>::<a class="el" href="classpugi_1_1xml__document.html">xml_document</a></div> <h1>pugi::xml_document Class Reference</h1><!-- doxytag: class="pugi::xml_document" --><!-- doxytag: inherits="pugi::xml_node" -->Inheritance diagram for pugi::xml_document:<p><center><img src="classpugi_1_1xml__document__inherit__graph.png" border="0" usemap="#pugi_1_1xml__document__inherit__map" alt="Inheritance graph"></center> <map name="pugi_1_1xml__document__inherit__map"> -<area href="classpugi_1_1xml__node.html" shape="rect" coords="24,7,136,34" alt=""> +<area href="classpugi_1_1xml__node.html" shape="rect" coords="20,5,132,32" alt=""> </map> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center>Collaboration diagram for pugi::xml_document:<p><center><img src="classpugi_1_1xml__document__coll__graph.png" border="0" usemap="#pugi_1_1xml__document__coll__map" alt="Collaboration graph"></center> <map name="pugi_1_1xml__document__coll__map"> -<area href="classpugi_1_1xml__node.html" shape="rect" coords="17,98,129,125" alt=""> +<area href="classpugi_1_1xml__node.html" shape="rect" coords="15,96,127,123" alt=""> </map> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center><a href="classpugi_1_1xml__document-members.html">List of all members.</a><hr><a name="_details"></a><h2>Detailed Description</h2> Document class (DOM tree root). @@ -358,7 +358,7 @@ Save XML to file. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__document__coll__graph.map b/docs/html/classpugi_1_1xml__document__coll__graph.map index 78dbed9..c3b53a3 100644 --- a/docs/html/classpugi_1_1xml__document__coll__graph.map +++ b/docs/html/classpugi_1_1xml__document__coll__graph.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xml__node.html 17,98 129,125 +rect $classpugi_1_1xml__node.html 15,96 127,123 diff --git a/docs/html/classpugi_1_1xml__document__coll__graph.png b/docs/html/classpugi_1_1xml__document__coll__graph.png Binary files differindex ac5f77f..cbde087 100644 --- a/docs/html/classpugi_1_1xml__document__coll__graph.png +++ b/docs/html/classpugi_1_1xml__document__coll__graph.png diff --git a/docs/html/classpugi_1_1xml__document__inherit__graph.map b/docs/html/classpugi_1_1xml__document__inherit__graph.map index a324f1d..a5959fe 100644 --- a/docs/html/classpugi_1_1xml__document__inherit__graph.map +++ b/docs/html/classpugi_1_1xml__document__inherit__graph.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xml__node.html 24,7 136,34 +rect $classpugi_1_1xml__node.html 20,5 132,32 diff --git a/docs/html/classpugi_1_1xml__document__inherit__graph.png b/docs/html/classpugi_1_1xml__document__inherit__graph.png Binary files differindex 8f89193..e6d4d5f 100644 --- a/docs/html/classpugi_1_1xml__document__inherit__graph.png +++ b/docs/html/classpugi_1_1xml__document__inherit__graph.png diff --git a/docs/html/classpugi_1_1xml__node-members.html b/docs/html/classpugi_1_1xml__node-members.html index 0a4dcee..81874e4 100644 --- a/docs/html/classpugi_1_1xml__node-members.html +++ b/docs/html/classpugi_1_1xml__node-members.html @@ -88,7 +88,7 @@ <tr bgcolor="#f0f0f0"><td><b>xml_node</b>(xml_node_struct *p) (defined in <a class="el" href="classpugi_1_1xml__node.html">pugi::xml_node</a>)</td><td><a class="el" href="classpugi_1_1xml__node.html">pugi::xml_node</a></td><td><code> [explicit, protected]</code></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__node.html#1db6c67c97cddd74f59d872057987432">xml_node</a>()</td><td><a class="el" href="classpugi_1_1xml__node.html">pugi::xml_node</a></td><td></td></tr> <tr bgcolor="#f0f0f0"><td><b>xml_node_iterator</b> (defined in <a class="el" href="classpugi_1_1xml__node.html">pugi::xml_node</a>)</td><td><a class="el" href="classpugi_1_1xml__node.html">pugi::xml_node</a></td><td><code> [friend]</code></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:43 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__node.html b/docs/html/classpugi_1_1xml__node.html index 2be96f3..24f8118 100644 --- a/docs/html/classpugi_1_1xml__node.html +++ b/docs/html/classpugi_1_1xml__node.html @@ -21,7 +21,7 @@ <a class="el" href="namespacepugi.html">pugi</a>::<a class="el" href="classpugi_1_1xml__node.html">xml_node</a></div> <h1>pugi::xml_node Class Reference</h1><!-- doxytag: class="pugi::xml_node" -->Inheritance diagram for pugi::xml_node:<p><center><img src="classpugi_1_1xml__node__inherit__graph.png" border="0" usemap="#pugi_1_1xml__node__inherit__map" alt="Inheritance graph"></center> <map name="pugi_1_1xml__node__inherit__map"> -<area href="classpugi_1_1xml__document.html" shape="rect" coords="8,82,152,109" alt=""> +<area href="classpugi_1_1xml__document.html" shape="rect" coords="5,80,147,107" alt=""> </map> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center>Collaboration diagram for pugi::xml_node:<p><center><img src="classpugi_1_1xml__node__coll__graph.png" border="0" usemap="#pugi_1_1xml__node__coll__map" alt="Collaboration graph"></center> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center><a href="classpugi_1_1xml__node-members.html">List of all members.</a><hr><a name="_details"></a><h2>Detailed Description</h2> @@ -2466,7 +2466,7 @@ Print subtree to stream. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:43 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__node__coll__graph.png b/docs/html/classpugi_1_1xml__node__coll__graph.png Binary files differindex db6620e..220239d 100644 --- a/docs/html/classpugi_1_1xml__node__coll__graph.png +++ b/docs/html/classpugi_1_1xml__node__coll__graph.png diff --git a/docs/html/classpugi_1_1xml__node__inherit__graph.map b/docs/html/classpugi_1_1xml__node__inherit__graph.map index e1b3a3b..822985a 100644 --- a/docs/html/classpugi_1_1xml__node__inherit__graph.map +++ b/docs/html/classpugi_1_1xml__node__inherit__graph.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xml__document.html 8,82 152,109 +rect $classpugi_1_1xml__document.html 5,80 147,107 diff --git a/docs/html/classpugi_1_1xml__node__inherit__graph.png b/docs/html/classpugi_1_1xml__node__inherit__graph.png Binary files differindex d889c51..48e55f2 100644 --- a/docs/html/classpugi_1_1xml__node__inherit__graph.png +++ b/docs/html/classpugi_1_1xml__node__inherit__graph.png diff --git a/docs/html/classpugi_1_1xml__node__iterator-members.html b/docs/html/classpugi_1_1xml__node__iterator-members.html index 0910691..9b6b0e2 100644 --- a/docs/html/classpugi_1_1xml__node__iterator-members.html +++ b/docs/html/classpugi_1_1xml__node__iterator-members.html @@ -30,7 +30,7 @@ <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__node__iterator.html#09538d658aef0ba20cbe050dff1c3a81">xml_node_iterator</a>()</td><td><a class="el" href="classpugi_1_1xml__node__iterator.html">pugi::xml_node_iterator</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__node__iterator.html#874c832b41aaaff159ef2c36cdcb705c">xml_node_iterator</a>(const xml_node &node)</td><td><a class="el" href="classpugi_1_1xml__node__iterator.html">pugi::xml_node_iterator</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__node__iterator.html#b16f30b8b0b96e750792c69e8e1fbeb2">xml_node_iterator</a>(xml_node_struct *ref, xml_node_struct *prev)</td><td><a class="el" href="classpugi_1_1xml__node__iterator.html">pugi::xml_node_iterator</a></td><td></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:43 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__node__iterator.html b/docs/html/classpugi_1_1xml__node__iterator.html index 225c11a..782f3e4 100644 --- a/docs/html/classpugi_1_1xml__node__iterator.html +++ b/docs/html/classpugi_1_1xml__node__iterator.html @@ -22,7 +22,7 @@ <h1>pugi::xml_node_iterator Class Reference</h1><!-- doxytag: class="pugi::xml_node_iterator" --><!-- doxytag: inherits="std::iterator" -->Inheritance diagram for pugi::xml_node_iterator:<p><center><img src="classpugi_1_1xml__node__iterator__inherit__graph.png" border="0" usemap="#pugi_1_1xml__node__iterator__inherit__map" alt="Inheritance graph"></center> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center>Collaboration diagram for pugi::xml_node_iterator:<p><center><img src="classpugi_1_1xml__node__iterator__coll__graph.png" border="0" usemap="#pugi_1_1xml__node__iterator__coll__map" alt="Collaboration graph"></center> <map name="pugi_1_1xml__node__iterator__coll__map"> -<area href="classpugi_1_1xml__node.html" shape="rect" coords="375,98,487,125" alt=""> +<area href="classpugi_1_1xml__node.html" shape="rect" coords="373,96,485,123" alt=""> </map> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center><a href="classpugi_1_1xml__node__iterator-members.html">List of all members.</a><hr><a name="_details"></a><h2>Detailed Description</h2> Child node iterator. @@ -407,7 +407,7 @@ Post-decrement operator. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:43 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__node__iterator__coll__graph.map b/docs/html/classpugi_1_1xml__node__iterator__coll__graph.map index a1778b4..bad08d7 100644 --- a/docs/html/classpugi_1_1xml__node__iterator__coll__graph.map +++ b/docs/html/classpugi_1_1xml__node__iterator__coll__graph.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xml__node.html 375,98 487,125 +rect $classpugi_1_1xml__node.html 373,96 485,123 diff --git a/docs/html/classpugi_1_1xml__node__iterator__coll__graph.png b/docs/html/classpugi_1_1xml__node__iterator__coll__graph.png Binary files differindex 820aee7..d1c7446 100644 --- a/docs/html/classpugi_1_1xml__node__iterator__coll__graph.png +++ b/docs/html/classpugi_1_1xml__node__iterator__coll__graph.png diff --git a/docs/html/classpugi_1_1xml__node__iterator__inherit__graph.png b/docs/html/classpugi_1_1xml__node__iterator__inherit__graph.png Binary files differindex e3f04ba..fe1a5e5 100644 --- a/docs/html/classpugi_1_1xml__node__iterator__inherit__graph.png +++ b/docs/html/classpugi_1_1xml__node__iterator__inherit__graph.png diff --git a/docs/html/classpugi_1_1xml__tree__walker-members.html b/docs/html/classpugi_1_1xml__tree__walker-members.html index 956ef8a..dc0efaf 100644 --- a/docs/html/classpugi_1_1xml__tree__walker-members.html +++ b/docs/html/classpugi_1_1xml__tree__walker-members.html @@ -25,7 +25,7 @@ <tr bgcolor="#f0f0f0"><td><b>xml_node</b> (defined in <a class="el" href="classpugi_1_1xml__tree__walker.html">pugi::xml_tree_walker</a>)</td><td><a class="el" href="classpugi_1_1xml__tree__walker.html">pugi::xml_tree_walker</a></td><td><code> [friend]</code></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__tree__walker.html#93c03157cff8f8a0ead30c2d256d061b">xml_tree_walker</a>()</td><td><a class="el" href="classpugi_1_1xml__tree__walker.html">pugi::xml_tree_walker</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xml__tree__walker.html#aa0d4eb42c6518a2a90bc264588ece84">~xml_tree_walker</a>()</td><td><a class="el" href="classpugi_1_1xml__tree__walker.html">pugi::xml_tree_walker</a></td><td><code> [virtual]</code></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__tree__walker.html b/docs/html/classpugi_1_1xml__tree__walker.html index 2e73c1a..aa39dc6 100644 --- a/docs/html/classpugi_1_1xml__tree__walker.html +++ b/docs/html/classpugi_1_1xml__tree__walker.html @@ -179,7 +179,7 @@ Callback that is called when traversal of node ends. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xml__tree__walker__coll__graph.png b/docs/html/classpugi_1_1xml__tree__walker__coll__graph.png Binary files differindex 39c90dd..c64cced 100644 --- a/docs/html/classpugi_1_1xml__tree__walker__coll__graph.png +++ b/docs/html/classpugi_1_1xml__tree__walker__coll__graph.png diff --git a/docs/html/classpugi_1_1xpath__exception-members.html b/docs/html/classpugi_1_1xpath__exception-members.html index 3fa5c6f..cacdc6a 100644 --- a/docs/html/classpugi_1_1xpath__exception-members.html +++ b/docs/html/classpugi_1_1xpath__exception-members.html @@ -20,7 +20,7 @@ <h1>pugi::xpath_exception Member List</h1>This is the complete list of members for <a class="el" href="classpugi_1_1xpath__exception.html">pugi::xpath_exception</a>, including all inherited members.<p><table> <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__exception.html#436980baf3d09670ecc15a110ed0f654">what</a>() const </td><td><a class="el" href="classpugi_1_1xpath__exception.html">pugi::xpath_exception</a></td><td><code> [virtual]</code></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__exception.html#9236dd8d2e0674417b2cb53760791017">xpath_exception</a>(const char *message)</td><td><a class="el" href="classpugi_1_1xpath__exception.html">pugi::xpath_exception</a></td><td><code> [explicit]</code></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xpath__exception.html b/docs/html/classpugi_1_1xpath__exception.html index 4278767..da5952e 100644 --- a/docs/html/classpugi_1_1xpath__exception.html +++ b/docs/html/classpugi_1_1xpath__exception.html @@ -101,7 +101,7 @@ Return error message. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xpath__exception__coll__graph.png b/docs/html/classpugi_1_1xpath__exception__coll__graph.png Binary files differindex f713014..4224ed7 100644 --- a/docs/html/classpugi_1_1xpath__exception__coll__graph.png +++ b/docs/html/classpugi_1_1xpath__exception__coll__graph.png diff --git a/docs/html/classpugi_1_1xpath__exception__inherit__graph.png b/docs/html/classpugi_1_1xpath__exception__inherit__graph.png Binary files differindex a88837e..86697fa 100644 --- a/docs/html/classpugi_1_1xpath__exception__inherit__graph.png +++ b/docs/html/classpugi_1_1xpath__exception__inherit__graph.png diff --git a/docs/html/classpugi_1_1xpath__node-members.html b/docs/html/classpugi_1_1xpath__node-members.html index f1efe50..ceea3b8 100644 --- a/docs/html/classpugi_1_1xpath__node-members.html +++ b/docs/html/classpugi_1_1xpath__node-members.html @@ -27,7 +27,7 @@ <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__node.html#c744d6466fee3a062ba3bb928331031e">xpath_node</a>()</td><td><a class="el" href="classpugi_1_1xpath__node.html">pugi::xpath_node</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__node.html#c19206fda68c2c67ff2b42009debe74f">xpath_node</a>(const xml_node &node)</td><td><a class="el" href="classpugi_1_1xpath__node.html">pugi::xpath_node</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__node.html#5cc7cfd8ceb6cae4be45b2f29fe57f34">xpath_node</a>(const xml_attribute &attribute, const xml_node &parent)</td><td><a class="el" href="classpugi_1_1xpath__node.html">pugi::xpath_node</a></td><td></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xpath__node.html b/docs/html/classpugi_1_1xpath__node.html index 87b5b59..be67764 100644 --- a/docs/html/classpugi_1_1xpath__node.html +++ b/docs/html/classpugi_1_1xpath__node.html @@ -21,8 +21,8 @@ <a class="el" href="namespacepugi.html">pugi</a>::<a class="el" href="classpugi_1_1xpath__node.html">xpath_node</a></div> <h1>pugi::xpath_node Class Reference</h1><!-- doxytag: class="pugi::xpath_node" -->Collaboration diagram for pugi::xpath_node:<p><center><img src="classpugi_1_1xpath__node__coll__graph.png" border="0" usemap="#pugi_1_1xpath__node__coll__map" alt="Collaboration graph"></center> <map name="pugi_1_1xpath__node__coll__map"> -<area href="classpugi_1_1xml__node.html" shape="rect" coords="22,98,134,125" alt=""> -<area href="classpugi_1_1xml__attribute.html" shape="rect" coords="166,98,300,125" alt=""> +<area href="classpugi_1_1xml__node.html" shape="rect" coords="20,96,132,123" alt=""> +<area href="classpugi_1_1xml__attribute.html" shape="rect" coords="164,96,297,123" alt=""> </map> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center><a href="classpugi_1_1xpath__node-members.html">List of all members.</a><hr><a name="_details"></a><h2>Detailed Description</h2> XPath node class. @@ -334,7 +334,7 @@ Compares two XPath nodes. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xpath__node__coll__graph.map b/docs/html/classpugi_1_1xpath__node__coll__graph.map index dd6359e..0c8dcec 100644 --- a/docs/html/classpugi_1_1xpath__node__coll__graph.map +++ b/docs/html/classpugi_1_1xpath__node__coll__graph.map @@ -1,3 +1,3 @@ base referer -rect $classpugi_1_1xml__node.html 22,98 134,125 -rect $classpugi_1_1xml__attribute.html 166,98 300,125 +rect $classpugi_1_1xml__node.html 20,96 132,123 +rect $classpugi_1_1xml__attribute.html 164,96 297,123 diff --git a/docs/html/classpugi_1_1xpath__node__coll__graph.png b/docs/html/classpugi_1_1xpath__node__coll__graph.png Binary files differindex ba8c62b..03863a0 100644 --- a/docs/html/classpugi_1_1xpath__node__coll__graph.png +++ b/docs/html/classpugi_1_1xpath__node__coll__graph.png diff --git a/docs/html/classpugi_1_1xpath__node__set-members.html b/docs/html/classpugi_1_1xpath__node__set-members.html index 4f9a678..456204d 100644 --- a/docs/html/classpugi_1_1xpath__node__set-members.html +++ b/docs/html/classpugi_1_1xpath__node__set-members.html @@ -35,7 +35,7 @@ <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__node__set.html#3e102821157e43d83f6623996709127d">xpath_node_set</a>()</td><td><a class="el" href="classpugi_1_1xpath__node__set.html">pugi::xpath_node_set</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__node__set.html#59f1f078606bb6c4f1a081bb82bcf901">xpath_node_set</a>(const xpath_node_set &ns)</td><td><a class="el" href="classpugi_1_1xpath__node__set.html">pugi::xpath_node_set</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__node__set.html#6ca44658aa0126e12f9fc3e3f8017376">~xpath_node_set</a>()</td><td><a class="el" href="classpugi_1_1xpath__node__set.html">pugi::xpath_node_set</a></td><td></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xpath__node__set.html b/docs/html/classpugi_1_1xpath__node__set.html index 2773fb6..d18e42b 100644 --- a/docs/html/classpugi_1_1xpath__node__set.html +++ b/docs/html/classpugi_1_1xpath__node__set.html @@ -21,9 +21,9 @@ <a class="el" href="namespacepugi.html">pugi</a>::<a class="el" href="classpugi_1_1xpath__node__set.html">xpath_node_set</a></div> <h1>pugi::xpath_node_set Class Reference</h1><!-- doxytag: class="pugi::xpath_node_set" -->Collaboration diagram for pugi::xpath_node_set:<p><center><img src="classpugi_1_1xpath__node__set__coll__graph.png" border="0" usemap="#pugi_1_1xpath__node__set__coll__map" alt="Collaboration graph"></center> <map name="pugi_1_1xpath__node__set__coll__map"> -<area href="classpugi_1_1xpath__node.html" shape="rect" coords="82,189,207,216" alt=""> -<area href="classpugi_1_1xml__node.html" shape="rect" coords="25,98,137,125" alt=""> -<area href="classpugi_1_1xml__attribute.html" shape="rect" coords="166,98,299,125" alt=""> +<area href="classpugi_1_1xpath__node.html" shape="rect" coords="77,187,203,213" alt=""> +<area href="classpugi_1_1xml__node.html" shape="rect" coords="23,96,135,123" alt=""> +<area href="classpugi_1_1xml__attribute.html" shape="rect" coords="164,96,297,123" alt=""> </map> <center><font size="2">[<a href="graph_legend.html">legend</a>]</font></center><a href="classpugi_1_1xpath__node__set-members.html">List of all members.</a><hr><a name="_details"></a><h2>Detailed Description</h2> Not necessarily ordered constant collection of XPath nodes. @@ -406,7 +406,7 @@ Return true if collection is empty. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xpath__node__set__coll__graph.map b/docs/html/classpugi_1_1xpath__node__set__coll__graph.map index 6f67906..beb06ca 100644 --- a/docs/html/classpugi_1_1xpath__node__set__coll__graph.map +++ b/docs/html/classpugi_1_1xpath__node__set__coll__graph.map @@ -1,4 +1,4 @@ base referer -rect $classpugi_1_1xpath__node.html 82,189 207,216 -rect $classpugi_1_1xml__node.html 25,98 137,125 -rect $classpugi_1_1xml__attribute.html 166,98 299,125 +rect $classpugi_1_1xpath__node.html 77,187 203,213 +rect $classpugi_1_1xml__node.html 23,96 135,123 +rect $classpugi_1_1xml__attribute.html 164,96 297,123 diff --git a/docs/html/classpugi_1_1xpath__node__set__coll__graph.png b/docs/html/classpugi_1_1xpath__node__set__coll__graph.png Binary files differindex 81c6982..1205ca7 100644 --- a/docs/html/classpugi_1_1xpath__node__set__coll__graph.png +++ b/docs/html/classpugi_1_1xpath__node__set__coll__graph.png diff --git a/docs/html/classpugi_1_1xpath__query-members.html b/docs/html/classpugi_1_1xpath__query-members.html index 5edc682..224d544 100644 --- a/docs/html/classpugi_1_1xpath__query-members.html +++ b/docs/html/classpugi_1_1xpath__query-members.html @@ -24,7 +24,7 @@ <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__query.html#0327ba2d1a1dddac08f18d400856dafc">evaluate_string</a>(const xml_node &n)</td><td><a class="el" href="classpugi_1_1xpath__query.html">pugi::xpath_query</a></td><td></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__query.html#df3ce6efc17c1b58a1ff60bedb632140">xpath_query</a>(const char *query)</td><td><a class="el" href="classpugi_1_1xpath__query.html">pugi::xpath_query</a></td><td><code> [explicit]</code></td></tr> <tr class="memlist"><td><a class="el" href="classpugi_1_1xpath__query.html#0ca09e7de62e46feb64d03995f389da3">~xpath_query</a>()</td><td><a class="el" href="classpugi_1_1xpath__query.html">pugi::xpath_query</a></td><td></td></tr> -</table><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +</table><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xpath__query.html b/docs/html/classpugi_1_1xpath__query.html index a55cb0d..1f86073 100644 --- a/docs/html/classpugi_1_1xpath__query.html +++ b/docs/html/classpugi_1_1xpath__query.html @@ -232,7 +232,7 @@ If expression does not directly evaluate to node set, function returns empty nod </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/classpugi_1_1xpath__query__coll__graph.png b/docs/html/classpugi_1_1xpath__query__coll__graph.png Binary files differindex f7b3e06..d42802b 100644 --- a/docs/html/classpugi_1_1xpath__query__coll__graph.png +++ b/docs/html/classpugi_1_1xpath__query__coll__graph.png diff --git a/docs/html/functions.html b/docs/html/functions.html index 7870ea7..16f61e3 100644 --- a/docs/html/functions.html +++ b/docs/html/functions.html @@ -188,7 +188,7 @@ Here is a list of all documented class members with links to the class documenta : <a class="el" href="classpugi_1_1xml__tree__walker.html#aa0d4eb42c6518a2a90bc264588ece84">pugi::xml_tree_walker</a><li>~xpath_node_set() : <a class="el" href="classpugi_1_1xpath__node__set.html#6ca44658aa0126e12f9fc3e3f8017376">pugi::xpath_node_set</a><li>~xpath_query() : <a class="el" href="classpugi_1_1xpath__query.html#0ca09e7de62e46feb64d03995f389da3">pugi::xpath_query</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/functions_enum.html b/docs/html/functions_enum.html index 5f676d1..fbca078 100644 --- a/docs/html/functions_enum.html +++ b/docs/html/functions_enum.html @@ -31,7 +31,7 @@ <ul> <li>type_t : <a class="el" href="classpugi_1_1xpath__node__set.html#6c6899c8ecfbce9e42ec85540907080e">pugi::xpath_node_set</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/functions_eval.html b/docs/html/functions_eval.html index ae211d9..7785097 100644 --- a/docs/html/functions_eval.html +++ b/docs/html/functions_eval.html @@ -33,7 +33,7 @@ : <a class="el" href="classpugi_1_1xpath__node__set.html#6c6899c8ecfbce9e42ec85540907080e9d5ce5e6194ac2003da0d86d9af87437">pugi::xpath_node_set</a><li>type_sorted_reverse : <a class="el" href="classpugi_1_1xpath__node__set.html#6c6899c8ecfbce9e42ec85540907080e7035df3be16759292de59850d6c0b9be">pugi::xpath_node_set</a><li>type_unsorted : <a class="el" href="classpugi_1_1xpath__node__set.html#6c6899c8ecfbce9e42ec85540907080e7636fa164710ab9b069850ea3b3e4924">pugi::xpath_node_set</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/functions_func.html b/docs/html/functions_func.html index a68a6c0..85873dc 100644 --- a/docs/html/functions_func.html +++ b/docs/html/functions_func.html @@ -181,7 +181,7 @@ : <a class="el" href="classpugi_1_1xml__tree__walker.html#aa0d4eb42c6518a2a90bc264588ece84">pugi::xml_tree_walker</a><li>~xpath_node_set() : <a class="el" href="classpugi_1_1xpath__node__set.html#6ca44658aa0126e12f9fc3e3f8017376">pugi::xpath_node_set</a><li>~xpath_query() : <a class="el" href="classpugi_1_1xpath__query.html#0ca09e7de62e46feb64d03995f389da3">pugi::xpath_query</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/functions_type.html b/docs/html/functions_type.html index e732be9..c6a9269 100644 --- a/docs/html/functions_type.html +++ b/docs/html/functions_type.html @@ -33,7 +33,7 @@ : <a class="el" href="classpugi_1_1xml__node.html#9084f97350ffc64af1eaf7c17c57f4ba">pugi::xml_node</a><li>const_iterator : <a class="el" href="classpugi_1_1xpath__node__set.html#6987510e88cea4a396d186285c174de6">pugi::xpath_node_set</a><li>iterator : <a class="el" href="classpugi_1_1xml__node.html#e053ea39add5a64de584f7a81212e388">pugi::xml_node</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/graph_legend.html b/docs/html/graph_legend.html index a07c58e..5dfec6f 100644 --- a/docs/html/graph_legend.html +++ b/docs/html/graph_legend.html @@ -73,7 +73,7 @@ A purple dashed arrow is used if a class is contained or used by another class. <li> A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance. </li> </ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:53 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/graph_legend.png b/docs/html/graph_legend.png Binary files differindex b8cfe42..acdfd8c 100644 --- a/docs/html/graph_legend.png +++ b/docs/html/graph_legend.png diff --git a/docs/html/hierarchy.html b/docs/html/hierarchy.html index bcd7f02..f677f84 100644 --- a/docs/html/hierarchy.html +++ b/docs/html/hierarchy.html @@ -38,7 +38,7 @@ This inheritance list is sorted roughly, but not completely, alphabetically:<ul> <li><a class="el" href="classpugi_1_1xpath__node__set.html">pugi::xpath_node_set</a> <li><a class="el" href="classpugi_1_1xpath__query.html">pugi::xpath_query</a> </ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/index.html b/docs/html/index.html index 39fb2e8..6c8b76a 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -13,7 +13,7 @@ </ul></div> <h1>pugixml Documentation</h1> <p> -<h3 align="center">0.3 </h3><hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<h3 align="center">0.34 </h3><hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/inherit__graph__0.map b/docs/html/inherit__graph__0.map index 795e91c..514209a 100644 --- a/docs/html/inherit__graph__0.map +++ b/docs/html/inherit__graph__0.map @@ -1,2 +1,2 @@ base referer -rect $structpugi_1_1transfer__ownership__tag.html 8,8 202,34 +rect $structpugi_1_1transfer__ownership__tag.html 5,5 200,32 diff --git a/docs/html/inherit__graph__0.png b/docs/html/inherit__graph__0.png Binary files differindex 1f839bd..6cfe491 100644 --- a/docs/html/inherit__graph__0.png +++ b/docs/html/inherit__graph__0.png diff --git a/docs/html/inherit__graph__1.map b/docs/html/inherit__graph__1.map index 8f51b91..b440a1c 100644 --- a/docs/html/inherit__graph__1.map +++ b/docs/html/inherit__graph__1.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xml__attribute.html 7,8 141,34 +rect $classpugi_1_1xml__attribute.html 5,5 139,32 diff --git a/docs/html/inherit__graph__1.png b/docs/html/inherit__graph__1.png Binary files differindex 1984539..d2daba7 100644 --- a/docs/html/inherit__graph__1.png +++ b/docs/html/inherit__graph__1.png diff --git a/docs/html/inherit__graph__2.map b/docs/html/inherit__graph__2.map index c81fa55..52515a0 100644 --- a/docs/html/inherit__graph__2.map +++ b/docs/html/inherit__graph__2.map @@ -1,3 +1,3 @@ base referer -rect $classpugi_1_1xml__attribute__iterator.html 121,7 302,34 -rect $classpugi_1_1xml__node__iterator.html 130,58 293,85 +rect $classpugi_1_1xml__attribute__iterator.html 119,5 300,32 +rect $classpugi_1_1xml__node__iterator.html 128,56 291,83 diff --git a/docs/html/inherit__graph__2.png b/docs/html/inherit__graph__2.png Binary files differindex c0f9a3f..942458f 100644 --- a/docs/html/inherit__graph__2.png +++ b/docs/html/inherit__graph__2.png diff --git a/docs/html/inherit__graph__3.map b/docs/html/inherit__graph__3.map index ac3e60d..7693a61 100644 --- a/docs/html/inherit__graph__3.map +++ b/docs/html/inherit__graph__3.map @@ -1,3 +1,3 @@ base referer -rect $classpugi_1_1xml__node.html 9,8 121,34 -rect $classpugi_1_1xml__document.html 170,8 314,34 +rect $classpugi_1_1xml__node.html 7,5 119,32 +rect $classpugi_1_1xml__document.html 169,5 311,32 diff --git a/docs/html/inherit__graph__3.png b/docs/html/inherit__graph__3.png Binary files differindex 4d9a231..94025a7 100644 --- a/docs/html/inherit__graph__3.png +++ b/docs/html/inherit__graph__3.png diff --git a/docs/html/inherit__graph__4.map b/docs/html/inherit__graph__4.map index a42cb31..ba579db 100644 --- a/docs/html/inherit__graph__4.map +++ b/docs/html/inherit__graph__4.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xml__tree__walker.html 9,8 161,34 +rect $classpugi_1_1xml__tree__walker.html 7,5 159,32 diff --git a/docs/html/inherit__graph__4.png b/docs/html/inherit__graph__4.png Binary files differindex 96d08a5..49b5d10 100644 --- a/docs/html/inherit__graph__4.png +++ b/docs/html/inherit__graph__4.png diff --git a/docs/html/inherit__graph__5.map b/docs/html/inherit__graph__5.map index 4cda6cd..8779b74 100644 --- a/docs/html/inherit__graph__5.map +++ b/docs/html/inherit__graph__5.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xpath__exception.html 137,8 289,34 +rect $classpugi_1_1xpath__exception.html 135,5 287,32 diff --git a/docs/html/inherit__graph__5.png b/docs/html/inherit__graph__5.png Binary files differindex f833cf9..18b58ff 100644 --- a/docs/html/inherit__graph__5.png +++ b/docs/html/inherit__graph__5.png diff --git a/docs/html/inherit__graph__6.map b/docs/html/inherit__graph__6.map index a984b26..9fa9db1 100644 --- a/docs/html/inherit__graph__6.map +++ b/docs/html/inherit__graph__6.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xpath__node.html 7,8 133,34 +rect $classpugi_1_1xpath__node.html 5,5 131,32 diff --git a/docs/html/inherit__graph__6.png b/docs/html/inherit__graph__6.png Binary files differindex 1468a8b..597e2f5 100644 --- a/docs/html/inherit__graph__6.png +++ b/docs/html/inherit__graph__6.png diff --git a/docs/html/inherit__graph__7.map b/docs/html/inherit__graph__7.map index 95b7466..3f5400b 100644 --- a/docs/html/inherit__graph__7.map +++ b/docs/html/inherit__graph__7.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xpath__node__set.html 9,8 158,34 +rect $classpugi_1_1xpath__node__set.html 5,5 155,32 diff --git a/docs/html/inherit__graph__7.png b/docs/html/inherit__graph__7.png Binary files differindex adc2e3a..ec162c8 100644 --- a/docs/html/inherit__graph__7.png +++ b/docs/html/inherit__graph__7.png diff --git a/docs/html/inherit__graph__8.map b/docs/html/inherit__graph__8.map index 442f8f7..dcf3277 100644 --- a/docs/html/inherit__graph__8.map +++ b/docs/html/inherit__graph__8.map @@ -1,2 +1,2 @@ base referer -rect $classpugi_1_1xpath__query.html 9,8 137,34 +rect $classpugi_1_1xpath__query.html 7,5 135,32 diff --git a/docs/html/inherit__graph__8.png b/docs/html/inherit__graph__8.png Binary files differindex 6bfb42e..74b84c3 100644 --- a/docs/html/inherit__graph__8.png +++ b/docs/html/inherit__graph__8.png diff --git a/docs/html/inherits.html b/docs/html/inherits.html index 310e5fa..9c44f84 100644 --- a/docs/html/inherits.html +++ b/docs/html/inherits.html @@ -22,44 +22,44 @@ <table border="0" cellspacing="10" cellpadding="0"> <tr><td><img src="inherit__graph__0.png" border="0" alt="" usemap="#pugi_1_1transfer__ownership__tag_map"> <map name="pugi_1_1transfer__ownership__tag_map"> -<area href="structpugi_1_1transfer__ownership__tag.html" shape="rect" coords="8,8,202,34" alt=""> +<area href="structpugi_1_1transfer__ownership__tag.html" shape="rect" coords="5,5,200,32" alt=""> </map></td></tr> <tr><td><img src="inherit__graph__1.png" border="0" alt="" usemap="#pugi_1_1xml__attribute_map"> <map name="pugi_1_1xml__attribute_map"> -<area href="classpugi_1_1xml__attribute.html" shape="rect" coords="7,8,141,34" alt=""> +<area href="classpugi_1_1xml__attribute.html" shape="rect" coords="5,5,139,32" alt=""> </map></td></tr> <tr><td><img src="inherit__graph__2.png" border="0" alt="" usemap="#pugi_1_1xml__attribute__iterator_map"> <map name="pugi_1_1xml__attribute__iterator_map"> -<area href="classpugi_1_1xml__attribute__iterator.html" shape="rect" coords="121,7,302,34" alt=""> -<area href="classpugi_1_1xml__node__iterator.html" shape="rect" coords="130,58,293,85" alt=""> +<area href="classpugi_1_1xml__attribute__iterator.html" shape="rect" coords="119,5,300,32" alt=""> +<area href="classpugi_1_1xml__node__iterator.html" shape="rect" coords="128,56,291,83" alt=""> </map></td></tr> <tr><td><img src="inherit__graph__3.png" border="0" alt="" usemap="#pugi_1_1xml__node_map"> <map name="pugi_1_1xml__node_map"> -<area href="classpugi_1_1xml__node.html" shape="rect" coords="9,8,121,34" alt=""> -<area href="classpugi_1_1xml__document.html" shape="rect" coords="170,8,314,34" alt=""> +<area href="classpugi_1_1xml__node.html" shape="rect" coords="7,5,119,32" alt=""> +<area href="classpugi_1_1xml__document.html" shape="rect" coords="169,5,311,32" alt=""> </map></td></tr> <tr><td><img src="inherit__graph__4.png" border="0" alt="" usemap="#pugi_1_1xml__tree__walker_map"> <map name="pugi_1_1xml__tree__walker_map"> -<area href="classpugi_1_1xml__tree__walker.html" shape="rect" coords="9,8,161,34" alt=""> +<area href="classpugi_1_1xml__tree__walker.html" shape="rect" coords="7,5,159,32" alt=""> </map></td></tr> <tr><td><img src="inherit__graph__5.png" border="0" alt="" usemap="#pugi_1_1xpath__exception_map"> <map name="pugi_1_1xpath__exception_map"> -<area href="classpugi_1_1xpath__exception.html" shape="rect" coords="137,8,289,34" alt=""> +<area href="classpugi_1_1xpath__exception.html" shape="rect" coords="135,5,287,32" alt=""> </map></td></tr> <tr><td><img src="inherit__graph__6.png" border="0" alt="" usemap="#pugi_1_1xpath__node_map"> <map name="pugi_1_1xpath__node_map"> -<area href="classpugi_1_1xpath__node.html" shape="rect" coords="7,8,133,34" alt=""> +<area href="classpugi_1_1xpath__node.html" shape="rect" coords="5,5,131,32" alt=""> </map></td></tr> <tr><td><img src="inherit__graph__7.png" border="0" alt="" usemap="#pugi_1_1xpath__node__set_map"> <map name="pugi_1_1xpath__node__set_map"> -<area href="classpugi_1_1xpath__node__set.html" shape="rect" coords="9,8,158,34" alt=""> +<area href="classpugi_1_1xpath__node__set.html" shape="rect" coords="5,5,155,32" alt=""> </map></td></tr> <tr><td><img src="inherit__graph__8.png" border="0" alt="" usemap="#pugi_1_1xpath__query_map"> <map name="pugi_1_1xpath__query_map"> -<area href="classpugi_1_1xpath__query.html" shape="rect" coords="9,8,137,34" alt=""> +<area href="classpugi_1_1xpath__query.html" shape="rect" coords="7,5,135,32" alt=""> </map></td></tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:53 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/namespacemembers.html b/docs/html/namespacemembers.html index 3a874c4..4056612 100644 --- a/docs/html/namespacemembers.html +++ b/docs/html/namespacemembers.html @@ -55,7 +55,7 @@ Here is a list of all documented namespace members with links to the namespaces : <a class="el" href="namespacepugi.html#8617ea5ba78c676aff8b7af960cb2f4b">pugi</a><li>parse_ws_pcdata : <a class="el" href="namespacepugi.html#e492a24302294f1ce3fbd56f2edbf131">pugi</a><li>xml_node_type : <a class="el" href="namespacepugi.html#137e94a038e4ab0ada6477cf7f6153a9">pugi</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/namespacemembers_enum.html b/docs/html/namespacemembers_enum.html index e682fba..bc25190 100644 --- a/docs/html/namespacemembers_enum.html +++ b/docs/html/namespacemembers_enum.html @@ -30,7 +30,7 @@ <ul> <li>xml_node_type : <a class="el" href="namespacepugi.html#137e94a038e4ab0ada6477cf7f6153a9">pugi</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/namespacemembers_eval.html b/docs/html/namespacemembers_eval.html index 4c55750..3a39b76 100644 --- a/docs/html/namespacemembers_eval.html +++ b/docs/html/namespacemembers_eval.html @@ -36,7 +36,7 @@ : <a class="el" href="namespacepugi.html#137e94a038e4ab0ada6477cf7f6153a9d58c55e810076e076318cc2268191b1f">pugi</a><li>node_pcdata : <a class="el" href="namespacepugi.html#137e94a038e4ab0ada6477cf7f6153a95c0042693a8b8b6b54c191b4403fca21">pugi</a><li>node_pi : <a class="el" href="namespacepugi.html#137e94a038e4ab0ada6477cf7f6153a9cd772b12b3d5442b9771151f45134440">pugi</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/namespacemembers_func.html b/docs/html/namespacemembers_func.html index 1c6e897..0ac7cfb 100644 --- a/docs/html/namespacemembers_func.html +++ b/docs/html/namespacemembers_func.html @@ -31,7 +31,7 @@ <li>as_utf16() : <a class="el" href="namespacepugi.html#557d234d14b2da1cf7ad9b72a05d2698">pugi</a><li>as_utf8() : <a class="el" href="namespacepugi.html#55c7bb5900e82254aa1b9671c61030fd">pugi</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/namespacemembers_vars.html b/docs/html/namespacemembers_vars.html index 9c6d3e2..3cb69d5 100644 --- a/docs/html/namespacemembers_vars.html +++ b/docs/html/namespacemembers_vars.html @@ -45,7 +45,7 @@ : <a class="el" href="namespacepugi.html#1e943812f2de36fc3ee14f7756afdbd7">pugi</a><li>parse_wnorm_attribute : <a class="el" href="namespacepugi.html#8617ea5ba78c676aff8b7af960cb2f4b">pugi</a><li>parse_ws_pcdata : <a class="el" href="namespacepugi.html#e492a24302294f1ce3fbd56f2edbf131">pugi</a></ul> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:52 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:45 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/namespacepugi.html b/docs/html/namespacepugi.html index 30b9247..45126d9 100644 --- a/docs/html/namespacepugi.html +++ b/docs/html/namespacepugi.html @@ -661,7 +661,7 @@ This is the default set of formatting flags. It includes indenting nodes depending on their depth in DOM tree and considering input data to be UTF-8. </td> </tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/namespaces.html b/docs/html/namespaces.html index b52fc10..71bd071 100644 --- a/docs/html/namespaces.html +++ b/docs/html/namespaces.html @@ -19,7 +19,7 @@ <h1>pugixml Namespace List</h1>Here is a list of all documented namespaces with brief descriptions:<table> <tr><td class="indexkey"><a class="el" href="namespacepugi.html">pugi</a></td><td class="indexvalue">The PugiXML Parser namespace </td></tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:50 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:42 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/html/structpugi_1_1transfer__ownership__tag.html b/docs/html/structpugi_1_1transfer__ownership__tag.html index aea2270..832d901 100644 --- a/docs/html/structpugi_1_1transfer__ownership__tag.html +++ b/docs/html/structpugi_1_1transfer__ownership__tag.html @@ -28,7 +28,7 @@ Struct used to distinguish parsing with ownership transfer from parsing without <table border="0" cellpadding="0" cellspacing="0"> <tr><td></td></tr> </table> -<hr size="1"><address style="align: right;"><small>Generated on Wed Feb 21 22:19:51 2007 for pugixml by +<hr size="1"><address style="align: right;"><small>Generated on Wed Oct 31 20:23:44 2007 for pugixml by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.6-NO </small></address> </body> diff --git a/docs/index.html b/docs/index.html index 7c8392f..a0cf022 100644 --- a/docs/index.html +++ b/docs/index.html @@ -415,10 +415,12 @@ environment). The library is written in standard-conformant C++ and was tested o <p>
<ul>
-<li>Windows 32-bit (MSVC<sup><a href="#annot-3">3</a></sup> 7.0 (2002), MSVC 7.1 (2003), MSVC 8.0 (2005), ICC<sup><a href="#annot-4">4</a></sup> 8.0, ICC 8.1, GCC 3.4.2 (MinGW), BCC<sup><a href="#annot-5">5</a></sup> 5.82)
+<li>Windows 32-bit (MSVC<sup><a href="#annot-3">3</a></sup> 6.0, MSVC 7.0 (2002), MSVC 7.1 (2003), MSVC 8.0 (2005), ICC<sup><a href="#annot-4">4</a></sup> 8.0, ICC 8.1, GCC 3.4.2 (MinGW), BCC<sup><a href="#annot-5">5</a></sup> 5.82, DMC<sup><a href="#annot-6">6</a></sup> 8.50, Comeau C++ 4.3.3, PGI<sup><a href="#annot-7">7</a></sup> 6.2, CW<sup><a href="#annot-8">8</a></sup> 8.0)
<li>Linux 32-bit (GCC 3.2)
<li>Sony Playstation Portable (GCC 3.4.2; in PUGIXML_NO_STL mode)
+<li>Sony Playstation 3 (GCC 4.0.2; in PUGIXML_NO_EXCEPTIONS mode (-fno-exceptions))
<li>Microsoft Xbox (MSVC 7.1)
+<li>Microsoft Xbox 360 (MSVC 8.0)
</ul>
</p>
@@ -428,7 +430,10 @@ environment). The library is written in standard-conformant C++ and was tested o <a name="annot-3"><sup>3</sup><small> MSVC is Microsoft Visual C++ Compiler</small> <br>
<a name="annot-4"><sup>4</sup><small> ICC is Intel C++ Compiler</small> <br>
-<a name="annot-5"><sup>5</sup><small> BCC is Borland C++ Compiler</small>
+<a name="annot-5"><sup>5</sup><small> BCC is Borland C++ Compiler</small> <br>
+<a name="annot-6"><sup>6</sup><small> DMC is Digital Mars C++ Compiler</small> <br>
+<a name="annot-7"><sup>7</sup><small> PGI is Portland Group C++ Compiler</small>
+<a name="annot-8"><sup>8</sup><small> CW is Metrowerks CodeWarrior</small>
<hr>
@@ -624,6 +629,17 @@ if necessary) </ul>
</dd>
</dt>
+<dt>31.10.2007 - v0.34
+<dd>Maintenance release. Changes: <ul>
+<li>Improved compatibility (supported Digital Mars C++, MSVC 6, CodeWarrior 8, PGI C++, Comeau, supported PS3 and XBox360)
+<li>Fixed bug with loading from text-mode iostreams
+<li>Fixed leak when transfer_ownership is true and parsing is failing
+<li>Fixed bug in saving (\r and \n are now escaped in attribute values)
+<li>PUGIXML_NO_EXCEPTION flag for platforms without exception handling
+<li>Renamed free() to destroy() - some macro conflicts were reported
+</ul>
+</dd>
+</dt>
</dl>
<hr>
@@ -670,7 +686,7 @@ OTHER DEALINGS IN THE SOFTWARE. <hr>
-<p>Revised 21 February, 2007</p>
+<p>Revised 31 October, 2007</p>
<p><i>© Copyright <a href="mailto:arseny.kapoulkine@gmail.com">Arseny Kapoulkine</a> 2006-2007. All Rights Reserved.</i></p>
</body>
</html>
diff --git a/docs/pugixml.cfg b/docs/pugixml.cfg new file mode 100644 index 0000000..69b031f --- /dev/null +++ b/docs/pugixml.cfg @@ -0,0 +1,1161 @@ +# Doxyfile 1.3.9.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = pugixml
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 0.34
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of source
+# files, where putting all generated files in the same directory would otherwise
+# cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = YES
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is used
+# as the annotated text. Otherwise, the brief description is used as-is. If left
+# blank, the following values are used ("$name" is automatically replaced with the
+# name of the entity): "The $name class" "The $name widget" "The $name file"
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = NO
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation.
+
+SHOW_DIRECTORIES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = pugixml.warn
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../src
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS = *.hpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = YES
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse the
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH = "C:\Program Files\ATT\Graphviz\bin"
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 30000
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 30000
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes that
+# lay further from the root node will be omitted. Note that setting this option to
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that a graph may be further truncated if the graph's image dimensions are
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/src/pugiconfig.hpp b/src/pugiconfig.hpp index 795a66f..75776a9 100644 --- a/src/pugiconfig.hpp +++ b/src/pugiconfig.hpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -// Pug Improved XML Parser - Version 0.3 +// Pug Improved XML Parser - Version 0.34 // -------------------------------------------------------- // Copyright (C) 2006-2007, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) // This work is based on the pugxml parser, which is: @@ -20,4 +20,8 @@ // Uncomment this to disable XPath // #define PUGIXML_NO_XPATH +// Uncomment this to disable exceptions +// Note: you can't use XPath with PUGIXML_NO_EXCEPTIONS +// #define PUGIXML_NO_EXCEPTIONS + #endif diff --git a/src/pugixml.cpp b/src/pugixml.cpp index e812710..be3de07 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -1,2569 +1,2673 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Pug Improved XML Parser - Version 0.3 -// -------------------------------------------------------- -// Copyright (C) 2006-2007, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) -// This work is based on the pugxml parser, which is: -// Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) -// Released into the Public Domain. Use at your own risk. -// See pugxml.xml for further information, history, etc. -// Contributions by Neville Franks (readonly@getsoft.com). -// -/////////////////////////////////////////////////////////////////////////////// - +///////////////////////////////////////////////////////////////////////////////
+//
+// Pug Improved XML Parser - Version 0.34
+// --------------------------------------------------------
+// Copyright (C) 2006-2007, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
+// This work is based on the pugxml parser, which is:
+// Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
+// Released into the Public Domain. Use at your own risk.
+// See pugxml.xml for further information, history, etc.
+// Contributions by Neville Franks (readonly@getsoft.com).
+//
+///////////////////////////////////////////////////////////////////////////////
+
#include "pugixml.hpp"
- +
#include <stdlib.h>
-#include <stdio.h> - -#include <new> - -#ifndef PUGIXML_NO_STL -# include <fstream> -#endif - -#ifdef _MSC_VER -# pragma warning(disable: 4127) // conditional expression is constant -# pragma warning(disable: 4996) // this function or variable may be unsafe -#endif - -#ifdef __BORLANDC__ -# pragma warn -8008 // condition is always false -# pragma warn -8066 // unreachable code -#endif - -#define STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed; } - -namespace pugi -{ - class xml_allocator - { - public: - xml_allocator(xml_memory_block* root): _root(root) - { - } - - template <typename T> T* allocate() - { - void* buf = memalloc(sizeof(T)); - return new (buf) T(); - } - - template <typename T, typename U> T* allocate(U val) - { - void* buf = memalloc(sizeof(T)); - return new (buf) T(val); - } - - private: - xml_memory_block* _root; - - void* memalloc(size_t size) - { - if (_root->size + size <= memory_block_size) - { - void* buf = _root->data + _root->size; - _root->size += size; - return buf; - } - else - { - _root->next = new xml_memory_block(); - _root = _root->next; - - _root->size = size; - - return _root->data; - } - } - }; - - /// A 'name=value' XML attribute structure. - struct xml_attribute_struct - { - /// Default ctor - xml_attribute_struct(): name_insitu(true), value_insitu(true), document_order(0), name(0), value(0), prev_attribute(0), next_attribute(0) - { - } - - void free() - { - if (!name_insitu) delete[] name; - if (!value_insitu) delete[] value; - } - - bool name_insitu : 1; - bool value_insitu : 1; - unsigned int document_order : 30; ///< Document order value - - char* name; ///< Pointer to attribute name. - char* value; ///< Pointer to attribute value. - - xml_attribute_struct* prev_attribute; ///< Previous attribute - xml_attribute_struct* next_attribute; ///< Next attribute - }; - - /// An XML document tree node. - struct xml_node_struct - { - /// Default ctor - /// \param type - node type - xml_node_struct(xml_node_type type = node_element): type(type), name_insitu(true), value_insitu(true), document_order(0), parent(0), name(0), value(0), first_child(0), last_child(0), prev_sibling(0), next_sibling(0), first_attribute(0), last_attribute(0) - { - } - - void free() - { - if (!name_insitu) delete[] name; - if (!value_insitu) delete[] value; - - for (xml_node_struct* cur = first_child; cur; cur = cur->next_sibling) - cur->free(); - - for (xml_attribute_struct* cur = first_attribute; cur; cur = cur->next_attribute) - cur->free(); - } - - xml_node_struct* append_node(xml_allocator& alloc, xml_node_type type = node_element) - { - xml_node_struct* child = alloc.allocate<xml_node_struct>(type); - child->parent = this; - - if (last_child) - { - last_child->next_sibling = child; - child->prev_sibling = last_child; - last_child = child; - } - else first_child = last_child = child; - - return child; - } - - xml_attribute_struct* append_attribute(xml_allocator& alloc) - { - xml_attribute_struct* a = alloc.allocate<xml_attribute_struct>(); - - if (last_attribute) - { - last_attribute->next_attribute = a; - a->prev_attribute = last_attribute; - last_attribute = a; - } - else first_attribute = last_attribute = a; - - return a; - } - - unsigned int type : 3; ///< Node type; see xml_node_type. - bool name_insitu : 1; - bool value_insitu : 1; - unsigned int document_order : 27; ///< Document order value - - xml_node_struct* parent; ///< Pointer to parent - - char* name; ///< Pointer to element name. - char* value; ///< Pointer to any associated string data. - - xml_node_struct* first_child; ///< First child - xml_node_struct* last_child; ///< Last child - - xml_node_struct* prev_sibling; ///< Left brother - xml_node_struct* next_sibling; ///< Right brother - - xml_attribute_struct* first_attribute; ///< First attribute - xml_attribute_struct* last_attribute; ///< Last attribute - }; - - struct xml_document_struct: public xml_node_struct - { - xml_document_struct(): xml_node_struct(node_document), allocator(0) - { - } - - xml_allocator allocator; - }; -} - -namespace -{ - using namespace pugi; - - const unsigned char UTF8_BYTE_MASK = 0xBF; - const unsigned char UTF8_BYTE_MARK = 0x80; - const unsigned char UTF8_BYTE_MASK_READ = 0x3F; - const unsigned char UTF8_FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - enum chartype - { - ct_parse_pcdata = 1, // \0, &, \r, < - ct_parse_attr = 2, // \0, &, \r, ', " - ct_parse_attr_ws = 4, // \0, &, \r, ', ", \n, space, tab - ct_space = 8, // \r, \n, space, tab - ct_parse_cdata = 16, // \0, ], >, \r - ct_parse_comment = 32, // \0, -, >, \r - ct_symbol = 64, // Any symbol > 127, a-z, A-Z, 0-9, _, :, -, . - ct_start_symbol = 128 // Any symbol > 127, a-z, A-Z, _, : - }; - - const unsigned char chartype_table[256] = - { - 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0, // 0-15 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 - 12, 0, 6, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 96, 64, 0, // 32-47 - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 0, 1, 0, 48, 0, // 48-63 - 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 64-79 - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 16, 0, 192, // 80-95 - 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 96-111 - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, // 112-127 - - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 128+ - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192 - }; - - bool is_chartype(char c, chartype ct) - { - return !!(chartype_table[static_cast<unsigned char>(c)] & ct); - } - - bool strcpy_insitu(char*& dest, bool& insitu, const char* source) - { - size_t source_size = strlen(source); - - if (dest && strlen(dest) >= source_size) - { - strcpy(dest, source); - - return true; - } - else - { - char* buf; - - try - { - buf = new char[source_size + 1]; - } - catch (const std::bad_alloc&) - { - return false; - } - - strcpy(buf, source); - - if (!insitu) delete[] dest; - - dest = buf; - insitu = false; - - return true; - } - } - - // Get the size that is needed for strutf16_utf8 applied to all s characters - size_t strutf16_utf8_size(const wchar_t* s) - { - size_t length = 0; - - for (; *s; ++s) - { - unsigned int ch = *s; - - if (ch < 0x80) length += 1; - else if (ch < 0x800) length += 2; - else if (ch < 0x10000) length += 3; - else if (ch < 0x200000) length += 4; - } - - return length; - } - - // Write utf16 char to stream, return position after the last written char - // \return position after last char - char* strutf16_utf8(char* s, unsigned int ch) - { - unsigned int length; - - if (ch < 0x80) length = 1; - else if (ch < 0x800) length = 2; - else if (ch < 0x10000) length = 3; - else if (ch < 0x200000) length = 4; - else return s; - - s += length; - - // Scary scary fall throughs. - switch (length) - { - case 4: - *--s = (char)((ch | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); - ch >>= 6; - case 3: - *--s = (char)((ch | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); - ch >>= 6; - case 2: - *--s = (char)((ch | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); - ch >>= 6; - case 1: - *--s = (char)(ch | UTF8_FIRST_BYTE_MARK[length]); - } - - return s + length; - } - - // Get the size that is needed for strutf8_utf16 applied to all s characters - size_t strutf8_utf16_size(const char* s) - { - size_t length = 0; - - for (; *s; ++s) - { - unsigned char ch = static_cast<unsigned char>(*s); - - if (ch < 0x80 || (ch >= 0xC0 && ch < 0xFC)) ++length; - } - - return length; - } - - // Read utf16 char from utf8 stream, return position after the last read char - // \return position after the last char - const char* strutf8_utf16(const char* s, unsigned int& ch) - { - unsigned int length; - - const unsigned char* str = reinterpret_cast<const unsigned char*>(s); - - if (*str < UTF8_BYTE_MARK) - { - ch = *str; - return s + 1; - } - else if (*str < 0xC0) - { - ch = ' '; - return s + 1; - } - else if (*str < 0xE0) length = 2; - else if (*str < 0xF0) length = 3; - else if (*str < 0xF8) length = 4; - else if (*str < 0xFC) length = 5; - else - { - ch = ' '; - return s + 1; - } - - ch = (*str++ & ~UTF8_FIRST_BYTE_MARK[length]); - - // Scary scary fall throughs. - switch (length) - { - case 5: - ch <<= 6; - ch += (*str++ & UTF8_BYTE_MASK_READ); - case 4: - ch <<= 6; - ch += (*str++ & UTF8_BYTE_MASK_READ); - case 3: - ch <<= 6; - ch += (*str++ & UTF8_BYTE_MASK_READ); - case 2: - ch <<= 6; - ch += (*str++ & UTF8_BYTE_MASK_READ); - } - - return reinterpret_cast<const char*>(str); - } - +#include <stdio.h>
+
+#include <new>
+
+#if !defined(PUGIXML_NO_XPATH) && defined(PUGIXML_NO_EXCEPTIONS)
+#error No exception mode can't be used with XPath support
+#endif
+
+#ifndef PUGIXML_NO_STL
+# include <fstream>
+#endif
+
+#ifdef _MSC_VER
+# pragma warning(disable: 4127) // conditional expression is constant
+# pragma warning(disable: 4996) // this function or variable may be unsafe
+#endif
+
+#ifdef __BORLANDC__
+# pragma warn -8008 // condition is always false
+# pragma warn -8066 // unreachable code
+#endif
+
+#ifdef __BORLANDC__
+// BC workaround
+using std::memmove;
+#endif
+
+#define STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; }
+
+namespace pugi
+{
+ struct xml_document_struct;
+
+ class xml_allocator
+ {
+ public:
+ xml_allocator(xml_memory_block* root): _root(root)
+ {
+ }
+
+ xml_document_struct* allocate_document();
+ xml_node_struct* allocate_node(xml_node_type type);
+ xml_attribute_struct* allocate_attribute();
+
+ private:
+ xml_memory_block* _root;
+
+ void* memalloc(size_t size)
+ {
+ if (_root->size + size <= memory_block_size)
+ {
+ void* buf = _root->data + _root->size;
+ _root->size += size;
+ return buf;
+ }
+ else
+ {
+ _root->next = new xml_memory_block();
+ _root = _root->next;
+
+ _root->size = size;
+
+ return _root->data;
+ }
+ }
+ };
+
+ /// A 'name=value' XML attribute structure.
+ struct xml_attribute_struct
+ {
+ /// Default ctor
+ xml_attribute_struct(): name_insitu(true), value_insitu(true), document_order(0), name(0), value(0), prev_attribute(0), next_attribute(0)
+ {
+ }
+
+ void destroy()
+ {
+ if (!name_insitu) delete[] name;
+ if (!value_insitu) delete[] value;
+ }
+
+ bool name_insitu : 1;
+ bool value_insitu : 1;
+ unsigned int document_order : 30; ///< Document order value
+
+ char* name; ///< Pointer to attribute name.
+ char* value; ///< Pointer to attribute value.
+
+ xml_attribute_struct* prev_attribute; ///< Previous attribute
+ xml_attribute_struct* next_attribute; ///< Next attribute
+ };
+
+ /// An XML document tree node.
+ struct xml_node_struct
+ {
+ /// Default ctor
+ /// \param type - node type
+ xml_node_struct(xml_node_type type = node_element): type(type), name_insitu(true), value_insitu(true), document_order(0), parent(0), name(0), value(0), first_child(0), last_child(0), prev_sibling(0), next_sibling(0), first_attribute(0), last_attribute(0)
+ {
+ }
+
+ void destroy()
+ {
+ if (!name_insitu) delete[] name;
+ if (!value_insitu) delete[] value;
+
+ for (xml_attribute_struct* attr = first_attribute; attr; attr = attr->next_attribute)
+ attr->destroy();
+
+ for (xml_node_struct* node = first_child; node; node = node->next_sibling)
+ node->destroy();
+ }
+
+ xml_node_struct* append_node(xml_allocator& alloc, xml_node_type type = node_element)
+ {
+ xml_node_struct* child = alloc.allocate_node(type);
+ child->parent = this;
+
+ if (last_child)
+ {
+ last_child->next_sibling = child;
+ child->prev_sibling = last_child;
+ last_child = child;
+ }
+ else first_child = last_child = child;
+
+ return child;
+ }
+
+ xml_attribute_struct* append_attribute(xml_allocator& alloc)
+ {
+ xml_attribute_struct* a = alloc.allocate_attribute();
+
+ if (last_attribute)
+ {
+ last_attribute->next_attribute = a;
+ a->prev_attribute = last_attribute;
+ last_attribute = a;
+ }
+ else first_attribute = last_attribute = a;
+
+ return a;
+ }
+
+ unsigned int type : 3; ///< Node type; see xml_node_type.
+ bool name_insitu : 1;
+ bool value_insitu : 1;
+ unsigned int document_order : 27; ///< Document order value
+
+ xml_node_struct* parent; ///< Pointer to parent
+
+ char* name; ///< Pointer to element name.
+ char* value; ///< Pointer to any associated string data.
+
+ xml_node_struct* first_child; ///< First child
+ xml_node_struct* last_child; ///< Last child
+
+ xml_node_struct* prev_sibling; ///< Left brother
+ xml_node_struct* next_sibling; ///< Right brother
+
+ xml_attribute_struct* first_attribute; ///< First attribute
+ xml_attribute_struct* last_attribute; ///< Last attribute
+ };
+
+ struct xml_document_struct: public xml_node_struct
+ {
+ xml_document_struct(): xml_node_struct(node_document), allocator(0)
+ {
+ }
+
+ xml_allocator allocator;
+ };
+
+ xml_document_struct* xml_allocator::allocate_document()
+ {
+ return new(memalloc(sizeof(xml_document_struct))) xml_document_struct;
+ }
+
+ xml_node_struct* xml_allocator::allocate_node(xml_node_type type)
+ {
+ return new(memalloc(sizeof(xml_node_struct))) xml_node_struct(type);
+ }
+
+ xml_attribute_struct* xml_allocator::allocate_attribute()
+ {
+ return new(memalloc(sizeof(xml_attribute_struct))) xml_attribute_struct;
+ }
+}
+
+namespace
+{
+ using namespace pugi;
+
+ const unsigned char UTF8_BYTE_MASK = 0xBF;
+ const unsigned char UTF8_BYTE_MARK = 0x80;
+ const unsigned char UTF8_BYTE_MASK_READ = 0x3F;
+ const unsigned char UTF8_FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+ enum chartype
+ {
+ ct_parse_pcdata = 1, // \0, &, \r, <
+ ct_parse_attr = 2, // \0, &, \r, ', "
+ ct_parse_attr_ws = 4, // \0, &, \r, ', ", \n, space, tab
+ ct_space = 8, // \r, \n, space, tab
+ ct_parse_cdata = 16, // \0, ], >, \r
+ ct_parse_comment = 32, // \0, -, >, \r
+ ct_symbol = 64, // Any symbol > 127, a-z, A-Z, 0-9, _, :, -, .
+ ct_start_symbol = 128 // Any symbol > 127, a-z, A-Z, _, :
+ };
+
+ const unsigned char chartype_table[256] =
+ {
+ 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0, // 0-15
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
+ 12, 0, 6, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 96, 64, 0, // 32-47
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 0, 1, 0, 48, 0, // 48-63
+ 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 64-79
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 16, 0, 192, // 80-95
+ 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 96-111
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, // 112-127
+
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 128+
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
+ };
+
+ bool is_chartype(char c, chartype ct)
+ {
+ return !!(chartype_table[static_cast<unsigned char>(c)] & ct);
+ }
+
+ bool strcpy_insitu(char*& dest, bool& insitu, const char* source)
+ {
+ size_t source_size = strlen(source);
+
+ if (dest && strlen(dest) >= source_size)
+ {
+ strcpy(dest, source);
+
+ return true;
+ }
+ else
+ {
+ char* buf;
+
+ #ifndef PUGIXML_NO_EXCEPTIONS
+ try
+ {
+ #endif
+ buf = new char[source_size + 1];
+ if (!buf) return false;
+ #ifndef PUGIXML_NO_EXCEPTIONS
+ }
+ catch (const std::bad_alloc&)
+ {
+ return false;
+ }
+ #endif
+
+ strcpy(buf, source);
+
+ if (!insitu) delete[] dest;
+
+ dest = buf;
+ insitu = false;
+
+ return true;
+ }
+ }
+
+ // Get the size that is needed for strutf16_utf8 applied to all s characters
+ size_t strutf16_utf8_size(const wchar_t* s)
+ {
+ size_t length = 0;
+
+ for (; *s; ++s)
+ {
+ unsigned int ch = *s;
+
+ if (ch < 0x80) length += 1;
+ else if (ch < 0x800) length += 2;
+ else if (ch < 0x10000) length += 3;
+ else if (ch < 0x200000) length += 4;
+ }
+
+ return length;
+ }
+
+ // Write utf16 char to stream, return position after the last written char
+ // \return position after last char
+ char* strutf16_utf8(char* s, unsigned int ch)
+ {
+ unsigned int length;
+
+ if (ch < 0x80) length = 1;
+ else if (ch < 0x800) length = 2;
+ else if (ch < 0x10000) length = 3;
+ else if (ch < 0x200000) length = 4;
+ else return s;
+
+ s += length;
+
+ // Scary scary fall throughs.
+ switch (length)
+ {
+ case 4:
+ *--s = (char)((ch | UTF8_BYTE_MARK) & UTF8_BYTE_MASK);
+ ch >>= 6;
+ case 3:
+ *--s = (char)((ch | UTF8_BYTE_MARK) & UTF8_BYTE_MASK);
+ ch >>= 6;
+ case 2:
+ *--s = (char)((ch | UTF8_BYTE_MARK) & UTF8_BYTE_MASK);
+ ch >>= 6;
+ case 1:
+ *--s = (char)(ch | UTF8_FIRST_BYTE_MARK[length]);
+ }
+
+ return s + length;
+ }
+
+ // Get the size that is needed for strutf8_utf16 applied to all s characters
+ size_t strutf8_utf16_size(const char* s)
+ {
+ size_t length = 0;
+
+ for (; *s; ++s)
+ {
+ unsigned char ch = static_cast<unsigned char>(*s);
+
+ if (ch < 0x80 || (ch >= 0xC0 && ch < 0xFC)) ++length;
+ }
+
+ return length;
+ }
+
+ // Read utf16 char from utf8 stream, return position after the last read char
+ // \return position after the last char
+ const char* strutf8_utf16(const char* s, unsigned int& ch)
+ {
+ unsigned int length;
+
+ const unsigned char* str = reinterpret_cast<const unsigned char*>(s);
+
+ if (*str < UTF8_BYTE_MARK)
+ {
+ ch = *str;
+ return s + 1;
+ }
+ else if (*str < 0xC0)
+ {
+ ch = ' ';
+ return s + 1;
+ }
+ else if (*str < 0xE0) length = 2;
+ else if (*str < 0xF0) length = 3;
+ else if (*str < 0xF8) length = 4;
+ else if (*str < 0xFC) length = 5;
+ else
+ {
+ ch = ' ';
+ return s + 1;
+ }
+
+ ch = (*str++ & ~UTF8_FIRST_BYTE_MARK[length]);
+
+ // Scary scary fall throughs.
+ switch (length)
+ {
+ case 5:
+ ch <<= 6;
+ ch += (*str++ & UTF8_BYTE_MASK_READ);
+ case 4:
+ ch <<= 6;
+ ch += (*str++ & UTF8_BYTE_MASK_READ);
+ case 3:
+ ch <<= 6;
+ ch += (*str++ & UTF8_BYTE_MASK_READ);
+ case 2:
+ ch <<= 6;
+ ch += (*str++ & UTF8_BYTE_MASK_READ);
+ }
+
+ return reinterpret_cast<const char*>(str);
+ }
+
+ template <bool _1, bool _2> struct opt2_to_type
+ {
+ static const bool o1;
+ static const bool o2;
+ };
+
+ template <bool _1, bool _2> const bool opt2_to_type<_1, _2>::o1 = _1;
+ template <bool _1, bool _2> const bool opt2_to_type<_1, _2>::o2 = _2;
+
+ template <bool _1, bool _2, bool _3, bool _4> struct opt4_to_type
+ {
+ static const bool o1;
+ static const bool o2;
+ static const bool o3;
+ static const bool o4;
+ };
+
+ template <bool _1, bool _2, bool _3, bool _4> const bool opt4_to_type<_1, _2, _3, _4>::o1 = _1;
+ template <bool _1, bool _2, bool _3, bool _4> const bool opt4_to_type<_1, _2, _3, _4>::o2 = _2;
+ template <bool _1, bool _2, bool _3, bool _4> const bool opt4_to_type<_1, _2, _3, _4>::o3 = _3;
+ template <bool _1, bool _2, bool _3, bool _4> const bool opt4_to_type<_1, _2, _3, _4>::o4 = _4;
+
+#ifndef PUGIXML_NO_STL
+ template <typename opt2> void text_output_escaped(std::ostream& os, const char* s, opt2)
+ {
+ const bool attribute = opt2::o1;
+ const bool utf8 = opt2::o2;
+
+ while (*s)
+ {
+ const char* prev = s;
+
+ // While *s is a usual symbol
+ while (*s && *s != '&' && *s != '<' && *s != '>' && ((*s != '"' && *s != '\'') || !attribute)
+ && (*s >= 32 || (*s == '\r' && !attribute) || (*s == '\n' && !attribute) || *s == '\t'))
+ ++s;
+
+ if (prev != s) os.write(prev, static_cast<std::streamsize>(s - prev));
+
+ switch (*s)
+ {
+ case 0: break;
+ case '&':
+ os << "&";
+ ++s;
+ break;
+ case '<':
+ os << "<";
+ ++s;
+ break;
+ case '>':
+ os << ">";
+ ++s;
+ break;
+ case '"':
+ os << """;
+ ++s;
+ break;
+ case '\'':
+ os << "'";
+ ++s;
+ break;
+ case '\r':
+ os << " ";
+ ++s;
+ break;
+ case '\n':
+ os << " ";
+ ++s;
+ break;
+ default: // s is not a usual symbol
+ {
+ unsigned int ch;
+
+ if (utf8)
+ s = strutf8_utf16(s, ch);
+ else
+ ch = (unsigned char)*s++;
+
+ os << "&#" << ch << ";";
+ }
+ }
+ }
+ }
+#endif
+
+ struct gap
+ {
+ char* end;
+ size_t size;
+
+ gap(): end(0), size(0)
+ {
+ }
+
+ // Push new gap, move s count bytes further (skipping the gap).
+ // Collapse previous gap.
+ void push(char*& s, size_t count)
+ {
+ if (end) // there was a gap already; collapse it
+ {
+ // Move [old_gap_end, new_gap_start) to [old_gap_start, ...)
+ memmove(end - size, end, s - end);
+ }
+
+ s += count; // end of current gap
+
+ // "merge" two gaps
+ end = s;
+ size += count;
+ }
+
+ // Collapse all gaps, return past-the-end pointer
+ char* flush(char* s)
+ {
+ if (end)
+ {
+ // Move [old_gap_end, current_pos) to [old_gap_start, ...)
+ memmove(end - size, end, s - end);
+
+ return s - size;
+ }
+ else return s;
+ }
+ };
+
+ char* strconv_escape(char* s, gap& g)
+ {
+ char* stre = s + 1;
+
+ switch (*stre)
+ {
+ case '#': // &#...
+ {
+ unsigned int ucsc = 0;
+
+ ++stre;
+
+ if (*stre == 'x') // &#x... (hex code)
+ {
+ ++stre;
+
+ while (*stre)
+ {
+ if (*stre >= '0' && *stre <= '9')
+ ucsc = 16 * ucsc + (*stre++ - '0');
+ else if (*stre >= 'A' && *stre <= 'F')
+ ucsc = 16 * ucsc + (*stre++ - 'A' + 10);
+ else if (*stre >= 'a' && *stre <= 'f')
+ ucsc = 16 * ucsc + (*stre++ - 'a' + 10);
+ else if (*stre == ';')
+ break;
+ else // cancel
+ return stre;
+ }
+
+ if (*stre != ';') return stre;
+
+ ++stre;
+ }
+ else // &#... (dec code)
+ {
+ while (*stre >= '0' && *stre <= '9')
+ ucsc = 10 * ucsc + (*stre++ - '0');
+
+ if (*stre != ';') return stre;
+
+ ++stre;
+ }
+
+ s = strutf16_utf8(s, ucsc);
+
+ g.push(s, stre - s);
+ return stre;
+ }
+ case 'a': // &a
+ {
+ ++stre;
+
+ if (*stre == 'm') // &am
+ {
+ if (*++stre == 'p' && *++stre == ';') // &
+ {
+ *s++ = '&';
+ ++stre;
+
+ g.push(s, stre - s);
+ return stre;
+ }
+ }
+ else if (*stre == 'p') // &ap
+ {
+ if (*++stre == 'o' && *++stre == 's' && *++stre == ';') // '
+ {
+ *s++ = '\'';
+ ++stre;
+
+ g.push(s, stre - s);
+ return stre;
+ }
+ }
+ break;
+ }
+ case 'g': // &g
+ {
+ if (*++stre == 't' && *++stre == ';') // >
+ {
+ *s++ = '>';
+ ++stre;
+
+ g.push(s, stre - s);
+ return stre;
+ }
+ break;
+ }
+ case 'l': // &l
+ {
+ if (*++stre == 't' && *++stre == ';') // <
+ {
+ *s++ = '<';
+ ++stre;
+
+ g.push(s, stre - s);
+ return stre;
+ }
+ break;
+ }
+ case 'q': // &q
+ {
+ if (*++stre == 'u' && *++stre == 'o' && *++stre == 't' && *++stre == ';') // "
+ {
+ *s++ = '"';
+ ++stre;
+
+ g.push(s, stre - s);
+ return stre;
+ }
+ break;
+ }
+ }
+
+ return stre;
+ }
+
+ char* strconv_comment(char* s)
+ {
+ if (!*s) return 0;
+
+ gap g;
+
+ while (true)
+ {
+ while (!is_chartype(*s, ct_parse_comment)) ++s;
+
+ if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair
+ {
+ *s++ = '\n'; // replace first one with 0x0a
+
+ if (*s == '\n') g.push(s, 1);
+ }
+ else if (*s == '-' && *(s+1) == '-' && *(s+2) == '>') // comment ends here
+ {
+ *g.flush(s) = 0;
+
+ return s + 3;
+ }
+ else if (*s == 0)
+ {
+ return 0;
+ }
+ else ++s;
+ }
+ }
+
+ char* strconv_cdata(char* s)
+ {
+ if (!*s) return 0;
+
+ gap g;
+
+ while (true)
+ {
+ while (!is_chartype(*s, ct_parse_cdata)) ++s;
+
+ if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair
+ {
+ *s++ = '\n'; // replace first one with 0x0a
+
+ if (*s == '\n') g.push(s, 1);
+ }
+ else if (*s == ']' && *(s+1) == ']' && *(s+2) == '>') // CDATA ends here
+ {
+ *g.flush(s) = 0;
+
+ return s + 1;
+ }
+ else if (*s == 0)
+ {
+ return 0;
+ }
+ else ++s;
+ }
+ }
+
+ template <typename opt2> char* strconv_pcdata_t(char* s, opt2)
+ {
+ const bool opt_eol = opt2::o1;
+ const bool opt_escape = opt2::o2;
+
+ if (!*s) return 0;
+
+ gap g;
+
+ while (true)
+ {
+ while (!is_chartype(*s, ct_parse_pcdata)) ++s;
+
+ if (opt_eol && *s == '\r') // Either a single 0x0d or 0x0d 0x0a pair
+ {
+ *s++ = '\n'; // replace first one with 0x0a
+
+ if (*s == '\n') g.push(s, 1);
+ }
+ else if (opt_escape && *s == '&')
+ {
+ s = strconv_escape(s, g);
+ }
+ else if (*s == '<') // PCDATA ends here
+ {
+ *g.flush(s) = 0;
+
+ return s + 1;
+ }
+ else if (*s == 0)
+ {
+ return s;
+ }
+ else ++s;
+ }
+ }
+
+ char* strconv_pcdata(char* s, unsigned int optmask)
+ {
+ STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20);
+
+ switch ((optmask >> 4) & 3) // get bitmask for flags (eol escapes)
+ {
+ case 0: return strconv_pcdata_t(s, opt2_to_type<0, 0>());
+ case 1: return strconv_pcdata_t(s, opt2_to_type<0, 1>());
+ case 2: return strconv_pcdata_t(s, opt2_to_type<1, 0>());
+ case 3: return strconv_pcdata_t(s, opt2_to_type<1, 1>());
+ default: return 0; // should not get here
+ }
+ }
+
+ template <typename opt4> char* strconv_attribute_t(char* s, char end_quote, opt4)
+ {
+ const bool opt_wconv = opt4::o1;
+ const bool opt_wnorm = opt4::o2;
+ const bool opt_eol = opt4::o3;
+ const bool opt_escape = opt4::o4;
+
+ if (!*s) return 0;
+
+ gap g;
+
+ // Trim whitespaces
+ if (opt_wnorm)
+ {
+ char* str = s;
+
+ while (is_chartype(*str, ct_space)) ++str;
+
+ if (str != s)
+ g.push(s, str - s);
+ }
+
+ while (true)
+ {
+ while (!is_chartype(*s, (opt_wnorm || opt_wconv) ? ct_parse_attr_ws : ct_parse_attr)) ++s;
+
+ if (opt_wnorm && is_chartype(*s, ct_space))
+ {
+ *s++ = ' ';
+
+ if (is_chartype(*s, ct_space))
+ {
+ char* str = s + 1;
+ while (is_chartype(*str, ct_space)) ++str;
+
+ g.push(s, str - s);
+ }
+ }
+ else if (opt_wconv && is_chartype(*s, ct_space))
+ {
+ if (opt_eol)
+ {
+ if (*s == '\r')
+ {
+ *s++ = ' ';
+
+ if (*s == '\n') g.push(s, 1);
+ }
+ else *s++ = ' ';
+ }
+ else *s++ = ' ';
+ }
+ else if (opt_eol && *s == '\r')
+ {
+ *s++ = '\n';
+
+ if (*s == '\n') g.push(s, 1);
+ }
+ else if (*s == end_quote)
+ {
+ char* str = g.flush(s);
+
+ if (opt_wnorm)
+ {
+ do *str-- = 0;
+ while (is_chartype(*str, ct_space));
+ }
+ else *str = 0;
+
+ return s + 1;
+ }
+ else if (opt_escape && *s == '&')
+ {
+ s = strconv_escape(s, g);
+ }
+ else if (!*s)
+ {
+ return 0;
+ }
+ else ++s;
+ }
+ }
+
+ char* strconv_attribute(char* s, char end_quote, unsigned int optmask)
+ {
+ STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wnorm_attribute == 0x40 && parse_wconv_attribute == 0x80);
+
+ switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes)
+ {
+ case 0: return strconv_attribute_t(s, end_quote, opt4_to_type<0, 0, 0, 0>());
+ case 1: return strconv_attribute_t(s, end_quote, opt4_to_type<0, 0, 0, 1>());
+ case 2: return strconv_attribute_t(s, end_quote, opt4_to_type<0, 0, 1, 0>());
+ case 3: return strconv_attribute_t(s, end_quote, opt4_to_type<0, 0, 1, 1>());
+ case 4: return strconv_attribute_t(s, end_quote, opt4_to_type<0, 1, 0, 0>());
+ case 5: return strconv_attribute_t(s, end_quote, opt4_to_type<0, 1, 0, 1>());
+ case 6: return strconv_attribute_t(s, end_quote, opt4_to_type<0, 1, 1, 0>());
+ case 7: return strconv_attribute_t(s, end_quote, opt4_to_type<0, 1, 1, 1>());
+ case 8: return strconv_attribute_t(s, end_quote, opt4_to_type<1, 0, 0, 0>());
+ case 9: return strconv_attribute_t(s, end_quote, opt4_to_type<1, 0, 0, 1>());
+ case 10: return strconv_attribute_t(s, end_quote, opt4_to_type<1, 0, 1, 0>());
+ case 11: return strconv_attribute_t(s, end_quote, opt4_to_type<1, 0, 1, 1>());
+ case 12: return strconv_attribute_t(s, end_quote, opt4_to_type<1, 1, 0, 0>());
+ case 13: return strconv_attribute_t(s, end_quote, opt4_to_type<1, 1, 0, 1>());
+ case 14: return strconv_attribute_t(s, end_quote, opt4_to_type<1, 1, 1, 0>());
+ case 15: return strconv_attribute_t(s, end_quote, opt4_to_type<1, 1, 1, 1>());
+ default: return 0; // should not get here
+ }
+ }
+
+ struct xml_parser
+ {
+ xml_allocator& alloc;
+
+ // Parser utilities.
+ #define SKIPWS() { while (is_chartype(*s, ct_space)) ++s; }
+ #define OPTSET(OPT) ( optmsk & OPT )
+ #define PUSHNODE(TYPE) { cursor = cursor->append_node(alloc,TYPE); }
+ #define POPNODE() { cursor = cursor->parent; }
+ #define SCANFOR(X) { while (*s != 0 && !(X)) ++s; }
+ #define SCANWHILE(X) { while ((X)) ++s; }
+ #define ENDSEG() { ch = *s; *s = 0; ++s; }
+ #define CHECK_ERROR() { if (*s == 0) return false; }
+
+ xml_parser(xml_allocator& alloc): alloc(alloc)
+ {
+ }
+
+ bool parse(char* s, xml_node_struct* xmldoc, unsigned int optmsk = parse_default)
+ {
+ if (!s || !xmldoc) return false;
+
+ // UTF-8 BOM
+ if ((unsigned char)*s == 0xEF && (unsigned char)*(s+1) == 0xBB && (unsigned char)*(s+2) == 0xBF)
+ s += 3;
+
+ char ch = 0;
+ xml_node_struct* cursor = xmldoc;
+ char* mark = s;
+
+ while (*s != 0)
+ {
+ if (*s == '<')
+ {
+ ++s;
+
+ LOC_TAG:
+ if (*s == '?') // '<?...'
+ {
+ ++s;
+
+ if (!is_chartype(*s, ct_start_symbol)) // bad PI
+ return false;
+ else if (OPTSET(parse_pi))
+ {
+ mark = s;
+ SCANWHILE(is_chartype(*s, ct_symbol)); // Read PI target
+ CHECK_ERROR();
+
+ if (!is_chartype(*s, ct_space) && *s != '?') // Target has to end with space or ?
+ return false;
+
+ ENDSEG();
+ CHECK_ERROR();
+
+ if (ch == '?') // nothing except target present
+ {
+ if (*s != '>') return false;
+ ++s;
+
+ // stricmp / strcasecmp is not portable
+ if ((mark[0] == 'x' || mark[0] == 'X') && (mark[1] == 'm' || mark[1] == 'M')
+ && (mark[2] == 'l' || mark[2] == 'L') && mark[3] == 0)
+ {
+ }
+ else
+ {
+ PUSHNODE(node_pi); // Append a new node on the tree.
+
+ cursor->name = mark;
+
+ POPNODE();
+ }
+ }
+ // stricmp / strcasecmp is not portable
+ else if ((mark[0] == 'x' || mark[0] == 'X') && (mark[1] == 'm' || mark[1] == 'M')
+ && (mark[2] == 'l' || mark[2] == 'L') && mark[3] == 0)
+ {
+ SCANFOR(*s == '?' && *(s+1) == '>'); // Look for '?>'.
+ CHECK_ERROR();
+ s += 2;
+ }
+ else
+ {
+ PUSHNODE(node_pi); // Append a new node on the tree.
+
+ cursor->name = mark;
+
+ if (is_chartype(ch, ct_space))
+ {
+ SKIPWS();
+ CHECK_ERROR();
+
+ mark = s;
+ }
+ else mark = 0;
+
+ SCANFOR(*s == '?' && *(s+1) == '>'); // Look for '?>'.
+ CHECK_ERROR();
+
+ ENDSEG();
+ CHECK_ERROR();
+
+ ++s; // Step over >
+
+ cursor->value = mark;
+
+ POPNODE();
+ }
+ }
+ else // not parsing PI
+ {
+ SCANFOR(*s == '?' && *(s+1) == '>'); // Look for '?>'.
+ CHECK_ERROR();
+
+ s += 2;
+ }
+ }
+ else if (*s == '!') // '<!...'
+ {
+ ++s;
+
+ if (*s == '-') // '<!-...'
+ {
+ ++s;
+
+ if (*s == '-') // '<!--...'
+ {
+ ++s;
+
+ if (OPTSET(parse_comments))
+ {
+ PUSHNODE(node_comment); // Append a new node on the tree.
+ cursor->value = s; // Save the offset.
+ }
+
+ if (OPTSET(parse_eol) && OPTSET(parse_comments))
+ {
+ s = strconv_comment(s);
+
+ if (!s) return false;
+ }
+ else
+ {
+ // Scan for terminating '-->'.
+ SCANFOR(*s == '-' && *(s+1) == '-' && *(s+2) == '>');
+ CHECK_ERROR();
+
+ if (OPTSET(parse_comments))
+ *s = 0; // Zero-terminate this segment at the first terminating '-'.
+
+ s += 3; // Step over the '\0->'.
+ }
+
+ if (OPTSET(parse_comments))
+ {
+ POPNODE(); // Pop since this is a standalone.
+ }
+ }
+ else return false;
+ }
+ else if(*s == '[')
+ {
+ // '<![CDATA[...'
+ if(*++s=='C' && *++s=='D' && *++s=='A' && *++s=='T' && *++s=='A' && *++s == '[')
+ {
+ ++s;
+
+ if (OPTSET(parse_cdata))
+ {
+ PUSHNODE(node_cdata); // Append a new node on the tree.
+ cursor->value = s; // Save the offset.
+
+ if (OPTSET(parse_eol))
+ {
+ s = strconv_cdata(s);
+
+ if (!s) return false;
+ }
+ else
+ {
+ // Scan for terminating ']]>'.
+ SCANFOR(*s == ']' && *(s+1) == ']' && *(s+2) == '>');
+ CHECK_ERROR();
+
+ ENDSEG(); // Zero-terminate this segment.
+ CHECK_ERROR();
+ }
+
+ POPNODE(); // Pop since this is a standalone.
+ }
+ else // Flagged for discard, but we still have to scan for the terminator.
+ {
+ // Scan for terminating ']]>'.
+ SCANFOR(*s == ']' && *(s+1) == ']' && *(s+2) == '>');
+ CHECK_ERROR();
+
+ ++s;
+ }
+
+ s += 2; // Step over the last ']>'.
+ }
+ else return false;
+ }
+ else if (*s=='D' && *++s=='O' && *++s=='C' && *++s=='T' && *++s=='Y' && *++s=='P' && *++s=='E')
+ {
+ ++s;
+
+ SKIPWS(); // Eat any whitespace.
+ CHECK_ERROR();
+
+ LOC_DOCTYPE:
+ SCANFOR(*s == '\'' || *s == '"' || *s == '[' || *s == '>');
+ CHECK_ERROR();
+
+ if (*s == '\'' || *s == '"') // '...SYSTEM "..."
+ {
+ ch = *s++;
+ SCANFOR(*s == ch);
+ CHECK_ERROR();
+
+ ++s;
+ goto LOC_DOCTYPE;
+ }
+
+ if(*s == '[') // '...[...'
+ {
+ ++s;
+ unsigned int bd = 1; // Bracket depth counter.
+ while (*s!=0) // Loop till we're out of all brackets.
+ {
+ if (*s == ']') --bd;
+ else if (*s == '[') ++bd;
+ if (bd == 0) break;
+ ++s;
+ }
+ }
+
+ SCANFOR(*s == '>');
+ CHECK_ERROR();
+
+ ++s;
+ }
+ else return false;
+ }
+ else if (is_chartype(*s, ct_start_symbol)) // '<#...'
+ {
+ PUSHNODE(node_element); // Append a new node to the tree.
+
+ cursor->name = s;
+
+ SCANWHILE(is_chartype(*s, ct_symbol)); // Scan for a terminator.
+ CHECK_ERROR();
+
+ ENDSEG(); // Save char in 'ch', terminate & step over.
+ CHECK_ERROR();
+
+ if (ch == '/') // '<#.../'
+ {
+ if (*s != '>') return false;
+
+ POPNODE(); // Pop.
+
+ ++s;
+ }
+ else if (ch == '>')
+ {
+ // end of tag
+ }
+ else if (is_chartype(ch, ct_space))
+ {
+ while (*s)
+ {
+ SKIPWS(); // Eat any whitespace.
+ CHECK_ERROR();
+
+ if (is_chartype(*s, ct_start_symbol)) // <... #...
+ {
+ xml_attribute_struct* a = cursor->append_attribute(alloc); // Make space for this attribute.
+ a->name = s; // Save the offset.
+
+ SCANWHILE(is_chartype(*s, ct_symbol)); // Scan for a terminator.
+ CHECK_ERROR();
+
+ ENDSEG(); // Save char in 'ch', terminate & step over.
+ CHECK_ERROR();
+
+ if (is_chartype(ch, ct_space))
+ {
+ SKIPWS(); // Eat any whitespace.
+ CHECK_ERROR();
+
+ ch = *s;
+ ++s;
+ }
+
+ if (ch == '=') // '<... #=...'
+ {
+ SKIPWS(); // Eat any whitespace.
+ CHECK_ERROR();
+
+ if (*s == '\'' || *s == '"') // '<... #="...'
+ {
+ ch = *s; // Save quote char to avoid breaking on "''" -or- '""'.
+ ++s; // Step over the quote.
+ a->value = s; // Save the offset.
+
+ s = strconv_attribute(s, ch, optmsk);
+
+ if (!s) return false;
+
+ // After this line the loop continues from the start;
+ // Whitespaces, / and > are ok, symbols are wrong,
+ // everything else will be detected
+ if (is_chartype(*s, ct_start_symbol)) return false;
+ }
+ else return false;
+ }
+ else return false;
+ }
+ else if (*s == '/')
+ {
+ ++s;
+
+ if (*s != '>') return false;
+
+ POPNODE(); // Pop.
+
+ ++s;
+
+ break;
+ }
+ else if (*s == '>')
+ {
+ ++s;
+
+ break;
+ }
+ else return false;
+ }
+ }
+ else return false;
+ }
+ else if (*s == '/')
+ {
+ ++s;
+
+ if (!cursor) return false;
+
+ char* name = cursor->name;
+ if (!name) return false;
+
+ while (*s && is_chartype(*s, ct_symbol))
+ {
+ if (*s++ != *name++) return false;
+ }
+
+ if (*name) return false;
+
+ POPNODE(); // Pop.
+
+ SKIPWS();
+ CHECK_ERROR();
+
+ if (*s != '>') return false;
+ ++s;
+ }
+ else return false;
+ }
+ else
+ {
+ mark = s; // Save this offset while searching for a terminator.
+
+ SKIPWS(); // Eat whitespace if no genuine PCDATA here.
+
+ if ((mark == s || !OPTSET(parse_ws_pcdata)) && (!*s || *s == '<'))
+ {
+ continue;
+ }
+
+ s = mark;
+
+ if (static_cast<xml_node_type>(cursor->type) != node_document)
+ {
+ PUSHNODE(node_pcdata); // Append a new node on the tree.
+ cursor->value = s; // Save the offset.
+
+ s = strconv_pcdata(s, optmsk);
+
+ if (!s) return false;
+
+ POPNODE(); // Pop since this is a standalone.
+
+ if (!*s) break;
+ }
+ else
+ {
+ SCANFOR(*s == '<'); // '...<'
+ if (!*s) break;
+
+ ++s;
+ }
+
+ // We're after '<'
+ goto LOC_TAG;
+ }
+ }
+
+ if (cursor != xmldoc) return false;
+
+ return true;
+ }
+
+ private:
+ xml_parser(const xml_parser&);
+ const xml_parser& operator=(const xml_parser&);
+ };
+
+ // Compare lhs with [rhs_begin, rhs_end)
+ int strcmprange(const char* lhs, const char* rhs_begin, const char* rhs_end)
+ {
+ while (*lhs && rhs_begin != rhs_end && *lhs == *rhs_begin)
+ {
+ ++lhs;
+ ++rhs_begin;
+ }
+
+ if (rhs_begin == rhs_end && *lhs == 0) return 0;
+ else return 1;
+ }
+
+ // Character set pattern match.
+ int strcmpwild_cset(const char** src, const char** dst)
+ {
+ int find = 0, excl = 0, star = 0;
+
+ if (**src == '!')
+ {
+ excl = 1;
+ ++(*src);
+ }
+
+ while (**src != ']' || star == 1)
+ {
+ if (find == 0)
+ {
+ if (**src == '-' && *(*src-1) < *(*src+1) && *(*src+1) != ']' && star == 0)
+ {
+ if (**dst >= *(*src-1) && **dst <= *(*src+1))
+ {
+ find = 1;
+ ++(*src);
+ }
+ }
+ else if (**src == **dst) find = 1;
+ }
+ ++(*src);
+ star = 0;
+ }
+
+ if (excl == 1) find = (1 - find);
+ if (find == 1) ++(*dst);
+
+ return find;
+ }
+
+ // Wildcard pattern match.
+ int strcmpwild_astr(const char** src, const char** dst)
+ {
+ int find = 1;
+ ++(*src);
+ while ((**dst != 0 && **src == '?') || **src == '*')
+ {
+ if(**src == '?') ++(*dst);
+ ++(*src);
+ }
+ while (**src == '*') ++(*src);
+ if (**dst == 0 && **src != 0) return 0;
+ if (**dst == 0 && **src == 0) return 1;
+ else
+ {
+ if (impl::strcmpwild(*src,*dst))
+ {
+ do
+ {
+ ++(*dst);
+ while(**src != **dst && **src != '[' && **dst != 0)
+ ++(*dst);
+ }
+ while ((**dst != 0) ? impl::strcmpwild(*src,*dst) : 0 != (find=0));
+ }
+ if (**dst == 0 && **src == 0) find = 1;
+ return find;
+ }
+ }
+}
+
+namespace pugi
+{
+ namespace impl
+ {
+ // Compare two strings, with globbing, and character sets.
+ int strcmpwild(const char* src, const char* dst)
+ {
+ int find = 1;
+ for(; *src != 0 && find == 1 && *dst != 0; ++src)
+ {
+ switch (*src)
+ {
+ case '?': ++dst; break;
+ case '[': ++src; find = strcmpwild_cset(&src,&dst); break;
+ case '*': find = strcmpwild_astr(&src,&dst); --src; break;
+ default : find = (int) (*src == *dst); ++dst;
+ }
+ }
+ while (*src == '*' && find == 1) ++src;
+ return (find == 1 && *dst == 0 && *src == 0) ? 0 : 1;
+ }
+ }
+
+ xml_tree_walker::xml_tree_walker(): _depth(0)
+ {
+ }
+
+ xml_tree_walker::~xml_tree_walker()
+ {
+ }
+
+ int xml_tree_walker::depth() const
+ {
+ return _depth;
+ }
+
+ bool xml_tree_walker::begin(xml_node&)
+ {
+ return true;
+ }
+
+ bool xml_tree_walker::end(xml_node&)
+ {
+ return true;
+ }
+
+ xml_attribute::xml_attribute(): _attr(0)
+ {
+ }
+
+ xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr)
+ {
+ }
+
+#ifdef __MWERKS__
+ xml_attribute::operator xml_attribute::unspecified_bool_type() const
+ {
+ return empty() ? 0 : &xml_attribute::empty;
+ }
+#else
+ xml_attribute::operator xml_attribute::unspecified_bool_type() const
+ {
+ return empty() ? 0 : &xml_attribute::_attr;
+ }
+#endif
+
+ bool xml_attribute::operator!() const
+ {
+ return empty();
+ }
+
+ bool xml_attribute::operator==(const xml_attribute& r) const
+ {
+ return (_attr == r._attr);
+ }
+
+ bool xml_attribute::operator!=(const xml_attribute& r) const
+ {
+ return (_attr != r._attr);
+ }
+
+ bool xml_attribute::operator<(const xml_attribute& r) const
+ {
+ return (_attr < r._attr);
+ }
+
+ bool xml_attribute::operator>(const xml_attribute& r) const
+ {
+ return (_attr > r._attr);
+ }
+
+ bool xml_attribute::operator<=(const xml_attribute& r) const
+ {
+ return (_attr <= r._attr);
+ }
+
+ bool xml_attribute::operator>=(const xml_attribute& r) const
+ {
+ return (_attr >= r._attr);
+ }
+
+ xml_attribute xml_attribute::next_attribute() const
+ {
+ return _attr ? xml_attribute(_attr->next_attribute) : xml_attribute();
+ }
+
+ xml_attribute xml_attribute::previous_attribute() const
+ {
+ return _attr ? xml_attribute(_attr->prev_attribute) : xml_attribute();
+ }
+
+ int xml_attribute::as_int() const
+ {
+ if(empty() || !_attr->value) return 0;
+ return atoi(_attr->value);
+ }
+
+ double xml_attribute::as_double() const
+ {
+ if(empty() || !_attr->value) return 0.0;
+ return atof(_attr->value);
+ }
+
+ float xml_attribute::as_float() const
+ {
+ if(empty() || !_attr->value) return 0.0f;
+ return (float)atof(_attr->value);
+ }
+
+ bool xml_attribute::as_bool() const
+ {
+ if(empty() || !_attr->value) return false;
+ if(*(_attr->value))
+ {
+ return // Only look at first char:
+ (
+ *(_attr->value) == '1' || // 1*
+ *(_attr->value) == 't' || // t* (true)
+ *(_attr->value) == 'T' || // T* (true|true)
+ *(_attr->value) == 'y' || // y* (yes)
+ *(_attr->value) == 'Y' // Y* (Yes|YES)
+ )
+ ? true : false; // Return true if matches above, else false.
+ }
+ else return false;
+ }
+
+ bool xml_attribute::empty() const
+ {
+ return (_attr == 0);
+ }
+
+ const char* xml_attribute::name() const
+ {
+ return (!empty() && _attr->name) ? _attr->name : "";
+ }
+
+ const char* xml_attribute::value() const
+ {
+ return (!empty() && _attr->value) ? _attr->value : "";
+ }
+
+ unsigned int xml_attribute::document_order() const
+ {
+ return empty() ? 0 : _attr->document_order;
+ }
+
+ xml_attribute& xml_attribute::operator=(const char* rhs)
+ {
+ set_value(rhs);
+ return *this;
+ }
+
+ xml_attribute& xml_attribute::operator=(int rhs)
+ {
+ char buf[128];
+ sprintf(buf, "%d", rhs);
+ set_value(buf);
+ return *this;
+ }
+
+ xml_attribute& xml_attribute::operator=(double rhs)
+ {
+ char buf[128];
+ sprintf(buf, "%g", rhs);
+ set_value(buf);
+ return *this;
+ }
+
+ xml_attribute& xml_attribute::operator=(bool rhs)
+ {
+ set_value(rhs ? "true" : "false");
+ return *this;
+ }
+
+ bool xml_attribute::set_name(const char* rhs)
+ {
+ if (empty()) return false;
+
+ bool insitu = _attr->name_insitu;
+ bool res = strcpy_insitu(_attr->name, insitu, rhs);
+ _attr->name_insitu = insitu;
+
+ return res;
+ }
+
+ bool xml_attribute::set_value(const char* rhs)
+ {
+ if (empty()) return false;
+
+ bool insitu = _attr->value_insitu;
+ bool res = strcpy_insitu(_attr->value, insitu, rhs);
+ _attr->value_insitu = insitu;
+
+ return res;
+ }
+
+#ifdef __BORLANDC__
+ bool operator&&(const xml_attribute& lhs, bool rhs)
+ {
+ return lhs ? rhs : false;
+ }
+
+ bool operator||(const xml_attribute& lhs, bool rhs)
+ {
+ return lhs ? true : rhs;
+ }
+#endif
+
+ xml_node::xml_node(): _root(0)
+ {
+ }
+
+ xml_node::xml_node(xml_node_struct* p): _root(p)
+ {
+ }
+
+#ifdef __MWERKS__
+ xml_node::operator xml_node::unspecified_bool_type() const
+ {
+ return empty() ? 0 : &xml_node::empty;
+ }
+#else
+ xml_node::operator xml_node::unspecified_bool_type() const
+ {
+ return empty() ? 0 : &xml_node::_root;
+ }
+#endif
+
+ bool xml_node::operator!() const
+ {
+ return empty();
+ }
+
+ xml_node::iterator xml_node::begin() const
+ {
+ return iterator(_root->first_child);
+ }
+
+ xml_node::iterator xml_node::end() const
+ {
+ return iterator(0, _root->last_child);
+ }
+
+ xml_node::attribute_iterator xml_node::attributes_begin() const
+ {
+ return attribute_iterator(_root->first_attribute);
+ }
+
+ xml_node::attribute_iterator xml_node::attributes_end() const
+ {
+ return attribute_iterator(0, _root->last_attribute);
+ }
+
+ bool xml_node::operator==(const xml_node& r) const
+ {
+ return (_root == r._root);
+ }
+
+ bool xml_node::operator!=(const xml_node& r) const
+ {
+ return (_root != r._root);
+ }
+
+ bool xml_node::operator<(const xml_node& r) const
+ {
+ return (_root < r._root);
+ }
+
+ bool xml_node::operator>(const xml_node& r) const
+ {
+ return (_root > r._root);
+ }
+
+ bool xml_node::operator<=(const xml_node& r) const
+ {
+ return (_root <= r._root);
+ }
+
+ bool xml_node::operator>=(const xml_node& r) const
+ {
+ return (_root >= r._root);
+ }
+
+ bool xml_node::empty() const
+ {
+ return (_root == 0);
+ }
+
+ xml_allocator& xml_node::get_allocator() const
+ {
+ xml_node_struct* r = root()._root;
+
+ return static_cast<xml_document_struct*>(r)->allocator;
+ }
+
+ const char* xml_node::name() const
+ {
+ return (!empty() && _root->name) ? _root->name : "";
+ }
+
+ xml_node_type xml_node::type() const
+ {
+ return _root ? static_cast<xml_node_type>(_root->type) : node_null;
+ }
+
+ const char* xml_node::value() const
+ {
+ return (!empty() && _root->value) ? _root->value : "";
+ }
+
+ xml_node xml_node::child(const char* name) const
+ {
+ if (!empty())
+ for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+ if (i->name && !strcmp(name, i->name)) return xml_node(i);
+
+ return xml_node();
+ }
+
+ xml_node xml_node::child_w(const char* name) const
+ {
+ if (!empty())
+ for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+ if (i->name && !impl::strcmpwild(name, i->name)) return xml_node(i);
+
+ return xml_node();
+ }
+
+ xml_attribute xml_node::attribute(const char* name) const
+ {
+ if (!_root) return xml_attribute();
+
+ for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute)
+ if (i->name && !strcmp(name, i->name))
+ return xml_attribute(i);
+
+ return xml_attribute();
+ }
+
+ xml_attribute xml_node::attribute_w(const char* name) const
+ {
+ if (!_root) return xml_attribute();
+
+ for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute)
+ if (i->name && !impl::strcmpwild(name, i->name))
+ return xml_attribute(i);
+
+ return xml_attribute();
+ }
+
+ xml_node xml_node::next_sibling(const char* name) const
+ {
+ if(empty()) return xml_node();
+
+ for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling)
+ if (i->name && !strcmp(name, i->name)) return xml_node(i);
+
+ return xml_node();
+ }
+
+ xml_node xml_node::next_sibling_w(const char* name) const
+ {
+ if(empty()) return xml_node();
+
+ for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling)
+ if (i->name && !impl::strcmpwild(name, i->name)) return xml_node(i);
+
+ return xml_node();
+ }
+
+ xml_node xml_node::next_sibling() const
+ {
+ if(empty()) return xml_node();
+
+ if (_root->next_sibling) return xml_node(_root->next_sibling);
+ else return xml_node();
+ }
+
+ xml_node xml_node::previous_sibling(const char* name) const
+ {
+ if (empty()) return xml_node();
+
+ for (xml_node_struct* i = _root->prev_sibling; i; i = i->prev_sibling)
+ if (i->name && !strcmp(name, i->name)) return xml_node(i);
+
+ return xml_node();
+ }
+
+ xml_node xml_node::previous_sibling_w(const char* name) const
+ {
+ if (empty()) return xml_node();
+
+ for (xml_node_struct* i = _root->prev_sibling; i; i = i->prev_sibling)
+ if (i->name && !impl::strcmpwild(name, i->name)) return xml_node(i);
+
+ return xml_node();
+ }
+
+ xml_node xml_node::previous_sibling() const
+ {
+ if(empty()) return xml_node();
+
+ if (_root->prev_sibling) return xml_node(_root->prev_sibling);
+ else return xml_node();
+ }
+
+ xml_node xml_node::parent() const
+ {
+ return empty() ? xml_node() : xml_node(_root->parent);
+ }
+
+ xml_node xml_node::root() const
+ {
+ xml_node r = *this;
+ while (r && r.parent()) r = r.parent();
+ return r;
+ }
+
+ const char* xml_node::child_value() const
+ {
+ if (!empty())
+ for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+ if ((static_cast<xml_node_type>(i->type) == node_pcdata || static_cast<xml_node_type>(i->type) == node_cdata) && i->value)
+ return i->value;
+ return "";
+ }
+
+ const char* xml_node::child_value(const char* name) const
+ {
+ return child(name).child_value();
+ }
+
+ const char* xml_node::child_value_w(const char* name) const
+ {
+ return child_w(name).child_value();
+ }
+
+ xml_attribute xml_node::first_attribute() const
+ {
+ return _root ? xml_attribute(_root->first_attribute) : xml_attribute();
+ }
+
+ xml_attribute xml_node::last_attribute() const
+ {
+ return _root ? xml_attribute(_root->last_attribute) : xml_attribute();
+ }
+
+ xml_node xml_node::first_child() const
+ {
+ if (_root) return xml_node(_root->first_child);
+ else return xml_node();
+ }
+
+ xml_node xml_node::last_child() const
+ {
+ if (_root) return xml_node(_root->last_child);
+ else return xml_node();
+ }
+
+ bool xml_node::set_name(const char* rhs)
+ {
+ switch (type())
+ {
+ case node_pi:
+ case node_element:
+ {
+ bool insitu = _root->name_insitu;
+ bool res = strcpy_insitu(_root->name, insitu, rhs);
+ _root->name_insitu = insitu;
+
+ return res;
+ }
+
+ default:
+ return false;
+ }
+ }
+
+ bool xml_node::set_value(const char* rhs)
+ {
+ switch (type())
+ {
+ case node_pi:
+ case node_cdata:
+ case node_pcdata:
+ case node_comment:
+ {
+ bool insitu = _root->value_insitu;
+ bool res = strcpy_insitu(_root->value, insitu, rhs);
+ _root->value_insitu = insitu;
+
+ return res;
+ }
+
+ default:
+ return false;
+ }
+ }
+
+ xml_attribute xml_node::append_attribute(const char* name)
+ {
+ if (type() != node_element) return xml_attribute();
+
+ xml_attribute a(_root->append_attribute(get_allocator()));
+ a.set_name(name);
+
+ return a;
+ }
+
+ xml_attribute xml_node::insert_attribute_before(const char* name, const xml_attribute& attr)
+ {
+ if (type() != node_element || attr.empty()) return xml_attribute();
+
+ // check that attribute belongs to *this
+ xml_attribute_struct* cur = attr._attr;
+
+ while (cur->prev_attribute) cur = cur->prev_attribute;
+
+ if (cur != _root->first_attribute) return xml_attribute();
+
+ xml_attribute a(get_allocator().allocate_attribute());
+ a.set_name(name);
+
+ if (attr._attr->prev_attribute)
+ attr._attr->prev_attribute->next_attribute = a._attr;
+ else
+ _root->first_attribute = a._attr;
+
+ a._attr->prev_attribute = attr._attr->prev_attribute;
+ a._attr->next_attribute = attr._attr;
+ attr._attr->prev_attribute = a._attr;
+
+ return a;
+ }
+
+ xml_attribute xml_node::insert_attribute_after(const char* name, const xml_attribute& attr)
+ {
+ if (type() != node_element || attr.empty()) return xml_attribute();
+
+ // check that attribute belongs to *this
+ xml_attribute_struct* cur = attr._attr;
+
+ while (cur->prev_attribute) cur = cur->prev_attribute;
+
+ if (cur != _root->first_attribute) return xml_attribute();
+
+ xml_attribute a(get_allocator().allocate_attribute());
+ a.set_name(name);
+
+ if (attr._attr->next_attribute)
+ attr._attr->next_attribute->prev_attribute = a._attr;
+ else
+ _root->last_attribute = a._attr;
+
+ a._attr->next_attribute = attr._attr->next_attribute;
+ a._attr->prev_attribute = attr._attr;
+ attr._attr->next_attribute = a._attr;
+
+ return a;
+ }
+
+ xml_node xml_node::append_child(xml_node_type type)
+ {
+ if ((this->type() != node_element && this->type() != node_document) || type == node_document || type == node_null) return xml_node();
+
+ return xml_node(_root->append_node(get_allocator(), type));
+ }
+
+ xml_node xml_node::insert_child_before(xml_node_type type, const xml_node& node)
+ {
+ if ((this->type() != node_element && this->type() != node_document) || type == node_document || type == node_null) return xml_node();
+ if (node.parent() != *this) return xml_node();
+
+ xml_node n(get_allocator().allocate_node(type));
+ n._root->parent = _root;
+
+ if (node._root->prev_sibling)
+ node._root->prev_sibling->next_sibling = n._root;
+ else
+ _root->first_child = n._root;
+
+ n._root->prev_sibling = node._root->prev_sibling;
+ n._root->next_sibling = node._root;
+ node._root->prev_sibling = n._root;
+
+ return n;
+ }
+
+ xml_node xml_node::insert_child_after(xml_node_type type, const xml_node& node)
+ {
+ if ((this->type() != node_element && this->type() != node_document) || type == node_document || type == node_null) return xml_node();
+ if (node.parent() != *this) return xml_node();
+
+ xml_node n(get_allocator().allocate_node(type));
+ n._root->parent = _root;
+
+ if (node._root->next_sibling)
+ node._root->next_sibling->prev_sibling = n._root;
+ else
+ _root->last_child = n._root;
+
+ n._root->next_sibling = node._root->next_sibling;
+ n._root->prev_sibling = node._root;
+ node._root->next_sibling = n._root;
+
+ return n;
+ }
+
+ void xml_node::remove_attribute(const char* name)
+ {
+ remove_attribute(attribute(name));
+ }
+
+ void xml_node::remove_attribute(const xml_attribute& a)
+ {
+ if (empty()) return;
+
+ // check that attribute belongs to *this
+ xml_attribute_struct* attr = a._attr;
+
+ while (attr->prev_attribute) attr = attr->prev_attribute;
+
+ if (attr != _root->first_attribute) return;
+
+ if (a._attr->next_attribute) a._attr->next_attribute->prev_attribute = a._attr->prev_attribute;
+ else _root->last_attribute = a._attr->prev_attribute;
+
+ if (a._attr->prev_attribute) a._attr->prev_attribute->next_attribute = a._attr->next_attribute;
+ else _root->first_attribute = a._attr->next_attribute;
+
+ a._attr->destroy();
+ }
+
+ void xml_node::remove_child(const char* name)
+ {
+ remove_child(child(name));
+ }
+
+ void xml_node::remove_child(const xml_node& n)
+ {
+ if (empty() || n.parent() != *this) return;
+
+ if (n._root->next_sibling) n._root->next_sibling->prev_sibling = n._root->prev_sibling;
+ else _root->last_child = n._root->prev_sibling;
+
+ if (n._root->prev_sibling) n._root->prev_sibling->next_sibling = n._root->next_sibling;
+ else _root->first_child = n._root->next_sibling;
+
+ n._root->destroy();
+ }
+
+#ifndef PUGIXML_NO_STL
+ std::string xml_node::path(char delimiter) const
+ {
+ std::string path;
+
+ xml_node cursor = *this; // Make a copy.
+
+ path = cursor.name();
+
+ while (cursor.parent())
+ {
+ cursor = cursor.parent();
+
+ std::string temp = cursor.name();
+ temp += delimiter;
+ temp += path;
+ path.swap(temp);
+ }
+
+ return path;
+ }
+#endif
+
+ xml_node xml_node::first_element_by_path(const char* path, char delimiter) const
+ {
+ xml_node found = *this; // Current search context.
+
+ if (empty() || !path || !path[0]) return found;
+
+ if (path[0] == delimiter)
+ {
+ // Absolute path; e.g. '/foo/bar'
+ while (found.parent()) found = found.parent();
+ ++path;
+ }
+
+ const char* path_segment = path;
+
+ while (*path_segment == delimiter) ++path_segment;
+
+ const char* path_segment_end = path_segment;
+
+ while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end;
+
+ if (path_segment == path_segment_end) return found;
+
+ const char* next_segment = path_segment_end;
+
+ while (*next_segment == delimiter) ++next_segment;
+
+ if (*path_segment == '.' && path_segment + 1 == path_segment_end)
+ return found.first_element_by_path(next_segment, delimiter);
+ else if (*path_segment == '.' && *(path_segment+1) == '.' && path_segment + 2 == path_segment_end)
+ return found.parent().first_element_by_path(next_segment, delimiter);
+ else
+ {
+ for (xml_node_struct* j = found._root->first_child; j; j = j->next_sibling)
+ {
+ if (j->name && !strcmprange(j->name, path_segment, path_segment_end))
+ {
+ xml_node subsearch = xml_node(j).first_element_by_path(next_segment, delimiter);
+
+ if (subsearch) return subsearch;
+ }
+ }
+
+ return xml_node();
+ }
+ }
+
+ bool xml_node::traverse(xml_tree_walker& walker)
+ {
+ walker._depth = 0;
+
+ if (!walker.begin(*this)) return false;
+
+ xml_node cur = first_child();
+
+ if (cur)
+ {
+ do
+ {
+ if (!walker.for_each(cur))
+ return false;
+
+ if (cur.first_child())
+ {
+ ++walker._depth;
+ cur = cur.first_child();
+ }
+ else if (cur.next_sibling())
+ cur = cur.next_sibling();
+ else
+ {
+ // Borland C++ workaround
+ while (!cur.next_sibling() && cur != *this && (bool)cur.parent())
+ {
+ --walker._depth;
+ cur = cur.parent();
+ }
+
+ if (cur != *this)
+ cur = cur.next_sibling();
+ }
+ }
+ while (cur && cur != *this);
+ }
+
+ if (!walker.end(*this)) return false;
+
+ return true;
+ }
+
+ unsigned int xml_node::document_order() const
+ {
+ return empty() ? 0 : _root->document_order;
+ }
+
+ void xml_node::precompute_document_order_impl()
+ {
+ if (type() != node_document) return;
+
+ unsigned int current = 1;
+ xml_node cur = *this;
+
+ for (;;)
+ {
+ cur._root->document_order = current++;
+
+ for (xml_attribute a = cur.first_attribute(); a; a = a.next_attribute())
+ a._attr->document_order = current++;
+
+ if (cur.first_child())
+ cur = cur.first_child();
+ else if (cur.next_sibling())
+ cur = cur.next_sibling();
+ else
+ {
+ while (cur && !cur.next_sibling()) cur = cur.parent();
+ cur = cur.next_sibling();
+
+ if (!cur) break;
+ }
+ }
+ }
+
+#ifndef PUGIXML_NO_STL
+ void xml_node::print(std::ostream& os, const char* indent, unsigned int flags, unsigned int depth)
+ {
+ if (empty()) return;
+
+ if ((flags & format_indent) != 0 && (flags & format_raw) == 0)
+ for (unsigned int i = 0; i < depth; ++i) os << indent;
+
+ switch (type())
+ {
+ case node_document:
+ {
+ for (xml_node n = first_child(); n; n = n.next_sibling())
+ n.print(os, indent, flags, depth);
+ break;
+ }
+
+ case node_element:
+ {
+ os << '<' << name();
+
+ for (xml_attribute a = first_attribute(); a; a = a.next_attribute())
+ {
+ os << ' ' << a.name() << "=\"";
+
+ if (flags & format_utf8)
+ text_output_escaped(os, a.value(), opt2_to_type<1, 1>());
+ else
+ text_output_escaped(os, a.value(), opt2_to_type<1, 0>());
+
+ os << "\"";
+ }
+
+ if (flags & format_raw)
+ {
+ if (!_root->first_child) // 0 children
+ os << " />";
+ else
+ {
+ os << ">";
+ for (xml_node n = first_child(); n; n = n.next_sibling())
+ n.print(os, indent, flags, depth + 1);
+ os << "</" << name() << ">";
+ }
+ }
+ else if (!_root->first_child) // 0 children
+ os << " />\n";
+ else if (_root->first_child == _root->last_child && first_child().type() == node_pcdata)
+ {
+ os << ">";
+
+ if (flags & format_utf8)
+ text_output_escaped(os, first_child().value(), opt2_to_type<0, 1>());
+ else
+ text_output_escaped(os, first_child().value(), opt2_to_type<0, 0>());
+
+ os << "</" << name() << ">\n";
+ }
+ else
+ {
+ os << ">\n";
+
+ for (xml_node n = first_child(); n; n = n.next_sibling())
+ n.print(os, indent, flags, depth + 1);
+
+ if ((flags & format_indent) != 0 && (flags & format_raw) == 0)
+ for (unsigned int i = 0; i < depth; ++i) os << indent;
+
+ os << "</" << name() << ">\n";
+ }
+
+ break;
+ }
+
+ case node_pcdata:
+ if (flags & format_utf8)
+ text_output_escaped(os, value(), opt2_to_type<0, 1>());
+ else
+ text_output_escaped(os, value(), opt2_to_type<0, 0>());
+ break;
+
+ case node_cdata:
+ os << "<![CDATA[" << value() << "]]>";
+ if ((flags & format_raw) == 0) os << "\n";
+ break;
+
+ case node_comment:
+ os << "<!--" << value() << "-->";
+ if ((flags & format_raw) == 0) os << "\n";
+ break;
+
+ case node_pi:
+ os << "<?" << name();
+ if (value()[0]) os << ' ' << value();
+ os << "?>";
+ if ((flags & format_raw) == 0) os << "\n";
+ break;
+
+ default:
+ ;
+ }
+ }
+#endif
+
+#ifdef __BORLANDC__
+ bool operator&&(const xml_node& lhs, bool rhs)
+ {
+ return lhs ? rhs : false;
+ }
+
+ bool operator||(const xml_node& lhs, bool rhs)
+ {
+ return lhs ? true : rhs;
+ }
+#endif
+
+ xml_node_iterator::xml_node_iterator()
+ {
+ }
+
+ xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node)
+ {
+ }
+
+ xml_node_iterator::xml_node_iterator(xml_node_struct* ref): _wrap(ref)
+ {
+ }
+
+ xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* prev): _prev(prev), _wrap(ref)
+ {
+ }
+
+ bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const
+ {
+ return (_wrap == rhs._wrap);
+ }
+
+ bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const
+ {
+ return (_wrap != rhs._wrap);
+ }
+
+ xml_node& xml_node_iterator::operator*()
+ {
+ return _wrap;
+ }
+
+ xml_node* xml_node_iterator::operator->()
+ {
+ return &_wrap;
+ }
+
+ const xml_node_iterator& xml_node_iterator::operator++()
+ {
+ _prev = _wrap;
+ _wrap = xml_node(_wrap._root->next_sibling);
+ return *this;
+ }
+
+ xml_node_iterator xml_node_iterator::operator++(int)
+ {
+ xml_node_iterator temp = *this;
+ ++*this;
+ return temp;
+ }
+
+ const xml_node_iterator& xml_node_iterator::operator--()
+ {
+ if (_wrap._root) _wrap = xml_node(_wrap._root->prev_sibling);
+ else _wrap = _prev;
+ return *this;
+ }
+
+ xml_node_iterator xml_node_iterator::operator--(int)
+ {
+ xml_node_iterator temp = *this;
+ --*this;
+ return temp;
+ }
+
+ xml_attribute_iterator::xml_attribute_iterator()
+ {
+ }
+
+ xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr): _wrap(attr)
+ {
+ }
+
+ xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref): _wrap(ref)
+ {
+ }
+
+ xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_attribute_struct* prev): _prev(prev), _wrap(ref)
+ {
+ }
+
+ bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const
+ {
+ return (_wrap == rhs._wrap);
+ }
+
+ bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const
+ {
+ return (_wrap != rhs._wrap);
+ }
+
+ xml_attribute& xml_attribute_iterator::operator*()
+ {
+ return _wrap;
+ }
+
+ xml_attribute* xml_attribute_iterator::operator->()
+ {
+ return &_wrap;
+ }
+
+ const xml_attribute_iterator& xml_attribute_iterator::operator++()
+ {
+ _prev = _wrap;
+ _wrap = xml_attribute(_wrap._attr->next_attribute);
+ return *this;
+ }
+
+ xml_attribute_iterator xml_attribute_iterator::operator++(int)
+ {
+ xml_attribute_iterator temp = *this;
+ ++*this;
+ return temp;
+ }
+
+ const xml_attribute_iterator& xml_attribute_iterator::operator--()
+ {
+ if (_wrap._attr) _wrap = xml_attribute(_wrap._attr->prev_attribute);
+ else _wrap = _prev;
+ return *this;
+ }
+
+ xml_attribute_iterator xml_attribute_iterator::operator--(int)
+ {
+ xml_attribute_iterator temp = *this;
+ --*this;
+ return temp;
+ }
+
+ xml_memory_block::xml_memory_block(): next(0), size(0)
+ {
+ }
+
+ xml_document::xml_document(): _buffer(0)
+ {
+ create();
+ }
+
+ xml_document::~xml_document()
+ {
+ destroy();
+ }
+
+ void xml_document::create()
+ {
+ xml_allocator alloc(&_memory);
+
+ _root = alloc.allocate_document(); // Allocate a new root.
+ xml_allocator& a = static_cast<xml_document_struct*>(_root)->allocator;
+ a = alloc;
+ }
+
+ void xml_document::destroy()
+ {
+ delete[] _buffer;
+ _buffer = 0;
+
+ if (_root) _root->destroy();
+
+ xml_memory_block* current = _memory.next;
+
+ while (current)
+ {
+ xml_memory_block* next = current->next;
+ delete current;
+ current = next;
+ }
+
+ _memory.next = 0;
+ _memory.size = 0;
+
+ create();
+ }
+
+#ifndef PUGIXML_NO_STL
+ bool xml_document::load(std::istream& stream, unsigned int options)
+ {
+ destroy();
+
+ if (!stream.good()) return false;
+
+ std::streamoff length, pos = stream.tellg();
+ stream.seekg(0, std::ios::end);
+ length = stream.tellg();
+ stream.seekg(pos, std::ios::beg);
+
+ if (!stream.good()) return false;
+
+ char* s;
+
+ #ifndef PUGIXML_NO_EXCEPTIONS
+ try
+ {
+ #endif
+ s = new char[length + 1];
+ if (!s) return false;
+ #ifndef PUGIXML_NO_EXCEPTIONS
+ }
+ catch (const std::bad_alloc&)
+ {
+ return false;
+ }
+ #endif
+
+ stream.read(s, length);
+
+ if (stream.gcount() > length || stream.gcount() == 0)
+ {
+ delete[] s;
+ return false;
+ }
+
+ s[stream.gcount()] = 0;
+
+ return parse(transfer_ownership_tag(), s, options); // Parse the input string.
+ }
+#endif
+
+ bool xml_document::load(const char* contents, unsigned int options)
+ {
+ destroy();
+
+ char* s;
+
+ #ifndef PUGIXML_NO_EXCEPTIONS
+ try
+ {
+ #endif
+ s = new char[strlen(contents) + 1];
+ if (!s) return false;
+ #ifndef PUGIXML_NO_EXCEPTIONS
+ }
+ catch (const std::bad_alloc&)
+ {
+ return false;
+ }
+ #endif
+
+ strcpy(s, contents);
+
+ return parse(transfer_ownership_tag(), s, options); // Parse the input string.
+ }
+
+ bool xml_document::load_file(const char* name, unsigned int options)
+ {
+ destroy();
+
+ FILE* file = fopen(name, "rb");
+ if (!file) return false;
+
+ fseek(file, 0, SEEK_END);
+ long length = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ if (length < 0)
+ {
+ fclose(file);
+ return false;
+ }
+
+ char* s;
+
+ #ifndef PUGIXML_NO_EXCEPTIONS
+ try
+ {
+ #endif
+ s = new char[length + 1];
+ if (!s) return false;
+ #ifndef PUGIXML_NO_EXCEPTIONS
+ }
+ catch (const std::bad_alloc&)
+ {
+ fclose(file);
+ return false;
+ }
+ #endif
+
+ size_t read = fread(s, (size_t)length, 1, file);
+ fclose(file);
+
+ if (read != 1)
+ {
+ delete[] s;
+ return false;
+ }
+
+ s[length] = 0;
+
+ return parse(transfer_ownership_tag(), s, options); // Parse the input string.
+ }
+
+ bool xml_document::parse(char* xmlstr, unsigned int options)
+ {
+ destroy();
+
+ xml_allocator& alloc = static_cast<xml_document_struct*>(_root)->allocator;
+
+ xml_parser parser(alloc);
+
+ return parser.parse(xmlstr, _root, options); // Parse the input string.
+ }
+
+ bool xml_document::parse(const transfer_ownership_tag&, char* xmlstr, unsigned int options)
+ {
+ bool res = parse(xmlstr, options);
+
+ if (res) _buffer = xmlstr;
+ else delete[] xmlstr;
+
+ return res;
+ }
+
+#ifndef PUGIXML_NO_STL
+ bool xml_document::save_file(const char* name, const char* indent, unsigned int flags)
+ {
+ std::ofstream out(name, std::ios::out);
+ if (!out) return false;
+
+ if (flags & format_write_bom)
+ {
+ if (flags & format_utf8)
+ {
+ static const unsigned char utf8_bom[] = {0xEF, 0xBB, 0xBF};
+ out.write(reinterpret_cast<const char*>(utf8_bom), 3);
+ }
+ }
+
+ out << "<?xml version=\"1.0\"?>";
+ if (!(flags & format_raw)) out << "\n";
+ print(out, indent, flags);
+
+ return true;
+ }
+#endif
+
+ void xml_document::precompute_document_order()
+ {
+ precompute_document_order_impl();
+ }
+
#ifndef PUGIXML_NO_STL
- template <bool quotes, bool utf8> void text_output_escaped(std::ostream& os, const char* s) - { - while (*s) - { - const char* prev = s; - - // While *s is a usual symbol - while (*s && *s != '&' && *s != '<' && *s != '>' && ((*s != '"' && *s != '\'') || !quotes) - && (*s >= 32 || *s == '\r' || *s == '\n' || *s == '\t')) - ++s; - - if (prev != s) os.write(prev, static_cast<std::streamsize>(s - prev)); - - switch (*s) - { - case 0: break; - case '&': - os << "&"; - ++s; - break; - case '<': - os << "<"; - ++s; - break; - case '>': - os << ">"; - ++s; - break; - case '"': - os << """; - ++s; - break; - case '\'': - os << "'"; - ++s; - break; - default: // s is not a usual symbol - { - unsigned int ch; - - if (utf8) - s = strutf8_utf16(s, ch); - else - ch = (unsigned char)*s++; - - os << "&#" << ch << ";"; - } - } - } - } + std::string as_utf8(const wchar_t* str)
+ {
+ std::string result;
+ result.reserve(strutf16_utf8_size(str));
+
+ for (; *str; ++str)
+ {
+ char buffer[6];
+
+ result.append(buffer, strutf16_utf8(buffer, *str));
+ }
+
+ return result;
+ }
+
+ std::wstring as_utf16(const char* str)
+ {
+ std::wstring result;
+ result.reserve(strutf8_utf16_size(str));
+
+ for (; *str;)
+ {
+ unsigned int ch;
+ str = strutf8_utf16(str, ch);
+ result += (wchar_t)ch;
+ }
+
+ return result;
+ }
#endif
- - struct gap - { - char* end; - size_t size; - - gap(): end(0), size(0) - { - } - - // Push new gap, move s count bytes further (skipping the gap). - // Collapse previous gap. - void push(char*& s, size_t count) - { - if (end) // there was a gap already; collapse it - { - // Move [old_gap_end, new_gap_start) to [old_gap_start, ...) - std::memmove(end - size, end, s - end); - } - - s += count; // end of current gap - - // "merge" two gaps - end = s; - size += count; - } - - // Collapse all gaps, return past-the-end pointer - char* flush(char* s) - { - if (end) - { - // Move [old_gap_end, current_pos) to [old_gap_start, ...) - std::memmove(end - size, end, s - end); - - return s - size; - } - else return s; - } - }; - - char* strconv_escape(char* s, gap& g) - { - char* stre = s + 1; - - switch (*stre) - { - case '#': // &#... - { - unsigned int ucsc = 0; - - ++stre; - - if (*stre == 'x') // &#x... (hex code) - { - ++stre; - - while (*stre) - { - if (*stre >= '0' && *stre <= '9') - ucsc = 16 * ucsc + (*stre++ - '0'); - else if (*stre >= 'A' && *stre <= 'F') - ucsc = 16 * ucsc + (*stre++ - 'A' + 10); - else if (*stre >= 'a' && *stre <= 'f') - ucsc = 16 * ucsc + (*stre++ - 'a' + 10); - else if (*stre == ';') - break; - else // cancel - return stre; - } - - if (*stre != ';') return stre; - - ++stre; - } - else // &#... (dec code) - { - while (*stre >= '0' && *stre <= '9') - ucsc = 10 * ucsc + (*stre++ - '0'); - - if (*stre != ';') return stre; - - ++stre; - } - - s = strutf16_utf8(s, ucsc); - - g.push(s, stre - s); - return stre; - } - case 'a': // &a - { - ++stre; - - if (*stre == 'm') // &am - { - if (*++stre == 'p' && *++stre == ';') // & - { - *s++ = '&'; - ++stre; - - g.push(s, stre - s); - return stre; - } - } - else if (*stre == 'p') // &ap - { - if (*++stre == 'o' && *++stre == 's' && *++stre == ';') // ' - { - *s++ = '\''; - ++stre; - - g.push(s, stre - s); - return stre; - } - } - break; - } - case 'g': // &g - { - if (*++stre == 't' && *++stre == ';') // > - { - *s++ = '>'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - case 'l': // &l - { - if (*++stre == 't' && *++stre == ';') // < - { - *s++ = '<'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - case 'q': // &q - { - if (*++stre == 'u' && *++stre == 'o' && *++stre == 't' && *++stre == ';') // " - { - *s++ = '"'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - } - - return stre; - } - - char* strconv_comment(char* s) - { - if (!*s) return 0; - - gap g; - - while (true) - { - while (!is_chartype(*s, ct_parse_comment)) ++s; - - if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (*s == '-' && *(s+1) == '-' && *(s+2) == '>') // comment ends here - { - *g.flush(s) = 0; - - return s + 3; - } - else if (*s == 0) - { - return 0; - } - else ++s; - } - } - - char* strconv_cdata(char* s) - { - if (!*s) return 0; - - gap g; - - while (true) - { - while (!is_chartype(*s, ct_parse_cdata)) ++s; - - if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (*s == ']' && *(s+1) == ']' && *(s+2) == '>') // CDATA ends here - { - *g.flush(s) = 0; - - return s + 1; - } - else if (*s == 0) - { - return 0; - } - else ++s; - } - } - - template <bool opt_eol, bool opt_escape> char* strconv_pcdata_t(char* s) - { - if (!*s) return 0; - - gap g; - - while (true) - { - while (!is_chartype(*s, ct_parse_pcdata)) ++s; - - if (opt_eol && *s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (opt_escape && *s == '&') - { - s = strconv_escape(s, g); - } - else if (*s == '<') // PCDATA ends here - { - *g.flush(s) = 0; - - return s + 1; - } - else if (*s == 0) - { - return s; - } - else ++s; - } - } - - char* strconv_pcdata(char* s, unsigned int optmask) - { - STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20); - - switch ((optmask >> 4) & 3) // get bitmask for flags (eol escapes) - { - case 0: return strconv_pcdata_t<0, 0>(s); - case 1: return strconv_pcdata_t<0, 1>(s); - case 2: return strconv_pcdata_t<1, 0>(s); - case 3: return strconv_pcdata_t<1, 1>(s); - default: return 0; // should not get here - } - } - - template <bool opt_wconv, bool opt_wnorm, bool opt_eol, bool opt_escape> char* strconv_attribute_t(char* s, char end_quote) - { - if (!*s) return 0; - - gap g; - - // Trim whitespaces - if (opt_wnorm) - { - char* str = s; - - while (is_chartype(*str, ct_space)) ++str; - - if (str != s) - g.push(s, str - s); - } - - while (true) - { - while (!is_chartype(*s, (opt_wnorm || opt_wconv) ? ct_parse_attr_ws : ct_parse_attr)) ++s; - - if (opt_escape && *s == '&') - { - s = strconv_escape(s, g); - } - else if (opt_wnorm && is_chartype(*s, ct_space)) - { - *s++ = ' '; - - if (is_chartype(*s, ct_space)) - { - char* str = s + 1; - while (is_chartype(*str, ct_space)) ++str; - - g.push(s, str - s); - } - } - else if (opt_wconv && is_chartype(*s, ct_space)) - { - if (opt_eol) - { - if (*s == '\r') - { - *s++ = ' '; - - if (*s == '\n') g.push(s, 1); - } - else *s++ = ' '; - } - else *s++ = ' '; - } - else if (opt_eol && *s == '\r') - { - *s++ = '\n'; - - if (*s == '\n') g.push(s, 1); - } - else if (*s == end_quote) - { - char* str = g.flush(s); - - if (opt_wnorm) - { - do *str-- = 0; - while (is_chartype(*str, ct_space)); - } - else *str = 0; - - return s + 1; - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - - char* strconv_attribute(char* s, char end_quote, unsigned int optmask) - { - STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wnorm_attribute == 0x40 && parse_wconv_attribute == 0x80); - - switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes) - { - case 0: return strconv_attribute_t <0, 0, 0, 0>(s, end_quote); - case 1: return strconv_attribute_t <0, 0, 0, 1>(s, end_quote); - case 2: return strconv_attribute_t <0, 0, 1, 0>(s, end_quote); - case 3: return strconv_attribute_t <0, 0, 1, 1>(s, end_quote); - case 4: return strconv_attribute_t <0, 1, 0, 0>(s, end_quote); - case 5: return strconv_attribute_t <0, 1, 0, 1>(s, end_quote); - case 6: return strconv_attribute_t <0, 1, 1, 0>(s, end_quote); - case 7: return strconv_attribute_t <0, 1, 1, 1>(s, end_quote); - case 8: return strconv_attribute_t <1, 0, 0, 0>(s, end_quote); - case 9: return strconv_attribute_t <1, 0, 0, 1>(s, end_quote); - case 10: return strconv_attribute_t<1, 0, 1, 0>(s, end_quote); - case 11: return strconv_attribute_t<1, 0, 1, 1>(s, end_quote); - case 12: return strconv_attribute_t<1, 1, 0, 0>(s, end_quote); - case 13: return strconv_attribute_t<1, 1, 0, 1>(s, end_quote); - case 14: return strconv_attribute_t<1, 1, 1, 0>(s, end_quote); - case 15: return strconv_attribute_t<1, 1, 1, 1>(s, end_quote); - default: return 0; // should not get here - } - } - - struct xml_parser - { - xml_allocator& alloc; - - // Parser utilities. - #define SKIPWS() { while (is_chartype(*s, ct_space)) ++s; } - #define OPTSET(OPT) ( optmsk & OPT ) - #define PUSHNODE(TYPE) { cursor = cursor->append_node(alloc,TYPE); } - #define POPNODE() { cursor = cursor->parent; } - #define SCANFOR(X) { while (*s != 0 && !(X)) ++s; } - #define SCANWHILE(X) { while ((X)) ++s; } - #define ENDSEG() { ch = *s; *s = 0; ++s; } - #define CHECK_ERROR() { if (*s == 0) return false; } - - xml_parser(xml_allocator& alloc): alloc(alloc) - { - } - - bool parse(char* s, xml_node_struct* xmldoc, unsigned int optmsk = parse_default) - { - if (!s || !xmldoc) return false; - - // UTF-8 BOM - if ((unsigned char)*s == 0xEF && (unsigned char)*(s+1) == 0xBB && (unsigned char)*(s+2) == 0xBF) - s += 3; - - char ch = 0; - xml_node_struct* cursor = xmldoc; - char* mark = s; - - while (*s != 0) - { - if (*s == '<') - { - ++s; - - LOC_TAG: - if (*s == '?') // '<?...' - { - ++s; - - if (!is_chartype(*s, ct_start_symbol)) // bad PI - return false; - else if (OPTSET(parse_pi)) - { - mark = s; - SCANWHILE(is_chartype(*s, ct_symbol)); // Read PI target - CHECK_ERROR(); - - if (!is_chartype(*s, ct_space) && *s != '?') // Target has to end with space or ? - return false; - - ENDSEG(); - CHECK_ERROR(); - - if (ch == '?') // nothing except target present - { - if (*s != '>') return false; - ++s; - - // stricmp / strcasecmp is not portable - if ((mark[0] == 'x' || mark[0] == 'X') && (mark[1] == 'm' || mark[1] == 'M') - && (mark[2] == 'l' || mark[2] == 'L') && mark[3] == 0) - { - } - else - { - PUSHNODE(node_pi); // Append a new node on the tree. - - cursor->name = mark; - - POPNODE(); - } - } - // stricmp / strcasecmp is not portable - else if ((mark[0] == 'x' || mark[0] == 'X') && (mark[1] == 'm' || mark[1] == 'M') - && (mark[2] == 'l' || mark[2] == 'L') && mark[3] == 0) - { - SCANFOR(*s == '?' && *(s+1) == '>'); // Look for '?>'. - CHECK_ERROR(); - s += 2; - } - else - { - PUSHNODE(node_pi); // Append a new node on the tree. - - cursor->name = mark; - - if (is_chartype(ch, ct_space)) - { - SKIPWS(); - CHECK_ERROR(); - - mark = s; - } - else mark = 0; - - SCANFOR(*s == '?' && *(s+1) == '>'); // Look for '?>'. - CHECK_ERROR(); - - ENDSEG(); - CHECK_ERROR(); - - ++s; // Step over > - - cursor->value = mark; - - POPNODE(); - } - } - else // not parsing PI - { - SCANFOR(*s == '?' && *(s+1) == '>'); // Look for '?>'. - CHECK_ERROR(); - - s += 2; - } - } - else if (*s == '!') // '<!...' - { - ++s; - - if (*s == '-') // '<!-...' - { - ++s; - - if (*s == '-') // '<!--...' - { - ++s; - - if (OPTSET(parse_comments)) - { - PUSHNODE(node_comment); // Append a new node on the tree. - cursor->value = s; // Save the offset. - } - - if (OPTSET(parse_eol) && OPTSET(parse_comments)) - { - s = strconv_comment(s); - - if (!s) return false; - } - else - { - // Scan for terminating '-->'. - SCANFOR(*s == '-' && *(s+1) == '-' && *(s+2) == '>'); - CHECK_ERROR(); - - if (OPTSET(parse_comments)) - *s = 0; // Zero-terminate this segment at the first terminating '-'. - - s += 3; // Step over the '\0->'. - } - - if (OPTSET(parse_comments)) - { - POPNODE(); // Pop since this is a standalone. - } - } - else return false; - } - else if(*s == '[') - { - // '<![CDATA[...' - if(*++s=='C' && *++s=='D' && *++s=='A' && *++s=='T' && *++s=='A' && *++s == '[') - { - ++s; - - if (OPTSET(parse_cdata)) - { - PUSHNODE(node_cdata); // Append a new node on the tree. - cursor->value = s; // Save the offset. - - if (OPTSET(parse_eol)) - { - s = strconv_cdata(s); - - if (!s) return false; - } - else - { - // Scan for terminating ']]>'. - SCANFOR(*s == ']' && *(s+1) == ']' && *(s+2) == '>'); - CHECK_ERROR(); - - ENDSEG(); // Zero-terminate this segment. - CHECK_ERROR(); - } - - POPNODE(); // Pop since this is a standalone. - } - else // Flagged for discard, but we still have to scan for the terminator. - { - // Scan for terminating ']]>'. - SCANFOR(*s == ']' && *(s+1) == ']' && *(s+2) == '>'); - CHECK_ERROR(); - - ++s; - } - - s += 2; // Step over the last ']>'. - } - else return false; - } - else if (*s=='D' && *++s=='O' && *++s=='C' && *++s=='T' && *++s=='Y' && *++s=='P' && *++s=='E') - { - ++s; - - SKIPWS(); // Eat any whitespace. - CHECK_ERROR(); - - LOC_DOCTYPE: - SCANFOR(*s == '\'' || *s == '"' || *s == '[' || *s == '>'); - CHECK_ERROR(); - - if (*s == '\'' || *s == '"') // '...SYSTEM "..." - { - ch = *s++; - SCANFOR(*s == ch); - CHECK_ERROR(); - - ++s; - goto LOC_DOCTYPE; - } - - if(*s == '[') // '...[...' - { - ++s; - unsigned int bd = 1; // Bracket depth counter. - while (*s!=0) // Loop till we're out of all brackets. - { - if (*s == ']') --bd; - else if (*s == '[') ++bd; - if (bd == 0) break; - ++s; - } - } - - SCANFOR(*s == '>'); - CHECK_ERROR(); - - ++s; - } - else return false; - } - else if (is_chartype(*s, ct_start_symbol)) // '<#...' - { - PUSHNODE(node_element); // Append a new node to the tree. - - cursor->name = s; - - SCANWHILE(is_chartype(*s, ct_symbol)); // Scan for a terminator. - CHECK_ERROR(); - - ENDSEG(); // Save char in 'ch', terminate & step over. - CHECK_ERROR(); - - if (ch == '/') // '<#.../' - { - if (*s != '>') return false; - - POPNODE(); // Pop. - - ++s; - } - else if (ch == '>') - { - // end of tag - } - else if (is_chartype(ch, ct_space)) - { - while (*s) - { - SKIPWS(); // Eat any whitespace. - CHECK_ERROR(); - - if (is_chartype(*s, ct_start_symbol)) // <... #... - { - xml_attribute_struct* a = cursor->append_attribute(alloc); // Make space for this attribute. - a->name = s; // Save the offset. - - SCANWHILE(is_chartype(*s, ct_symbol)); // Scan for a terminator. - CHECK_ERROR(); - - ENDSEG(); // Save char in 'ch', terminate & step over. - CHECK_ERROR(); - - if (is_chartype(ch, ct_space)) - { - SKIPWS(); // Eat any whitespace. - CHECK_ERROR(); - - ch = *s; - ++s; - } - - if (ch == '=') // '<... #=...' - { - SKIPWS(); // Eat any whitespace. - CHECK_ERROR(); - - if (*s == '\'' || *s == '"') // '<... #="...' - { - ch = *s; // Save quote char to avoid breaking on "''" -or- '""'. - ++s; // Step over the quote. - a->value = s; // Save the offset. - - s = strconv_attribute(s, ch, optmsk); - - if (!s) return false; - - // After this line the loop continues from the start; - // Whitespaces, / and > are ok, symbols are wrong, - // everything else will be detected - if (is_chartype(*s, ct_start_symbol)) return false; - } - else return false; - } - else return false; - } - else if (*s == '/') - { - ++s; - - if (*s != '>') return false; - - POPNODE(); // Pop. - - ++s; - - break; - } - else if (*s == '>') - { - ++s; - - break; - } - else return false; - } - } - else return false; - } - else if (*s == '/') - { - ++s; - - if (!cursor) return false; - - char* name = cursor->name; - if (!name) return false; - - while (*s && is_chartype(*s, ct_symbol)) - { - if (*s++ != *name++) return false; - } - - if (*name) return false; - - POPNODE(); // Pop. - - SKIPWS(); - CHECK_ERROR(); - - if (*s != '>') return false; - ++s; - } - else return false; - } - else - { - mark = s; // Save this offset while searching for a terminator. - - SKIPWS(); // Eat whitespace if no genuine PCDATA here. - - if ((mark == s || !OPTSET(parse_ws_pcdata)) && (!*s || *s == '<')) - { - continue; - } - - s = mark; - - if (static_cast<xml_node_type>(cursor->type) != node_document) - { - PUSHNODE(node_pcdata); // Append a new node on the tree. - cursor->value = s; // Save the offset. - - s = strconv_pcdata(s, optmsk); - - if (!s) return false; - - POPNODE(); // Pop since this is a standalone. - - if (!*s) break; - } - else - { - SCANFOR(*s == '<'); // '...<' - if (!*s) break; - - ++s; - } - - // We're after '<' - goto LOC_TAG; - } - } - - if (cursor != xmldoc) return false; - - return true; - } - - private: - xml_parser(const xml_parser&); - const xml_parser& operator=(const xml_parser&); - }; - - // Compare lhs with [rhs_begin, rhs_end) - int strcmprange(const char* lhs, const char* rhs_begin, const char* rhs_end) - { - while (*lhs && rhs_begin != rhs_end && *lhs == *rhs_begin) - { - ++lhs; - ++rhs_begin; - } - - if (rhs_begin == rhs_end && *lhs == 0) return 0; - else return 1; - } - - // Character set pattern match. - int strcmpwild_cset(const char** src, const char** dst) - { - int find = 0, excl = 0, star = 0; - - if (**src == '!') - { - excl = 1; - ++(*src); - } - - while (**src != ']' || star == 1) - { - if (find == 0) - { - if (**src == '-' && *(*src-1) < *(*src+1) && *(*src+1) != ']' && star == 0) - { - if (**dst >= *(*src-1) && **dst <= *(*src+1)) - { - find = 1; - ++(*src); - } - } - else if (**src == **dst) find = 1; - } - ++(*src); - star = 0; - } - - if (excl == 1) find = (1 - find); - if (find == 1) ++(*dst); - - return find; - } - - // Wildcard pattern match. - int strcmpwild_astr(const char** src, const char** dst) - { - int find = 1; - ++(*src); - while ((**dst != 0 && **src == '?') || **src == '*') - { - if(**src == '?') ++(*dst); - ++(*src); - } - while (**src == '*') ++(*src); - if (**dst == 0 && **src != 0) return 0; - if (**dst == 0 && **src == 0) return 1; - else - { - if (impl::strcmpwild(*src,*dst)) - { - do - { - ++(*dst); - while(**src != **dst && **src != '[' && **dst != 0) - ++(*dst); - } - while ((**dst != 0) ? impl::strcmpwild(*src,*dst) : 0 != (find=0)); - } - if (**dst == 0 && **src == 0) find = 1; - return find; - } - } -} - -namespace pugi -{ - namespace impl - { - // Compare two strings, with globbing, and character sets. - int strcmpwild(const char* src, const char* dst) - { - int find = 1; - for(; *src != 0 && find == 1 && *dst != 0; ++src) - { - switch (*src) - { - case '?': ++dst; break; - case '[': ++src; find = strcmpwild_cset(&src,&dst); break; - case '*': find = strcmpwild_astr(&src,&dst); --src; break; - default : find = (int) (*src == *dst); ++dst; - } - } - while (*src == '*' && find == 1) ++src; - return (find == 1 && *dst == 0 && *src == 0) ? 0 : 1; - } - } - - xml_tree_walker::xml_tree_walker(): _depth(0) - { - } - - xml_tree_walker::~xml_tree_walker() - { - } - - int xml_tree_walker::depth() const - { - return _depth; - } - - bool xml_tree_walker::begin(xml_node&) - { - return true; - } - - bool xml_tree_walker::end(xml_node&) - { - return true; - } - - xml_attribute::xml_attribute(): _attr(0) - { - } - - xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr) - { - } - - xml_attribute::operator xml_attribute::unspecified_bool_type() const - { - return empty() ? 0 : &xml_attribute::_attr; - } - - bool xml_attribute::operator!() const - { - return empty(); - } - - bool xml_attribute::operator==(const xml_attribute& r) const - { - return (_attr == r._attr); - } - - bool xml_attribute::operator!=(const xml_attribute& r) const - { - return (_attr != r._attr); - } - - bool xml_attribute::operator<(const xml_attribute& r) const - { - return (_attr < r._attr); - } - - bool xml_attribute::operator>(const xml_attribute& r) const - { - return (_attr > r._attr); - } - - bool xml_attribute::operator<=(const xml_attribute& r) const - { - return (_attr <= r._attr); - } - - bool xml_attribute::operator>=(const xml_attribute& r) const - { - return (_attr >= r._attr); - } - - xml_attribute xml_attribute::next_attribute() const - { - return _attr ? xml_attribute(_attr->next_attribute) : xml_attribute(); - } - - xml_attribute xml_attribute::previous_attribute() const - { - return _attr ? xml_attribute(_attr->prev_attribute) : xml_attribute(); - } - - int xml_attribute::as_int() const - { - if(empty() || !_attr->value) return 0; - return atoi(_attr->value); - } - - double xml_attribute::as_double() const - { - if(empty() || !_attr->value) return 0.0; - return atof(_attr->value); - } - - float xml_attribute::as_float() const - { - if(empty() || !_attr->value) return 0.0f; - return (float)atof(_attr->value); - } - - bool xml_attribute::as_bool() const - { - if(empty() || !_attr->value) return false; - if(*(_attr->value)) - { - return // Only look at first char: - ( - *(_attr->value) == '1' || // 1* - *(_attr->value) == 't' || // t* (true) - *(_attr->value) == 'T' || // T* (true|true) - *(_attr->value) == 'y' || // y* (yes) - *(_attr->value) == 'Y' // Y* (Yes|YES) - ) - ? true : false; // Return true if matches above, else false. - } - else return false; - } - - bool xml_attribute::empty() const - { - return (_attr == 0); - } - - const char* xml_attribute::name() const - { - return (!empty() && _attr->name) ? _attr->name : ""; - } - - const char* xml_attribute::value() const - { - return (!empty() && _attr->value) ? _attr->value : ""; - } - - unsigned int xml_attribute::document_order() const - { - return empty() ? 0 : _attr->document_order; - } - - xml_attribute& xml_attribute::operator=(const char* rhs) - { - set_value(rhs); - return *this; - } - - xml_attribute& xml_attribute::operator=(int rhs) - { - char buf[128]; - sprintf(buf, "%d", rhs); - set_value(buf); - return *this; - } - - xml_attribute& xml_attribute::operator=(double rhs) - { - char buf[128]; - sprintf(buf, "%g", rhs); - set_value(buf); - return *this; - } - - xml_attribute& xml_attribute::operator=(bool rhs) - { - set_value(rhs ? "true" : "false"); - return *this; - } - - bool xml_attribute::set_name(const char* rhs) - { - if (empty()) return false; - - bool insitu = _attr->name_insitu; - bool res = strcpy_insitu(_attr->name, insitu, rhs); - _attr->name_insitu = insitu; - - return res; - } - - bool xml_attribute::set_value(const char* rhs) - { - if (empty()) return false; - - bool insitu = _attr->value_insitu; - bool res = strcpy_insitu(_attr->value, insitu, rhs); - _attr->value_insitu = insitu; - - return res; - } - -#ifdef __BORLANDC__ - bool operator&&(const xml_attribute& lhs, bool rhs) - { - return lhs ? rhs : false; - } - - bool operator||(const xml_attribute& lhs, bool rhs) - { - return lhs ? true : rhs; - } -#endif - - xml_node::xml_node(): _root(0) - { - } - - xml_node::xml_node(xml_node_struct* p): _root(p) - { - } - - xml_node::operator xml_node::unspecified_bool_type() const - { - return empty() ? 0 : &xml_node::_root; - } - - bool xml_node::operator!() const - { - return empty(); - } - - xml_node::iterator xml_node::begin() const - { - return iterator(_root->first_child); - } - - xml_node::iterator xml_node::end() const - { - return iterator(0, _root->last_child); - } - - xml_node::attribute_iterator xml_node::attributes_begin() const - { - return attribute_iterator(_root->first_attribute); - } - - xml_node::attribute_iterator xml_node::attributes_end() const - { - return attribute_iterator(0, _root->last_attribute); - } - - bool xml_node::operator==(const xml_node& r) const - { - return (_root == r._root); - } - - bool xml_node::operator!=(const xml_node& r) const - { - return (_root != r._root); - } - - bool xml_node::operator<(const xml_node& r) const - { - return (_root < r._root); - } - - bool xml_node::operator>(const xml_node& r) const - { - return (_root > r._root); - } - - bool xml_node::operator<=(const xml_node& r) const - { - return (_root <= r._root); - } - - bool xml_node::operator>=(const xml_node& r) const - { - return (_root >= r._root); - } - - bool xml_node::empty() const - { - return (_root == 0); - } - - xml_allocator& xml_node::get_allocator() const - { - xml_node_struct* r = root()._root; - - return static_cast<xml_document_struct*>(r)->allocator; - } - - const char* xml_node::name() const - { - return (!empty() && _root->name) ? _root->name : ""; - } - - xml_node_type xml_node::type() const - { - return _root ? static_cast<xml_node_type>(_root->type) : node_null; - } - - const char* xml_node::value() const - { - return (!empty() && _root->value) ? _root->value : ""; - } - - xml_node xml_node::child(const char* name) const - { - if (!empty()) - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->name && !strcmp(name, i->name)) return xml_node(i); - - return xml_node(); - } - - xml_node xml_node::child_w(const char* name) const - { - if (!empty()) - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->name && !impl::strcmpwild(name, i->name)) return xml_node(i); - - return xml_node(); - } - - xml_attribute xml_node::attribute(const char* name) const - { - if (!_root) return xml_attribute(); - - for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) - if (i->name && !strcmp(name, i->name)) - return xml_attribute(i); - - return xml_attribute(); - } - - xml_attribute xml_node::attribute_w(const char* name) const - { - if (!_root) return xml_attribute(); - - for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) - if (i->name && !impl::strcmpwild(name, i->name)) - return xml_attribute(i); - - return xml_attribute(); - } - - xml_node xml_node::next_sibling(const char* name) const - { - if(empty()) return xml_node(); - - for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling) - if (i->name && !strcmp(name, i->name)) return xml_node(i); - - return xml_node(); - } - - xml_node xml_node::next_sibling_w(const char* name) const - { - if(empty()) return xml_node(); - - for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling) - if (i->name && !impl::strcmpwild(name, i->name)) return xml_node(i); - - return xml_node(); - } - - xml_node xml_node::next_sibling() const - { - if(empty()) return xml_node(); - - if (_root->next_sibling) return xml_node(_root->next_sibling); - else return xml_node(); - } - - xml_node xml_node::previous_sibling(const char* name) const - { - if (empty()) return xml_node(); - - for (xml_node_struct* i = _root->prev_sibling; i; i = i->prev_sibling) - if (i->name && !strcmp(name, i->name)) return xml_node(i); - - return xml_node(); - } - - xml_node xml_node::previous_sibling_w(const char* name) const - { - if (empty()) return xml_node(); - - for (xml_node_struct* i = _root->prev_sibling; i; i = i->prev_sibling) - if (i->name && !impl::strcmpwild(name, i->name)) return xml_node(i); - - return xml_node(); - } - - xml_node xml_node::previous_sibling() const - { - if(empty()) return xml_node(); - - if (_root->prev_sibling) return xml_node(_root->prev_sibling); - else return xml_node(); - } - - xml_node xml_node::parent() const - { - return empty() ? xml_node() : xml_node(_root->parent); - } - - xml_node xml_node::root() const - { - xml_node r = *this; - while (r && r.parent()) r = r.parent(); - return r; - } - - const char* xml_node::child_value() const - { - if (!empty()) - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if ((static_cast<xml_node_type>(i->type) == node_pcdata || static_cast<xml_node_type>(i->type) == node_cdata) && i->value) - return i->value; - return ""; - } - - const char* xml_node::child_value(const char* name) const - { - return child(name).child_value(); - } - - const char* xml_node::child_value_w(const char* name) const - { - return child_w(name).child_value(); - } - - xml_attribute xml_node::first_attribute() const - { - return _root ? xml_attribute(_root->first_attribute) : xml_attribute(); - } - - xml_attribute xml_node::last_attribute() const - { - return _root ? xml_attribute(_root->last_attribute) : xml_attribute(); - } - - xml_node xml_node::first_child() const - { - if (_root) return xml_node(_root->first_child); - else return xml_node(); - } - - xml_node xml_node::last_child() const - { - if (_root) return xml_node(_root->last_child); - else return xml_node(); - } - - bool xml_node::set_name(const char* rhs) - { - switch (type()) - { - case node_pi: - case node_element: - { - bool insitu = _root->name_insitu; - bool res = strcpy_insitu(_root->name, insitu, rhs); - _root->name_insitu = insitu; - - return res; - } - - default: - return false; - } - } - - bool xml_node::set_value(const char* rhs) - { - switch (type()) - { - case node_pi: - case node_cdata: - case node_pcdata: - case node_comment: - { - bool insitu = _root->value_insitu; - bool res = strcpy_insitu(_root->value, insitu, rhs); - _root->value_insitu = insitu; - - return res; - } - - default: - return false; - } - } - - xml_attribute xml_node::append_attribute(const char* name) - { - if (type() != node_element) return xml_attribute(); - - xml_attribute a(_root->append_attribute(get_allocator())); - a.set_name(name); - - return a; - } - - xml_attribute xml_node::insert_attribute_before(const char* name, const xml_attribute& attr) - { - if (type() != node_element || attr.empty()) return xml_attribute(); - - // check that attribute belongs to *this - xml_attribute_struct* cur = attr._attr; - - while (cur->prev_attribute) cur = cur->prev_attribute; - - if (cur != _root->first_attribute) return xml_attribute(); - - xml_attribute a(get_allocator().allocate<xml_attribute_struct>()); - a.set_name(name); - - if (attr._attr->prev_attribute) - attr._attr->prev_attribute->next_attribute = a._attr; - else - _root->first_attribute = a._attr; - - a._attr->prev_attribute = attr._attr->prev_attribute; - a._attr->next_attribute = attr._attr; - attr._attr->prev_attribute = a._attr; - - return a; - } - - xml_attribute xml_node::insert_attribute_after(const char* name, const xml_attribute& attr) - { - if (type() != node_element || attr.empty()) return xml_attribute(); - - // check that attribute belongs to *this - xml_attribute_struct* cur = attr._attr; - - while (cur->prev_attribute) cur = cur->prev_attribute; - - if (cur != _root->first_attribute) return xml_attribute(); - - xml_attribute a(get_allocator().allocate<xml_attribute_struct>()); - a.set_name(name); - - if (attr._attr->next_attribute) - attr._attr->next_attribute->prev_attribute = a._attr; - else - _root->last_attribute = a._attr; - - a._attr->next_attribute = attr._attr->next_attribute; - a._attr->prev_attribute = attr._attr; - attr._attr->next_attribute = a._attr; - - return a; - } - - xml_node xml_node::append_child(xml_node_type type) - { - if ((this->type() != node_element && this->type() != node_document) || type == node_document || type == node_null) return xml_node(); - - return xml_node(_root->append_node(get_allocator(), type)); - } - - xml_node xml_node::insert_child_before(xml_node_type type, const xml_node& node) - { - if ((this->type() != node_element && this->type() != node_document) || type == node_document || type == node_null) return xml_node(); - if (node.parent() != *this) return xml_node(); - - xml_node n(get_allocator().allocate<xml_node_struct>(type)); - n._root->parent = _root; - - if (node._root->prev_sibling) - node._root->prev_sibling->next_sibling = n._root; - else - _root->first_child = n._root; - - n._root->prev_sibling = node._root->prev_sibling; - n._root->next_sibling = node._root; - node._root->prev_sibling = n._root; - - return n; - } - - xml_node xml_node::insert_child_after(xml_node_type type, const xml_node& node) - { - if ((this->type() != node_element && this->type() != node_document) || type == node_document || type == node_null) return xml_node(); - if (node.parent() != *this) return xml_node(); - - xml_node n(get_allocator().allocate<xml_node_struct>(type)); - n._root->parent = _root; - - if (node._root->next_sibling) - node._root->next_sibling->prev_sibling = n._root; - else - _root->last_child = n._root; - - n._root->next_sibling = node._root->next_sibling; - n._root->prev_sibling = node._root; - node._root->next_sibling = n._root; - - return n; - } - - void xml_node::remove_attribute(const char* name) - { - remove_attribute(attribute(name)); - } - - void xml_node::remove_attribute(const xml_attribute& a) - { - if (empty()) return; - - // check that attribute belongs to *this - xml_attribute_struct* attr = a._attr; - - while (attr->prev_attribute) attr = attr->prev_attribute; - - if (attr != _root->first_attribute) return; - - if (a._attr->next_attribute) a._attr->next_attribute->prev_attribute = a._attr->prev_attribute; - else _root->last_attribute = a._attr->prev_attribute; - - if (a._attr->prev_attribute) a._attr->prev_attribute->next_attribute = a._attr->next_attribute; - else _root->first_attribute = a._attr->next_attribute; - - a._attr->free(); - } - - void xml_node::remove_child(const char* name) - { - remove_child(child(name)); - } - - void xml_node::remove_child(const xml_node& n) - { - if (empty() || n.parent() != *this) return; - - if (n._root->next_sibling) n._root->next_sibling->prev_sibling = n._root->prev_sibling; - else _root->last_child = n._root->prev_sibling; - - if (n._root->prev_sibling) n._root->prev_sibling->next_sibling = n._root->next_sibling; - else _root->first_child = n._root->next_sibling; - - n._root->free(); - } - -#ifndef PUGIXML_NO_STL - std::string xml_node::path(char delimiter) const - { - std::string path; - - xml_node cursor = *this; // Make a copy. - - path = cursor.name(); - - while (cursor.parent()) - { - cursor = cursor.parent(); - - std::string temp = cursor.name(); - temp += delimiter; - temp += path; - path.swap(temp); - } - - return path; - } -#endif - - xml_node xml_node::first_element_by_path(const char* path, char delimiter) const - { - xml_node found = *this; // Current search context. - - if (empty() || !path || !path[0]) return found; - - if (path[0] == delimiter) - { - // Absolute path; e.g. '/foo/bar' - while (found.parent()) found = found.parent(); - ++path; - } - - const char* path_segment = path; - - while (*path_segment == delimiter) ++path_segment; - - const char* path_segment_end = path_segment; - - while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end; - - if (path_segment == path_segment_end) return found; - - const char* next_segment = path_segment_end; - - while (*next_segment == delimiter) ++next_segment; - - if (*path_segment == '.' && path_segment + 1 == path_segment_end) - return found.first_element_by_path(next_segment, delimiter); - else if (*path_segment == '.' && *(path_segment+1) == '.' && path_segment + 2 == path_segment_end) - return found.parent().first_element_by_path(next_segment, delimiter); - else - { - for (xml_node_struct* j = found._root->first_child; j; j = j->next_sibling) - { - if (j->name && !strcmprange(j->name, path_segment, path_segment_end)) - { - xml_node subsearch = xml_node(j).first_element_by_path(next_segment, delimiter); - - if (subsearch) return subsearch; - } - } - - return xml_node(); - } - } - - bool xml_node::traverse(xml_tree_walker& walker) - { - walker._depth = 0; - - if (!walker.begin(*this)) return false; - - xml_node cur = first_child(); - - if (cur) - { - do - { - if (!walker.for_each(cur)) - return false; - - if (cur.first_child()) - { - ++walker._depth; - cur = cur.first_child(); - } - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - // Borland C++ workaround - while (!cur.next_sibling() && cur != *this && (bool)cur.parent()) - { - --walker._depth; - cur = cur.parent(); - } - - if (cur != *this) - cur = cur.next_sibling(); - } - } - while (cur && cur != *this); - } - - if (!walker.end(*this)) return false; - - return true; - } - - unsigned int xml_node::document_order() const - { - return empty() ? 0 : _root->document_order; - } - - void xml_node::precompute_document_order_impl() - { - if (type() != node_document) return; - - unsigned int current = 1; - xml_node cur = *this; - - for (;;) - { - cur._root->document_order = current++; - - for (xml_attribute a = cur.first_attribute(); a; a = a.next_attribute()) - a._attr->document_order = current++; - - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - while (cur && !cur.next_sibling()) cur = cur.parent(); - cur = cur.next_sibling(); - - if (!cur) break; - } - } - } - -#ifndef PUGIXML_NO_STL - void xml_node::print(std::ostream& os, const char* indent, unsigned int flags, unsigned int depth) - { - if (empty()) return; - - if ((flags & format_indent) != 0 && (flags & format_raw) == 0) - for (unsigned int i = 0; i < depth; ++i) os << indent; - - switch (type()) - { - case node_document: - for (xml_node n = first_child(); n; n = n.next_sibling()) - n.print(os, indent, flags, depth); - break; - - case node_element: - { - os << '<' << name(); - - for (xml_attribute a = first_attribute(); a; a = a.next_attribute()) - { - os << ' ' << a.name() << "=\""; - - if (flags & format_utf8) - text_output_escaped<true, true>(os, a.value()); - else - text_output_escaped<true, false>(os, a.value()); - - os << "\""; - } - - if (flags & format_raw) - { - if (!_root->first_child) // 0 children - os << " />"; - else - { - os << ">"; - for (xml_node n = first_child(); n; n = n.next_sibling()) - n.print(os, indent, flags, depth + 1); - os << "</" << name() << ">"; - } - } - else if (!_root->first_child) // 0 children - os << " />\n"; - else if (_root->first_child == _root->last_child && first_child().type() == node_pcdata) - { - os << ">"; - - if (flags & format_utf8) - text_output_escaped<false, true>(os, first_child().value()); - else - text_output_escaped<false, false>(os, first_child().value()); - - os << "</" << name() << ">\n"; - } - else - { - os << ">\n"; - - for (xml_node n = first_child(); n; n = n.next_sibling()) - n.print(os, indent, flags, depth + 1); - - if ((flags & format_indent) != 0 && (flags & format_raw) == 0) - for (unsigned int i = 0; i < depth; ++i) os << indent; - - os << "</" << name() << ">\n"; - } - - break; - } - case node_pcdata: - if (flags & format_utf8) - text_output_escaped<false, true>(os, value()); - else - text_output_escaped<false, false>(os, value()); - break; - - case node_cdata: - os << "<![CDATA[" << value() << "]]>"; - if ((flags & format_raw) == 0) os << "\n"; - break; - - case node_comment: - os << "<!--" << value() << "-->"; - if ((flags & format_raw) == 0) os << "\n"; - break; - - case node_pi: - os << "<?" << name(); - if (value()[0]) os << ' ' << value(); - os << "?>"; - if ((flags & format_raw) == 0) os << "\n"; - break; - - default: - ; - } - } -#endif - -#ifdef __BORLANDC__ - bool operator&&(const xml_node& lhs, bool rhs) - { - return lhs ? rhs : false; - } - - bool operator||(const xml_node& lhs, bool rhs) - { - return lhs ? true : rhs; - } -#endif - - xml_node_iterator::xml_node_iterator() - { - } - - xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node) - { - } - - xml_node_iterator::xml_node_iterator(xml_node_struct* ref): _wrap(ref) - { - } - - xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* prev): _prev(prev), _wrap(ref) - { - } - - bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const - { - return (_wrap == rhs._wrap); - } - - bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const - { - return (_wrap != rhs._wrap); - } - - xml_node& xml_node_iterator::operator*() - { - return _wrap; - } - - xml_node* xml_node_iterator::operator->() - { - return &_wrap; - } - - const xml_node_iterator& xml_node_iterator::operator++() - { - _prev = _wrap; - _wrap = xml_node(_wrap._root->next_sibling); - return *this; - } - - xml_node_iterator xml_node_iterator::operator++(int) - { - xml_node_iterator temp = *this; - ++*this; - return temp; - } - - const xml_node_iterator& xml_node_iterator::operator--() - { - if (_wrap._root) _wrap = xml_node(_wrap._root->prev_sibling); - else _wrap = _prev; - return *this; - } - - xml_node_iterator xml_node_iterator::operator--(int) - { - xml_node_iterator temp = *this; - --*this; - return temp; - } - - xml_attribute_iterator::xml_attribute_iterator() - { - } - - xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr): _wrap(attr) - { - } - - xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref): _wrap(ref) - { - } - - xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_attribute_struct* prev): _prev(prev), _wrap(ref) - { - } - - bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const - { - return (_wrap == rhs._wrap); - } - - bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const - { - return (_wrap != rhs._wrap); - } - - xml_attribute& xml_attribute_iterator::operator*() - { - return _wrap; - } - - xml_attribute* xml_attribute_iterator::operator->() - { - return &_wrap; - } - - const xml_attribute_iterator& xml_attribute_iterator::operator++() - { - _prev = _wrap; - _wrap = xml_attribute(_wrap._attr->next_attribute); - return *this; - } - - xml_attribute_iterator xml_attribute_iterator::operator++(int) - { - xml_attribute_iterator temp = *this; - ++*this; - return temp; - } - - const xml_attribute_iterator& xml_attribute_iterator::operator--() - { - if (_wrap._attr) _wrap = xml_attribute(_wrap._attr->prev_attribute); - else _wrap = _prev; - return *this; - } - - xml_attribute_iterator xml_attribute_iterator::operator--(int) - { - xml_attribute_iterator temp = *this; - --*this; - return temp; - } - - xml_memory_block::xml_memory_block(): next(0), size(0) - { - } - - xml_document::xml_document(): _buffer(0) - { - create(); - } - - xml_document::~xml_document() - { - free(); - } - - void xml_document::create() - { - xml_allocator alloc(&_memory); - - _root = alloc.allocate<xml_document_struct>(); // Allocate a new root. - xml_allocator& a = static_cast<xml_document_struct*>(_root)->allocator; - a = alloc; - } - - void xml_document::free() - { - delete[] _buffer; - _buffer = 0; - - if (_root) _root->free(); - - xml_memory_block* current = _memory.next; - - while (current) - { - xml_memory_block* next = current->next; - delete current; - current = next; - } - - _memory.next = 0; - _memory.size = 0; - - create(); - } - -#ifndef PUGIXML_NO_STL - bool xml_document::load(std::istream& stream, unsigned int options) - { - if (!stream.good()) return false; - - std::streamoff length, pos = stream.tellg(); - stream.seekg(0, std::ios_base::end); - length = stream.tellg(); - stream.seekg(pos, std::ios_base::beg); - - if (!stream.good()) return false; - - char* s; - - try - { - s = new char[length + 1]; - } - catch (const std::bad_alloc&) - { - return false; - } - - stream.read(s, length); - s[length] = 0; - - if (!stream.good()) - { - delete[] s; - return false; - } - - return parse(transfer_ownership_tag(), s, options); // Parse the input string. - } -#endif - - bool xml_document::load(const char* contents, unsigned int options) - { - char* s; - - try - { - s = new char[strlen(contents) + 1]; - } - catch (const std::bad_alloc&) - { - return false; - } - - strcpy(s, contents); - - return parse(transfer_ownership_tag(), s, options); // Parse the input string. - } - - bool xml_document::load_file(const char* name, unsigned int options) - { - FILE* file = fopen(name, "rb"); - if (!file) return false; - - fseek(file, 0, SEEK_END); - long length = ftell(file); - fseek(file, 0, SEEK_SET); - - if (length < 0) - { - fclose(file); - return false; - } - - char* s; - - try - { - s = new char[length + 1]; - } - catch (const std::bad_alloc&) - { - fclose(file); - return false; - } - - size_t read = fread(s, (size_t)length, 1, file); - fclose(file); - - if (read != 1) - { - delete[] s; - return false; - } - - s[length] = 0; - - return parse(transfer_ownership_tag(), s, options); // Parse the input string. - } - - bool xml_document::parse(char* xmlstr, unsigned int options) - { - free(); - - xml_allocator& alloc = static_cast<xml_document_struct*>(_root)->allocator; - - xml_parser parser(alloc); - - return parser.parse(xmlstr, _root, options); // Parse the input string. - } - - bool xml_document::parse(const transfer_ownership_tag&, char* xmlstr, unsigned int options) - { - bool res = parse(xmlstr, options); - - if (res) _buffer = xmlstr; - - return res; - } - -#ifndef PUGIXML_NO_STL - bool xml_document::save_file(const char* name, const char* indent, unsigned int flags) - { - std::ofstream out(name, std::ios::out); - if (!out) return false; - - if (flags & format_write_bom) - { - if (flags & format_utf8) - { - static const unsigned char utf8_bom[] = {0xEF, 0xBB, 0xBF}; - out.write(reinterpret_cast<const char*>(utf8_bom), 3); - } - } - - out << "<?xml version=\"1.0\"?>"; - if (!(flags & format_raw)) out << "\n"; - print(out, indent, flags); - - return true; - } -#endif - - void xml_document::precompute_document_order() - { - precompute_document_order_impl(); - } - -#ifndef PUGIXML_NO_STL - std::string as_utf8(const wchar_t* str) - { - std::string result; - result.reserve(strutf16_utf8_size(str)); - - for (; *str; ++str) - { - char buffer[6]; - - result.append(buffer, strutf16_utf8(buffer, *str)); - } - - return result; - } - - std::wstring as_utf16(const char* str) - { - std::wstring result; - result.reserve(strutf8_utf16_size(str)); - - for (; *str;) - { - unsigned int ch; - str = strutf8_utf16(str, ch); - result += (wchar_t)ch; - } - - return result; - } -#endif -} +}
diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 91e7a5b..5ce3fcd 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -// Pug Improved XML Parser - Version 0.3 +// Pug Improved XML Parser - Version 0.34 // -------------------------------------------------------- // Copyright (C) 2006-2007, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) // This work is based on the pugxml parser, which is: @@ -29,8 +29,8 @@ # endif #endif -#include <cstddef> -#include <cstring> +#include <stddef.h> +#include <string.h> /// The PugiXML Parser namespace. namespace pugi @@ -311,7 +311,11 @@ namespace pugi xml_attribute_struct* _attr; /// \internal Safe bool type +#ifdef __MWERKS__ + typedef bool (xml_attribute::*unspecified_bool_type)() const; +#else typedef xml_attribute_struct* xml_attribute::*unspecified_bool_type; +#endif /// \internal Initializing ctor explicit xml_attribute(xml_attribute_struct* attr); @@ -519,7 +523,11 @@ namespace pugi xml_node_struct* _root; /// \internal Safe bool type +#ifdef __MWERKS__ + typedef bool (xml_node::*unspecified_bool_type)() const; +#else typedef xml_node_struct* xml_node::*unspecified_bool_type; +#endif /// \internal Initializing ctor explicit xml_node(xml_node_struct* p); @@ -1315,7 +1323,7 @@ namespace pugi const xml_document& operator=(const xml_document&); void create(); - void free(); + void destroy(); public: /** diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp index 75b5844..f94cefd 100644 --- a/src/pugixpath.cpp +++ b/src/pugixpath.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////////
//
-// Pug Improved XML Parser - Version 0.3
+// Pug Improved XML Parser - Version 0.34
// --------------------------------------------------------
// Copyright (C) 2006-2007, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
// This work is based on the pugxml parser, which is:
@@ -30,6 +30,17 @@ # pragma warning(disable: 4996) // this function or variable may be unsafe
#endif
+#if defined(_MSC_VER) && _MSC_VER == 1200
+// MSVC6 workaround
+namespace std
+{
+ template <typename T> const T& min(const T& a, const T& b)
+ {
+ return _cpp_min(a, b);
+ }
+}
+#endif
+
namespace
{
using namespace pugi;
@@ -176,7 +187,7 @@ namespace return false;
else // lp is parent, ln & rn are distinct siblings
{
- for (; ln; ln = ln.next_sibling());
+ for (; ln; ln = ln.next_sibling())
if (ln == rn)
return true;
@@ -256,7 +267,7 @@ namespace {
#if defined(__USE_ISOC99)
return isnan(value);
-#elif defined(_MSC_VER) || defined(__BORLANDC__)
+#elif (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__COMO__)
return !!_isnan(value);
#elif FLT_RADIX == 2 && DBL_MAX_EXP == 1024 && DBL_MANT_DIG == 53
// IEEE 754
@@ -275,7 +286,7 @@ namespace {
#if defined(__USE_ISOC99)
return !isfinite(value);
-#elif defined(_MSC_VER) || defined(__BORLANDC__)
+#elif (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__COMO__)
return !_finite(value);
#elif FLT_RADIX == 2 && DBL_MAX_EXP == 1024 && DBL_MANT_DIG == 53
// IEEE 754
@@ -371,7 +382,7 @@ namespace double ieee754_round(double value)
{
- return value == value ? floor(value + 0.5) : value;
+ return is_nan(value) ? value : floor(value + 0.5);
}
const char* local_name(const char* name)
@@ -550,6 +561,8 @@ namespace pugi return block->data;
}
}
+
+ void* node();
};
xpath_node::xpath_node()
@@ -1155,6 +1168,13 @@ namespace pugi nodetest_all,
nodetest_all_in_namespace
};
+
+ template <axis_t N> struct axis_to_type
+ {
+ static const axis_t axis;
+ };
+
+ template <axis_t N> const axis_t axis_to_type<N>::axis = N;
class xpath_ast_node
{
@@ -1181,65 +1201,109 @@ namespace pugi xpath_ast_node(const xpath_ast_node&);
xpath_ast_node& operator=(const xpath_ast_node&);
- template <class Cbool, class Cdouble, class Cstring> bool compare_eq(xpath_ast_node* lhs, xpath_ast_node* rhs, xpath_context& c)
+ template <class Cbool, class Cdouble, class Cstring> struct compare_eq
{
- if (lhs->rettype() != ast_type_node_set && rhs->rettype() != ast_type_node_set)
+ static bool run(xpath_ast_node* lhs, xpath_ast_node* rhs, xpath_context& c)
{
- if (lhs->rettype() == ast_type_boolean || rhs->rettype() == ast_type_boolean)
- return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c));
- else if (lhs->rettype() == ast_type_number || rhs->rettype() == ast_type_number)
- return Cdouble()(lhs->eval_number(c), rhs->eval_number(c));
- else if (lhs->rettype() == ast_type_string || rhs->rettype() == ast_type_string)
- return Cstring()(lhs->eval_string(c), rhs->eval_string(c));
- else
- {
- assert(!"Wrong types");
- return false;
- }
- }
- else if (lhs->rettype() == ast_type_node_set && rhs->rettype() == ast_type_node_set)
- {
- xpath_node_set ls = lhs->eval_node_set(c);
- xpath_node_set rs = rhs->eval_node_set(c);
-
- for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li)
- for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
+ if (lhs->rettype() != ast_type_node_set && rhs->rettype() != ast_type_node_set)
{
- if (Cstring()(string_value(*li), string_value(*ri)))
- return true;
+ if (lhs->rettype() == ast_type_boolean || rhs->rettype() == ast_type_boolean)
+ return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c));
+ else if (lhs->rettype() == ast_type_number || rhs->rettype() == ast_type_number)
+ return Cdouble()(lhs->eval_number(c), rhs->eval_number(c));
+ else if (lhs->rettype() == ast_type_string || rhs->rettype() == ast_type_string)
+ return Cstring()(lhs->eval_string(c), rhs->eval_string(c));
+ else
+ {
+ assert(!"Wrong types");
+ return false;
+ }
}
-
- return false;
- }
- else if (lhs->rettype() != ast_type_node_set && rhs->rettype() == ast_type_node_set)
- {
- if (lhs->rettype() == ast_type_boolean)
- return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c));
- else if (lhs->rettype() == ast_type_number)
+ else if (lhs->rettype() == ast_type_node_set && rhs->rettype() == ast_type_node_set)
{
- double l = lhs->eval_number(c);
+ xpath_node_set ls = lhs->eval_node_set(c);
xpath_node_set rs = rhs->eval_node_set(c);
+ for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li)
for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
{
- if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true)
+ if (Cstring()(string_value(*li), string_value(*ri)))
return true;
}
return false;
}
- else if (lhs->rettype() == ast_type_string)
+ else if (lhs->rettype() != ast_type_node_set && rhs->rettype() == ast_type_node_set)
{
- std::string l = lhs->eval_string(c);
- xpath_node_set rs = rhs->eval_node_set(c);
+ if (lhs->rettype() == ast_type_boolean)
+ return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c));
+ else if (lhs->rettype() == ast_type_number)
+ {
+ double l = lhs->eval_number(c);
+ xpath_node_set rs = rhs->eval_node_set(c);
+
+ for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
+ {
+ if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true)
+ return true;
+ }
+
+ return false;
+ }
+ else if (lhs->rettype() == ast_type_string)
+ {
+ std::string l = lhs->eval_string(c);
+ xpath_node_set rs = rhs->eval_node_set(c);
- for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
+ for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
+ {
+ if (Cstring()(l, string_value(*ri)) == true)
+ return true;
+ }
+
+ return false;
+ }
+ else
{
- if (Cstring()(l, string_value(*ri)) == true)
- return true;
+ assert(!"Wrong types");
+ return false;
+ }
+ }
+ else if (lhs->rettype() == ast_type_node_set && rhs->rettype() != ast_type_node_set)
+ {
+ if (rhs->rettype() == ast_type_boolean)
+ return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c));
+ else if (rhs->rettype() == ast_type_number)
+ {
+ xpath_node_set ls = lhs->eval_node_set(c);
+ double r = rhs->eval_number(c);
+
+ for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li)
+ {
+ if (Cdouble()(convert_string_to_number(string_value(*li).c_str()), r) == true)
+ return true;
+ }
+
+ return false;
+ }
+ else if (rhs->rettype() == ast_type_string)
+ {
+ xpath_node_set ls = lhs->eval_node_set(c);
+ std::string r = rhs->eval_string(c);
+
+ for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li)
+ {
+ if (Cstring()(string_value(*li), r) == true)
+ return true;
+ }
+
+ return false;
+ }
+ else
+ {
+ assert(!"Wrong types");
+ return false;
}
-
- return false;
}
else
{
@@ -1247,31 +1311,53 @@ namespace pugi return false;
}
}
- else if (lhs->rettype() == ast_type_node_set && rhs->rettype() != ast_type_node_set)
+ };
+
+ template <class Cdouble> struct compare_rel
+ {
+ static bool run(xpath_ast_node* lhs, xpath_ast_node* rhs, xpath_context& c)
{
- if (rhs->rettype() == ast_type_boolean)
- return Cbool()(lhs->eval_boolean(c), rhs->eval_boolean(c));
- else if (rhs->rettype() == ast_type_number)
+ if (lhs->rettype() != ast_type_node_set && rhs->rettype() != ast_type_node_set)
+ return Cdouble()(lhs->eval_number(c), rhs->eval_number(c));
+ else if (lhs->rettype() == ast_type_node_set && rhs->rettype() == ast_type_node_set)
{
xpath_node_set ls = lhs->eval_node_set(c);
- double r = rhs->eval_number(c);
-
+ xpath_node_set rs = rhs->eval_node_set(c);
+
for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li)
{
- if (Cdouble()(convert_string_to_number(string_value(*li).c_str()), r) == true)
+ double l = convert_string_to_number(string_value(*li).c_str());
+
+ for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
+ {
+ if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true)
+ return true;
+ }
+ }
+
+ return false;
+ }
+ else if (lhs->rettype() != ast_type_node_set && rhs->rettype() == ast_type_node_set)
+ {
+ double l = lhs->eval_number(c);
+ xpath_node_set rs = rhs->eval_node_set(c);
+
+ for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
+ {
+ if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true)
return true;
}
return false;
}
- else if (rhs->rettype() == ast_type_string)
+ else if (lhs->rettype() == ast_type_node_set && rhs->rettype() != ast_type_node_set)
{
xpath_node_set ls = lhs->eval_node_set(c);
- std::string r = rhs->eval_string(c);
+ double r = rhs->eval_number(c);
for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li)
{
- if (Cstring()(string_value(*li), r) == true)
+ if (Cdouble()(convert_string_to_number(string_value(*li).c_str()), r) == true)
return true;
}
@@ -1283,68 +1369,8 @@ namespace pugi return false;
}
}
- else
- {
- assert(!"Wrong types");
- return false;
- }
- }
-
- template <class Cdouble> bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, xpath_context& c)
- {
- if (lhs->rettype() != ast_type_node_set && rhs->rettype() != ast_type_node_set)
- return Cdouble()(lhs->eval_number(c), rhs->eval_number(c));
- else if (lhs->rettype() == ast_type_node_set && rhs->rettype() == ast_type_node_set)
- {
- xpath_node_set ls = lhs->eval_node_set(c);
- xpath_node_set rs = rhs->eval_node_set(c);
-
- for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li)
- {
- double l = convert_string_to_number(string_value(*li).c_str());
-
- for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
- {
- if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true)
- return true;
- }
- }
-
- return false;
- }
- else if (lhs->rettype() != ast_type_node_set && rhs->rettype() == ast_type_node_set)
- {
- double l = lhs->eval_number(c);
- xpath_node_set rs = rhs->eval_node_set(c);
-
- for (xpath_node_set::const_iterator ri = rs.begin(); ri != rs.end(); ++ri)
- {
- if (Cdouble()(l, convert_string_to_number(string_value(*ri).c_str())) == true)
- return true;
- }
-
- return false;
- }
- else if (lhs->rettype() == ast_type_node_set && rhs->rettype() != ast_type_node_set)
- {
- xpath_node_set ls = lhs->eval_node_set(c);
- double r = rhs->eval_number(c);
+ };
- for (xpath_node_set::const_iterator li = ls.begin(); li != ls.end(); ++li)
- {
- if (Cdouble()(convert_string_to_number(string_value(*li).c_str()), r) == true)
- return true;
- }
-
- return false;
- }
- else
- {
- assert(!"Wrong types");
- return false;
- }
- }
-
void apply_predicate(xpath_node_set& ns, size_t first, xpath_ast_node* expr, const xpath_context& context)
{
xpath_context c;
@@ -1456,25 +1482,31 @@ namespace pugi }
}
- template <axis_t axis> void step_fill(xpath_node_set& ns, const xml_node& n)
+ template <class T> void step_fill(xpath_node_set& ns, const xml_node& n, T)
{
+ const axis_t axis = T::axis;
+
switch (axis)
{
case axis_attribute:
+ {
ns.m_type = ns.empty() ? xpath_node_set::type_sorted : xpath_node_set::type_unsorted;
for (xml_attribute a = n.first_attribute(); a; a = a.next_attribute())
step_push(ns, a, n);
break;
+ }
case axis_child:
+ {
ns.m_type = ns.empty() ? xpath_node_set::type_sorted : xpath_node_set::type_unsorted;
for (xml_node c = n.first_child(); c; c = c.next_sibling())
step_push(ns, c);
break;
+ }
case axis_descendant:
case axis_descendant_or_self:
@@ -1513,20 +1545,24 @@ namespace pugi }
case axis_following_sibling:
+ {
ns.m_type = ns.empty() ? xpath_node_set::type_sorted : xpath_node_set::type_unsorted;
for (xml_node c = n.next_sibling(); c; c = c.next_sibling())
step_push(ns, c);
break;
+ }
case axis_preceding_sibling:
+ {
ns.m_type = ns.empty() ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_unsorted;
for (xml_node c = n.previous_sibling(); c; c = c.previous_sibling())
step_push(ns, c);
break;
+ }
case axis_following:
{
@@ -1623,8 +1659,10 @@ namespace pugi }
}
- template <axis_t axis> void step_fill(xpath_node_set& ns, const xml_attribute& a, const xml_node& p)
+ template <class T> void step_fill(xpath_node_set& ns, const xml_attribute& a, const xml_node& p, T)
{
+ const axis_t axis = T::axis;
+
switch (axis)
{
case axis_ancestor:
@@ -1652,8 +1690,10 @@ namespace pugi }
}
- template <axis_t axis> void step_do(xpath_node_set& ns, xpath_context& c)
+ template <class T> void step_do(xpath_node_set& ns, xpath_context& c, T v)
{
+ const axis_t axis = T::axis;
+
switch (axis)
{
case axis_parent:
@@ -1726,17 +1766,17 @@ namespace pugi size_t s = ns.size();
if (it->node())
- step_fill<axis>(ns, it->node());
+ step_fill(ns, it->node(), v);
else
- step_fill<axis>(ns, it->attribute(), it->parent());
+ step_fill(ns, it->attribute(), it->parent(), v);
apply_predicates(ns, s, c);
}
}
else
{
- if (c.n.node()) step_fill<axis>(ns, c.n.node());
- else step_fill<axis>(ns, c.n.attribute(), c.n.parent());
+ if (c.n.node()) step_fill(ns, c.n.node(), v);
+ else step_fill(ns, c.n.attribute(), c.n.parent(), v);
apply_predicates(ns, 0, c);
}
@@ -1760,14 +1800,14 @@ namespace pugi size_t s = ns.size();
if (it->node())
- step_fill<axis>(ns, it->node());
+ step_fill(ns, it->node(), v);
apply_predicates(ns, s, c);
}
}
else if (c.n.node())
{
- step_fill<axis>(ns, c.n.node());
+ step_fill(ns, c.n.node(), v);
apply_predicates(ns, 0, c);
}
@@ -1836,22 +1876,22 @@ namespace pugi else return m_right->eval_boolean(c);
case ast_op_equal:
- return compare_eq<equal_to<bool>, equal_to<double>, equal_to<std::string> >(m_left, m_right, c);
+ return compare_eq<equal_to<bool>, equal_to<double>, equal_to<std::string> >::run(m_left, m_right, c);
case ast_op_not_equal:
- return compare_eq<not_equal_to<bool>, not_equal_to<double>, not_equal_to<std::string> >(m_left, m_right, c);
+ return compare_eq<not_equal_to<bool>, not_equal_to<double>, not_equal_to<std::string> >::run(m_left, m_right, c);
case ast_op_less:
- return compare_rel<less<double> >(m_left, m_right, c);
+ return compare_rel<less<double> >::run(m_left, m_right, c);
case ast_op_greater:
- return compare_rel<greater<double> >(m_left, m_right, c);
+ return compare_rel<greater<double> >::run(m_left, m_right, c);
case ast_op_less_or_equal:
- return compare_rel<less_equal<double> >(m_left, m_right, c);
+ return compare_rel<less_equal<double> >::run(m_left, m_right, c);
case ast_op_greater_or_equal:
- return compare_rel<greater_equal<double> >(m_left, m_right, c);
+ return compare_rel<greater_equal<double> >::run(m_left, m_right, c);
case ast_func_starts_with:
return starts_with(m_left->eval_string(c), m_right->eval_string(c).c_str());
@@ -2125,7 +2165,7 @@ namespace pugi std::string s = m_left->eval_string(c);
double first = ieee754_round(m_right->eval_number(c));
- if (first != first) return ""; // NaN
+ if (is_nan(first)) return ""; // NaN
else if (first >= s.length() + 1) return "";
size_t pos = first < 1 ? 1 : (size_t)first;
@@ -2139,7 +2179,7 @@ namespace pugi double first = ieee754_round(m_right->eval_number(c));
double last = first + ieee754_round(m_third->eval_number(c));
- if (first != first || last != last) return "";
+ if (is_nan(first) || is_nan(last)) return "";
else if (first >= s.length() + 1) return "";
else if (first >= last) return "";
@@ -2305,55 +2345,55 @@ namespace pugi switch (m_axis)
{
case axis_ancestor:
- step_do<axis_ancestor>(ns, c);
+ step_do(ns, c, axis_to_type<axis_ancestor>());
break;
case axis_ancestor_or_self:
- step_do<axis_ancestor_or_self>(ns, c);
+ step_do(ns, c, axis_to_type<axis_ancestor_or_self>());
break;
case axis_attribute:
- step_do<axis_attribute>(ns, c);
+ step_do(ns, c, axis_to_type<axis_attribute>());
break;
case axis_child:
- step_do<axis_child>(ns, c);
+ step_do(ns, c, axis_to_type<axis_child>());
break;
case axis_descendant:
- step_do<axis_descendant>(ns, c);
+ step_do(ns, c, axis_to_type<axis_descendant>());
break;
case axis_descendant_or_self:
- step_do<axis_descendant_or_self>(ns, c);
+ step_do(ns, c, axis_to_type<axis_descendant_or_self>());
break;
case axis_following:
- step_do<axis_following>(ns, c);
+ step_do(ns, c, axis_to_type<axis_following>());
break;
case axis_following_sibling:
- step_do<axis_following_sibling>(ns, c);
+ step_do(ns, c, axis_to_type<axis_following_sibling>());
break;
case axis_namespace:
- step_do<axis_namespace>(ns, c);
+ step_do(ns, c, axis_to_type<axis_namespace>());
break;
case axis_parent:
- step_do<axis_parent>(ns, c);
+ step_do(ns, c, axis_to_type<axis_parent>());
break;
case axis_preceding:
- step_do<axis_preceding>(ns, c);
+ step_do(ns, c, axis_to_type<axis_preceding>());
break;
case axis_preceding_sibling:
- step_do<axis_preceding_sibling>(ns, c);
+ step_do(ns, c, axis_to_type<axis_preceding_sibling>());
break;
case axis_self:
- step_do<axis_self>(ns, c);
+ step_do(ns, c, axis_to_type<axis_self>());
break;
default:
@@ -2434,13 +2474,15 @@ namespace pugi return false;
case ast_func_concat:
+ {
if (m_left->contains(type)) return true;
for (xpath_ast_node* n = m_right; n; n = n->m_next)
if (n->contains(type)) return true;
return false;
-
+ }
+
case ast_func_starts_with:
case ast_func_contains:
case ast_func_substring_before:
@@ -2475,6 +2517,9 @@ namespace pugi default:
throw xpath_exception("Unknown semantics error");
+#ifdef __DMC__
+ return false; // Digital Mars C++
+#endif
}
}
@@ -2585,6 +2630,7 @@ namespace pugi break;
case ast_func_concat:
+ {
m_left->check_semantics();
for (xpath_ast_node* n = m_right; n; n = n->m_next)
@@ -2592,7 +2638,8 @@ namespace pugi m_rettype = ast_type_string;
break;
-
+ }
+
case ast_func_starts_with:
case ast_func_contains:
m_left->check_semantics();
@@ -2653,8 +2700,9 @@ namespace pugi if (m_left) m_left->check_semantics();
m_rettype = ast_type_number;
break;
-
+
case ast_step:
+ {
if (m_left)
{
m_left->check_semantics();
@@ -2667,6 +2715,7 @@ namespace pugi m_rettype = ast_type_node_set;
break;
+ }
case ast_step_root:
m_rettype = ast_type_node_set;
@@ -2681,17 +2730,13 @@ namespace pugi {
return m_rettype;
}
-
- void* operator new(size_t size, xpath_allocator& a)
- {
- return a.alloc(size);
- }
-
- void operator delete(void*, xpath_allocator&)
- {
- }
};
+ void* xpath_allocator::node()
+ {
+ return alloc(sizeof(xpath_ast_node));
+ }
+
class xpath_parser
{
private:
@@ -2713,7 +2758,7 @@ namespace pugi if (m_lexer.current() != lex_string)
throw xpath_exception("incorrect variable reference");
- xpath_ast_node* n = new (m_alloc) xpath_ast_node(ast_variable, m_lexer.contents(), m_alloc);
+ xpath_ast_node* n = new (m_alloc.node()) xpath_ast_node(ast_variable, m_lexer.contents(), m_alloc);
m_lexer.next();
return n;
@@ -2735,7 +2780,7 @@ namespace pugi case lex_quoted_string:
{
- xpath_ast_node* n = new (m_alloc) xpath_ast_node(ast_string_constant, m_lexer.contents(), m_alloc);
+ xpath_ast_node* n = new (m_alloc.node()) xpath_ast_node(ast_string_constant, m_lexer.contents(), m_alloc);
m_lexer.next();
return n;
@@ -2743,7 +2788,7 @@ namespace pugi case lex_number:
{
- xpath_ast_node* n = new (m_alloc) xpath_ast_node(ast_number_constant, m_lexer.contents(), m_alloc);
+ xpath_ast_node* n = new (m_alloc.node()) xpath_ast_node(ast_number_constant, m_lexer.contents(), m_alloc);
m_lexer.next();
return n;
@@ -2813,7 +2858,7 @@ namespace pugi else if (function == "concat" && argc == 2)
{
// set_next was done earlier
- return new (m_alloc) xpath_ast_node(ast_func_concat, args[0], args[1]);
+ return new (m_alloc.node()) xpath_ast_node(ast_func_concat, args[0], args[1]);
}
else if (function == "ceiling" && argc == 1)
type = ast_func_ceiling;
@@ -2919,10 +2964,10 @@ namespace pugi {
switch (argc)
{
- case 0: return new (m_alloc) xpath_ast_node(type);
- case 1: return new (m_alloc) xpath_ast_node(type, args[0]);
- case 2: return new (m_alloc) xpath_ast_node(type, args[0], args[1]);
- case 3: return new (m_alloc) xpath_ast_node(type, args[0], args[1], args[2]);
+ case 0: return new (m_alloc.node()) xpath_ast_node(type);
+ case 1: return new (m_alloc.node()) xpath_ast_node(type, args[0]);
+ case 2: return new (m_alloc.node()) xpath_ast_node(type, args[0], args[1]);
+ case 3: return new (m_alloc.node()) xpath_ast_node(type, args[0], args[1], args[2]);
}
}
@@ -2931,6 +2976,9 @@ namespace pugi default:
throw xpath_exception("unrecognizable primary expression");
+#ifdef __DMC__
+ return 0; // Digital Mars C++
+#endif
}
}
@@ -2945,7 +2993,7 @@ namespace pugi {
m_lexer.next();
- n = new (m_alloc) xpath_ast_node(ast_filter, n, parse_expression(), axis_child);
+ n = new (m_alloc.node()) xpath_ast_node(ast_filter, n, parse_expression(), axis_child);
if (m_lexer.current() != lex_close_square_brace)
throw xpath_exception("Unmatched square brace");
@@ -2975,13 +3023,13 @@ namespace pugi {
m_lexer.next();
- return new (m_alloc) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0, m_alloc);
+ return new (m_alloc.node()) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0, m_alloc);
}
else if (m_lexer.current() == lex_double_dot)
{
m_lexer.next();
- return new (m_alloc) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0, m_alloc);
+ return new (m_alloc.node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0, m_alloc);
}
else // implied child axis
axis = axis_child;
@@ -3104,7 +3152,7 @@ namespace pugi else
throw xpath_exception("Unrecognized node type");
- nt_name.clear();
+ nt_name.erase(nt_name.begin(), nt_name.end());
}
else if (nt_name == "processing-instruction")
{
@@ -3150,7 +3198,7 @@ namespace pugi }
else throw xpath_exception("Unrecognized node test");
- xpath_ast_node* n = new (m_alloc) xpath_ast_node(ast_step, set, axis, nt_type, nt_name.c_str(), m_alloc);
+ xpath_ast_node* n = new (m_alloc.node()) xpath_ast_node(ast_step, set, axis, nt_type, nt_name.c_str(), m_alloc);
xpath_ast_node* last = 0;
@@ -3158,7 +3206,7 @@ namespace pugi {
m_lexer.next();
- xpath_ast_node* pred = new (m_alloc) xpath_ast_node(ast_predicate, parse_expression(), 0, axis);
+ xpath_ast_node* pred = new (m_alloc.node()) xpath_ast_node(ast_predicate, parse_expression(), 0, axis);
if (m_lexer.current() != lex_close_square_brace)
throw xpath_exception("unmatched square brace");
@@ -3184,7 +3232,7 @@ namespace pugi m_lexer.next();
if (l == lex_double_slash)
- n = new (m_alloc) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0, m_alloc);
+ n = new (m_alloc.node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0, m_alloc);
n = parse_step(n);
}
@@ -3203,7 +3251,7 @@ namespace pugi m_lexer.next();
- xpath_ast_node* n = new (m_alloc) xpath_ast_node(ast_step_root);
+ xpath_ast_node* n = new (m_alloc.node()) xpath_ast_node(ast_step_root);
try
{
@@ -3220,8 +3268,8 @@ namespace pugi {
m_lexer.next();
- xpath_ast_node* n = new (m_alloc) xpath_ast_node(ast_step_root);
- n = new (m_alloc) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0, m_alloc);
+ xpath_ast_node* n = new (m_alloc.node()) xpath_ast_node(ast_step_root);
+ n = new (m_alloc.node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0, m_alloc);
return parse_relative_location_path(n);
}
@@ -3266,7 +3314,7 @@ namespace pugi m_lexer.next();
if (l == lex_double_slash)
- n = new (m_alloc) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0, m_alloc);
+ n = new (m_alloc.node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0, m_alloc);
// select from location path
return parse_relative_location_path(n);
@@ -3286,7 +3334,7 @@ namespace pugi {
m_lexer.next();
- n = new (m_alloc) xpath_ast_node(ast_op_union, n, parse_union_expression());
+ n = new (m_alloc.node()) xpath_ast_node(ast_op_union, n, parse_union_expression());
}
return n;
@@ -3299,7 +3347,7 @@ namespace pugi {
m_lexer.next();
- return new (m_alloc) xpath_ast_node(ast_op_negate, parse_unary_expression());
+ return new (m_alloc.node()) xpath_ast_node(ast_op_negate, parse_unary_expression());
}
else return parse_union_expression();
}
@@ -3319,7 +3367,7 @@ namespace pugi !strcmp(m_lexer.contents(), "div") ? ast_op_divide : ast_op_mod;
m_lexer.next();
- n = new (m_alloc) xpath_ast_node(op, n, parse_unary_expression());
+ n = new (m_alloc.node()) xpath_ast_node(op, n, parse_unary_expression());
}
return n;
@@ -3338,7 +3386,7 @@ namespace pugi m_lexer.next();
- n = new (m_alloc) xpath_ast_node(l == lex_plus ? ast_op_add : ast_op_subtract, n, parse_multiplicative_expression());
+ n = new (m_alloc.node()) xpath_ast_node(l == lex_plus ? ast_op_add : ast_op_subtract, n, parse_multiplicative_expression());
}
return n;
@@ -3359,7 +3407,7 @@ namespace pugi lexeme_t l = m_lexer.current();
m_lexer.next();
- n = new (m_alloc) xpath_ast_node(l == lex_less ? ast_op_less : l == lex_greater ? ast_op_greater :
+ n = new (m_alloc.node()) xpath_ast_node(l == lex_less ? ast_op_less : l == lex_greater ? ast_op_greater :
l == lex_less_or_equal ? ast_op_less_or_equal : ast_op_greater_or_equal,
n, parse_additive_expression());
}
@@ -3380,7 +3428,7 @@ namespace pugi m_lexer.next();
- n = new (m_alloc) xpath_ast_node(l == lex_equal ? ast_op_equal : ast_op_not_equal, n, parse_relational_expression());
+ n = new (m_alloc.node()) xpath_ast_node(l == lex_equal ? ast_op_equal : ast_op_not_equal, n, parse_relational_expression());
}
return n;
@@ -3395,7 +3443,7 @@ namespace pugi {
m_lexer.next();
- n = new (m_alloc) xpath_ast_node(ast_op_and, n, parse_equality_expression());
+ n = new (m_alloc.node()) xpath_ast_node(ast_op_and, n, parse_equality_expression());
}
return n;
@@ -3410,7 +3458,7 @@ namespace pugi {
m_lexer.next();
- n = new (m_alloc) xpath_ast_node(ast_op_or, n, parse_and_expression());
+ n = new (m_alloc.node()) xpath_ast_node(ast_op_or, n, parse_and_expression());
}
return n;
|