aboutsummaryrefslogtreecommitdiff
path: root/libbutl/diagnostics.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-07-26 13:44:24 +0200
committerKaren Arutyunov <karen@codesynthesis.com>2017-07-27 12:22:19 +0300
commit72450e72e400eb03325ca182f0e118fde8cd1705 (patch)
tree8e7d7c9fba4b99d047c1f770dcb85479b2c0ede1 /libbutl/diagnostics.hxx
parent3fae4ef8b228374c865bc0afcb1041eabae5a111 (diff)
Add support for printing progress
Diffstat (limited to 'libbutl/diagnostics.hxx')
-rw-r--r--libbutl/diagnostics.hxx57
1 files changed, 48 insertions, 9 deletions
diff --git a/libbutl/diagnostics.hxx b/libbutl/diagnostics.hxx
index c195ba0..9544945 100644
--- a/libbutl/diagnostics.hxx
+++ b/libbutl/diagnostics.hxx
@@ -23,8 +23,8 @@ namespace butl
// Diagnostics destination stream (std::cerr by default). Note that its
// modification is not MT-safe. Also note that concurrent writing to the
// stream from multiple threads can result in interleaved characters. To
- // prevent this an object of diag_lock type (see below) must be created prior
- // to write operation.
+ // prevent this an object of diag_stream_lock type (see below) must be
+ // created prior to write operation.
//
LIBBUTL_SYMEXPORT extern std::ostream* diag_stream;
@@ -32,12 +32,51 @@ namespace butl
// An object of the type must be created prior to writing to diag_stream (see
// above).
//
- struct LIBBUTL_SYMEXPORT diag_lock
+ struct LIBBUTL_SYMEXPORT diag_stream_lock
{
- diag_lock ();
- ~diag_lock ();
+ diag_stream_lock ();
+ ~diag_stream_lock ();
+
+ // Support for one-liners, for example:
+ //
+ // diag_stream_lock () << "Hello, World!" << endl;
+ //
+ template <typename T>
+ std::ostream&
+ operator<< (const T& x) const
+ {
+ return *diag_stream << x;
+ }
+ };
+
+ // Progress line facility.
+ //
+ // The idea is to keep a progress line at the bottom of the terminal with
+ // other output scrolling above it. The printing of the progress line is
+ // integrated into diag_stream_lock and diag_progress_lock. To print or
+ // update the progress acquire diag_progress_lock and update the
+ // diag_progress string. To remove the progress line, set this string to
+ // empty. For better readability start the progress line with a space
+ // (which is where the cursor will be parked). Should only be used if
+ // diag_stream points to std::cerr.
+ //
+ // Note that child processes writing to the same stream may not completely
+ // overwrite the progress line so in this case it makes sense to keep the
+ // line as short as possible.
+ //
+ // To restore the progress line being overwritten by an independent writer
+ // (such as a child process), create and destroy the diag_progress_lock.
+ //
+ LIBBUTL_SYMEXPORT extern std::string diag_progress;
+
+ struct LIBBUTL_SYMEXPORT diag_progress_lock
+ {
+ diag_progress_lock ();
+ ~diag_progress_lock ();
};
+ //
+ //
struct diag_record;
template <typename> struct diag_prologue;
template <typename> struct diag_mark;
@@ -47,11 +86,11 @@ namespace butl
struct LIBBUTL_SYMEXPORT diag_record
{
template <typename T>
- friend const diag_record&
- operator<< (const diag_record& r, const T& x)
+ const diag_record&
+ operator<< (const T& x) const
{
- r.os << x;
- return r;
+ os << x;
+ return *this;
}
diag_record ()