about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-07-30 15:50:16 -0700
committerBrian Anderson <banderson@mozilla.com>2011-08-02 10:39:09 -0700
commit5f4b7e1ba7121955ce4805cd55a51bc856d1f5b2 (patch)
tree5d790b7fe89820389d627f072743d2b1bd24e6b9
parent2d5b651f4981b85d0e3864d8df6bd0953578e1f4 (diff)
downloadrust-5f4b7e1ba7121955ce4805cd55a51bc856d1f5b2.tar.gz
rust-5f4b7e1ba7121955ce4805cd55a51bc856d1f5b2.zip
Compiler accepts input from stdin when source file is called "-"
-rw-r--r--src/comp/driver/rustc.rs42
-rw-r--r--src/comp/syntax/codemap.rs11
-rw-r--r--src/comp/syntax/parse/eval.rs3
-rw-r--r--src/comp/syntax/parse/parser.rs27
4 files changed, 66 insertions, 17 deletions
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