aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-12-08 10:49:57 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-12-08 10:49:57 +0200
commitf7600f07eecbdac0a4400ca2bc39e3e9f5a53b1b (patch)
tree3bc35a46a68b41dab1148fdbac1d64b818b53960 /libbuild2
parente55ab94a6fa652c71cdb119dc1b269c836672930 (diff)
Add --[no]diag-color options (infrastructure only)
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/b-cmdline.cxx6
-rw-r--r--libbuild2/b-cmdline.hxx1
-rw-r--r--libbuild2/b-options.cxx33
-rw-r--r--libbuild2/b-options.hxx8
-rw-r--r--libbuild2/b-options.ixx12
-rw-r--r--libbuild2/b.cli18
-rw-r--r--libbuild2/context.cxx18
-rw-r--r--libbuild2/diagnostics.cxx40
-rw-r--r--libbuild2/diagnostics.hxx16
-rw-r--r--libbuild2/utility.hxx13
10 files changed, 152 insertions, 13 deletions
diff --git a/libbuild2/b-cmdline.cxx b/libbuild2/b-cmdline.cxx
index 2e2deb8..8d78036 100644
--- a/libbuild2/b-cmdline.cxx
+++ b/libbuild2/b-cmdline.cxx
@@ -396,6 +396,9 @@ namespace build2
if (ops.progress () && ops.no_progress ())
fail << "both --progress and --no-progress specified";
+ if (ops.diag_color () && ops.no_diag_color ())
+ fail << "both --diag-color and --no-diag-color specified";
+
if (ops.mtime_check () && ops.no_mtime_check ())
fail << "both --mtime-check and --no-mtime-check specified";
}
@@ -416,6 +419,9 @@ namespace build2
r.progress = (ops.progress () ? optional<bool> (true) :
ops.no_progress () ? optional<bool> (false) : nullopt);
+ r.diag_color = (ops.diag_color () ? optional<bool> (true) :
+ ops.no_diag_color () ? optional<bool> (false) : nullopt);
+
r.mtime_check = (ops.mtime_check () ? optional<bool> (true) :
ops.no_mtime_check () ? optional<bool> (false) : nullopt);
diff --git a/libbuild2/b-cmdline.hxx b/libbuild2/b-cmdline.hxx
index c5c82fc..8ccbb20 100644
--- a/libbuild2/b-cmdline.hxx
+++ b/libbuild2/b-cmdline.hxx
@@ -24,6 +24,7 @@ namespace build2
//
uint16_t verbosity = 1;
optional<bool> progress;
+ optional<bool> diag_color;
optional<bool> mtime_check;
optional<path> config_sub;
optional<path> config_guess;
diff --git a/libbuild2/b-options.cxx b/libbuild2/b-options.cxx
index c1e5f23..1fa801a 100644
--- a/libbuild2/b-options.cxx
+++ b/libbuild2/b-options.cxx
@@ -278,6 +278,8 @@ namespace build2
stat_ (),
progress_ (),
no_progress_ (),
+ diag_color_ (),
+ no_diag_color_ (),
jobs_ (),
jobs_specified_ (false),
max_jobs_ (),
@@ -449,6 +451,18 @@ namespace build2
this->no_progress_, a.no_progress_);
}
+ if (a.diag_color_)
+ {
+ ::build2::build::cli::parser< bool>::merge (
+ this->diag_color_, a.diag_color_);
+ }
+
+ if (a.no_diag_color_)
+ {
+ ::build2::build::cli::parser< bool>::merge (
+ this->no_diag_color_, a.no_diag_color_);
+ }
+
if (a.jobs_specified_)
{
::build2::build::cli::parser< size_t>::merge (
@@ -690,6 +704,19 @@ namespace build2
<< "\033[1m--no-progress\033[0m Don't display build progress." << ::std::endl;
os << std::endl
+ << "\033[1m--diag-color\033[0m Use color in diagnostics. If printing to a terminal the" << ::std::endl
+ << " color is used by default provided the terminal is not" << ::std::endl
+ << " dumb. Use \033[1m--no-diag-color\033[0m to suppress." << ::std::endl
+ << ::std::endl
+ << " This option affects the diagnostics printed by the" << ::std::endl
+ << " build system itself. Some rules may also choose to" << ::std::endl
+ << " propagate its value to tools (such as compilers) that" << ::std::endl
+ << " they invoke." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-diag-color\033[0m Don't use color in diagnostics." << ::std::endl;
+
+ os << std::endl
<< "\033[1m--jobs\033[0m|\033[1m-j\033[0m \033[4mnum\033[0m Number of active jobs to perform in parallel. This" << ::std::endl
<< " includes both the number of active threads inside the" << ::std::endl
<< " build system as well as the number of external commands" << ::std::endl
@@ -763,7 +790,7 @@ namespace build2
<< " in order to prevent interleaving. However, this can" << ::std::endl
<< " have side-effects since the child process' \033[1mstderr\033[0m is no" << ::std::endl
<< " longer a terminal. Most notably, the use of color in" << ::std::endl
- << " diagnostics will be disabled by most programs. On the" << ::std::endl
+ << " diagnostics may be disabled by some programs. On the" << ::std::endl
<< " other hand, depending on the platform and programs" << ::std::endl
<< " invoked, the interleaving diagnostics may not break" << ::std::endl
<< " lines and thus could be tolerable." << ::std::endl;
@@ -998,6 +1025,10 @@ namespace build2
&::build2::build::cli::thunk< b_options, &b_options::progress_ >;
_cli_b_options_map_["--no-progress"] =
&::build2::build::cli::thunk< b_options, &b_options::no_progress_ >;
+ _cli_b_options_map_["--diag-color"] =
+ &::build2::build::cli::thunk< b_options, &b_options::diag_color_ >;
+ _cli_b_options_map_["--no-diag-color"] =
+ &::build2::build::cli::thunk< b_options, &b_options::no_diag_color_ >;
_cli_b_options_map_["--jobs"] =
&::build2::build::cli::thunk< b_options, size_t, &b_options::jobs_,
&b_options::jobs_specified_ >;
diff --git a/libbuild2/b-options.hxx b/libbuild2/b-options.hxx
index 4e85192..d965ff6 100644
--- a/libbuild2/b-options.hxx
+++ b/libbuild2/b-options.hxx
@@ -104,6 +104,12 @@ namespace build2
const bool&
no_progress () const;
+ const bool&
+ diag_color () const;
+
+ const bool&
+ no_diag_color () const;
+
const size_t&
jobs () const;
@@ -266,6 +272,8 @@ namespace build2
bool stat_;
bool progress_;
bool no_progress_;
+ bool diag_color_;
+ bool no_diag_color_;
size_t jobs_;
bool jobs_specified_;
size_t max_jobs_;
diff --git a/libbuild2/b-options.ixx b/libbuild2/b-options.ixx
index 895831f..cdbbc3a 100644
--- a/libbuild2/b-options.ixx
+++ b/libbuild2/b-options.ixx
@@ -80,6 +80,18 @@ namespace build2
return this->no_progress_;
}
+ inline const bool& b_options::
+ diag_color () const
+ {
+ return this->diag_color_;
+ }
+
+ inline const bool& b_options::
+ no_diag_color () const
+ {
+ return this->no_diag_color_;
+ }
+
inline const size_t& b_options::
jobs () const
{
diff --git a/libbuild2/b.cli b/libbuild2/b.cli
index 4b5e459..773e29e 100644
--- a/libbuild2/b.cli
+++ b/libbuild2/b.cli
@@ -549,6 +549,22 @@ namespace build2
"Don't display build progress."
}
+ bool --diag-color
+ {
+ "Use color in diagnostics. If printing to a terminal the color is used
+ by default provided the terminal is not dumb. Use \cb{--no-diag-color}
+ to suppress.
+
+ This option affects the diagnostics printed by the build system itself.
+ Some rules may also choose to propagate its value to tools (such as
+ compilers) that they invoke."
+ }
+
+ bool --no-diag-color
+ {
+ "Don't use color in diagnostics."
+ }
+
size_t --jobs|-j
{
"<num>",
@@ -632,7 +648,7 @@ namespace build2
once after each child exits in order to prevent interleaving.
However, this can have side-effects since the child process'
\cb{stderr} is no longer a terminal. Most notably, the use of
- color in diagnostics will be disabled by most programs. On the
+ color in diagnostics may be disabled by some programs. On the
other hand, depending on the platform and programs invoked, the
interleaving diagnostics may not break lines and thus could be
tolerable."
diff --git a/libbuild2/context.cxx b/libbuild2/context.cxx
index 967577f..c9f4340 100644
--- a/libbuild2/context.cxx
+++ b/libbuild2/context.cxx
@@ -204,10 +204,10 @@ namespace build2
//
set ("build.verbosity", uint64_t (verb));
- // Build system progress diagnostics.
+ // Build system diagnostics progress and color.
//
- // Note that it can be true, false, or NULL if progress was neither
- // requested nor suppressed.
+ // Note that these can be true, false, or NULL if neither requested nor
+ // suppressed explicitly.
//
{
value& v (gs.assign (vp.insert<bool> ("build.progress", v_g)));
@@ -215,6 +215,18 @@ namespace build2
v = *diag_progress_option;
}
+ {
+ value& v (gs.assign (vp.insert<bool> ("build.diag_color", v_g)));
+ if (diag_color_option)
+ v = *diag_color_option;
+ }
+
+ // These are the "effective" values that incorporate a suitable default
+ // if neither requested nor suppressed explicitly.
+ //
+ set ("build.show_progress", show_progress (verb_never));
+ set ("build.show_diag_color", show_diag_color ());
+
// Build system version (similar to what we do in the version module
// except here we don't include package epoch/revision).
//
diff --git a/libbuild2/diagnostics.cxx b/libbuild2/diagnostics.cxx
index d91150b..b31ff82 100644
--- a/libbuild2/diagnostics.cxx
+++ b/libbuild2/diagnostics.cxx
@@ -3,7 +3,8 @@
#include <libbuild2/diagnostics.hxx>
-#include <cstring> // strchr(), memcpy()
+#include <cstring> // strcmp(), strchr(), memcpy()
+#include <cstdlib> // getenv()
#include <libbutl/process-io.hxx>
@@ -24,23 +25,54 @@ namespace build2
bool silent = true;
optional<bool> diag_progress_option;
+ optional<bool> diag_color_option;
bool diag_no_line = false;
bool diag_no_column = false;
- bool stderr_term = false;
+ optional<const char*> stderr_term = nullopt;
+ bool stderr_term_color = false;
void
- init_diag (uint16_t v, bool s, optional<bool> p, bool nl, bool nc, bool st)
+ init_diag (uint16_t v,
+ bool s,
+ optional<bool> p,
+ optional<bool> c,
+ bool nl,
+ bool nc,
+ bool st)
{
assert (!s || v == 0);
verb = v;
silent = s;
diag_progress_option = p;
+ diag_color_option = c;
diag_no_line = nl;
diag_no_column = nc;
- stderr_term = st;
+
+ if (st)
+ {
+ stderr_term = std::getenv ("TERM");
+
+ stderr_term_color =
+#ifdef _WIN32
+ // For now we disable color on Windows since it's unclear if/where/how
+ // it is supported. Maybe one day someone will figure this out.
+ //
+ false
+#else
+ // This test was lifted from GCC (Emacs shell sets TERM=dumb).
+ //
+ *stderr_term != nullptr && strcmp (*stderr_term, "dumb") != 0
+#endif
+ ;
+ }
+ else
+ {
+ stderr_term = nullopt;
+ stderr_term_color = false;
+ }
}
// Stream verbosity.
diff --git a/libbuild2/diagnostics.hxx b/libbuild2/diagnostics.hxx
index c048d5b..129e00d 100644
--- a/libbuild2/diagnostics.hxx
+++ b/libbuild2/diagnostics.hxx
@@ -401,15 +401,25 @@ namespace build2
using butl::diag_progress_lock;
// Return true if progress is to be shown. The max_verb argument is the
- // maximum verbosity level that this type of progress should be shown by
- // default.
+ // maximum verbosity level that this type of progress should be shown at by
+ // default. If it is verb_never, then both min and max verbosity checks are
+ // omitted, assuming the caller takes care of that themselves.
//
inline bool
show_progress (uint16_t max_verb)
{
return diag_progress_option
? *diag_progress_option
- : stderr_term && verb >= 1 && verb <= max_verb;
+ : stderr_term && (max_verb == verb_never ||
+ (verb >= 1 && verb <= max_verb));
+ }
+
+ // Diagnostics color.
+ //
+ inline bool
+ show_diag_color ()
+ {
+ return diag_color_option ? *diag_color_option : stderr_term_color;
}
// Diagnostic facility.
diff --git a/libbuild2/utility.hxx b/libbuild2/utility.hxx
index c12fae7..e27eec2 100644
--- a/libbuild2/utility.hxx
+++ b/libbuild2/utility.hxx
@@ -129,6 +129,7 @@ namespace build2
init_diag (uint16_t verbosity,
bool silent = false,
optional<bool> progress = nullopt,
+ optional<bool> diag_color = nullopt,
bool no_lines = false,
bool no_columns = false,
bool stderr_term = false);
@@ -138,13 +139,23 @@ namespace build2
LIBBUILD2_SYMEXPORT extern bool silent;
// --[no-]progress
+ // --[no-]diag-color
//
LIBBUILD2_SYMEXPORT extern optional<bool> diag_progress_option;
+ LIBBUILD2_SYMEXPORT extern optional<bool> diag_color_option;
LIBBUILD2_SYMEXPORT extern bool diag_no_line; // --no-line
LIBBUILD2_SYMEXPORT extern bool diag_no_column; // --no-column
- LIBBUILD2_SYMEXPORT extern bool stderr_term; // True if stderr is a terminal.
+ // If stderr is not a terminal, then the value is absent (so can be used as
+ // bool). Otherwise, it is the value of the TERM environment variable (which
+ // can be NULL).
+ //
+ LIBBUILD2_SYMEXPORT extern optional<const char*> stderr_term;
+
+ // True if the color can be used on the stderr terminal.
+ //
+ LIBBUILD2_SYMEXPORT extern bool stderr_term_color;
// Global state (verbosity, home/work directories, etc).