aboutsummaryrefslogtreecommitdiff
path: root/libbutl/pager.mxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-09-22 23:32:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-09-22 23:32:28 +0200
commitc09cd7512491cee1e82c1ad8128ce9fd4bc3f79b (patch)
treea659ed768d849130ab5780a11b7f791a463a1a91 /libbutl/pager.mxx
parent2a00871f07067f8f9e2de08bb9c8f50e1bf6a650 (diff)
Initial modularization with both Clang and VC hacks
Note: gave up on VC about half way though.
Diffstat (limited to 'libbutl/pager.mxx')
-rw-r--r--libbutl/pager.mxx103
1 files changed, 103 insertions, 0 deletions
diff --git a/libbutl/pager.mxx b/libbutl/pager.mxx
new file mode 100644
index 0000000..6955f53
--- /dev/null
+++ b/libbutl/pager.mxx
@@ -0,0 +1,103 @@
+// file : libbutl/pager.mxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <vector>
+#include <iostream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.pager;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.process;
+import butl.fdstream;
+#else
+#include <libbutl/process.mxx>
+#include <libbutl/fdstream.mxx>
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
+{
+ // Try to run the output through a pager program, such as more or less (no
+ // pun intended, less is used by default). If the default pager program is
+ // used, then the output is indented so that 80-character long lines will
+ // appear centered in the terminal. If the default pager program fails to
+ // start, then the output is sent directly to STDOUT.
+ //
+ // If the pager program is specified and is empty, then no pager is used
+ // and the output is sent directly to STDOUT.
+ //
+ // Throw std::system_error if there are problems with the pager program.
+ //
+ // Typical usage:
+ //
+ // try
+ // {
+ // pager p ("help for foo");
+ // ostream& os (p.stream ());
+ //
+ // os << "Foo is such and so ...";
+ //
+ // if (!p.wait ())
+ // ... // Pager program returned non-zero status.
+ // }
+ // catch (const std::system_error& e)
+ // {
+ // cerr << "pager error: " << e << endl;
+ // }
+ //
+ class LIBBUTL_SYMEXPORT pager: protected std::streambuf
+ {
+ public:
+ ~pager () {wait (true);}
+
+ // If verbose is true, then print (to STDERR) the pager command line.
+ //
+ pager (const std::string& name,
+ bool verbose = false,
+ const std::string* pager = nullptr,
+ const std::vector<std::string>* pager_options = nullptr);
+
+ std::ostream&
+ stream () {return os_.is_open () ? os_ : std::cout;}
+
+ bool
+ wait (bool ignore_errors = false);
+
+ // The streambuf output interface that implements indentation. You can
+ // override it to implement custom output pre-processing.
+ //
+ protected:
+ using int_type = std::streambuf::int_type;
+ using traits_type = std::streambuf::traits_type;
+
+ virtual int_type
+ overflow (int_type);
+
+ virtual int
+ sync ();
+
+ private:
+ process p_;
+ ofdstream os_;
+
+ std::string indent_;
+ int_type prev_ = '\n'; // Previous character.
+ std::streambuf* buf_ = nullptr;
+ };
+}