aboutsummaryrefslogtreecommitdiff
path: root/tests/fdstream/driver.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-07-12 17:24:00 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-07-23 19:42:48 +0300
commit6c8e3f09c185d7fa4664ccd9e5c4f623a17b84cc (patch)
tree513f523dba31f275994d8152c02db82f3380c56e /tests/fdstream/driver.cxx
parent09bedede7116961fbfb298a6a6cfa933af7af682 (diff)
Extend fdstream
Diffstat (limited to 'tests/fdstream/driver.cxx')
-rw-r--r--tests/fdstream/driver.cxx192
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&)
{
}