From d02475fdae3da10c9b821e529c6dda775279974c Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Mon, 29 Apr 2002 07:00:50 +0000 Subject: [PATCH] re PR libstdc++/5280 (Problems with named locales and iostreams (gnulocale)) 2002-04-28 Benjamin Kosnik PR libstdc++/5280 * config/io/basic_file_stdio.h (__basic_file::sys_getc): Return int. (__basic_file::sys_ungetc): Take int. * config/io/basic_file_stdio.cc (__basic_file::sys_ungetc): Same. * include/bits/fstream.tcc (basic_filebuf::_M_underflow_common): Use sys_getc for unbuffered input. * testsuite/27_io/narrow_stream_objects.cc (test06): New. * src/ios.cc (_M_grow_words): Adjust error checking. * testsuite/27_io/ios_base_storage.cc: Same. From-SVN: r52879 --- libstdc++-v3/ChangeLog | 13 ++++++ libstdc++-v3/config/io/basic_file_stdio.cc | 10 +++-- libstdc++-v3/config/io/basic_file_stdio.h | 6 +-- libstdc++-v3/include/bits/fstream.tcc | 19 ++++---- libstdc++-v3/src/ios.cc | 45 ++++++++++--------- .../testsuite/27_io/ios_base_storage.cc | 2 +- .../testsuite/27_io/narrow_stream_objects.cc | 23 +++++++++- 7 files changed, 79 insertions(+), 39 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7956c74d0c4..e1b79dbab32 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2002-04-28 Benjamin Kosnik + + PR libstdc++/5280 + * config/io/basic_file_stdio.h (__basic_file::sys_getc): Return int. + (__basic_file::sys_ungetc): Take int. + * config/io/basic_file_stdio.cc (__basic_file::sys_ungetc): Same. + * include/bits/fstream.tcc (basic_filebuf::_M_underflow_common): + Use sys_getc for unbuffered input. + * testsuite/27_io/narrow_stream_objects.cc (test06): New. + + * src/ios.cc (_M_grow_words): Adjust error checking. + * testsuite/27_io/ios_base_storage.cc: Same. + 2002-04-28 Peter Schmid * include/ext/stl_hashtable.h: Import __iterator_category diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc b/libstdc++-v3/config/io/basic_file_stdio.cc index eaebdf25ad9..25c93e322dc 100644 --- a/libstdc++-v3/config/io/basic_file_stdio.cc +++ b/libstdc++-v3/config/io/basic_file_stdio.cc @@ -81,11 +81,13 @@ namespace std return __ret; } - char - __basic_file::sys_getc() { return getc (_M_cfile); } + int + __basic_file::sys_getc() + { return getc(_M_cfile); } - char - __basic_file::sys_ungetc(char __s) { return ungetc (__s, _M_cfile); } + int + __basic_file::sys_ungetc(int __c) + { return ungetc(__c, _M_cfile); } __basic_file* __basic_file::open(const char* __name, ios_base::openmode __mode, diff --git a/libstdc++-v3/config/io/basic_file_stdio.h b/libstdc++-v3/config/io/basic_file_stdio.h index ca81d6d168f..137dfec9499 100644 --- a/libstdc++-v3/config/io/basic_file_stdio.h +++ b/libstdc++-v3/config/io/basic_file_stdio.h @@ -72,11 +72,11 @@ namespace std __basic_file* sys_open(__c_file* __file, ios_base::openmode __mode); - char + int sys_getc(); - char - sys_ungetc(char); + int + sys_ungetc(int); __basic_file* close(); diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index 740d5e2c433..2ca89c32fc2 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -224,6 +224,17 @@ namespace std return traits_type::to_int_type(*_M_in_cur); } + // Check for unbuffered stream. + if (_M_buf_size == 1) + { + __ret = _M_file.sys_getc(); + *_M_in_cur = traits_type::to_char_type(__ret); + _M_set_determinate(1); + if (__testout) + _M_out_cur = _M_in_cur; + return __ret; + } + // Sync internal and external buffers. // NB: __testget -> __testput as _M_buf_unified here. bool __testget = _M_in_cur && _M_in_beg < _M_in_cur; @@ -278,14 +289,6 @@ namespace std __ret = traits_type::to_int_type(*_M_in_cur); if (__bump) _M_in_cur_move(1); - else if (_M_buf_size == 1) - { - // If we are synced with stdio, we have to unget the - // character we just read so that the file pointer - // doesn't move. - _M_file.sys_ungetc(*_M_in_cur); - _M_set_indeterminate(); - } } } } diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index 1d97bf9e7a8..8e834fd65b0 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -226,32 +226,34 @@ namespace std // Precondition: _M_word_size <= ix int newsize = _S_local_word_size; _Words* words = _M_local_word; - int i = 0; if (ix > _S_local_word_size - 1) { - const int max = numeric_limits::max(); - if (ix < max) - newsize = ix + 1; - else - newsize = max; - - try - { words = new _Words[newsize]; } - catch (...) + if (ix < numeric_limits::max()) { - delete [] _M_word; - _M_word = 0; - _M_streambuf_state |= badbit; - if (_M_streambuf_state & _M_exception) - __throw_ios_failure("ios_base::_M_grow_words caused exception"); - return _M_word_zero; + newsize = ix + 1; + try + { words = new _Words[newsize]; } + catch (...) + { + delete [] _M_word; + _M_word = 0; + _M_streambuf_state |= badbit; + if (_M_streambuf_state & _M_exception) + __throw_ios_failure("ios_base::_M_grow_words failure"); + return _M_word_zero; + } + for (int i = 0; i < _M_word_size; i++) + words[i] = _M_word[i]; + if (_M_word && _M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } } - for (; i < _M_word_size; i++) - words[i] = _M_word[i]; - if (_M_word && _M_word != _M_local_word) + else { - delete [] _M_word; - _M_word = 0; + _M_streambuf_state |= badbit; + return _M_word_zero; } } _M_word = words; @@ -351,4 +353,3 @@ namespace std return __ret; } } // namespace std - diff --git a/libstdc++-v3/testsuite/27_io/ios_base_storage.cc b/libstdc++-v3/testsuite/27_io/ios_base_storage.cc index 560e6969512..c39d0302716 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base_storage.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base_storage.cc @@ -45,7 +45,7 @@ void test01() void test02() { bool test = true; - int max = std::numeric_limits::max(); + int max = std::numeric_limits::max() - 1; std::stringbuf strbuf; std::ios ios(&strbuf); diff --git a/libstdc++-v3/testsuite/27_io/narrow_stream_objects.cc b/libstdc++-v3/testsuite/27_io/narrow_stream_objects.cc index 3abcb07b47e..27291be00fc 100644 --- a/libstdc++-v3/testsuite/27_io/narrow_stream_objects.cc +++ b/libstdc++-v3/testsuite/27_io/narrow_stream_objects.cc @@ -1,6 +1,6 @@ // 2000-08-02 bkoz -// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -145,6 +145,26 @@ void test05() std::cout << "hello " << s << std::endl; } +// libstdc++/5280 +// Interactive test: input "1234^D^D" for i should terminate for EOF. +void test06() +{ + using namespace std; + int i; + cin >> i; + if (!cin.good()) + { + cerr << endl; + cerr << "i == " << i << endl; + cerr << "cin.rdstate() == " << cin.rdstate() << endl; + cerr << "cin.bad() == " << cin.bad() << endl; + cerr << "cin.fail() == " << cin.fail() << endl; + cerr << "cin.eof() == " << cin.eof() << endl; + } + else + cerr << "i == " << i << endl; +} + int main() { @@ -154,5 +174,6 @@ main() // test03(); // test04(); // test05(); + // test06(); return 0; }