about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-05-09 19:41:24 -0700
committerBrian Anderson <banderson@mozilla.com>2012-05-09 23:40:50 -0700
commitfa6c18e0149c9e31a69c9084c416ea5c7cd363dd (patch)
treeb17a81cb0c831776d0453425ca8ab47a84bb0649
parent50a3dd40ae8ae6494e55d5cfc29eafdb4172af52 (diff)
downloadrust-fa6c18e0149c9e31a69c9084c416ea5c7cd363dd.tar.gz
rust-fa6c18e0149c9e31a69c9084c416ea5c7cd363dd.zip
rustc: Refactor driver to better understand string sources
-rw-r--r--src/rustc/driver/driver.rs73
-rw-r--r--src/rustc/driver/rustc.rs28
-rw-r--r--src/rustdoc/parse.rs10
3 files changed, 79 insertions, 32 deletions
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs
index a1a082da994..6fb525a1346 100644
--- a/src/rustc/driver/driver.rs
+++ b/src/rustc/driver/driver.rs
@@ -18,7 +18,20 @@ import back::{x86, x86_64};
 enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified,
               ppm_expanded_identified }
 
-fn default_configuration(sess: session, argv0: str, input: str) ->
+#[doc = "
+The name used for source code that doesn't originate in a file
+(e.g. source from stdin or a string)
+"]
+fn anon_src() -> str { "<anon>" }
+
+fn source_name(input: input) -> str {
+    alt input {
+      file_input(ifile) { ifile }
+      str_input(_) { anon_src() }
+    }
+}
+
+fn default_configuration(sess: session, argv0: str, input: input) ->
    ast::crate_cfg {
     let libc = alt sess.targ_cfg.os {
       session::os_win32 { "msvcrt.dll" }
@@ -42,10 +55,10 @@ fn default_configuration(sess: session, argv0: str, input: str) ->
          mk("target_libc", libc),
          // Build bindings.
          mk("build_compiler", argv0),
-         mk("build_input", input)];
+         mk("build_input", source_name(input))];
 }
 
