Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r63400 - in trunk: boost/filesystem/v3 libs/filesystem/v3/test
From: bdawes_at_[hidden]
Date: 2010-06-27 16:41:12


Author: bemandawes
Date: 2010-06-27 16:41:08 EDT (Sun, 27 Jun 2010)
New Revision: 63400
URL: http://svn.boost.org/trac/boost/changeset/63400

Log:
Use "funny" codecvt facet instead of UTF-8 to detect failures on systems that default to UTF-8. Fix generic_string bug with codecvt argument.
Added:
   trunk/libs/filesystem/v3/test/test_codecvt.hpp (contents, props changed)
Text files modified:
   trunk/boost/filesystem/v3/path.hpp | 12 ++--
   trunk/libs/filesystem/v3/test/path_unit_test.cpp | 109 ++++++++++++++++++++++++---------------
   2 files changed, 74 insertions(+), 47 deletions(-)

Modified: trunk/boost/filesystem/v3/path.hpp
==============================================================================
--- trunk/boost/filesystem/v3/path.hpp (original)
+++ trunk/boost/filesystem/v3/path.hpp 2010-06-27 16:41:08 EDT (Sun, 27 Jun 2010)
@@ -317,8 +317,8 @@
     // On POSIX-like systems, the generic format is the same as the native format
     const std::string& generic_string() const { return m_pathname; }
     const std::string& generic_string(const codecvt_type&) const { return m_pathname; }
- const std::wstring generic_wstring() const { return wstring(); }
- const std::wstring generic_wstring(const codecvt_type&) const { return wstring(); }
+ const std::wstring generic_wstring() const { return wstring(codecvt()); }
+ const std::wstring generic_wstring(const codecvt_type& cvt) const { return wstring(cvt); }
 
 # endif
 
@@ -651,14 +651,14 @@
     { return generic_string(); }
 
   template <> inline
- std::string path::generic_string<std::string>(const codecvt_type& cvt) const
- { return generic_string(cvt); }
-
- template <> inline
   std::wstring path::generic_string<std::wstring>() const
     { return generic_wstring(); }
 
   template <> inline
+ std::string path::generic_string<std::string>(const codecvt_type& cvt) const
+ { return generic_string(cvt); }
+
+ template <> inline
   std::wstring path::generic_string<std::wstring>(const codecvt_type& cvt) const
     { return generic_wstring(cvt); }
 

Modified: trunk/libs/filesystem/v3/test/path_unit_test.cpp
==============================================================================
--- trunk/libs/filesystem/v3/test/path_unit_test.cpp (original)
+++ trunk/libs/filesystem/v3/test/path_unit_test.cpp 2010-06-27 16:41:08 EDT (Sun, 27 Jun 2010)
@@ -33,9 +33,11 @@
 
 #include <boost/filesystem/path.hpp>
 #include <boost/filesystem/detail/utf8_codecvt_facet.hpp> // for imbue tests
+#include "test_codecvt.hpp" // for codecvt arg tests
 #include <boost/detail/lightweight_test.hpp>
 
 #include <iostream>
+#include <iomanip>
 #include <sstream>
 #include <string>
 #include <locale>
@@ -51,6 +53,7 @@
 
 #define CHECK(x) check(x, __FILE__, __LINE__)
 #define PATH_IS(a, b) check_path(a, b, __FILE__, __LINE__)
+#define NATIVE_IS(p, s, ws) check_native(p, s, ws, __FILE__, __LINE__)
 #define IS(a,b) check_equal(a, b, __FILE__, __LINE__)
 
 #if defined(_MSC_VER)
@@ -67,8 +70,8 @@
 
   std::string platform(BOOST_PLATFORM);
 
- void check_path(const path & source,
- const wstring & expected, const char* file, int line)
+ void check_path(const path& source,
+ const wstring& expected, const char* file, int line)
   {
     if (source == expected) return;
 
@@ -81,9 +84,32 @@
                << L"\"\n" ;
   }
 
