From b7676f2df5e1ff97e0baa3f7e70936d4bd4dacb5 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Thu, 8 May 2014 13:10:03 +0000 Subject: [PATCH] Add compiler flag to configure output coloring This adds the flag --color, which allows the user to force coloring or turn it off. The default behavior stays the same as before (colorize, if output goes to tty). Why this is beneficial is explained in issue #12881. Please note that this commit doesn't include any regression tests. I thought about how I'd write a test for this and it doesn't seem to be worth the effort to me for a UI change like this. Fixes #12881. --- src/librustc/driver/config.rs | 22 +++++++++++++++++++++- src/librustc/driver/mod.rs | 4 ++-- src/librustc/driver/session.rs | 2 +- src/librustdoc/core.rs | 2 +- src/librustdoc/test.rs | 2 +- src/libsyntax/diagnostic.rs | 22 ++++++++++++++++++---- src/libsyntax/parse/mod.rs | 4 ++-- 7 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index b60468e85bb..e929c64e58a 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -27,6 +27,7 @@ use syntax::ast; use syntax::ast::{IntTy, UintTy}; use syntax::attr; use syntax::attr::AttrMetaMethods; +use syntax::diagnostic::{ColorConfig, Auto, Always, Never}; use syntax::parse; use syntax::parse::token::InternedString; @@ -92,6 +93,7 @@ pub struct Options { /// Crate id-related things to maybe print. It's (crate_id, crate_name, crate_file_name). pub print_metas: (bool, bool, bool), pub cg: CodegenOptions, + pub color: ColorConfig, } /// Some reasonable defaults @@ -115,6 +117,7 @@ pub fn basic_options() -> Options { write_dependency_info: (false, None), print_metas: (false, false, false), cg: basic_codegen_options(), + color: Auto, } } @@ -536,7 +539,11 @@ pub fn optgroups() -> Vec { optmulti("F", "forbid", "Set lint forbidden", "OPT"), optmulti("C", "codegen", "Set a codegen option", "OPT[=VALUE]"), optmulti("Z", "", "Set internal debugging options", "FLAG"), - optflag( "v", "version", "Print version info and exit") + optflag("v", "version", "Print version info and exit"), + optopt("", "color", "Configure coloring of output: + auto = colorize, if output goes to a tty (default); + always = always colorize output; + never = never colorize output", "auto|always|never") ) } @@ -707,6 +714,18 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { matches.opt_present("crate-file-name")); let cg = build_codegen_options(matches); + let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) { + Some("auto") => Auto, + Some("always") => Always, + Some("never") => Never, + + None => Auto, + + Some(arg) => early_error(format!( + "argument for --color must be auto, always or never (instead was `{}`)", + arg)) + }; + Options { crate_types: crate_types, gc: gc, @@ -726,6 +745,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { write_dependency_info: write_dependency_info, print_metas: print_metas, cg: cg, + color: color } } diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs index b9207544423..b355d474bd5 100644 --- a/src/librustc/driver/mod.rs +++ b/src/librustc/driver/mod.rs @@ -323,7 +323,7 @@ fn parse_crate_attrs(sess: &Session, input: &Input) -> } pub fn early_error(msg: &str) -> ! { - let mut emitter = diagnostic::EmitterWriter::stderr(); + let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto); emitter.emit(None, msg, diagnostic::Fatal); fail!(diagnostic::FatalError); } @@ -368,7 +368,7 @@ fn monitor(f: proc():Send) { Err(value) => { // Task failed without emitting a fatal diagnostic if !value.is::() { - let mut emitter = diagnostic::EmitterWriter::stderr(); + let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto); // a .span_bug or .bug call has already printed what // it wants to print. diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index b5176d3f4a8..e450fd200a6 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -196,7 +196,7 @@ pub fn build_session(sopts: config::Options, -> Session { let codemap = codemap::CodeMap::new(); let diagnostic_handler = - diagnostic::default_handler(); + diagnostic::default_handler(sopts.color); let span_diagnostic_handler = diagnostic::mk_span_handler(diagnostic_handler, codemap); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2f6f16a4ed4..791ee96d672 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -78,7 +78,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet, cfgs: Vec) let codemap = syntax::codemap::CodeMap::new(); - let diagnostic_handler = syntax::diagnostic::default_handler(); + let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto); let span_diagnostic_handler = syntax::diagnostic::mk_span_handler(diagnostic_handler, codemap); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9e63848b90e..88887ee2afd 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -53,7 +53,7 @@ pub fn run(input: &str, let codemap = CodeMap::new(); - let diagnostic_handler = diagnostic::default_handler(); + let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto); let span_diagnostic_handler = diagnostic::mk_span_handler(diagnostic_handler, codemap); diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 73027013090..94132988d97 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -49,6 +49,13 @@ impl RenderSpan { } } +#[deriving(Clone)] +pub enum ColorConfig { + Auto, + Always, + Never +} + pub trait Emitter { fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>, msg: &str, lvl: Level); @@ -176,8 +183,8 @@ pub fn mk_span_handler(handler: Handler, cm: codemap::CodeMap) -> SpanHandler { } } -pub fn default_handler() -> Handler { - mk_handler(box EmitterWriter::stderr()) +pub fn default_handler(color_config: ColorConfig) -> Handler { + mk_handler(box EmitterWriter::stderr(color_config)) } pub fn mk_handler(e: Box) -> Handler { @@ -257,9 +264,16 @@ enum Destination { } impl EmitterWriter { - pub fn stderr() -> EmitterWriter { + pub fn stderr(color_config: ColorConfig) -> EmitterWriter { let stderr = io::stderr(); - if stderr.get_ref().isatty() { + + let use_color = match color_config { + Always => true, + Never => false, + Auto => stderr.get_ref().isatty() + }; + + if use_color { let dst = match term::Terminal::new(stderr.unwrap()) { Ok(t) => Terminal(t), Err(..) => Raw(box io::stderr()), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 28f235a3da0..d8a9f69e293 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -13,7 +13,7 @@ use ast; use codemap::{Span, CodeMap, FileMap}; -use diagnostic::{SpanHandler, mk_span_handler, default_handler}; +use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto}; use parse::attr::ParserAttr; use parse::parser::Parser; @@ -41,7 +41,7 @@ pub struct ParseSess { pub fn new_parse_sess() -> ParseSess { ParseSess { - span_diagnostic: mk_span_handler(default_handler(), CodeMap::new()), + span_diagnostic: mk_span_handler(default_handler(Auto), CodeMap::new()), included_mod_stack: RefCell::new(Vec::new()), } }