michael@0: /* michael@0: * Copyright (c) 1999 michael@0: * Silicon Graphics Computer Systems, Inc. michael@0: * michael@0: * Copyright (c) 1999 michael@0: * Boris Fomitchev michael@0: * michael@0: * This material is provided "as is", with absolutely no warranty expressed michael@0: * or implied. Any use is at your own risk. michael@0: * michael@0: * Permission to use or copy this software for any purpose is hereby granted michael@0: * without fee, provided the above notices are retained on all copies. michael@0: * Permission to modify the code and to distribute modified code is granted, michael@0: * provided the above notices are retained, and a notice that the code was michael@0: * modified is included with the above copyright notice. michael@0: * michael@0: */ michael@0: #include "stlport_prefix.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "c_locale.h" michael@0: #include "locale_impl.h" michael@0: #include "acquire_release.h" michael@0: michael@0: _STLP_BEGIN_NAMESPACE michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // ctype_byname michael@0: michael@0: #if defined (__DMC__) michael@0: _STLP_DECLSPEC michael@0: #endif michael@0: ctype_byname::ctype_byname(const char* name, size_t refs) michael@0: : ctype( 0, false, refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_ctype = _STLP_PRIV __acquire_ctype(name, buf, 0, &__err_code); michael@0: if (!_M_ctype) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "ctype"); michael@0: michael@0: _M_init(); michael@0: } michael@0: michael@0: void ctype_byname::_M_init() { michael@0: _M_ctype_table = _M_byname_table; michael@0: michael@0: // We have to do this, instead of just pointer twiddling, because michael@0: // ctype_base::mask isn't the same type as _Locale_mask_t. michael@0: const _Locale_mask_t* p = _Locale_ctype_table(_M_ctype); michael@0: for (size_t i = 0; i != table_size; ++i) { michael@0: _M_byname_table[i] = ctype_base::mask(p[i]); michael@0: } michael@0: } michael@0: michael@0: ctype_byname::~ctype_byname() michael@0: { _STLP_PRIV __release_ctype(_M_ctype); } michael@0: michael@0: char ctype_byname::do_toupper(char c) const michael@0: { return (char)_Locale_toupper(_M_ctype, c); } michael@0: michael@0: char ctype_byname::do_tolower(char c) const michael@0: { return (char)_Locale_tolower(_M_ctype, c); } michael@0: michael@0: const char* michael@0: ctype_byname::do_toupper(char* first, const char* last) const { michael@0: for ( ; first != last ; ++first) michael@0: *first = (char)_Locale_toupper(_M_ctype, *first); michael@0: return last; michael@0: } michael@0: michael@0: const char* michael@0: ctype_byname::do_tolower(char* first, const char* last) const { michael@0: for ( ; first != last ; ++first) michael@0: *first = (char)_Locale_tolower(_M_ctype, *first); michael@0: return last; michael@0: } michael@0: michael@0: michael@0: // Some helper functions used in ctype<>::scan_is and scan_is_not. michael@0: #if !defined (_STLP_NO_WCHAR_T) michael@0: michael@0: _STLP_MOVE_TO_PRIV_NAMESPACE michael@0: michael@0: // ctype_byname michael@0: michael@0: struct _Ctype_byname_w_is_mask : public unary_function { michael@0: _Locale_mask_t M; michael@0: _Locale_ctype* M_ctp; michael@0: michael@0: _Ctype_byname_w_is_mask(_Locale_mask_t m, _Locale_ctype* c) michael@0: : M(m), M_ctp(c) {} michael@0: bool operator()(wchar_t c) const michael@0: { return _WLocale_ctype(M_ctp, c, M) != 0; } michael@0: }; michael@0: michael@0: _STLP_MOVE_TO_STD_NAMESPACE michael@0: michael@0: #if defined (__DMC__) michael@0: _STLP_DECLSPEC michael@0: #endif michael@0: ctype_byname::ctype_byname(const char* name, size_t refs) michael@0: : ctype(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_ctype = _STLP_PRIV __acquire_ctype(name, buf, 0, &__err_code); michael@0: if (!_M_ctype) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "ctype"); michael@0: } michael@0: michael@0: ctype_byname::~ctype_byname() michael@0: { _STLP_PRIV __release_ctype(_M_ctype); } michael@0: michael@0: bool ctype_byname::do_is(ctype_base::mask m, wchar_t c) const michael@0: { return _WLocale_ctype(_M_ctype, c, (_Locale_mask_t)m) != 0; } michael@0: michael@0: const wchar_t* michael@0: ctype_byname::do_is(const wchar_t* low, const wchar_t* high, michael@0: ctype_base::mask * m) const { michael@0: _Locale_mask_t all_bits = _Locale_mask_t(ctype_base::space | michael@0: ctype_base::print | michael@0: ctype_base::cntrl | michael@0: ctype_base::upper | michael@0: ctype_base::lower | michael@0: ctype_base::alpha | michael@0: ctype_base::digit | michael@0: ctype_base::punct | michael@0: ctype_base::xdigit); michael@0: michael@0: for ( ; low < high; ++low, ++m) michael@0: *m = ctype_base::mask (_WLocale_ctype(_M_ctype, *low, all_bits)); michael@0: return high; michael@0: } michael@0: michael@0: const wchar_t* michael@0: ctype_byname michael@0: ::do_scan_is(ctype_base::mask m, const wchar_t* low, const wchar_t* high) const michael@0: { return find_if(low, high, _STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype)); } michael@0: michael@0: const wchar_t* michael@0: ctype_byname michael@0: ::do_scan_not(ctype_base::mask m, const wchar_t* low, const wchar_t* high) const michael@0: { return find_if(low, high, not1(_STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype))); } michael@0: michael@0: wchar_t ctype_byname::do_toupper(wchar_t c) const michael@0: { return _WLocale_toupper(_M_ctype, c); } michael@0: michael@0: const wchar_t* michael@0: ctype_byname::do_toupper(wchar_t* low, const wchar_t* high) const { michael@0: for ( ; low < high; ++low) michael@0: *low = _WLocale_toupper(_M_ctype, *low); michael@0: return high; michael@0: } michael@0: michael@0: wchar_t ctype_byname::do_tolower(wchar_t c) const michael@0: { return _WLocale_tolower(_M_ctype, c); } michael@0: michael@0: const wchar_t* michael@0: ctype_byname::do_tolower(wchar_t* low, const wchar_t* high) const { michael@0: for ( ; low < high; ++low) michael@0: *low = _WLocale_tolower(_M_ctype, *low); michael@0: return high; michael@0: } michael@0: michael@0: #endif /* WCHAR_T */ michael@0: michael@0: // collate_byname michael@0: #if defined (__DMC__) michael@0: _STLP_DECLSPEC michael@0: #endif michael@0: collate_byname::collate_byname(const char* name, size_t refs) michael@0: : collate(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_collate = _STLP_PRIV __acquire_collate(name, buf, 0, &__err_code); michael@0: if (!_M_collate) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "collate"); michael@0: } michael@0: michael@0: collate_byname::~collate_byname() michael@0: { _STLP_PRIV __release_collate(_M_collate); } michael@0: michael@0: int collate_byname::do_compare(const char* __low1, michael@0: const char* __high1, michael@0: const char* __low2, michael@0: const char* __high2) const { michael@0: return _Locale_strcmp(_M_collate, michael@0: __low1, __high1 - __low1, michael@0: __low2, __high2 - __low2); michael@0: } michael@0: michael@0: collate_byname::string_type michael@0: collate_byname::do_transform(const char* low, const char* high) const { michael@0: if (low == high) michael@0: return string_type(); michael@0: michael@0: size_t n = _Locale_strxfrm(_M_collate, NULL, 0, low, high - low); michael@0: michael@0: // NOT PORTABLE. What we're doing relies on internal details of the michael@0: // string implementation. (Contiguity of string elements and presence michael@0: // of trailing zero.) michael@0: string_type buf(n, 0); michael@0: _Locale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low); michael@0: return buf; michael@0: } michael@0: michael@0: michael@0: #if !defined (_STLP_NO_WCHAR_T) michael@0: michael@0: // collate_byname michael@0: michael@0: #if defined (__DMC__) michael@0: _STLP_DECLSPEC michael@0: #endif michael@0: collate_byname::collate_byname(const char* name, size_t refs) michael@0: : collate(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_collate = _STLP_PRIV __acquire_collate(name, buf, 0, &__err_code); michael@0: if (!_M_collate) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "collate"); michael@0: } michael@0: michael@0: collate_byname::~collate_byname() michael@0: { _STLP_PRIV __release_collate(_M_collate); } michael@0: michael@0: int collate_byname::do_compare(const wchar_t* low1, michael@0: const wchar_t* high1, michael@0: const wchar_t* low2, michael@0: const wchar_t* high2) const { michael@0: return _WLocale_strcmp(_M_collate, michael@0: low1, high1 - low1, michael@0: low2, high2 - low2); michael@0: } michael@0: michael@0: collate_byname::string_type michael@0: collate_byname::do_transform(const wchar_t* low, michael@0: const wchar_t* high) const { michael@0: if (low == high) michael@0: return string_type(); michael@0: michael@0: size_t n = _WLocale_strxfrm(_M_collate, NULL, 0, low, high - low); michael@0: michael@0: // NOT PORTABLE. What we're doing relies on internal details of the michael@0: // string implementation. (Contiguity of string elements and presence michael@0: // of trailing zero.) michael@0: string_type buf(n, 0); michael@0: _WLocale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low); michael@0: return buf; michael@0: } michael@0: michael@0: #endif /* _STLP_NO_WCHAR_T */ michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // codecvt_byname michael@0: michael@0: codecvt_byname michael@0: ::codecvt_byname(const char* name, size_t refs) michael@0: : codecvt(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: } michael@0: michael@0: codecvt_byname::~codecvt_byname() {} michael@0: michael@0: michael@0: #if !defined (_STLP_NO_WCHAR_T) michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // codecvt_byname michael@0: codecvt_byname::codecvt_byname(const char* name, size_t refs) michael@0: : codecvt(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_codecvt = _STLP_PRIV __acquire_codecvt(name, buf, 0, &__err_code); michael@0: if (!_M_codecvt) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "ctype"); michael@0: } michael@0: michael@0: codecvt_byname::~codecvt_byname() michael@0: { _STLP_PRIV __release_codecvt(_M_codecvt); } michael@0: michael@0: codecvt::result michael@0: codecvt_byname::do_out(state_type& state, michael@0: const intern_type* from, michael@0: const intern_type* from_end, michael@0: const intern_type*& from_next, michael@0: extern_type* to, michael@0: extern_type* to_limit, michael@0: extern_type*& to_next) const { michael@0: while (from != from_end && to != to_limit) { michael@0: size_t chars_stored = _WLocale_wctomb(_M_codecvt, michael@0: to, to_limit - to, *from, michael@0: &state); michael@0: if (chars_stored == (size_t) -1) { michael@0: from_next = from; michael@0: to_next = to; michael@0: return error; michael@0: } michael@0: else if (chars_stored == (size_t) -2) { michael@0: from_next = from; michael@0: to_next = to; michael@0: return partial; michael@0: } michael@0: michael@0: ++from; michael@0: to += chars_stored; michael@0: } michael@0: michael@0: from_next = from; michael@0: to_next = to; michael@0: return ok; michael@0: } michael@0: michael@0: codecvt::result michael@0: codecvt_byname::do_in(state_type& state, michael@0: const extern_type* from, michael@0: const extern_type* from_end, michael@0: const extern_type*& from_next, michael@0: intern_type* to, michael@0: intern_type* to_end, michael@0: intern_type*& to_next) const { michael@0: while (from != from_end && to != to_end) { michael@0: size_t chars_read = _WLocale_mbtowc(_M_codecvt, michael@0: to, from, from_end - from, michael@0: &state); michael@0: if (chars_read == (size_t) -1) { michael@0: from_next = from; michael@0: to_next = to; michael@0: return error; michael@0: } michael@0: michael@0: if (chars_read == (size_t) -2) { michael@0: from_next = from; michael@0: to_next = to; michael@0: return partial; michael@0: } michael@0: michael@0: from += chars_read; michael@0: to++; michael@0: } michael@0: michael@0: from_next = from; michael@0: to_next = to; michael@0: return ok; michael@0: } michael@0: michael@0: codecvt::result michael@0: codecvt_byname::do_unshift(state_type& state, michael@0: extern_type* to, michael@0: extern_type* to_limit, michael@0: extern_type*& to_next) const { michael@0: to_next = to; michael@0: size_t result = _WLocale_unshift(_M_codecvt, &state, michael@0: to, to_limit - to, &to_next); michael@0: if (result == (size_t) -1) michael@0: return error; michael@0: else if (result == (size_t) -2) michael@0: return partial; michael@0: else michael@0: # if defined (__ISCPP__) michael@0: return /*to_next == to ? noconv :*/ ok; michael@0: # else michael@0: return to_next == to ? noconv : ok; michael@0: # endif michael@0: } michael@0: michael@0: int michael@0: codecvt_byname::do_encoding() const _STLP_NOTHROW { michael@0: if (_WLocale_is_stateless(_M_codecvt)) { michael@0: int max_width = _WLocale_mb_cur_max(_M_codecvt); michael@0: int min_width = _WLocale_mb_cur_min(_M_codecvt); michael@0: return min_width == max_width ? min_width : 0; michael@0: } michael@0: else michael@0: return -1; michael@0: } michael@0: michael@0: bool michael@0: codecvt_byname::do_always_noconv() const _STLP_NOTHROW michael@0: { return false; } michael@0: michael@0: int michael@0: codecvt_byname::do_length(state_type& state, michael@0: const extern_type* from, michael@0: const extern_type* end, michael@0: size_t mx) const { michael@0: size_t __count = 0; michael@0: while (from != end && mx--) { michael@0: intern_type __dummy; michael@0: size_t chars_read = _WLocale_mbtowc(_M_codecvt, michael@0: &__dummy, from, end - from, michael@0: &state); michael@0: if ((chars_read == (size_t) -1) || (chars_read == (size_t) -2)) // error or partial michael@0: break; michael@0: __count += chars_read; michael@0: from += chars_read; michael@0: } michael@0: return int(__count); michael@0: } michael@0: michael@0: int michael@0: codecvt_byname::do_max_length() const _STLP_NOTHROW michael@0: { return _WLocale_mb_cur_max(_M_codecvt); } michael@0: #endif michael@0: michael@0: // numpunct_byname michael@0: numpunct_byname::numpunct_byname(const char* name, size_t refs) michael@0: : numpunct(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_numeric = _STLP_PRIV __acquire_numeric(name, buf, 0, &__err_code); michael@0: if (!_M_numeric) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "numpunct"); michael@0: } michael@0: michael@0: numpunct_byname::~numpunct_byname() michael@0: { _STLP_PRIV __release_numeric(_M_numeric); } michael@0: michael@0: char numpunct_byname::do_decimal_point() const michael@0: { return _Locale_decimal_point(_M_numeric); } michael@0: michael@0: char numpunct_byname::do_thousands_sep() const michael@0: { return _Locale_thousands_sep(_M_numeric); } michael@0: michael@0: string numpunct_byname::do_grouping() const { michael@0: const char * __grouping = _Locale_grouping(_M_numeric); michael@0: if (__grouping != NULL && __grouping[0] == CHAR_MAX) michael@0: __grouping = ""; michael@0: return __grouping; michael@0: } michael@0: michael@0: string numpunct_byname::do_truename() const michael@0: { return _Locale_true(_M_numeric); } michael@0: michael@0: string numpunct_byname::do_falsename() const michael@0: { return _Locale_false(_M_numeric); } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: // numpunct michael@0: michael@0: #if !defined (_STLP_NO_WCHAR_T) michael@0: michael@0: // numpunct_byname michael@0: michael@0: numpunct_byname::numpunct_byname(const char* name, size_t refs) michael@0: : numpunct(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_numeric = _STLP_PRIV __acquire_numeric(name, buf, 0, &__err_code); michael@0: if (!_M_numeric) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "numpunct"); michael@0: } michael@0: michael@0: numpunct_byname::~numpunct_byname() michael@0: { _STLP_PRIV __release_numeric(_M_numeric); } michael@0: michael@0: wchar_t numpunct_byname::do_decimal_point() const michael@0: { return _WLocale_decimal_point(_M_numeric); } michael@0: michael@0: wchar_t numpunct_byname::do_thousands_sep() const michael@0: { return _WLocale_thousands_sep(_M_numeric); } michael@0: michael@0: string numpunct_byname::do_grouping() const { michael@0: const char * __grouping = _Locale_grouping(_M_numeric); michael@0: if (__grouping != NULL && __grouping[0] == CHAR_MAX) michael@0: __grouping = ""; michael@0: return __grouping; michael@0: } michael@0: michael@0: wstring numpunct_byname::do_truename() const { michael@0: wchar_t buf[16]; michael@0: return _WLocale_true(_M_numeric, _STLP_ARRAY_AND_SIZE(buf)); michael@0: } michael@0: michael@0: wstring numpunct_byname::do_falsename() const { michael@0: wchar_t buf[16]; michael@0: return _WLocale_false(_M_numeric, _STLP_ARRAY_AND_SIZE(buf)); michael@0: } michael@0: michael@0: #endif michael@0: michael@0: _STLP_MOVE_TO_PRIV_NAMESPACE michael@0: michael@0: static void _Init_monetary_formats(money_base::pattern& pos_format, michael@0: money_base::pattern& neg_format, michael@0: _Locale_monetary * monetary) { michael@0: switch (_Locale_p_sign_posn(monetary)) { michael@0: case 0: // Parentheses surround the quantity and currency symbol michael@0: case 1: // The sign string precedes the quantity and currency symbol michael@0: pos_format.field[0] = (char) money_base::sign; michael@0: if (_Locale_p_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a positive value michael@0: pos_format.field[1] = (char) money_base::symbol; michael@0: if (_Locale_p_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a positive value. michael@0: pos_format.field[2] = (char) money_base::space; michael@0: pos_format.field[3] = (char) money_base::value; michael@0: } else { michael@0: // a space not separates currency symbol from a positive value. michael@0: pos_format.field[2] = (char) money_base::value; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: } michael@0: } else { michael@0: // 0 if currency symbol succeeds a positive value michael@0: pos_format.field[1] = (char) money_base::value; michael@0: if (_Locale_p_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a positive value. michael@0: pos_format.field[2] = (char) money_base::space; michael@0: pos_format.field[3] = (char) money_base::symbol; michael@0: } else { michael@0: // a space not separates currency symbol from a positive value. michael@0: pos_format.field[2] = (char) money_base::symbol; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: } michael@0: } michael@0: break; michael@0: case 2: // The sign string succeeds the quantity and currency symbol. michael@0: if (_Locale_p_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a positive value michael@0: pos_format.field[0] = (char) money_base::symbol; michael@0: if (_Locale_p_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a positive value. michael@0: pos_format.field[1] = (char) money_base::space; michael@0: pos_format.field[2] = (char) money_base::value; michael@0: pos_format.field[3] = (char) money_base::sign; michael@0: } else { michael@0: // a space not separates currency symbol from a positive value. michael@0: pos_format.field[1] = (char) money_base::value; michael@0: pos_format.field[2] = (char) money_base::sign; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: } michael@0: } else { michael@0: // 0 if currency symbol succeeds a positive value michael@0: pos_format.field[0] = (char) money_base::value; michael@0: if (_Locale_p_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a positive value. michael@0: pos_format.field[1] = (char) money_base::space; michael@0: pos_format.field[2] = (char) money_base::symbol; michael@0: pos_format.field[3] = (char) money_base::sign; michael@0: } else { michael@0: // a space not separates currency symbol from a positive value. michael@0: pos_format.field[1] = (char) money_base::symbol; michael@0: pos_format.field[2] = (char) money_base::sign; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: } michael@0: } michael@0: break; michael@0: case 3: // The sign string immediately precedes the currency symbol. michael@0: if (_Locale_p_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a positive value michael@0: pos_format.field[0] = (char) money_base::sign; michael@0: pos_format.field[1] = (char) money_base::symbol; michael@0: if (_Locale_p_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a positive value. michael@0: pos_format.field[2] = (char) money_base::space; michael@0: pos_format.field[3] = (char) money_base::value; michael@0: } else { michael@0: // a space not separates currency symbol from a positive value. michael@0: pos_format.field[2] = (char) money_base::value; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: } michael@0: } else { michael@0: // 0 if currency symbol succeeds a positive value michael@0: pos_format.field[0] = (char) money_base::value; michael@0: pos_format.field[1] = (char) money_base::sign; michael@0: pos_format.field[2] = (char) money_base::symbol; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: } michael@0: break; michael@0: case 4: // The sign string immediately succeeds the currency symbol. michael@0: if (_Locale_p_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a positive value michael@0: pos_format.field[0] = (char) money_base::symbol; michael@0: pos_format.field[1] = (char) money_base::sign; michael@0: pos_format.field[2] = (char) money_base::value; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: } else { michael@0: // 0 if currency symbol succeeds a positive value michael@0: pos_format.field[0] = (char) money_base::value; michael@0: if (_Locale_p_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a positive value. michael@0: pos_format.field[1] = (char) money_base::space; michael@0: pos_format.field[2] = (char) money_base::symbol; michael@0: pos_format.field[3] = (char) money_base::sign; michael@0: } else { michael@0: // a space not separates currency symbol from a positive value. michael@0: pos_format.field[1] = (char) money_base::symbol; michael@0: pos_format.field[2] = (char) money_base::sign; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: } michael@0: } michael@0: break; michael@0: default: // Default C++ Standard format michael@0: pos_format.field[0] = (char) money_base::symbol; michael@0: pos_format.field[1] = (char) money_base::sign; michael@0: pos_format.field[2] = (char) money_base::none; michael@0: pos_format.field[3] = (char) money_base::value; michael@0: break; michael@0: } michael@0: michael@0: switch (_Locale_n_sign_posn(monetary)) { michael@0: case 0: // Parentheses surround the quantity and currency symbol michael@0: case 1: // The sign string precedes the quantity and currency symbol michael@0: neg_format.field[0] = (char) money_base::sign; michael@0: if (_Locale_n_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a negative value michael@0: neg_format.field[1] = (char) money_base::symbol; michael@0: if (_Locale_n_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a negative value. michael@0: neg_format.field[2] = (char) money_base::space; michael@0: neg_format.field[3] = (char) money_base::value; michael@0: } else { michael@0: // a space not separates currency symbol from a negative value. michael@0: neg_format.field[2] = (char) money_base::value; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: } michael@0: } else { michael@0: // 0 if currency symbol succeeds a negative value michael@0: neg_format.field[1] = (char) money_base::value; michael@0: if (_Locale_n_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a negative value. michael@0: neg_format.field[2] = (char) money_base::space; michael@0: neg_format.field[3] = (char) money_base::symbol; michael@0: } else { michael@0: // a space not separates currency symbol from a negative value. michael@0: neg_format.field[2] = (char) money_base::symbol; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: } michael@0: } michael@0: break; michael@0: case 2: // The sign string succeeds the quantity and currency symbol. michael@0: if (_Locale_n_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a negative value michael@0: neg_format.field[0] = (char) money_base::symbol; michael@0: if (_Locale_n_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a negative value. michael@0: neg_format.field[1] = (char) money_base::space; michael@0: neg_format.field[2] = (char) money_base::value; michael@0: neg_format.field[3] = (char) money_base::sign; michael@0: } else { michael@0: // a space not separates currency symbol from a negative value. michael@0: neg_format.field[1] = (char) money_base::value; michael@0: neg_format.field[2] = (char) money_base::sign; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: } michael@0: } else { michael@0: // 0 if currency symbol succeeds a negative value michael@0: neg_format.field[0] = (char) money_base::value; michael@0: if (_Locale_n_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a negative value. michael@0: neg_format.field[1] = (char) money_base::space; michael@0: neg_format.field[2] = (char) money_base::symbol; michael@0: neg_format.field[3] = (char) money_base::sign; michael@0: } else { michael@0: // a space not separates currency symbol from a negative value. michael@0: neg_format.field[1] = (char) money_base::symbol; michael@0: neg_format.field[2] = (char) money_base::sign; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: } michael@0: } michael@0: break; michael@0: case 3: // The sign string immediately precedes the currency symbol. michael@0: if (_Locale_n_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a negative value michael@0: neg_format.field[0] = (char) money_base::sign; michael@0: neg_format.field[1] = (char) money_base::symbol; michael@0: if (_Locale_n_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a negative value. michael@0: neg_format.field[2] = (char) money_base::space; michael@0: neg_format.field[3] = (char) money_base::value; michael@0: } else { michael@0: // a space not separates currency symbol from a negative value. michael@0: neg_format.field[2] = (char) money_base::value; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: } michael@0: } else { michael@0: // 0 if currency symbol succeeds a negative value michael@0: neg_format.field[0] = (char) money_base::value; michael@0: neg_format.field[1] = (char) money_base::sign; michael@0: neg_format.field[2] = (char) money_base::symbol; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: } michael@0: break; michael@0: case 4: // The sign string immediately succeeds the currency symbol. michael@0: if (_Locale_n_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a negative value michael@0: neg_format.field[0] = (char) money_base::symbol; michael@0: neg_format.field[1] = (char) money_base::sign; michael@0: neg_format.field[2] = (char) money_base::none; michael@0: neg_format.field[3] = (char) money_base::value; michael@0: } else { michael@0: // 0 if currency symbol succeeds a negative value michael@0: neg_format.field[0] = (char) money_base::value; michael@0: if (_Locale_n_sep_by_space(monetary)) { michael@0: // a space separates currency symbol from a negative value. michael@0: neg_format.field[1] = (char) money_base::space; michael@0: neg_format.field[2] = (char) money_base::symbol; michael@0: neg_format.field[3] = (char) money_base::sign; michael@0: } else { michael@0: // a space not separates currency symbol from a negative value. michael@0: neg_format.field[1] = (char) money_base::symbol; michael@0: neg_format.field[2] = (char) money_base::sign; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: } michael@0: } michael@0: break; michael@0: default: // Default C++ Standard format michael@0: neg_format.field[0] = (char) money_base::symbol; michael@0: neg_format.field[1] = (char) money_base::sign; michael@0: neg_format.field[2] = (char) money_base::none; michael@0: neg_format.field[3] = (char) money_base::value; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: // international variant of monetary michael@0: michael@0: /* michael@0: * int_curr_symbol michael@0: * michael@0: * The international currency symbol. The operand is a four-character michael@0: * string, with the first three characters containing the alphabetic michael@0: * international currency symbol in accordance with those specified michael@0: * in the ISO 4217 specification. The fourth character is the character used michael@0: * to separate the international currency symbol from the monetary quantity. michael@0: * michael@0: * (http://www.opengroup.org/onlinepubs/7990989775/xbd/locale.html) michael@0: */ michael@0: michael@0: /* michael@0: * Standards are unclear in the usage of international currency michael@0: * and monetary formats. michael@0: * But I am expect that international currency symbol should be the first michael@0: * (not depends upon where currency symbol situated in the national michael@0: * format). michael@0: * michael@0: * If this isn't so, let's see: michael@0: * 1 234.56 RUR michael@0: * GBP 1,234.56 michael@0: * USD 1,234.56 michael@0: * The situation really is worse than you see above: michael@0: * RUR typed wrong here---it prints '1 234.56 RUR ' (see space after RUR). michael@0: * This is due to intl_fmp.curr_symbol() == "RUR ". (see reference in comments michael@0: * above). michael@0: * michael@0: */ michael@0: michael@0: static void _Init_monetary_formats_int(money_base::pattern& pos_format, michael@0: money_base::pattern& neg_format, michael@0: _Locale_monetary * monetary) michael@0: { michael@0: michael@0: switch (_Locale_p_sign_posn(monetary)) { michael@0: case 0: // Parentheses surround the quantity and currency symbol michael@0: case 1: // The sign string precedes the quantity and currency symbol michael@0: pos_format.field[0] = (char) money_base::symbol; michael@0: pos_format.field[1] = (char) money_base::sign; michael@0: pos_format.field[2] = (char) money_base::value; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: break; michael@0: case 2: // The sign string succeeds the quantity and currency symbol. michael@0: pos_format.field[0] = (char) money_base::symbol; michael@0: pos_format.field[1] = (char) money_base::value; michael@0: pos_format.field[2] = (char) money_base::sign; michael@0: pos_format.field[3] = (char) money_base::none; michael@0: break; michael@0: case 3: // The sign string immediately precedes the currency symbol. michael@0: case 4: // The sign string immediately succeeds the currency symbol. michael@0: pos_format.field[0] = (char) money_base::symbol; michael@0: if (_Locale_p_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a positive value michael@0: pos_format.field[1] = (char) money_base::sign; michael@0: pos_format.field[2] = (char) money_base::value; michael@0: } else { michael@0: // 0 if currency symbol succeeds a positive value michael@0: pos_format.field[1] = (char) money_base::value; michael@0: pos_format.field[2] = (char) money_base::sign; michael@0: } michael@0: pos_format.field[3] = (char) money_base::none; michael@0: break; michael@0: default: // Default C++ Standard format michael@0: pos_format.field[0] = (char) money_base::symbol; michael@0: pos_format.field[1] = (char) money_base::sign; michael@0: pos_format.field[2] = (char) money_base::none; michael@0: pos_format.field[3] = (char) money_base::value; michael@0: break; michael@0: } michael@0: michael@0: michael@0: switch (_Locale_n_sign_posn(monetary)) { michael@0: case 0: // Parentheses surround the quantity and currency symbol michael@0: case 1: // The sign string precedes the quantity and currency symbol michael@0: neg_format.field[0] = (char) money_base::symbol; michael@0: neg_format.field[1] = (char) money_base::sign; michael@0: neg_format.field[2] = (char) money_base::value; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: break; michael@0: case 2: // The sign string succeeds the quantity and currency symbol. michael@0: neg_format.field[0] = (char) money_base::symbol; michael@0: neg_format.field[1] = (char) money_base::value; michael@0: neg_format.field[2] = (char) money_base::sign; michael@0: neg_format.field[3] = (char) money_base::none; michael@0: break; michael@0: case 3: // The sign string immediately precedes the currency symbol. michael@0: case 4: // The sign string immediately succeeds the currency symbol. michael@0: neg_format.field[0] = (char) money_base::symbol; michael@0: if (_Locale_n_cs_precedes(monetary)) { michael@0: // 1 if currency symbol precedes a negative value michael@0: neg_format.field[1] = (char) money_base::sign; michael@0: neg_format.field[2] = (char) money_base::value; michael@0: } else { michael@0: // 0 if currency symbol succeeds a negative value michael@0: neg_format.field[1] = (char) money_base::value; michael@0: neg_format.field[2] = (char) money_base::sign; michael@0: } michael@0: neg_format.field[3] = (char) money_base::none; michael@0: break; michael@0: default: // Default C++ Standard format michael@0: neg_format.field[0] = (char) money_base::symbol; michael@0: neg_format.field[1] = (char) money_base::sign; michael@0: neg_format.field[2] = (char) money_base::none; michael@0: neg_format.field[3] = (char) money_base::value; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: _STLP_MOVE_TO_STD_NAMESPACE michael@0: michael@0: // michael@0: // moneypunct_byname<> michael@0: // michael@0: moneypunct_byname::moneypunct_byname(const char * name, michael@0: size_t refs) michael@0: : moneypunct(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code); michael@0: if (!_M_monetary) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct"); michael@0: michael@0: _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary); michael@0: } michael@0: michael@0: moneypunct_byname::moneypunct_byname(_Locale_monetary *__mon) michael@0: : _M_monetary(__mon) { michael@0: _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary); michael@0: } michael@0: michael@0: moneypunct_byname::~moneypunct_byname() michael@0: { _STLP_PRIV __release_monetary(_M_monetary); } michael@0: michael@0: char moneypunct_byname::do_decimal_point() const michael@0: { return _Locale_mon_decimal_point(_M_monetary); } michael@0: michael@0: char moneypunct_byname::do_thousands_sep() const michael@0: { return _Locale_mon_thousands_sep(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_grouping() const michael@0: { return _Locale_mon_grouping(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_curr_symbol() const michael@0: { return _Locale_int_curr_symbol(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_positive_sign() const michael@0: { return _Locale_positive_sign(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_negative_sign() const michael@0: { return _Locale_negative_sign(_M_monetary); } michael@0: michael@0: int moneypunct_byname::do_frac_digits() const michael@0: { return _Locale_int_frac_digits(_M_monetary); } michael@0: michael@0: moneypunct_byname::moneypunct_byname(const char * name, michael@0: size_t refs) michael@0: : moneypunct(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code); michael@0: if (!_M_monetary) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct"); michael@0: michael@0: _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary); michael@0: } michael@0: michael@0: moneypunct_byname::moneypunct_byname(_Locale_monetary *__mon) michael@0: : _M_monetary(__mon) { michael@0: _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary); michael@0: } michael@0: michael@0: moneypunct_byname::~moneypunct_byname() michael@0: { _STLP_PRIV __release_monetary(_M_monetary); } michael@0: michael@0: char moneypunct_byname::do_decimal_point() const michael@0: { return _Locale_mon_decimal_point(_M_monetary); } michael@0: michael@0: char moneypunct_byname::do_thousands_sep() const michael@0: { return _Locale_mon_thousands_sep(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_grouping() const michael@0: { return _Locale_mon_grouping(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_curr_symbol() const michael@0: { return _Locale_currency_symbol(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_positive_sign() const michael@0: { return _Locale_positive_sign(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_negative_sign() const michael@0: { return _Locale_negative_sign(_M_monetary); } michael@0: michael@0: int moneypunct_byname::do_frac_digits() const michael@0: { return _Locale_frac_digits(_M_monetary); } michael@0: michael@0: // michael@0: // moneypunct_byname michael@0: // michael@0: #if !defined (_STLP_NO_WCHAR_T) michael@0: michael@0: moneypunct_byname::moneypunct_byname(const char * name, michael@0: size_t refs) michael@0: : moneypunct(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name(); michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code); michael@0: if (!_M_monetary) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct"); michael@0: michael@0: _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary); michael@0: } michael@0: michael@0: moneypunct_byname::moneypunct_byname(_Locale_monetary *__mon) michael@0: : _M_monetary(__mon) { michael@0: _STLP_PRIV _Init_monetary_formats_int(_M_pos_format, _M_neg_format, _M_monetary); michael@0: } michael@0: michael@0: moneypunct_byname::~moneypunct_byname() michael@0: { _STLP_PRIV __release_monetary(_M_monetary); } michael@0: michael@0: wchar_t moneypunct_byname::do_decimal_point() const michael@0: { return _Locale_mon_decimal_point(_M_monetary); } michael@0: michael@0: wchar_t moneypunct_byname::do_thousands_sep() const michael@0: { return _Locale_mon_thousands_sep(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_grouping() const michael@0: { return _Locale_mon_grouping(_M_monetary); } michael@0: michael@0: inline wstring __do_widen (string const& str) { michael@0: #if defined (_STLP_NO_MEMBER_TEMPLATES) || defined (_STLP_MSVC) michael@0: wstring::_Reserve_t __Reserve; michael@0: size_t __size = str.size(); michael@0: wstring result(__Reserve, __size); michael@0: copy(str.begin(), str.end(), result.begin()); michael@0: #else michael@0: wstring result(str.begin(), str.end()); michael@0: #endif michael@0: return result; michael@0: } michael@0: michael@0: wstring moneypunct_byname::do_curr_symbol() const michael@0: { wchar_t buf[16]; return _WLocale_int_curr_symbol(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); } michael@0: michael@0: wstring moneypunct_byname::do_positive_sign() const michael@0: { wchar_t buf[16]; return _WLocale_positive_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); } michael@0: michael@0: wstring moneypunct_byname::do_negative_sign() const michael@0: { wchar_t buf[16]; return _WLocale_negative_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); } michael@0: michael@0: int moneypunct_byname::do_frac_digits() const michael@0: { return _Locale_int_frac_digits(_M_monetary); } michael@0: michael@0: moneypunct_byname::moneypunct_byname(const char * name, michael@0: size_t refs) michael@0: : moneypunct(refs) { michael@0: if (!name) michael@0: locale::_M_throw_on_null_name() ; michael@0: michael@0: int __err_code; michael@0: char buf[_Locale_MAX_SIMPLE_NAME]; michael@0: _M_monetary = _STLP_PRIV __acquire_monetary(name, buf, 0, &__err_code); michael@0: if (!_M_monetary) michael@0: locale::_M_throw_on_creation_failure(__err_code, name, "moneypunct"); michael@0: michael@0: _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary); michael@0: } michael@0: michael@0: moneypunct_byname::moneypunct_byname(_Locale_monetary *__mon) michael@0: : _M_monetary(__mon) { michael@0: _STLP_PRIV _Init_monetary_formats(_M_pos_format, _M_neg_format, _M_monetary); michael@0: } michael@0: michael@0: moneypunct_byname::~moneypunct_byname() michael@0: { _STLP_PRIV __release_monetary(_M_monetary); } michael@0: michael@0: wchar_t moneypunct_byname::do_decimal_point() const michael@0: { return _Locale_mon_decimal_point(_M_monetary); } michael@0: michael@0: wchar_t moneypunct_byname::do_thousands_sep() const michael@0: { return _Locale_mon_thousands_sep(_M_monetary); } michael@0: michael@0: string moneypunct_byname::do_grouping() const michael@0: { return _Locale_mon_grouping(_M_monetary); } michael@0: michael@0: wstring moneypunct_byname::do_curr_symbol() const michael@0: { wchar_t buf[16]; return _WLocale_currency_symbol(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); } michael@0: michael@0: wstring moneypunct_byname::do_positive_sign() const michael@0: { wchar_t buf[16]; return _WLocale_positive_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); } michael@0: michael@0: wstring moneypunct_byname::do_negative_sign() const michael@0: { wchar_t buf[16]; return _WLocale_negative_sign(_M_monetary, _STLP_ARRAY_AND_SIZE(buf)); } michael@0: michael@0: int moneypunct_byname::do_frac_digits() const michael@0: { return _Locale_frac_digits(_M_monetary); } michael@0: michael@0: #endif michael@0: michael@0: _STLP_END_NAMESPACE michael@0: