Skip to content

Commit

Permalink
StatusPrinter: only strip ANSI sequences when needed.
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
digit-google committed Aug 28, 2024
1 parent b16d27c commit 0b8f610
Showing 1 changed file with 21 additions and 24 deletions.
45 changes: 21 additions & 24 deletions src/status_printer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit 0b8f610

Please sign in to comment.