X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libstdc%2B%2B-v3%2Finclude%2Fbits%2Flocale_facets.tcc;h=d781503c3cf9a93ce3012e3f9d1c7091dea59191;hb=c6b83c3c04b42670c276707842d23bc8b7a0cd98;hp=b934482251114eefbe627510f3d3932cbfa7f44a;hpb=53366bcba3748c5db5000450372bfdff8d9b0899;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index b9344822511..d781503c3cf 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -163,12 +163,18 @@ namespace std const __cache_type* __lc = __uc(__loc); const _CharT* __lit = __lc->_M_atoms_in; + // True if a mantissa is found. + bool __found_mantissa = false; + // First check for sign. if (__beg != __end) { const char_type __c = *__beg; const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]); - if (__plus || __traits_type::eq(__c, __lit[_S_iminus])) + if ((__plus || __traits_type::eq(__c, __lit[_S_iminus])) + && !__traits_type::eq(__c, __lc->_M_decimal_point) + && (!__lc->_M_use_grouping + || !__traits_type::eq(__c, __lc->_M_thousands_sep))) { __xtrc += __plus ? _S_atoms_in[_S_iplus] : _S_atoms_in[_S_iminus]; @@ -176,16 +182,25 @@ namespace std } } - // Next, look for a zero... - bool __found_mantissa = false; - if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero])) + // Next, look for leading zeros. + while (__beg != __end) { - __xtrc += _S_atoms_in[_S_izero]; - __found_mantissa = true; - ++__beg; - // ... and skip the additional ones. - for (; __beg != __end - && __traits_type::eq(*__beg, __lit[_S_izero]); ++__beg); + const char_type __c = *__beg; + if (__traits_type::eq(__c, __lc->_M_decimal_point) + || (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep))) + break; + else if (__traits_type::eq(__c, __lit[_S_izero])) + { + if (!__found_mantissa) + { + __xtrc += _S_atoms_in[_S_izero]; + __found_mantissa = true; + } + ++__beg; + } + else + break; } // Only need acceptable digits for floating point numbers. @@ -197,39 +212,47 @@ namespace std const char_type* __p; while (__beg != __end) { - // According to 22.2.2.1.2, p8-9, first look for decimal_point - // and thousands_sep. + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. const char_type __c = *__beg; - if (__traits_type::eq(__c, __lc->_M_decimal_point) - && !__found_dec && !__found_sci) - { - // According to the standard, if no grouping chars are seen, - // no grouping check is applied. Therefore __found_grouping - // must be adjusted only if __dec comes after some __sep. - if (__found_grouping.size()) - __found_grouping += static_cast(__sep_pos); - __xtrc += '.'; - __found_dec = true; - ++__beg; - } - else if (__lc->_M_use_grouping - && __traits_type::eq(__c, __lc->_M_thousands_sep) - && !__found_dec && !__found_sci) + if (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep)) { - // NB: Thousands separator at the beginning of a string - // is a no-no, as is two consecutive thousands separators. - if (__sep_pos) - { - __found_grouping += static_cast(__sep_pos); - __sep_pos = 0; - ++__beg; - } - else + if (!__found_dec && !__found_sci) { - __err |= ios_base::failbit; - break; + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + ++__beg; + } + else + { + __err |= ios_base::failbit; + break; + } } + else + break; } + else if (__traits_type::eq(__c, __lc->_M_decimal_point)) + { + if (!__found_dec && !__found_sci) + { + // If no grouping chars are seen, no grouping check + // is applied. Therefore __found_grouping is adjusted + // only if decimal_point comes after some thousands_sep. + if (__found_grouping.size()) + __found_grouping += static_cast(__sep_pos); + __xtrc += '.'; + __found_dec = true; + ++__beg; + } + else + break; + } else if (__p = __traits_type::find(__lit + _S_izero, 10, __c)) { __xtrc += _S_atoms_in[__p - __lit]; @@ -307,48 +330,51 @@ namespace std // First check for sign. bool __negative = false; if (__beg != __end) - { + { + const char_type __c = *__beg; if (numeric_limits<_ValueT>::is_signed) - __negative = __traits_type::eq(*__beg, __lit[_S_iminus]); - if (__negative || __traits_type::eq(*__beg, __lit[_S_iplus])) + __negative = __traits_type::eq(__c, __lit[_S_iminus]); + if ((__negative || __traits_type::eq(__c, __lit[_S_iplus])) + && !__traits_type::eq(__c, __lc->_M_decimal_point) + && (!__lc->_M_use_grouping + || !__traits_type::eq(__c, __lc->_M_thousands_sep))) ++__beg; } // Next, look for leading zeros and check required digits // for base formats. - if (__beg != __end && __traits_type::eq(*__beg, __lit[_S_izero])) + while (__beg != __end) { - __found_num = true; - ++__beg; - if (__builtin_expect(__base == 10, true)) + const char_type __c = *__beg; + if (__traits_type::eq(__c, __lc->_M_decimal_point) + || (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep))) + break; + else if (__traits_type::eq(__c, __lit[_S_izero]) + && (!__found_num || __base == 10)) { - // Skip the additional zeros. - for (; __beg != __end - && __traits_type::eq(*__beg, __lit[_S_izero]); ++__beg); - - // Check required digits. - if (__beg != __end && __basefield == 0) - { - const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]); - if (__x || __traits_type::eq(*__beg, __lit[_S_iX])) - { - __base = 16; - ++__beg; - __found_num = false; - } - else - __base = 8; - } + __found_num = true; + ++__beg; } - else if (__base == 16 && __beg != __end) + else if (__found_num) { - const bool __x = __traits_type::eq(*__beg, __lit[_S_ix]); - if (__x || __traits_type::eq(*__beg, __lit[_S_iX])) + if (__traits_type::eq(__c, __lit[_S_ix]) + || __traits_type::eq(__c, __lit[_S_iX])) { - ++__beg; - __found_num = false; + if (__basefield == 0) + __base = 16; + if (__base == 16) + { + __found_num = false; + ++__beg; + } } + else if (__basefield == 0) + __base = 8; + break; } + else + break; } // At this point, base is determined. If not hex, only allow @@ -367,13 +393,11 @@ namespace std const _ValueT __min = numeric_limits<_ValueT>::min() / __base; for (; __beg != __end; ++__beg) { - // According to 22.2.2.1.2, p8-9, first look for decimal_point - // and thousands_sep. - const char_type __c = *__beg; - if (__traits_type::eq(__c, __lc->_M_decimal_point)) - break; - else if (__lc->_M_use_grouping - && __traits_type::eq(__c, __lc->_M_thousands_sep)) + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep)) { // NB: Thousands separator at the beginning of a string // is a no-no, as is two consecutive thousands separators. @@ -388,6 +412,8 @@ namespace std break; } } + else if (__traits_type::eq(__c, __lc->_M_decimal_point)) + break; else if (__p = __traits_type::find(__lit_zero, __len, __c)) { int __digit = __p - __lit_zero; @@ -414,11 +440,9 @@ namespace std const _ValueT __max = numeric_limits<_ValueT>::max() / __base; for (; __beg != __end; ++__beg) { - const char_type __c = *__beg; - if (__traits_type::eq(__c, __lc->_M_decimal_point)) - break; - else if (__lc->_M_use_grouping - && __traits_type::eq(__c, __lc->_M_thousands_sep)) + const char_type __c = *__beg; + if (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep)) { if (__sep_pos) { @@ -430,7 +454,9 @@ namespace std __err |= ios_base::failbit; break; } - } + } + else if (__traits_type::eq(__c, __lc->_M_decimal_point)) + break; else if (__p = __traits_type::find(__lit_zero, __len, __c)) { int __digit = __p - __lit_zero; @@ -503,8 +529,6 @@ namespace std __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); - const size_t __tn = __traits_type::length(__lc->_M_truename); - const size_t __fn = __traits_type::length(__lc->_M_falsename); bool __testf = true; bool __testt = true; @@ -512,13 +536,13 @@ namespace std for (__n = 0; __beg != __end; ++__n, ++__beg) { if (__testf) - if (__n < __fn) + if (__n < __lc->_M_falsename_len) __testf = __traits_type::eq(*__beg, __lc->_M_falsename[__n]); else break; if (__testt) - if (__n < __tn) + if (__n < __lc->_M_truename_len) __testt = __traits_type::eq(*__beg, __lc->_M_truename[__n]); else break; @@ -526,9 +550,9 @@ namespace std if (!__testf && !__testt) break; } - if (__testf && __n == __fn) + if (__testf && __n == __lc->_M_falsename_len) __v = 0; - else if (__testt && __n == __tn) + else if (__testt && __n == __lc->_M_truename_len) __v = 1; else __err |= ios_base::failbit; @@ -631,9 +655,7 @@ namespace std // Prepare for hex formatted input. typedef ios_base::fmtflags fmtflags; const fmtflags __fmt = __io.flags(); - const fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield - | ios_base::uppercase | ios_base::internal); - __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase)); + __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); unsigned long __ul; __beg = _M_extract_int(__beg, __end, __io, __err, __ul); @@ -1022,7 +1044,8 @@ namespace std const _CharT* __name = __v ? __lc->_M_truename : __lc->_M_falsename; - int __len = char_traits<_CharT>::length(__name); + int __len = __v ? __lc->_M_truename_len + : __lc->_M_falsename_len; const streamsize __w = __io.width(); if (__w > static_cast(__len)) @@ -1525,6 +1548,10 @@ namespace std time_get<_CharT, _InIter>::do_date_order() const { return time_base::no_order; } + // Recursively expand a strftime format string and parse it. Starts w/ %x + // and %X from do_get_time() and do_get_date(), which translate to a more + // specific string, which may contain yet more strings. I.e. %x => %r => + // %H:%M:%S => extracted characters. template void time_get<_CharT, _InIter>:: @@ -2245,23 +2272,22 @@ namespace std bool __verify_grouping(const basic_string<_CharT>& __grouping, const basic_string<_CharT>& __grouping_tmp) - { - size_t __i = 0; - size_t __j = 0; - const size_t __len = __grouping.size(); - const size_t __n = __grouping_tmp.size(); + { + const size_t __n = __grouping_tmp.size() - 1; + const size_t __min = std::min(__n, __grouping.size() - 1); + size_t __i = __n; bool __test = true; - + // Parsed number groupings have to match the // numpunct::grouping string exactly, starting at the // right-most point of the parsed sequence of elements ... - while (__test && __i < __n - 1) - for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j, ++__i) - __test = __grouping[__j] == __grouping_tmp[__n - __i - 1]; + for (size_t __j = 0; __j < __min && __test; --__i, ++__j) + __test = __grouping_tmp[__i] == __grouping[__j]; + for (; __i && __test; --__i) + __test = __grouping_tmp[__i] == __grouping[__min]; // ... but the last parsed grouping can be <= numpunct // grouping. - __j == __len ? __j = 0 : __j; - __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1]; + __test &= __grouping_tmp[0] <= __grouping[__min]; return __test; }