first commit
This commit is contained in:
381
extern/stdcxx/4.2.1/include/loc/_money_get.cc
vendored
Normal file
381
extern/stdcxx/4.2.1/include/loc/_money_get.cc
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* _money_get.cc - definition of std::money_get members
|
||||
*
|
||||
* $Id: _money_get.cc 637130 2008-03-14 15:16:33Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2008 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <streambuf>
|
||||
#include <loc/_ctype.h>
|
||||
#include <loc/_moneypunct.h>
|
||||
#include <rw/_defs.h>
|
||||
|
||||
|
||||
_RWSTD_NAMESPACE (__rw) {
|
||||
|
||||
_RWSTD_EXPORT int
|
||||
__rw_get_num (void*, const char*, int, int,
|
||||
const char*, _RWSTD_SIZE_T, const char*, _RWSTD_SIZE_T);
|
||||
|
||||
_RWSTD_EXPORT int
|
||||
__rw_check_grouping (const char*, _RWSTD_SIZE_T,
|
||||
const char*, _RWSTD_SIZE_T);
|
||||
|
||||
} // namespace __rw
|
||||
|
||||
|
||||
_RWSTD_NAMESPACE (std) {
|
||||
|
||||
|
||||
template <class _CharT, class _InputIter>
|
||||
_RW::__rw_facet_id money_get<_CharT, _InputIter>::id;
|
||||
|
||||
|
||||
template <class _CharT, class _InputIter>
|
||||
_TYPENAME money_get<_CharT, _InputIter>::iter_type
|
||||
money_get<_CharT, _InputIter>::
|
||||
_C_get (iter_type __it, iter_type __end, bool __intl, ios_base &__flags,
|
||||
_RWSTD_IOSTATE &__err, void *__pval, string_type *__pstr) const
|
||||
{
|
||||
typedef moneypunct<_CharT, false> _Punct0;
|
||||
typedef moneypunct<_CharT, true> _Punct1;
|
||||
|
||||
const _Punct0 &__pun = __intl ?
|
||||
_RWSTD_REINTERPRET_CAST (const _Punct0&,
|
||||
_RWSTD_USE_FACET (_Punct1,
|
||||
__flags.getloc ()))
|
||||
: _RWSTD_USE_FACET (_Punct0, __flags.getloc ());
|
||||
|
||||
// retrieve positive and negative sign, currency symbol,
|
||||
// the grouping string and the pattern format
|
||||
const string_type __ps = __pun.positive_sign ();
|
||||
const string_type __ns = __pun.negative_sign ();
|
||||
const string_type __cs = __pun.curr_symbol ();
|
||||
const string __gr = __pun.grouping ();
|
||||
const money_base::pattern __pat = __pun.neg_format ();
|
||||
|
||||
_RWSTD_IOSTATE __ebits = _RW::__rw_goodbit;
|
||||
|
||||
bool __needws = false; // whitespace required?
|
||||
bool __seendp = false; // seen decimal point in input
|
||||
|
||||
const ctype<_CharT> &__ctp =
|
||||
_RWSTD_USE_FACET (ctype<_CharT>, __flags.getloc ());
|
||||
|
||||
char __buf [304];
|
||||
char *__pcur = __buf;
|
||||
|
||||
typedef _TYPENAME string_type::traits_type _Traits;
|
||||
|
||||
char __grpbuf [sizeof __buf]; // holds sizes of discovered groups
|
||||
char *__pgrp = __grpbuf; // current group
|
||||
const char *__grpstart = 0; // the start of the last group
|
||||
const char *__grpend = 0; // the end of the last group
|
||||
|
||||
|
||||
int __sign = 0; // the sign of the result if detected (-1, 0, or +1)
|
||||
|
||||
// buffer must always start with a sign (__rw_get_num requirement)
|
||||
// use a '+' and overwrite it with a '-' if necessary
|
||||
*__pcur++ = '+';
|
||||
|
||||
const int __fl = __flags.flags ();
|
||||
|
||||
typedef _RWSTD_SIZE_T _SizeT;
|
||||
|
||||
for (_SizeT __i = 0; !__ebits && __i != sizeof __pat.field; ++__i) {
|
||||
|
||||
switch (__pat.field [__i]) {
|
||||
|
||||
case /* '\1' */ money_base::space:
|
||||
__needws = true;
|
||||
// fall through...
|
||||
|
||||
case /* '\0' */ money_base::none: {
|
||||
|
||||
// optional or even required whitespace is consumed only if
|
||||
// other characters may be required to complete the format
|
||||
if ( sizeof __pat.field == __i + 1
|
||||
|| 2 == __i && money_base::symbol == __pat.field [3]
|
||||
&& (!(__fl & _RW::__rw_showbase) || 0 == __cs.size ())
|
||||
&& !( __sign < 0 && __ns.size () > 1
|
||||
|| __sign > 0 && __ps.size () > 1)
|
||||
|| 1 == __i && money_base::value == __pat.field [0]
|
||||
&& 0 == __ns.size () && 0 == __ps.size ()
|
||||
&& (0 == __cs.size () || !(__fl & _RW::__rw_showbase)))
|
||||
break;
|
||||
|
||||
_SizeT __nc = 0;
|
||||
|
||||
while (__it != __end && __ctp.is (ctype_base::space, *__it)) {
|
||||
++__it;
|
||||
++__nc;
|
||||
}
|
||||
|
||||
if (__needws && !__nc)
|
||||
__ebits |= _RW::__rw_failbit;
|
||||
break;
|
||||
}
|
||||
|
||||
case /* '\2' */ money_base::symbol: {
|
||||
|
||||
// if optional, currency symbol is not extracted unless
|
||||
// it is consumed only if it is followed by characters
|
||||
// required to complete the pattern (see example in
|
||||
// 22.2.6.1.2, p3)
|
||||
if ( __fl & _RW::__rw_showbase
|
||||
|| __i < 2
|
||||
|| 2 == __i && (money_base::none != __pat.field [3])
|
||||
|| __sign < 0 && __ns.size () > 1
|
||||
|| __sign > 0 && __ps.size () > 1) {
|
||||
|
||||
for (_SizeT __nc = 0; __nc != __cs.size ();
|
||||
++__nc, ++__it) {
|
||||
if (__it == __end || !_Traits::eq (*__it, __cs [__nc])) {
|
||||
|
||||
// 22.2.6.1.2, p2: unless showbase is set,
|
||||
// curr_symbol is optional
|
||||
if (__nc || __fl & _RW::__rw_showbase)
|
||||
__ebits |= _RW::__rw_failbit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case /* '\3' */ money_base::sign: {
|
||||
|
||||
if (__it == __end) {
|
||||
if (__ps.size () && __ns.size ())
|
||||
__ebits |= _RW::__rw_failbit;
|
||||
else
|
||||
__sign = __ps.empty () - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
const char_type __c = *__it;
|
||||
|
||||
// 22.2.6.1.2, p3: if the first character of positive
|
||||
// and negative sign is the same, the result is positive
|
||||
|
||||
if (__ps.size () && _Traits::eq (__c, __ps [0])) {
|
||||
__sign = 1;
|
||||
++__it;
|
||||
}
|
||||
else if (__ns.size () && _Traits::eq (__c, __ns [0])) {
|
||||
__sign = -1;
|
||||
++__it;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case /* '\4' */ money_base::value: {
|
||||
|
||||
const char_type __ts =
|
||||
__gr.size () && __gr [0] && __gr [0] != _RWSTD_CHAR_MAX ?
|
||||
__pun.thousands_sep () : __ctp.widen ('0');
|
||||
|
||||
int __fd = __pun.frac_digits ();
|
||||
|
||||
for (; __it != __end; ++__it) {
|
||||
|
||||
// read and narrow a character (note that narrow() may
|
||||
// yield the same narrow char for more than one wide
|
||||
// character; e.g., there may be two sets of digits)
|
||||
const char_type __c = *__it;
|
||||
const char __ch = __ctp.narrow (__c, '\0');
|
||||
|
||||
if (__ch >= '0' && __ch <= '9') {
|
||||
if (!__seendp || __fd-- > 0)
|
||||
*__pcur++ = __ch;
|
||||
}
|
||||
else if ( !__seendp && __fd > 0
|
||||
&& _Traits::eq (__c, __pun.decimal_point ())) {
|
||||
__grpend = __pcur;
|
||||
__seendp = true;
|
||||
}
|
||||
else if (!__seendp && _Traits::eq (__c, __ts)) {
|
||||
// add the length of the current group to the array groups
|
||||
// store UCHAR_MAX if group length exceeds the size of char
|
||||
_RWSTD_PTRDIFF_T __len;
|
||||
|
||||
if (__grpstart)
|
||||
__len = __pcur - __grpstart;
|
||||
else {
|
||||
__grpstart = __pcur;
|
||||
__len = __pcur - __buf - 1;
|
||||
}
|
||||
|
||||
typedef unsigned char _UChar;
|
||||
|
||||
*__pgrp++ = char (__len < _UChar (-1) ? __len : -1);
|
||||
__grpstart = __pcur;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (__pcur - __buf > 1) {
|
||||
// append zeros to a non-empty string of digits
|
||||
// up to the number of frac_digits
|
||||
while (__fd-- > 0)
|
||||
*__pcur++ = '0';
|
||||
}
|
||||
|
||||
*__pcur = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
__ebits = _RW::__rw_failbit;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!(__ebits & _RW::__rw_failbit)) {
|
||||
|
||||
if (__buf [1]) {
|
||||
|
||||
// process the remainder of a multicharacter sign
|
||||
const _SizeT __sizes [] = {
|
||||
__ps.size () ? __ps.size () -1 : 0,
|
||||
__ns.size () ? __ns.size () -1 : 0
|
||||
};
|
||||
|
||||
const char_type* const __names [] = {
|
||||
__ps.data () + !!__sizes [0],
|
||||
__ns.data () + !!__sizes [1]
|
||||
};
|
||||
|
||||
if (__sign && (__sizes [0] || __sizes [1])) {
|
||||
|
||||
// if the first character of a multi-character sign
|
||||
// has been seen, try to extract the rest of the sign
|
||||
|
||||
_SizeT __inx = 0;
|
||||
|
||||
int __errtmp = 1; // no duplicates allowed
|
||||
|
||||
__it = _RW::__rw_match_name (__it, __end, __names, __sizes,
|
||||
sizeof __names / sizeof *__names,
|
||||
__inx, __errtmp, 0);
|
||||
|
||||
if (1 < __inx && __sizes [__sign < 0]) {
|
||||
|
||||
// failed to match the remainder of the sign to
|
||||
// the input and the first character of the sign
|
||||
// does not form the complete (positive or negative)
|
||||
// sign
|
||||
__ebits = _RW::__rw_failbit;
|
||||
__buf [1] = '\0';
|
||||
}
|
||||
else if (!_Traits::eq (*__ps.data (), *__ns.data ())) {
|
||||
|
||||
// if the first extracted character of the sign string
|
||||
// forms the complete sign whose first character doesn't
|
||||
// form an initial substring of the other sign string
|
||||
// the resulting sign is determined by the one-character
|
||||
// sign string
|
||||
if (1 < __inx)
|
||||
__inx = 0 < __sizes [__sign < 0];
|
||||
|
||||
// if both signs begin with the same character,
|
||||
// the result is positive (22.2.6.1.2, p3)
|
||||
*__buf = __inx ? '-' : '+';
|
||||
__sign = -int (__inx);
|
||||
}
|
||||
}
|
||||
else if (__sign < 0) {
|
||||
*__buf = '-';
|
||||
}
|
||||
|
||||
if (__pstr && !(__ebits & _RW::__rw_failbit)) {
|
||||
// skip over the leading sign and any redundant zeros after it
|
||||
const char *__start = __buf + 1;
|
||||
for (; '0' == *__start && '0' == __start [1]; ++__start);
|
||||
|
||||
// invert the sign if negative
|
||||
__sign = __sign < 0;
|
||||
|
||||
// widen narrow digits optionally preceded by the minus sign
|
||||
// into the basic_string object as required by 22.2.6.1.2, p1
|
||||
__pstr->resize ((__pcur - __start) + _SizeT (__sign));
|
||||
|
||||
if (__sign)
|
||||
_Traits::assign ((*__pstr)[0], __ctp.widen ('-'));
|
||||
|
||||
__ctp.widen (__start, __pcur, &(*__pstr)[_SizeT (__sign)]);
|
||||
}
|
||||
|
||||
const char *__grs = "";
|
||||
_SizeT __grn = 0;
|
||||
|
||||
// 22.2.6.1.2, p1: thousands separators are optional
|
||||
|
||||
// add the length of the last group to the array of groups
|
||||
// store UCHAR_MAX if group length exceeds the size of char
|
||||
if (__grpstart) {
|
||||
const _RWSTD_PTRDIFF_T __len =
|
||||
(__grpend ? __grpend : __pcur) - __grpstart;
|
||||
|
||||
typedef unsigned char _UChar;
|
||||
|
||||
*__pgrp++ = char (__len < _UChar (-1) ? __len : -1);
|
||||
*__pgrp = '\0';
|
||||
__grs = __gr.data ();
|
||||
__grn = __gr.size ();
|
||||
}
|
||||
|
||||
if (__pval) {
|
||||
// produce a number from the extracted string of digits
|
||||
// and (optionally) check grouping
|
||||
|
||||
const int __errtmp =
|
||||
_RW::__rw_get_num (__pval, __buf, _C_ldouble, 0,
|
||||
__grpbuf, __pgrp - __grpbuf,
|
||||
__grs, __grn);
|
||||
|
||||
__ebits |= _RWSTD_IOSTATE (__errtmp);
|
||||
}
|
||||
else if (0 > _RW::__rw_check_grouping (__grpbuf, __pgrp - __grpbuf,
|
||||
__grs, __grn))
|
||||
__ebits |= _RW::__rw_failbit;
|
||||
}
|
||||
else
|
||||
__ebits |= _RW::__rw_failbit;
|
||||
}
|
||||
|
||||
if (__it == __end)
|
||||
__ebits |= _RW::__rw_eofbit;
|
||||
|
||||
__err |= __ebits;
|
||||
|
||||
return __it;
|
||||
}
|
||||
|
||||
|
||||
} // namespace std
|
||||
Reference in New Issue
Block a user