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