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&);
test_supported_locale(LocaleTest & inst,_Test __test)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
locale_by_name()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
loc_has_facet()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
locale_init_problem()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)
_locale_init_problem(const locale & loc)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
default_locale()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
combine()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