aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-11-07 12:04:38 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-11-08 11:08:03 +0200
commit1703a30dec2695e7a5f1b81c633ac4c63479d9dd (patch)
tree48168a64b070f7e24384cce1ea2b4cc61d875602 /libbuild2
parent5efc7faaea8fc780cf0fc9d0629fc50ea4fbd3b4 (diff)
Allow passing fail diag record to diag_buffer::close()
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/cc/compile-rule.cxx15
-rw-r--r--libbuild2/diagnostics.cxx17
-rw-r--r--libbuild2/diagnostics.hxx5
3 files changed, 17 insertions, 20 deletions
diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx
index 7ccaeb4..f0854a7 100644
--- a/libbuild2/cc/compile-rule.cxx
+++ b/libbuild2/cc/compile-rule.cxx
@@ -4624,16 +4624,13 @@ namespace build2
diag_record dr;
if (bad_error)
- dr << error << "expected error exit status from "
+ dr << fail << "expected error exit status from "
<< x_lang << " compiler";
if (dbuf.is_open ())
- dbuf.close (move (dr));
+ dbuf.close (move (dr)); // Throws if error.
}
- if (bad_error)
- throw failed ();
-
// Ignore expected successes (we are done).
//
if (!restart && psrc)
@@ -4731,10 +4728,9 @@ namespace build2
// example, because we have removed all the partially
// preprocessed source files).
//
- bool f (force_gen_skip && *force_gen_skip == skip_count);
{
diag_record dr;
- if (f)
+ if (force_gen_skip && *force_gen_skip == skip_count)
{
dr <<
fail << "inconsistent " << x_lang << " compiler behavior" <<
@@ -4749,12 +4745,9 @@ namespace build2
}
if (dbuf.is_open ())
- dbuf.close (move (dr));
+ dbuf.close (move (dr)); // Throws if error.
}
- if (f)
- throw failed ();
-
restart = true;
force_gen = true;
force_gen_skip = skip_count;
diff --git a/libbuild2/diagnostics.cxx b/libbuild2/diagnostics.cxx
index 01bd43f..9433cd8 100644
--- a/libbuild2/diagnostics.cxx
+++ b/libbuild2/diagnostics.cxx
@@ -425,12 +425,20 @@ namespace build2
state_ = state::eof;
}
+ // Note: flushing of the diag record may throw.
+ //
+ args0 = nullptr;
+ state_ = state::closed;
+
if (!buf.empty () || !dr.empty ())
{
diag_stream_lock l;
if (!buf.empty ())
+ {
diag_stream->write (buf.data (), static_cast<streamsize> (buf.size ()));
+ buf.clear ();
+ }
if (!dr.empty ())
dr.flush ([] (const butl::diag_record& r)
@@ -438,14 +446,11 @@ namespace build2
// Similar to default_writer().
//
*diag_stream << r.os.str () << '\n';
+ diag_stream->flush ();
});
-
- diag_stream->flush ();
+ else
+ diag_stream->flush ();
}
-
- buf.clear ();
- args0 = nullptr;
- state_ = state::closed;
}
// diag_do(), etc.
diff --git a/libbuild2/diagnostics.hxx b/libbuild2/diagnostics.hxx
index b53d375..9d516be 100644
--- a/libbuild2/diagnostics.hxx
+++ b/libbuild2/diagnostics.hxx
@@ -657,9 +657,8 @@ namespace build2
bool omit_normall = false);
// As above but with a custom diag record for the child exit diagnostics,
- // if any.
- //
- // @@ TODO: currently cannot be used with the fail epilogue.
+ // if any. Note that if the diag record has the fail epilogue, then this
+ // function will throw.
//
void
close (diag_record&& = {});