diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index d58968c6546..5572d40d37f 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -86,15 +86,24 @@ fn parse_cfgspecs(cfgspecs: &vec[str]) -> ast::crate_cfg { ret words; } +fn input_is_stdin(filename: str) -> bool { filename == "-" } + fn parse_input(sess: session::session, cfg: &ast::crate_cfg, input: str) -> @ast::crate { - ret if str::ends_with(input, ".rc") { - parser::parse_crate_from_crate_file(input, cfg, - sess.get_parse_sess()) - } else if (str::ends_with(input, ".rs")) { - parser::parse_crate_from_source_file(input, cfg, - sess.get_parse_sess()) - } else { sess.fatal("unknown input file type: " + input) }; + if !input_is_stdin(input) { + parser::parse_crate_from_file(input, cfg, sess.get_parse_sess()) + } else { + parse_input_src(sess, cfg, input).crate + } +} + +fn parse_input_src(sess: session::session, cfg: &ast::crate_cfg, + infile: str) -> {crate: @ast::crate, src: str} { + let srcbytes = ioivec::stdin().read_whole_stream(); + let src = str::unsafe_from_bytes_ivec(srcbytes); + let crate = parser::parse_crate_from_source_str(infile, src, cfg, + sess.get_codemap()); + ret {crate: crate, src: src}; } fn time[T](do_it: bool, what: str, thunk: fn() -> T ) -> T { @@ -195,7 +204,14 @@ fn pretty_print_input(sess: session::session, cfg: ast::crate_cfg, input: str, } } - let crate = parse_input(sess, cfg, input); + // Because the pretty printer needs to make a pass over the source + // to collect comments and literals, and we need to support reading + // from stdin, we're going to just suck the source into a string + // so both the parser and pretty-printer can use it. + let crate_src = parse_input_src(sess, cfg, input); + let crate = crate_src.crate; + let src = crate_src.src; + if expand { crate = syntax::ext::expand::expand_crate(sess, crate); } let ann; alt ppm { @@ -213,7 +229,7 @@ fn pretty_print_input(sess: session::session, cfg: ast::crate_cfg, input: str, ppm_normal. { ann = pprust::no_ann(); } } pprust::print_crate(sess.get_codemap(), crate, input, - ioivec::file_reader(input), ioivec::stdout(), ann); + ioivec::string_reader(src), ioivec::stdout(), ann); } fn version(argv0: str) { @@ -484,7 +500,13 @@ fn main(args: vec[str]) { alt output_file { none. { - let parts: vec[str] = str::split(ifile, '.' as u8); + // "-" as input file will cause the parser to read from stdin so we + // have to make up a name + let parts: vec[str] = if !input_is_stdin(ifile) { + str::split(ifile, '.' as u8) + } else { + ["default", "rs"] + }; vec::pop[str](parts); saved_out_filename = parts.(0); alt sopts.output_type { diff --git a/src/comp/syntax/codemap.rs b/src/comp/syntax/codemap.rs index 3904bd8cb25..b94be023d9d 100644 --- a/src/comp/syntax/codemap.rs +++ b/src/comp/syntax/codemap.rs @@ -93,8 +93,19 @@ fn emit_diagnostic(sp: &option::t[span], msg: &str, kind: &str, color: u8, termivec::reset(ioivec::stdout().get_buf_writer()); } ioivec::stdout().write_str(#fmt(" %s\n", msg)); + + maybe_highlight_lines(sp, cm, maybe_lines); +} + +fn maybe_highlight_lines(sp: &option::t[span], cm: &codemap, + maybe_lines: option::t[@file_lines]) { + alt maybe_lines { some(lines) { + // If we're not looking at a real file then we can't re-open it to + // pull out the lines + if lines.name == "-" { ret; } + // FIXME: reading in the entire file is the worst possible way to // get access to the necessary lines. let rdr = ioivec::file_reader(lines.name); diff --git a/src/comp/syntax/parse/eval.rs b/src/comp/syntax/parse/eval.rs index 08a60404172..c5bf0f2586b 100644 --- a/src/comp/syntax/parse/eval.rs +++ b/src/comp/syntax/parse/eval.rs @@ -9,6 +9,7 @@ import syntax::parse::parser::parser; import syntax::parse::parser::new_parser_from_file; import syntax::parse::parser::parse_inner_attrs_and_next; import syntax::parse::parser::parse_mod_items; +import syntax::parse::parser::SOURCE_FILE; export eval_crate_directives_to_mod; export mode_parse; @@ -55,7 +56,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, if cx.mode == mode_depend { cx.deps += ~[full_path]; ret; } let p0 = new_parser_from_file(cx.sess, cx.cfg, full_path, cx.chpos, - cx.byte_pos); + cx.byte_pos, SOURCE_FILE); let inner_attrs = parse_inner_attrs_and_next(p0); let mod_attrs = attrs + inner_attrs.inner; let first_item_outer_attrs = inner_attrs.next; diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 9c929390bd2..58146b950ea 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -58,10 +58,10 @@ type parser = fn get_sess() -> parse_sess ; }; -fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str, - chpos: uint, byte_pos: uint) -> parser { - let ftype = SOURCE_FILE; - if str::ends_with(path, ".rc") { ftype = CRATE_FILE; } +fn new_parser_from_file(sess: parse_sess, cfg: + ast::crate_cfg, path: str, + chpos: uint, byte_pos: uint, + ftype: file_type) -> parser { let srdr = ioivec::file_reader(path); let src = str::unsafe_from_bytes_ivec(srdr.read_whole_stream()); let filemap = codemap::new_filemap(path, chpos, byte_pos); @@ -2313,7 +2313,7 @@ fn parse_native_view(p: &parser) -> (@ast::view_item)[] { fn parse_crate_from_source_file(input: &str, cfg: &ast::crate_cfg, sess: &parse_sess) -> @ast::crate { - let p = new_parser_from_file(sess, cfg, input, 0u, 0u); + let p = new_parser_from_file(sess, cfg, input, 0u, 0u, SOURCE_FILE); ret parse_crate_mod(p, cfg, sess); } @@ -2430,7 +2430,7 @@ fn parse_crate_directives(p: &parser, term: token::token, fn parse_crate_from_crate_file(input: &str, cfg: &ast::crate_cfg, sess: &parse_sess) -> @ast::crate { - let p = new_parser_from_file(sess, cfg, input, 0u, 0u); + let p = new_parser_from_file(sess, cfg, input, 0u, 0u, CRATE_FILE); let lo = p.get_lo_pos(); let prefix = std::fs::dirname(p.get_filemap().name); let leading_attrs = parse_inner_attrs_and_next(p); @@ -2455,6 +2455,21 @@ fn parse_crate_from_crate_file(input: &str, cfg: &ast::crate_cfg, attrs: crate_attrs, config: p.get_cfg()}); } + +fn parse_crate_from_file(input: &str, cfg: &ast::crate_cfg, + sess: &parse_sess) -> @ast::crate { + if str::ends_with(input, ".rc") { + parse_crate_from_crate_file(input, cfg, sess) + } else if str::ends_with(input, ".rs") { + parse_crate_from_source_file(input, cfg, sess) + } else { + codemap::emit_error(none, + "unknown input file type: " + input, + sess.cm); + fail + } +} + // // Local Variables: // mode: rust