diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e773f32ff48..40378505d9c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2003-10-28 Paolo Carlini + + * include/bits/locale_facets.tcc + (money_get<>::do_get(..., string_type&)): Absolutely avoid + dereferencing end iterators; general clean up. + 2003-10-28 Paolo Carlini * include/bits/locale_facets.tcc (time_get::_M_extract_num): diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index c890e7026f4..6af77a95d94 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -1144,10 +1144,10 @@ namespace std const money_base::pattern __p = __intl ? __mpt.neg_format() : __mpf.neg_format(); - const string_type __pos_sign =__intl ? __mpt.positive_sign() - : __mpf.positive_sign(); - const string_type __neg_sign =__intl ? __mpt.negative_sign() - : __mpf.negative_sign(); + const string_type __pos_sign = __intl ? __mpt.positive_sign() + : __mpf.positive_sign(); + const string_type __neg_sign = __intl ? __mpt.negative_sign() + : __mpf.negative_sign(); const char_type __d = __intl ? __mpt.decimal_point() : __mpf.decimal_point(); const char_type __sep = __intl ? __mpt.thousands_sep() @@ -1169,113 +1169,103 @@ namespace std // The tentative returned string is stored here. string_type __tmp_units; - char_type __c = *__beg; for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i) { + char_type __c; const part __which = static_cast(__p.field[__i]); switch (__which) + { + case money_base::symbol: + if (__io.flags() & ios_base::showbase + || __i < 2 || __sign.size() > 1 + || ((static_cast(__p.field[3]) != money_base::none) + && __i == 2)) { - case money_base::symbol: - if (__io.flags() & ios_base::showbase - || __i < 2 || __sign.size() > 1 - || ((static_cast(__p.field[3]) != money_base::none) - && __i == 2)) - { - // According to 22.2.6.1.2.2, symbol is required - // if (__io.flags() & ios_base::showbase), - // otherwise is optional and consumed only if - // other characters are needed to complete the - // format. - const string_type __symbol = __intl ? __mpt.curr_symbol() - : __mpf.curr_symbol(); - const size_type __len = __symbol.size(); - size_type __j = 0; - while (__beg != __end - && __j < __len && __symbol[__j] == __c) - { - __c = *(++__beg); - ++__j; - } - // When (__io.flags() & ios_base::showbase) - // symbol is required. - if (__j != __len && (__io.flags() & ios_base::showbase)) - __testvalid = false; - } - break; - case money_base::sign: - // Sign might not exist, or be more than one character long. - if (__pos_sign.size() && __c == __pos_sign[0]) - { - __sign = __pos_sign; - __c = *(++__beg); - } - else if (__neg_sign.size() && __c == __neg_sign[0]) - { - __sign = __neg_sign; - __c = *(++__beg); - } - else if (__pos_sign.size() && __neg_sign.size()) - { - // Sign is mandatory. - __testvalid = false; - } - break; - case money_base::value: - // Extract digits, remove and stash away the - // grouping of found thousands separators. - while (__beg != __end - && (__ctype.is(ctype_base::digit, __c) - || (__c == __d && !__testdecfound) - || __c == __sep)) - { - if (__c == __d) - { - __grouping_tmp += static_cast(__sep_pos); - __sep_pos = 0; - __testdecfound = true; - } - else if (__c == __sep) - { - if (__grouping.size()) - { - // Mark position for later analysis. - __grouping_tmp += static_cast(__sep_pos); - __sep_pos = 0; - } - else - { - __testvalid = false; - break; - } - } - else - { - __tmp_units += __c; - ++__sep_pos; - } - __c = *(++__beg); - } - break; - case money_base::space: - case money_base::none: - // Only if not at the end of the pattern. - if (__i != 3) - while (__beg != __end - && __ctype.is(ctype_base::space, __c)) - __c = *(++__beg); - break; + // According to 22.2.6.1.2.2, symbol is required + // if (__io.flags() & ios_base::showbase), + // otherwise is optional and consumed only if + // other characters are needed to complete the + // format. + const string_type __symbol = __intl ? __mpt.curr_symbol() + : __mpf.curr_symbol(); + const size_type __len = __symbol.size(); + size_type __j = 0; + for (; __beg != __end && __j < __len + && *__beg == __symbol[__j]; ++__beg, ++__j); + // When (__io.flags() & ios_base::showbase) + // symbol is required. + if (__j != __len && (__io.flags() & ios_base::showbase)) + __testvalid = false; } + break; + case money_base::sign: + // Sign might not exist, or be more than one character long. + if (__pos_sign.size() && *__beg == __pos_sign[0]) + { + __sign = __pos_sign; + ++__beg; + } + else if (__neg_sign.size() && *__beg == __neg_sign[0]) + { + __sign = __neg_sign; + ++__beg; + } + else if (__pos_sign.size() && __neg_sign.size()) + { + // Sign is mandatory. + __testvalid = false; + } + break; + case money_base::value: + // Extract digits, remove and stash away the + // grouping of found thousands separators. + for (; __beg != __end; ++__beg) + if (__ctype.is(ctype_base::digit, __c = *__beg)) + { + __tmp_units += __c; + ++__sep_pos; + } + else if (__c == __d && !__testdecfound) + { + __grouping_tmp += static_cast(__sep_pos); + __sep_pos = 0; + __testdecfound = true; + } + else if (__c == __sep) + { + if (__grouping.size()) + { + // Mark position for later analysis. + __grouping_tmp += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + __testvalid = false; + break; + } + } + else + break; + break; + case money_base::space: + case money_base::none: + // Only if not at the end of the pattern. + if (__i != 3) + for (; __beg != __end + && __ctype.is(ctype_base::space, *__beg); ++__beg); + break; + } } - + // Need to get the rest of the sign characters, if they exist. - const char_type __eof = static_cast(char_traits::eof()); if (__sign.size() > 1) { const size_type __len = __sign.size(); size_type __i = 1; - for (; __c != __eof && __i < __len; ++__i) - while (__beg != __end && __c != __sign[__i]) - __c = *(++__beg); + for (; __beg != __end && __i < __len; ++__i) + for (; __beg != __end + && *__beg != __sign[__i]; ++__beg); if (__i != __len) __testvalid = false; @@ -1320,7 +1310,7 @@ namespace std __testvalid = false; // Iff no more characters are available. - if (__c == __eof) + if (__beg == __end) __err |= ios_base::eofbit; // Iff valid sequence is not recognized.