diff options
Diffstat (limited to 'tests/fdstream')
-rw-r--r-- | tests/fdstream/driver.cxx | 192 |
1 files changed, 184 insertions, 8 deletions
diff --git a/tests/fdstream/driver.cxx b/tests/fdstream/driver.cxx index 3972473..0c6c480 100644 --- a/tests/fdstream/driver.cxx +++ b/tests/fdstream/driver.cxx @@ -2,9 +2,11 @@ // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file +#include <ios> #include <string> #include <cassert> -#include <system_error> +#include <sstream> +#include <exception> #include <butl/path> #include <butl/fdstream> @@ -20,20 +22,20 @@ static const string text3 ("ABCDEF\r\nXYZ"); static string from_file (const path& f, fdopen_mode m = fdopen_mode::none) { - ifdstream ifs (fdopen (f, m | fdopen_mode::in)); - ifs.exceptions (ifdstream::badbit); + ifdstream ifs (f, m, ifdstream::badbit); string s; getline (ifs, s, '\0'); + ifs.close (); // Not to miss failed close of the underlying file descriptor. return s; } static void to_file (const path& f, const string& s, fdopen_mode m = fdopen_mode::none) { - ofdstream ofs (fdopen (f, m | fdopen_mode::out)); - ofs.exceptions (ofdstream::badbit | ofdstream::failbit); + ofdstream ofs (f, m); ofs << s; + ofs.close (); } int @@ -55,7 +57,7 @@ main () fdopen (f, fdopen_mode::out); // fdopen_mode::create is missed. assert (false); } - catch (const system_error&) + catch (const ios::failure&) { } @@ -64,13 +66,45 @@ main () assert (from_file (f, fdopen_mode::create) == ""); assert (try_rmfile (f) == rmfile_status::success); + // Read from the newly created non-empty file. + // to_file (f, text1, fdopen_mode::create); assert (from_file (f) == text1); + // Check that skip on close as requested. + // + { + ifdstream ifs (fdopen (f, fdopen_mode::in), fdstream_mode::skip); + + string s; + getline (ifs, s); + assert (!ifs.eof ()); + + ifs.close (); + assert (ifs.eof ()); + } + + // Check that don't skip on close by default. + // + { + ifdstream ifs (fdopen (f, fdopen_mode::in)); + + string s; + getline (ifs, s); + assert (!ifs.eof ()); + + ifs.close (); + assert (!ifs.eof ()); + } + // Read from the file opened in R/W mode. // assert (from_file (f, fdopen_mode::out) == text1); + // Read starting from the file's end. + // + assert (from_file (f, fdopen_mode::at_end) == ""); + try { // Fail to create if the file already exists. @@ -80,7 +114,7 @@ main () assert (false); } - catch (const system_error&) + catch (const ios::failure&) { } @@ -101,6 +135,148 @@ main () to_file (f, text2, fdopen_mode::append); assert (from_file (f) == text1 + text2); + // Append to the file with the yet another way. + // + to_file (f, text1, fdopen_mode::truncate); + to_file (f, text2, fdopen_mode::at_end); + assert (from_file (f) == text1 + text2); + + // Check creating unopened ifdstream with a non-default exception mask. + // + to_file (f, "", fdopen_mode::truncate); + + { + ifdstream ifs (-1, ifdstream::badbit); + ifs.open (f); + + string s; + assert (!getline (ifs, s)); + } + + { + ifdstream ifs (-1, fdstream_mode::text, ifdstream::badbit); + ifs.open (f); + + string s; + assert (!getline (ifs, s)); + } + + // Check creating unopened ofdstream with a non-default exception mask. + // + { + ofdstream ofs (-1, ifdstream::badbit); + ofs.open (f); + + istringstream is; + ofs << is.rdbuf (); // Sets failbit if no characters is inserted. + ofs.close (); + } + + { + ofdstream ofs (-1, fdstream_mode::binary, ifdstream::badbit); + ofs.open (f); + + istringstream is; + ofs << is.rdbuf (); // Sets failbit if no characters is inserted. + ofs.close (); + } + + // Fail to write to a read-only file. + // + // Don't work well for MinGW GCC (5.2.0) that throws ios::failure, which in + // combination with libstdc++'s ios::failure ABI fiasco (#66145) make it + // impossible to properly catch in this situation. + // + try + { + { + ofdstream ofs (fdopen (f, fdopen_mode::in)); + ofs << text1; + ofs.flush (); + } + + assert (false); + } +#if !defined(_WIN32) || !defined(__GLIBCXX__) + catch (const ios::failure&) + { + } +#else + catch (const std::exception&) + { + } +#endif + + try + { + ofdstream ofs; + ofs.open (fdopen (f, fdopen_mode::in)); + ofs << text1; + ofs.close (); + + assert (false); + } +#if !defined(_WIN32) || !defined(__GLIBCXX__) + catch (const ios::failure&) + { + } +#else + catch (const std::exception&) + { + } +#endif + + // Fail to read from a write-only file. + // + try + { + ifdstream ifs (fdopen (f, fdopen_mode::out)); + ifs.peek (); + + assert (false); + } + catch (const ios::failure&) + { + } + + try + { + ifdstream ifs; + ifs.open (fdopen (f, fdopen_mode::out)); + ifs.peek (); + + assert (false); + } + catch (const ios::failure&) + { + } + + // Dtor of a not opened ofdstream doesn't terminate a program. + // + { + ofdstream ofs; + } + + // Dtor of an opened ofdstream doesn't terminate a program during the stack + // unwinding. + // + try + { + ofdstream ofs (f); + throw true; + } + catch (bool) + { + } + + // Dtor of an opened but being in a bad state ofdstream doesn't terminate a + // program. + // + { + ofdstream ofs (f, fdopen_mode::out, ofdstream::badbit); + ofs.clear (ofdstream::failbit); + } + #ifndef _WIN32 // Fail for an existing symlink to unexistent file. @@ -115,7 +291,7 @@ main () assert (false); } - catch (const system_error&) + catch (const ios::failure&) { } |