diff --git a/include/boost/property_tree/detail/exception_implementation.hpp b/include/boost/property_tree/detail/exception_implementation.hpp index 8ac6d93..551e10c 100644 --- a/include/boost/property_tree/detail/exception_implementation.hpp +++ b/include/boost/property_tree/detail/exception_implementation.hpp @@ -30,8 +30,8 @@ namespace boost { namespace property_tree /////////////////////////////////////////////////////////////////////////// // ptree_error - inline ptree_error::ptree_error(const std::string &what): - std::runtime_error(what) + inline ptree_error::ptree_error(const std::string &w): + std::runtime_error(w) { } @@ -43,8 +43,8 @@ namespace boost { namespace property_tree // ptree_bad_data template inline - ptree_bad_data::ptree_bad_data(const std::string &what, const D &data): - ptree_error(what), m_data(data) + ptree_bad_data::ptree_bad_data(const std::string &w, const D &d): + ptree_error(w), m_data(d) { } @@ -62,8 +62,8 @@ namespace boost { namespace property_tree // ptree_bad_path template inline - ptree_bad_path::ptree_bad_path(const std::string &what, const P &path): - ptree_error(detail::prepare_bad_path_what(what, path)), m_path(path) + ptree_bad_path::ptree_bad_path(const std::string &w, const P &p): + ptree_error(detail::prepare_bad_path_what(w, p)), m_path(p) { } diff --git a/include/boost/property_tree/detail/file_parser_error.hpp b/include/boost/property_tree/detail/file_parser_error.hpp index 4c8b237..ff90583 100644 --- a/include/boost/property_tree/detail/file_parser_error.hpp +++ b/include/boost/property_tree/detail/file_parser_error.hpp @@ -26,11 +26,11 @@ namespace boost { namespace property_tree // Construction & destruction // Construct error - file_parser_error(const std::string &message, - const std::string &filename, - unsigned long line) : - ptree_error(format_what(message, filename, line)), - m_message(message), m_filename(filename), m_line(line) + file_parser_error(const std::string &msg, + const std::string &file, + unsigned long l) : + ptree_error(format_what(msg, file, l)), + m_message(msg), m_filename(file), m_line(l) { } @@ -45,19 +45,19 @@ namespace boost { namespace property_tree // Get error message (without line and file - use what() to get // full message) - std::string message() + std::string message() const { return m_message; } // Get error filename - std::string filename() + std::string filename() const { return m_filename; } // Get error line number - unsigned long line() + unsigned long line() const { return m_line; } @@ -69,20 +69,15 @@ namespace boost { namespace property_tree unsigned long m_line; // Format error message to be returned by std::runtime_error::what() - std::string format_what(const std::string &message, - const std::string &filename, - unsigned long line) + static std::string format_what(const std::string &msg, + const std::string &file, + unsigned long l) { std::stringstream stream; - if (line > 0) - stream << (filename.empty() ? "" - : filename.c_str()) - << '(' << line << "): " - << message; - else - stream << (filename.empty() ? "" - : filename.c_str()) - << ": " << message; + stream << (file.empty() ? "" : file.c_str()); + if (l > 0) + stream << '(' << l << ')'; + stream << ": " << msg; return stream.str(); } diff --git a/include/boost/property_tree/detail/json_parser_read.hpp b/include/boost/property_tree/detail/json_parser_read.hpp index dc9ec02..25aabf4 100644 --- a/include/boost/property_tree/detail/json_parser_read.hpp +++ b/include/boost/property_tree/detail/json_parser_read.hpp @@ -128,7 +128,6 @@ namespace boost { namespace property_tree { namespace json_parser { case Ch('\"'): c.string += Ch('\"'); break; case Ch('\\'): c.string += Ch('\\'); break; - case Ch('0'): c.string += Ch('\0'); break; case Ch('b'): c.string += Ch('\b'); break; case Ch('f'): c.string += Ch('\f'); break; case Ch('n'): c.string += Ch('\n'); break; @@ -232,8 +231,12 @@ namespace boost { namespace property_tree { namespace json_parser ; number - = strict_real_p - | int_p + = !ch_p("-") >> + (ch_p("0") | (range_p(Ch('1'), Ch('9')) >> *digit_p)) >> + !(ch_p(".") >> +digit_p) >> + !(chset_p(detail::widen("eE").c_str()) >> + !chset_p(detail::widen("-+").c_str()) >> + +digit_p) ; string @@ -246,7 +249,7 @@ namespace boost { namespace property_tree { namespace json_parser ; escape - = chset_p(detail::widen("\"\\0bfnrt").c_str())[typename Context::a_escape(self.c)] + = chset_p(detail::widen("\"\\bfnrt").c_str())[typename Context::a_escape(self.c)] | 'u' >> uint_parser()[typename Context::a_unicode(self.c)] ; diff --git a/include/boost/property_tree/detail/json_parser_write.hpp b/include/boost/property_tree/detail/json_parser_write.hpp index c5609ee..0b48ca1 100644 --- a/include/boost/property_tree/detail/json_parser_write.hpp +++ b/include/boost/property_tree/detail/json_parser_write.hpp @@ -21,37 +21,37 @@ namespace boost { namespace property_tree { namespace json_parser // Create necessary escape sequences from illegal characters template - std::basic_string create_escapes(const std::basic_string &s, - const std::locale &loc) + std::basic_string create_escapes(const std::basic_string &s) { std::basic_string result; typename std::basic_string::const_iterator b = s.begin(); typename std::basic_string::const_iterator e = s.end(); while (b != e) { - if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0'); + // This assumes an ASCII superset. But so does everything in PTree. + // We escape everything outside ASCII, because this code can't + // handle high unicode characters. + if (*b == 0x20 || *b == 0x21 || + (*b >= 0x23 && *b <= 0x5B) || (*b >= 0x5D && *b <= 0xFF)) + result += *b; else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b'); else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f'); else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n'); else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r'); - else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"'); + else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"'); else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\'); else { - if (std::isprint(*b, loc)) - result += *b; - else - { - const char *hexdigits = "0123456789ABCDEF"; - unsigned long u = (std::min)(static_cast(*b), 0xFFFFul); - int d1 = u / 4096; u -= d1 * 4096; - int d2 = u / 256; u -= d2 * 256; - int d3 = u / 16; u -= d3 * 16; - int d4 = u; - result += Ch('\\'); result += Ch('u'); - result += Ch(hexdigits[d1]); result += Ch(hexdigits[d2]); - result += Ch(hexdigits[d3]); result += Ch(hexdigits[d4]); - } + const char *hexdigits = "0123456789ABCDEF"; + unsigned long u = (std::min)(static_cast(*b), + 0xFFFFul); + int d1 = u / 4096; u -= d1 * 4096; + int d2 = u / 256; u -= d2 * 256; + int d3 = u / 16; u -= d3 * 16; + int d4 = u; + result += Ch('\\'); result += Ch('u'); + result += Ch(hexdigits[d1]); result += Ch(hexdigits[d2]); + result += Ch(hexdigits[d3]); result += Ch(hexdigits[d4]); } ++b; } @@ -60,60 +60,61 @@ namespace boost { namespace property_tree { namespace json_parser template void write_json_helper(std::basic_ostream &stream, - const Ptree &pt, - int indent) + const Ptree &pt, + int indent, bool pretty) { typedef typename Ptree::key_type::value_type Ch; typedef typename std::basic_string Str; - + // Value or object or array if (indent > 0 && pt.empty()) { - // Write value - Str data = create_escapes(pt.template get_value(), stream.getloc()); + Str data = create_escapes(pt.template get_value()); stream << Ch('"') << data << Ch('"'); } else if (indent > 0 && pt.count(Str()) == pt.size()) { - // Write array - stream << Ch('[') << Ch('\n'); + stream << Ch('['); + if (pretty) stream << Ch('\n'); typename Ptree::const_iterator it = pt.begin(); for (; it != pt.end(); ++it) { - stream << Str(4 * (indent + 1), Ch(' ')); - write_json_helper(stream, it->second, indent + 1); + if (pretty) stream << Str(4 * (indent + 1), Ch(' ')); + write_json_helper(stream, it->second, indent + 1, pretty); if (boost::next(it) != pt.end()) stream << Ch(','); - stream << Ch('\n'); + if (pretty) stream << Ch('\n'); } stream << Str(4 * indent, Ch(' ')) << Ch(']'); } else { - // Write object - stream << Ch('{') << Ch('\n'); + stream << Ch('{'); + if (pretty) stream << Ch('\n'); typename Ptree::const_iterator it = pt.begin(); for (; it != pt.end(); ++it) { - stream << Str(4 * (indent + 1), Ch(' ')); - stream << Ch('"') << create_escapes(it->first, stream.getloc()) << Ch('"') << Ch(':'); - if (it->second.empty()) - stream << Ch(' '); - else - stream << Ch('\n') << Str(4 * (indent + 1), Ch(' ')); - write_json_helper(stream, it->second, indent + 1); + if (pretty) stream << Str(4 * (indent + 1), Ch(' ')); + stream << Ch('"') << create_escapes(it->first) << Ch('"') << Ch(':'); + if (pretty) { + if (it->second.empty()) + stream << Ch(' '); + else + stream << Ch('\n') << Str(4 * (indent + 1), Ch(' ')); + } + write_json_helper(stream, it->second, indent + 1, pretty); if (boost::next(it) != pt.end()) stream << Ch(','); - stream << Ch('\n'); + if (pretty) stream << Ch('\n'); } - stream << Str(4 * indent, Ch(' ')) << Ch('}'); - + if (pretty) stream << Str(4 * indent, Ch(' ')); + stream << Ch('}'); } } @@ -149,11 +150,12 @@ namespace boost { namespace property_tree { namespace json_parser template void write_json_internal(std::basic_ostream &stream, const Ptree &pt, - const std::string &filename) + const std::string &filename, + bool pretty) { if (!verify_json(pt, 0)) BOOST_PROPERTY_TREE_THROW(json_parser_error("ptree contains data that cannot be represented in JSON format", filename, 0)); - write_json_helper(stream, pt, 0); + write_json_helper(stream, pt, 0, pretty); stream << std::endl; if (!stream.good()) BOOST_PROPERTY_TREE_THROW(json_parser_error("write error", filename, 0)); diff --git a/include/boost/property_tree/detail/ptree_implementation.hpp b/include/boost/property_tree/detail/ptree_implementation.hpp index 6616d87..bfed43d 100644 --- a/include/boost/property_tree/detail/ptree_implementation.hpp +++ b/include/boost/property_tree/detail/ptree_implementation.hpp @@ -183,8 +183,8 @@ namespace boost { namespace property_tree } template inline - basic_ptree::basic_ptree(const data_type &data) - : m_data(data), m_children(new typename subs::base_container) + basic_ptree::basic_ptree(const data_type &d) + : m_data(d), m_children(new typename subs::base_container) { } @@ -467,8 +467,8 @@ namespace boost { namespace property_tree std::pair r( subs::assoc(this).equal_range(key)); - return std::pair(r.first.base(), - r.second.base()); + return std::pair( + assoc_iterator(r.first), assoc_iterator(r.second)); } template inline @@ -481,7 +481,7 @@ namespace boost { namespace property_tree typename subs::by_name_index::const_iterator> r( subs::assoc(this).equal_range(key)); return std::pair( - r.first.base(), r.second.base()); + const_assoc_iterator(r.first), const_assoc_iterator(r.second)); } template inline @@ -770,7 +770,8 @@ namespace boost { namespace property_tree Translator tr) const { if (optional child = get_child_optional(path)) - return child.get().BOOST_NESTED_TEMPLATE get_value_optional(tr); + return child.get(). + BOOST_NESTED_TEMPLATE get_value_optional(tr); else return optional(); } diff --git a/include/boost/property_tree/detail/rapidxml.hpp b/include/boost/property_tree/detail/rapidxml.hpp index 1c5e2ad..191bc70 100644 --- a/include/boost/property_tree/detail/rapidxml.hpp +++ b/include/boost/property_tree/detail/rapidxml.hpp @@ -7,17 +7,14 @@ // // For more information, see www.boost.org // ---------------------------------------------------------------------------- -#ifndef RAPIDXML_HPP_INCLUDED -#define RAPIDXML_HPP_INCLUDED +#ifndef BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED //! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation -// If standard library is disabled, user must provide implementations of required functions and typedefs -#if !defined(RAPIDXML_NO_STDLIB) - #include // For std::size_t - #include // For assert - #include // For placement new -#endif +#include // For std::size_t +#include // For assert +#include // For placement new // On MSVC, disable "conditional expression is constant" warning (level 4). // This warning is almost impossible to avoid with certain types of templated code @@ -27,40 +24,13 @@ #endif /////////////////////////////////////////////////////////////////////////// -// RAPIDXML_PARSE_ERROR - -#if defined(RAPIDXML_NO_EXCEPTIONS) - -#define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); } - -namespace rapidxml -{ - //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, - //! this function is called to notify user about the error. - //! It must be defined by the user. - //!

- //! This function cannot return. If it does, the results are undefined. - //!

- //! A very simple definition might look like that: - //!
-    //! void %rapidxml::%parse_error_handler(const char *what, void *where)
-    //! {
-    //!     std::cout << "Parse error: " << what << "\n";
-    //!     std::abort();
-    //! }
-    //! 
- //! \param what Human readable description of the error. - //! \param where Pointer to character data where error was detected. - void parse_error_handler(const char *what, void *where); -} - -#else +// BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR #include // For std::exception -#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where) +#define BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where) -namespace rapidxml +namespace boost { namespace property_tree { namespace detail {namespace rapidxml { //! Parse error exception. @@ -80,9 +50,9 @@ namespace rapidxml public: //! Constructs parse error - parse_error(const char *what, void *where) - : m_what(what) - , m_where(where) + parse_error(const char *wa, void *we) + : m_what(wa) + , m_where(we) { } @@ -108,36 +78,34 @@ namespace rapidxml void *m_where; }; -} - -#endif +}}}} /////////////////////////////////////////////////////////////////////////// // Pool sizes -#ifndef RAPIDXML_STATIC_POOL_SIZE +#ifndef BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE // Size of static memory block of memory_pool. - // Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. + // Define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. // No dynamic memory allocations are performed by memory_pool until static memory is exhausted. - #define RAPIDXML_STATIC_POOL_SIZE (64 * 1024) + #define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE (64 * 1024) #endif -#ifndef RAPIDXML_DYNAMIC_POOL_SIZE +#ifndef BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE // Size of dynamic memory block of memory_pool. - // Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. + // Define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool. - #define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024) + #define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024) #endif -#ifndef RAPIDXML_ALIGNMENT +#ifndef BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT // Memory allocation alignment. - // Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer. + // Define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer. // All memory allocations for nodes, attributes and strings will be aligned to this value. // This must be a power of 2 and at least 1, otherwise memory_pool will not work. - #define RAPIDXML_ALIGNMENT sizeof(void *) + #define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT sizeof(void *) #endif -namespace rapidxml +namespace boost { namespace property_tree { namespace detail {namespace rapidxml { // Forward declarations template class xml_node; @@ -364,20 +332,20 @@ namespace rapidxml //! It is also possible to create a standalone memory_pool, and use it //! to allocate nodes, whose lifetime will not be tied to any document. //!

- //! Pool maintains RAPIDXML_STATIC_POOL_SIZE bytes of statically allocated memory. + //! Pool maintains BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE bytes of statically allocated memory. //! Until static memory is exhausted, no dynamic memory allocations are done. - //! When static memory is exhausted, pool allocates additional blocks of memory of size RAPIDXML_DYNAMIC_POOL_SIZE each, + //! When static memory is exhausted, pool allocates additional blocks of memory of size BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE each, //! by using global new[] and delete[] operators. //! This behaviour can be changed by setting custom allocation routines. //! Use set_allocator() function to set them. //!

- //! Allocations for nodes, attributes and strings are aligned at RAPIDXML_ALIGNMENT bytes. + //! Allocations for nodes, attributes and strings are aligned at BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT bytes. //! This value defaults to the size of pointer on target architecture. //!

//! To obtain absolutely top performance from the parser, //! it is important that all nodes are allocated from a single, contiguous block of memory. //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably. - //! If required, you can tweak RAPIDXML_STATIC_POOL_SIZE, RAPIDXML_DYNAMIC_POOL_SIZE and RAPIDXML_ALIGNMENT + //! If required, you can tweak BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE, BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE and BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT //! to obtain best wasted memory to performance compromise. //! To do it, define their values before rapidxml.hpp file is included. //! \param Ch Character type of created nodes. @@ -578,7 +546,7 @@ namespace rapidxml char *align(char *ptr) { - std::size_t alignment = ((RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1))) & (RAPIDXML_ALIGNMENT - 1)); + std::size_t alignment = ((BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 1))) & (BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 1)); return ptr + alignment; } @@ -594,10 +562,6 @@ namespace rapidxml else { memory = new char[size]; -#ifdef RAPIDXML_NO_EXCEPTIONS - if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc - RAPIDXML_PARSE_ERROR("out of memory", 0); -#endif } return static_cast(memory); } @@ -610,13 +574,13 @@ namespace rapidxml // If not enough memory left in current pool, allocate a new pool if (result + size > m_end) { - // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE) - std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE; + // Calculate required pool size (may be bigger than BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE) + std::size_t pool_size = BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE; if (pool_size < size) pool_size = size; // Allocate - std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation + std::size_t alloc_size = sizeof(header) + (2 * BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation char *raw_memory = allocate_raw(alloc_size); // Setup new pool in allocated memory @@ -639,7 +603,7 @@ namespace rapidxml char *m_begin; // Start of raw memory making up current pool char *m_ptr; // First free byte in current pool char *m_end; // One past last available byte in current pool - char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]; // Static raw memory + char m_static_memory[BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE]; // Static raw memory alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used free_func *m_free_func; // Free function, or 0 if default is to be used }; @@ -722,20 +686,20 @@ namespace rapidxml //!

//! Size of name must be specified separately, because name does not have to be zero terminated. //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated). - //! \param name Name of node to set. Does not have to be zero terminated. + //! \param n Name of node to set. Does not have to be zero terminated. //! \param size Size of name, in characters. This does not include zero terminator, if one is present. - void name(const Ch *name, std::size_t size) + void name(const Ch *n, std::size_t size) { - m_name = const_cast(name); + m_name = const_cast(n); m_name_size = size; } //! Sets name of node to a zero-terminated string. //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t). - //! \param name Name of node to set. Must be zero terminated. - void name(const Ch *name) + //! \param n Name of node to set. Must be zero terminated. + void name(const Ch *n) { - this->name(name, internal::measure(name)); + name(n, internal::measure(n)); } //! Sets value of node to a non zero-terminated string. @@ -752,20 +716,20 @@ namespace rapidxml //!

//! If an element has a child node of type node_data, it will take precedence over element value when printing. //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser. - //! \param value value of node to set. Does not have to be zero terminated. + //! \param val value of node to set. Does not have to be zero terminated. //! \param size Size of value, in characters. This does not include zero terminator, if one is present. - void value(const Ch *value, std::size_t size) + void value(const Ch *val, std::size_t size) { - m_value = const_cast(value); + m_value = const_cast(val); m_value_size = size; } //! Sets value of node to a zero-terminated string. //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t). - //! \param value Vame of node to set. Must be zero terminated. - void value(const Ch *value) + //! \param val Vame of node to set. Must be zero terminated. + void value(const Ch *val) { - this->value(value, internal::measure(value)); + this->value(val, internal::measure(val)); } /////////////////////////////////////////////////////////////////////////// @@ -835,18 +799,18 @@ namespace rapidxml } //! Gets previous attribute, optionally matching attribute name. - //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero - //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param n Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found attribute, or 0 if not found. - xml_attribute *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + xml_attribute *previous_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const { - if (name) + if (n) { - if (name_size == 0) - name_size = internal::measure(name); + if (nsize == 0) + nsize = internal::measure(n); for (xml_attribute *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute) - if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive)) return attribute; return 0; } @@ -855,18 +819,18 @@ namespace rapidxml } //! Gets next attribute, optionally matching attribute name. - //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero - //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param n Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found attribute, or 0 if not found. - xml_attribute *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + xml_attribute *next_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const { - if (name) + if (n) { - if (name_size == 0) - name_size = internal::measure(name); + if (nsize == 0) + nsize = internal::measure(n); for (xml_attribute *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute) - if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive)) return attribute; return 0; } @@ -903,9 +867,9 @@ namespace rapidxml //! Constructs an empty node with the specified type. //! Consider using memory_pool of appropriate document to allocate nodes manually. - //! \param type Type of node to construct. - xml_node(node_type type) - : m_type(type) + //! \param t Type of node to construct. + xml_node(node_type t) + : m_type(t) , m_first_node(0) , m_first_attribute(0) { @@ -935,18 +899,18 @@ namespace rapidxml } //! Gets first child node, optionally matching node name. - //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero - //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param n Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found child, or 0 if not found. - xml_node *first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + xml_node *first_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const { - if (name) + if (n) { - if (name_size == 0) - name_size = internal::measure(name); + if (nsize == 0) + nsize = internal::measure(n); for (xml_node *child = m_first_node; child; child = child->next_sibling()) - if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) + if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive)) return child; return 0; } @@ -957,19 +921,19 @@ namespace rapidxml //! Gets last child node, optionally matching node name. //! Behaviour is undefined if node has no children. //! Use first_node() to test if node has children. - //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero - //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param n Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found child, or 0 if not found. - xml_node *last_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + xml_node *last_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const { assert(m_first_node); // Cannot query for last child if node has no children - if (name) + if (n) { - if (name_size == 0) - name_size = internal::measure(name); + if (nsize == 0) + nsize = internal::measure(n); for (xml_node *child = m_last_node; child; child = child->previous_sibling()) - if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) + if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive)) return child; return 0; } @@ -980,19 +944,19 @@ namespace rapidxml //! Gets previous sibling node, optionally matching node name. //! Behaviour is undefined if node has no parent. //! Use parent() to test if node has a parent. - //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero - //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param n Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found sibling, or 0 if not found. - xml_node *previous_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + xml_node *previous_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const { assert(this->m_parent); // Cannot query for siblings if node has no parent - if (name) + if (n) { - if (name_size == 0) - name_size = internal::measure(name); + if (nsize == 0) + nsize = internal::measure(n); for (xml_node *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling) - if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) + if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive)) return sibling; return 0; } @@ -1003,19 +967,19 @@ namespace rapidxml //! Gets next sibling node, optionally matching node name. //! Behaviour is undefined if node has no parent. //! Use parent() to test if node has a parent. - //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero - //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param n Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found sibling, or 0 if not found. - xml_node *next_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + xml_node *next_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const { assert(this->m_parent); // Cannot query for siblings if node has no parent - if (name) + if (n) { - if (name_size == 0) - name_size = internal::measure(name); + if (nsize == 0) + nsize = internal::measure(n); for (xml_node *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling) - if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) + if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive)) return sibling; return 0; } @@ -1024,18 +988,18 @@ namespace rapidxml } //! Gets first attribute of node, optionally matching attribute name. - //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero - //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param n Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found attribute, or 0 if not found. - xml_attribute *first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + xml_attribute *first_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const { - if (name) + if (n) { - if (name_size == 0) - name_size = internal::measure(name); + if (nsize == 0) + nsize = internal::measure(n); for (xml_attribute *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute) - if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive)) return attribute; return 0; } @@ -1044,18 +1008,18 @@ namespace rapidxml } //! Gets last attribute of node, optionally matching attribute name. - //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero - //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param n Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found attribute, or 0 if not found. - xml_attribute *last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const + xml_attribute *last_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const { - if (name) + if (n) { - if (name_size == 0) - name_size = internal::measure(name); + if (nsize == 0) + nsize = internal::measure(n); for (xml_attribute *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute) - if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive)) return attribute; return 0; } @@ -1067,10 +1031,10 @@ namespace rapidxml // Node modification //! Sets type of node. - //! \param type Type of node to set. - void type(node_type type) + //! \param t Type of node to set. + void type(node_type t) { - m_type = type; + m_type = t; } /////////////////////////////////////////////////////////////////////////// @@ -1411,7 +1375,7 @@ namespace rapidxml this->append_node(node); } else - RAPIDXML_PARSE_ERROR("expected <", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected <", text); } } @@ -1554,7 +1518,7 @@ namespace rapidxml } else // Invalid, only codes up to 0x10FFFF are allowed in Unicode { - RAPIDXML_PARSE_ERROR("invalid numeric character entity", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid numeric character entity", text); } } } @@ -1685,7 +1649,7 @@ namespace rapidxml if (*src == Ch(';')) ++src; else - RAPIDXML_PARSE_ERROR("expected ;", src); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ;", src); continue; // Something else @@ -1735,7 +1699,7 @@ namespace rapidxml static_cast(text[1]) == 0xBB && static_cast(text[2]) == 0xBF) { - text += 3; // Skup utf-8 bom + text += 3; // Skip utf-8 bom } } @@ -1750,7 +1714,7 @@ namespace rapidxml while (text[0] != Ch('?') || text[1] != Ch('>')) { if (!text[0]) - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } text += 2; // Skip '?>' @@ -1768,7 +1732,7 @@ namespace rapidxml // Skip ?> if (text[0] != Ch('?') || text[1] != Ch('>')) - RAPIDXML_PARSE_ERROR("expected ?>", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ?>", text); text += 2; return declaration; @@ -1785,7 +1749,7 @@ namespace rapidxml while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) { if (!text[0]) - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } text += 3; // Skip '-->' @@ -1793,19 +1757,19 @@ namespace rapidxml } // Remember value start - Ch *value = text; + Ch *val = text; // Skip until end of comment while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) { if (!text[0]) - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } // Create comment node xml_node *comment = this->allocate_node(node_comment); - comment->value(value, text - value); + comment->value(val, text - val); // Place zero terminator after comment value if (!(Flags & parse_no_string_terminators)) @@ -1820,7 +1784,7 @@ namespace rapidxml xml_node *parse_doctype(Ch *&text) { // Remember value start - Ch *value = text; + Ch *val = text; // Skip to > while (*text != Ch('>')) @@ -1841,7 +1805,8 @@ namespace rapidxml { case Ch('['): ++depth; break; case Ch(']'): --depth; break; - case 0: RAPIDXML_PARSE_ERROR("unexpected end of data", text); + case 0: BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + default: break; } ++text; } @@ -1850,7 +1815,7 @@ namespace rapidxml // Error on end of text case Ch('\0'): - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); // Other character, skip it default: @@ -1864,7 +1829,7 @@ namespace rapidxml { // Create a new doctype node xml_node *doctype = this->allocate_node(node_doctype); - doctype->value(value, text - value); + doctype->value(val, text - val); // Place zero terminator after value if (!(Flags & parse_no_string_terminators)) @@ -1892,29 +1857,29 @@ namespace rapidxml xml_node *pi = this->allocate_node(node_pi); // Extract PI target name - Ch *name = text; + Ch *n = text; skip(text); - if (text == name) - RAPIDXML_PARSE_ERROR("expected PI target", text); - pi->name(name, text - name); + if (text == n) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected PI target", text); + pi->name(n, text - n); // Skip whitespace between pi target and pi skip(text); // Remember start of pi - Ch *value = text; + Ch *val = text; // Skip to '?>' while (text[0] != Ch('?') || text[1] != Ch('>')) { if (*text == Ch('\0')) - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } // Set pi value (verbatim, no entity expansion or whitespace normalization) - pi->value(value, text - value); - + pi->value(val, text - val); + // Place zero terminator after name and value if (!(Flags & parse_no_string_terminators)) { @@ -1931,7 +1896,7 @@ namespace rapidxml while (text[0] != Ch('?') || text[1] != Ch('>')) { if (*text == Ch('\0')) - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } text += 2; // Skip '?>' @@ -1950,7 +1915,7 @@ namespace rapidxml text = contents_start; // Skip until end of data - Ch *value = text, *end; + Ch *val = text, *end; if (Flags & parse_normalize_whitespace) end = skip_and_expand_character_refs(text); else @@ -1978,14 +1943,14 @@ namespace rapidxml if (!(Flags & parse_no_data_nodes)) { xml_node *data = this->allocate_node(node_data); - data->value(value, end - value); + data->value(val, end - val); node->append_node(data); } // Add data to parent node if no data exists yet if (!(Flags & parse_no_element_values)) if (*node->value() == Ch('\0')) - node->value(value, end - value); + node->value(val, end - val); // Place zero terminator after value if (!(Flags & parse_no_string_terminators)) @@ -2010,7 +1975,7 @@ namespace rapidxml while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) { if (!text[0]) - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } text += 3; // Skip ]]> @@ -2018,17 +1983,17 @@ namespace rapidxml } // Skip until end of cdata - Ch *value = text; + Ch *val = text; while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) { if (!text[0]) - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } // Create new cdata node xml_node *cdata = this->allocate_node(node_cdata); - cdata->value(value, text - value); + cdata->value(val, text - val); // Place zero terminator after value if (!(Flags & parse_no_string_terminators)) @@ -2046,11 +2011,11 @@ namespace rapidxml xml_node *element = this->allocate_node(node_element); // Extract element name - Ch *name = text; + Ch *n = text; skip(text); - if (text == name) - RAPIDXML_PARSE_ERROR("expected element name", text); - element->name(name, text - name); + if (text == n) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected element name", text); + element->name(n, text - n); // Skip whitespace between element name and attributes or > skip(text); @@ -2068,11 +2033,11 @@ namespace rapidxml { ++text; if (*text != Ch('>')) - RAPIDXML_PARSE_ERROR("expected >", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text); ++text; } else - RAPIDXML_PARSE_ERROR("expected >", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text); // Place zero terminator after name if (!(Flags & parse_no_string_terminators)) @@ -2151,6 +2116,9 @@ namespace rapidxml text += 9; // skip '!DOCTYPE ' return parse_doctype(text); } + break; + + default: break; } // switch @@ -2159,7 +2127,7 @@ namespace rapidxml while (*text != Ch('>')) { if (*text == 0) - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } ++text; // Skip '>' @@ -2177,7 +2145,8 @@ namespace rapidxml { // Skip whitespace between > and node contents Ch *contents_start = text; // Store start of node contents before whitespace is skipped - skip(text); + if (Flags & parse_trim_whitespace) + skip(text); Ch next_char = *text; // After data nodes, instead of continuing the loop, control jumps here. @@ -2202,7 +2171,7 @@ namespace rapidxml Ch *closing_name = text; skip(text); if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true)) - RAPIDXML_PARSE_ERROR("invalid closing tag name", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid closing tag name", text); } else { @@ -2212,7 +2181,7 @@ namespace rapidxml // Skip remaining whitespace after node name skip(text); if (*text != Ch('>')) - RAPIDXML_PARSE_ERROR("expected >", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text); ++text; // Skip '>' return; // Node closed, finished parsing contents } @@ -2227,7 +2196,7 @@ namespace rapidxml // End of data - error case Ch('\0'): - RAPIDXML_PARSE_ERROR("unexpected end of data", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); // Data node default: @@ -2246,15 +2215,15 @@ namespace rapidxml while (attribute_name_pred::test(*text)) { // Extract attribute name - Ch *name = text; + Ch *n = text; ++text; // Skip first character of attribute name skip(text); - if (text == name) - RAPIDXML_PARSE_ERROR("expected attribute name", name); + if (text == n) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected attribute name", n); // Create new attribute xml_attribute *attribute = this->allocate_attribute(); - attribute->name(name, text - name); + attribute->name(n, text - n); node->append_attribute(attribute); // Skip whitespace after attribute name @@ -2262,7 +2231,7 @@ namespace rapidxml // Skip = if (*text != Ch('=')) - RAPIDXML_PARSE_ERROR("expected =", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected =", text); ++text; // Add terminating zero after name @@ -2275,11 +2244,11 @@ namespace rapidxml // Skip quote and remember if it was ' or " Ch quote = *text; if (quote != Ch('\'') && quote != Ch('"')) - RAPIDXML_PARSE_ERROR("expected ' or \"", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text); ++text; // Extract attribute value and expand char refs in it - Ch *value = text, *end; + Ch *val = text, *end; const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes if (quote == Ch('\'')) end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags>(text); @@ -2287,11 +2256,11 @@ namespace rapidxml end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags>(text); // Set attribute value - attribute->value(value, end - value); + attribute->value(val, end - val); // Make sure that end quote is present if (*text != quote) - RAPIDXML_PARSE_ERROR("expected ' or \"", text); + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text); ++text; // Skip quote // Add terminating zero after value @@ -2589,10 +2558,10 @@ namespace rapidxml } //! \endcond -} +}}}} // Undefine internal macros -#undef RAPIDXML_PARSE_ERROR +#undef BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR // On MSVC, restore warnings state #ifdef _MSC_VER diff --git a/include/boost/property_tree/detail/xml_parser_error.hpp b/include/boost/property_tree/detail/xml_parser_error.hpp index 3410a04..c79835c 100644 --- a/include/boost/property_tree/detail/xml_parser_error.hpp +++ b/include/boost/property_tree/detail/xml_parser_error.hpp @@ -20,10 +20,10 @@ namespace boost { namespace property_tree { namespace xml_parser class xml_parser_error: public file_parser_error { public: - xml_parser_error(const std::string &message, - const std::string &filename, - unsigned long line): - file_parser_error(message, filename, line) + xml_parser_error(const std::string &msg, + const std::string &file, + unsigned long l): + file_parser_error(msg, file, l) { } }; diff --git a/include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp b/include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp index d271d5e..acec34d 100644 --- a/include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp +++ b/include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp @@ -21,49 +21,58 @@ namespace boost { namespace property_tree { namespace xml_parser { template - void read_xml_node(rapidxml::xml_node *node, Ptree &pt, int flags) + void read_xml_node(detail::rapidxml::xml_node *node, + Ptree &pt, int flags) { + using namespace detail::rapidxml; switch (node->type()) { // Element nodes - case rapidxml::node_element: + case node_element: { // Create node - Ptree &pt_node = pt.push_back(std::make_pair(node->name(), Ptree()))->second; - + Ptree &pt_node = pt.push_back(std::make_pair(node->name(), + Ptree()))->second; + // Copy attributes if (node->first_attribute()) { - Ptree &pt_attr_root = pt_node.push_back(std::make_pair(xmlattr(), Ptree()))->second; - for (rapidxml::xml_attribute *attr = node->first_attribute(); attr; attr = attr->next_attribute()) + Ptree &pt_attr_root = pt_node.push_back( + std::make_pair(xmlattr(), Ptree()))->second; + for (xml_attribute *attr = node->first_attribute(); + attr; attr = attr->next_attribute()) { - Ptree &pt_attr = pt_attr_root.push_back(std::make_pair(attr->name(), Ptree()))->second; + Ptree &pt_attr = pt_attr_root.push_back( + std::make_pair(attr->name(), Ptree()))->second; pt_attr.data() = attr->value(); } } // Copy children - for (rapidxml::xml_node *child = node->first_node(); child; child = child->next_sibling()) + for (xml_node *child = node->first_node(); + child; child = child->next_sibling()) read_xml_node(child, pt_node, flags); } break; // Data nodes - case rapidxml::node_data: - case rapidxml::node_cdata: + case node_data: + case node_cdata: { if (flags & no_concat_text) - pt.push_back(std::make_pair(xmltext(), Ptree(node->value()))); + pt.push_back(std::make_pair(xmltext(), + Ptree(node->value()))); else pt.data() += node->value(); } break; // Comment nodes - case rapidxml::node_comment: + case node_comment: { if (!(flags & no_comments)) - pt.push_back(std::make_pair(xmlcomment(), Ptree(node->value()))); + pt.push_back(std::make_pair(xmlcomment(), + Ptree(node->value()))); } break; @@ -81,6 +90,7 @@ namespace boost { namespace property_tree { namespace xml_parser const std::string &filename) { typedef typename Ptree::key_type::value_type Ch; + using namespace detail::rapidxml; // Load data into vector stream.unsetf(std::ios::skipws); @@ -93,10 +103,13 @@ namespace boost { namespace property_tree { namespace xml_parser try { // Parse using appropriate flags - using namespace rapidxml; const int f_tws = parse_normalize_whitespace | parse_trim_whitespace; const int f_c = parse_comment_nodes; + // Some compilers don't like the bitwise or in the template arg. + const int f_tws_c = parse_normalize_whitespace + | parse_trim_whitespace + | parse_comment_nodes; xml_document doc; if (flags & no_comments) { if (flags & trim_whitespace) @@ -105,19 +118,20 @@ namespace boost { namespace property_tree { namespace xml_parser doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front()); } else { if (flags & trim_whitespace) - doc.BOOST_NESTED_TEMPLATE parse(&v.front()); + doc.BOOST_NESTED_TEMPLATE parse(&v.front()); else doc.BOOST_NESTED_TEMPLATE parse(&v.front()); } // Create ptree from nodes Ptree local; - for (rapidxml::xml_node *child = doc.first_node(); child; child = child->next_sibling()) + for (xml_node *child = doc.first_node(); + child; child = child->next_sibling()) read_xml_node(child, local, flags); // Swap local and result ptrees pt.swap(local); - } catch (rapidxml::parse_error &e) { + } catch (parse_error &e) { long line = static_cast( std::count(&v.front(), e.where(), Ch('\n')) + 1); BOOST_PROPERTY_TREE_THROW( diff --git a/include/boost/property_tree/detail/xml_parser_utils.hpp b/include/boost/property_tree/detail/xml_parser_utils.hpp index 995bea6..7c8a6e1 100644 --- a/include/boost/property_tree/detail/xml_parser_utils.hpp +++ b/include/boost/property_tree/detail/xml_parser_utils.hpp @@ -44,6 +44,9 @@ namespace boost { namespace property_tree { namespace xml_parser template std::basic_string encode_char_entities(const std::basic_string &s) { + // Don't do anything for empty strings. + if(s.empty()) return s; + typedef typename std::basic_string Str; Str r; // To properly round-trip spaces and not uglify the XML beyond diff --git a/include/boost/property_tree/detail/xml_parser_write.hpp b/include/boost/property_tree/detail/xml_parser_write.hpp index 77423a0..614854e 100644 --- a/include/boost/property_tree/detail/xml_parser_write.hpp +++ b/include/boost/property_tree/detail/xml_parser_write.hpp @@ -31,14 +31,18 @@ namespace boost { namespace property_tree { namespace xml_parser void write_xml_comment(std::basic_ostream &stream, const std::basic_string &s, int indent, + bool separate_line, const xml_writer_settings & settings ) { typedef typename std::basic_string Str; - write_xml_indent(stream,indent,settings); + if (separate_line) + write_xml_indent(stream,indent,settings); stream << Ch('<') << Ch('!') << Ch('-') << Ch('-'); stream << s; - stream << Ch('-') << Ch('-') << Ch('>') << std::endl; + stream << Ch('-') << Ch('-') << Ch('>'); + if (separate_line) + stream << Ch('\n'); } template @@ -52,7 +56,7 @@ namespace boost { namespace property_tree { namespace xml_parser if (separate_line) write_xml_indent(stream,indent,settings); stream << encode_char_entities(s); - if (separate_line) + if (separate_line) stream << Ch('\n'); } @@ -92,7 +96,9 @@ namespace boost { namespace property_tree { namespace xml_parser { write_xml_indent(stream,indent,settings); stream << Ch('<') << key << - Ch('/') << Ch('>') << std::endl; + Ch('/') << Ch('>'); + if (want_pretty) + stream << Ch('\n'); } } else // Nonempty key @@ -144,7 +150,7 @@ namespace boost { namespace property_tree { namespace xml_parser else if (it->first == xmlcomment()) write_xml_comment(stream, it->second.template get_value >(), - indent + 1, settings); + indent + 1, want_pretty, settings); else if (it->first == xmltext()) write_xml_text(stream, it->second.template get_value >(), diff --git a/include/boost/property_tree/detail/xml_parser_writer_settings.hpp b/include/boost/property_tree/detail/xml_parser_writer_settings.hpp index 678c213..0cc707a 100644 --- a/include/boost/property_tree/detail/xml_parser_writer_settings.hpp +++ b/include/boost/property_tree/detail/xml_parser_writer_settings.hpp @@ -35,12 +35,12 @@ namespace boost { namespace property_tree { namespace xml_parser class xml_writer_settings { public: - xml_writer_settings(Ch indent_char = Ch(' '), - typename std::basic_string::size_type indent_count = 0, - const std::basic_string &encoding = widen("utf-8")) - : indent_char(indent_char) - , indent_count(indent_count) - , encoding(encoding) + xml_writer_settings(Ch inchar = Ch(' '), + typename std::basic_string::size_type incount = 0, + const std::basic_string &enc = widen("utf-8")) + : indent_char(inchar) + , indent_count(incount) + , encoding(enc) { } diff --git a/include/boost/property_tree/json_parser.hpp b/include/boost/property_tree/json_parser.hpp index 3199d2d..d3bc32e 100644 --- a/include/boost/property_tree/json_parser.hpp +++ b/include/boost/property_tree/json_parser.hpp @@ -85,14 +85,17 @@ namespace boost { namespace property_tree { namespace json_parser * @param stream The stream to which to write the JSON representation of the * property tree. * @param pt The property tree to tranlsate to JSON and output. + * @param pretty Whether to pretty-print. Defaults to true for backward + * compatibility. */ template void write_json(std::basic_ostream< typename Ptree::key_type::value_type > &stream, - const Ptree &pt) + const Ptree &pt, + bool pretty = true) { - write_json_internal(stream, pt, std::string()); + write_json_internal(stream, pt, std::string(), pretty); } /** @@ -106,11 +109,14 @@ namespace boost { namespace property_tree { namespace json_parser * representation of the property tree. * @param pt The property tree to translate to JSON and output. * @param loc The locale to use when writing out to the output file. + * @param pretty Whether to pretty-print. Defaults to true and last place + * for backward compatibility. */ template void write_json(const std::string &filename, const Ptree &pt, - const std::locale &loc = std::locale()) + const std::locale &loc = std::locale(), + bool pretty = true) { std::basic_ofstream stream(filename.c_str()); @@ -118,7 +124,7 @@ namespace boost { namespace property_tree { namespace json_parser BOOST_PROPERTY_TREE_THROW(json_parser_error( "cannot open file", filename, 0)); stream.imbue(loc); - write_json_internal(stream, pt, filename); + write_json_internal(stream, pt, filename, pretty); } } } } diff --git a/include/boost/property_tree/ptree_fwd.hpp b/include/boost/property_tree/ptree_fwd.hpp index d8e2f14..fe36741 100644 --- a/include/boost/property_tree/ptree_fwd.hpp +++ b/include/boost/property_tree/ptree_fwd.hpp @@ -13,6 +13,7 @@ #include #include +#include #include // for std::less #include // for std::allocator #include @@ -87,9 +88,6 @@ namespace boost { namespace property_tree /** Implements a path using a std::string as the key. */ typedef string_path > path; - /** Implements a path using a std::wstring as the key. */ - typedef string_path > wpath; - /** * A property tree with std::string for key and data, and default * comparison. @@ -104,7 +102,10 @@ namespace boost { namespace property_tree detail::less_nocase > iptree; -#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_STD_WSTRING + /** Implements a path using a std::wstring as the key. */ + typedef string_path > wpath; + /** * A property tree with std::wstring for key and data, and default * comparison. @@ -136,7 +137,7 @@ namespace boost { namespace property_tree #if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED) // Throwing macro to avoid no return warnings portably -# define BOOST_PROPERTY_TREE_THROW(e) { throw_exception(e); std::exit(1); } +# define BOOST_PROPERTY_TREE_THROW(e) BOOST_THROW_EXCEPTION(e) #endif #endif diff --git a/include/boost/property_tree/string_path.hpp b/include/boost/property_tree/string_path.hpp index 73762c7..1d92994 100644 --- a/include/boost/property_tree/string_path.hpp +++ b/include/boost/property_tree/string_path.hpp @@ -57,10 +57,12 @@ namespace boost { namespace property_tree { return s; } +#ifndef BOOST_NO_STD_WSTRING inline std::string dump_sequence(const std::wstring &s) { return narrow(s.c_str()); } +#endif } /// Default path class. A path is a sequence of values. Groups of values