about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorKevin Ballard <kevin@sb.org>2014-05-19 14:37:52 -0700
committerKevin Ballard <kevin@sb.org>2014-05-19 18:45:36 -0700
commitb991bbe2d0f148d25d00a8c17bfa6304d1b1ae5a (patch)
tree0a75a4ffaab40116499c84fc285c0a7575cbcce1 /src/libsyntax
parente8c579e01d026df002fe6522d6f9c123b3920dc8 (diff)
downloadrust-b991bbe2d0f148d25d00a8c17bfa6304d1b1ae5a.tar.gz
rust-b991bbe2d0f148d25d00a8c17bfa6304d1b1ae5a.zip
Reset the terminal color before the newline for diagnostics
When printing colored diagnostics, we need to reset the terminal before
emitting the newline, not after. Otherwise it gets line-buffered and the
color won't reset until the next line is printed or the compiler exits.

Normally this isn't a problem, but when running rustc in parallel with
other processes (e.g. `make -j4`) this can cause the color to leak
to other lines.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/diagnostic.rs23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 1a07393f9fc..3eb6f40ba53 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -232,8 +232,27 @@ fn print_maybe_styled(w: &mut EmitterWriter,
     match w.dst {
         Terminal(ref mut t) => {
             try!(t.attr(color));
-            try!(t.write_str(msg));
-            try!(t.reset());
+            // If `msg` ends in a newline, we need to reset the color before
+            // the newline. We're making the assumption that we end up writing
+            // to a `LineBufferedWriter`, which means that emitting the reset
+            // after the newline ends up buffering the reset until we print
+            // another line or exit. Buffering the reset is a problem if we're
+            // sharing the terminal with any other programs (e.g. other rustc
+            // instances via `make -jN`).
+            //
+            // Note that if `msg` contains any internal newlines, this will
+            // result in the `LineBufferedWriter` flushing twice instead of
+            // once, which still leaves the opportunity for interleaved output
+            // to be miscolored. We assume this is rare enough that we don't
+            // have to worry about it.
+            if msg.ends_with("\n") {
+                try!(t.write_str(msg.slice_to(msg.len()-1)));
+                try!(t.reset());
+                try!(t.write_str("\n"));
+            } else {
+                try!(t.write_str(msg));
+                try!(t.reset());
+            }
             Ok(())
         }
         Raw(ref mut w) => {