From 0b8f61080f30adb01022101cd24fe3071ee734d1 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Sun, 19 May 2024 12:50:40 +0200 Subject: [PATCH] StatusPrinter: only strip ANSI sequences when needed. Just check for the ESC character in the `output` string, if none is present, or if the terminal supports color, avoid unnecessary busy work (string allocations and parsing). --- src/status_printer.cc | 45 ++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/status_printer.cc b/src/status_printer.cc index ed48a5c77b..62c7d7a9d2 100644 --- a/src/status_printer.cc +++ b/src/status_printer.cc @@ -216,37 +216,34 @@ void StatusPrinter::BuildEdgeFinished(Edge* edge, int64_t start_time_millis, printer_.PrintOnNewLine(edge->EvaluateCommand() + "\n"); } - if (!output.empty()) { - // ninja sets stdout and stderr of subprocesses to a pipe, to be able to - // check if the output is empty. Some compilers, e.g. clang, check - // isatty(stderr) to decide if they should print colored output. - // To make it possible to use colored output with ninja, subprocesses should - // be run with a flag that forces them to always print color escape codes. - // To make sure these escape codes don't show up in a file if ninja's output - // is piped to a file, ninja strips ansi escape codes again if it's not - // writing to a |smart_terminal_|. - // (Launching subprocesses in pseudo ttys doesn't work because there are - // only a few hundred available on some systems, and ninja can launch - // thousands of parallel compile commands.) - string final_output; - if (!printer_.supports_color()) - final_output = StripAnsiEscapeCodes(output); - else - final_output = output; - #ifdef _WIN32 - // Fix extra CR being added on Windows, writing out CR CR LF (#773) - fflush(stdout); // Begin Windows extra CR fix - _setmode(_fileno(stdout), _O_BINARY); + // Fix extra CR being added on Windows, writing out CR CR LF (#773) + fflush(stdout); // Begin Windows extra CR fix + _setmode(_fileno(stdout), _O_BINARY); #endif + // ninja sets stdout and stderr of subprocesses to a pipe, to be able to + // check if the output is empty. Some compilers, e.g. clang, check + // isatty(stderr) to decide if they should print colored output. + // To make it possible to use colored output with ninja, subprocesses should + // be run with a flag that forces them to always print color escape codes. + // To make sure these escape codes don't show up in a file if ninja's output + // is piped to a file, ninja strips ansi escape codes again if it's not + // writing to a |smart_terminal_|. + // (Launching subprocesses in pseudo ttys doesn't work because there are + // only a few hundred available on some systems, and ninja can launch + // thousands of parallel compile commands.) + if (printer_.supports_color() || output.find('\x1b') == std::string::npos) { + printer_.PrintOnNewLine(output); + } else { + std::string final_output = StripAnsiEscapeCodes(output); printer_.PrintOnNewLine(final_output); + } #ifdef _WIN32 - fflush(stdout); - _setmode(_fileno(stdout), _O_TEXT); // End Windows extra CR fix + fflush(stdout); + _setmode(_fileno(stdout), _O_TEXT); // End Windows extra CR fix #endif - } } void StatusPrinter::BuildStarted() {