1#include "locale_test.h" 2 3#if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS) 4# include <sstream> 5# include <locale> 6# include <stdexcept> 7 8# if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) 9using namespace std; 10# endif 11 12static const char* tested_locales[] = { 13//name, 14# if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 15 "fr_FR", 16 "ru_RU.koi8r", 17 "en_GB", 18 "en_US", 19# endif 20 "", 21 "C" 22}; 23 24CPPUNIT_TEST_SUITE_REGISTRATION(LocaleTest); 25 26// 27// tests implementation 28// 29typedef void (LocaleTest::*_Test) (const locale&); 30static void test_supported_locale(LocaleTest &inst, _Test __test) { 31 size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]); 32 for (size_t i = 0; i < n; ++i) { 33 locale loc; 34# if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 35 try { 36# endif 37 locale tmp(tested_locales[i]); 38 loc = tmp; 39# if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 40 } 41 catch (runtime_error const&) { 42 //This locale is not supported. 43 continue; 44 } 45# endif 46 CPPUNIT_MESSAGE( loc.name().c_str() ); 47 (inst.*__test)(loc); 48 } 49} 50 51void LocaleTest::locale_by_name() { 52# if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 53 /* 54 * Check of the 22.1.1.2.7 standard point. Construction of a locale 55 * instance from a null pointer or an unknown name should result in 56 * a runtime_error exception. 57 */ 58 try { 59 locale loc(static_cast<char const*>(0)); 60 CPPUNIT_FAIL; 61 } 62 catch (runtime_error const&) { 63 } 64 catch (...) { 65 CPPUNIT_FAIL; 66 } 67 68 try { 69 locale loc("yasli_language"); 70 CPPUNIT_FAIL; 71 } 72 catch (runtime_error const& /* e */) { 73 //CPPUNIT_MESSAGE( e.what() ); 74 } 75 catch (...) { 76 CPPUNIT_FAIL; 77 } 78 79 try { 80 string very_large_locale_name(1024, '?'); 81 locale loc(very_large_locale_name.c_str()); 82 CPPUNIT_FAIL; 83 } 84 catch (runtime_error const& /* e */) { 85 //CPPUNIT_MESSAGE( e.what() ); 86 } 87 catch (...) { 88 CPPUNIT_FAIL; 89 } 90 91#if defined (STLPORT) || !defined (_MSC_VER) || (_MSC_VER > 1400) 92 try { 93 string very_large_locale_name("LC_CTYPE="); 94 very_large_locale_name.append(1024, '?'); 95 locale loc(very_large_locale_name.c_str()); 96 CPPUNIT_FAIL; 97 } 98 catch (runtime_error const& /* e */) { 99 //CPPUNIT_MESSAGE( e.what() ); 100 } 101 catch (...) { 102 CPPUNIT_FAIL; 103 } 104 105 try { 106 string very_large_locale_name("LC_ALL="); 107 very_large_locale_name.append(1024, '?'); 108 locale loc(very_large_locale_name.c_str()); 109 CPPUNIT_FAIL; 110 } 111 catch (runtime_error const& /* e */) { 112 //CPPUNIT_MESSAGE( e.what() ); 113 } 114 catch (...) { 115 CPPUNIT_FAIL; 116 } 117#endif 118 119 try { 120 locale loc("C"); 121 } 122 catch (runtime_error const& /* e */) { 123 /* CPPUNIT_MESSAGE( e.what() ); */ 124 CPPUNIT_FAIL; 125 } 126 catch (...) { 127 CPPUNIT_FAIL; 128 } 129 130 try { 131 // On platform without real localization support we should rely on the "C" locale facet. 132 locale loc(""); 133 } 134 catch (runtime_error const& /* e */) { 135 /* CPPUNIT_MESSAGE( e.what() ); */ 136 CPPUNIT_FAIL; 137 } 138 catch (...) { 139 CPPUNIT_FAIL; 140 } 141 142# endif 143} 144 145void LocaleTest::loc_has_facet() { 146 locale loc("C"); 147 typedef numpunct<char> implemented_facet; 148 CPPUNIT_ASSERT( has_facet<implemented_facet>(loc) ); 149 /* 150 typedef num_put<char, back_insert_iterator<string> > not_implemented_facet; 151 CPPUNIT_ASSERT( !has_facet<not_implemented_facet>(loc) ); 152 */ 153} 154 155void LocaleTest::locale_init_problem() { 156# if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES) 157 test_supported_locale(*this, &LocaleTest::_locale_init_problem); 158# endif 159} 160 161/* 162 * Creation of a locale instance imply initialization of some STLport internal 163 * static objects first. We use a static instance of locale to check that this 164 * initialization is done correctly. 165 */ 166static locale global_loc; 167static locale other_loc(""); 168 169# if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES) 170void LocaleTest::_locale_init_problem( const locale& loc) 171{ 172# if !defined (__APPLE__) && !defined (__FreeBSD__) || \ 173 !defined(__GNUC__) || ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__> 3))) 174 typedef codecvt<char,char,mbstate_t> my_facet; 175# else 176// std::mbstate_t required for gcc 3.3.2 on FreeBSD... 177// I am not sure what key here---FreeBSD or 3.3.2... 178// - ptr 2005-04-04 179 typedef codecvt<char,char,std::mbstate_t> my_facet; 180# endif 181 182 locale loc_ref(global_loc); 183 { 184 locale gloc( loc_ref, new my_facet() ); 185 CPPUNIT_ASSERT( has_facet<my_facet>( gloc ) ); 186 //The following code is just here to try to confuse the reference counting underlying mecanism: 187 locale::global( locale::classic() ); 188 locale::global( gloc ); 189 } 190 191# if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 192 try { 193# endif 194 ostringstream os("test") ; 195 locale loc2( loc, new my_facet() ); 196 CPPUNIT_ASSERT( has_facet<my_facet>( loc2 ) ); 197 os.imbue( loc2 ); 198# if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 199 } 200 catch ( runtime_error& ) { 201 CPPUNIT_FAIL; 202 } 203 catch ( ... ) { 204 CPPUNIT_FAIL; 205 } 206# endif 207 208# if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 209 try { 210# endif 211 ostringstream os2("test2"); 212# if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 213 } 214 catch ( runtime_error& ) { 215 CPPUNIT_FAIL; 216 } 217 catch ( ... ) { 218 CPPUNIT_FAIL; 219 } 220# endif 221} 222#endif 223 224void LocaleTest::default_locale() 225{ 226 locale loc( "" ); 227} 228 229class dummy_facet : public locale::facet { 230public: 231 static locale::id id; 232}; 233 234locale::id dummy_facet::id; 235 236void LocaleTest::combine() 237{ 238# if (!defined (STLPORT) || \ 239 (defined (_STLP_USE_EXCEPTIONS) && !defined (_STLP_NO_MEMBER_TEMPLATES) && !defined (_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS))) 240 { 241 try { 242 locale loc(""); 243 if (!has_facet<messages<char> >(loc)) { 244 loc.combine<messages<char> >(loc); 245 CPPUNIT_FAIL; 246 } 247 } 248 catch (const runtime_error & /* e */) { 249 /* CPPUNIT_MESSAGE( e.what() ); */ 250 } 251 252 try { 253 locale loc; 254 if (!has_facet<dummy_facet>(loc)) { 255 loc.combine<dummy_facet>(loc); 256 CPPUNIT_FAIL; 257 } 258 } 259 catch (const runtime_error & /* e */) { 260 /* CPPUNIT_MESSAGE( e.what() ); */ 261 } 262 } 263 264 locale loc1(locale::classic()), loc2; 265 size_t loc1_index = 0; 266 for (size_t i = 0; _get_ref_monetary(i) != 0; ++i) { 267 try { 268 { 269 locale loc(_get_ref_monetary_name(_get_ref_monetary(i))); 270 if (loc1 == locale::classic()) 271 { 272 loc1 = loc; 273 loc1_index = i; 274 continue; 275 } 276 else 277 { 278 loc2 = loc; 279 } 280 } 281 282 //We can start the test 283 ostringstream ostr; 284 ostr << "combining '" << loc2.name() << "' money facets with '" << loc1.name() << "'"; 285 CPPUNIT_MESSAGE( ostr.str().c_str() ); 286 287 //We are going to combine money facets as all formats are different. 288 { 289 //We check that resulting locale has correctly acquire loc2 facets. 290 locale loc = loc1.combine<moneypunct<char, true> >(loc2); 291 loc = loc.combine<moneypunct<char, false> >(loc2); 292 loc = loc.combine<money_put<char> >(loc2); 293 loc = loc.combine<money_get<char> >(loc2); 294 295 //Check loc has the correct facets: 296 _money_put_get2(loc2, loc, _get_ref_monetary(i)); 297 298 //Check loc1 has not been impacted: 299 _money_put_get2(loc1, loc1, _get_ref_monetary(loc1_index)); 300 301 //Check loc2 has not been impacted: 302 _money_put_get2(loc2, loc2, _get_ref_monetary(i)); 303 } 304 { 305 //We check that resulting locale has not wrongly acquire loc1 facets that hasn't been combine: 306 locale loc = loc2.combine<numpunct<char> >(loc1); 307 loc = loc.combine<time_put<char> >(loc1); 308 loc = loc.combine<time_get<char> >(loc1); 309 310 //Check loc has the correct facets: 311 _money_put_get2(loc2, loc, _get_ref_monetary(i)); 312 313 //Check loc1 has not been impacted: 314 _money_put_get2(loc1, loc1, _get_ref_monetary(loc1_index)); 315 316 //Check loc2 has not been impacted: 317 _money_put_get2(loc2, loc2, _get_ref_monetary(i)); 318 } 319 320 { 321 // Check auto combination do not result in weird reference counting behavior 322 // (might generate a crash). 323 loc1.combine<numpunct<char> >(loc1); 324 } 325 326 loc1 = loc2; 327 loc1_index = i; 328 } 329 catch (runtime_error const&) { 330 //This locale is not supported. 331 continue; 332 } 333 } 334# endif 335} 336 337#endif 338