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 @@ 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 { "" } + +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) -> {crate: @ast::crate, tcx: option} { 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, output: option) { 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 ann_identified_post(node: pprust::ann_node) { } 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, ofile: option, 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 @@ fn test_switch_implies_cfg_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 @@ fn test_switch_implies_cfg_test_unless_cfg_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::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::(ppm) { pretty_print_input(sess, cfg, ifile, ppm); ret; } + some::(ppm) { pretty_print_input(sess, cfg, input, ppm); ret; } none:: {/* 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", "") +fn cfg(sess: session::session, input: driver::input) -> ast::crate_cfg { + driver::default_configuration(sess, "rustdoc", input) }