| #include "locale_test.h" |
| |
| #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS) |
| # include <sstream> |
| # include <locale> |
| # include <stdexcept> |
| |
| # if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) |
| using namespace std; |
| # endif |
| |
| static const char* tested_locales[] = { |
| //name, |
| # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) |
| "fr_FR", |
| "ru_RU.koi8r", |
| "en_GB", |
| "en_US", |
| # endif |
| "", |
| "C" |
| }; |
| |
| CPPUNIT_TEST_SUITE_REGISTRATION(LocaleTest); |
| |
| // |
| // tests implementation |
| // |
| typedef void (LocaleTest::*_Test) (const locale&); |
| static void test_supported_locale(LocaleTest &inst, _Test __test) { |
| size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]); |
| for (size_t i = 0; i < n; ++i) { |
| locale loc; |
| # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) |
| try { |
| # endif |
| locale tmp(tested_locales[i]); |
| loc = tmp; |
| # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) |
| } |
| catch (runtime_error const&) { |
| //This locale is not supported. |
| continue; |
| } |
| # endif |
| CPPUNIT_MESSAGE( loc.name().c_str() ); |
| (inst.*__test)(loc); |
| } |
| } |
| |
| void LocaleTest::locale_by_name() { |
| # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) |
| /* |
| * Check of the 22.1.1.2.7 standard point. Construction of a locale |
| * instance from a null pointer or an unknown name should result in |
| * a runtime_error exception. |
| */ |
| try { |
| locale loc(static_cast<char const*>(0)); |
| CPPUNIT_FAIL; |
| } |
| catch (runtime_error const&) { |
| } |
| catch (...) { |
| CPPUNIT_FAIL; |
| } |
| |
| try { |
| locale loc("yasli_language"); |
| CPPUNIT_FAIL; |
| } |
| catch (runtime_error const& /* e */) { |
| //CPPUNIT_MESSAGE( e.what() ); |
| } |
| catch (...) { |
| CPPUNIT_FAIL; |
| } |
| |
| try { |
| string very_large_locale_name(1024, '?'); |
| locale loc(very_large_locale_name.c_str()); |
| CPPUNIT_FAIL; |
| } |
| catch (runtime_error const& /* e */) { |
| //CPPUNIT_MESSAGE( e.what() ); |
| } |
| catch (...) { |
| CPPUNIT_FAIL; |
| } |
| |
| #if defined (STLPORT) || !defined (_MSC_VER) || (_MSC_VER > 1400) |
| try { |
| string very_large_locale_name("LC_CTYPE="); |
| very_large_locale_name.append(1024, '?'); |
| locale loc(very_large_locale_name.c_str()); |
| CPPUNIT_FAIL; |
| } |
| catch (runtime_error const& /* e */) { |
| //CPPUNIT_MESSAGE( e.what() ); |
| } |
| catch (...) { |
| CPPUNIT_FAIL; |
| } |
| |
| try { |
| string very_large_locale_name("LC_ALL="); |
| very_large_locale_name.append(1024, '?'); |
| locale loc(very_large_locale_name.c_str()); |
| CPPUNIT_FAIL; |
| } |
| catch (runtime_error const& /* e */) { |
| //CPPUNIT_MESSAGE( e.what() ); |
| } |
| catch (...) { |
| CPPUNIT_FAIL; |
| } |
| #endif |
| |
| try { |
| locale loc("C"); |
| } |
| catch (runtime_error const& /* e */) { |
| /* CPPUNIT_MESSAGE( e.what() ); */ |
| CPPUNIT_FAIL; |
| } |
| catch (...) { |
| CPPUNIT_FAIL; |
| } |
| |
| try { |
| // On platform without real localization support we should rely on the "C" locale facet. |
| locale loc(""); |
| } |
| catch (runtime_error const& /* e */) { |
| /* CPPUNIT_MESSAGE( e.what() ); */ |
| CPPUNIT_FAIL; |
| } |
| catch (...) { |
| CPPUNIT_FAIL; |
| } |
| |
| # endif |
| } |
| |
| void LocaleTest::loc_has_facet() { |
| locale loc("C"); |
| typedef numpunct<char> implemented_facet; |
| CPPUNIT_ASSERT( has_facet<implemented_facet>(loc) ); |
| /* |
| typedef num_put<char, back_insert_iterator<string> > not_implemented_facet; |
| CPPUNIT_ASSERT( !has_facet<not_implemented_facet>(loc) ); |
| */ |
| } |
| |
| void LocaleTest::locale_init_problem() { |
| # if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES) |
| test_supported_locale(*this, &LocaleTest::_locale_init_problem); |
| # endif |
| } |
| |
| /* |
| * Creation of a locale instance imply initialization of some STLport internal |
| * static objects first. We use a static instance of locale to check that this |
| * initialization is done correctly. |
| */ |
| static locale global_loc; |
| static locale other_loc(""); |
| |
| # if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES) |
| void LocaleTest::_locale_init_problem( const locale& loc) |
| { |
| # if !defined (__APPLE__) && !defined (__FreeBSD__) || \ |
| !defined(__GNUC__) || ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__> 3))) |
| typedef codecvt<char,char,mbstate_t> my_facet; |
| # else |
| // std::mbstate_t required for gcc 3.3.2 on FreeBSD... |
| // I am not sure what key here---FreeBSD or 3.3.2... |
| // - ptr 2005-04-04 |
| typedef codecvt<char,char,std::mbstate_t> my_facet; |
| # endif |
| |
| locale loc_ref(global_loc); |
| { |
| locale gloc( loc_ref, new my_facet() ); |
| CPPUNIT_ASSERT( has_facet<my_facet>( gloc ) ); |
| //The following code is just here to try to confuse the reference counting underlying mecanism: |
| locale::global( locale::classic() ); |
| locale::global( gloc ); |
| } |
| |
| # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) |
| try { |
| # endif |
| ostringstream os("test") ; |
| locale loc2( loc, new my_facet() ); |
| CPPUNIT_ASSERT( has_facet<my_facet>( loc2 ) ); |
| os.imbue( loc2 ); |
| # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) |
| } |
| catch ( runtime_error& ) { |
| CPPUNIT_FAIL; |
| } |
| catch ( ... ) { |
| CPPUNIT_FAIL; |
| } |
| # endif |
| |
| # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) |
| try { |
| # endif |
| ostringstream os2("test2"); |
| # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) |
| } |
| catch ( runtime_error& ) { |
| CPPUNIT_FAIL; |
| } |
| catch ( ... ) { |
| CPPUNIT_FAIL; |
| } |
| # endif |
| } |
| #endif |
| |
| void LocaleTest::default_locale() |
| { |
| locale loc( "" ); |
| } |
| |
| class dummy_facet : public locale::facet { |
| public: |
| static locale::id id; |
| }; |
| |
| locale::id dummy_facet::id; |
| |
| void LocaleTest::combine() |
| { |
| # if (!defined (STLPORT) || \ |
| (defined (_STLP_USE_EXCEPTIONS) && !defined (_STLP_NO_MEMBER_TEMPLATES) && !defined (_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS))) |
| { |
| try { |
| locale loc(""); |
| if (!has_facet<messages<char> >(loc)) { |
| loc.combine<messages<char> >(loc); |
| CPPUNIT_FAIL; |
| } |
| } |
| catch (const runtime_error & /* e */) { |
| /* CPPUNIT_MESSAGE( e.what() ); */ |
| } |
| |
| try { |
| locale loc; |
| if (!has_facet<dummy_facet>(loc)) { |
| loc.combine<dummy_facet>(loc); |
| CPPUNIT_FAIL; |
| } |
| } |
| catch (const runtime_error & /* e */) { |
| /* CPPUNIT_MESSAGE( e.what() ); */ |
| } |
| } |
| |
| locale loc1(locale::classic()), loc2; |
| size_t loc1_index = 0; |
| for (size_t i = 0; _get_ref_monetary(i) != 0; ++i) { |
| try { |
| { |
| locale loc(_get_ref_monetary_name(_get_ref_monetary(i))); |
| if (loc1 == locale::classic()) |
| { |
| loc1 = loc; |
| loc1_index = i; |
| continue; |
| } |
| else |
| { |
| loc2 = loc; |
| } |
| } |
| |
| //We can start the test |
| ostringstream ostr; |
| ostr << "combining '" << loc2.name() << "' money facets with '" << loc1.name() << "'"; |
| CPPUNIT_MESSAGE( ostr.str().c_str() ); |
| |
| //We are going to combine money facets as all formats are different. |
| { |
| //We check that resulting locale has correctly acquire loc2 facets. |
| locale loc = loc1.combine<moneypunct<char, true> >(loc2); |
| loc = loc.combine<moneypunct<char, false> >(loc2); |
| loc = loc.combine<money_put<char> >(loc2); |
| loc = loc.combine<money_get<char> >(loc2); |
| |
| //Check loc has the correct facets: |
| _money_put_get2(loc2, loc, _get_ref_monetary(i)); |
| |
| //Check loc1 has not been impacted: |
| _money_put_get2(loc1, loc1, _get_ref_monetary(loc1_index)); |
| |
| //Check loc2 has not been impacted: |
| _money_put_get2(loc2, loc2, _get_ref_monetary(i)); |
| } |
| { |
| //We check that resulting locale has not wrongly acquire loc1 facets that hasn't been combine: |
| locale loc = loc2.combine<numpunct<char> >(loc1); |
| loc = loc.combine<time_put<char> >(loc1); |
| loc = loc.combine<time_get<char> >(loc1); |
| |
| //Check loc has the correct facets: |
| _money_put_get2(loc2, loc, _get_ref_monetary(i)); |
| |
| //Check loc1 has not been impacted: |
| _money_put_get2(loc1, loc1, _get_ref_monetary(loc1_index)); |
| |
| //Check loc2 has not been impacted: |
| _money_put_get2(loc2, loc2, _get_ref_monetary(i)); |
| } |
| |
| { |
| // Check auto combination do not result in weird reference counting behavior |
| // (might generate a crash). |
| loc1.combine<numpunct<char> >(loc1); |
| } |
| |
| loc1 = loc2; |
| loc1_index = i; |
| } |
| catch (runtime_error const&) { |
| //This locale is not supported. |
| continue; |
| } |
| } |
| # endif |
| } |
| |
| #endif |