diff options
-rw-r--r-- | build2/b.cxx | 1 | ||||
-rw-r--r-- | libbuild2/b-cmdline.cxx | 6 | ||||
-rw-r--r-- | libbuild2/b-cmdline.hxx | 1 | ||||
-rw-r--r-- | libbuild2/b-options.cxx | 33 | ||||
-rw-r--r-- | libbuild2/b-options.hxx | 8 | ||||
-rw-r--r-- | libbuild2/b-options.ixx | 12 | ||||
-rw-r--r-- | libbuild2/b.cli | 18 | ||||
-rw-r--r-- | libbuild2/context.cxx | 18 | ||||
-rw-r--r-- | libbuild2/diagnostics.cxx | 40 | ||||
-rw-r--r-- | libbuild2/diagnostics.hxx | 16 | ||||
-rw-r--r-- | libbuild2/utility.hxx | 13 |
11 files changed, 153 insertions, 13 deletions
diff --git a/build2/b.cxx b/build2/b.cxx index 68c77c8..0e52d25 100644 --- a/build2/b.cxx +++ b/build2/b.cxx @@ -329,6 +329,7 @@ main (int argc, char* argv[]) init_diag (cmdl.verbosity, ops.silent (), cmdl.progress, + cmdl.diag_color, ops.no_line (), ops.no_column (), fdterm (stderr_fd ())); 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). |