]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/src/c++98/locale_facets.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / src / c++98 / locale_facets.cc
CommitLineData
83ffe9cd 1// Copyright (C) 1997-2023 Free Software Foundation, Inc.
c755e77d
BK
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
748086b7 6// Free Software Foundation; either version 3, or (at your option)
c755e77d
BK
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
748086b7
JJ
14// Under Section 7 of GPL version 3, you are granted additional
15// permissions described in the GCC Runtime Library Exception, version
16// 3.1, as published by the Free Software Foundation.
17
18// You should have received a copy of the GNU General Public License and
19// a copy of the GCC Runtime Library Exception along with this program;
20// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
21// <http://www.gnu.org/licenses/>.
c755e77d 22
34a2b755 23#define _GLIBCXX_USE_CXX11_ABI 0
c755e77d
BK
24#include <locale>
25
12ffa228
BK
26namespace std _GLIBCXX_VISIBILITY(default)
27{
28_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 29
c755e77d 30 // Definitions for static const data members of time_base.
f92ab29f 31 template<>
c755e77d
BK
32 const char*
33 __timepunct_cache<char>::_S_timezones[14] =
f92ab29f
CG
34 {
35 "GMT", "HST", "AKST", "PST", "MST", "CST", "EST", "AST", "NST", "CET",
36 "IST", "EET", "CST", "JST"
c755e77d 37 };
f92ab29f 38
c755e77d 39#ifdef _GLIBCXX_USE_WCHAR_T
f92ab29f 40 template<>
c755e77d
BK
41 const wchar_t*
42 __timepunct_cache<wchar_t>::_S_timezones[14] =
f92ab29f
CG
43 {
44 L"GMT", L"HST", L"AKST", L"PST", L"MST", L"CST", L"EST", L"AST",
45 L"NST", L"CET", L"IST", L"EET", L"CST", L"JST"
c755e77d
BK
46 };
47#endif
48
49 // Definitions for static const data members of money_base.
f92ab29f 50 const money_base::pattern
c755e77d
BK
51 money_base::_S_default_pattern = { {symbol, sign, none, value} };
52
fe932e50
PC
53 const char* money_base::_S_atoms = "-0123456789";
54
0fa96a60 55 const char* __num_base::_S_atoms_in = "-+xX0123456789abcdefABCDEF";
c755e77d
BK
56 const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF";
57
58 // _GLIBCXX_RESOLVE_LIB_DEFECTS
59 // According to the resolution of DR 231, about 22.2.2.2.2, p11,
60 // "str.precision() is specified in the conversion specification".
61 void
f92ab29f 62 __num_base::_S_format_float(const ios_base& __io, char* __fptr,
32ade559 63 char __mod) throw()
c755e77d
BK
64 {
65 ios_base::fmtflags __flags = __io.flags();
66 *__fptr++ = '%';
67 // [22.2.2.2.2] Table 60
68 if (__flags & ios_base::showpos)
69 *__fptr++ = '+';
70 if (__flags & ios_base::showpoint)
71 *__fptr++ = '#';
72
c4b64f5b
RS
73 ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
74
23c64853 75#if _GLIBCXX_USE_C99_STDIO
9d07d890 76 // Precision is always used except for hexfloat format.
c4b64f5b 77 if (__fltfield != (ios_base::fixed | ios_base::scientific))
9d07d890 78#endif
c4b64f5b
RS
79 {
80 // As per DR 231: not only when __flags & ios_base::fixed || __prec > 0
81 *__fptr++ = '.';
82 *__fptr++ = '*';
83 }
c755e77d
BK
84
85 if (__mod)
86 *__fptr++ = __mod;
c755e77d
BK
87 // [22.2.2.2.2] Table 58
88 if (__fltfield == ios_base::fixed)
89 *__fptr++ = 'f';
90 else if (__fltfield == ios_base::scientific)
91 *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
23c64853 92#if _GLIBCXX_USE_C99_STDIO
c4b64f5b
RS
93 else if (__fltfield == (ios_base::fixed | ios_base::scientific))
94 *__fptr++ = (__flags & ios_base::uppercase) ? 'A' : 'a';
95#endif
c755e77d
BK
96 else
97 *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
98 *__fptr = '\0';
99 }
3cbc7af0 100
34a2b755
JW
101 // This function is not exported but is needed internally, by the versions
102 // of __verify_grouping below and in src/c++11/cxx11-locale-inst.cc
103 extern bool
104 __verify_grouping_impl(const char* __grouping, size_t __grouping_size,
105 const char* __grouping_tmp, size_t __grouping_tmp_size)
c68e4128 106 {
34a2b755 107 const size_t __n = __grouping_tmp_size - 1;
c68e4128
PC
108 const size_t __min = std::min(__n, size_t(__grouping_size - 1));
109 size_t __i = __n;
110 bool __test = true;
f92ab29f 111
c68e4128
PC
112 // Parsed number groupings have to match the
113 // numpunct::grouping string exactly, starting at the
114 // right-most point of the parsed sequence of elements ...
115 for (size_t __j = 0; __j < __min && __test; --__i, ++__j)
116 __test = __grouping_tmp[__i] == __grouping[__j];
117 for (; __i && __test; --__i)
118 __test = __grouping_tmp[__i] == __grouping[__min];
119 // ... but the first parsed grouping can be <= numpunct
120 // grouping (only do the check if the numpunct char is > 0
121 // because <= 0 means any size is ok).
bbcac3be
PC
122 if (static_cast<signed char>(__grouping[__min]) > 0
123 && __grouping[__min] != __gnu_cxx::__numeric_traits<char>::__max)
c68e4128
PC
124 __test &= __grouping_tmp[0] <= __grouping[__min];
125 return __test;
126 }
c755e77d 127
34a2b755
JW
128 bool
129 __verify_grouping(const char* __grouping, size_t __grouping_size,
130 const string& __grouping_tmp) throw()
131 {
132 return __verify_grouping_impl(__grouping, __grouping_size,
133 __grouping_tmp.c_str(),
134 __grouping_tmp.size());
135 }
136
a8d3c987
JJ
137 namespace
138 {
139 bool
140 is_leap(int year)
141 {
142 return (year % 100 != 0 || year % 400 == 0) && year % 4 == 0;
143 }
144
145 const unsigned short int mon_yday[2][13] =
146 {
147 // Normal years.
148 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
149 // Leap years.
150 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
151 };
152
153 int
154 day_of_the_week (int year, int mon, int mday)
155 {
156 // We know that January 1st 1970 was a Thursday (= 4). Compute the
157 // difference between this date and the one in arguments and so
158 // determine the weekday.
159 int corr_year = 1900 + year - (mon < 2);
160 int wday = (-473
161 + (365 * (year - 70))
162 + (corr_year / 4)
163 - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
164 + (((corr_year / 4) / 25) / 4)
165 + mon_yday[0][mon]
166 + mday - 1);
167 return ((wday % 7) + 7) % 7;
168 }
169
170 // Compute the day of the year.
171 int
172 day_of_the_year (tm *tm)
173 {
174 return (mon_yday[is_leap (1900 + tm->tm_year)][tm->tm_mon]
175 + (tm->tm_mday - 1));
176 }
177 }
178
179 // Finalize time_get state.
180 void
181 __time_get_state::
182 _M_finalize_state(tm* tm)
183 {
184 if (_M_have_I && _M_is_pm)
185 tm->tm_hour += 12;
186 if (_M_have_century)
187 {
188 if (_M_want_century)
189 tm->tm_year = tm->tm_year % 100;
190 else
191 tm->tm_year = 0;
192 tm->tm_year += (_M_century - 19) * 100;
193 }
194 if (_M_want_xday && !_M_have_wday)
195 {
196 if (!(_M_have_mon && _M_have_mday) && _M_have_yday)
197 {
198 // We don't have tm_mon and/or tm_mday, compute them.
199 int t_mon = 0;
200 while (mon_yday[is_leap(1900 + tm->tm_year)][t_mon]
201 <= tm->tm_yday)
202 ++t_mon;
203 if (!_M_have_mon)
204 tm->tm_mon = t_mon - 1;
205 if (!_M_have_mday)
206 tm->tm_mday
207 = (tm->tm_yday
208 - mon_yday[is_leap(1900 + tm->tm_year)][t_mon - 1] + 1);
209 _M_have_mon = 1;
210 _M_have_mday = 1;
211 }
212 // Don't crash in day_of_the_week if tm_mon is uninitialized.
213 if (_M_have_mon || (unsigned) tm->tm_mon <= 11)
214 tm->tm_wday
215 = day_of_the_week (tm->tm_year, tm->tm_mon, tm->tm_mday);
216 }
217 if (_M_want_xday
218 && !_M_have_yday
219 && (_M_have_mon || (unsigned) tm->tm_mon <= 11))
220 tm->tm_yday = day_of_the_year (tm);
221 if ((_M_have_uweek || _M_have_wweek) && _M_have_wday)
222 {
223 int w_offset = _M_have_uweek ? 0 : 1;
224 int wday = day_of_the_week (tm->tm_year, 0, 1);
225
226 if (!_M_have_yday)
227 tm->tm_yday = ((7 - (wday - w_offset)) % 7
228 + (_M_week_no - 1) * 7
229 + (tm->tm_wday - w_offset + 7) % 7);
230
231 if (!_M_have_mday || !_M_have_mon)
232 {
233 int t_mon = 0;
234 while (mon_yday[is_leap(1900 + tm->tm_year)][t_mon]
235 <= tm->tm_yday)
236 ++t_mon;
237 if (!_M_have_mon)
238 tm->tm_mon = t_mon - 1;
239 if (!_M_have_mday)
240 tm->tm_mday
241 = (tm->tm_yday
242 - mon_yday[is_leap(1900 + tm->tm_year)][t_mon - 1] + 1);
243 }
244 }
245 }
246
12ffa228
BK
247_GLIBCXX_END_NAMESPACE_VERSION
248} // namespace