Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55215 - in sandbox/pinhole: boost/pinhole libs/pinhole/test
From: jmcintyre_at_[hidden]
Date: 2009-07-30 14:43:38


Author: jared
Date: 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
New Revision: 55215
URL: http://svn.boost.org/trac/boost/changeset/55215

Log:
Pinhole: Properties could cause memory corruption if an old property was replaced with a new one.
Exceptions now use boost::exception
select helper functions now use parser from depth-first search
Text files modified:
   sandbox/pinhole/boost/pinhole/exceptions.hpp | 23 +++++--
   sandbox/pinhole/boost/pinhole/find.hpp | 116 +++++++++++++++++----------------------
   sandbox/pinhole/boost/pinhole/property_group.hpp | 88 +++++++++++++----------------
   sandbox/pinhole/boost/pinhole/property_info.hpp | 6 +
   sandbox/pinhole/boost/pinhole/property_manager.hpp | 22 ++++++-
   sandbox/pinhole/boost/pinhole/value.hpp | 38 +++++++-----
   sandbox/pinhole/libs/pinhole/test/Jamfile.v2 | 3
   sandbox/pinhole/libs/pinhole/test/test_tokenizer.cpp | 23 +++++++
   8 files changed, 179 insertions(+), 140 deletions(-)

Modified: sandbox/pinhole/boost/pinhole/exceptions.hpp
==============================================================================
--- sandbox/pinhole/boost/pinhole/exceptions.hpp (original)
+++ sandbox/pinhole/boost/pinhole/exceptions.hpp 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
@@ -11,26 +11,37 @@
 #include <exception>
 #include <stdexcept>
 #include <string>
+#include <boost/exception.hpp>
 
 namespace boost { namespace pinhole
 {
- class multiple_property_groups : public std::runtime_error
+ class multiple_property_groups : public std::runtime_error, public ::boost::exception
     {
         public: multiple_property_groups(const std::string& strErrMsg) : std::runtime_error(strErrMsg) {;}
     };
 
- class invalid_path : public std::runtime_error
+ class invalid_path : public std::runtime_error, public ::boost::exception
     {
         public: invalid_path(const std::string& strErrMsg) : std::runtime_error(strErrMsg) {;}
     };
 
- class failed_to_find_group : public std::exception{};
+ class failed_to_find_group : public std::runtime_error, public ::boost::exception
+ {
+ public: failed_to_find_group(const std::string& strErrMsg) : std::runtime_error(strErrMsg) {;}
+ };
     
- class no_metadata_defined_error : public std::runtime_error
+ class no_metadata_defined : public std::runtime_error, public ::boost::exception
     {
- public:
- no_metadata_defined_error() : runtime_error( "No Property Editor Defined" ) {;}
+ public: no_metadata_defined() : runtime_error( "No metadata defined for property" ) {;}
     };
+
+ typedef boost::error_info< struct tag_requested_type, const std::string > exception_requested_type;
+ typedef boost::error_info< struct tag_property_name, const std::string > exception_property_name;
+ typedef boost::error_info< struct tag_property_type, const std::string > exception_property_type;
+ typedef boost::error_info< struct tag_actual_type, const std::string > exception_actual_type;
+ typedef boost::error_info< struct tag_action_name, const std::string > exception_action_name;
+ typedef boost::error_info< struct tag_path, const std::string > exception_path;
+ typedef boost::error_info< struct tag_path_section, const std::string > exception_path_section;
 }}
 
 #endif // include guard
\ No newline at end of file

Modified: sandbox/pinhole/boost/pinhole/find.hpp
==============================================================================
--- sandbox/pinhole/boost/pinhole/find.hpp (original)
+++ sandbox/pinhole/boost/pinhole/find.hpp 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
@@ -10,11 +10,24 @@
 
 #include <vector>
 
-#include "./detail/path.hpp"
+#include "./detail/tokenizer.hpp"
 #include "path_filtered_iterator.hpp"
 
 namespace boost { namespace pinhole
 {
+ namespace detail
+ {
+ inline
+ void ThrowIfPathIsRelative(const std::string& path)
+ {
+ if( path.length() > 0 && path[0] != '/' )
+ {
+ throw boost::pinhole::invalid_path("A relative path was requested, but no property_group to search from was given.")
+ << ::boost::pinhole::exception_path(path);
+ }
+ }
+ }
+
     /**
      * Returns a property_group based on a path that describes where that property_group
      * exists within the property group hierarchy. This path can either be from the
@@ -45,87 +58,62 @@
      */
     inline boost::pinhole::property_group* select_single_node(boost::pinhole::property_group* current_property_group, const std::string& path)
     {
- std::pair<boost::pinhole::children_collection::iterator,boost::pinhole::children_collection::iterator> range;
+ typedef boost::iterator_range< boost::pinhole::children_collection::iterator > child_range;
+
+ child_range range;
 
         if( NULL != current_property_group )
         {
- range.first = current_property_group->get_children_collection().begin();
- range.second = current_property_group->get_children_collection().end();
+ range = child_range( current_property_group->get_children_collection().begin(),
+ current_property_group->get_children_collection().end() );
         }
         else
         {
             detail::ThrowIfPathIsRelative(path);
         }
- boost::pinhole::children_collection* root_property_group_collection = 0; //The root collection might not be needed if it is not referred.
-
- typedef std::vector< std::string > split_vector_type;
- split_vector_type vecproperty_groups;
- boost::split( vecproperty_groups, path, boost::is_any_of("/") ); //Note: "/" is the separator for a property group
- try
+
+ detail::token_path token_path;
+ process_path( path, token_path );
+
+ if( false == token_path.relative_path )
         {
- for(split_vector_type::const_iterator iter_property_group = vecproperty_groups.begin(); iter_property_group != vecproperty_groups.end(); iter_property_group++)
+ boost::pinhole::property_manager::instance_type manager = boost::pinhole::property_manager::instance();
+ range = child_range(manager->begin(), manager->end() );
+ }
+
+ boost::pinhole::property_group* property_group_found = NULL;
+
+ BOOST_FOREACH( const boost::pinhole::detail::token_path::token& token, token_path.tokens )
+ {
+ property_group_found = NULL;
+
+ BOOST_FOREACH( property_group* group, range )
             {
- std::string strproperty_group = *iter_property_group;
- split_vector_type properties;
- boost::split( properties, strproperty_group, boost::is_any_of(".=") );
- //Note: "." is the separator between Property group name and Property name.
- //"=" is the separator between property name and property value. If there's no "." or "=",
- //we will just use this property group.
- size_t nNumOfItems = properties.size();
- switch(nNumOfItems)
+ if( token.name == group->get_name() &&
+ (true == token.property.empty() ||
+ (group->is_valid_property(token.property) && token.value == group->get_as_string(token.property)) ))
                 {
- case 1:
- {
- std::string strItem = properties[0]; //It either is "/" or the property group name.
- boost::trim(strItem);
- if(strItem.empty()) //It is "/"
- {
- boost::pinhole::property_manager::instance_type manager = boost::pinhole::property_manager::instance();
- range.first = manager->begin();
- range.second = manager->end();
- }
- else
- {
- //strItem here must be a property group name.
- //If multiple or none is found ,exception will be thrown.
- current_property_group = detail::search_single_property_group_based_on_name(range.first, range.second, strItem);
-
- range.first = current_property_group->get_children_collection().begin();
- range.second = current_property_group->get_children_collection().end();
- }
- }
- break;
- case 3:
+ if( NULL == property_group_found )
                     {
- std::string property_group_name = properties[0];
- boost::trim(property_group_name);
-
- std::string property_name = properties[1];
- boost::trim(property_name);
-
- std::string property_value = properties[2];
- boost::trim(property_value);
- current_property_group = detail::search_single_property_group_based_on_property_value(range.first, range.second, property_group_name, property_name, property_value);
-
- range.first = current_property_group->get_children_collection().begin();
- range.second = current_property_group->get_children_collection().end();
+ property_group_found = group;
                     }
- break;
- default:
+ else
                     {
- std::string strError = path + " is not a valid path. Details: " + strproperty_group + " should be either A.B=C or A format";
- throw invalid_path(strError.c_str());
+ throw ::boost::pinhole::multiple_property_groups("Requested path does not lead to a unique property group.");
                     }
                 }
             }
+
+ if( NULL == property_group_found )
+ {
+ break;
+ }
+
+ range = child_range( property_group_found->get_children_collection().begin(),
+ property_group_found->get_children_collection().end() );
         }
- catch(no_metadata_defined_error&)
- {
- current_property_group = NULL;
- }
-
- delete root_property_group_collection;
- return current_property_group;
+
+ return property_group_found;
     }
 
     inline property_group* select_single_node(boost::pinhole::property_group& current_property_group, const std::string& path)

Modified: sandbox/pinhole/boost/pinhole/property_group.hpp
==============================================================================
--- sandbox/pinhole/boost/pinhole/property_group.hpp (original)
+++ sandbox/pinhole/boost/pinhole/property_group.hpp 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
@@ -15,18 +15,12 @@
 #include "property_manager.hpp"
 #include <sstream>
 
-#if defined(BOOST_MSVC)
- #pragma warning(push)
- #pragma warning( disable: 4561)
-#endif
 #include <boost/bind.hpp>
 #include <boost/type_traits.hpp>
 #include <boost/function.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/any.hpp>
-#if defined(BOOST_MSVC)
- #pragma warning(pop)
-#endif
+#include <boost/throw_exception.hpp>
 
 #define BOOST_SETTER(c) boost::bind(c, this, _1)
 #if defined(BOOST_MSVC) && (_MSC_VER > 1310) && (_MSC_VER <= 1400)
@@ -95,6 +89,7 @@
      */
     class property_group
     {
+
     public:
         /**
          * Constructor.
@@ -334,19 +329,20 @@
                 {
                     detail::property_info_base* propInfo = (*itemItr).second;
                     
- // throws boost::bad_function_call if there isn't a get_as_string
- // function associated with this property.
- if( NULL != propInfo && typeid(Return_Type) == propInfo->m_type )
+ if( typeid(Return_Type) == propInfo->m_type )
                     {
+ // throws boost::bad_function_call if there isn't a get_as_string
+ // function associated with this property.
                         return static_cast<detail::property_info<Return_Type>*>(propInfo)->getter();
                     }
                     
- throw std::bad_cast();
+ throw ::boost::enable_error_info(std::bad_cast("Attempted to get a property using a type different from the properties type."))
+ << ::boost::pinhole::exception_property_name(property)
+ << ::boost::pinhole::exception_requested_type(typeid(Return_Type).name())
+ << ::boost::pinhole::exception_property_type(propInfo->m_type.name());
                 }
                 
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
             }
             
             /**
@@ -377,12 +373,13 @@
                         return static_cast<detail::property_info<Set_Type>*>(propInfo)->setter(value);
                     }
                     
- throw std::bad_cast();
+ throw ::boost::enable_error_info(std::bad_cast("Attempted to set a property using a type different from the properties type."))
+ << ::boost::pinhole::exception_property_name(property)
+ << ::boost::pinhole::exception_requested_type(typeid(Set_Type).name())
+ << ::boost::pinhole::exception_property_type(propInfo->m_type.name());
                 }
                 
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
             }
 
             /**
@@ -406,9 +403,7 @@
                 }
                 else
                 {
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
                 }
             }
 
@@ -433,9 +428,7 @@
                 }
                 else
                 {
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
                 }
             }
 
@@ -457,9 +450,7 @@
                     return (*itemItr).second->get_as_string();
                 }
                 
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
             }
 
             /**
@@ -480,9 +471,7 @@
                     return (*itemItr).second->get_as_wstring();
                 }
 
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
             }
 
             /**
@@ -502,9 +491,7 @@
                 }
                 else
                 {
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
                 }
             }
 
@@ -524,9 +511,7 @@
                 }
                 else
                 {
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
                 }
             }
 
@@ -547,9 +532,7 @@
                 }
                 else
                 {
- std::stringstream err;
- err << "The requested property \"" << property << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested property does not exist.")) << ::boost::pinhole::exception_property_name(property);
                 }
             }
         //@}
@@ -627,9 +610,8 @@
                 }
                 else
                 {
- std::stringstream err;
- err << "The requested action \"" << action << "\" does not exist.";
- throw std::out_of_range(err.str().c_str());
+ throw ::boost::enable_error_info(std::out_of_range("The requested action does not exist."))
+ << ::boost::pinhole::exception_action_name(action);
                 }
             }
 
@@ -758,15 +740,11 @@
                                     boost::function<Value_Type ()> getter,
                                     boost::any &metadata )
         {
- property_collection::iterator previousInstance = m_properties.find(name);
- if( m_properties.end() != previousInstance )
- {
- delete (*previousInstance).second;
- }
-
             // If you get an error here, then the type you are using for the property likely doesn't have a proper operator<< for it
             detail::property_info<Value_Type> *prop = new detail::property_info<Value_Type>();
 
+ // Fill out property information
+
             prop->m_name = name;
             prop->m_description = description;
             if( NULL != setter )
@@ -779,7 +757,19 @@
             }
             prop->m_metadata = metadata;
 
- m_properties.insert( std::make_pair(name, prop) );
+ // Store property information
+
+ property_collection::iterator previousInstance = m_properties.find(name);
+ if( m_properties.end() != previousInstance )
+ {
+ // Object already exists. Destroy existing instance and replace it.
+ delete (*previousInstance).second;
+ (*previousInstance).second = prop;
+ }
+ else
+ {
+ m_properties.insert( std::make_pair(name, prop) );
+ }
         }
 
     private:

Modified: sandbox/pinhole/boost/pinhole/property_info.hpp
==============================================================================
--- sandbox/pinhole/boost/pinhole/property_info.hpp (original)
+++ sandbox/pinhole/boost/pinhole/property_info.hpp 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
@@ -46,13 +46,17 @@
         template<typename Set_Type>
         inline void operator()( Set_Type setter, String_Type value )
         {
+ typedef boost::error_info< struct tag_requested_value, const String_Type > exception_requested_value;
+
             try
             {
                 setter( boost::lexical_cast<Value_Type>(value) );
             }
             catch(boost::bad_lexical_cast &)
             {
- throw std::invalid_argument( "An invalid property value was used to set." );
+ throw ::boost::enable_error_info(std::invalid_argument("Could not convert string to the property's type."))
+ << exception_requested_value(value)
+ << ::boost::pinhole::exception_property_type(typeid(Value_Type).name());
             }
         }
     };

Modified: sandbox/pinhole/boost/pinhole/property_manager.hpp
==============================================================================
--- sandbox/pinhole/boost/pinhole/property_manager.hpp (original)
+++ sandbox/pinhole/boost/pinhole/property_manager.hpp 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
@@ -24,6 +24,19 @@
     #pragma warning(pop)
 #endif
 
+#if defined(BOOST_HAS_DECLSPEC) && (defined(BOOST_PINHOLE_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_PINHOLE_STATIC_LINK)
+# if defined(BOOST_PINHOLE_SOURCE)
+# define BOOST_PINHOLE_DECL __declspec(dllexport)
+# define BOOST_PINHOLE_BUILD_DLL
+# else
+# define BOOST_PINHOLE_DECL __declspec(dllimport)
+# endif
+#endif
+
+#ifndef BOOST_PINHOLE_DECL
+# define BOOST_PINHOLE_DECL
+#endif
+
 namespace boost { namespace pinhole
 {
     class property_group;
@@ -31,10 +44,10 @@
     typedef std::set<std::string> category_collection;
     typedef std::list<property_group*> children_collection;
     
- class event_source
+ class BOOST_PINHOLE_DECL event_source
     {
     public :
- static event_source* instance()
+ inline static event_source* instance()
         {
             static boost::shared_ptr<boost::pinhole::event_source> instance;
 
@@ -55,6 +68,7 @@
         #if defined(BOOST_MSVC)
             #pragma warning(pop)
         #endif
+
         void raise_on_add_event( property_group *group )
         {
             add_event( group );
@@ -71,7 +85,7 @@
         
     };
 
- class property_manager
+ class BOOST_PINHOLE_DECL property_manager
     {
     public:
         typedef boost::shared_ptr<property_manager> instance_type;
@@ -88,7 +102,7 @@
         typedef boost::pinhole::category_iterator<boost::pinhole::children_collection::iterator> filtered_iterator;
         typedef boost::pinhole::category_iterator<boost::pinhole::children_collection::const_iterator> const_filtered_iterator;
         
- static instance_type instance()
+ inline static instance_type instance()
         {
             if ( !exists() ) // is it the first call?
             {

Modified: sandbox/pinhole/boost/pinhole/value.hpp
==============================================================================
--- sandbox/pinhole/boost/pinhole/value.hpp (original)
+++ sandbox/pinhole/boost/pinhole/value.hpp 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
@@ -17,19 +17,18 @@
     /**
      * Finds specified property_group and returns the value of one of its properties as the
      * type specified. Finds property_group based on a path that describes where that property_group
- * exists within the property group hierarchy. This version does not allow for relative
- * path accessing.
- * @n
+ * exists within the property group hierarchy.
+ * @n_at_n
      * Path format one: /A/X.Y=Z @n
      * A represents a property group name. The assumption is that A is the only property
      * group in the current level. The path search will start from root\
- * @n
+ * @n_at_n
      * Path format two: /A.B=C/X.Y=Z @n
      * A and X represent property group names. B and Y represent property names. C and Z
      * represent property values. The path search will start from root.
      *
      * @param current_property_group The property_group in which to search.
- * @param path The path to search with.
+ * @param path The path to search with. See format above.
      * @param property The name of the property.
      * @return The value of the property.
      * @throw invalid_path The path does not meet the requirements for a valid path.
@@ -45,18 +44,23 @@
         property_group* pGroup = select_single_node(current_property_group, path);
         if( NULL == pGroup )
         {
- throw boost::pinhole::failed_to_find_group();
+ throw ::boost::pinhole::failed_to_find_group("Property Group doesn't exist at requested path.")
+ << ::boost::pinhole::exception_path(path);
         }
         return pGroup->get<T>(property);
     }
 
+ /**
+ * @overload
+ */
     template<typename T>
     T get_single_value(const std::string& path, const std::string& property)
     {
         property_group* pGroup = select_single_node(path);
         if( NULL == pGroup )
         {
- throw boost::pinhole::failed_to_find_group();
+ throw ::boost::pinhole::failed_to_find_group("Property Group doesn't exist at requested path.")
+ << ::boost::pinhole::exception_path(path);
         }
         return pGroup->get<T>(property);
     }
@@ -64,21 +68,20 @@
     /**
      * Finds specified property_group and sets the value of one of its properties.
      * Finds property_group based on a path that describes where that property_group
- * exists within the property group hierarchy. This version does not allow for relative
- * path accessing.
- * @n
+ * exists within the property group hierarchy.
+ * @n_at_n
      * Path format one: /A/X.Y=Z @n
      * A represents a property group name. The assumption is that A is the only property
      * group in the current level. The path search will start from root\
- * @n
+ * @n_at_n
      * Path format two: /A.B=C/X.Y=Z @n
      * A and X represent property group names. B and Y represent property names. C and Z
      * represent property values. The path search will start from root.
      *
      * @param current_property_group The property_group in which to search.
- * @param path The path to search with.
+ * @param path The path to search with. See format above.
      * @param property The name of the property.
- * @return The value to set on the property.
+ * @param value the value to set on the property.
      * @throw invalid_path The path does not meet the requirements for a valid path.
      * @throw multiple_property_groups There were multiple property groups matching this path.
      * @throw failed_to_find_group The path is not found.
@@ -92,18 +95,23 @@
         property_group* pGroup = select_single_node(current_property_group, path);
         if( NULL == pGroup )
         {
- throw boost::pinhole::failed_to_find_group();
+ throw ::boost::pinhole::failed_to_find_group("Property Group doesn't exist at requested path.")
+ << ::boost::pinhole::exception_path(path);
         }
         pGroup->set<T>(property, value);
     }
 
+ /**
+ * @overload
+ */
     template<typename T>
     void set_single_value(const std::string& path, const std::string& property, T value)
     {
         property_group* pGroup = select_single_node(path);
         if( NULL == pGroup )
         {
- throw boost::pinhole::failed_to_find_group();
+ throw ::boost::pinhole::failed_to_find_group("Property Group doesn't exist at requested path.")
+ << ::boost::pinhole::exception_path(path);
         }
         pGroup->set<T>(property, value);
     }

Modified: sandbox/pinhole/libs/pinhole/test/Jamfile.v2
==============================================================================
--- sandbox/pinhole/libs/pinhole/test/Jamfile.v2 (original)
+++ sandbox/pinhole/libs/pinhole/test/Jamfile.v2 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
@@ -29,11 +29,12 @@
   [ run test_string_properties.cpp ]
   
   [ run test_actions.cpp ]
-
+
   [ run test_tokenizer.cpp ]
   [ run test_depth_first_iterator.cpp ]
   [ run test_path_filtered_iterator.cpp ]
   [ run test_category_iterator.cpp ]
   [ run test_find.cpp ]
+ [ run test_value.cpp ]
  ;
 }

Modified: sandbox/pinhole/libs/pinhole/test/test_tokenizer.cpp
==============================================================================
--- sandbox/pinhole/libs/pinhole/test/test_tokenizer.cpp (original)
+++ sandbox/pinhole/libs/pinhole/test/test_tokenizer.cpp 2009-07-27 17:43:08 EDT (Mon, 27 Jul 2009)
@@ -176,6 +176,29 @@
 
         ++ct;
     }
+
+ // obscure values
+
+ BOOST_CHECK_EQUAL( process_path("name.pro.perty=value", path), 1u);
+ BOOST_CHECK_EQUAL( path.relative_path, true );
+ BOOST_CHECK_EQUAL( path.tokens.size(), 1u );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).name, "name" );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).property, "pro.perty" );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).value, "value" );
+
+ BOOST_CHECK_EQUAL( process_path("name.property=va.lue", path), 1u);
+ BOOST_CHECK_EQUAL( path.relative_path, true );
+ BOOST_CHECK_EQUAL( path.tokens.size(), 1u );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).name, "name" );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).property, "property" );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).value, "va.lue" );
+
+ BOOST_CHECK_EQUAL( process_path("name.property=va=lue", path), 1u);
+ BOOST_CHECK_EQUAL( path.relative_path, true );
+ BOOST_CHECK_EQUAL( path.tokens.size(), 1u );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).name, "name" );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).property, "property" );
+ BOOST_CHECK_EQUAL( (*path.tokens.begin()).value, "va=lue" );
 }
 
 BOOST_AUTO_TEST_CASE( TestTokenizer_InvalidPaths )


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk