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) 9 using namespace std; 10 # endif 11 12 static 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 24 CPPUNIT_TEST_SUITE_REGISTRATION(LocaleTest); 25 26 // 27 // tests implementation 28 // 29 typedef void (LocaleTest::*_Test) (const locale&); 30 static 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 51 void 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 145 void 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 155 void 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 */ 166 static locale global_loc; 167 static locale other_loc(""); 168 169 # if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES) 170 void 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 224 void LocaleTest::default_locale() 225 { 226 locale loc( "" ); 227 } 228 229 class dummy_facet : public locale::facet { 230 public: 231 static locale::id id; 232 }; 233 234 locale::id dummy_facet::id; 235 236 void 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