提交 b7676f2d 编写于 作者: H Hanno Braun

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.
上级 579e0a5f
......@@ -27,6 +27,7 @@
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<getopts::OptGroup> {
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
}
}
......
......@@ -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::<diagnostic::FatalError>() {
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.
......
......@@ -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);
......
......@@ -78,7 +78,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<StrBuf>)
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);
......
......@@ -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);
......
......@@ -49,6 +49,13 @@ fn is_full_span(&self) -> bool {
}
}
#[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<Emitter:Send>) -> 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()),
......
......@@ -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()),
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册