1 #include "locale_test.h" 2 3 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS) 4 # include <locale> 5 # include <sstream> 6 # include <memory> 7 # include <stdexcept> 8 9 # if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) 10 using namespace std; 11 # endif 12 13 static const char* tested_locales[] = { 14 // name, 15 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 16 "fr_FR", 17 "ru_RU.koi8r", 18 "en_GB", 19 "en_US", 20 # endif 21 "", 22 "C" 23 }; 24 25 void LocaleTest::_time_put_get( const locale& loc ) 26 { 27 { 28 typedef time_put<char, ostreambuf_iterator<char, char_traits<char> > > time_put_facet; 29 CPPUNIT_ASSERT( has_facet<time_put_facet>(loc) ); 30 const time_put_facet& tmp = use_facet<time_put_facet>(loc); 31 32 struct tm xmas = { 0, 0, 12, 25, 11, 93 }; 33 ostringstream ostr; 34 ostr.imbue(loc); 35 string format = "%B %d %Y"; 36 37 time_put_facet::iter_type ret = tmp.put(ostr, ostr, ' ', &xmas, format.data(), format.data() + format.size()); 38 CPPUNIT_ASSERT( !ret.failed() ); 39 40 /* 41 * In other words, user conformation is required for reliable parsing 42 * of user-entered dates and times, but machine-generated formats can be 43 * parsed reliably. This allows parsers to be aggressive about interpreting 44 * user variations on standard format. 45 * 46 * ISO/IEC 14882, 22.2.5.1 47 */ 48 typedef time_get<char, istreambuf_iterator<char, char_traits<char> > > time_get_facet; 49 CPPUNIT_ASSERT( has_facet<time_get_facet>(loc) ); 50 const time_get_facet& tmg = use_facet<time_get_facet>(loc); 51 basic_ios<char> io(0); 52 io.imbue(loc); 53 54 istringstream istr( ostr.str() ); 55 istreambuf_iterator<char, char_traits<char> > i( istr ); 56 istreambuf_iterator<char, char_traits<char> > e; 57 ios_base::iostate err = ios_base::goodbit; 58 struct tm other = { 15, 20, 9, 14, 7, 105 }; 59 60 i = tmg.get_monthname( i, e, io, err, &other ); 61 CPPUNIT_ASSERT( err == ios_base::goodbit ); 62 CPPUNIT_ASSERT( other.tm_mon == xmas.tm_mon ); 63 64 ++i; ++i; ++i; ++i; // skip day of month and spaces around it 65 i = tmg.get_year( i, e, io, err, &other ); 66 67 CPPUNIT_ASSERT( err == ios_base::eofbit ); 68 CPPUNIT_ASSERT( other.tm_year == xmas.tm_year ); 69 70 ostringstream ostrX; 71 ostrX.imbue(loc); 72 format = "%x %X"; 73 74 ret = tmp.put(ostrX, ostrX, ' ', &xmas, format.data(), format.data() + format.size()); 75 CPPUNIT_ASSERT( !ret.failed() ); 76 77 istringstream istrX( ostrX.str() ); 78 istreambuf_iterator<char, char_traits<char> > j( istrX ); 79 80 err = ios_base::goodbit; 81 82 struct tm yet_more = { 15, 20, 9, 14, 7, 105 }; 83 84 j = tmg.get_date( j, e, io, err, &yet_more ); 85 86 CPPUNIT_ASSERT( err == ios_base::goodbit ); 87 88 CPPUNIT_ASSERT( yet_more.tm_sec != xmas.tm_sec ); 89 CPPUNIT_ASSERT( yet_more.tm_min != xmas.tm_min ); 90 CPPUNIT_ASSERT( yet_more.tm_hour != xmas.tm_hour ); 91 CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday ); 92 CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon ); 93 CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year ); 94 95 ++j; // skip space 96 97 j = tmg.get_time( j, e, io, err, &yet_more ); 98 99 CPPUNIT_ASSERT( err == ios_base::eofbit || err == ios_base::goodbit ); 100 101 CPPUNIT_ASSERT( yet_more.tm_sec == xmas.tm_sec ); 102 CPPUNIT_ASSERT( yet_more.tm_min == xmas.tm_min ); 103 CPPUNIT_ASSERT( yet_more.tm_hour == xmas.tm_hour ); 104 CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday ); 105 CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon ); 106 CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year ); 107 } 108 # if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T) 109 { 110 typedef time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > time_put_facet; 111 CPPUNIT_ASSERT( has_facet<time_put_facet>(loc) ); 112 const time_put_facet& tmp = use_facet<time_put_facet>(loc); 113 114 struct tm xmas = { 0, 0, 12, 25, 11, 93 }; 115 wostringstream ostr; 116 ostr.imbue(loc); 117 wstring format = L"%B %d %Y"; 118 119 time_put_facet::iter_type ret = tmp.put(ostr, ostr, ' ', &xmas, format.data(), format.data() + format.size()); 120 CPPUNIT_ASSERT( !ret.failed() ); 121 122 /* 123 * In other words, user conformation is required for reliable parsing 124 * of user-entered dates and times, but machine-generated formats can be 125 * parsed reliably. This allows parsers to be aggressive about interpreting 126 * user variations on standard format. 127 * 128 * ISO/IEC 14882, 22.2.5.1 129 */ 130 typedef time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > time_get_facet; 131 CPPUNIT_ASSERT( has_facet<time_get_facet>(loc) ); 132 const time_get_facet& tmg = use_facet<time_get_facet>(loc); 133 // Intentional instantiation with char to show a bug in a previous STLport version. 134 basic_ios<char> io(0); 135 io.imbue(loc); 136 137 wistringstream istr( ostr.str() ); 138 istreambuf_iterator<wchar_t, char_traits<wchar_t> > i( istr ); 139 istreambuf_iterator<wchar_t, char_traits<wchar_t> > e; 140 ios_base::iostate err = ios_base::goodbit; 141 struct tm other = { 15, 20, 9, 14, 7, 105 }; 142 143 i = tmg.get_monthname( i, e, io, err, &other ); 144 CPPUNIT_ASSERT( err == ios_base::goodbit ); 145 CPPUNIT_ASSERT( other.tm_mon == xmas.tm_mon ); 146 147 ++i; ++i; ++i; ++i; // skip day of month and spaces around it 148 i = tmg.get_year( i, e, io, err, &other ); 149 150 CPPUNIT_ASSERT( err == ios_base::eofbit ); 151 CPPUNIT_ASSERT( other.tm_year == xmas.tm_year ); 152 153 wostringstream ostrX; 154 ostrX.imbue(loc); 155 format = L"%x %X"; 156 157 ret = tmp.put(ostrX, ostrX, ' ', &xmas, format.data(), format.data() + format.size()); 158 CPPUNIT_ASSERT( !ret.failed() ); 159 160 wistringstream istrX( ostrX.str() ); 161 istreambuf_iterator<wchar_t, char_traits<wchar_t> > j( istrX ); 162 163 err = ios_base::goodbit; 164 165 struct tm yet_more = { 15, 20, 9, 14, 7, 105 }; 166 167 j = tmg.get_date( j, e, io, err, &yet_more ); 168 169 CPPUNIT_ASSERT( err == ios_base::goodbit ); 170 171 CPPUNIT_ASSERT( yet_more.tm_sec != xmas.tm_sec ); 172 CPPUNIT_ASSERT( yet_more.tm_min != xmas.tm_min ); 173 CPPUNIT_ASSERT( yet_more.tm_hour != xmas.tm_hour ); 174 CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday ); 175 CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon ); 176 CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year ); 177 178 ++j; // skip space 179 180 j = tmg.get_time( j, e, io, err, &yet_more ); 181 182 CPPUNIT_ASSERT( err == ios_base::eofbit || err == ios_base::goodbit ); 183 184 CPPUNIT_ASSERT( yet_more.tm_sec == xmas.tm_sec ); 185 CPPUNIT_ASSERT( yet_more.tm_min == xmas.tm_min ); 186 CPPUNIT_ASSERT( yet_more.tm_hour == xmas.tm_hour ); 187 CPPUNIT_ASSERT( yet_more.tm_mday == xmas.tm_mday ); 188 CPPUNIT_ASSERT( yet_more.tm_mon == xmas.tm_mon ); 189 CPPUNIT_ASSERT( yet_more.tm_year == xmas.tm_year ); 190 } 191 # endif 192 } 193 194 typedef void (LocaleTest::*_Test) (const locale&); 195 static void test_supported_locale(LocaleTest& inst, _Test __test) { 196 size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]); 197 for (size_t i = 0; i < n; ++i) { 198 locale loc; 199 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 200 try 201 # endif 202 { 203 locale tmp(tested_locales[i]); 204 loc = tmp; 205 } 206 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 207 catch (runtime_error const&) { 208 //This locale is not supported. 209 continue; 210 } 211 # endif 212 CPPUNIT_MESSAGE( loc.name().c_str() ); 213 (inst.*__test)(loc); 214 215 { 216 locale tmp(locale::classic(), tested_locales[i], locale::time); 217 loc = tmp; 218 } 219 (inst.*__test)(loc); 220 221 { 222 typedef time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > > time_put_facet; 223 locale tmp0(locale::classic(), new time_put_facet(tested_locales[i])); 224 typedef time_get_byname<char, istreambuf_iterator<char, char_traits<char> > > time_get_facet; 225 locale tmp1(tmp0, new time_get_facet(tested_locales[i])); 226 loc = tmp1; 227 } 228 (inst.*__test)(loc); 229 } 230 } 231 232 void LocaleTest::time_put_get() 233 { test_supported_locale(*this, &LocaleTest::_time_put_get); } 234 235 void LocaleTest::time_by_name() 236 { 237 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 238 /* 239 * Check of the 22.1.1.2.7 standard point. Construction of a locale 240 * instance from a null pointer or an unknown name should result in 241 * a runtime_error exception. 242 */ 243 # if defined (STLPORT) || !defined (_MSC_VER) || (_MSC_VER > 1400) 244 try { 245 locale loc(locale::classic(), new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >(static_cast<char const*>(0))); 246 CPPUNIT_FAIL; 247 } 248 catch (runtime_error const&) { 249 } 250 catch (...) { 251 CPPUNIT_FAIL; 252 } 253 # endif 254 255 try { 256 locale loc(locale::classic(), new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >("yasli_language")); 257 CPPUNIT_FAIL; 258 } 259 catch (runtime_error const&) { 260 } 261 catch (...) { 262 CPPUNIT_FAIL; 263 } 264 265 try { 266 string veryLongFacetName("LC_TIME="); 267 veryLongFacetName.append(512, '?'); 268 locale loc(locale::classic(), new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >(veryLongFacetName.c_str())); 269 CPPUNIT_FAIL; 270 } 271 catch (runtime_error const& /* e */) { 272 //CPPUNIT_MESSAGE( e.what() ); 273 } 274 catch (...) { 275 CPPUNIT_FAIL; 276 } 277 278 try { 279 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >(static_cast<char const*>(0))); 280 CPPUNIT_FAIL; 281 } 282 catch (runtime_error const&) { 283 } 284 catch (...) { 285 CPPUNIT_FAIL; 286 } 287 288 try { 289 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >("yasli_language")); 290 CPPUNIT_FAIL; 291 } 292 catch (runtime_error const&) { 293 } 294 catch (...) { 295 CPPUNIT_FAIL; 296 } 297 298 try { 299 string veryLongFacetName("LC_TIME="); 300 veryLongFacetName.append(512, '?'); 301 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >(veryLongFacetName.c_str())); 302 CPPUNIT_FAIL; 303 } 304 catch (runtime_error const& /* e */) { 305 //CPPUNIT_MESSAGE( e.what() ); 306 } 307 catch (...) { 308 CPPUNIT_FAIL; 309 } 310 311 try { 312 locale loc(locale::classic(), "C", locale::time); 313 } 314 catch (runtime_error const& /* e */) { 315 /* CPPUNIT_MESSAGE( e.what() ); */ 316 CPPUNIT_FAIL; 317 } 318 catch (...) { 319 CPPUNIT_FAIL; 320 } 321 322 try { 323 // On platform without real localization support we should rely on the "C" facet. 324 locale loc(locale::classic(), "", locale::time); 325 } 326 catch (runtime_error const& /* e */) { 327 /* CPPUNIT_MESSAGE( e.what() ); */ 328 CPPUNIT_FAIL; 329 } 330 catch (...) { 331 CPPUNIT_FAIL; 332 } 333 334 try { 335 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >("C")); 336 } 337 catch (runtime_error const& /* e */) { 338 /* CPPUNIT_MESSAGE( e.what() ); */ 339 CPPUNIT_FAIL; 340 } 341 catch (...) { 342 CPPUNIT_FAIL; 343 } 344 345 try { 346 // On platform without real localization support we should rely on the "C" locale facet. 347 locale loc(locale::classic(), new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >("")); 348 } 349 catch (runtime_error const& /* e */) { 350 /* CPPUNIT_MESSAGE( e.what() ); */ 351 CPPUNIT_FAIL; 352 } 353 catch (...) { 354 CPPUNIT_FAIL; 355 } 356 357 # if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T) 358 try { 359 locale loc(locale::classic(), new time_put_byname<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(static_cast<char const*>(0))); 360 CPPUNIT_FAIL; 361 } 362 catch (runtime_error const&) { 363 } 364 catch (...) { 365 CPPUNIT_FAIL; 366 } 367 368 try { 369 locale loc(locale::classic(), new time_put_byname<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >("yasli_language")); 370 CPPUNIT_FAIL; 371 } 372 catch (runtime_error const&) { 373 } 374 catch (...) { 375 CPPUNIT_FAIL; 376 } 377 378 try { 379 locale loc(locale::classic(), new time_get_byname<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(static_cast<char const*>(0))); 380 CPPUNIT_FAIL; 381 } 382 catch (runtime_error const&) { 383 } 384 catch (...) { 385 CPPUNIT_FAIL; 386 } 387 388 try { 389 locale loc(locale::classic(), new time_get_byname<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >("yasli_language")); 390 CPPUNIT_FAIL; 391 } 392 catch (runtime_error const&) { 393 } 394 catch (...) { 395 CPPUNIT_FAIL; 396 } 397 398 # endif 399 # endif 400 } 401 402 #endif 403