+# ifdef BOOST_WINDOWS_API
+ void check_native(const path& p,
+ const string&, const wstring& expected, const char* file, int line)
+# else
+ void check_native(const path& p,
+ const string& expected, const wstring&, const char* file, int line)
+# endif
+ {
+ if (p.native() == expected) return;
+
+ ++::boost::detail::test_errors();
+
+ std::cout << file << '(' << line << "): native() is not equal expected\n"
+ " native---: " << std::hex;
+ path::string_type nat(p.native());
+ for (path::string_type::const_iterator it = nat.begin(); it != nat.end(); ++it)
+ std::cout << long(*it) << ' ';
+ std::cout << "\n expected-: ";
+ for (path::string_type::const_iterator it = expected.begin(); it != expected.end(); ++it)
+ std::cout << long(*it) << ' ';
+ std::cout << std::dec << std::endl;
+ }
+
   template< class T1, class T2 >
- void check_equal(const T1 & value,
- const T2 & expected, const char* file, int line)
+ void check_equal(const T1& value,
+ const T2& expected, const char* file, int line)
   {
     if (value == expected) return;
 
@@ -630,75 +656,76 @@
   {
     std::cout << "testing codecvt arguments..." << std::endl;
 
- // U+2780 is DINGBAT CIRCLED SANS-SERIF DIGIT ONE == 0xE2 0x9E 0x80 in UTF-8
- // U+1234 is ETHIOPIC SYLLABLE SEE == 0xE1 0x88 0xB4 in UTF-8
+ const char * c1 = "a1";
+ const std::string s1(c1);
+ const std::wstring ws1(L"b2"); // off-by-one mimics test_codecvt
+ const std::string s2("y8");
+ const std::wstring ws2(L"z9");
 
- const char * c1 = "\xE2\x9E\x80\xE1\x88\xB4";
- const std::string s1("\xE2\x9E\x80\xE1\x88\xB4");
- const std::wstring ws1(L"\u2780\u1234");
+ test_codecvt cvt; // produces off-by-one values that will always differ from
+ // the system's default locale codecvt facet
 
- fs::detail::utf8_codecvt_facet cvt;
-
- int t = 0;
+ int t = 0;
 
     // constructors
- std::cout << " constructors test " << ++t << std::endl;
+ std::cout << " constructors test " << ++t << std::endl;
     path p(c1, cvt);
- std::cout << " test " << ++t << std::endl;
+ NATIVE_IS(p, s1, ws1);
+
+ std::cout << " test " << ++t << std::endl;
     path p1(s1.begin(), s1.end(), cvt);
- std::cout << " test " << ++t << std::endl;
- CHECK(p1 == path(ws1, cvt));
+ NATIVE_IS(p1, s1, ws1);
+
+ std::cout << " test " << ++t << std::endl;
+ path p2(ws2, cvt);
+ NATIVE_IS(p2, s2, ws2);
+
+ std::cout << " test " << ++t << std::endl;
+ path p3(ws2.begin(), ws2.end(), cvt);
+ NATIVE_IS(p3, s2, ws2);
+
     // path p2(p1, cvt); // fails to compile, and that is OK
 
     // assigns
     p1.clear();
- std::cout << " assigns test " << ++t << std::endl;
+ std::cout << " assigns test " << ++t << std::endl;
     p1.assign(s1,cvt);
- std::cout << " test " << ++t << std::endl;
- CHECK(p == p1);
+ NATIVE_IS(p1, s1, ws1);
     p1.clear();
- std::cout << " test " << ++t << std::endl;
+ std::cout << " test " << ++t << std::endl;
     p1.assign(s1.begin(), s1.end(), cvt);
- std::cout << " test " << ++t << std::endl;
- CHECK(p == p1);
+ NATIVE_IS(p1, s1, ws1);
     // p1.assign(p, cvt); // fails to compile, and that is OK
 
-
     // appends
     p1.clear();
- std::cout << " appends test " << ++t << std::endl;
+ std::cout << " appends test " << ++t << std::endl;
     p1.append(s1,cvt);
- std::cout << " test " << ++t << std::endl;
- CHECK(p == p1);
+ NATIVE_IS(p1, s1, ws1);
     p1.clear();
- std::cout << " test " << ++t << std::endl;
+ std::cout << " test " << ++t << std::endl;
     p1.append(s1.begin(), s1.end(), cvt);
- std::cout << " test " << ++t << std::endl;
- CHECK(p == p1);
+ NATIVE_IS(p1, s1, ws1);
     // p1.append(p, cvt); // fails to compile, and that is OK
 
     // native observers
-# ifdef BOOST_WINDOWS_API
- std::cout << " (windows) test " << ++t << std::endl;
- CHECK(p.string<std::string>() != s1); // non-Windows systems may have UTF-8 as default
-# endif
- std::cout << " native observers test " << ++t << std::endl;
+ std::cout << " native observers test " << ++t << std::endl;
     CHECK(p.string<std::string>(cvt) == s1);
- std::cout << " test " << ++t << std::endl;
+ std::cout << " test " << ++t << std::endl;
     CHECK(p.string(cvt) == s1);
- std::cout << " test " << ++t << std::endl;
+ std::cout << " test " << ++t << std::endl;
     CHECK(p.string<std::wstring>(cvt) == ws1);
- std::cout << " test " << ++t << std::endl;
+ std::cout << " test " << ++t << std::endl;
     CHECK(p.wstring(cvt) == ws1);
 
     // generic observers
- std::cout << " generic observers test " << ++t << std::endl;
+ std::cout << " generic observers test " << ++t << std::endl;
     CHECK(p.generic_string<std::string>(cvt) == s1);
- std::cout << " test " << ++t << std::endl;
+ std::cout << " test " << ++t << std::endl;
     CHECK(p.generic_string(cvt) == s1);
- std::cout << " test " << ++t << std::endl;
+ std::cout << " test " << ++t << std::endl;
     CHECK(p.generic_string<std::wstring>(cvt) == ws1);
- std::cout << " test " << ++t << std::endl;
+ std::cout << " test " << ++t << std::endl;
     CHECK(p.generic_wstring(cvt) == ws1);
 
     std::cout << " codecvt arguments testing complete" << std::endl;

Added: trunk/libs/filesystem/v3/test/test_codecvt.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/filesystem/v3/test/test_codecvt.hpp 2010-06-27 16:41:08 EDT (Sun, 27 Jun 2010)
@@ -0,0 +1,78 @@
+// test_codecvt.hpp ------------------------------------------------------------------//
+
+// Copyright Beman Dawes 2009, 2010
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#ifndef BOOST_FILESYSTEM3_TEST_CODECVT_HPP
+#define BOOST_FILESYSTEM3_TEST_CODECVT_HPP
+
+#include <boost/filesystem/v3/config.hpp>
+#include <locale>
+
+ //------------------------------------------------------------------------------------//
+ // //
+ // class test_codecvt //
+ // //
+ // Warning: partial implementation; even do_in and do_out only partially meet the //
+ // standard library specifications as the "to" buffer must hold the entire result. //
+ // //
+ // The value of a wide character is the value of the corresponding narrow character //
+ // plus 1. This ensures that compares against expected values will fail if the //
+ // code conversion did not occur as expected. //
+ // //
+ //------------------------------------------------------------------------------------//
+
+ class test_codecvt
+ : public std::codecvt< wchar_t, char, std::mbstate_t >
+ {
+ public:
+ explicit test_codecvt()
+ : std::codecvt<wchar_t, char, std::mbstate_t>() {}
+ protected:
+
+ virtual bool do_always_noconv() const throw() { return false; }
+
+ virtual int do_encoding() const throw() { return 0; }
+
+ virtual std::codecvt_base::result do_in(std::mbstate_t&,
+ const char* from, const char* from_end, const char*& from_next,
+ wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const
+ {
+ for (; from != from_end && to != to_end; ++from, ++to)
+ *to = *from + 1;
+ if (to == to_end)
+ return error;
+ *to = L'\0';
+ from_next = from;
+ to_next = to;
+ return ok;
+ }
+
+ virtual std::codecvt_base::result do_out(std::mbstate_t&,
+ const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next,
+ char* to, char* to_end, char*& to_next) const
+ {
+ for (; from != from_end && to != to_end; ++from, ++to)
+ *to = static_cast<char>(*from - 1);
+ if (to == to_end)
+ return error;
+ *to = '\0';
+ from_next = from;
+ to_next = to;
+ return ok;
+ }
+
+ virtual std::codecvt_base::result do_unshift(std::mbstate_t&,
+ char* /*from*/, char* /*to*/, char* & /*next*/) const { return ok; }
+
+ virtual int do_length(std::mbstate_t&,
+ const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const { return 0; }
+
+ virtual int do_max_length() const throw () { return 0; }
+ };
+
+#endif // BOOST_FILESYSTEM3_TEST_CODECVT_HPP


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