diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2015-04-08 03:09:47 +0000 |
---|---|---|
committer | <> | 2015-05-05 14:37:32 +0000 |
commit | f2541bb90af059680aa7036f315f052175999355 (patch) | |
tree | a5b214744b256f07e1dc2bd7273035a7808c659f /libs/property_tree | |
parent | ed232fdd34968697a68783b3195b1da4226915b5 (diff) | |
download | boost-tarball-master.tar.gz |
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_58_0.tar.bz2.HEADboost_1_58_0master
Diffstat (limited to 'libs/property_tree')
-rw-r--r-- | libs/property_tree/doc/Jamfile.v2 | 9 | ||||
-rw-r--r-- | libs/property_tree/doc/intro.qbk | 3 | ||||
-rw-r--r-- | libs/property_tree/doc/property_tree.qbk | 16 | ||||
-rw-r--r-- | libs/property_tree/doc/tutorial.qbk | 91 | ||||
-rw-r--r-- | libs/property_tree/examples/Jamfile.v2 | 12 | ||||
-rw-r--r-- | libs/property_tree/examples/debug_settings.cpp | 92 | ||||
-rw-r--r-- | libs/property_tree/meta/libraries.json | 16 | ||||
-rw-r--r-- | libs/property_tree/test/test_ini_parser.cpp | 57 | ||||
-rw-r--r-- | libs/property_tree/test/test_json_parser.cpp | 25 | ||||
-rw-r--r-- | libs/property_tree/test/test_property_tree.cpp | 154 | ||||
-rw-r--r-- | libs/property_tree/test/test_property_tree.hpp | 74 | ||||
-rw-r--r-- | libs/property_tree/test/xml_parser_test_data.hpp | 10 |
12 files changed, 255 insertions, 304 deletions
diff --git a/libs/property_tree/doc/Jamfile.v2 b/libs/property_tree/doc/Jamfile.v2 index 4f62fc9df..96601b722 100644 --- a/libs/property_tree/doc/Jamfile.v2 +++ b/libs/property_tree/doc/Jamfile.v2 @@ -12,6 +12,7 @@ import doxygen ; import quickbook ; + doxygen autodoc : [ glob ../../../boost/property_tree/*.hpp ] @@ -42,11 +43,5 @@ boostbook standalone <xsl:param>toc.section.depth=2 <xsl:param>chunk.section.depth=3 <dependency>autodoc - <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/functional/hash/doc/html + <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/property_tree/doc/html ; - -#install ../ -# : ../../../boost.png -# ../../../next.png -# ../../../prev.png -# ; diff --git a/libs/property_tree/doc/intro.qbk b/libs/property_tree/doc/intro.qbk index 30236970c..354e0c044 100644 --- a/libs/property_tree/doc/intro.qbk +++ b/libs/property_tree/doc/intro.qbk @@ -28,7 +28,8 @@ Conceptually, then, a node can be thought of as the following structure: list< pair<key_type, ptree> > children; // ordered list of named children }; -Both key_type and data_type are configurable, but will usually be std::string. +Both key_type and data_type are configurable to some extent, but will usually be +std::string or std::wstring, and the parsers only work with this kind of tree. Many software projects develop a similar tool at some point of their lifetime, and property tree originated the same way. We hope the library can save many diff --git a/libs/property_tree/doc/property_tree.qbk b/libs/property_tree/doc/property_tree.qbk index fef18f749..83f6a6bc8 100644 --- a/libs/property_tree/doc/property_tree.qbk +++ b/libs/property_tree/doc/property_tree.qbk @@ -7,15 +7,16 @@ /] [library Boost.PropertyTree - [quickbook 1.4] - [copyright 2008 Marcin Kalicinski] + [quickbook 1.6] + [copyright 2008-2010 Marcin Kalicinski] + [copyright 2010-2013 Sebastian Redl] [purpose Property Tree library] [license Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at [@http://www.boost.org/LICENSE_1_0.txt]) ] - [authors [Kalicinski, Marcin]] + [authors [Kalicinski, Marcin], [Redl, Sebastian]] [id property_tree] [dirname property_tree] [category container] @@ -29,19 +30,20 @@ [def __ptree_data_type__ [classref boost::property_tree::basic_ptree::data_type data_type]] [def __ptree_iterator__ [classref boost::property_tree::basic_ptree::iterator iterator]] [def __ptree_const_iterator__ [classref boost::property_tree::basic_ptree::const_iterator const_iterator]] +[def __ptree_assoc_iterator__ [classref boost::property_tree::basic_ptree::assoc_iterator assoc_iterator]] +[def __ptree_const_assoc_iterator__ [classref boost::property_tree::basic_ptree::const_assoc_iterator const_assoc_iterator]] [def __path__ [classref boost::property_tree::string_path path]] [def __ptree_error__ [classref boost::property_tree::ptree_error ptree_error]] [def __ptree_bad_data__ [classref boost::property_tree::ptree_bad_data ptree_bad_data]] [def __ptree_bad_path__ [classref boost::property_tree::ptree_bad_path ptree_bad_path]] [/ members] +[def __ptree_data__ [memberref boost::property_tree::basic_ptree::data data]] +[def __ptree_find__ [memberref boost::property_tree::basic_ptree::find find]] [def __ptree_insert__ [memberref boost::property_tree::basic_ptree::insert insert]] +[def __ptree_push_front__ [memberref boost::property_tree::basic_ptree::push_front push_front]] [def __ptree_push_back__ [memberref boost::property_tree::basic_ptree::push_back push_back]] -[def __ptree_find__ [memberref boost::property_tree::basic_ptree::find find]] [def __ptree_erase__ [memberref boost::property_tree::basic_ptree::erase erase]] -[def __ptree_find__ [memberref boost::property_tree::basic_ptree::find find]] -[def __ptree_data__ [memberref boost::property_tree::basic_ptree::data data]] -[def __ptree_push_front__ [memberref boost::property_tree::basic_ptree::push_front push_front]] [def __ptree_sort__ [memberref boost::property_tree::basic_ptree::sort sort]] [def __ptree_get__ [memberref boost::property_tree::basic_ptree::get get]] [/ XXX: Don't know how to specify overloads] diff --git a/libs/property_tree/doc/tutorial.qbk b/libs/property_tree/doc/tutorial.qbk index 4d374c368..9ef3a922d 100644 --- a/libs/property_tree/doc/tutorial.qbk +++ b/libs/property_tree/doc/tutorial.qbk @@ -1,14 +1,16 @@ [/ / Copyright (c) 2008 Marcin Kalicinski (kalita <at> poczta dot onet dot pl) - / Copyright (c) 2009 Sebastian Redl (sebastian dot redl <at> getdesigned dot at) + / Copyright (c) 2009, 2013 Sebastian Redl (sebastian dot redl <at> getdesigned dot at) / / Distributed under the Boost Software License, Version 1.0. (See accompanying / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) /] [section:tutorial Five Minute Tutorial] +[import ../examples/debug_settings.cpp] + This tutorial uses XML. Note that the library is not specifically bound to XML, and any other supported format (such as INI or JSON) could be used instead. -XML was chosen because the author thinks that wide range of people is familiar +XML was chosen because the author thinks that a wide range of people is familiar with it. Suppose we are writing a logging system for some application, and need to read @@ -28,89 +30,26 @@ configuration looks like this: ] It contains the log filename, a list of modules where logging is enabled, and -the debug level value. To store the logging configuration in the program we -created a debug_settings structure: - - struct debug_settings - { - std::string m_file; // log filename - int m_level; // debug level - std::set<string> m_modules; // modules where logging is enabled - void load(const std::string &filename); - void save(const std::string &filename); - }; - -All that needs to be done now is to write implementations of load() and save() -member functions. Let's first deal with load(). It contains just 7 lines of -code, although it does all the necessary things, including error reporting: +the debug level value. - #include <boost/property_tree/ptree.hpp> - #include <boost/property_tree/xml_parser.hpp> +First we need some includes: - // Loads debug_settings structure from the specified XML file - void debug_settings::load(const std::string &filename) - { - // Create an empty property tree object - using boost::property_tree::__ptree__; - __ptree__ pt; +[debug_settings_includes] - // Load the XML file into the property tree. If reading fails - // (cannot open file, parse error), an exception is thrown. - __read_xml__(filename, pt); +To store the logging configuration in the program we create a debug_settings +structure: - // Get the filename and store it in the m_file variable. - // Note that we construct the path to the value by separating - // the individual keys with dots. If dots appear in the keys, - // a path type with a different separator can be used. - // If the debug.filename key is not found, an exception is thrown. - m_file = pt.__ptree_get__<std::string>("debug.filename"); +[debug_settings_data] - // Get the debug level and store it in the m_level variable. - // This is another version of the get method: if the value is - // not found, the default value (specified by the second - // parameter) is returned instead. The type of the value - // extracted is determined by the type of the second parameter, - // so we can simply write get(...) instead of get<int>(...). - m_level = pt.__ptree_get__("debug.level", 0); +All that needs to be done now is to write implementations of load() and save() +member functions. Let's first deal with load(). It contains just 7 lines of +code, although it does all the necessary things, including error reporting: - // Iterate over the debug.modules section and store all found - // modules in the m_modules set. The get_child() function - // returns a reference to the child at the specified path; if - // there is no such child, it throws. Property tree iterators - // are models of BidirectionalIterator. - BOOST_FOREACH(__ptree__::__ptree_value_type__ &v, - pt.__ptree_get_child__("debug.modules")) - m_modules.__ptree_insert__(v.second.data()); - } +[debug_settings_load] Now the save() function. It is also 7 lines of code: - // Saves the debug_settings structure to the specified XML file - void debug_settings::save(const std::string &filename) - { - // Create an empty property tree object - using boost::property_tree::__ptree__; - __ptree__ pt; - - // Put log filename in property tree - pt.__ptree_put__("debug.filename", m_file); - - // Put debug level in property tree - pt.__ptree_put__("debug.level", m_level); - - // Iterate over the modules in the set and put them in the - // property tree. Note that the put function places the new - // key at the end of the list of keys. This is fine most of - // the time. If you want to place an item at some other place - // (i.e. at the front or somewhere in the middle), this can - // be achieved using a combination of the insert and put_own - // functions. - BOOST_FOREACH(const std::string &name, m_modules) - pt.__ptree_add__("debug.modules.module", name); - - // Write the property tree to the XML file. - __write_xml__(filename, pt); - } +[debug_settings_save] The full program [@boost:/libs/property_tree/examples/debug_settings.cpp debug_settings.cpp] is included in the examples directory. diff --git a/libs/property_tree/examples/Jamfile.v2 b/libs/property_tree/examples/Jamfile.v2 new file mode 100644 index 000000000..07c382aed --- /dev/null +++ b/libs/property_tree/examples/Jamfile.v2 @@ -0,0 +1,12 @@ +# Boost PropertyTree Library Example Jamfile +# Copyright (c) 2013 Sebastian Redl +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +project + : requirements + <include>../../../ + : + ; + +exe debug_settings : debug_settings.cpp ; diff --git a/libs/property_tree/examples/debug_settings.cpp b/libs/property_tree/examples/debug_settings.cpp index 639155608..2684f4359 100644 --- a/libs/property_tree/examples/debug_settings.cpp +++ b/libs/property_tree/examples/debug_settings.cpp @@ -8,6 +8,7 @@ // For more information, see www.boost.org // ---------------------------------------------------------------------------- +//[debug_settings_includes #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> #include <boost/foreach.hpp> @@ -15,7 +16,9 @@ #include <set> #include <exception> #include <iostream> - +namespace pt = boost::property_tree; +//] +//[debug_settings_data struct debug_settings { std::string m_file; // log filename @@ -24,80 +27,63 @@ struct debug_settings void load(const std::string &filename); void save(const std::string &filename); }; - +//] +//[debug_settings_load void debug_settings::load(const std::string &filename) { - // Create empty property tree object - using boost::property_tree::ptree; - ptree pt; + pt::ptree tree; - // Load XML file and put its contents in property tree. - // No namespace qualification is needed, because of Koenig - // lookup on the second argument. If reading fails, exception - // is thrown. - read_xml(filename, pt); + // Parse the XML into the property tree. + pt::read_xml(filename, tree); - // Get filename and store it in m_file variable. Note that - // we specify a path to the value using notation where keys - // are separated with dots (different separator may be used - // if keys themselves contain dots). If debug.filename key is - // not found, exception is thrown. - m_file = pt.get<std::string>("debug.filename"); - - // Get debug level and store it in m_level variable. This is - // another version of get method: if debug.level key is not - // found, it will return default value (specified by second - // parameter) instead of throwing. Type of the value extracted - // is determined by type of second parameter, so we can simply - // write get(...) instead of get<int>(...). - m_level = pt.get("debug.level", 0); + // Use the throwing version of get to find the debug filename. + // If the path cannot be resolved, an exception is thrown. + m_file = tree.get<std::string>("debug.filename"); - // Iterate over debug.modules section and store all found - // modules in m_modules set. get_child() function returns a - // reference to child at specified path; if there is no such - // child, it throws. Property tree iterator can be used in - // the same way as standard container iterator. Category - // is bidirectional_iterator. - BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules")) + // Use the default-value version of get to find the debug level. + // Note that the default value is used to deduce the target type. + m_level = tree.get("debug.level", 0); + + // Use get_child to find the node containing the modules, and iterate over + // its children. If the path cannot be resolved, get_child throws. + // A C++11 for-range loop would also work. + BOOST_FOREACH(pt::ptree::value_type &v, tree.get_child("debug.modules")) { + // The data function is used to access the data stored in a node. m_modules.insert(v.second.data()); + } } - +//] +//[debug_settings_save void debug_settings::save(const std::string &filename) { + // Create an empty property tree object. + pt::ptree tree; - // Create empty property tree object - using boost::property_tree::ptree; - ptree pt; - - // Put log filename in property tree - pt.put("debug.filename", m_file); - - // Put debug level in property tree - pt.put("debug.level", m_level); + // Put the simple values into the tree. The integer is automatically + // converted to a string. Note that the "debug" node is automatically + // created if it doesn't exist. + tree.put("debug.filename", m_file); + tree.put("debug.level", m_level); - // Iterate over modules in set and put them in property - // tree. Note that the add function places new key at the - // end of list of keys. This is fine in most of the - // situations. If you want to place item at some other - // place (i.e. at front or somewhere in the middle), - // this can be achieved using a combination of the insert - // and put_value functions + // Add all the modules. Unlike put, which overwrites existing nodes, add + // adds a new node at the lowest level, so the "modules" node will have + // multiple "module" children. BOOST_FOREACH(const std::string &name, m_modules) - pt.add("debug.modules.module", name); - - // Write property tree to XML file - write_xml(filename, pt); + tree.add("debug.modules.module", name); + // Write property tree to XML file + pt::write_xml(filename, tree); } +//] int main() { try { debug_settings ds; - ds.load("debug_settings.xml"); + ds.load("debug_settings_xml"); ds.save("debug_settings_out.xml"); std::cout << "Success\n"; } diff --git a/libs/property_tree/meta/libraries.json b/libs/property_tree/meta/libraries.json new file mode 100644 index 000000000..025c04397 --- /dev/null +++ b/libs/property_tree/meta/libraries.json @@ -0,0 +1,16 @@ +{ + "key": "property_tree", + "name": "Property Tree", + "authors": [ + "Marcin Kalicinski", + "Sebastian Redl" + ], + "description": "A tree data structure especially suited to storing configuration data.", + "category": [ + "Containers", + "Data" + ], + "maintainers": [ + "Sebastian Redl <sebastian.redl -at- getdesigned.at>" + ] +} diff --git a/libs/property_tree/test/test_ini_parser.cpp b/libs/property_tree/test/test_ini_parser.cpp index 6507bd353..2edb48cd4 100644 --- a/libs/property_tree/test/test_ini_parser.cpp +++ b/libs/property_tree/test/test_ini_parser.cpp @@ -12,6 +12,8 @@ #include <boost/property_tree/ini_parser.hpp> #include <sstream> +using namespace boost::property_tree; + /////////////////////////////////////////////////////////////////////////////// // Test data @@ -70,7 +72,7 @@ struct ReadFunc template<class Ptree> void operator()(const std::string &filename, Ptree &pt) const { - boost::property_tree::read_ini(filename, pt); + read_ini(filename, pt); } }; @@ -79,13 +81,12 @@ struct WriteFunc template<class Ptree> void operator()(const std::string &filename, const Ptree &pt) const { - boost::property_tree::write_ini(filename, pt); + write_ini(filename, pt); } }; void test_erroneous_write(const boost::property_tree::ptree &pt) { - using namespace boost::property_tree; std::stringstream stream; try { @@ -105,9 +106,6 @@ void test_erroneous_write(const boost::property_tree::ptree &pt) template<class Ptree> void test_ini_parser() { - - using namespace boost::property_tree; - generic_parser_test_ok<Ptree, ReadFunc, WriteFunc> ( ReadFunc(), WriteFunc(), ok_data_1, NULL, @@ -155,24 +153,10 @@ void test_ini_parser() ReadFunc(), WriteFunc(), error_data_2, NULL, "testerr2.ini", NULL, "testerr2out.ini", 3 ); - } -int test_main(int argc, char *argv[]) +void test_unmappable_trees() { - - using namespace boost::property_tree; - - test_ini_parser<ptree>(); - test_ini_parser<iptree>(); -#ifndef BOOST_NO_CWCHAR - test_ini_parser<wptree>(); - test_ini_parser<wiptree>(); -#endif - - /////////////////////////////////////////////////////////////////////////// - // Too rich property tree tests - // Test too deep ptrees { ptree pt; @@ -205,7 +189,38 @@ int test_main(int argc, char *argv[]) child.push_back(std::make_pair("key", ptree())); test_erroneous_write(pt); } +} + +void test_other_trees() +{ + // Top-level keys must be written before any section. + { + ptree pt; + pt.put("section.innerkey", "v1"); + pt.put("nosection", "v2"); + std::stringstream s; + write_ini(s, pt); + s.clear(); + s.seekg(0, std::ios_base::beg); + ptree result; + read_ini(s, result); + BOOST_CHECK(result.get("section.innerkey", "bad") == "v1"); + BOOST_CHECK(result.get("nosection", "bad") == "v2"); + } +} + +int test_main(int argc, char *argv[]) +{ + test_ini_parser<ptree>(); + test_ini_parser<iptree>(); +#ifndef BOOST_NO_CWCHAR + test_ini_parser<wptree>(); + test_ini_parser<wiptree>(); +#endif + test_unmappable_trees(); + test_other_trees(); + return 0; } diff --git a/libs/property_tree/test/test_json_parser.cpp b/libs/property_tree/test/test_json_parser.cpp index 0e6791923..33828d946 100644 --- a/libs/property_tree/test/test_json_parser.cpp +++ b/libs/property_tree/test/test_json_parser.cpp @@ -414,14 +414,39 @@ void test_json_parser() } +void test_escaping_utf8() +{ + // This is cyrillic text encoded as UTF-8 + std::string str = "\xD0\x9C\xD0\xB0\xD0\xBC\xD0\xB0 " + "\xD0\xBC\xD1\x8B\xD0\xBB\xD0\xB0 \xD1\x80\xD0\xB0\xD0\xBC\xD1\x83"; + // Should NOT escape UTF-8 + BOOST_CHECK(boost::property_tree::json_parser::create_escapes(str) == str); +} + +void test_escaping_wide() +{ + // Should NOT escape characters within ASCII range. + std::wstring str1 = L"I am wstring with ASCII"; + BOOST_CHECK(boost::property_tree::json_parser::create_escapes(str1) == str1); + // Should escape characters outside ASCII range - this is NOT utf-8 + // This is cyrillic text + std::wstring str2 = L"\u041C\u0430\u043C\u0430 " + L"\u043C\u044B\u043B\u0430 \u0440\u0430\u043C\u0443"; + BOOST_CHECK(boost::property_tree::json_parser::create_escapes(str2) == + L"\\u041C\\u0430\\u043C\\u0430 " + L"\\u043C\\u044B\\u043B\\u0430 \\u0440\\u0430\\u043C\\u0443"); +} + int test_main(int argc, char *argv[]) { using namespace boost::property_tree; test_json_parser<ptree>(); test_json_parser<iptree>(); + test_escaping_utf8(); #ifndef BOOST_NO_CWCHAR test_json_parser<wptree>(); test_json_parser<wiptree>(); + test_escaping_wide(); #endif return 0; } diff --git a/libs/property_tree/test/test_property_tree.cpp b/libs/property_tree/test/test_property_tree.cpp index d9dd10bbd..55ff5a830 100644 --- a/libs/property_tree/test/test_property_tree.cpp +++ b/libs/property_tree/test/test_property_tree.cpp @@ -132,6 +132,40 @@ namespace boost { namespace property_tree { # undef WIDECHAR #endif +template <typename Ptree> +void run_tests(Ptree* pt) +{ + test_debug(pt); + test_constructor_destructor_assignment(pt); + test_insertion(pt); + test_erasing(pt); + test_clear(pt); + test_pushpop(pt); + test_container_iteration(pt); + test_swap(pt); + test_sort_reverse(pt); + test_case(pt); + test_comparison(pt); + test_front_back(pt); + test_get_put(pt); + test_get_child_put_child(pt); + test_equal_range(pt); + test_path_separator(pt); + test_path(pt); + test_precision(pt); + test_locale(pt); + test_custom_data_type(pt); + test_empty_size_max_size(pt); + test_ptree_bad_path(pt); + test_ptree_bad_data(pt); + test_serialization(pt); + test_bool(pt); + test_char(pt); + test_float(pt); + test_sort(pt); + test_leaks(pt); // must be a final test +} + int test_main(int, char *[]) { @@ -140,138 +174,30 @@ int test_main(int, char *[]) // char tests, case sensitive { ptree *pt = 0; - test_debug(pt); - test_constructor_destructor_assignment(pt); - test_insertion(pt); - test_erasing(pt); - test_clear(pt); - test_pushpop(pt); - test_container_iteration(pt); - test_swap(pt); - test_sort_reverse(pt); - test_case(pt); - test_comparison(pt); - test_front_back(pt); - test_get_put(pt); - test_get_child_put_child(pt); - test_equal_range(pt); - test_path_separator(pt); - test_path(pt); - test_precision(pt); - test_locale(pt); - test_custom_data_type(pt); - test_empty_size_max_size(pt); - test_ptree_bad_path(pt); - test_ptree_bad_data(pt); - test_serialization(pt); - test_bool(pt); - test_char(pt); - test_sort(pt); - test_leaks(pt); // must be a final test + run_tests(pt); } -#if 0 + // wchar_t tests, case sensitive #ifndef BOOST_NO_CWCHAR { wptree *pt = 0; - test_debug(pt); - test_constructor_destructor_assignment(pt); - test_insertion(pt); - test_erasing(pt); - test_clear(pt); - test_pushpop(pt); - test_container_iteration(pt); - test_swap(pt); - test_sort_reverse(pt); - test_case(pt); - test_comparison(pt); - test_front_back(pt); - test_get_put(pt); - test_get_child_put_child(pt); - test_equal_range(pt); - test_path_separator(pt); - test_path(pt); - test_precision(pt); - test_locale(pt); - test_custom_data_type(pt); - test_empty_size_max_size(pt); - test_ptree_bad_path(pt); - test_ptree_bad_data(pt); - test_serialization(pt); - test_bool(pt); - test_char(pt); - test_sort(pt); - test_leaks(pt); // must be a final test + run_tests(pt); } #endif // char tests, case insensitive { iptree *pt = 0; - test_debug(pt); - test_constructor_destructor_assignment(pt); - test_insertion(pt); - test_erasing(pt); - test_clear(pt); - test_pushpop(pt); - test_container_iteration(pt); - test_swap(pt); - test_sort_reverse(pt); - test_case(pt); - test_comparison(pt); - test_front_back(pt); - test_get_put(pt); - test_get_child_put_child(pt); - test_equal_range(pt); - test_path_separator(pt); - test_path(pt); - test_precision(pt); - test_locale(pt); - test_custom_data_type(pt); - test_empty_size_max_size(pt); - test_ptree_bad_path(pt); - test_ptree_bad_data(pt); - test_serialization(pt); - test_bool(pt); - test_char(pt); - test_sort(pt); - test_leaks(pt); // must be a final test + run_tests(pt); } // wchar_t tests, case insensitive #ifndef BOOST_NO_CWCHAR { wiptree *pt = 0; - test_debug(pt); - test_constructor_destructor_assignment(pt); - test_insertion(pt); - test_erasing(pt); - test_clear(pt); - test_pushpop(pt); - test_container_iteration(pt); - test_swap(pt); - test_sort_reverse(pt); - test_case(pt); - test_comparison(pt); - test_front_back(pt); - test_get_put(pt); - test_get_child_put_child(pt); - test_equal_range(pt); - test_path_separator(pt); - test_path(pt); - test_precision(pt); - test_locale(pt); - test_custom_data_type(pt); - test_empty_size_max_size(pt); - test_ptree_bad_path(pt); - test_ptree_bad_data(pt); - test_serialization(pt); - test_bool(pt); - test_char(pt); - test_sort(pt); - test_leaks(pt); // must be a final test + run_tests(pt); } #endif -#endif + return 0; } diff --git a/libs/property_tree/test/test_property_tree.hpp b/libs/property_tree/test/test_property_tree.hpp index 9a0b1272f..4216945a1 100644 --- a/libs/property_tree/test/test_property_tree.hpp +++ b/libs/property_tree/test/test_property_tree.hpp @@ -1248,42 +1248,80 @@ void test_bool(PTREE *) void test_char(PTREE *) { + typedef signed char schar; + typedef unsigned char uchar; // Prepare test tree PTREE pt; #if WIDECHAR == 0 pt.put(T("char"), char('A')); #endif - pt.put(T("signed char"), static_cast<signed char>('A')); - pt.put(T("unsigned char"), static_cast<unsigned char>('A')); - pt.put(T("signed char min"), (std::numeric_limits<signed char>::min)()); - pt.put(T("signed char max"), (std::numeric_limits<signed char>::max)()); - pt.put(T("unsigned char min"), (std::numeric_limits<unsigned char>::min)()); - pt.put(T("unsigned char max"), (std::numeric_limits<unsigned char>::max)()); + pt.put(T("signed char"), static_cast<schar>('A')); + pt.put(T("unsigned char"), static_cast<uchar>('A')); + pt.put(T("signed char min"), (std::numeric_limits<schar>::min)()); + pt.put(T("signed char max"), (std::numeric_limits<schar>::max)()); + pt.put(T("signed char underflow"), + static_cast<int>((std::numeric_limits<schar>::min)()) - 1); + pt.put(T("signed char overflow"), + static_cast<int>((std::numeric_limits<schar>::max)()) + 1); + pt.put(T("unsigned char min"), (std::numeric_limits<uchar>::min)()); + pt.put(T("unsigned char max"), (std::numeric_limits<uchar>::max)()); + pt.put(T("unsigned char overflow"), + static_cast<unsigned>((std::numeric_limits<uchar>::max)()) + 1); // Verify normal conversions #if WIDECHAR == 0 BOOST_CHECK(pt.get<char>(T("char")) == 'A'); #endif - BOOST_CHECK(pt.get<signed char>(T("signed char")) == - static_cast<signed char>('A')); - BOOST_CHECK(pt.get<unsigned char>(T("unsigned char")) == - static_cast<unsigned char>('A')); + BOOST_CHECK(pt.get<schar>(T("signed char")) == static_cast<schar>('A')); + BOOST_CHECK(pt.get<uchar>(T("unsigned char")) == static_cast<uchar>('A')); // Verify that numbers are saved for signed and unsigned char BOOST_CHECK(pt.get<int>(T("signed char")) == int('A')); BOOST_CHECK(pt.get<int>(T("unsigned char")) == int('A')); // Verify ranges - BOOST_CHECK(pt.get<signed char>(T("signed char min")) == - (std::numeric_limits<signed char>::min)()); - BOOST_CHECK(pt.get<signed char>(T("signed char max")) == - (std::numeric_limits<signed char>::max)()); - BOOST_CHECK(pt.get<unsigned char>(T("unsigned char min")) == - (std::numeric_limits<unsigned char>::min)()); - BOOST_CHECK(pt.get<unsigned char>(T("unsigned char max")) == - (std::numeric_limits<unsigned char>::max)()); + BOOST_CHECK(pt.get<schar>(T("signed char min")) == + (std::numeric_limits<schar>::min)()); + BOOST_CHECK(pt.get<schar>(T("signed char max")) == + (std::numeric_limits<schar>::max)()); + BOOST_CHECK(pt.get<uchar>(T("unsigned char min")) == + (std::numeric_limits<uchar>::min)()); + BOOST_CHECK(pt.get<uchar>(T("unsigned char max")) == + (std::numeric_limits<uchar>::max)()); + + // Check that out-of-range throws. + try { + pt.get<schar>(T("signed char underflow")); + BOOST_ERROR("expected ptree_bad_data, but nothing was thrown"); + } catch (boost::property_tree::ptree_bad_data&) { + } catch (...) { + BOOST_ERROR("expected ptree_bad_data, but something else was thrown"); + } + try { + pt.get<schar>(T("signed char overflow")); + BOOST_ERROR("expected ptree_bad_data, but nothing was thrown"); + } catch (boost::property_tree::ptree_bad_data&) { + } catch (...) { + BOOST_ERROR("expected ptree_bad_data, but something else was thrown"); + } + try { + pt.get<uchar>(T("unsigned char overflow")); + BOOST_ERROR("expected ptree_bad_data, but nothing was thrown"); + } catch (boost::property_tree::ptree_bad_data&) { + } catch (...) { + BOOST_ERROR("expected ptree_bad_data, but something else was thrown"); + } +} + +void test_float(PTREE*) +{ + const double difficult = -183.12345000098765e-10; + PTREE pt; + pt.put(T("num"), difficult); + double result = pt.get<double>(T("num")); + BOOST_CHECK(!(result < difficult || result > difficult)); } void test_sort(PTREE *) diff --git a/libs/property_tree/test/xml_parser_test_data.hpp b/libs/property_tree/test/xml_parser_test_data.hpp index 8ed329753..d0b4c071c 100644 --- a/libs/property_tree/test/xml_parser_test_data.hpp +++ b/libs/property_tree/test/xml_parser_test_data.hpp @@ -743,13 +743,9 @@ const char *ok_data_4 = "</rss>\n"; // Correct, with UTF-8 data -const char ok_data_5[] = { - '<', '?', 'x', 'm', 'l', ' ', 'v', 'e', 'r', 's', 'i', 'o', 'n', '=', '"', - '1', '.', '0', '"', ' ', 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '=', '"', - 'u', 't', 'f', '-', '8', '"', '?', '>', '\n', /*39 chars*/ - '<', 'd', 'o', 'c', '>', -61, -92, '<', '/', 'd', 'o', 'c', '>', - 0 -}; +const char ok_data_5[] = + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" /*39 chars*/ + "<doc>\xC3\xA4</doc>"; // Erroneous const char *error_data_1 = |