diff options
| author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-01-16 21:48:50 -0800 | 
|---|---|---|
| committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-01-16 21:48:50 -0800 | 
| commit | e5ecbd63ce75de0a8f1473cbe0c1f9eea657dd02 (patch) | |
| tree | 8ace0fd644cc3c8274c1e74f2b0743d21a957441 | |
| parent | 93c3ab46494f35c390b40220519d83634e4e347f (diff) | |
| parent | 8e95f0d88947631162f5ed1fc5427b414425604b (diff) | |
Merge branch 'master' into compact
| -rw-r--r-- | docs/manual.qbk | 8 | ||||
| -rw-r--r-- | src/pugiconfig.hpp | 1 | ||||
| -rw-r--r-- | src/pugixml.cpp | 45 | ||||
| -rw-r--r-- | src/pugixml.hpp | 13 | ||||
| -rw-r--r-- | tests/test_document.cpp | 2 | ||||
| -rw-r--r-- | tests/test_dom_modify.cpp | 98 | ||||
| -rw-r--r-- | tests/test_dom_text.cpp | 14 | ||||
| -rw-r--r-- | tests/test_header_only.cpp | 16 | 
8 files changed, 170 insertions, 27 deletions
diff --git a/docs/manual.qbk b/docs/manual.qbk index 20305cf..f0ee852 100644 --- a/docs/manual.qbk +++ b/docs/manual.qbk @@ -1190,6 +1190,7 @@ In addition to string functions, several functions are provided for handling att      bool xml_attribute::set_value(int rhs);      bool xml_attribute::set_value(unsigned int rhs);      bool xml_attribute::set_value(double rhs); +    bool xml_attribute::set_value(float rhs);      bool xml_attribute::set_value(bool rhs);      bool xml_attribute::set_value(long long rhs);      bool xml_attribute::set_value(unsigned long long rhs); @@ -1208,6 +1209,7 @@ For convenience, all `set_value` functions have the corresponding assignment ope      xml_attribute& xml_attribute::operator=(int rhs);      xml_attribute& xml_attribute::operator=(unsigned int rhs);      xml_attribute& xml_attribute::operator=(double rhs); +    xml_attribute& xml_attribute::operator=(float rhs);      xml_attribute& xml_attribute::operator=(bool rhs);      xml_attribute& xml_attribute::operator=(long long rhs);      xml_attribute& xml_attribute::operator=(unsigned long long rhs); @@ -1312,6 +1314,7 @@ In addition to a string function, several functions are provided for handling te      bool xml_text::set(int rhs);      bool xml_text::set(unsigned int rhs);      bool xml_text::set(double rhs); +    bool xml_text::set(float rhs);      bool xml_text::set(bool rhs);      bool xml_text::set(long long rhs);      bool xml_text::set(unsigned long long rhs); @@ -1326,6 +1329,7 @@ For convenience, all `set` functions have the corresponding assignment operators      xml_text& xml_text::operator=(int rhs);      xml_text& xml_text::operator=(unsigned int rhs);      xml_text& xml_text::operator=(double rhs); +    xml_text& xml_text::operator=(float rhs);      xml_text& xml_text::operator=(bool rhs);      xml_text& xml_text::operator=(long long rhs);      xml_text& xml_text::operator=(unsigned long long rhs); @@ -2369,6 +2373,7 @@ Classes:      * `bool `[link xml_attribute::set_value set_value]`(int rhs);`      * `bool `[link xml_attribute::set_value set_value]`(unsigned int rhs);`      * `bool `[link xml_attribute::set_value set_value]`(double rhs);` +    * `bool `[link xml_attribute::set_value set_value]`(float rhs);`      * `bool `[link xml_attribute::set_value set_value]`(bool rhs);`      * `bool `[link xml_attribute::set_value set_value]`(long long rhs);`      * `bool `[link xml_attribute::set_value set_value]`(unsigned long long rhs);` @@ -2378,6 +2383,7 @@ Classes:      * `xml_attribute& `[link xml_attribute::assign operator=]`(int rhs);`      * `xml_attribute& `[link xml_attribute::assign operator=]`(unsigned int rhs);`      * `xml_attribute& `[link xml_attribute::assign operator=]`(double rhs);` +    * `xml_attribute& `[link xml_attribute::assign operator=]`(float rhs);`      * `xml_attribute& `[link xml_attribute::assign operator=]`(bool rhs);`      * `xml_attribute& `[link xml_attribute::assign operator=]`(long long rhs);`      * `xml_attribute& `[link xml_attribute::assign operator=]`(unsnigned long long rhs);` @@ -2608,6 +2614,7 @@ Classes:      * `bool `[link xml_text::set set]`(int rhs);`      * `bool `[link xml_text::set set]`(unsigned int rhs);`      * `bool `[link xml_text::set set]`(double rhs);` +    * `bool `[link xml_text::set set]`(float rhs);`      * `bool `[link xml_text::set set]`(bool rhs);`      * `bool `[link xml_text::set set]`(long long rhs);`      * `bool `[link xml_text::set set]`(unsigned long long rhs);` @@ -2617,6 +2624,7 @@ Classes:      * `xml_text& `[link xml_text::assign operator=]`(int rhs);`      * `xml_text& `[link xml_text::assign operator=]`(unsigned int rhs);`      * `xml_text& `[link xml_text::assign operator=]`(double rhs);` +    * `xml_text& `[link xml_text::assign operator=]`(float rhs);`      * `xml_text& `[link xml_text::assign operator=]`(bool rhs);`      * `xml_text& `[link xml_text::assign operator=]`(long long rhs);`      * `xml_text& `[link xml_text::assign operator=]`(unsigned long long rhs);` diff --git a/src/pugiconfig.hpp b/src/pugiconfig.hpp index 1c216e3..6219dbe 100644 --- a/src/pugiconfig.hpp +++ b/src/pugiconfig.hpp @@ -39,7 +39,6 @@  // Uncomment this to switch to header-only version  // #define PUGIXML_HEADER_ONLY -// #include "pugixml.cpp"  // Uncomment this to enable long long support  // #define PUGIXML_HAS_LONG_LONG diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 52ddf4c..7d53832 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -4504,10 +4504,19 @@ PUGI__NS_BEGIN  	}  	template <typename String, typename Header> +	PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value) +	{ +		char buf[128]; +		sprintf(buf, "%.9g", value); + +		return set_value_buffer(dest, header, header_mask, buf); +	} + +	template <typename String, typename Header>  	PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value)  	{  		char buf[128]; -		sprintf(buf, "%g", value); +		sprintf(buf, "%.17g", value);  		return set_value_buffer(dest, header, header_mask, buf);  	} @@ -4548,7 +4557,7 @@ PUGI__NS_BEGIN  		_fseeki64(file, 0, SEEK_END);  		length_type length = _ftelli64(file);  		_fseeki64(file, 0, SEEK_SET); -	#elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && !(defined(__STRICT_ANSI__) && __GNUC__ * 100 + __GNUC_MINOR__ <= 405) +	#elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))  		// there are 64-bit versions of fseek/ftell, let's use them  		typedef off64_t length_type; @@ -4793,7 +4802,7 @@ PUGI__NS_BEGIN  	}  #endif -#if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && !(defined(__STRICT_ANSI__) && __GNUC__ * 100 + __GNUC_MINOR__ <= 405)) +#if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR)))  	PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode)  	{  		return _wfopen(path, mode); @@ -5112,6 +5121,12 @@ namespace pugi  		return *this;  	} +	PUGI__FN xml_attribute& xml_attribute::operator=(float rhs) +	{ +		set_value(rhs); +		return *this; +	} +  	PUGI__FN xml_attribute& xml_attribute::operator=(bool rhs)  	{  		set_value(rhs); @@ -5167,6 +5182,13 @@ namespace pugi  		return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);  	} +	PUGI__FN bool xml_attribute::set_value(float rhs) +	{ +		if (!_attr) return false; + +		return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); +	} +  	PUGI__FN bool xml_attribute::set_value(bool rhs)  	{  		if (!_attr) return false; @@ -6224,6 +6246,13 @@ namespace pugi  		return dn ? impl::set_value_convert(dn->contents, dn->header, impl::xml_memory_page_contents_allocated_mask, rhs) : false;  	} +	PUGI__FN bool xml_text::set(float rhs) +	{ +		xml_node_struct* dn = _data_new(); + +		return dn ? impl::set_value_convert(dn->contents, dn->header, impl::xml_memory_page_contents_allocated_mask, rhs) : false; +	} +  	PUGI__FN bool xml_text::set(double rhs)  	{  		xml_node_struct* dn = _data_new(); @@ -6278,6 +6307,12 @@ namespace pugi  		return *this;  	} +	PUGI__FN xml_text& xml_text::operator=(float rhs) +	{ +		set(rhs); +		return *this; +	} +  	PUGI__FN xml_text& xml_text::operator=(bool rhs)  	{  		set(rhs); @@ -9272,7 +9307,7 @@ PUGI__NS_BEGIN  		bool step_push(xpath_node_set_raw& ns, xml_attribute_struct* a, xml_node_struct* parent, xpath_allocator* alloc)  		{ -            assert(a); +			assert(a);  			const char_t* name = a->name ? a->name + 0 : PUGIXML_TEXT(""); @@ -9312,7 +9347,7 @@ PUGI__NS_BEGIN  		bool step_push(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc)  		{ -            assert(n); +			assert(n);  			xml_node_type type = PUGI__NODETYPE(n); diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 917ef4a..9798b46 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -352,6 +352,7 @@ namespace pugi  		bool set_value(int rhs);  		bool set_value(unsigned int rhs);  		bool set_value(double rhs); +		bool set_value(float rhs);  		bool set_value(bool rhs);  	#ifdef PUGIXML_HAS_LONG_LONG @@ -364,6 +365,7 @@ namespace pugi  		xml_attribute& operator=(int rhs);  		xml_attribute& operator=(unsigned int rhs);  		xml_attribute& operator=(double rhs); +		xml_attribute& operator=(float rhs);  		xml_attribute& operator=(bool rhs);  	#ifdef PUGIXML_HAS_LONG_LONG @@ -431,7 +433,7 @@ namespace pugi  		const char_t* name() const;  		// Get node value, or "" if node is empty or it has no value -        // Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. +		// Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes.  		const char_t* value() const;  		// Get attribute list @@ -694,6 +696,7 @@ namespace pugi  		bool set(int rhs);  		bool set(unsigned int rhs);  		bool set(double rhs); +		bool set(float rhs);  		bool set(bool rhs);  	#ifdef PUGIXML_HAS_LONG_LONG @@ -706,6 +709,7 @@ namespace pugi  		xml_text& operator=(int rhs);  		xml_text& operator=(unsigned int rhs);  		xml_text& operator=(double rhs); +		xml_text& operator=(float rhs);  		xml_text& operator=(bool rhs);  	#ifdef PUGIXML_HAS_LONG_LONG @@ -1329,6 +1333,13 @@ namespace std  #endif +// Make sure implementation is included in header-only mode +// Use macro expansion in #include to work around QMake (QTBUG-11923) +#if defined(PUGIXML_HEADER_ONLY) && !defined(PUGIXML_SOURCE) +#	define PUGIXML_SOURCE "pugixml.cpp" +#	include PUGIXML_SOURCE +#endif +  /**   * Copyright (c) 2006-2014 Arseny Kapoulkine   * diff --git a/tests/test_document.cpp b/tests/test_document.cpp index f57465f..ebcdcd1 100644 --- a/tests/test_document.cpp +++ b/tests/test_document.cpp @@ -323,7 +323,7 @@ TEST(document_load_file_wide_ascii)  	CHECK_NODE(doc, STR("<node />"));  } -#if !defined(__DMC__) && !defined(__MWERKS__) && !(defined(__MINGW32__) && defined(__STRICT_ANSI__) && __GNUC__ * 100 + __GNUC_MINOR__ <= 405) +#if !defined(__DMC__) && !defined(__MWERKS__) && !(defined(__MINGW32__) && defined(__STRICT_ANSI__) && !defined(__MINGW64_VERSION_MAJOR))  TEST(document_load_file_wide_unicode)  {  	pugi::xml_document doc; diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index 9c9109b..f8a8b2f 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -2,6 +2,7 @@  #include <limits>  #include <string> +#include <cmath>  TEST_XML(dom_attr_assign, "<node/>")  { @@ -21,10 +22,13 @@ TEST_XML(dom_attr_assign, "<node/>")  	node.append_attribute(STR("attr6")) = 0.5;  	xml_attribute() = 0.5; -	node.append_attribute(STR("attr7")) = true; +	node.append_attribute(STR("attr7")) = 0.25f; +	xml_attribute() = 0.25f; + +	node.append_attribute(STR("attr8")) = true;  	xml_attribute() = true; -	CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"true\" />")); +	CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\" />"));  }  TEST_XML(dom_attr_set_name, "<node attr='value' />") @@ -55,10 +59,13 @@ TEST_XML(dom_attr_set_value, "<node/>")  	CHECK(node.append_attribute(STR("attr6")).set_value(0.5));  	CHECK(!xml_attribute().set_value(0.5)); -	CHECK(node.append_attribute(STR("attr7")).set_value(true)); +	CHECK(node.append_attribute(STR("attr7")).set_value(0.25f)); +	CHECK(!xml_attribute().set_value(0.25f)); + +	CHECK(node.append_attribute(STR("attr8")).set_value(true));  	CHECK(!xml_attribute().set_value(true)); -	CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"true\" />")); +	CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\" />"));  }  #ifdef PUGIXML_HAS_LONG_LONG @@ -93,6 +100,17 @@ TEST_XML(dom_attr_set_value_llong, "<node/>")  }  #endif +TEST_XML(dom_attr_assign_large_number, "<node attr1='' attr2='' />") +{ +	xml_node node = doc.child(STR("node")); + +	node.attribute(STR("attr1")) = std::numeric_limits<float>::max(); +	node.attribute(STR("attr2")) = std::numeric_limits<double>::max(); + +	CHECK(test_node(node, STR("<node attr1=\"3.40282347e+038\" attr2=\"1.7976931348623157e+308\" />"), STR(""), pugi::format_raw) || +		  test_node(node, STR("<node attr1=\"3.40282347e+38\" attr2=\"1.7976931348623157e+308\" />"), STR(""), pugi::format_raw)); +} +  TEST_XML(dom_node_set_name, "<node>text</node>")  {  	CHECK(doc.child(STR("node")).set_name(STR("n"))); @@ -746,17 +764,6 @@ TEST_XML_FLAGS(dom_node_copy_types, "<?xml version='1.0'?><!DOCTYPE id><root><?p  	CHECK_NODE(doc, STR("<?xml version=\"1.0\"?><!DOCTYPE id><?xml version=\"1.0\"?><!DOCTYPE id><root><?pi value?><!--comment--><node id=\"1\">pcdata<![CDATA[cdata]]></node></root><root><?pi value?><!--comment--><node id=\"1\">pcdata<![CDATA[cdata]]></node></root>"));  } -TEST_XML(dom_attr_assign_large_number, "<node attr1='' attr2='' />") -{ -	xml_node node = doc.child(STR("node")); - -	node.attribute(STR("attr1")) = std::numeric_limits<float>::max(); -	node.attribute(STR("attr2")) = std::numeric_limits<double>::max(); - -	CHECK(test_node(node, STR("<node attr1=\"3.40282e+038\" attr2=\"1.79769e+308\" />"), STR(""), pugi::format_raw) || -		  test_node(node, STR("<node attr1=\"3.40282e+38\" attr2=\"1.79769e+308\" />"), STR(""), pugi::format_raw)); -} -  TEST(dom_node_declaration_name)  {  	xml_document doc; @@ -1443,3 +1450,64 @@ TEST(dom_node_copy_declaration_empty_name)  	CHECK_STRING(decl2.name(), STR(""));  } + +TEST(dom_fp_roundtrip_min_max) +{ +	xml_document doc; +	xml_node node = doc.append_child(STR("node")); +	xml_attribute attr = node.append_attribute(STR("attr")); + +	node.text().set(std::numeric_limits<float>::min()); +	CHECK(node.text().as_float() == std::numeric_limits<float>::min()); + +	attr.set_value(std::numeric_limits<float>::max()); +	CHECK(attr.as_float() == std::numeric_limits<float>::max()); + +	attr.set_value(std::numeric_limits<double>::min()); +	CHECK(attr.as_double() == std::numeric_limits<double>::min()); + +	node.text().set(std::numeric_limits<double>::max()); +	CHECK(node.text().as_double() == std::numeric_limits<double>::max()); +} + +const double fp_roundtrip_base[] = +{ +	0.31830988618379067154, +	0.43429448190325182765, +	0.57721566490153286061, +	0.69314718055994530942, +	0.70710678118654752440, +	0.78539816339744830962, +}; + +TEST(dom_fp_roundtrip_float) +{ +	xml_document doc; + +	for (int e = -125; e <= 128; ++e) +	{ +		for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i) +		{ +			float value = ldexpf(fp_roundtrip_base[i], e); + +			doc.text().set(value); +			CHECK(doc.text().as_float() == value); +		} +	} +} + +TEST(dom_fp_roundtrip_double) +{ +	xml_document doc; + +	for (int e = -1021; e <= 1024; ++e) +	{ +		for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i) +		{ +			double value = ldexp(fp_roundtrip_base[i], e); + +			doc.text().set(value); +			CHECK(doc.text().as_double() == value); +		} +	} +} diff --git a/tests/test_dom_text.cpp b/tests/test_dom_text.cpp index fb65b03..007334a 100644 --- a/tests/test_dom_text.cpp +++ b/tests/test_dom_text.cpp @@ -263,10 +263,13 @@ TEST_XML(dom_text_assign, "<node/>")  	node.append_child(STR("text6")).text() = 0.5;
  	xml_text() = 0.5;
 -	node.append_child(STR("text7")).text() = true;
 +	node.append_child(STR("text7")).text() = 0.25f;
 +	xml_text() = 0.25f;
 +
 +	node.append_child(STR("text8")).text() = true;
  	xml_text() = true;
 -	CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
 +	CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>0.25</text7><text8>true</text8></node>"));
  }
  TEST_XML(dom_text_set_value, "<node/>")
 @@ -287,10 +290,13 @@ TEST_XML(dom_text_set_value, "<node/>")  	CHECK(node.append_child(STR("text6")).text().set(0.5));
  	CHECK(!xml_text().set(0.5));
 -	CHECK(node.append_child(STR("text7")).text().set(true));
 +	CHECK(node.append_child(STR("text7")).text().set(0.25f));
 +	CHECK(!xml_text().set(0.25f));
 +
 +	CHECK(node.append_child(STR("text8")).text().set(true));
  	CHECK(!xml_text().set(true));
 -	CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
 +	CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>0.25</text7><text8>true</text8></node>"));
  }
  #ifdef PUGIXML_HAS_LONG_LONG
 diff --git a/tests/test_header_only.cpp b/tests/test_header_only.cpp new file mode 100644 index 0000000..f1990dd --- /dev/null +++ b/tests/test_header_only.cpp @@ -0,0 +1,16 @@ +#define PUGIXML_HEADER_ONLY +#define pugi pugih + +#include "common.hpp" + +// Check header guards +#include "../src/pugixml.hpp" +#include "../src/pugixml.hpp" + +TEST(header_only) +{ +	xml_document doc; +	CHECK(doc.load_string(STR("<node/>"))); +	CHECK_STRING(doc.first_child().name(), STR("node")); +	CHECK(doc.first_child() == doc.select_node(STR("//*")).node()); +}  | 
