1 // 2001-11-21 Benjamin Kosnik  <bkoz@redhat.com>
2 
3 // Copyright (C) 2001, 2002 Free Software Foundation
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20 
21 // 22.2.2.1.1  num_get members
22 
23 #include <locale>
24 #include <sstream>
25 #include <testsuite_hooks.h>
26 
27 // XXX This test is not working for non-glibc locale models.
28 // { dg-do run { xfail *-*-* } }
29 
test01()30 void test01()
31 {
32   using namespace std;
33   typedef istreambuf_iterator<char> iterator_type;
34 
35   bool test = true;
36 
37   // basic construction
38   locale loc_c = locale::classic();
39   locale loc_hk("en_HK");
40   locale loc_fr("fr_FR@euro");
41   locale loc_de("de_DE");
42   VERIFY( loc_c != loc_de );
43   VERIFY( loc_hk != loc_fr );
44   VERIFY( loc_hk != loc_de );
45   VERIFY( loc_de != loc_fr );
46 
47   // cache the numpunct facets
48   const numpunct<char>& numpunct_c = use_facet<numpunct<char> >(loc_c);
49   const numpunct<char>& numpunct_de = use_facet<numpunct<char> >(loc_de);
50   const numpunct<char>& numpunct_hk = use_facet<numpunct<char> >(loc_hk);
51 
52   // sanity check the data is correct.
53   const string empty;
54   char c;
55 
56   bool b1 = true;
57   bool b0 = false;
58   long l1 = 2147483647;
59   long l2 = -2147483647;
60   long l;
61   unsigned long ul1 = 1294967294;
62   unsigned long ul2 = 0;
63   unsigned long ul;
64   double d1 =  1.02345e+308;
65   double d2 = 3.15e-308;
66   double d;
67   long double ld1 = 6.630025e+4;
68   long double ld2 = 0.0;
69   long double ld;
70   void* v;
71   const void* cv = &ul2;
72 
73   // cache the num_get facet
74   istringstream iss;
75   iss.imbue(loc_de);
76   const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
77   const ios_base::iostate goodbit = ios_base::goodbit;
78   const ios_base::iostate eofbit = ios_base::eofbit;
79   ios_base::iostate err = ios_base::goodbit;
80 
81   // bool, simple
82   iss.str("1");
83   iterator_type os_it00 = iss.rdbuf();
84   iterator_type os_it01 = ng.get(os_it00, 0, iss, err, b1);
85   VERIFY( b1 == true );
86   VERIFY( err & ios_base::eofbit );
87 
88   iss.str("0");
89   err = goodbit;
90   ng.get(iss.rdbuf(), 0, iss, err, b0);
91   VERIFY( b0 == false );
92   VERIFY( err & eofbit );
93 
94   // bool, more twisted examples
95   iss.imbue(loc_c);
96   iss.str("true ");
97   iss.clear();
98   iss.setf(ios_base::boolalpha);
99   err = goodbit;
100   ng.get(iss.rdbuf(), 0, iss, err, b0);
101   VERIFY( b0 == true );
102   VERIFY( err == goodbit );
103 
104   iss.str("false ");
105   iss.clear();
106   iss.setf(ios_base::boolalpha);
107   err = goodbit;
108   ng.get(iss.rdbuf(), 0, iss, err, b1);
109   VERIFY( b1 == false );
110   VERIFY( err == goodbit );
111 
112   // long, in a locale that expects grouping
113   iss.imbue(loc_hk);
114   iss.str("2,147,483,647 ");
115   iss.clear();
116   err = goodbit;
117   ng.get(iss.rdbuf(), 0, iss, err, l);
118   VERIFY( l == l1 );
119   VERIFY( err == goodbit );
120 
121   iss.str("-2,147,483,647++++++");
122   iss.clear();
123   err = goodbit;
124   ng.get(iss.rdbuf(), 0, iss, err, l);
125   VERIFY( l == l2 );
126   VERIFY( err == goodbit );
127 
128   // unsigned long, in a locale that does not group
129   iss.imbue(loc_c);
130   iss.str("1294967294");
131   iss.clear();
132   err = goodbit;
133   ng.get(iss.rdbuf(), 0, iss, err, ul);
134   VERIFY( ul == ul1);
135   VERIFY( err == eofbit );
136 
137   iss.str("0+++++++++++++++++++");
138   iss.clear();
139   err = goodbit;
140   ng.get(iss.rdbuf(), 0, iss, err, ul);
141   VERIFY( ul == ul2);
142   VERIFY( err == goodbit );
143 
144   // ... and one that does
145   iss.imbue(loc_de);
146   iss.str("1.294.967.294+++++++");
147   iss.clear();
148   iss.width(20);
149   iss.setf(ios_base::left, ios_base::adjustfield);
150   err = goodbit;
151   ng.get(iss.rdbuf(), 0, iss, err, ul);
152   VERIFY( ul == ul1 );
153   VERIFY( err == goodbit );
154 
155   // double
156   iss.imbue(loc_c);
157   iss.str("1.02345e+308++++++++");
158   iss.clear();
159   iss.width(20);
160   iss.setf(ios_base::left, ios_base::adjustfield);
161   err = goodbit;
162   ng.get(iss.rdbuf(), 0, iss, err, d);
163   VERIFY( d == d1 );
164   VERIFY( err == goodbit );
165 
166   iss.str("+3.15e-308");
167   iss.clear();
168   iss.width(20);
169   iss.setf(ios_base::right, ios_base::adjustfield);
170   err = goodbit;
171   ng.get(iss.rdbuf(), 0, iss, err, d);
172   VERIFY( d == d2 );
173   VERIFY( err == eofbit );
174 
175   iss.imbue(loc_de);
176   iss.str("+1,02345e+308");
177   iss.clear();
178   iss.width(20);
179   iss.setf(ios_base::right, ios_base::adjustfield);
180   iss.setf(ios_base::scientific, ios_base::floatfield);
181   err = goodbit;
182   ng.get(iss.rdbuf(), 0, iss, err, d);
183   VERIFY( d == d1 );
184   VERIFY( err == eofbit );
185 
186   iss.str("3,15E-308 ");
187   iss.clear();
188   iss.width(20);
189   iss.precision(10);
190   iss.setf(ios_base::right, ios_base::adjustfield);
191   iss.setf(ios_base::scientific, ios_base::floatfield);
192   iss.setf(ios_base::uppercase);
193   err = goodbit;
194   ng.get(iss.rdbuf(), 0, iss, err, d);
195   VERIFY( d == d2 );
196   VERIFY( err == goodbit );
197 
198   // long double
199   iss.str("6,630025e+4");
200   iss.clear();
201   err = goodbit;
202   ng.get(iss.rdbuf(), 0, iss, err, ld);
203   VERIFY( ld == ld1 );
204   VERIFY( err == eofbit );
205 
206   iss.str("0 ");
207   iss.clear();
208   iss.precision(0);
209   iss.setf(ios_base::fixed, ios_base::floatfield);
210   err = goodbit;
211   ng.get(iss.rdbuf(), 0, iss, err, ld);
212   VERIFY( ld == 0 );
213   VERIFY( err == goodbit );
214 
215   // const void
216   iss.str("0xbffff74c,");
217   iss.clear();
218   err = goodbit;
219   ng.get(iss.rdbuf(), 0, iss, err, v);
220   VERIFY( &v != &cv );
221   VERIFY( err == goodbit );
222 
223 
224 #ifdef _GLIBCPP_USE_LONG_LONG
225   long long ll1 = 9223372036854775807LL;
226   long long ll2 = -9223372036854775807LL;
227   long long ll;
228 
229   iss.str("9.223.372.036.854.775.807");
230   iss.clear();
231   err = goodbit;
232   ng.get(iss.rdbuf(), 0, iss, err, ll);
233   VERIFY( ll == ll1 );
234   VERIFY( err == eofbit );
235 #endif
236 }
237 
238 // 2002-01-10  David Seymour  <seymour_dj@yahoo.com>
239 // libstdc++/5331
test02()240 void test02()
241 {
242   using namespace std;
243   bool test = true;
244 
245   // Check num_get works with other iterators besides streambuf
246   // output iterators. (As long as output_iterator requirements are met.)
247   typedef string::const_iterator iter_type;
248   typedef num_get<char, iter_type> num_get_type;
249   const ios_base::iostate goodbit = ios_base::goodbit;
250   const ios_base::iostate eofbit = ios_base::eofbit;
251   ios_base::iostate err = ios_base::goodbit;
252   const locale loc_c = locale::classic();
253   const string str("20000106 Elizabeth Durack");
254   const string str2("0 true 0xbffff74c Durack");
255 
256   istringstream iss; // need an ios, add my num_get facet
257   iss.imbue(locale(loc_c, new num_get_type));
258 
259   // Iterator advanced, state, output.
260   const num_get_type& ng = use_facet<num_get_type>(iss.getloc());
261 
262   // 01 get(long)
263   // 02 get(long double)
264   // 03 get(bool)
265   // 04 get(void*)
266 
267   // 01 get(long)
268   long i = 0;
269   err = goodbit;
270   iter_type end1 = ng.get(str.begin(), str.end(), iss, err, i);
271   string rem1(end1, str.end());
272   VERIFY( err == goodbit );
273   VERIFY( i == 20000106);
274   VERIFY( rem1 == " Elizabeth Durack" );
275 
276   // 02 get(long double)
277   long double ld = 0.0;
278   err = goodbit;
279   iter_type end2 = ng.get(str.begin(), str.end(), iss, err, ld);
280   string rem2(end2, str.end());
281   VERIFY( err == goodbit );
282   VERIFY( ld == 20000106);
283   VERIFY( rem2 == " Elizabeth Durack" );
284 
285   // 03 get(bool)
286   bool b = 1;
287   iss.clear();
288   err = goodbit;
289   iter_type end3 = ng.get(str2.begin(), str2.end(), iss, err, b);
290   string rem3(end3, str2.end());
291   VERIFY( err == goodbit );
292   VERIFY( b == 0 );
293   VERIFY( rem3 == " true 0xbffff74c Durack" );
294 
295   iss.clear();
296   err = goodbit;
297   iss.setf(ios_base::boolalpha);
298   iter_type end4 = ng.get(++end3, str2.end(), iss, err, b);
299   string rem4(end4, str2.end());
300   VERIFY( err == goodbit );
301   VERIFY( b == true );
302   VERIFY( rem4 == " 0xbffff74c Durack" );
303 
304   // 04 get(void*)
305   void* v;
306   iss.clear();
307   err = goodbit;
308   iss.setf(ios_base::fixed, ios_base::floatfield);
309   iter_type end5 = ng.get(++end4, str2.end(), iss, err, v);
310   string rem5(end5, str2.end());
311   VERIFY( err == goodbit );
312   VERIFY( b == true );
313   VERIFY( rem5 == " Durack" );
314 }
315 
316 // libstdc++/5280
test03()317 void test03()
318 {
319 #ifdef _GLIBCPP_HAVE_SETENV
320   // Set the global locale to non-"C".
321   std::locale loc_de("de_DE");
322   std::locale::global(loc_de);
323 
324   // Set LANG environment variable to de_DE.
325   const char* oldLANG = getenv("LANG");
326   if (!setenv("LANG", "de_DE", 1))
327     {
328       test01();
329       test02();
330       setenv("LANG", oldLANG ? oldLANG : "", 1);
331     }
332 #endif
333 }
334 
335 // Testing the correct parsing of grouped hexadecimals and octals.
test04()336 void test04()
337 {
338   using namespace std;
339 
340   bool test = true;
341 
342   unsigned long ul;
343 
344   istringstream iss;
345 
346   // A locale that expects grouping
347   locale loc_de("de_DE");
348   iss.imbue(loc_de);
349 
350   const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
351   const ios_base::iostate goodbit = ios_base::goodbit;
352   ios_base::iostate err = ios_base::goodbit;
353 
354   iss.setf(ios::hex, ios::basefield);
355   iss.str("0xbf.fff.74c ");
356   err = goodbit;
357   ng.get(iss.rdbuf(), 0, iss, err, ul);
358   VERIFY( err == goodbit );
359   VERIFY( ul == 0xbffff74c );
360 
361   iss.str("0Xf.fff ");
362   err = goodbit;
363   ng.get(iss.rdbuf(), 0, iss, err, ul);
364   VERIFY( err == goodbit );
365   VERIFY( ul == 0xffff );
366 
367   iss.str("ffe ");
368   err = goodbit;
369   ng.get(iss.rdbuf(), 0, iss, err, ul);
370   VERIFY( err == goodbit );
371   VERIFY( ul == 0xffe );
372 
373   iss.setf(ios::oct, ios::basefield);
374   iss.str("07.654.321 ");
375   err = goodbit;
376   ng.get(iss.rdbuf(), 0, iss, err, ul);
377   VERIFY( err == goodbit );
378   VERIFY( ul == 07654321 );
379 
380   iss.str("07.777 ");
381   err = goodbit;
382   ng.get(iss.rdbuf(), 0, iss, err, ul);
383   VERIFY( err == goodbit );
384   VERIFY( ul == 07777 );
385 
386   iss.str("776 ");
387   err = goodbit;
388   ng.get(iss.rdbuf(), 0, iss, err, ul);
389   VERIFY( err == goodbit );
390   VERIFY( ul == 0776 );
391 }
392 
393 // libstdc++/5816
test05()394 void test05()
395 {
396   using namespace std;
397   bool test = true;
398 
399   double d = 0.0;
400 
401   istringstream iss;
402   locale loc_de("de_DE");
403   iss.imbue(loc_de);
404 
405   const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
406   const ios_base::iostate goodbit = ios_base::goodbit;
407   ios_base::iostate err = ios_base::goodbit;
408 
409   iss.str("1234,5 ");
410   err = goodbit;
411   ng.get(iss.rdbuf(), 0, iss, err, d);
412   VERIFY( err == goodbit );
413   VERIFY( d == 1234.5 );
414 }
415 
416 // http://gcc.gnu.org/ml/libstdc++/2002-05/msg00038.html
test06()417 void test06()
418 {
419   bool test = true;
420 
421   const char* tentLANG = std::setlocale(LC_ALL, "ja_JP.eucjp");
422   if (tentLANG != NULL)
423     {
424       std::string preLANG = tentLANG;
425       test01();
426       test02();
427       test04();
428       test05();
429       std::string postLANG = std::setlocale(LC_ALL, NULL);
430       VERIFY( preLANG == postLANG );
431     }
432 }
433 
main()434 int main()
435 {
436   test01();
437   test02();
438   test03();
439   test04();
440   test05();
441   test06();
442   return 0;
443 }
444 
445 
446 // Kathleen Hannah, humanitarian, woman, art-thief
447