1// Locale support -*- C++ -*-
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING.  If not, write to the Free
19// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20// USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction.  Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License.  This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31/** @file ctype_noninline.h
32 *  This is an internal header file, included by other library headers.
33 *  You should not attempt to use it directly.
34 */
35
36//
37// ISO C++ 14882: 22.1  Locales
38//
39
40// Information as gleaned from /usr/include/ctype.h
41
42#if _GLIBCXX_C_LOCALE_GNU
43  const ctype_base::mask*
44  ctype<char>::classic_table() throw()
45  { return _S_get_c_locale()->__ctype_b; }
46#else
47  const ctype_base::mask*
48  ctype<char>::classic_table() throw()
49  {
50    const ctype_base::mask* __ret;
51    char* __old = strdup(setlocale(LC_CTYPE, NULL));
52    setlocale(LC_CTYPE, "C");
53#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
54    __ret = *__ctype_b_loc();
55#else
56    __ret = __ctype_b;
57#endif
58    setlocale(LC_CTYPE, __old);
59    free(__old);
60    return __ret;
61  }
62#endif
63
64#if _GLIBCXX_C_LOCALE_GNU
65  ctype<char>::ctype(__c_locale __cloc, const mask* __table, bool __del,
66		     size_t __refs)
67  : facet(__refs), _M_c_locale_ctype(_S_clone_c_locale(__cloc)),
68  _M_del(__table != 0 && __del),
69  _M_toupper(_M_c_locale_ctype->__ctype_toupper),
70  _M_tolower(_M_c_locale_ctype->__ctype_tolower),
71  _M_table(__table ? __table : _M_c_locale_ctype->__ctype_b),
72  _M_widen_ok(0), _M_narrow_ok(0)
73  {
74    memset(_M_widen, 0, sizeof(_M_widen));
75    memset(_M_narrow, 0, sizeof(_M_narrow));
76  }
77#else
78  ctype<char>::ctype(__c_locale, const mask* __table, bool __del,
79		     size_t __refs)
80  : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()),
81  _M_del(__table != 0 && __del), _M_widen_ok(0), _M_narrow_ok(0)
82  {
83    char* __old=strdup(setlocale(LC_CTYPE, NULL));
84    setlocale(LC_CTYPE, "C");
85#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
86    _M_toupper = *__ctype_toupper_loc();
87    _M_tolower = *__ctype_tolower_loc();
88    _M_table = __table ? __table : *__ctype_b_loc();
89#else
90    _M_toupper = __ctype_toupper;
91    _M_tolower = __ctype_tolower;
92    _M_table = __table ? __table : __ctype_b;
93#endif
94    setlocale(LC_CTYPE, __old);
95    free(__old);
96    memset(_M_widen, 0, sizeof(_M_widen));
97    memset(_M_narrow, 0, sizeof(_M_narrow));
98  }
99#endif
100
101#if _GLIBCXX_C_LOCALE_GNU
102  ctype<char>::ctype(const mask* __table, bool __del, size_t __refs)
103  : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()),
104  _M_del(__table != 0 && __del),
105  _M_toupper(_M_c_locale_ctype->__ctype_toupper),
106  _M_tolower(_M_c_locale_ctype->__ctype_tolower),
107  _M_table(__table ? __table : _M_c_locale_ctype->__ctype_b),
108  _M_widen_ok(0), _M_narrow_ok(0)
109  {
110    memset(_M_widen, 0, sizeof(_M_widen));
111    memset(_M_narrow, 0, sizeof(_M_narrow));
112  }
113#else
114  ctype<char>::ctype(const mask* __table, bool __del, size_t __refs)
115  : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()),
116  _M_del(__table != 0 && __del), _M_widen_ok(0), _M_narrow_ok(0)
117  {
118    char* __old=strdup(setlocale(LC_CTYPE, NULL));
119    setlocale(LC_CTYPE, "C");
120#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
121    _M_toupper = *__ctype_toupper_loc();
122    _M_tolower = *__ctype_tolower_loc();
123    _M_table = __table ? __table : *__ctype_b_loc();
124#else
125    _M_toupper = __ctype_toupper;
126    _M_tolower = __ctype_tolower;
127    _M_table = __table ? __table : __ctype_b;
128#endif
129    setlocale(LC_CTYPE, __old);
130    free(__old);
131    memset(_M_widen, 0, sizeof(_M_widen));
132    memset(_M_narrow, 0, sizeof(_M_narrow));
133  }
134#endif
135
136  char
137  ctype<char>::do_toupper(char __c) const
138  { return _M_toupper[static_cast<unsigned char>(__c)]; }
139
140  const char*
141  ctype<char>::do_toupper(char* __low, const char* __high) const
142  {
143    while (__low < __high)
144      {
145	*__low = _M_toupper[static_cast<unsigned char>(*__low)];
146	++__low;
147      }
148    return __high;
149  }
150
151  char
152  ctype<char>::do_tolower(char __c) const
153  { return _M_tolower[static_cast<unsigned char>(__c)]; }
154
155  const char*
156  ctype<char>::do_tolower(char* __low, const char* __high) const
157  {
158    while (__low < __high)
159      {
160	*__low = _M_tolower[static_cast<unsigned char>(*__low)];
161	++__low;
162      }
163    return __high;
164  }
165