Upload Tizen:Base source
[external/gmp.git] / tests / cxx / t-locale.cc
1 /* Test locale support in C++ functions.
2
3 Copyright 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library.
6
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19
20 #include <clocale>
21 #include <iostream>
22 #include <cstdlib>
23
24 #include "gmp.h"
25 #include "gmp-impl.h"
26 #include "tests.h"
27
28 using namespace std;
29
30
31 extern "C" {
32   char point_string[2];
33 }
34
35 #if HAVE_STD__LOCALE
36 // Like std::numpunct, but with decimal_point coming from point_string[].
37 class my_numpunct : public numpunct<char> {
38  public:
39   explicit my_numpunct (size_t r = 0) : numpunct<char>(r) { }
40  protected:
41   char do_decimal_point() const { return point_string[0]; }
42 };
43 #endif
44
45 void
46 set_point (char c)
47 {
48   point_string[0] = c;
49
50 #if HAVE_STD__LOCALE
51   locale loc (locale::classic(), new my_numpunct ());
52   locale::global (loc);
53 #endif
54 }
55
56
57 void
58 check_input (void)
59 {
60   static const struct {
61     const char  *str1;
62     const char  *str2;
63     double      want;
64   } data[] = {
65
66     { "1","",   1.0 },
67     { "1","0",  1.0 },
68     { "1","00", 1.0 },
69
70     { "","5",    0.5 },
71     { "0","5",   0.5 },
72     { "00","5",  0.5 },
73     { "00","50", 0.5 },
74
75     { "1","5",    1.5 },
76     { "1","5e1", 15.0 },
77   };
78
79   static char point[] = {
80     '.', ',', 'x', '\xFF'
81   };
82
83   mpf_t  got;
84   mpf_init (got);
85
86   for (size_t i = 0; i < numberof (point); i++)
87     {
88       set_point (point[i]);
89
90       for (int neg = 0; neg <= 1; neg++)
91         {
92           for (size_t j = 0; j < numberof (data); j++)
93             {
94               string str = string(data[j].str1)+point[i]+string(data[j].str2);
95               if (neg)
96                 str = "-" + str;
97
98               istringstream is (str.c_str());
99
100               mpf_set_ui (got, 123);   // dummy initial value
101
102               if (! (is >> got))
103                 {
104                   cout << "istream mpf_t operator>> error\n";
105                   cout << "  point " << point[i] << "\n";
106                   cout << "  str   \"" << str << "\"\n";
107                   cout << "  localeconv point \""
108                        << localeconv()->decimal_point << "\"\n";
109                   abort ();
110                 }
111
112               double want = data[j].want;
113               if (neg)
114                 want = -want;
115               if (mpf_cmp_d (got, want) != 0)
116                 {
117                   cout << "istream mpf_t operator>> wrong\n";
118                   cout << "  point " << point[i] << "\n";
119                   cout << "  str   \"" << str << "\"\n";
120                   cout << "  got   " << got << "\n";
121                   cout << "  want  " << want << "\n";
122                   cout << "  localeconv point \""
123                        << localeconv()->decimal_point << "\"\n";
124                   abort ();
125                 }
126             }
127         }
128     }
129
130   mpf_clear (got);
131 }
132
133 void
134 check_output (void)
135 {
136   static char point[] = {
137     '.', ',', 'x', '\xFF'
138   };
139
140   for (size_t i = 0; i < numberof (point); i++)
141     {
142       set_point (point[i]);
143       ostringstream  got;
144
145       mpf_t  f;
146       mpf_init (f);
147       mpf_set_d (f, 1.5);
148       got << f;
149       mpf_clear (f);
150
151       string  want = string("1") + point[i] + string("5");
152
153       if (want.compare (got.str()) != 0)
154         {
155           cout << "ostream mpf_t operator<< doesn't respect locale\n";
156           cout << "  point " << point[i] << "\n";
157           cout << "  got   \"" << got.str() << "\"\n";
158           cout << "  want  \"" << want      << "\"\n";
159           abort ();
160         }
161     }
162 }
163
164 int
165 replacement_works (void)
166 {
167   set_point ('x');
168   mpf_t  f;
169   mpf_init (f);
170   mpf_set_d (f, 1.5);
171   ostringstream s;
172   s << f;
173   mpf_clear (f);
174
175   return (s.str().compare("1x5") == 0);
176 }
177
178 int
179 main (void)
180 {
181   tests_start ();
182
183   if (replacement_works())
184     {
185       check_input ();
186       check_output ();
187     }
188   else
189     {
190       cout << "Replacing decimal point didn't work, tests skipped\n";
191     }
192
193   tests_end ();
194   return 0;
195 }