197403Sobrien// Wrapper for underlying C-language localization -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 4169691Skan// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien// 3297403Sobrien// ISO C++ 14882: 22.8 Standard locale categories. 3397403Sobrien// 3497403Sobrien 3597403Sobrien// Written by Benjamin Kosnik <bkoz@redhat.com> 3697403Sobrien 37132720Skan#include <cerrno> // For errno 3897403Sobrien#include <locale> 3997403Sobrien#include <stdexcept> 4097403Sobrien#include <langinfo.h> 41117397Skan#include <bits/c++locale_internal.h> 4297403Sobrien 43169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 44169691Skan 4597403Sobrien template<> 4697403Sobrien void 4797403Sobrien __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 48132720Skan const __c_locale& __cloc) 4997403Sobrien { 50169691Skan char* __sanity; 51169691Skan errno = 0; 52169691Skan float __f = __strtof_l(__s, &__sanity, __cloc); 53169691Skan if (__sanity != __s && errno != ERANGE) 54169691Skan __v = __f; 55169691Skan else 56169691Skan __err |= ios_base::failbit; 5797403Sobrien } 5897403Sobrien 5997403Sobrien template<> 6097403Sobrien void 6197403Sobrien __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 62132720Skan const __c_locale& __cloc) 6397403Sobrien { 64169691Skan char* __sanity; 65169691Skan errno = 0; 66169691Skan double __d = __strtod_l(__s, &__sanity, __cloc); 67169691Skan if (__sanity != __s && errno != ERANGE) 68169691Skan __v = __d; 69169691Skan else 70169691Skan __err |= ios_base::failbit; 7197403Sobrien } 7297403Sobrien 7397403Sobrien template<> 7497403Sobrien void 7597403Sobrien __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err, 76132720Skan const __c_locale& __cloc) 7797403Sobrien { 78169691Skan char* __sanity; 79169691Skan errno = 0; 80169691Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 81169691Skan // Prefer strtold_l, as __strtold_l isn't prototyped in more recent 82169691Skan // glibc versions. 83169691Skan long double __ld = strtold_l(__s, &__sanity, __cloc); 84169691Skan#else 85169691Skan long double __ld = __strtold_l(__s, &__sanity, __cloc); 86169691Skan#endif 87169691Skan if (__sanity != __s && errno != ERANGE) 88169691Skan __v = __ld; 89169691Skan else 90169691Skan __err |= ios_base::failbit; 9197403Sobrien } 9297403Sobrien 9397403Sobrien void 9497403Sobrien locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s, 9597403Sobrien __c_locale __old) 9697403Sobrien { 9797403Sobrien __cloc = __newlocale(1 << LC_ALL, __s, __old); 9897403Sobrien if (!__cloc) 9997403Sobrien { 10097403Sobrien // This named locale is not supported by the underlying OS. 101132720Skan __throw_runtime_error(__N("locale::facet::_S_create_c_locale " 102132720Skan "name not valid")); 10397403Sobrien } 10497403Sobrien } 10597403Sobrien 10697403Sobrien void 10797403Sobrien locale::facet::_S_destroy_c_locale(__c_locale& __cloc) 108107606Sobrien { 109169691Skan if (__cloc && _S_get_c_locale() != __cloc) 110107606Sobrien __freelocale(__cloc); 111107606Sobrien } 11297403Sobrien 11397403Sobrien __c_locale 11497403Sobrien locale::facet::_S_clone_c_locale(__c_locale& __cloc) 11597403Sobrien { return __duplocale(__cloc); } 116107606Sobrien 117169691Skan_GLIBCXX_END_NAMESPACE 118169691Skan 119169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 120169691Skan 121132720Skan const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] = 122107606Sobrien { 123107606Sobrien "LC_CTYPE", 124117397Skan "LC_NUMERIC", 125117397Skan "LC_TIME", 126107606Sobrien "LC_COLLATE", 127107606Sobrien "LC_MONETARY", 128107606Sobrien "LC_MESSAGES", 129107606Sobrien "LC_PAPER", 130107606Sobrien "LC_NAME", 131107606Sobrien "LC_ADDRESS", 132107606Sobrien "LC_TELEPHONE", 133107606Sobrien "LC_MEASUREMENT", 134107606Sobrien "LC_IDENTIFICATION" 135107606Sobrien }; 136132720Skan 137169691Skan_GLIBCXX_END_NAMESPACE 138169691Skan 139169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 140169691Skan 141132720Skan const char* const* const locale::_S_categories = __gnu_cxx::category_names; 142169691Skan 143169691Skan_GLIBCXX_END_NAMESPACE 144169691Skan 145169691Skan// XXX GLIBCXX_ABI Deprecated 146169691Skan#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT 147169691Skan#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \ 148169691Skan extern "C" void ldbl (void) __attribute__ ((alias (#dbl))) 149169691Skan_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct); 150169691Skan#endif // _GLIBCXX_LONG_DOUBLE_COMPAT 151