-fn build_configuration(sess: session, argv0: str, input: str) ->
+fn build_configuration(sess: session, argv0: str, input: input) ->
    ast::crate_cfg {
     // Combine the configuration requested by the session (command line) with
     // some default and generated configuration items
@@ -71,15 +84,24 @@ fn parse_cfgspecs(cfgspecs: [str]) -> ast::crate_cfg {
     ret words;
 }
 
-fn input_is_stdin(filename: str) -> bool { filename == "-" }
+enum input {
+    #[doc = "Load source from file"]
+    file_input(str),
+    #[doc = "The string is the source"]
+    str_input(str)
+}
 
-fn parse_input(sess: session, cfg: ast::crate_cfg, input: str)
+fn parse_input(sess: session, cfg: ast::crate_cfg, input: input)
     -> @ast::crate {
-    if !input_is_stdin(input) {
-        parse::parse_crate_from_file(input, cfg, sess.parse_sess)
-    } else {
-        let src = @str::from_bytes(io::stdin().read_whole_stream());
-        parse::parse_crate_from_source_str(input, src, cfg, sess.parse_sess)
+    alt input {
+      file_input(file) {
+        parse::parse_crate_from_file(file, cfg, sess.parse_sess)
+      }
+      str_input(src) {
+        // FIXME: Don't really want to box the source string
+        parse::parse_crate_from_source_str(
+            anon_src(), @src, cfg, sess.parse_sess)
+      }
     }
 }
 
@@ -102,7 +124,7 @@ enum compile_upto {
 }
 
 fn compile_upto(sess: session, cfg: ast::crate_cfg,
-                input: str, upto: compile_upto,
+                input: input, upto: compile_upto,
                 outputs: option<output_filenames>)
     -> {crate: @ast::crate, tcx: option<ty::ctxt>} {
     let time_passes = sess.opts.time_passes;
@@ -208,7 +230,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
     ret {crate: crate, tcx: some(ty_cx)};
 }
 
-fn compile_input(sess: session, cfg: ast::crate_cfg, input: str,
+fn compile_input(sess: session, cfg: ast::crate_cfg, input: input,
                  outdir: option<str>, output: option<str>) {
 
     let upto = if sess.opts.parse_only { cu_parse }
@@ -218,7 +240,7 @@ fn compile_input(sess: session, cfg: ast::crate_cfg, input: str,
     compile_upto(sess, cfg, input, upto, some(outputs));
 }
 
-fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str,
+fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: input,
                       ppm: pp_mode) {
     fn ann_paren_for_expr(node: pprust::ann_node) {
         alt node { pprust::node_expr(s, expr) { pprust::popen(s); } _ { } }
@@ -277,9 +299,10 @@ fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str,
       }
       ppm_expanded | ppm_normal {}
     }
-    let src = codemap::get_filemap(sess.codemap, input).src;
+    let src = codemap::get_filemap(sess.codemap, source_name(input)).src;
     io::with_str_reader(*src) { |rdr|
-        pprust::print_crate(sess.codemap, sess.span_diagnostic, crate, input,
+        pprust::print_crate(sess.codemap, sess.span_diagnostic, crate,
+                            source_name(input),
                             rdr, io::stdout(), ann);
     }
 }
@@ -549,7 +572,7 @@ fn opts() -> [getopts::opt] {
 
 type output_filenames = @{out_filename: str, obj_filename:str};
 
-fn build_output_filenames(ifile: str,
+fn build_output_filenames(input: input,
                           odir: option<str>,
                           ofile: option<str>,
                           sess: session)
@@ -582,19 +605,25 @@ fn build_output_filenames(ifile: str,
         let dirname = alt odir {
           some(d) { d }
           none {
-            if input_is_stdin(ifile) {
+            alt input {
+              str_input(_) {
                 os::getcwd()
-            } else {
+              }
+              file_input(ifile) {
                 path::dirname(ifile)
+              }
             }
           }
         };
 
-        let base_filename = if !input_is_stdin(ifile) {
+        let base_filename = alt input {
+          file_input(ifile) {
             let (path, _) = path::splitext(ifile);
             path::basename(path)
-        } else {
+          }
+          str_input(_) {
             "rust_out"
+          }
         };
         let base_path = path::connect(dirname, base_filename);
 
@@ -659,7 +688,7 @@ mod test {
             };
         let sessopts = build_session_options(match, diagnostic::emit);
         let sess = build_session(sessopts, diagnostic::emit);
-        let cfg = build_configuration(sess, "whatever", "whatever");
+        let cfg = build_configuration(sess, "whatever", str_input(""));
         assert (attr::contains_name(cfg, "test"));
     }
 
@@ -675,7 +704,7 @@ mod test {
             };
         let sessopts = build_session_options(match, diagnostic::emit);
         let sess = build_session(sessopts, diagnostic::emit);
-        let cfg = build_configuration(sess, "whatever", "whatever");
+        let cfg = build_configuration(sess, "whatever", str_input(""));
         let test_items = attr::find_meta_items_by_name(cfg, "test");
         assert (vec::len(test_items) == 1u);
     }
diff --git a/src/rustc/driver/rustc.rs b/src/rustc/driver/rustc.rs
index de194211277..71474865827 100644
--- a/src/rustc/driver/rustc.rs
+++ b/src/rustc/driver/rustc.rs
@@ -15,6 +15,7 @@ import rustc::driver::driver::*;
 import rustc::syntax::codemap;
 import rustc::driver::diagnostic;
 import rustc::middle::lint;
+import io::reader_util;
 
 fn version(argv0: str) {
     let mut vers = "unknown version";
@@ -138,9 +139,17 @@ fn run_compiler(args: [str], demitter: diagnostic::emitter) {
         version(binary);
         ret;
     }
-    let ifile = alt vec::len(match.free) {
+    let input = alt vec::len(match.free) {
       0u { early_error(demitter, "no input filename given") }
-      1u { match.free[0] }
+      1u {
+        let ifile = match.free[0];
+        if ifile == "-" {
+            let src = str::from_bytes(io::stdin().read_whole_stream());
+            str_input(src)
+        } else {
+            file_input(ifile)
+        }
+      }
       _ { early_error(demitter, "multiple input filenames provided") }
     };
 
@@ -148,22 +157,29 @@ fn run_compiler(args: [str], demitter: diagnostic::emitter) {
     let sess = build_session(sopts, demitter);
     let odir = getopts::opt_maybe_str(match, "out-dir");
     let ofile = getopts::opt_maybe_str(match, "o");
-    let cfg = build_configuration(sess, binary, ifile);
+    let cfg = build_configuration(sess, binary, input);
     let pretty =
         option::map(getopts::opt_default(match, "pretty",
                                          "normal"),
                     bind parse_pretty(sess, _));
     alt pretty {
-      some::<pp_mode>(ppm) { pretty_print_input(sess, cfg, ifile, ppm); ret; }
+      some::<pp_mode>(ppm) { pretty_print_input(sess, cfg, input, ppm); ret; }
       none::<pp_mode> {/* continue */ }
     }
     let ls = opt_present(match, "ls");
     if ls {
-        list_metadata(sess, ifile, io::stdout());
+        alt input {
+          file_input(ifile) {
+            list_metadata(sess, ifile, io::stdout());
+          }
+          str_input(_) {
+            early_error(demitter, "can not list metadata for stdin");
+          }
+        }
         ret;
     }
 
-    compile_input(sess, cfg, ifile, odir, ofile);
+    compile_input(sess, cfg, input, odir, ofile);
 }
 
 /*
diff --git a/src/rustdoc/parse.rs b/src/rustdoc/parse.rs
index 3ad8f51e8db..788d9b9e4fb 100644
--- a/src/rustdoc/parse.rs
+++ b/src/rustdoc/parse.rs
@@ -1,6 +1,7 @@
 #[doc = "AST-parsing helpers"];
 
 import rustc::driver::driver;
+import driver::{file_input, str_input};
 import rustc::driver::session;
 import rustc::driver::diagnostic;
 import rustc::syntax::ast;
@@ -33,14 +34,15 @@ fn from_str(source: str) -> @ast::crate {
 }
 
 fn from_file_sess(sess: session::session, file: str) -> @ast::crate {
-    parse::parse_crate_from_file(file, cfg(sess), sess.parse_sess)
+    parse::parse_crate_from_file(
+        file, cfg(sess, file_input(file)), sess.parse_sess)
 }
 
 fn from_str_sess(sess: session::session, source: str) -> @ast::crate {
     parse::parse_crate_from_source_str(
-        "-", @source, cfg(sess), sess.parse_sess)
+        "-", @source, cfg(sess, str_input(source)), sess.parse_sess)
 }
 
-fn cfg(sess: session::session) -> ast::crate_cfg {
-    driver::default_configuration(sess, "rustdoc", "<anon>")
+fn cfg(sess: session::session, input: driver::input) -> ast::crate_cfg {
+    driver::default_configuration(sess, "rustdoc", input)
 }