1 // 2000-09-13 Benjamin Kosnik <bkoz@redhat.com>
2 
3 // Copyright (C) 2000, 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.1.1.5 locale static members [lib.locale.statics]
22 
23 #include <cwchar> // for mbstate_t
24 #include <locale>
25 #include <iostream>
26 #include <testsuite_hooks.h>
27 
28 typedef std::codecvt<char, char, std::mbstate_t> ccodecvt;
29 class gnu_codecvt: public ccodecvt { };
30 
test01()31 void test01()
32 {
33   using namespace std;
34   bool test = true;
35 
36   string str1, str2;
37 
38   // Construct a locale object with the C facet.
39   const locale loc01 = locale::classic();
40 
41   // Construct a locale object with the specialized facet.
42   locale loc02(locale::classic(), new gnu_codecvt);
43   VERIFY ( loc01 != loc02 );
44   VERIFY ( !(loc01 == loc02) );
45 
46   // classic
47   locale loc06("C");
48   VERIFY (loc06 == loc01);
49   str1 = loc06.name();
50   VERIFY( str1 == "C" );
51 
52   // global
53   locale loc03;
54   VERIFY ( loc03 == loc01);
55   locale global_orig = locale::global(loc02);
56   locale loc05;
57   VERIFY (loc05 != loc03);
58   VERIFY (loc05 == loc02);
59 
60   // Reset global settings.
61   locale::global(global_orig);
62 }
63 
64 // Sanity check locale::global(loc) and setlocale.
test02()65 void test02()
66 {
67   using namespace std;
68   bool test = true;
69 
70   const string ph("en_PH");
71   const string mx("es_MX");
72   const char* orig = setlocale(LC_ALL, NULL);
73   const char* testph = setlocale(LC_ALL, ph.c_str());
74   const char* testmx = setlocale(LC_ALL, mx.c_str());
75   setlocale(LC_ALL, orig);
76 
77   // If the underlying locale doesn't support these names, setlocale
78   // won't be reset. Therefore, disable unless we know these specific
79   // named locales work.
80   if (testph && testmx)
81     {
82       const locale loc_ph(ph.c_str());
83       const locale loc_mx(mx.c_str());
84 
85       // Use setlocale between two calls to locale("")
86       const locale loc_env_1("");
87       setlocale(LC_ALL, ph.c_str());
88       const locale loc_env_2("");
89       VERIFY( loc_env_1 == loc_env_2 );
90 
91       // Change global locale.
92       locale global_orig = locale::global(loc_mx);
93       const char* lc_all_mx = setlocale(LC_ALL, NULL);
94       if (lc_all_mx)
95 	{
96 	  cout << "lc_all_mx is " << lc_all_mx << endl;
97 	  VERIFY( mx == lc_all_mx );
98 	}
99 
100       // Restore global settings.
101       locale::global(global_orig);
102     }
103 }
104 
105 // Static counter for use in checking ctors/dtors.
106 static std::size_t counter;
107 
108 class surf : public std::locale::facet
109 {
110 public:
111   static std::locale::id 	       	id;
surf(size_t refs=0)112   surf(size_t refs = 0): std::locale::facet(refs) { ++counter; }
~surf()113   ~surf() { --counter; }
114 };
115 
116 std::locale::id surf::id;
117 
118 typedef surf facet_type;
119 
120 // Verify lifetimes of global objects.
test03()121 void test03()
122 {
123   using namespace std;
124   bool test = true;
125 
126   string name;
127   locale global_orig;
128   // 1: Destroyed when out of scope.
129   {
130     {
131       {
132 	VERIFY( counter == 0 );
133 	{
134 	  locale loc01(locale::classic(), new facet_type);
135 	  VERIFY( counter == 1 );
136 	  global_orig = locale::global(loc01);
137 	  name = loc01.name();
138 	}
139 	VERIFY( counter == 1 );
140 	locale loc02 = locale();
141 	// Weak, but it's something...
142 	VERIFY( loc02.name() == name );
143       }
144       VERIFY( counter == 1 );
145       // NB: loc03 should be a copy of the previous global locale.
146       locale loc03 = locale::global(global_orig);
147       VERIFY( counter == 1 );
148       VERIFY( loc03.name() == name );
149     }
150     VERIFY( counter == 0 );
151     locale loc04 = locale();
152     VERIFY( loc04 == global_orig );
153   }
154 
155   // 2: Not destroyed when out of scope, deliberately leaked.
156   {
157     {
158       {
159 	VERIFY( counter == 0 );
160 	{
161 	  locale loc01(locale::classic(), new facet_type(1));
162 	  VERIFY( counter == 1 );
163 	  global_orig = locale::global(loc01);
164 	  name = loc01.name();
165 	}
166 	VERIFY( counter == 1 );
167 	locale loc02 = locale();
168 	// Weak, but it's something...
169 	VERIFY( loc02.name() == name );
170       }
171       VERIFY( counter == 1 );
172       // NB: loc03 should be a copy of the previous global locale.
173       locale loc03 = locale::global(global_orig);
174       VERIFY( counter == 1 );
175       VERIFY( loc03.name() == name );
176     }
177     VERIFY( counter == 1 );
178     locale loc04 = locale();
179     VERIFY( loc04 == global_orig );
180   }
181   VERIFY( counter == 1 );
182 
183   // Restore global settings.
184   locale::global(global_orig);
185 }
186 
main()187 int main ()
188 {
189   test01();
190   test02();
191 
192   test03();
193   return 0;
194 }
195