]> git.lizzy.rs Git - rust.git/commitdiff
Rename all files with the 'rc' extension
authorAlex Crichton <alex@alexcrichton.com>
Mon, 10 Jun 2013 20:00:38 +0000 (13:00 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 25 Jun 2013 15:55:15 +0000 (08:55 -0700)
20 files changed:
Makefile.in
mk/tools.mk
src/compiletest/compiletest.rc [deleted file]
src/compiletest/compiletest.rs [new file with mode: 0644]
src/libextra/extra.rs [new file with mode: 0644]
src/libextra/std.rc [deleted file]
src/librust/rust.rc [deleted file]
src/librust/rust.rs [new file with mode: 0644]
src/librustc/rustc.rc [deleted file]
src/librustc/rustc.rs [new file with mode: 0644]
src/librustdoc/rustdoc.rc [deleted file]
src/librustdoc/rustdoc.rs [new file with mode: 0644]
src/librusti/rusti.rc [deleted file]
src/librusti/rusti.rs [new file with mode: 0644]
src/librustpkg/rustpkg.rc [deleted file]
src/librustpkg/rustpkg.rs [new file with mode: 0644]
src/libstd/core.rc [deleted file]
src/libstd/std.rs [new file with mode: 0644]
src/libsyntax/syntax.rc [deleted file]
src/libsyntax/syntax.rs [new file with mode: 0644]

index baae56c4f4093a816827438ad033eb8fb1ab2384..fa6c7806581352fa216bb1d92fae6e5988a78af4 100644 (file)
@@ -239,29 +239,29 @@ $(foreach target,$(CFG_TARGET_TRIPLES),\
 # Standard library variables
 ######################################################################
 
-STDLIB_CRATE := $(S)src/libstd/core.rc
+STDLIB_CRATE := $(S)src/libstd/std.rs
 STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/,        \
-                                           core.rc *.rs */*.rs */*/*rs */*/*/*rs))
+                                           *.rs */*.rs */*/*rs */*/*/*rs))
 
 ######################################################################
 # Extra library variables
 ######################################################################
 
-EXTRALIB_CRATE := $(S)src/libextra/std.rc
+EXTRALIB_CRATE := $(S)src/libextra/extra.rs
 EXTRALIB_INPUTS := $(wildcard $(addprefix $(S)src/libextra/,          \
-                                          std.rc *.rs */*.rs))
+                                          *.rs */*.rs))
 
 ######################################################################
 # rustc crate variables
 ######################################################################
 
-COMPILER_CRATE := $(S)src/librustc/rustc.rc
+COMPILER_CRATE := $(S)src/librustc/rustc.rs
 COMPILER_INPUTS := $(wildcard $(addprefix $(S)src/librustc/,      \
-                           rustc.rc *.rs */*.rs */*/*.rs */*/*/*.rs))
+                           *.rs */*.rs */*/*.rs */*/*/*.rs))
 
-LIBSYNTAX_CRATE := $(S)src/libsyntax/syntax.rc
+LIBSYNTAX_CRATE := $(S)src/libsyntax/syntax.rs
 LIBSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/libsyntax/, \
-                            syntax.rc *.rs */*.rs */*/*.rs))
+                           *.rs */*.rs */*/*.rs))
 
 DRIVER_CRATE := $(S)src/driver/driver.rs
 
index 8319d8d4e4835fee4c1879d6038358b3aedbe4a0..7b50441b3c7f2f4a483649f651f031c5aae2c5be 100644 (file)
 # and host architectures
 
 # The test runner that runs the cfail/rfail/rpass and bxench tests
-COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rc
-COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*rs)
+COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rs
+COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*.rs)
 
 # Rustpkg, the package manager and build system
-RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rc
-RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*rs)
+RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rs
+RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*.rs)
 
 # Rustdoc, the documentation tool
-RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rc
+RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rs
 RUSTDOC_INPUTS := $(wildcard $(S)src/librustdoc/*.rs)
 
 # Rusti, the JIT REPL
-RUSTI_LIB := $(S)src/librusti/rusti.rc
+RUSTI_LIB := $(S)src/librusti/rusti.rs
 RUSTI_INPUTS := $(wildcard $(S)src/librusti/*.rs)
 
 # Rust, the convenience tool
-RUST_LIB := $(S)src/librust/rust.rc
+RUST_LIB := $(S)src/librust/rust.rs
 RUST_INPUTS := $(wildcard $(S)src/librust/*.rs)
 
 # FIXME: These are only built for the host arch. Eventually we'll
diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc
deleted file mode 100644 (file)
index e8876c4..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[crate_type = "bin"];
-
-#[allow(non_camel_case_types)];
-
-#[no_core]; // XXX: Remove after snapshot
-#[no_std];
-
-extern mod core(name = "std", vers = "0.7-pre");
-extern mod extra(name = "extra", vers = "0.7-pre");
-
-use core::prelude::*;
-use core::*;
-
-use extra::getopts;
-use extra::test;
-
-use core::result::{Ok, Err};
-
-use common::config;
-use common::mode_run_pass;
-use common::mode_run_fail;
-use common::mode_compile_fail;
-use common::mode_pretty;
-use common::mode_debug_info;
-use common::mode;
-use util::logv;
-
-pub mod procsrv;
-pub mod util;
-pub mod header;
-pub mod runtest;
-pub mod common;
-pub mod errors;
-
-mod std {
-    pub use core::cmp;
-    pub use core::str;
-    pub use core::sys;
-    pub use core::unstable;
-}
-
-pub fn main() {
-    let args = os::args();
-    let config = parse_config(args);
-    log_config(&config);
-    run_tests(&config);
-}
-
-pub fn parse_config(args: ~[~str]) -> config {
-    let opts =
-        ~[getopts::reqopt("compile-lib-path"),
-          getopts::reqopt("run-lib-path"),
-          getopts::reqopt("rustc-path"), getopts::reqopt("src-base"),
-          getopts::reqopt("build-base"), getopts::reqopt("aux-base"),
-          getopts::reqopt("stage-id"),
-          getopts::reqopt("mode"), getopts::optflag("ignored"),
-          getopts::optopt("runtool"), getopts::optopt("rustcflags"),
-          getopts::optflag("verbose"),
-          getopts::optopt("logfile"),
-          getopts::optflag("jit"),
-          getopts::optflag("newrt"),
-          getopts::optopt("target"),
-          getopts::optopt("adb-path"),
-          getopts::optopt("adb-test-dir")
-         ];
-
-    assert!(!args.is_empty());
-    let args_ = vec::tail(args);
-    let matches =
-        &match getopts::getopts(args_, opts) {
-          Ok(m) => m,
-          Err(f) => fail!(getopts::fail_str(f))
-        };
-
-    fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
-        Path(getopts::opt_str(m, nm))
-    }
-
-    config {
-        compile_lib_path: getopts::opt_str(matches, "compile-lib-path"),
-        run_lib_path: getopts::opt_str(matches, "run-lib-path"),
-        rustc_path: opt_path(matches, "rustc-path"),
-        src_base: opt_path(matches, "src-base"),
-        build_base: opt_path(matches, "build-base"),
-        aux_base: opt_path(matches, "aux-base"),
-        stage_id: getopts::opt_str(matches, "stage-id"),
-        mode: str_mode(getopts::opt_str(matches, "mode")),
-        run_ignored: getopts::opt_present(matches, "ignored"),
-        filter:
-             if !matches.free.is_empty() {
-                 option::Some(copy matches.free[0])
-             } else { option::None },
-        logfile: getopts::opt_maybe_str(matches, "logfile").map(|s| Path(*s)),
-        runtool: getopts::opt_maybe_str(matches, "runtool"),
-        rustcflags: getopts::opt_maybe_str(matches, "rustcflags"),
-        jit: getopts::opt_present(matches, "jit"),
-        newrt: getopts::opt_present(matches, "newrt"),
-        target: opt_str2(getopts::opt_maybe_str(matches, "target")).to_str(),
-        adb_path: opt_str2(getopts::opt_maybe_str(matches, "adb-path")).to_str(),
-        adb_test_dir:
-            opt_str2(getopts::opt_maybe_str(matches, "adb-test-dir")).to_str(),
-        adb_device_status:
-            if (opt_str2(getopts::opt_maybe_str(matches, "target")) ==
-                ~"arm-linux-androideabi") {
-                if (opt_str2(getopts::opt_maybe_str(matches, "adb-test-dir")) !=
-                    ~"(none)" &&
-                    opt_str2(getopts::opt_maybe_str(matches, "adb-test-dir")) !=
-                    ~"") { true }
-                else { false }
-            } else { false },
-        verbose: getopts::opt_present(matches, "verbose")
-    }
-}
-
-pub fn log_config(config: &config) {
-    let c = config;
-    logv(c, fmt!("configuration:"));
-    logv(c, fmt!("compile_lib_path: %s", config.compile_lib_path));
-    logv(c, fmt!("run_lib_path: %s", config.run_lib_path));
-    logv(c, fmt!("rustc_path: %s", config.rustc_path.to_str()));
-    logv(c, fmt!("src_base: %s", config.src_base.to_str()));
-    logv(c, fmt!("build_base: %s", config.build_base.to_str()));
-    logv(c, fmt!("stage_id: %s", config.stage_id));
-    logv(c, fmt!("mode: %s", mode_str(config.mode)));
-    logv(c, fmt!("run_ignored: %b", config.run_ignored));
-    logv(c, fmt!("filter: %s", opt_str(&config.filter)));
-    logv(c, fmt!("runtool: %s", opt_str(&config.runtool)));
-    logv(c, fmt!("rustcflags: %s", opt_str(&config.rustcflags)));
-    logv(c, fmt!("jit: %b", config.jit));
-    logv(c, fmt!("newrt: %b", config.newrt));
-    logv(c, fmt!("target: %s", config.target));
-    logv(c, fmt!("adb_path: %s", config.adb_path));
-    logv(c, fmt!("adb_test_dir: %s", config.adb_test_dir));
-    logv(c, fmt!("adb_device_status: %b", config.adb_device_status));
-    logv(c, fmt!("verbose: %b", config.verbose));
-    logv(c, fmt!("\n"));
-}
-
-pub fn opt_str<'a>(maybestr: &'a Option<~str>) -> &'a str {
-    match *maybestr {
-        option::None => "(none)",
-        option::Some(ref s) => {
-            let s: &'a str = *s;
-            s
-        }
-    }
-}
-
-pub fn opt_str2(maybestr: Option<~str>) -> ~str {
-    match maybestr { None => ~"(none)", Some(s) => { s } }
-}
-
-pub fn str_opt(maybestr: ~str) -> Option<~str> {
-    if maybestr != ~"(none)" { option::Some(maybestr) } else { option::None }
-}
-
-pub fn str_mode(s: ~str) -> mode {
-    match s {
-      ~"compile-fail" => mode_compile_fail,
-      ~"run-fail" => mode_run_fail,
-      ~"run-pass" => mode_run_pass,
-      ~"pretty" => mode_pretty,
-      ~"debug-info" => mode_debug_info,
-      _ => fail!("invalid mode")
-    }
-}
-
-pub fn mode_str(mode: mode) -> ~str {
-    match mode {
-      mode_compile_fail => ~"compile-fail",
-      mode_run_fail => ~"run-fail",
-      mode_run_pass => ~"run-pass",
-      mode_pretty => ~"pretty",
-      mode_debug_info => ~"debug-info",
-    }
-}
-
-pub fn run_tests(config: &config) {
-    let opts = test_opts(config);
-    let tests = make_tests(config);
-    let res = test::run_tests_console(&opts, tests);
-    if !res { fail!("Some tests failed"); }
-}
-
-pub fn test_opts(config: &config) -> test::TestOpts {
-    test::TestOpts {
-        filter: copy config.filter,
-        run_ignored: config.run_ignored,
-        logfile: copy config.logfile,
-        run_tests: true,
-        run_benchmarks: false,
-        save_results: option::None,
-        compare_results: option::None
-    }
-}
-
-pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] {
-    debug!("making tests from %s",
-           config.src_base.to_str());
-    let mut tests = ~[];
-    let dirs = os::list_dir_path(&config.src_base);
-    for dirs.iter().advance |file| {
-        let file = copy *file;
-        debug!("inspecting file %s", file.to_str());
-        if is_test(config, file) {
-            tests.push(make_test(config, file))
-        }
-    }
-    tests
-}
-
-pub fn is_test(config: &config, testfile: &Path) -> bool {
-    // Pretty-printer does not work with .rc files yet
-    let valid_extensions =
-        match config.mode {
-          mode_pretty => ~[~".rs"],
-          _ => ~[~".rc", ~".rs"]
-        };
-    let invalid_prefixes = ~[~".", ~"#", ~"~"];
-    let name = testfile.filename().get();
-
-    let mut valid = false;
-
-    for valid_extensions.iter().advance |ext| {
-        if name.ends_with(*ext) { valid = true; }
-    }
-
-    for invalid_prefixes.iter().advance |pre| {
-        if name.starts_with(*pre) { valid = false; }
-    }
-
-    return valid;
-}
-
-pub fn make_test(config: &config, testfile: &Path) -> test::TestDescAndFn {
-    test::TestDescAndFn {
-        desc: test::TestDesc {
-            name: make_test_name(config, testfile),
-            ignore: header::is_test_ignored(config, testfile),
-            should_fail: false
-        },
-        testfn: make_test_closure(config, testfile),
-    }
-}
-
-pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName {
-    test::DynTestName(fmt!("[%s] %s",
-                           mode_str(config.mode),
-                           testfile.to_str()))
-}
-
-pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn {
-    use core::cell::Cell;
-    let config = Cell::new(copy *config);
-    let testfile = Cell::new(testfile.to_str());
-    test::DynTestFn(|| { runtest::run(config.take(), testfile.take()) })
-}
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
new file mode 100644 (file)
index 0000000..e8876c4
--- /dev/null
@@ -0,0 +1,267 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[crate_type = "bin"];
+
+#[allow(non_camel_case_types)];
+
+#[no_core]; // XXX: Remove after snapshot
+#[no_std];
+
+extern mod core(name = "std", vers = "0.7-pre");
+extern mod extra(name = "extra", vers = "0.7-pre");
+
+use core::prelude::*;
+use core::*;
+
+use extra::getopts;
+use extra::test;
+
+use core::result::{Ok, Err};
+
+use common::config;
+use common::mode_run_pass;
+use common::mode_run_fail;
+use common::mode_compile_fail;
+use common::mode_pretty;
+use common::mode_debug_info;
+use common::mode;
+use util::logv;
+
+pub mod procsrv;
+pub mod util;
+pub mod header;
+pub mod runtest;
+pub mod common;
+pub mod errors;
+
+mod std {
+    pub use core::cmp;
+    pub use core::str;
+    pub use core::sys;
+    pub use core::unstable;
+}
+
+pub fn main() {
+    let args = os::args();
+    let config = parse_config(args);
+    log_config(&config);
+    run_tests(&config);
+}
+
+pub fn parse_config(args: ~[~str]) -> config {
+    let opts =
+        ~[getopts::reqopt("compile-lib-path"),
+          getopts::reqopt("run-lib-path"),
+          getopts::reqopt("rustc-path"), getopts::reqopt("src-base"),
+          getopts::reqopt("build-base"), getopts::reqopt("aux-base"),
+          getopts::reqopt("stage-id"),
+          getopts::reqopt("mode"), getopts::optflag("ignored"),
+          getopts::optopt("runtool"), getopts::optopt("rustcflags"),
+          getopts::optflag("verbose"),
+          getopts::optopt("logfile"),
+          getopts::optflag("jit"),
+          getopts::optflag("newrt"),
+          getopts::optopt("target"),
+          getopts::optopt("adb-path"),
+          getopts::optopt("adb-test-dir")
+         ];
+
+    assert!(!args.is_empty());
+    let args_ = vec::tail(args);
+    let matches =
+        &match getopts::getopts(args_, opts) {
+          Ok(m) => m,
+          Err(f) => fail!(getopts::fail_str(f))
+        };
+
+    fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
+        Path(getopts::opt_str(m, nm))
+    }
+
+    config {
+        compile_lib_path: getopts::opt_str(matches, "compile-lib-path"),
+        run_lib_path: getopts::opt_str(matches, "run-lib-path"),
+        rustc_path: opt_path(matches, "rustc-path"),
+        src_base: opt_path(matches, "src-base"),
+        build_base: opt_path(matches, "build-base"),
+        aux_base: opt_path(matches, "aux-base"),
+        stage_id: getopts::opt_str(matches, "stage-id"),
+        mode: str_mode(getopts::opt_str(matches, "mode")),
+        run_ignored: getopts::opt_present(matches, "ignored"),
+        filter:
+             if !matches.free.is_empty() {
+                 option::Some(copy matches.free[0])
+             } else { option::None },
+        logfile: getopts::opt_maybe_str(matches, "logfile").map(|s| Path(*s)),
+        runtool: getopts::opt_maybe_str(matches, "runtool"),
+        rustcflags: getopts::opt_maybe_str(matches, "rustcflags"),
+        jit: getopts::opt_present(matches, "jit"),
+        newrt: getopts::opt_present(matches, "newrt"),
+        target: opt_str2(getopts::opt_maybe_str(matches, "target")).to_str(),
+        adb_path: opt_str2(getopts::opt_maybe_str(matches, "adb-path")).to_str(),
+        adb_test_dir:
+            opt_str2(getopts::opt_maybe_str(matches, "adb-test-dir")).to_str(),
+        adb_device_status:
+            if (opt_str2(getopts::opt_maybe_str(matches, "target")) ==
+                ~"arm-linux-androideabi") {
+                if (opt_str2(getopts::opt_maybe_str(matches, "adb-test-dir")) !=
+                    ~"(none)" &&
+                    opt_str2(getopts::opt_maybe_str(matches, "adb-test-dir")) !=
+                    ~"") { true }
+                else { false }
+            } else { false },
+        verbose: getopts::opt_present(matches, "verbose")
+    }
+}
+
+pub fn log_config(config: &config) {
+    let c = config;
+    logv(c, fmt!("configuration:"));
+    logv(c, fmt!("compile_lib_path: %s", config.compile_lib_path));
+    logv(c, fmt!("run_lib_path: %s", config.run_lib_path));
+    logv(c, fmt!("rustc_path: %s", config.rustc_path.to_str()));
+    logv(c, fmt!("src_base: %s", config.src_base.to_str()));
+    logv(c, fmt!("build_base: %s", config.build_base.to_str()));
+    logv(c, fmt!("stage_id: %s", config.stage_id));
+    logv(c, fmt!("mode: %s", mode_str(config.mode)));
+    logv(c, fmt!("run_ignored: %b", config.run_ignored));
+    logv(c, fmt!("filter: %s", opt_str(&config.filter)));
+    logv(c, fmt!("runtool: %s", opt_str(&config.runtool)));
+    logv(c, fmt!("rustcflags: %s", opt_str(&config.rustcflags)));
+    logv(c, fmt!("jit: %b", config.jit));
+    logv(c, fmt!("newrt: %b", config.newrt));
+    logv(c, fmt!("target: %s", config.target));
+    logv(c, fmt!("adb_path: %s", config.adb_path));
+    logv(c, fmt!("adb_test_dir: %s", config.adb_test_dir));
+    logv(c, fmt!("adb_device_status: %b", config.adb_device_status));
+    logv(c, fmt!("verbose: %b", config.verbose));
+    logv(c, fmt!("\n"));
+}
+
+pub fn opt_str<'a>(maybestr: &'a Option<~str>) -> &'a str {
+    match *maybestr {
+        option::None => "(none)",
+        option::Some(ref s) => {
+            let s: &'a str = *s;
+            s
+        }
+    }
+}
+
+pub fn opt_str2(maybestr: Option<~str>) -> ~str {
+    match maybestr { None => ~"(none)", Some(s) => { s } }
+}
+
+pub fn str_opt(maybestr: ~str) -> Option<~str> {
+    if maybestr != ~"(none)" { option::Some(maybestr) } else { option::None }
+}
+
+pub fn str_mode(s: ~str) -> mode {
+    match s {
+      ~"compile-fail" => mode_compile_fail,
+      ~"run-fail" => mode_run_fail,
+      ~"run-pass" => mode_run_pass,
+      ~"pretty" => mode_pretty,
+      ~"debug-info" => mode_debug_info,
+      _ => fail!("invalid mode")
+    }
+}
+
+pub fn mode_str(mode: mode) -> ~str {
+    match mode {
+      mode_compile_fail => ~"compile-fail",
+      mode_run_fail => ~"run-fail",
+      mode_run_pass => ~"run-pass",
+      mode_pretty => ~"pretty",
+      mode_debug_info => ~"debug-info",
+    }
+}
+
+pub fn run_tests(config: &config) {
+    let opts = test_opts(config);
+    let tests = make_tests(config);
+    let res = test::run_tests_console(&opts, tests);
+    if !res { fail!("Some tests failed"); }
+}
+
+pub fn test_opts(config: &config) -> test::TestOpts {
+    test::TestOpts {
+        filter: copy config.filter,
+        run_ignored: config.run_ignored,
+        logfile: copy config.logfile,
+        run_tests: true,
+        run_benchmarks: false,
+        save_results: option::None,
+        compare_results: option::None
+    }
+}
+
+pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] {
+    debug!("making tests from %s",
+           config.src_base.to_str());
+    let mut tests = ~[];
+    let dirs = os::list_dir_path(&config.src_base);
+    for dirs.iter().advance |file| {
+        let file = copy *file;
+        debug!("inspecting file %s", file.to_str());
+        if is_test(config, file) {
+            tests.push(make_test(config, file))
+        }
+    }
+    tests
+}
+
+pub fn is_test(config: &config, testfile: &Path) -> bool {
+    // Pretty-printer does not work with .rc files yet
+    let valid_extensions =
+        match config.mode {
+          mode_pretty => ~[~".rs"],
+          _ => ~[~".rc", ~".rs"]
+        };
+    let invalid_prefixes = ~[~".", ~"#", ~"~"];
+    let name = testfile.filename().get();
+
+    let mut valid = false;
+
+    for valid_extensions.iter().advance |ext| {
+        if name.ends_with(*ext) { valid = true; }
+    }
+
+    for invalid_prefixes.iter().advance |pre| {
+        if name.starts_with(*pre) { valid = false; }
+    }
+
+    return valid;
+}
+
+pub fn make_test(config: &config, testfile: &Path) -> test::TestDescAndFn {
+    test::TestDescAndFn {
+        desc: test::TestDesc {
+            name: make_test_name(config, testfile),
+            ignore: header::is_test_ignored(config, testfile),
+            should_fail: false
+        },
+        testfn: make_test_closure(config, testfile),
+    }
+}
+
+pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName {
+    test::DynTestName(fmt!("[%s] %s",
+                           mode_str(config.mode),
+                           testfile.to_str()))
+}
+
+pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn {
+    use core::cell::Cell;
+    let config = Cell::new(copy *config);
+    let testfile = Cell::new(testfile.to_str());
+    test::DynTestFn(|| { runtest::run(config.take(), testfile.take()) })
+}
diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs
new file mode 100644 (file)
index 0000000..11aebdf
--- /dev/null
@@ -0,0 +1,155 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+
+Rust extras.
+
+The `extra` crate is a set of useful modules for a variety of
+purposes, including collections, numerics, I/O, serialization,
+and concurrency.
+
+Rust extras are part of the standard Rust distribution.
+
+*/
+
+#[link(name = "extra",
+       vers = "0.7-pre",
+       uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
+       url = "https://github.com/mozilla/rust/tree/master/src/libextra")];
+
+#[comment = "Rust extras"];
+#[license = "MIT/ASL2"];
+#[crate_type = "lib"];
+
+#[deny(non_camel_case_types)];
+#[deny(missing_doc)];
+
+#[no_std];
+
+extern mod core(name = "std", vers = "0.7-pre");
+
+use core::str::{StrSlice, OwnedStr};
+
+pub use core::os;
+
+pub mod uv_ll;
+
+// General io and system-services modules
+
+pub mod net;
+pub mod net_ip;
+pub mod net_tcp;
+pub mod net_url;
+
+// libuv modules
+pub mod uv;
+pub mod uv_iotask;
+pub mod uv_global_loop;
+
+
+// Utility modules
+
+pub mod c_vec;
+pub mod timer;
+pub mod io_util;
+pub mod rc;
+
+// Concurrency
+
+pub mod sync;
+pub mod arc;
+pub mod comm;
+pub mod future;
+pub mod task_pool;
+pub mod flatpipes;
+
+// Collections
+
+pub mod bitv;
+pub mod deque;
+pub mod fun_treemap;
+pub mod list;
+pub mod priority_queue;
+pub mod rope;
+pub mod smallintmap;
+
+pub mod sort;
+
+pub mod dlist;
+pub mod treemap;
+
+// Crypto
+#[path="crypto/digest.rs"]
+pub mod digest;
+#[path="crypto/sha1.rs"]
+pub mod sha1;
+#[path="crypto/sha2.rs"]
+pub mod sha2;
+
+// And ... other stuff
+
+pub mod ebml;
+pub mod dbg;
+pub mod getopts;
+pub mod json;
+pub mod md4;
+pub mod tempfile;
+pub mod term;
+pub mod time;
+pub mod arena;
+pub mod par;
+pub mod base64;
+pub mod rl;
+pub mod workcache;
+#[path="num/bigint.rs"]
+pub mod bigint;
+#[path="num/rational.rs"]
+pub mod rational;
+#[path="num/complex.rs"]
+pub mod complex;
+pub mod stats;
+pub mod semver;
+pub mod fileinput;
+pub mod flate;
+
+#[cfg(unicode)]
+mod unicode;
+
+#[path="terminfo/terminfo.rs"]
+pub mod terminfo;
+
+// Compiler support modules
+
+pub mod test;
+pub mod serialize;
+
+// A curious inner-module that's not exported that contains the binding
+// 'extra' so that macro-expanded references to extra::serialize and such
+// can be resolved within libextra.
+#[doc(hidden)]
+pub mod std {
+    pub use serialize;
+    pub use test;
+
+    // For bootstrapping.
+    pub use core::clone;
+    pub use core::condition;
+    pub use core::cmp;
+    pub use core::sys;
+    pub use core::unstable;
+    pub use core::str;
+    pub use core::os;
+}
+#[doc(hidden)]
+pub mod extra {
+    pub use serialize;
+    pub use test;
+}
diff --git a/src/libextra/std.rc b/src/libextra/std.rc
deleted file mode 100644 (file)
index 11aebdf..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Rust extras.
-
-The `extra` crate is a set of useful modules for a variety of
-purposes, including collections, numerics, I/O, serialization,
-and concurrency.
-
-Rust extras are part of the standard Rust distribution.
-
-*/
-
-#[link(name = "extra",
-       vers = "0.7-pre",
-       uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
-       url = "https://github.com/mozilla/rust/tree/master/src/libextra")];
-
-#[comment = "Rust extras"];
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-#[deny(non_camel_case_types)];
-#[deny(missing_doc)];
-
-#[no_std];
-
-extern mod core(name = "std", vers = "0.7-pre");
-
-use core::str::{StrSlice, OwnedStr};
-
-pub use core::os;
-
-pub mod uv_ll;
-
-// General io and system-services modules
-
-pub mod net;
-pub mod net_ip;
-pub mod net_tcp;
-pub mod net_url;
-
-// libuv modules
-pub mod uv;
-pub mod uv_iotask;
-pub mod uv_global_loop;
-
-
-// Utility modules
-
-pub mod c_vec;
-pub mod timer;
-pub mod io_util;
-pub mod rc;
-
-// Concurrency
-
-pub mod sync;
-pub mod arc;
-pub mod comm;
-pub mod future;
-pub mod task_pool;
-pub mod flatpipes;
-
-// Collections
-
-pub mod bitv;
-pub mod deque;
-pub mod fun_treemap;
-pub mod list;
-pub mod priority_queue;
-pub mod rope;
-pub mod smallintmap;
-
-pub mod sort;
-
-pub mod dlist;
-pub mod treemap;
-
-// Crypto
-#[path="crypto/digest.rs"]
-pub mod digest;
-#[path="crypto/sha1.rs"]
-pub mod sha1;
-#[path="crypto/sha2.rs"]
-pub mod sha2;
-
-// And ... other stuff
-
-pub mod ebml;
-pub mod dbg;
-pub mod getopts;
-pub mod json;
-pub mod md4;
-pub mod tempfile;
-pub mod term;
-pub mod time;
-pub mod arena;
-pub mod par;
-pub mod base64;
-pub mod rl;
-pub mod workcache;
-#[path="num/bigint.rs"]
-pub mod bigint;
-#[path="num/rational.rs"]
-pub mod rational;
-#[path="num/complex.rs"]
-pub mod complex;
-pub mod stats;
-pub mod semver;
-pub mod fileinput;
-pub mod flate;
-
-#[cfg(unicode)]
-mod unicode;
-
-#[path="terminfo/terminfo.rs"]
-pub mod terminfo;
-
-// Compiler support modules
-
-pub mod test;
-pub mod serialize;
-
-// A curious inner-module that's not exported that contains the binding
-// 'extra' so that macro-expanded references to extra::serialize and such
-// can be resolved within libextra.
-#[doc(hidden)]
-pub mod std {
-    pub use serialize;
-    pub use test;
-
-    // For bootstrapping.
-    pub use core::clone;
-    pub use core::condition;
-    pub use core::cmp;
-    pub use core::sys;
-    pub use core::unstable;
-    pub use core::str;
-    pub use core::os;
-}
-#[doc(hidden)]
-pub mod extra {
-    pub use serialize;
-    pub use test;
-}
diff --git a/src/librust/rust.rc b/src/librust/rust.rc
deleted file mode 100644 (file)
index 6842774..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// rust - central access to other rust tools
-// FIXME #2238 Make commands run and test emit proper file endings on windows
-// FIXME #2238 Make run only accept source that emits an executable
-
-#[link(name = "rust",
-       vers = "0.7-pre",
-       uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c",
-       url = "https://github.com/mozilla/rust/tree/master/src/rust")];
-
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-#[no_std];
-
-extern mod core(name = "std");
-
-extern mod rustpkg;
-extern mod rustdoc;
-extern mod rusti;
-extern mod rustc;
-
-use core::prelude::*;
-
-use core::io;
-use core::os;
-use core::run;
-use core::libc::exit;
-
-// For bootstrapping.
-mod std {
-    pub use core::os;
-    pub use core::str;
-    pub use core::unstable;
-}
-
-enum ValidUsage {
-    Valid(int), Invalid
-}
-
-impl ValidUsage {
-    fn is_valid(&self) -> bool {
-        match *self {
-            Valid(_)   => true,
-            Invalid    => false
-        }
-    }
-}
-
-enum Action<'self> {
-    Call(&'self fn(args: &[~str]) -> ValidUsage),
-    CallMain(&'static str, &'self fn()),
-}
-
-enum UsageSource<'self> {
-    UsgStr(&'self str),
-    UsgCall(&'self fn()),
-}
-
-struct Command<'self> {
-    cmd: &'self str,
-    action: Action<'self>,
-    usage_line: &'self str,
-    usage_full: UsageSource<'self>,
-}
-
-static commands: &'static [Command<'static>] = &[
-    Command{
-        cmd: "build",
-        action: CallMain("rustc", rustc::main),
-        usage_line: "compile rust source files",
-        usage_full: UsgCall(rustc_help),
-    },
-    Command{
-        cmd: "run",
-        action: Call(cmd_run),
-        usage_line: "build an executable, and run it",
-        usage_full: UsgStr(
-            "The run command is an shortcut for the command line \n\
-             \"rustc <filename> -o <filestem>~ && ./<filestem>~ [<arguments>...]\".\
-            \n\nUsage:\trust run <filename> [<arguments>...]"
-        )
-    },
-    Command{
-        cmd: "test",
-        action: Call(cmd_test),
-        usage_line: "build a test executable, and run it",
-        usage_full: UsgStr(
-            "The test command is an shortcut for the command line \n\
-            \"rustc --test <filename> -o <filestem>test~ && \
-            ./<filestem>test~\"\n\nUsage:\trust test <filename>"
-        )
-    },
-    Command{
-        cmd: "doc",
-        action: CallMain("rustdoc", rustdoc::main),
-        usage_line: "generate documentation from doc comments",
-        usage_full: UsgCall(rustdoc::config::usage),
-    },
-    Command{
-        cmd: "pkg",
-        action: CallMain("rustpkg", rustpkg::main),
-        usage_line: "download, build, install rust packages",
-        usage_full: UsgCall(rustpkg::usage::general),
-    },
-    Command{
-        cmd: "sketch",
-        action: CallMain("rusti", rusti::main),
-        usage_line: "run a rust interpreter",
-        usage_full: UsgStr("\nUsage:\trusti"),
-    },
-    Command{
-        cmd: "help",
-        action: Call(cmd_help),
-        usage_line: "show detailed usage of a command",
-        usage_full: UsgStr(
-            "The help command displays the usage text of another command.\n\
-            The text is either build in, or provided by the corresponding \
-            program.\n\nUsage:\trust help <command>"
-        )
-    }
-];
-
-fn rustc_help() {
-    rustc::usage(copy os::args()[0])
-}
-
-fn find_cmd(command_string: &str) -> Option<Command> {
-    do commands.iter().find_ |command| {
-        command.cmd == command_string
-    }.map_consume(|x| copy *x)
-}
-
-fn cmd_help(args: &[~str]) -> ValidUsage {
-    fn print_usage(command_string: ~str) -> ValidUsage {
-        match find_cmd(command_string) {
-            Some(command) => {
-                match command.action {
-                    CallMain(prog, _) => io::println(fmt!(
-                        "The %s command is an alias for the %s program.",
-                        command.cmd, prog)),
-                    _       => ()
-                }
-                match command.usage_full {
-                    UsgStr(msg) => io::println(fmt!("%s\n", msg)),
-                    UsgCall(f)  => f(),
-                }
-                Valid(0)
-            },
-            None => Invalid
-        }
-    }
-
-    match args {
-        [ref command_string] => print_usage(copy *command_string),
-        _                    => Invalid
-    }
-}
-
-fn cmd_test(args: &[~str]) -> ValidUsage {
-    match args {
-        [ref filename] => {
-            let test_exec = Path(*filename).filestem().unwrap() + "test~";
-            invoke("rustc", &[~"--test", filename.to_owned(),
-                              ~"-o", test_exec.to_owned()], rustc::main);
-            let exit_code = run::process_status(~"./" + test_exec, []);
-            Valid(exit_code)
-        }
-        _ => Invalid
-    }
-}
-
-fn cmd_run(args: &[~str]) -> ValidUsage {
-    match args {
-        [ref filename, ..prog_args] => {
-            let exec = Path(*filename).filestem().unwrap() + "~";
-            invoke("rustc", &[filename.to_owned(), ~"-o", exec.to_owned()],
-                   rustc::main);
-            let exit_code = run::process_status(~"./"+exec, prog_args);
-            Valid(exit_code)
-        }
-        _ => Invalid
-    }
-}
-
-fn invoke(prog: &str, args: &[~str], f: &fn()) {
-    let mut osargs = ~[prog.to_owned()];
-    osargs.push_all_move(args.to_owned());
-    os::set_args(osargs);
-    f();
-}
-
-fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
-    match command.action {
-        Call(f) => f(args),
-        CallMain(prog, f) => {
-            invoke(prog, args, f);
-            Valid(0)
-        }
-    }
-}
-
-fn usage() {
-    static indent: uint = 8;
-
-    io::print(
-        "The rust tool is a convenience for managing rust source code.\n\
-        It acts as a shortcut for programs of the rust tool chain.\n\
-        \n\
-        Usage:\trust <command> [arguments]\n\
-        \n\
-        The commands are:\n\
-        \n"
-    );
-
-    for commands.iter().advance |command| {
-        let padding = " ".repeat(indent - command.cmd.len());
-        io::println(fmt!("    %s%s%s",
-                         command.cmd, padding, command.usage_line));
-    }
-
-    io::print(
-        "\n\
-        Use \"rust help <command>\" for more information about a command.\n\
-        \n"
-    );
-
-}
-
-pub fn main() {
-    let os_args = os::args();
-    let args = os_args.tail();
-
-    if !args.is_empty() {
-        let r = find_cmd(*args.head());
-        for r.iter().advance |command| {
-            let result = do_command(command, args.tail());
-            match result {
-                Valid(exit_code) => unsafe { exit(exit_code.to_i32()) },
-                _                => loop
-            }
-        }
-    }
-
-    usage();
-}
diff --git a/src/librust/rust.rs b/src/librust/rust.rs
new file mode 100644 (file)
index 0000000..6842774
--- /dev/null
@@ -0,0 +1,255 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// rust - central access to other rust tools
+// FIXME #2238 Make commands run and test emit proper file endings on windows
+// FIXME #2238 Make run only accept source that emits an executable
+
+#[link(name = "rust",
+       vers = "0.7-pre",
+       uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c",
+       url = "https://github.com/mozilla/rust/tree/master/src/rust")];
+
+#[license = "MIT/ASL2"];
+#[crate_type = "lib"];
+
+#[no_std];
+
+extern mod core(name = "std");
+
+extern mod rustpkg;
+extern mod rustdoc;
+extern mod rusti;
+extern mod rustc;
+
+use core::prelude::*;
+
+use core::io;
+use core::os;
+use core::run;
+use core::libc::exit;
+
+// For bootstrapping.
+mod std {
+    pub use core::os;
+    pub use core::str;
+    pub use core::unstable;
+}
+
+enum ValidUsage {
+    Valid(int), Invalid
+}
+
+impl ValidUsage {
+    fn is_valid(&self) -> bool {
+        match *self {
+            Valid(_)   => true,
+            Invalid    => false
+        }
+    }
+}
+
+enum Action<'self> {
+    Call(&'self fn(args: &[~str]) -> ValidUsage),
+    CallMain(&'static str, &'self fn()),
+}
+
+enum UsageSource<'self> {
+    UsgStr(&'self str),
+    UsgCall(&'self fn()),
+}
+
+struct Command<'self> {
+    cmd: &'self str,
+    action: Action<'self>,
+    usage_line: &'self str,
+    usage_full: UsageSource<'self>,
+}
+
+static commands: &'static [Command<'static>] = &[
+    Command{
+        cmd: "build",
+        action: CallMain("rustc", rustc::main),
+        usage_line: "compile rust source files",
+        usage_full: UsgCall(rustc_help),
+    },
+    Command{
+        cmd: "run",
+        action: Call(cmd_run),
+        usage_line: "build an executable, and run it",
+        usage_full: UsgStr(
+            "The run command is an shortcut for the command line \n\
+             \"rustc <filename> -o <filestem>~ && ./<filestem>~ [<arguments>...]\".\
+            \n\nUsage:\trust run <filename> [<arguments>...]"
+        )
+    },
+    Command{
+        cmd: "test",
+        action: Call(cmd_test),
+        usage_line: "build a test executable, and run it",
+        usage_full: UsgStr(
+            "The test command is an shortcut for the command line \n\
+            \"rustc --test <filename> -o <filestem>test~ && \
+            ./<filestem>test~\"\n\nUsage:\trust test <filename>"
+        )
+    },
+    Command{
+        cmd: "doc",
+        action: CallMain("rustdoc", rustdoc::main),
+        usage_line: "generate documentation from doc comments",
+        usage_full: UsgCall(rustdoc::config::usage),
+    },
+    Command{
+        cmd: "pkg",
+        action: CallMain("rustpkg", rustpkg::main),
+        usage_line: "download, build, install rust packages",
+        usage_full: UsgCall(rustpkg::usage::general),
+    },
+    Command{
+        cmd: "sketch",
+        action: CallMain("rusti", rusti::main),
+        usage_line: "run a rust interpreter",
+        usage_full: UsgStr("\nUsage:\trusti"),
+    },
+    Command{
+        cmd: "help",
+        action: Call(cmd_help),
+        usage_line: "show detailed usage of a command",
+        usage_full: UsgStr(
+            "The help command displays the usage text of another command.\n\
+            The text is either build in, or provided by the corresponding \
+            program.\n\nUsage:\trust help <command>"
+        )
+    }
+];
+
+fn rustc_help() {
+    rustc::usage(copy os::args()[0])
+}
+
+fn find_cmd(command_string: &str) -> Option<Command> {
+    do commands.iter().find_ |command| {
+        command.cmd == command_string
+    }.map_consume(|x| copy *x)
+}
+
+fn cmd_help(args: &[~str]) -> ValidUsage {
+    fn print_usage(command_string: ~str) -> ValidUsage {
+        match find_cmd(command_string) {
+            Some(command) => {
+                match command.action {
+                    CallMain(prog, _) => io::println(fmt!(
+                        "The %s command is an alias for the %s program.",
+                        command.cmd, prog)),
+                    _       => ()
+                }
+                match command.usage_full {
+                    UsgStr(msg) => io::println(fmt!("%s\n", msg)),
+                    UsgCall(f)  => f(),
+                }
+                Valid(0)
+            },
+            None => Invalid
+        }
+    }
+
+    match args {
+        [ref command_string] => print_usage(copy *command_string),
+        _                    => Invalid
+    }
+}
+
+fn cmd_test(args: &[~str]) -> ValidUsage {
+    match args {
+        [ref filename] => {
+            let test_exec = Path(*filename).filestem().unwrap() + "test~";
+            invoke("rustc", &[~"--test", filename.to_owned(),
+                              ~"-o", test_exec.to_owned()], rustc::main);
+            let exit_code = run::process_status(~"./" + test_exec, []);
+            Valid(exit_code)
+        }
+        _ => Invalid
+    }
+}
+
+fn cmd_run(args: &[~str]) -> ValidUsage {
+    match args {
+        [ref filename, ..prog_args] => {
+            let exec = Path(*filename).filestem().unwrap() + "~";
+            invoke("rustc", &[filename.to_owned(), ~"-o", exec.to_owned()],
+                   rustc::main);
+            let exit_code = run::process_status(~"./"+exec, prog_args);
+            Valid(exit_code)
+        }
+        _ => Invalid
+    }
+}
+
+fn invoke(prog: &str, args: &[~str], f: &fn()) {
+    let mut osargs = ~[prog.to_owned()];
+    osargs.push_all_move(args.to_owned());
+    os::set_args(osargs);
+    f();
+}
+
+fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
+    match command.action {
+        Call(f) => f(args),
+        CallMain(prog, f) => {
+            invoke(prog, args, f);
+            Valid(0)
+        }
+    }
+}
+
+fn usage() {
+    static indent: uint = 8;
+
+    io::print(
+        "The rust tool is a convenience for managing rust source code.\n\
+        It acts as a shortcut for programs of the rust tool chain.\n\
+        \n\
+        Usage:\trust <command> [arguments]\n\
+        \n\
+        The commands are:\n\
+        \n"
+    );
+
+    for commands.iter().advance |command| {
+        let padding = " ".repeat(indent - command.cmd.len());
+        io::println(fmt!("    %s%s%s",
+                         command.cmd, padding, command.usage_line));
+    }
+
+    io::print(
+        "\n\
+        Use \"rust help <command>\" for more information about a command.\n\
+        \n"
+    );
+
+}
+
+pub fn main() {
+    let os_args = os::args();
+    let args = os_args.tail();
+
+    if !args.is_empty() {
+        let r = find_cmd(*args.head());
+        for r.iter().advance |command| {
+            let result = do_command(command, args.tail());
+            match result {
+                Valid(exit_code) => unsafe { exit(exit_code.to_i32()) },
+                _                => loop
+            }
+        }
+    }
+
+    usage();
+}
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
deleted file mode 100644 (file)
index 20705b3..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[link(name = "rustc",
-       vers = "0.7-pre",
-       uuid = "0ce89b41-2f92-459e-bbc1-8f5fe32f16cf",
-       url = "https://github.com/mozilla/rust/tree/master/src/rustc")];
-
-#[comment = "The Rust compiler"];
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-#[allow(non_implicitly_copyable_typarams)];
-#[allow(non_camel_case_types)];
-#[deny(deprecated_pattern)];
-
-#[no_core];
-#[no_std];
-
-extern mod core(name = "std");
-extern mod extra(name = "extra");
-extern mod syntax;
-
-extern mod std(name = "std", vers = "0.7-pre");
-
-use core::prelude::*;
-
-use driver::driver::{host_triple, optgroups, early_error};
-use driver::driver::{str_input, file_input, build_session_options};
-use driver::driver::{build_session, build_configuration, parse_pretty};
-use driver::driver::{pp_mode, pretty_print_input, list_metadata};
-use driver::driver::{compile_input};
-use driver::session;
-use middle::lint;
-
-use core::io;
-use core::os;
-use core::result;
-use core::str;
-use core::task;
-use core::uint;
-use core::vec;
-use extra::getopts::{groups, opt_present};
-use extra::getopts;
-use syntax::codemap;
-use syntax::diagnostic;
-
-pub mod middle {
-    #[path = "trans/mod.rs"]
-    pub mod trans;
-    pub mod ty;
-    pub mod subst;
-    pub mod resolve;
-    #[path = "typeck/mod.rs"]
-    pub mod typeck;
-    pub mod check_loop;
-    pub mod check_match;
-    pub mod check_const;
-    pub mod lint;
-    #[path = "borrowck/mod.rs"]
-    pub mod borrowck;
-    pub mod dataflow;
-    pub mod mem_categorization;
-    pub mod liveness;
-    pub mod kind;
-    pub mod freevars;
-    pub mod pat_util;
-    pub mod region;
-    pub mod const_eval;
-    pub mod astencode;
-    pub mod lang_items;
-    pub mod privacy;
-    pub mod moves;
-    pub mod entry;
-    pub mod effect;
-}
-
-pub mod front {
-    pub mod config;
-    pub mod test;
-    pub mod std_inject;
-}
-
-pub mod back {
-    pub mod link;
-    pub mod abi;
-    pub mod upcall;
-    pub mod arm;
-    pub mod mips;
-    pub mod x86;
-    pub mod x86_64;
-    pub mod rpath;
-    pub mod target_strs;
-    pub mod passes;
-}
-
-#[path = "metadata/mod.rs"]
-pub mod metadata;
-
-#[path = "driver/mod.rs"]
-pub mod driver;
-
-pub mod util {
-    pub mod common;
-    pub mod ppaux;
-    pub mod enum_set;
-}
-
-pub mod lib {
-    pub mod llvm;
-}
-
-// A curious inner module that allows ::std::foo to be available in here for
-// macros.
-mod std {
-    pub use core::cmp;
-    pub use core::os;
-    pub use core::str;
-    pub use core::sys;
-    pub use core::to_bytes;
-    pub use core::unstable;
-    pub use extra::serialize;
-}
-
-pub fn version(argv0: &str) {
-    let mut vers = ~"unknown version";
-    let env_vers = env!("CFG_VERSION");
-    if env_vers.len() != 0 { vers = env_vers.to_owned(); }
-    io::println(fmt!("%s %s", argv0, vers));
-    io::println(fmt!("host: %s", host_triple()));
-}
-
-pub fn usage(argv0: &str) {
-    let message = fmt!("Usage: %s [OPTIONS] INPUT", argv0);
-    io::println(fmt!("%s\
-Additional help:
-    -W help             Print 'lint' options and default settings
-    -Z help             Print internal options for debugging rustc\n",
-                     groups::usage(message, optgroups())));
-}
-
-pub fn describe_warnings() {
-    io::println(fmt!("
-Available lint options:
-    -W <foo>           Warn about <foo>
-    -A <foo>           Allow <foo>
-    -D <foo>           Deny <foo>
-    -F <foo>           Forbid <foo> (deny, and deny all overrides)
-"));
-
-    let lint_dict = lint::get_lint_dict();
-    let mut max_key = 0;
-    for lint_dict.each_key |k| { max_key = uint::max(k.len(), max_key); }
-    fn padded(max: uint, s: &str) -> ~str {
-        str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s
-    }
-    io::println(fmt!("\nAvailable lint checks:\n"));
-    io::println(fmt!("    %s  %7.7s  %s",
-                     padded(max_key, "name"), "default", "meaning"));
-    io::println(fmt!("    %s  %7.7s  %s\n",
-                     padded(max_key, "----"), "-------", "-------"));
-    for lint_dict.each |k, v| {
-        let k = k.replace("_", "-");
-        io::println(fmt!("    %s  %7.7s  %s",
-                         padded(max_key, k),
-                         match v.default {
-                             lint::allow => ~"allow",
-                             lint::warn => ~"warn",
-                             lint::deny => ~"deny",
-                             lint::forbid => ~"forbid"
-                         },
-                         v.desc));
-    }
-    io::println("");
-}
-
-pub fn describe_debug_flags() {
-    io::println(fmt!("\nAvailable debug options:\n"));
-    let r = session::debugging_opts_map();
-    for r.iter().advance |pair| {
-        let (name, desc, _) = /*bad*/copy *pair;
-        io::println(fmt!("    -Z %-20s -- %s", name, desc));
-    }
-}
-
-pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) {
-    // Don't display log spew by default. Can override with RUST_LOG.
-    ::core::logging::console_off();
-
-    let mut args = /*bad*/copy *args;
-    let binary = args.shift().to_managed();
-
-    if args.is_empty() { usage(binary); return; }
-
-    let matches =
-        &match getopts::groups::getopts(args, optgroups()) {
-          Ok(m) => m,
-          Err(f) => {
-            early_error(demitter, getopts::fail_str(f));
-          }
-        };
-
-    if opt_present(matches, "h") || opt_present(matches, "help") {
-        usage(binary);
-        return;
-    }
-
-    // Display the available lint options if "-W help" or only "-W" is given.
-    let lint_flags = vec::append(getopts::opt_strs(matches, "W"),
-                                 getopts::opt_strs(matches, "warn"));
-
-    let show_lint_options = lint_flags.iter().any_(|x| x == &~"help") ||
-        (opt_present(matches, "W") && lint_flags.is_empty());
-
-    if show_lint_options {
-        describe_warnings();
-        return;
-    }
-
-    let r = getopts::opt_strs(matches, "Z");
-    if r.iter().any_(|x| x == &~"help") {
-        describe_debug_flags();
-        return;
-    }
-
-    if getopts::opt_maybe_str(matches, "passes") == Some(~"list") {
-        back::passes::list_passes();
-        return;
-    }
-
-    if opt_present(matches, "v") || opt_present(matches, "version") {
-        version(binary);
-        return;
-    }
-    let input = match matches.free.len() {
-      0u => early_error(demitter, ~"no input filename given"),
-      1u => {
-        let ifile = matches.free[0].as_slice();
-        if "-" == ifile {
-            let src = str::from_bytes(io::stdin().read_whole_stream());
-            str_input(src.to_managed())
-        } else {
-            file_input(Path(ifile))
-        }
-      }
-      _ => early_error(demitter, ~"multiple input filenames provided")
-    };
-
-    let sopts = build_session_options(binary, matches, demitter);
-    let sess = build_session(sopts, demitter);
-    let odir = getopts::opt_maybe_str(matches, "out-dir");
-    let odir = odir.map(|o| Path(*o));
-    let ofile = getopts::opt_maybe_str(matches, "o");
-    let ofile = ofile.map(|o| Path(*o));
-    let cfg = build_configuration(sess, binary, &input);
-    let pretty = getopts::opt_default(matches, "pretty", "normal").map(
-                    |a| parse_pretty(sess, *a));
-    match pretty {
-      Some::<pp_mode>(ppm) => {
-        pretty_print_input(sess, cfg, &input, ppm);
-        return;
-      }
-      None::<pp_mode> => {/* continue */ }
-    }
-    let ls = opt_present(matches, "ls");
-    if ls {
-        match input {
-          file_input(ref ifile) => {
-            list_metadata(sess, &(*ifile), io::stdout());
-          }
-          str_input(_) => {
-            early_error(demitter, ~"can not list metadata for stdin");
-          }
-        }
-        return;
-    }
-
-    compile_input(sess, cfg, &input, &odir, &ofile);
-}
-
-#[deriving(Eq)]
-pub enum monitor_msg {
-    fatal,
-    done,
-}
-
-/*
-This is a sanity check that any failure of the compiler is performed
-through the diagnostic module and reported properly - we shouldn't be calling
-plain-old-fail on any execution path that might be taken. Since we have
-console logging off by default, hitting a plain fail statement would make the
-compiler silently exit, which would be terrible.
-
-This method wraps the compiler in a subtask and injects a function into the
-diagnostic emitter which records when we hit a fatal error. If the task
-fails without recording a fatal error then we've encountered a compiler
-bug and need to present an error.
-*/
-pub fn monitor(f: ~fn(diagnostic::Emitter)) {
-    use core::comm::*;
-    let (p, ch) = stream();
-    let ch = SharedChan::new(ch);
-    let ch_capture = ch.clone();
-    match do task::try || {
-        let ch = ch_capture.clone();
-        let ch_capture = ch.clone();
-        // The 'diagnostics emitter'. Every error, warning, etc. should
-        // go through this function.
-        let demitter: @fn(Option<(@codemap::CodeMap, codemap::span)>,
-                          &str,
-                          diagnostic::level) =
-                          |cmsp, msg, lvl| {
-            if lvl == diagnostic::fatal {
-                ch_capture.send(fatal);
-            }
-            diagnostic::emit(cmsp, msg, lvl);
-        };
-
-        struct finally {
-            ch: SharedChan<monitor_msg>,
-        }
-
-        impl Drop for finally {
-            fn finalize(&self) { self.ch.send(done); }
-        }
-
-        let _finally = finally { ch: ch };
-
-        f(demitter)
-    } {
-        result::Ok(_) => { /* fallthrough */ }
-        result::Err(_) => {
-            // Task failed without emitting a fatal diagnostic
-            if p.recv() == done {
-                diagnostic::emit(
-                    None,
-                    diagnostic::ice_msg("unexpected failure"),
-                    diagnostic::error);
-
-                let xs = [
-                    ~"the compiler hit an unexpected failure path. \
-                     this is a bug",
-                    ~"try running with RUST_LOG=rustc=1,::rt::backtrace \
-                     to get further details and report the results \
-                     to github.com/mozilla/rust/issues"
-                ];
-                for xs.iter().advance |note| {
-                    diagnostic::emit(None, *note, diagnostic::note)
-                }
-            }
-            // Fail so the process returns a failure code
-            fail!();
-        }
-    }
-}
-
-pub fn main() {
-    let args = os::args();
-    do monitor |demitter| {
-        run_compiler(&args, demitter);
-    }
-}
diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs
new file mode 100644 (file)
index 0000000..20705b3
--- /dev/null
@@ -0,0 +1,369 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[link(name = "rustc",
+       vers = "0.7-pre",
+       uuid = "0ce89b41-2f92-459e-bbc1-8f5fe32f16cf",
+       url = "https://github.com/mozilla/rust/tree/master/src/rustc")];
+
+#[comment = "The Rust compiler"];
+#[license = "MIT/ASL2"];
+#[crate_type = "lib"];
+
+#[allow(non_implicitly_copyable_typarams)];
+#[allow(non_camel_case_types)];
+#[deny(deprecated_pattern)];
+
+#[no_core];
+#[no_std];
+
+extern mod core(name = "std");
+extern mod extra(name = "extra");
+extern mod syntax;
+
+extern mod std(name = "std", vers = "0.7-pre");
+
+use core::prelude::*;
+
+use driver::driver::{host_triple, optgroups, early_error};
+use driver::driver::{str_input, file_input, build_session_options};
+use driver::driver::{build_session, build_configuration, parse_pretty};
+use driver::driver::{pp_mode, pretty_print_input, list_metadata};
+use driver::driver::{compile_input};
+use driver::session;
+use middle::lint;
+
+use core::io;
+use core::os;
+use core::result;
+use core::str;
+use core::task;
+use core::uint;
+use core::vec;
+use extra::getopts::{groups, opt_present};
+use extra::getopts;
+use syntax::codemap;
+use syntax::diagnostic;
+
+pub mod middle {
+    #[path = "trans/mod.rs"]
+    pub mod trans;
+    pub mod ty;
+    pub mod subst;
+    pub mod resolve;
+    #[path = "typeck/mod.rs"]
+    pub mod typeck;
+    pub mod check_loop;
+    pub mod check_match;
+    pub mod check_const;
+    pub mod lint;
+    #[path = "borrowck/mod.rs"]
+    pub mod borrowck;
+    pub mod dataflow;
+    pub mod mem_categorization;
+    pub mod liveness;
+    pub mod kind;
+    pub mod freevars;
+    pub mod pat_util;
+    pub mod region;
+    pub mod const_eval;
+    pub mod astencode;
+    pub mod lang_items;
+    pub mod privacy;
+    pub mod moves;
+    pub mod entry;
+    pub mod effect;
+}
+
+pub mod front {
+    pub mod config;
+    pub mod test;
+    pub mod std_inject;
+}
+
+pub mod back {
+    pub mod link;
+    pub mod abi;
+    pub mod upcall;
+    pub mod arm;
+    pub mod mips;
+    pub mod x86;
+    pub mod x86_64;
+    pub mod rpath;
+    pub mod target_strs;
+    pub mod passes;
+}
+
+#[path = "metadata/mod.rs"]
+pub mod metadata;
+
+#[path = "driver/mod.rs"]
+pub mod driver;
+
+pub mod util {
+    pub mod common;
+    pub mod ppaux;
+    pub mod enum_set;
+}
+
+pub mod lib {
+    pub mod llvm;
+}
+
+// A curious inner module that allows ::std::foo to be available in here for
+// macros.
+mod std {
+    pub use core::cmp;
+    pub use core::os;
+    pub use core::str;
+    pub use core::sys;
+    pub use core::to_bytes;
+    pub use core::unstable;
+    pub use extra::serialize;
+}
+
+pub fn version(argv0: &str) {
+    let mut vers = ~"unknown version";
+    let env_vers = env!("CFG_VERSION");
+    if env_vers.len() != 0 { vers = env_vers.to_owned(); }
+    io::println(fmt!("%s %s", argv0, vers));
+    io::println(fmt!("host: %s", host_triple()));
+}
+
+pub fn usage(argv0: &str) {
+    let message = fmt!("Usage: %s [OPTIONS] INPUT", argv0);
+    io::println(fmt!("%s\
+Additional help:
+    -W help             Print 'lint' options and default settings
+    -Z help             Print internal options for debugging rustc\n",
+                     groups::usage(message, optgroups())));
+}
+
+pub fn describe_warnings() {
+    io::println(fmt!("
+Available lint options:
+    -W <foo>           Warn about <foo>
+    -A <foo>           Allow <foo>
+    -D <foo>           Deny <foo>
+    -F <foo>           Forbid <foo> (deny, and deny all overrides)
+"));
+
+    let lint_dict = lint::get_lint_dict();
+    let mut max_key = 0;
+    for lint_dict.each_key |k| { max_key = uint::max(k.len(), max_key); }
+    fn padded(max: uint, s: &str) -> ~str {
+        str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s
+    }
+    io::println(fmt!("\nAvailable lint checks:\n"));
+    io::println(fmt!("    %s  %7.7s  %s",
+                     padded(max_key, "name"), "default", "meaning"));
+    io::println(fmt!("    %s  %7.7s  %s\n",
+                     padded(max_key, "----"), "-------", "-------"));
+    for lint_dict.each |k, v| {
+        let k = k.replace("_", "-");
+        io::println(fmt!("    %s  %7.7s  %s",
+                         padded(max_key, k),
+                         match v.default {
+                             lint::allow => ~"allow",
+                             lint::warn => ~"warn",
+                             lint::deny => ~"deny",
+                             lint::forbid => ~"forbid"
+                         },
+                         v.desc));
+    }
+    io::println("");
+}
+
+pub fn describe_debug_flags() {
+    io::println(fmt!("\nAvailable debug options:\n"));
+    let r = session::debugging_opts_map();
+    for r.iter().advance |pair| {
+        let (name, desc, _) = /*bad*/copy *pair;
+        io::println(fmt!("    -Z %-20s -- %s", name, desc));
+    }
+}
+
+pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) {
+    // Don't display log spew by default. Can override with RUST_LOG.
+    ::core::logging::console_off();
+
+    let mut args = /*bad*/copy *args;
+    let binary = args.shift().to_managed();
+
+    if args.is_empty() { usage(binary); return; }
+
+    let matches =
+        &match getopts::groups::getopts(args, optgroups()) {
+          Ok(m) => m,
+          Err(f) => {
+            early_error(demitter, getopts::fail_str(f));
+          }
+        };
+
+    if opt_present(matches, "h") || opt_present(matches, "help") {
+        usage(binary);
+        return;
+    }
+
+    // Display the available lint options if "-W help" or only "-W" is given.
+    let lint_flags = vec::append(getopts::opt_strs(matches, "W"),
+                                 getopts::opt_strs(matches, "warn"));
+
+    let show_lint_options = lint_flags.iter().any_(|x| x == &~"help") ||
+        (opt_present(matches, "W") && lint_flags.is_empty());
+
+    if show_lint_options {
+        describe_warnings();
+        return;
+    }
+
+    let r = getopts::opt_strs(matches, "Z");
+    if r.iter().any_(|x| x == &~"help") {
+        describe_debug_flags();
+        return;
+    }
+
+    if getopts::opt_maybe_str(matches, "passes") == Some(~"list") {
+        back::passes::list_passes();
+        return;
+    }
+
+    if opt_present(matches, "v") || opt_present(matches, "version") {
+        version(binary);
+        return;
+    }
+    let input = match matches.free.len() {
+      0u => early_error(demitter, ~"no input filename given"),
+      1u => {
+        let ifile = matches.free[0].as_slice();
+        if "-" == ifile {
+            let src = str::from_bytes(io::stdin().read_whole_stream());
+            str_input(src.to_managed())
+        } else {
+            file_input(Path(ifile))
+        }
+      }
+      _ => early_error(demitter, ~"multiple input filenames provided")
+    };
+
+    let sopts = build_session_options(binary, matches, demitter);
+    let sess = build_session(sopts, demitter);
+    let odir = getopts::opt_maybe_str(matches, "out-dir");
+    let odir = odir.map(|o| Path(*o));
+    let ofile = getopts::opt_maybe_str(matches, "o");
+    let ofile = ofile.map(|o| Path(*o));
+    let cfg = build_configuration(sess, binary, &input);
+    let pretty = getopts::opt_default(matches, "pretty", "normal").map(
+                    |a| parse_pretty(sess, *a));
+    match pretty {
+      Some::<pp_mode>(ppm) => {
+        pretty_print_input(sess, cfg, &input, ppm);
+        return;
+      }
+      None::<pp_mode> => {/* continue */ }
+    }
+    let ls = opt_present(matches, "ls");
+    if ls {
+        match input {
+          file_input(ref ifile) => {
+            list_metadata(sess, &(*ifile), io::stdout());
+          }
+          str_input(_) => {
+            early_error(demitter, ~"can not list metadata for stdin");
+          }
+        }
+        return;
+    }
+
+    compile_input(sess, cfg, &input, &odir, &ofile);
+}
+
+#[deriving(Eq)]
+pub enum monitor_msg {
+    fatal,
+    done,
+}
+
+/*
+This is a sanity check that any failure of the compiler is performed
+through the diagnostic module and reported properly - we shouldn't be calling
+plain-old-fail on any execution path that might be taken. Since we have
+console logging off by default, hitting a plain fail statement would make the
+compiler silently exit, which would be terrible.
+
+This method wraps the compiler in a subtask and injects a function into the
+diagnostic emitter which records when we hit a fatal error. If the task
+fails without recording a fatal error then we've encountered a compiler
+bug and need to present an error.
+*/
+pub fn monitor(f: ~fn(diagnostic::Emitter)) {
+    use core::comm::*;
+    let (p, ch) = stream();
+    let ch = SharedChan::new(ch);
+    let ch_capture = ch.clone();
+    match do task::try || {
+        let ch = ch_capture.clone();
+        let ch_capture = ch.clone();
+        // The 'diagnostics emitter'. Every error, warning, etc. should
+        // go through this function.
+        let demitter: @fn(Option<(@codemap::CodeMap, codemap::span)>,
+                          &str,
+                          diagnostic::level) =
+                          |cmsp, msg, lvl| {
+            if lvl == diagnostic::fatal {
+                ch_capture.send(fatal);
+            }
+            diagnostic::emit(cmsp, msg, lvl);
+        };
+
+        struct finally {
+            ch: SharedChan<monitor_msg>,
+        }
+
+        impl Drop for finally {
+            fn finalize(&self) { self.ch.send(done); }
+        }
+
+        let _finally = finally { ch: ch };
+
+        f(demitter)
+    } {
+        result::Ok(_) => { /* fallthrough */ }
+        result::Err(_) => {
+            // Task failed without emitting a fatal diagnostic
+            if p.recv() == done {
+                diagnostic::emit(
+                    None,
+                    diagnostic::ice_msg("unexpected failure"),
+                    diagnostic::error);
+
+                let xs = [
+                    ~"the compiler hit an unexpected failure path. \
+                     this is a bug",
+                    ~"try running with RUST_LOG=rustc=1,::rt::backtrace \
+                     to get further details and report the results \
+                     to github.com/mozilla/rust/issues"
+                ];
+                for xs.iter().advance |note| {
+                    diagnostic::emit(None, *note, diagnostic::note)
+                }
+            }
+            // Fail so the process returns a failure code
+            fail!();
+        }
+    }
+}
+
+pub fn main() {
+    let args = os::args();
+    do monitor |demitter| {
+        run_compiler(&args, demitter);
+    }
+}
diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc
deleted file mode 100644 (file)
index d026202..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Rustdoc - The Rust documentation generator
-
-#[link(name = "rustdoc",
-       vers = "0.7-pre",
-       uuid = "f8abd014-b281-484d-a0c3-26e3de8e2412",
-       url = "https://github.com/mozilla/rust/tree/master/src/rustdoc")];
-
-#[comment = "The Rust documentation generator"];
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-#[allow(non_implicitly_copyable_typarams)];
-
-#[no_std];
-
-extern mod core(name = "std");
-extern mod extra(name = "extra");
-
-extern mod rustc;
-extern mod syntax;
-
-use core::prelude::*;
-
-use config::Config;
-use doc::Item;
-use doc::ItemUtils;
-
-use core::*;
-
-pub mod pass;
-pub mod config;
-pub mod parse;
-pub mod extract;
-pub mod attr_parser;
-pub mod doc;
-pub mod markdown_index_pass;
-pub mod markdown_pass;
-pub mod markdown_writer;
-pub mod fold;
-pub mod path_pass;
-pub mod attr_pass;
-pub mod tystr_pass;
-pub mod prune_hidden_pass;
-pub mod desc_to_brief_pass;
-pub mod text_pass;
-pub mod unindent_pass;
-pub mod trim_pass;
-pub mod astsrv;
-pub mod demo;
-pub mod sort_pass;
-pub mod sort_item_name_pass;
-pub mod sort_item_type_pass;
-pub mod page_pass;
-pub mod sectionalize_pass;
-pub mod escape_pass;
-pub mod prune_private_pass;
-pub mod util;
-
-mod std {
-    pub use core::clone;
-    pub use core::cmp;
-    pub use core::os;
-    pub use core::str;
-    pub use core::sys;
-    pub use core::unstable;
-}
-
-pub fn main() {
-    let args = os::args();
-
-    if args.iter().any_(|x| "-h" == *x) || args.iter().any_(|x| "--help" == *x) {
-        config::usage();
-        return;
-    }
-
-    let config = match config::parse_config(args) {
-      Ok(config) => config,
-      Err(err) => {
-        io::println(fmt!("error: %s", err));
-        return;
-      }
-    };
-
-    run(config);
-}
-
-/// Runs rustdoc over the given file
-fn run(config: Config) {
-
-    let source_file = copy config.input_crate;
-
-    // Create an AST service from the source code
-    do astsrv::from_file(source_file.to_str()) |srv| {
-
-        // Just time how long it takes for the AST to become available
-        do time(~"wait_ast") {
-            do astsrv::exec(srv.clone()) |_ctxt| { }
-        };
-
-        // Extract the initial doc tree from the AST. This contains
-        // just names and node ids.
-        let doc = time(~"extract", || {
-            let default_name = copy source_file;
-            extract::from_srv(srv.clone(), default_name.to_str())
-        });
-
-        // Refine and publish the document
-        pass::run_passes(srv, doc, ~[
-            // Generate type and signature strings
-            tystr_pass::mk_pass(),
-            // Record the full paths to various nodes
-            path_pass::mk_pass(),
-            // Extract the docs attributes and attach them to doc nodes
-            attr_pass::mk_pass(),
-            // Perform various text escaping
-            escape_pass::mk_pass(),
-            // Remove things marked doc(hidden)
-            prune_hidden_pass::mk_pass(),
-            // Remove things that are private
-            prune_private_pass::mk_pass(),
-            // Extract brief documentation from the full descriptions
-            desc_to_brief_pass::mk_pass(),
-            // Massage the text to remove extra indentation
-            unindent_pass::mk_pass(),
-            // Split text into multiple sections according to headers
-            sectionalize_pass::mk_pass(),
-            // Trim extra spaces from text
-            trim_pass::mk_pass(),
-            // Sort items by name
-            sort_item_name_pass::mk_pass(),
-            // Sort items again by kind
-            sort_item_type_pass::mk_pass(),
-            // Create indexes appropriate for markdown
-            markdown_index_pass::mk_pass(copy config),
-            // Break the document into pages if required by the
-            // output format
-            page_pass::mk_pass(config.output_style),
-            // Render
-            markdown_pass::mk_pass(
-                markdown_writer::make_writer_factory(copy config)
-            )
-        ]);
-    }
-}
-
-pub fn time<T>(what: ~str, f: &fn() -> T) -> T {
-    let start = extra::time::precise_time_s();
-    let rv = f();
-    let end = extra::time::precise_time_s();
-    info!("time: %3.3f s    %s", end - start, what);
-    rv
-}
diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs
new file mode 100644 (file)
index 0000000..d026202
--- /dev/null
@@ -0,0 +1,162 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Rustdoc - The Rust documentation generator
+
+#[link(name = "rustdoc",
+       vers = "0.7-pre",
+       uuid = "f8abd014-b281-484d-a0c3-26e3de8e2412",
+       url = "https://github.com/mozilla/rust/tree/master/src/rustdoc")];
+
+#[comment = "The Rust documentation generator"];
+#[license = "MIT/ASL2"];
+#[crate_type = "lib"];
+
+#[allow(non_implicitly_copyable_typarams)];
+
+#[no_std];
+
+extern mod core(name = "std");
+extern mod extra(name = "extra");
+
+extern mod rustc;
+extern mod syntax;
+
+use core::prelude::*;
+
+use config::Config;
+use doc::Item;
+use doc::ItemUtils;
+
+use core::*;
+
+pub mod pass;
+pub mod config;
+pub mod parse;
+pub mod extract;
+pub mod attr_parser;
+pub mod doc;
+pub mod markdown_index_pass;
+pub mod markdown_pass;
+pub mod markdown_writer;
+pub mod fold;
+pub mod path_pass;
+pub mod attr_pass;
+pub mod tystr_pass;
+pub mod prune_hidden_pass;
+pub mod desc_to_brief_pass;
+pub mod text_pass;
+pub mod unindent_pass;
+pub mod trim_pass;
+pub mod astsrv;
+pub mod demo;
+pub mod sort_pass;
+pub mod sort_item_name_pass;
+pub mod sort_item_type_pass;
+pub mod page_pass;
+pub mod sectionalize_pass;
+pub mod escape_pass;
+pub mod prune_private_pass;
+pub mod util;
+
+mod std {
+    pub use core::clone;
+    pub use core::cmp;
+    pub use core::os;
+    pub use core::str;
+    pub use core::sys;
+    pub use core::unstable;
+}
+
+pub fn main() {
+    let args = os::args();
+
+    if args.iter().any_(|x| "-h" == *x) || args.iter().any_(|x| "--help" == *x) {
+        config::usage();
+        return;
+    }
+
+    let config = match config::parse_config(args) {
+      Ok(config) => config,
+      Err(err) => {
+        io::println(fmt!("error: %s", err));
+        return;
+      }
+    };
+
+    run(config);
+}
+
+/// Runs rustdoc over the given file
+fn run(config: Config) {
+
+    let source_file = copy config.input_crate;
+
+    // Create an AST service from the source code
+    do astsrv::from_file(source_file.to_str()) |srv| {
+
+        // Just time how long it takes for the AST to become available
+        do time(~"wait_ast") {
+            do astsrv::exec(srv.clone()) |_ctxt| { }
+        };
+
+        // Extract the initial doc tree from the AST. This contains
+        // just names and node ids.
+        let doc = time(~"extract", || {
+            let default_name = copy source_file;
+            extract::from_srv(srv.clone(), default_name.to_str())
+        });
+
+        // Refine and publish the document
+        pass::run_passes(srv, doc, ~[
+            // Generate type and signature strings
+            tystr_pass::mk_pass(),
+            // Record the full paths to various nodes
+            path_pass::mk_pass(),
+            // Extract the docs attributes and attach them to doc nodes
+            attr_pass::mk_pass(),
+            // Perform various text escaping
+            escape_pass::mk_pass(),
+            // Remove things marked doc(hidden)
+            prune_hidden_pass::mk_pass(),
+            // Remove things that are private
+            prune_private_pass::mk_pass(),
+            // Extract brief documentation from the full descriptions
+            desc_to_brief_pass::mk_pass(),
+            // Massage the text to remove extra indentation
+            unindent_pass::mk_pass(),
+            // Split text into multiple sections according to headers
+            sectionalize_pass::mk_pass(),
+            // Trim extra spaces from text
+            trim_pass::mk_pass(),
+            // Sort items by name
+            sort_item_name_pass::mk_pass(),
+            // Sort items again by kind
+            sort_item_type_pass::mk_pass(),
+            // Create indexes appropriate for markdown
+            markdown_index_pass::mk_pass(copy config),
+            // Break the document into pages if required by the
+            // output format
+            page_pass::mk_pass(config.output_style),
+            // Render
+            markdown_pass::mk_pass(
+                markdown_writer::make_writer_factory(copy config)
+            )
+        ]);
+    }
+}
+
+pub fn time<T>(what: ~str, f: &fn() -> T) -> T {
+    let start = extra::time::precise_time_s();
+    let rv = f();
+    let end = extra::time::precise_time_s();
+    info!("time: %3.3f s    %s", end - start, what);
+    rv
+}
diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc
deleted file mode 100644 (file)
index 57a2a48..0000000
+++ /dev/null
@@ -1,665 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
- * rusti - A REPL using the JIT backend
- *
- * Rusti works by serializing state between lines of input. This means that each
- * line can be run in a separate task, and the only limiting factor is that all
- * local bound variables are encodable.
- *
- * This is accomplished by feeding in generated input to rustc for execution in
- * the JIT compiler. Currently input actually gets fed in three times to get
- * information about the program.
- *
- * - Pass #1
- *   In this pass, the input is simply thrown at the parser and the input comes
- *   back. This validates the structure of the program, and at this stage the
- *   global items (fns, structs, impls, traits, etc.) are filtered from the
- *   input into the "global namespace". These declarations shadow all previous
- *   declarations of an item by the same name.
- *
- * - Pass #2
- *   After items have been stripped, the remaining input is passed to rustc
- *   along with all local variables declared (initialized to nothing). This pass
- *   runs up to typechecking. From this, we can learn about the types of each
- *   bound variable, what variables are bound, and also ensure that all the
- *   types are encodable (the input can actually be run).
- *
- * - Pass #3
- *   Finally, a program is generated to deserialize the local variable state,
- *   run the code input, and then reserialize all bindings back into a local
- *   hash map. Once this code runs, the input has fully been run and the REPL
- *   waits for new input.
- *
- * Encoding/decoding is done with EBML, and there is simply a map of ~str ->
- * ~[u8] maintaining the values of each local binding (by name).
- */
-
-#[link(name = "rusti",
-       vers = "0.7-pre",
-       uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc",
-       url = "https://github.com/mozilla/rust/tree/master/src/rusti")];
-
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-extern mod extra;
-extern mod rustc;
-extern mod syntax;
-
-use std::{libc, io, os, task, vec};
-use std::cell::Cell;
-use extra::rl;
-
-use rustc::driver::{driver, session};
-use syntax::{ast, diagnostic};
-use syntax::ast_util::*;
-use syntax::parse::token;
-use syntax::print::pprust;
-
-use program::Program;
-use utils::*;
-
-mod program;
-pub mod utils;
-
-/**
- * A structure shared across REPL instances for storing history
- * such as statements and view items. I wish the AST was sendable.
- */
-pub struct Repl {
-    prompt: ~str,
-    binary: ~str,
-    running: bool,
-    lib_search_paths: ~[~str],
-
-    program: Program,
-}
-
-// Action to do after reading a :command
-enum CmdAction {
-    action_none,
-    action_run_line(~str),
-}
-
-/// Run an input string in a Repl, returning the new Repl.
-fn run(mut repl: Repl, input: ~str) -> Repl {
-    // Build some necessary rustc boilerplate for compiling things
-    let binary = repl.binary.to_managed();
-    let options = @session::options {
-        crate_type: session::unknown_crate,
-        binary: binary,
-        addl_lib_search_paths: @mut repl.lib_search_paths.map(|p| Path(*p)),
-        jit: true,
-        .. copy *session::basic_options()
-    };
-    // Because we assume that everything is encodable (and assert so), add some
-    // extra helpful information if the error crops up. Otherwise people are
-    // bound to be very confused when they find out code is running that they
-    // never typed in...
-    let sess = driver::build_session(options, |cm, msg, lvl| {
-        diagnostic::emit(cm, msg, lvl);
-        if msg.contains("failed to find an implementation of trait") &&
-           msg.contains("extra::serialize::Encodable") {
-            diagnostic::emit(cm,
-                             "Currrently rusti serializes bound locals between \
-                              different lines of input. This means that all \
-                              values of local variables need to be encodable, \
-                              and this type isn't encodable",
-                             diagnostic::note);
-        }
-    });
-    let intr = token::get_ident_interner();
-
-    //
-    // Stage 1: parse the input and filter it into the program (as necessary)
-    //
-    debug!("parsing: %s", input);
-    let crate = parse_input(sess, binary, input);
-    let mut to_run = ~[];       // statements to run (emitted back into code)
-    let new_locals = @mut ~[];  // new locals being defined
-    let mut result = None;      // resultant expression (to print via pp)
-    do find_main(crate, sess) |blk| {
-        // Fish out all the view items, be sure to record 'extern mod' items
-        // differently beause they must appear before all 'use' statements
-        for blk.node.view_items.iter().advance |vi| {
-            let s = do with_pp(intr) |pp, _| {
-                pprust::print_view_item(pp, *vi);
-            };
-            match vi.node {
-                ast::view_item_extern_mod(*) => {
-                    repl.program.record_extern(s);
-                }
-                ast::view_item_use(*) => { repl.program.record_view_item(s); }
-            }
-        }
-
-        // Iterate through all of the block's statements, inserting them into
-        // the correct portions of the program
-        for blk.node.stmts.iter().advance |stmt| {
-            let s = do with_pp(intr) |pp, _| { pprust::print_stmt(pp, *stmt); };
-            match stmt.node {
-                ast::stmt_decl(d, _) => {
-                    match d.node {
-                        ast::decl_item(it) => {
-                            let name = sess.str_of(it.ident);
-                            match it.node {
-                                // Structs are treated specially because to make
-                                // them at all usable they need to be decorated
-                                // with #[deriving(Encoable, Decodable)]
-                                ast::item_struct(*) => {
-                                    repl.program.record_struct(name, s);
-                                }
-                                // Item declarations are hoisted out of main()
-                                _ => { repl.program.record_item(name, s); }
-                            }
-                        }
-
-                        // Local declarations must be specially dealt with,
-                        // record all local declarations for use later on
-                        ast::decl_local(l) => {
-                            let mutbl = l.node.is_mutbl;
-                            do each_binding(l) |path, _| {
-                                let s = do with_pp(intr) |pp, _| {
-                                    pprust::print_path(pp, path, false);
-                                };
-                                new_locals.push((s, mutbl));
-                            }
-                            to_run.push(s);
-                        }
-                    }
-                }
-
-                // run statements with expressions (they have effects)
-                ast::stmt_mac(*) | ast::stmt_semi(*) | ast::stmt_expr(*) => {
-                    to_run.push(s);
-                }
-            }
-        }
-        result = do blk.node.expr.map_consume |e| {
-            do with_pp(intr) |pp, _| { pprust::print_expr(pp, e); }
-        };
-    }
-    // return fast for empty inputs
-    if to_run.len() == 0 && result.is_none() {
-        return repl;
-    }
-
-    //
-    // Stage 2: run everything up to typeck to learn the types of the new
-    //          variables introduced into the program
-    //
-    info!("Learning about the new types in the program");
-    repl.program.set_cache(); // before register_new_vars (which changes them)
-    let input = to_run.connect("\n");
-    let test = repl.program.test_code(input, &result, *new_locals);
-    debug!("testing with ^^^^^^ %?", (||{ println(test) })());
-    let dinput = driver::str_input(test.to_managed());
-    let cfg = driver::build_configuration(sess, binary, &dinput);
-    let outputs = driver::build_output_filenames(&dinput, &None, &None, [], sess);
-    let (crate, tcx) = driver::compile_upto(sess, copy cfg, &dinput,
-                                            driver::cu_typeck, Some(outputs));
-    // Once we're typechecked, record the types of all local variables defined
-    // in this input
-    do find_main(crate.expect("crate after cu_typeck"), sess) |blk| {
-        repl.program.register_new_vars(blk, tcx.expect("tcx after cu_typeck"));
-    }
-
-    //
-    // Stage 3: Actually run the code in the JIT
-    //
-    info!("actually running code");
-    let code = repl.program.code(input, &result);
-    debug!("actually running ^^^^^^ %?", (||{ println(code) })());
-    let input = driver::str_input(code.to_managed());
-    let cfg = driver::build_configuration(sess, binary, &input);
-    let outputs = driver::build_output_filenames(&input, &None, &None, [], sess);
-    let sess = driver::build_session(options, diagnostic::emit);
-    driver::compile_upto(sess, cfg, &input, driver::cu_everything,
-                         Some(outputs));
-
-    //
-    // Stage 4: Inform the program that computation is done so it can update all
-    //          local variable bindings.
-    //
-    info!("cleaning up after code");
-    repl.program.consume_cache();
-
-    return repl;
-
-    fn parse_input(sess: session::Session, binary: @str,
-                   input: &str) -> @ast::crate {
-        let code = fmt!("fn main() {\n %s \n}", input);
-        let input = driver::str_input(code.to_managed());
-        let cfg = driver::build_configuration(sess, binary, &input);
-        let outputs = driver::build_output_filenames(&input, &None, &None, [], sess);
-        let (crate, _) = driver::compile_upto(sess, cfg, &input,
-                                              driver::cu_parse, Some(outputs));
-        crate.expect("parsing should return a crate")
-    }
-
-    fn find_main(crate: @ast::crate, sess: session::Session,
-                 f: &fn(&ast::blk)) {
-        for crate.node.module.items.iter().advance |item| {
-            match item.node {
-                ast::item_fn(_, _, _, _, ref blk) => {
-                    if item.ident == sess.ident_of("main") {
-                        return f(blk);
-                    }
-                }
-                _ => {}
-            }
-        }
-        fail!("main function was expected somewhere...");
-    }
-}
-
-// Compiles a crate given by the filename as a library if the compiled
-// version doesn't exist or is older than the source file. Binary is
-// the name of the compiling executable. Returns Some(true) if it
-// successfully compiled, Some(false) if the crate wasn't compiled
-// because it already exists and is newer than the source file, or
-// None if there were compile errors.
-fn compile_crate(src_filename: ~str, binary: ~str) -> Option<bool> {
-    match do task::try {
-        let src_path = Path(src_filename);
-        let binary = binary.to_managed();
-        let options = @session::options {
-            binary: binary,
-            addl_lib_search_paths: @mut ~[os::getcwd()],
-            .. copy *session::basic_options()
-        };
-        let input = driver::file_input(copy src_path);
-        let sess = driver::build_session(options, diagnostic::emit);
-        *sess.building_library = true;
-        let cfg = driver::build_configuration(sess, binary, &input);
-        let outputs = driver::build_output_filenames(
-            &input, &None, &None, [], sess);
-        // If the library already exists and is newer than the source
-        // file, skip compilation and return None.
-        let mut should_compile = true;
-        let dir = os::list_dir_path(&Path(outputs.out_filename.dirname()));
-        let maybe_lib_path = do dir.iter().find_ |file| {
-            // The actual file's name has a hash value and version
-            // number in it which is unknown at this time, so looking
-            // for a file that matches out_filename won't work,
-            // instead we guess which file is the library by matching
-            // the prefix and suffix of out_filename to files in the
-            // directory.
-            let file_str = file.filename().get();
-            file_str.starts_with(outputs.out_filename.filestem().get())
-                && file_str.ends_with(outputs.out_filename.filetype().get())
-        };
-        match maybe_lib_path {
-            Some(lib_path) => {
-                let (src_mtime, _) = src_path.get_mtime().get();
-                let (lib_mtime, _) = lib_path.get_mtime().get();
-                if lib_mtime >= src_mtime {
-                    should_compile = false;
-                }
-            },
-            None => { },
-        }
-        if (should_compile) {
-            println(fmt!("compiling %s...", src_filename));
-            driver::compile_upto(sess, cfg, &input, driver::cu_everything,
-                                 Some(outputs));
-            true
-        } else { false }
-    } {
-        Ok(true) => Some(true),
-        Ok(false) => Some(false),
-        Err(_) => None,
-    }
-}
-
-/// Tries to get a line from rl after outputting a prompt. Returns
-/// None if no input was read (e.g. EOF was reached).
-fn get_line(use_rl: bool, prompt: &str) -> Option<~str> {
-    if use_rl {
-        let result = unsafe { rl::read(prompt) };
-
-        match result {
-            None => None,
-            Some(line) => {
-                unsafe { rl::add_history(line) };
-                Some(line)
-            }
-        }
-    } else {
-        if io::stdin().eof() {
-            None
-        } else {
-            Some(io::stdin().read_line())
-        }
-    }
-}
-
-/// Run a command, e.g. :clear, :exit, etc.
-fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer,
-           cmd: ~str, args: ~[~str], use_rl: bool) -> CmdAction {
-    let mut action = action_none;
-    match cmd {
-        ~"exit" => repl.running = false,
-        ~"clear" => {
-            repl.program.clear();
-
-            // XXX: Win32 version of linenoise can't do this
-            //rl::clear();
-        }
-        ~"help" => {
-            println(
-                ":{\\n ..lines.. \\n:}\\n - execute multiline command\n\
-                 :load <crate> ... - loads given crates as dynamic libraries\n\
-                 :clear - clear the bindings\n\
-                 :exit - exit from the repl\n\
-                 :help - show this message");
-        }
-        ~"load" => {
-            let mut loaded_crates: ~[~str] = ~[];
-            for args.iter().advance |arg| {
-                let (crate, filename) =
-                    if arg.ends_with(".rs") || arg.ends_with(".rc") {
-                    (arg.slice_to(arg.len() - 3).to_owned(), copy *arg)
-                } else {
-                    (copy *arg, *arg + ".rs")
-                };
-                match compile_crate(filename, copy repl.binary) {
-                    Some(_) => loaded_crates.push(crate),
-                    None => { }
-                }
-            }
-            for loaded_crates.iter().advance |crate| {
-                let crate_path = Path(*crate);
-                let crate_dir = crate_path.dirname();
-                repl.program.record_extern(fmt!("extern mod %s;", *crate));
-                if !repl.lib_search_paths.iter().any_(|x| x == &crate_dir) {
-                    repl.lib_search_paths.push(crate_dir);
-                }
-            }
-            if loaded_crates.is_empty() {
-                println("no crates loaded");
-            } else {
-                println(fmt!("crates loaded: %s",
-                                 loaded_crates.connect(", ")));
-            }
-        }
-        ~"{" => {
-            let mut multiline_cmd = ~"";
-            let mut end_multiline = false;
-            while (!end_multiline) {
-                match get_line(use_rl, "rusti| ") {
-                    None => fail!("unterminated multiline command :{ .. :}"),
-                    Some(line) => {
-                        if line.trim() == ":}" {
-                            end_multiline = true;
-                        } else {
-                            multiline_cmd += line + "\n";
-                        }
-                    }
-                }
-            }
-            action = action_run_line(multiline_cmd);
-        }
-        _ => println(~"unknown cmd: " + cmd)
-    }
-    return action;
-}
-
-/// Executes a line of input, which may either be rust code or a
-/// :command. Returns a new Repl if it has changed.
-pub fn run_line(repl: &mut Repl, in: @io::Reader, out: @io::Writer, line: ~str,
-                use_rl: bool)
-    -> Option<Repl> {
-    if line.starts_with(":") {
-        // drop the : and the \n (one byte each)
-        let full = line.slice(1, line.len());
-        let split: ~[~str] = full.word_iter().transform(|s| s.to_owned()).collect();
-        let len = split.len();
-
-        if len > 0 {
-            let cmd = copy split[0];
-
-            if !cmd.is_empty() {
-                let args = if len > 1 {
-                    vec::slice(split, 1, len).to_owned()
-                } else { ~[] };
-
-                match run_cmd(repl, in, out, cmd, args, use_rl) {
-                    action_none => { }
-                    action_run_line(multiline_cmd) => {
-                        if !multiline_cmd.is_empty() {
-                            return run_line(repl, in, out, multiline_cmd, use_rl);
-                        }
-                    }
-                }
-                return None;
-            }
-        }
-    }
-
-    let line = Cell::new(line);
-    let r = Cell::new(copy *repl);
-    let result = do task::try {
-        run(r.take(), line.take())
-    };
-
-    if result.is_ok() {
-        return Some(result.get());
-    }
-    return None;
-}
-
-pub fn main() {
-    let args = os::args();
-    let in = io::stdin();
-    let out = io::stdout();
-    let mut repl = Repl {
-        prompt: ~"rusti> ",
-        binary: copy args[0],
-        running: true,
-        lib_search_paths: ~[],
-
-        program: Program::new(),
-    };
-
-    let istty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0;
-
-    // only print this stuff if the user is actually typing into rusti
-    if istty {
-        println("WARNING: The Rust REPL is experimental and may be");
-        println("unstable. If you encounter problems, please use the");
-        println("compiler instead. Type :help for help.");
-
-        unsafe {
-            do rl::complete |line, suggest| {
-                if line.starts_with(":") {
-                    suggest(~":clear");
-                    suggest(~":exit");
-                    suggest(~":help");
-                    suggest(~":load");
-                }
-            }
-        }
-    }
-
-    while repl.running {
-        match get_line(istty, repl.prompt) {
-            None => break,
-            Some(line) => {
-                if line.is_empty() {
-                    if istty {
-                        println("()");
-                    }
-                    loop;
-                }
-                match run_line(&mut repl, in, out, line, istty) {
-                    Some(new_repl) => repl = new_repl,
-                    None => { }
-                }
-            }
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use std::io;
-    use std::iterator::IteratorUtil;
-    use program::Program;
-    use super::*;
-
-    fn repl() -> Repl {
-        Repl {
-            prompt: ~"rusti> ",
-            binary: ~"rusti",
-            running: true,
-            lib_search_paths: ~[],
-            program: Program::new(),
-        }
-    }
-
-    fn run_program(prog: &str) {
-        let mut r = repl();
-        for prog.split_iter('\n').advance |cmd| {
-            let result = run_line(&mut r, io::stdin(), io::stdout(),
-                                  cmd.to_owned(), false);
-            r = result.expect(fmt!("the command '%s' failed", cmd));
-        }
-    }
-
-    #[test]
-    // FIXME: #7220 rusti on 32bit mac doesn't work.
-    #[cfg(not(target_word_size="32",
-              target_os="macos"))]
-    fn run_all() {
-        // FIXME(#7071):
-        // By default, unit tests are run in parallel. Rusti, on the other hand,
-        // does not enjoy doing this. I suspect that it is because the LLVM
-        // bindings are not thread-safe (when running parallel tests, some tests
-        // were triggering assertions in LLVM (or segfaults). Hence, this
-        // function exists to run everything serially (sadface).
-        //
-        // To get some interesting output, run with RUST_LOG=rusti::tests
-
-        debug!("hopefully this runs");
-        run_program("");
-
-        debug!("regression test for #5937");
-        run_program("use std::hashmap;");
-
-        debug!("regression test for #5784");
-        run_program("let a = 3;");
-
-        // XXX: can't spawn new tasks because the JIT code is cleaned up
-        //      after the main function is done.
-        // debug!("regression test for #5803");
-        // run_program("
-        //     spawn( || println(\"Please don't segfault\") );
-        //     do spawn { println(\"Please?\"); }
-        // ");
-
-        debug!("inferred integers are usable");
-        run_program("let a = 2;\n()\n");
-        run_program("
-            let a = 3;
-            let b = 4u;
-            assert!((a as uint) + b == 7)
-        ");
-
-        debug!("local variables can be shadowed");
-        run_program("
-            let a = 3;
-            let a = 5;
-            assert!(a == 5)
-        ");
-
-        debug!("strings are usable");
-        run_program("
-            let a = ~\"\";
-            let b = \"\";
-            let c = @\"\";
-            let d = a + b + c;
-            assert!(d.len() == 0);
-        ");
-
-        debug!("vectors are usable");
-        run_program("
-            let a = ~[1, 2, 3];
-            let b = &[1, 2, 3];
-            let c = @[1, 2, 3];
-            let d = a + b + c;
-            assert!(d.len() == 9);
-            let e: &[int] = [];
-        ");
-
-        debug!("structs are usable");
-        run_program("
-            struct A{ a: int }
-            let b = A{ a: 3 };
-            assert!(b.a == 3)
-        ");
-
-        debug!("mutable variables");
-        run_program("
-            let mut a = 3;
-            a = 5;
-            let mut b = std::hashmap::HashSet::new::<int>();
-            b.insert(a);
-            assert!(b.contains(&5))
-            assert!(b.len() == 1)
-        ");
-
-        debug!("functions are cached");
-        run_program("
-            fn fib(x: int) -> int { if x < 2 {x} else { fib(x - 1) + fib(x - 2) } }
-            let a = fib(3);
-            let a = a + fib(4);
-            assert!(a == 5)
-        ");
-
-        debug!("modules are cached");
-        run_program("
-            mod b { pub fn foo() -> uint { 3 } }
-            assert!(b::foo() == 3)
-        ");
-
-        debug!("multiple function definitions are allowed");
-        run_program("
-            fn f() {}
-            fn f() {}
-            f()
-        ");
-
-        debug!("multiple item definitions are allowed");
-        run_program("
-            fn f() {}
-            mod f {}
-            struct f;
-            enum f {}
-            fn f() {}
-            f()
-        ");
-    }
-
-    #[test]
-    // FIXME: #7220 rusti on 32bit mac doesn't work.
-    #[cfg(not(target_word_size="32",
-              target_os="macos"))]
-    fn exit_quits() {
-        let mut r = repl();
-        assert!(r.running);
-        let result = run_line(&mut r, io::stdin(), io::stdout(),
-                              ~":exit", false);
-        assert!(result.is_none());
-        assert!(!r.running);
-    }
-}
diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs
new file mode 100644 (file)
index 0000000..57a2a48
--- /dev/null
@@ -0,0 +1,665 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+ * rusti - A REPL using the JIT backend
+ *
+ * Rusti works by serializing state between lines of input. This means that each
+ * line can be run in a separate task, and the only limiting factor is that all
+ * local bound variables are encodable.
+ *
+ * This is accomplished by feeding in generated input to rustc for execution in
+ * the JIT compiler. Currently input actually gets fed in three times to get
+ * information about the program.
+ *
+ * - Pass #1
+ *   In this pass, the input is simply thrown at the parser and the input comes
+ *   back. This validates the structure of the program, and at this stage the
+ *   global items (fns, structs, impls, traits, etc.) are filtered from the
+ *   input into the "global namespace". These declarations shadow all previous
+ *   declarations of an item by the same name.
+ *
+ * - Pass #2
+ *   After items have been stripped, the remaining input is passed to rustc
+ *   along with all local variables declared (initialized to nothing). This pass
+ *   runs up to typechecking. From this, we can learn about the types of each
+ *   bound variable, what variables are bound, and also ensure that all the
+ *   types are encodable (the input can actually be run).
+ *
+ * - Pass #3
+ *   Finally, a program is generated to deserialize the local variable state,
+ *   run the code input, and then reserialize all bindings back into a local
+ *   hash map. Once this code runs, the input has fully been run and the REPL
+ *   waits for new input.
+ *
+ * Encoding/decoding is done with EBML, and there is simply a map of ~str ->
+ * ~[u8] maintaining the values of each local binding (by name).
+ */
+
+#[link(name = "rusti",
+       vers = "0.7-pre",
+       uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc",
+       url = "https://github.com/mozilla/rust/tree/master/src/rusti")];
+
+#[license = "MIT/ASL2"];
+#[crate_type = "lib"];
+
+extern mod extra;
+extern mod rustc;
+extern mod syntax;
+
+use std::{libc, io, os, task, vec};
+use std::cell::Cell;
+use extra::rl;
+
+use rustc::driver::{driver, session};
+use syntax::{ast, diagnostic};
+use syntax::ast_util::*;
+use syntax::parse::token;
+use syntax::print::pprust;
+
+use program::Program;
+use utils::*;
+
+mod program;
+pub mod utils;
+
+/**
+ * A structure shared across REPL instances for storing history
+ * such as statements and view items. I wish the AST was sendable.
+ */
+pub struct Repl {
+    prompt: ~str,
+    binary: ~str,
+    running: bool,
+    lib_search_paths: ~[~str],
+
+    program: Program,
+}
+
+// Action to do after reading a :command
+enum CmdAction {
+    action_none,
+    action_run_line(~str),
+}
+
+/// Run an input string in a Repl, returning the new Repl.
+fn run(mut repl: Repl, input: ~str) -> Repl {
+    // Build some necessary rustc boilerplate for compiling things
+    let binary = repl.binary.to_managed();
+    let options = @session::options {
+        crate_type: session::unknown_crate,
+        binary: binary,
+        addl_lib_search_paths: @mut repl.lib_search_paths.map(|p| Path(*p)),
+        jit: true,
+        .. copy *session::basic_options()
+    };
+    // Because we assume that everything is encodable (and assert so), add some
+    // extra helpful information if the error crops up. Otherwise people are
+    // bound to be very confused when they find out code is running that they
+    // never typed in...
+    let sess = driver::build_session(options, |cm, msg, lvl| {
+        diagnostic::emit(cm, msg, lvl);
+        if msg.contains("failed to find an implementation of trait") &&
+           msg.contains("extra::serialize::Encodable") {
+            diagnostic::emit(cm,
+                             "Currrently rusti serializes bound locals between \
+                              different lines of input. This means that all \
+                              values of local variables need to be encodable, \
+                              and this type isn't encodable",
+                             diagnostic::note);
+        }
+    });
+    let intr = token::get_ident_interner();
+
+    //
+    // Stage 1: parse the input and filter it into the program (as necessary)
+    //
+    debug!("parsing: %s", input);
+    let crate = parse_input(sess, binary, input);
+    let mut to_run = ~[];       // statements to run (emitted back into code)
+    let new_locals = @mut ~[];  // new locals being defined
+    let mut result = None;      // resultant expression (to print via pp)
+    do find_main(crate, sess) |blk| {
+        // Fish out all the view items, be sure to record 'extern mod' items
+        // differently beause they must appear before all 'use' statements
+        for blk.node.view_items.iter().advance |vi| {
+            let s = do with_pp(intr) |pp, _| {
+                pprust::print_view_item(pp, *vi);
+            };
+            match vi.node {
+                ast::view_item_extern_mod(*) => {
+                    repl.program.record_extern(s);
+                }
+                ast::view_item_use(*) => { repl.program.record_view_item(s); }
+            }
+        }
+
+        // Iterate through all of the block's statements, inserting them into
+        // the correct portions of the program
+        for blk.node.stmts.iter().advance |stmt| {
+            let s = do with_pp(intr) |pp, _| { pprust::print_stmt(pp, *stmt); };
+            match stmt.node {
+                ast::stmt_decl(d, _) => {
+                    match d.node {
+                        ast::decl_item(it) => {
+                            let name = sess.str_of(it.ident);
+                            match it.node {
+                                // Structs are treated specially because to make
+                                // them at all usable they need to be decorated
+                                // with #[deriving(Encoable, Decodable)]
+                                ast::item_struct(*) => {
+                                    repl.program.record_struct(name, s);
+                                }
+                                // Item declarations are hoisted out of main()
+                                _ => { repl.program.record_item(name, s); }
+                            }
+                        }
+
+                        // Local declarations must be specially dealt with,
+                        // record all local declarations for use later on
+                        ast::decl_local(l) => {
+                            let mutbl = l.node.is_mutbl;
+                            do each_binding(l) |path, _| {
+                                let s = do with_pp(intr) |pp, _| {
+                                    pprust::print_path(pp, path, false);
+                                };
+                                new_locals.push((s, mutbl));
+                            }
+                            to_run.push(s);
+                        }
+                    }
+                }
+
+                // run statements with expressions (they have effects)
+                ast::stmt_mac(*) | ast::stmt_semi(*) | ast::stmt_expr(*) => {
+                    to_run.push(s);
+                }
+            }
+        }
+        result = do blk.node.expr.map_consume |e| {
+            do with_pp(intr) |pp, _| { pprust::print_expr(pp, e); }
+        };
+    }
+    // return fast for empty inputs
+    if to_run.len() == 0 && result.is_none() {
+        return repl;
+    }
+
+    //
+    // Stage 2: run everything up to typeck to learn the types of the new
+    //          variables introduced into the program
+    //
+    info!("Learning about the new types in the program");
+    repl.program.set_cache(); // before register_new_vars (which changes them)
+    let input = to_run.connect("\n");
+    let test = repl.program.test_code(input, &result, *new_locals);
+    debug!("testing with ^^^^^^ %?", (||{ println(test) })());
+    let dinput = driver::str_input(test.to_managed());
+    let cfg = driver::build_configuration(sess, binary, &dinput);
+    let outputs = driver::build_output_filenames(&dinput, &None, &None, [], sess);
+    let (crate, tcx) = driver::compile_upto(sess, copy cfg, &dinput,
+                                            driver::cu_typeck, Some(outputs));
+    // Once we're typechecked, record the types of all local variables defined
+    // in this input
+    do find_main(crate.expect("crate after cu_typeck"), sess) |blk| {
+        repl.program.register_new_vars(blk, tcx.expect("tcx after cu_typeck"));
+    }
+
+    //
+    // Stage 3: Actually run the code in the JIT
+    //
+    info!("actually running code");
+    let code = repl.program.code(input, &result);
+    debug!("actually running ^^^^^^ %?", (||{ println(code) })());
+    let input = driver::str_input(code.to_managed());
+    let cfg = driver::build_configuration(sess, binary, &input);
+    let outputs = driver::build_output_filenames(&input, &None, &None, [], sess);
+    let sess = driver::build_session(options, diagnostic::emit);
+    driver::compile_upto(sess, cfg, &input, driver::cu_everything,
+                         Some(outputs));
+
+    //
+    // Stage 4: Inform the program that computation is done so it can update all
+    //          local variable bindings.
+    //
+    info!("cleaning up after code");
+    repl.program.consume_cache();
+
+    return repl;
+
+    fn parse_input(sess: session::Session, binary: @str,
+                   input: &str) -> @ast::crate {
+        let code = fmt!("fn main() {\n %s \n}", input);
+        let input = driver::str_input(code.to_managed());
+        let cfg = driver::build_configuration(sess, binary, &input);
+        let outputs = driver::build_output_filenames(&input, &None, &None, [], sess);
+        let (crate, _) = driver::compile_upto(sess, cfg, &input,
+                                              driver::cu_parse, Some(outputs));
+        crate.expect("parsing should return a crate")
+    }
+
+    fn find_main(crate: @ast::crate, sess: session::Session,
+                 f: &fn(&ast::blk)) {
+        for crate.node.module.items.iter().advance |item| {
+            match item.node {
+                ast::item_fn(_, _, _, _, ref blk) => {
+                    if item.ident == sess.ident_of("main") {
+                        return f(blk);
+                    }
+                }
+                _ => {}
+            }
+        }
+        fail!("main function was expected somewhere...");
+    }
+}
+
+// Compiles a crate given by the filename as a library if the compiled
+// version doesn't exist or is older than the source file. Binary is
+// the name of the compiling executable. Returns Some(true) if it
+// successfully compiled, Some(false) if the crate wasn't compiled
+// because it already exists and is newer than the source file, or
+// None if there were compile errors.
+fn compile_crate(src_filename: ~str, binary: ~str) -> Option<bool> {
+    match do task::try {
+        let src_path = Path(src_filename);
+        let binary = binary.to_managed();
+        let options = @session::options {
+            binary: binary,
+            addl_lib_search_paths: @mut ~[os::getcwd()],
+            .. copy *session::basic_options()
+        };
+        let input = driver::file_input(copy src_path);
+        let sess = driver::build_session(options, diagnostic::emit);
+        *sess.building_library = true;
+        let cfg = driver::build_configuration(sess, binary, &input);
+        let outputs = driver::build_output_filenames(
+            &input, &None, &None, [], sess);
+        // If the library already exists and is newer than the source
+        // file, skip compilation and return None.
+        let mut should_compile = true;
+        let dir = os::list_dir_path(&Path(outputs.out_filename.dirname()));
+        let maybe_lib_path = do dir.iter().find_ |file| {
+            // The actual file's name has a hash value and version
+            // number in it which is unknown at this time, so looking
+            // for a file that matches out_filename won't work,
+            // instead we guess which file is the library by matching
+            // the prefix and suffix of out_filename to files in the
+            // directory.
+            let file_str = file.filename().get();
+            file_str.starts_with(outputs.out_filename.filestem().get())
+                && file_str.ends_with(outputs.out_filename.filetype().get())
+        };
+        match maybe_lib_path {
+            Some(lib_path) => {
+                let (src_mtime, _) = src_path.get_mtime().get();
+                let (lib_mtime, _) = lib_path.get_mtime().get();
+                if lib_mtime >= src_mtime {
+                    should_compile = false;
+                }
+            },
+            None => { },
+        }
+        if (should_compile) {
+            println(fmt!("compiling %s...", src_filename));
+            driver::compile_upto(sess, cfg, &input, driver::cu_everything,
+                                 Some(outputs));
+            true
+        } else { false }
+    } {
+        Ok(true) => Some(true),
+        Ok(false) => Some(false),
+        Err(_) => None,
+    }
+}
+
+/// Tries to get a line from rl after outputting a prompt. Returns
+/// None if no input was read (e.g. EOF was reached).
+fn get_line(use_rl: bool, prompt: &str) -> Option<~str> {
+    if use_rl {
+        let result = unsafe { rl::read(prompt) };
+
+        match result {
+            None => None,
+            Some(line) => {
+                unsafe { rl::add_history(line) };
+                Some(line)
+            }
+        }
+    } else {
+        if io::stdin().eof() {
+            None
+        } else {
+            Some(io::stdin().read_line())
+        }
+    }
+}
+
+/// Run a command, e.g. :clear, :exit, etc.
+fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer,
+           cmd: ~str, args: ~[~str], use_rl: bool) -> CmdAction {
+    let mut action = action_none;
+    match cmd {
+        ~"exit" => repl.running = false,
+        ~"clear" => {
+            repl.program.clear();
+
+            // XXX: Win32 version of linenoise can't do this
+            //rl::clear();
+        }
+        ~"help" => {
+            println(
+                ":{\\n ..lines.. \\n:}\\n - execute multiline command\n\
+                 :load <crate> ... - loads given crates as dynamic libraries\n\
+                 :clear - clear the bindings\n\
+                 :exit - exit from the repl\n\
+                 :help - show this message");
+        }
+        ~"load" => {
+            let mut loaded_crates: ~[~str] = ~[];
+            for args.iter().advance |arg| {
+                let (crate, filename) =
+                    if arg.ends_with(".rs") || arg.ends_with(".rc") {
+                    (arg.slice_to(arg.len() - 3).to_owned(), copy *arg)
+                } else {
+                    (copy *arg, *arg + ".rs")
+                };
+                match compile_crate(filename, copy repl.binary) {
+                    Some(_) => loaded_crates.push(crate),
+                    None => { }
+                }
+            }
+            for loaded_crates.iter().advance |crate| {
+                let crate_path = Path(*crate);
+                let crate_dir = crate_path.dirname();
+                repl.program.record_extern(fmt!("extern mod %s;", *crate));
+                if !repl.lib_search_paths.iter().any_(|x| x == &crate_dir) {
+                    repl.lib_search_paths.push(crate_dir);
+                }
+            }
+            if loaded_crates.is_empty() {
+                println("no crates loaded");
+            } else {
+                println(fmt!("crates loaded: %s",
+                                 loaded_crates.connect(", ")));
+            }
+        }
+        ~"{" => {
+            let mut multiline_cmd = ~"";
+            let mut end_multiline = false;
+            while (!end_multiline) {
+                match get_line(use_rl, "rusti| ") {
+                    None => fail!("unterminated multiline command :{ .. :}"),
+                    Some(line) => {
+                        if line.trim() == ":}" {
+                            end_multiline = true;
+                        } else {
+                            multiline_cmd += line + "\n";
+                        }
+                    }
+                }
+            }
+            action = action_run_line(multiline_cmd);
+        }
+        _ => println(~"unknown cmd: " + cmd)
+    }
+    return action;
+}
+
+/// Executes a line of input, which may either be rust code or a
+/// :command. Returns a new Repl if it has changed.
+pub fn run_line(repl: &mut Repl, in: @io::Reader, out: @io::Writer, line: ~str,
+                use_rl: bool)
+    -> Option<Repl> {
+    if line.starts_with(":") {
+        // drop the : and the \n (one byte each)
+        let full = line.slice(1, line.len());
+        let split: ~[~str] = full.word_iter().transform(|s| s.to_owned()).collect();
+        let len = split.len();
+
+        if len > 0 {
+            let cmd = copy split[0];
+
+            if !cmd.is_empty() {
+                let args = if len > 1 {
+                    vec::slice(split, 1, len).to_owned()
+                } else { ~[] };
+
+                match run_cmd(repl, in, out, cmd, args, use_rl) {
+                    action_none => { }
+                    action_run_line(multiline_cmd) => {
+                        if !multiline_cmd.is_empty() {
+                            return run_line(repl, in, out, multiline_cmd, use_rl);
+                        }
+                    }
+                }
+                return None;
+            }
+        }
+    }
+
+    let line = Cell::new(line);
+    let r = Cell::new(copy *repl);
+    let result = do task::try {
+        run(r.take(), line.take())
+    };
+
+    if result.is_ok() {
+        return Some(result.get());
+    }
+    return None;
+}
+
+pub fn main() {
+    let args = os::args();
+    let in = io::stdin();
+    let out = io::stdout();
+    let mut repl = Repl {
+        prompt: ~"rusti> ",
+        binary: copy args[0],
+        running: true,
+        lib_search_paths: ~[],
+
+        program: Program::new(),
+    };
+
+    let istty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0;
+
+    // only print this stuff if the user is actually typing into rusti
+    if istty {
+        println("WARNING: The Rust REPL is experimental and may be");
+        println("unstable. If you encounter problems, please use the");
+        println("compiler instead. Type :help for help.");
+
+        unsafe {
+            do rl::complete |line, suggest| {
+                if line.starts_with(":") {
+                    suggest(~":clear");
+                    suggest(~":exit");
+                    suggest(~":help");
+                    suggest(~":load");
+                }
+            }
+        }
+    }
+
+    while repl.running {
+        match get_line(istty, repl.prompt) {
+            None => break,
+            Some(line) => {
+                if line.is_empty() {
+                    if istty {
+                        println("()");
+                    }
+                    loop;
+                }
+                match run_line(&mut repl, in, out, line, istty) {
+                    Some(new_repl) => repl = new_repl,
+                    None => { }
+                }
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::io;
+    use std::iterator::IteratorUtil;
+    use program::Program;
+    use super::*;
+
+    fn repl() -> Repl {
+        Repl {
+            prompt: ~"rusti> ",
+            binary: ~"rusti",
+            running: true,
+            lib_search_paths: ~[],
+            program: Program::new(),
+        }
+    }
+
+    fn run_program(prog: &str) {
+        let mut r = repl();
+        for prog.split_iter('\n').advance |cmd| {
+            let result = run_line(&mut r, io::stdin(), io::stdout(),
+                                  cmd.to_owned(), false);
+            r = result.expect(fmt!("the command '%s' failed", cmd));
+        }
+    }
+
+    #[test]
+    // FIXME: #7220 rusti on 32bit mac doesn't work.
+    #[cfg(not(target_word_size="32",
+              target_os="macos"))]
+    fn run_all() {
+        // FIXME(#7071):
+        // By default, unit tests are run in parallel. Rusti, on the other hand,
+        // does not enjoy doing this. I suspect that it is because the LLVM
+        // bindings are not thread-safe (when running parallel tests, some tests
+        // were triggering assertions in LLVM (or segfaults). Hence, this
+        // function exists to run everything serially (sadface).
+        //
+        // To get some interesting output, run with RUST_LOG=rusti::tests
+
+        debug!("hopefully this runs");
+        run_program("");
+
+        debug!("regression test for #5937");
+        run_program("use std::hashmap;");
+
+        debug!("regression test for #5784");
+        run_program("let a = 3;");
+
+        // XXX: can't spawn new tasks because the JIT code is cleaned up
+        //      after the main function is done.
+        // debug!("regression test for #5803");
+        // run_program("
+        //     spawn( || println(\"Please don't segfault\") );
+        //     do spawn { println(\"Please?\"); }
+        // ");
+
+        debug!("inferred integers are usable");
+        run_program("let a = 2;\n()\n");
+        run_program("
+            let a = 3;
+            let b = 4u;
+            assert!((a as uint) + b == 7)
+        ");
+
+        debug!("local variables can be shadowed");
+        run_program("
+            let a = 3;
+            let a = 5;
+            assert!(a == 5)
+        ");
+
+        debug!("strings are usable");
+        run_program("
+            let a = ~\"\";
+            let b = \"\";
+            let c = @\"\";
+            let d = a + b + c;
+            assert!(d.len() == 0);
+        ");
+
+        debug!("vectors are usable");
+        run_program("
+            let a = ~[1, 2, 3];
+            let b = &[1, 2, 3];
+            let c = @[1, 2, 3];
+            let d = a + b + c;
+            assert!(d.len() == 9);
+            let e: &[int] = [];
+        ");
+
+        debug!("structs are usable");
+        run_program("
+            struct A{ a: int }
+            let b = A{ a: 3 };
+            assert!(b.a == 3)
+        ");
+
+        debug!("mutable variables");
+        run_program("
+            let mut a = 3;
+            a = 5;
+            let mut b = std::hashmap::HashSet::new::<int>();
+            b.insert(a);
+            assert!(b.contains(&5))
+            assert!(b.len() == 1)
+        ");
+
+        debug!("functions are cached");
+        run_program("
+            fn fib(x: int) -> int { if x < 2 {x} else { fib(x - 1) + fib(x - 2) } }
+            let a = fib(3);
+            let a = a + fib(4);
+            assert!(a == 5)
+        ");
+
+        debug!("modules are cached");
+        run_program("
+            mod b { pub fn foo() -> uint { 3 } }
+            assert!(b::foo() == 3)
+        ");
+
+        debug!("multiple function definitions are allowed");
+        run_program("
+            fn f() {}
+            fn f() {}
+            f()
+        ");
+
+        debug!("multiple item definitions are allowed");
+        run_program("
+            fn f() {}
+            mod f {}
+            struct f;
+            enum f {}
+            fn f() {}
+            f()
+        ");
+    }
+
+    #[test]
+    // FIXME: #7220 rusti on 32bit mac doesn't work.
+    #[cfg(not(target_word_size="32",
+              target_os="macos"))]
+    fn exit_quits() {
+        let mut r = repl();
+        assert!(r.running);
+        let result = run_line(&mut r, io::stdin(), io::stdout(),
+                              ~":exit", false);
+        assert!(result.is_none());
+        assert!(!r.running);
+    }
+}
diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc
deleted file mode 100644 (file)
index 9242e45..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// rustpkg - a package manager and build system for Rust
-
-#[link(name = "rustpkg",
-       vers = "0.7-pre",
-       uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf",
-       url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")];
-
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-#[no_core];
-#[no_std];
-
-extern mod core(name = "std");
-extern mod extra(name = "extra");
-
-extern mod rustc;
-extern mod syntax;
-
-use core::prelude::*;
-use core::*;
-pub use core::path::Path;
-use core::hashmap::HashMap;
-use rustc::driver::{driver, session};
-use rustc::metadata::filesearch;
-use extra::{getopts};
-use syntax::{ast, diagnostic};
-use util::*;
-use messages::*;
-use path_util::{build_pkg_id_in_workspace, first_pkgid_src_in_workspace};
-use path_util::{u_rwx, rust_path};
-use path_util::{built_executable_in_workspace, built_library_in_workspace};
-use path_util::{target_executable_in_workspace, target_library_in_workspace};
-use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces};
-use context::Ctx;
-use package_id::PkgId;
-use package_source::PkgSrc;
-
-mod conditions;
-mod context;
-mod crate;
-mod messages;
-mod package_id;
-mod package_path;
-mod package_source;
-mod path_util;
-mod search;
-mod target;
-#[cfg(test)]
-mod tests;
-mod util;
-mod version;
-mod workspace;
-
-pub mod usage;
-
-mod std {
-    pub use core::cmp;
-    pub use core::condition;
-    pub use core::os;
-    pub use core::str;
-    pub use core::sys;
-    pub use core::unstable;
-}
-
-/// A PkgScript represents user-supplied custom logic for
-/// special build hooks. This only exists for packages with
-/// an explicit package script.
-struct PkgScript<'self> {
-    /// Uniquely identifies this package
-    id: &'self PkgId,
-    // Used to have this field:    deps: ~[(~str, Option<~str>)]
-    // but I think it shouldn't be stored here
-    /// The contents of the package script: either a file path,
-    /// or a string containing the text of the input
-    input: driver::input,
-    /// The session to use *only* for compiling the custom
-    /// build script
-    sess: session::Session,
-    /// The config for compiling the custom build script
-    cfg: ast::crate_cfg,
-    /// The crate for the custom build script
-    crate: @ast::crate,
-    /// Directory in which to store build output
-    build_dir: Path
-}
-
-impl<'self> PkgScript<'self> {
-    /// Given the path name for a package script
-    /// and a package ID, parse the package script into
-    /// a PkgScript that we can then execute
-    fn parse<'a>(script: Path, workspace: &Path, id: &'a PkgId) -> PkgScript<'a> {
-        // Get the executable name that was invoked
-        let binary = os::args()[0].to_managed();
-        // Build the rustc session data structures to pass
-        // to the compiler
-        let options = @session::options {
-            binary: binary,
-            crate_type: session::bin_crate,
-            .. copy *session::basic_options()
-        };
-        let input = driver::file_input(script);
-        let sess = driver::build_session(options, diagnostic::emit);
-        let cfg = driver::build_configuration(sess, binary, &input);
-        let (crate, _) = driver::compile_upto(sess, copy cfg, &input, driver::cu_parse, None);
-        let work_dir = build_pkg_id_in_workspace(id, workspace);
-
-        debug!("Returning package script with id %?", id);
-
-        PkgScript {
-            id: id,
-            input: input,
-            sess: sess,
-            cfg: cfg,
-            crate: crate.unwrap(),
-            build_dir: work_dir
-        }
-    }
-
-    /// Run the contents of this package script, where <what>
-    /// is the command to pass to it (e.g., "build", "clean", "install")
-    /// Returns a pair of an exit code and list of configs (obtained by
-    /// calling the package script's configs() function if it exists
-    // FIXME (#4432): Use workcache to only compile the script when changed
-    fn run_custom(&self, what: ~str) -> (~[~str], ExitCode) {
-        debug!("run_custom: %s", what);
-        let sess = self.sess;
-
-        debug!("Working directory = %s", self.build_dir.to_str());
-        // Collect together any user-defined commands in the package script
-        let crate = util::ready_crate(sess, self.crate);
-        debug!("Building output filenames with script name %s",
-               driver::source_name(&self.input));
-        match filesearch::get_rustpkg_sysroot() {
-            Ok(r) => {
-                let root = r.pop().pop().pop().pop(); // :-\
-                debug!("Root is %s, calling compile_rest", root.to_str());
-                let exe = self.build_dir.push(~"pkg" + util::exe_suffix());
-                let binary = os::args()[0].to_managed();
-                util::compile_crate_from_input(&self.input,
-                                               &self.build_dir,
-                                               sess,
-                                               crate,
-                                               driver::build_configuration(sess,
-                                                                           binary, &self.input));
-                debug!("Running program: %s %s %s", exe.to_str(), root.to_str(), what);
-                let status = run::process_status(exe.to_str(), [root.to_str(), what]);
-                if status != 0 {
-                    return (~[], status);
-                }
-                else {
-                    debug!("Running program (configs): %s %s %s",
-                           exe.to_str(), root.to_str(), "configs");
-                    let output = run::process_output(exe.to_str(), [root.to_str(), ~"configs"]);
-                    // Run the configs() function to get the configs
-                    let cfgs = str::from_bytes_slice(output.output).word_iter()
-                        .transform(|w| w.to_owned()).collect();
-                    (cfgs, output.status)
-                }
-            }
-            Err(e) => {
-                fail!("Running package script, couldn't find rustpkg sysroot (%s)", e)
-            }
-        }
-    }
-
-    fn hash(&self) -> ~str {
-        self.id.hash()
-    }
-
-}
-
-impl Ctx {
-
-    fn run(&self, cmd: &str, args: ~[~str]) {
-        match cmd {
-            "build" => {
-                if args.len() < 1 {
-                    return usage::build();
-                }
-                // The package id is presumed to be the first command-line
-                // argument
-                let pkgid = PkgId::new(copy args[0]);
-                for each_pkg_parent_workspace(&pkgid) |workspace| {
-                    self.build(workspace, &pkgid);
-                }
-            }
-            "clean" => {
-                if args.len() < 1 {
-                    return usage::build();
-                }
-                // The package id is presumed to be the first command-line
-                // argument
-                let pkgid = PkgId::new(copy args[0]);
-                let cwd = os::getcwd();
-                self.clean(&cwd, &pkgid); // tjc: should use workspace, not cwd
-            }
-            "do" => {
-                if args.len() < 2 {
-                    return usage::do_cmd();
-                }
-
-                self.do_cmd(copy args[0], copy args[1]);
-            }
-            "info" => {
-                self.info();
-            }
-            "install" => {
-                if args.len() < 1 {
-                    return usage::install();
-                }
-
-                // The package id is presumed to be the first command-line
-                // argument
-                let pkgid = PkgId::new(args[0]);
-                let workspaces = pkg_parent_workspaces(&pkgid);
-                if workspaces.is_empty() {
-                    let rp = rust_path();
-                    assert!(!rp.is_empty());
-                    let src = PkgSrc::new(&rp[0], &build_pkg_id_in_workspace(&pkgid, &rp[0]),
-                                          &pkgid);
-                    src.fetch_git();
-                    self.install(&rp[0], &pkgid);
-                }
-                else {
-                    for each_pkg_parent_workspace(&pkgid) |workspace| {
-                        self.install(workspace, &pkgid);
-                    }
-                }
-            }
-            "prefer" => {
-                if args.len() < 1 {
-                    return usage::uninstall();
-                }
-
-                self.prefer(args[0], None);
-            }
-            "test" => {
-                self.test();
-            }
-            "uninstall" => {
-                if args.len() < 1 {
-                    return usage::uninstall();
-                }
-
-                self.uninstall(args[0], None);
-            }
-            "unprefer" => {
-                if args.len() < 1 {
-                    return usage::uninstall();
-                }
-
-                self.unprefer(args[0], None);
-            }
-            _ => fail!(fmt!("I don't know the command `%s`", cmd))
-        }
-    }
-
-    fn do_cmd(&self, _cmd: &str, _pkgname: &str)  {
-        // stub
-        fail!("`do` not yet implemented");
-    }
-
-    fn build(&self, workspace: &Path, pkgid: &PkgId) {
-        debug!("build: workspace = %s pkgid = %s", workspace.to_str(),
-               pkgid.to_str());
-        let src_dir   = first_pkgid_src_in_workspace(pkgid, workspace);
-        let build_dir = build_pkg_id_in_workspace(pkgid, workspace);
-        debug!("Destination dir = %s", build_dir.to_str());
-
-        // Create the package source
-        let mut src = PkgSrc::new(workspace, &build_dir, pkgid);
-        debug!("Package src = %?", src);
-
-        // Is there custom build logic? If so, use it
-        let pkg_src_dir = src_dir;
-        let mut custom = false;
-        debug!("Package source directory = %?", pkg_src_dir);
-        let cfgs = match pkg_src_dir.chain_ref(|p| src.package_script_option(p)) {
-            Some(package_script_path) => {
-                let pscript = PkgScript::parse(package_script_path,
-                                               workspace,
-                                               pkgid);
-                // Limited right now -- we're only running the post_build
-                // hook and probably fail otherwise
-                // also post_build should be called pre_build
-                let (cfgs, hook_result) = pscript.run_custom(~"post_build");
-                debug!("Command return code = %?", hook_result);
-                if hook_result != 0 {
-                    fail!("Error running custom build command")
-                }
-                custom = true;
-                // otherwise, the package script succeeded
-                cfgs
-            }
-            None => {
-                debug!("No package script, continuing");
-                ~[]
-            }
-        };
-
-        // If there was a package script, it should have finished
-        // the build already. Otherwise...
-        if !custom {
-            // Find crates inside the workspace
-            src.find_crates();
-            // Build it!
-            src.build(self, build_dir, cfgs);
-        }
-    }
-
-    fn clean(&self, workspace: &Path, id: &PkgId)  {
-        // Could also support a custom build hook in the pkg
-        // script for cleaning files rustpkg doesn't know about.
-        // Do something reasonable for now
-
-        let dir = build_pkg_id_in_workspace(id, workspace);
-        note(fmt!("Cleaning package %s (removing directory %s)",
-                        id.to_str(), dir.to_str()));
-        if os::path_exists(&dir) {
-            os::remove_dir_recursive(&dir);
-            note(fmt!("Removed directory %s", dir.to_str()));
-        }
-
-        note(fmt!("Cleaned package %s", id.to_str()));
-    }
-
-    fn info(&self) {
-        // stub
-        fail!("info not yet implemented");
-    }
-
-    fn install(&self, workspace: &Path, id: &PkgId)  {
-        use conditions::copy_failed::cond;
-
-        // Should use RUST_PATH in the future.
-        // Also should use workcache to not build if not necessary.
-        self.build(workspace, id);
-        debug!("install: workspace = %s, id = %s", workspace.to_str(),
-               id.to_str());
-
-        // Now copy stuff into the install dirs
-        let maybe_executable = built_executable_in_workspace(id, workspace);
-        let maybe_library = built_library_in_workspace(id, workspace);
-        let target_exec = target_executable_in_workspace(id, workspace);
-        let target_lib = maybe_library.map(|_p| target_library_in_workspace(id, workspace));
-
-        debug!("target_exec = %s target_lib = %? \
-                maybe_executable = %? maybe_library = %?",
-               target_exec.to_str(), target_lib,
-               maybe_executable, maybe_library);
-
-        for maybe_executable.iter().advance |exec| {
-            debug!("Copying: %s -> %s", exec.to_str(), target_exec.to_str());
-            if !(os::mkdir_recursive(&target_exec.dir_path(), u_rwx) &&
-                 os::copy_file(exec, &target_exec)) {
-                cond.raise((copy *exec, copy target_exec));
-            }
-        }
-        for maybe_library.iter().advance |lib| {
-            let target_lib = (copy target_lib).expect(fmt!("I built %s but apparently \
-                                                didn't install it!", lib.to_str()));
-            debug!("Copying: %s -> %s", lib.to_str(), target_lib.to_str());
-            if !(os::mkdir_recursive(&target_lib.dir_path(), u_rwx) &&
-                 os::copy_file(lib, &target_lib)) {
-                cond.raise((copy *lib, copy target_lib));
-            }
-        }
-    }
-
-    fn prefer(&self, _id: &str, _vers: Option<~str>)  {
-        fail!("prefer not yet implemented");
-    }
-
-    fn test(&self)  {
-        // stub
-        fail!("test not yet implemented");
-    }
-
-    fn uninstall(&self, _id: &str, _vers: Option<~str>)  {
-        fail!("uninstall not yet implemented");
-    }
-
-    fn unprefer(&self, _id: &str, _vers: Option<~str>)  {
-        fail!("unprefer not yet implemented");
-    }
-}
-
-
-pub fn main() {
-    io::println("WARNING: The Rust package manager is experimental and may be unstable");
-
-    let args = os::args();
-    let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
-                 getopts::optflag("j"), getopts::optflag("json"),
-                 getopts::optmulti("c"), getopts::optmulti("cfg")];
-    let matches = &match getopts::getopts(args, opts) {
-        result::Ok(m) => m,
-        result::Err(f) => {
-            error(fmt!("%s", getopts::fail_str(f)));
-
-            return;
-        }
-    };
-    let help = getopts::opt_present(matches, "h") ||
-               getopts::opt_present(matches, "help");
-    let json = getopts::opt_present(matches, "j") ||
-               getopts::opt_present(matches, "json");
-    let mut args = copy matches.free;
-
-    args.shift();
-
-    if (args.len() < 1) {
-        return usage::general();
-    }
-
-    let cmd = args.shift();
-
-    if !util::is_cmd(cmd) {
-        return usage::general();
-    } else if help {
-        return match cmd {
-            ~"build" => usage::build(),
-            ~"clean" => usage::clean(),
-            ~"do" => usage::do_cmd(),
-            ~"info" => usage::info(),
-            ~"install" => usage::install(),
-            ~"prefer" => usage::prefer(),
-            ~"test" => usage::test(),
-            ~"uninstall" => usage::uninstall(),
-            ~"unprefer" => usage::unprefer(),
-            _ => usage::general()
-        };
-    }
-
-    let sroot = match filesearch::get_rustpkg_sysroot() {
-        Ok(r) => Some(@r.pop().pop()), Err(_) => None
-    };
-    debug!("Using sysroot: %?", sroot);
-    Ctx {
-        sysroot_opt: sroot, // Currently, only tests override this
-        json: json,
-        dep_cache: @mut HashMap::new()
-    }.run(cmd, args);
-}
-
-/**
- * Get the working directory of the package script.
- * Assumes that the package script has been compiled
- * in is the working directory.
- */
-pub fn work_dir() -> Path {
-    os::self_exe_path().get()
-}
-
-/**
- * Get the source directory of the package (i.e.
- * where the crates are located). Assumes
- * that the cwd is changed to it before
- * running this executable.
- */
-pub fn src_dir() -> Path {
-    os::getcwd()
-}
diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs
new file mode 100644 (file)
index 0000000..9242e45
--- /dev/null
@@ -0,0 +1,474 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// rustpkg - a package manager and build system for Rust
+
+#[link(name = "rustpkg",
+       vers = "0.7-pre",
+       uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf",
+       url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")];
+
+#[license = "MIT/ASL2"];
+#[crate_type = "lib"];
+
+#[no_core];
+#[no_std];
+
+extern mod core(name = "std");
+extern mod extra(name = "extra");
+
+extern mod rustc;
+extern mod syntax;
+
+use core::prelude::*;
+use core::*;
+pub use core::path::Path;
+use core::hashmap::HashMap;
+use rustc::driver::{driver, session};
+use rustc::metadata::filesearch;
+use extra::{getopts};
+use syntax::{ast, diagnostic};
+use util::*;
+use messages::*;
+use path_util::{build_pkg_id_in_workspace, first_pkgid_src_in_workspace};
+use path_util::{u_rwx, rust_path};
+use path_util::{built_executable_in_workspace, built_library_in_workspace};
+use path_util::{target_executable_in_workspace, target_library_in_workspace};
+use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces};
+use context::Ctx;
+use package_id::PkgId;
+use package_source::PkgSrc;
+
+mod conditions;
+mod context;
+mod crate;
+mod messages;
+mod package_id;
+mod package_path;
+mod package_source;
+mod path_util;
+mod search;
+mod target;
+#[cfg(test)]
+mod tests;
+mod util;
+mod version;
+mod workspace;
+
+pub mod usage;
+
+mod std {
+    pub use core::cmp;
+    pub use core::condition;
+    pub use core::os;
+    pub use core::str;
+    pub use core::sys;
+    pub use core::unstable;
+}
+
+/// A PkgScript represents user-supplied custom logic for
+/// special build hooks. This only exists for packages with
+/// an explicit package script.
+struct PkgScript<'self> {
+    /// Uniquely identifies this package
+    id: &'self PkgId,
+    // Used to have this field:    deps: ~[(~str, Option<~str>)]
+    // but I think it shouldn't be stored here
+    /// The contents of the package script: either a file path,
+    /// or a string containing the text of the input
+    input: driver::input,
+    /// The session to use *only* for compiling the custom
+    /// build script
+    sess: session::Session,
+    /// The config for compiling the custom build script
+    cfg: ast::crate_cfg,
+    /// The crate for the custom build script
+    crate: @ast::crate,
+    /// Directory in which to store build output
+    build_dir: Path
+}
+
+impl<'self> PkgScript<'self> {
+    /// Given the path name for a package script
+    /// and a package ID, parse the package script into
+    /// a PkgScript that we can then execute
+    fn parse<'a>(script: Path, workspace: &Path, id: &'a PkgId) -> PkgScript<'a> {
+        // Get the executable name that was invoked
+        let binary = os::args()[0].to_managed();
+        // Build the rustc session data structures to pass
+        // to the compiler
+        let options = @session::options {
+            binary: binary,
+            crate_type: session::bin_crate,
+            .. copy *session::basic_options()
+        };
+        let input = driver::file_input(script);
+        let sess = driver::build_session(options, diagnostic::emit);
+        let cfg = driver::build_configuration(sess, binary, &input);
+        let (crate, _) = driver::compile_upto(sess, copy cfg, &input, driver::cu_parse, None);
+        let work_dir = build_pkg_id_in_workspace(id, workspace);
+
+        debug!("Returning package script with id %?", id);
+
+        PkgScript {
+            id: id,
+            input: input,
+            sess: sess,
+            cfg: cfg,
+            crate: crate.unwrap(),
+            build_dir: work_dir
+        }
+    }
+
+    /// Run the contents of this package script, where <what>
+    /// is the command to pass to it (e.g., "build", "clean", "install")
+    /// Returns a pair of an exit code and list of configs (obtained by
+    /// calling the package script's configs() function if it exists
+    // FIXME (#4432): Use workcache to only compile the script when changed
+    fn run_custom(&self, what: ~str) -> (~[~str], ExitCode) {
+        debug!("run_custom: %s", what);
+        let sess = self.sess;
+
+        debug!("Working directory = %s", self.build_dir.to_str());
+        // Collect together any user-defined commands in the package script
+        let crate = util::ready_crate(sess, self.crate);
+        debug!("Building output filenames with script name %s",
+               driver::source_name(&self.input));
+        match filesearch::get_rustpkg_sysroot() {
+            Ok(r) => {
+                let root = r.pop().pop().pop().pop(); // :-\
+                debug!("Root is %s, calling compile_rest", root.to_str());
+                let exe = self.build_dir.push(~"pkg" + util::exe_suffix());
+                let binary = os::args()[0].to_managed();
+                util::compile_crate_from_input(&self.input,
+                                               &self.build_dir,
+                                               sess,
+                                               crate,
+                                               driver::build_configuration(sess,
+                                                                           binary, &self.input));
+                debug!("Running program: %s %s %s", exe.to_str(), root.to_str(), what);
+                let status = run::process_status(exe.to_str(), [root.to_str(), what]);
+                if status != 0 {
+                    return (~[], status);
+                }
+                else {
+                    debug!("Running program (configs): %s %s %s",
+                           exe.to_str(), root.to_str(), "configs");
+                    let output = run::process_output(exe.to_str(), [root.to_str(), ~"configs"]);
+                    // Run the configs() function to get the configs
+                    let cfgs = str::from_bytes_slice(output.output).word_iter()
+                        .transform(|w| w.to_owned()).collect();
+                    (cfgs, output.status)
+                }
+            }
+            Err(e) => {
+                fail!("Running package script, couldn't find rustpkg sysroot (%s)", e)
+            }
+        }
+    }
+
+    fn hash(&self) -> ~str {
+        self.id.hash()
+    }
+
+}
+
+impl Ctx {
+
+    fn run(&self, cmd: &str, args: ~[~str]) {
+        match cmd {
+            "build" => {
+                if args.len() < 1 {
+                    return usage::build();
+                }
+                // The package id is presumed to be the first command-line
+                // argument
+                let pkgid = PkgId::new(copy args[0]);
+                for each_pkg_parent_workspace(&pkgid) |workspace| {
+                    self.build(workspace, &pkgid);
+                }
+            }
+            "clean" => {
+                if args.len() < 1 {
+                    return usage::build();
+                }
+                // The package id is presumed to be the first command-line
+                // argument
+                let pkgid = PkgId::new(copy args[0]);
+                let cwd = os::getcwd();
+                self.clean(&cwd, &pkgid); // tjc: should use workspace, not cwd
+            }
+            "do" => {
+                if args.len() < 2 {
+                    return usage::do_cmd();
+                }
+
+                self.do_cmd(copy args[0], copy args[1]);
+            }
+            "info" => {
+                self.info();
+            }
+            "install" => {
+                if args.len() < 1 {
+                    return usage::install();
+                }
+
+                // The package id is presumed to be the first command-line
+                // argument
+                let pkgid = PkgId::new(args[0]);
+                let workspaces = pkg_parent_workspaces(&pkgid);
+                if workspaces.is_empty() {
+                    let rp = rust_path();
+                    assert!(!rp.is_empty());
+                    let src = PkgSrc::new(&rp[0], &build_pkg_id_in_workspace(&pkgid, &rp[0]),
+                                          &pkgid);
+                    src.fetch_git();
+                    self.install(&rp[0], &pkgid);
+                }
+                else {
+                    for each_pkg_parent_workspace(&pkgid) |workspace| {
+                        self.install(workspace, &pkgid);
+                    }
+                }
+            }
+            "prefer" => {
+                if args.len() < 1 {
+                    return usage::uninstall();
+                }
+
+                self.prefer(args[0], None);
+            }
+            "test" => {
+                self.test();
+            }
+            "uninstall" => {
+                if args.len() < 1 {
+                    return usage::uninstall();
+                }
+
+                self.uninstall(args[0], None);
+            }
+            "unprefer" => {
+                if args.len() < 1 {
+                    return usage::uninstall();
+                }
+
+                self.unprefer(args[0], None);
+            }
+            _ => fail!(fmt!("I don't know the command `%s`", cmd))
+        }
+    }
+
+    fn do_cmd(&self, _cmd: &str, _pkgname: &str)  {
+        // stub
+        fail!("`do` not yet implemented");
+    }
+
+    fn build(&self, workspace: &Path, pkgid: &PkgId) {
+        debug!("build: workspace = %s pkgid = %s", workspace.to_str(),
+               pkgid.to_str());
+        let src_dir   = first_pkgid_src_in_workspace(pkgid, workspace);
+        let build_dir = build_pkg_id_in_workspace(pkgid, workspace);
+        debug!("Destination dir = %s", build_dir.to_str());
+
+        // Create the package source
+        let mut src = PkgSrc::new(workspace, &build_dir, pkgid);
+        debug!("Package src = %?", src);
+
+        // Is there custom build logic? If so, use it
+        let pkg_src_dir = src_dir;
+        let mut custom = false;
+        debug!("Package source directory = %?", pkg_src_dir);
+        let cfgs = match pkg_src_dir.chain_ref(|p| src.package_script_option(p)) {
+            Some(package_script_path) => {
+                let pscript = PkgScript::parse(package_script_path,
+                                               workspace,
+                                               pkgid);
+                // Limited right now -- we're only running the post_build
+                // hook and probably fail otherwise
+                // also post_build should be called pre_build
+                let (cfgs, hook_result) = pscript.run_custom(~"post_build");
+                debug!("Command return code = %?", hook_result);
+                if hook_result != 0 {
+                    fail!("Error running custom build command")
+                }
+                custom = true;
+                // otherwise, the package script succeeded
+                cfgs
+            }
+            None => {
+                debug!("No package script, continuing");
+                ~[]
+            }
+        };
+
+        // If there was a package script, it should have finished
+        // the build already. Otherwise...
+        if !custom {
+            // Find crates inside the workspace
+            src.find_crates();
+            // Build it!
+            src.build(self, build_dir, cfgs);
+        }
+    }
+
+    fn clean(&self, workspace: &Path, id: &PkgId)  {
+        // Could also support a custom build hook in the pkg
+        // script for cleaning files rustpkg doesn't know about.
+        // Do something reasonable for now
+
+        let dir = build_pkg_id_in_workspace(id, workspace);
+        note(fmt!("Cleaning package %s (removing directory %s)",
+                        id.to_str(), dir.to_str()));
+        if os::path_exists(&dir) {
+            os::remove_dir_recursive(&dir);
+            note(fmt!("Removed directory %s", dir.to_str()));
+        }
+
+        note(fmt!("Cleaned package %s", id.to_str()));
+    }
+
+    fn info(&self) {
+        // stub
+        fail!("info not yet implemented");
+    }
+
+    fn install(&self, workspace: &Path, id: &PkgId)  {
+        use conditions::copy_failed::cond;
+
+        // Should use RUST_PATH in the future.
+        // Also should use workcache to not build if not necessary.
+        self.build(workspace, id);
+        debug!("install: workspace = %s, id = %s", workspace.to_str(),
+               id.to_str());
+
+        // Now copy stuff into the install dirs
+        let maybe_executable = built_executable_in_workspace(id, workspace);
+        let maybe_library = built_library_in_workspace(id, workspace);
+        let target_exec = target_executable_in_workspace(id, workspace);
+        let target_lib = maybe_library.map(|_p| target_library_in_workspace(id, workspace));
+
+        debug!("target_exec = %s target_lib = %? \
+                maybe_executable = %? maybe_library = %?",
+               target_exec.to_str(), target_lib,
+               maybe_executable, maybe_library);
+
+        for maybe_executable.iter().advance |exec| {
+            debug!("Copying: %s -> %s", exec.to_str(), target_exec.to_str());
+            if !(os::mkdir_recursive(&target_exec.dir_path(), u_rwx) &&
+                 os::copy_file(exec, &target_exec)) {
+                cond.raise((copy *exec, copy target_exec));
+            }
+        }
+        for maybe_library.iter().advance |lib| {
+            let target_lib = (copy target_lib).expect(fmt!("I built %s but apparently \
+                                                didn't install it!", lib.to_str()));
+            debug!("Copying: %s -> %s", lib.to_str(), target_lib.to_str());
+            if !(os::mkdir_recursive(&target_lib.dir_path(), u_rwx) &&
+                 os::copy_file(lib, &target_lib)) {
+                cond.raise((copy *lib, copy target_lib));
+            }
+        }
+    }
+
+    fn prefer(&self, _id: &str, _vers: Option<~str>)  {
+        fail!("prefer not yet implemented");
+    }
+
+    fn test(&self)  {
+        // stub
+        fail!("test not yet implemented");
+    }
+
+    fn uninstall(&self, _id: &str, _vers: Option<~str>)  {
+        fail!("uninstall not yet implemented");
+    }
+
+    fn unprefer(&self, _id: &str, _vers: Option<~str>)  {
+        fail!("unprefer not yet implemented");
+    }
+}
+
+
+pub fn main() {
+    io::println("WARNING: The Rust package manager is experimental and may be unstable");
+
+    let args = os::args();
+    let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
+                 getopts::optflag("j"), getopts::optflag("json"),
+                 getopts::optmulti("c"), getopts::optmulti("cfg")];
+    let matches = &match getopts::getopts(args, opts) {
+        result::Ok(m) => m,
+        result::Err(f) => {
+            error(fmt!("%s", getopts::fail_str(f)));
+
+            return;
+        }
+    };
+    let help = getopts::opt_present(matches, "h") ||
+               getopts::opt_present(matches, "help");
+    let json = getopts::opt_present(matches, "j") ||
+               getopts::opt_present(matches, "json");
+    let mut args = copy matches.free;
+
+    args.shift();
+
+    if (args.len() < 1) {
+        return usage::general();
+    }
+
+    let cmd = args.shift();
+
+    if !util::is_cmd(cmd) {
+        return usage::general();
+    } else if help {
+        return match cmd {
+            ~"build" => usage::build(),
+            ~"clean" => usage::clean(),
+            ~"do" => usage::do_cmd(),
+            ~"info" => usage::info(),
+            ~"install" => usage::install(),
+            ~"prefer" => usage::prefer(),
+            ~"test" => usage::test(),
+            ~"uninstall" => usage::uninstall(),
+            ~"unprefer" => usage::unprefer(),
+            _ => usage::general()
+        };
+    }
+
+    let sroot = match filesearch::get_rustpkg_sysroot() {
+        Ok(r) => Some(@r.pop().pop()), Err(_) => None
+    };
+    debug!("Using sysroot: %?", sroot);
+    Ctx {
+        sysroot_opt: sroot, // Currently, only tests override this
+        json: json,
+        dep_cache: @mut HashMap::new()
+    }.run(cmd, args);
+}
+
+/**
+ * Get the working directory of the package script.
+ * Assumes that the package script has been compiled
+ * in is the working directory.
+ */
+pub fn work_dir() -> Path {
+    os::self_exe_path().get()
+}
+
+/**
+ * Get the source directory of the package (i.e.
+ * where the crates are located). Assumes
+ * that the cwd is changed to it before
+ * running this executable.
+ */
+pub fn src_dir() -> Path {
+    os::getcwd()
+}
diff --git a/src/libstd/core.rc b/src/libstd/core.rc
deleted file mode 100644 (file)
index 13c5479..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-# The Rust standard library
-
-The Rust standard library is a group of interrelated modules defining
-the core language traits, operations on built-in data types, collections,
-platform abstractions, the task scheduler, runtime support for language
-features and other common functionality.
-
-`std` includes modules corresponding to each of the integer types,
-each of the floating point types, the `bool` type, tuples, characters,
-strings (`str`), vectors (`vec`), managed boxes (`managed`), owned
-boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`).
-Additionally, `std` provides pervasive types (`option` and `result`),
-task creation and communication primitives (`task`, `comm`), platform
-abstractions (`os` and `path`), basic I/O abstractions (`io`), common
-traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings
-to the C standard library (`libc`).
-
-# Standard library injection and the Rust prelude
-
-`std` is imported at the topmost level of every crate by default, as
-if the first line of each crate was
-
-    extern mod std;
-
-This means that the contents of std can be accessed from any context
-with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
-etc.
-
-Additionally, `std` contains a `prelude` module that reexports many of the
-most common types, traits and functions. The contents of the prelude are
-imported into every *module* by default.  Implicitly, all modules behave as if
-they contained the following prologue:
-
-    use std::prelude::*;
-
-*/
-
-
-#[link(name = "std",
-       vers = "0.7-pre",
-       uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
-       url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
-
-#[comment = "The Rust standard library"];
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-// Don't link to std. We are std.
-#[no_std];
-
-#[deny(non_camel_case_types)];
-#[deny(missing_doc)];
-
-// Make std testable by not duplicating lang items. See #2912
-#[cfg(test)] extern mod realstd(name = "std");
-#[cfg(test)] pub use kinds = realstd::kinds;
-#[cfg(test)] pub use ops = realstd::ops;
-#[cfg(test)] pub use cmp = realstd::cmp;
-
-// On Linux, link to the runtime with -lrt.
-#[cfg(target_os = "linux")]
-#[doc(hidden)]
-pub mod linkhack {
-    #[link_args="-lrustrt -lrt"]
-    #[link_args = "-lpthread"]
-    extern {
-    }
-}
-
-// Internal macros
-mod macros;
-
-/* The Prelude. */
-
-pub mod prelude;
-
-/* Primitive types */
-
-#[path = "num/int_macros.rs"]   mod int_macros;
-#[path = "num/uint_macros.rs"]  mod uint_macros;
-
-#[path = "num/int.rs"]  pub mod int;
-#[path = "num/i8.rs"]   pub mod i8;
-#[path = "num/i16.rs"]  pub mod i16;
-#[path = "num/i32.rs"]  pub mod i32;
-#[path = "num/i64.rs"]  pub mod i64;
-
-#[path = "num/uint.rs"] pub mod uint;
-#[path = "num/u8.rs"]   pub mod u8;
-#[path = "num/u16.rs"]  pub mod u16;
-#[path = "num/u32.rs"]  pub mod u32;
-#[path = "num/u64.rs"]  pub mod u64;
-
-#[path = "num/float.rs"] pub mod float;
-#[path = "num/f32.rs"]   pub mod f32;
-#[path = "num/f64.rs"]   pub mod f64;
-
-pub mod nil;
-pub mod bool;
-pub mod char;
-pub mod tuple;
-
-pub mod vec;
-pub mod at_vec;
-pub mod str;
-
-#[path = "str/ascii.rs"]
-pub mod ascii;
-
-pub mod ptr;
-pub mod owned;
-pub mod managed;
-pub mod borrow;
-
-
-/* Core language traits */
-
-#[cfg(not(test))] pub mod kinds;
-#[cfg(not(test))] pub mod ops;
-#[cfg(not(test))] pub mod cmp;
-
-
-/* Common traits */
-
-pub mod from_str;
-#[path = "num/num.rs"]
-pub mod num;
-pub mod iter;
-pub mod iterator;
-pub mod to_str;
-pub mod to_bytes;
-pub mod clone;
-pub mod io;
-pub mod hash;
-pub mod container;
-
-
-/* Common data structures */
-
-pub mod option;
-pub mod result;
-pub mod either;
-pub mod hashmap;
-pub mod cell;
-pub mod trie;
-
-
-/* Tasks and communication */
-
-#[path = "task/mod.rs"]
-pub mod task;
-pub mod comm;
-pub mod pipes;
-pub mod local_data;
-
-
-/* Runtime and platform support */
-
-pub mod gc;
-pub mod libc;
-pub mod os;
-pub mod path;
-pub mod rand;
-pub mod run;
-pub mod sys;
-pub mod cast;
-pub mod repr;
-pub mod cleanup;
-pub mod reflect;
-pub mod condition;
-pub mod logging;
-pub mod util;
-
-
-/* Unsupported interfaces */
-
-// Private APIs
-#[path = "unstable/mod.rs"]
-pub mod unstable;
-
-/* For internal use, not exported */
-
-mod unicode;
-#[path = "num/cmath.rs"]
-mod cmath;
-mod stackwalk;
-
-// XXX: This shouldn't be pub, and it should be reexported under 'unstable'
-// but name resolution doesn't work without it being pub.
-#[path = "rt/mod.rs"]
-pub mod rt;
-
-// A curious inner-module that's not exported that contains the binding
-// 'std' so that macro-expanded references to std::error and such
-// can be resolved within libstd.
-#[doc(hidden)]
-mod core {
-    pub use clone;
-    pub use cmp;
-    pub use condition;
-    pub use option;
-    pub use kinds;
-    pub use sys;
-    pub use pipes;
-}
-#[doc(hidden)]
-mod std {
-    pub use clone;
-    pub use cmp;
-    pub use condition;
-    pub use option;
-    pub use kinds;
-    pub use sys;
-    pub use pipes;
-    pub use unstable;
-    pub use str;
-    pub use os;
-}
diff --git a/src/libstd/std.rs b/src/libstd/std.rs
new file mode 100644 (file)
index 0000000..13c5479
--- /dev/null
@@ -0,0 +1,230 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+
+# The Rust standard library
+
+The Rust standard library is a group of interrelated modules defining
+the core language traits, operations on built-in data types, collections,
+platform abstractions, the task scheduler, runtime support for language
+features and other common functionality.
+
+`std` includes modules corresponding to each of the integer types,
+each of the floating point types, the `bool` type, tuples, characters,
+strings (`str`), vectors (`vec`), managed boxes (`managed`), owned
+boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`).
+Additionally, `std` provides pervasive types (`option` and `result`),
+task creation and communication primitives (`task`, `comm`), platform
+abstractions (`os` and `path`), basic I/O abstractions (`io`), common
+traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings
+to the C standard library (`libc`).
+
+# Standard library injection and the Rust prelude
+
+`std` is imported at the topmost level of every crate by default, as
+if the first line of each crate was
+
+    extern mod std;
+
+This means that the contents of std can be accessed from any context
+with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
+etc.
+
+Additionally, `std` contains a `prelude` module that reexports many of the
+most common types, traits and functions. The contents of the prelude are
+imported into every *module* by default.  Implicitly, all modules behave as if
+they contained the following prologue:
+
+    use std::prelude::*;
+
+*/
+
+
+#[link(name = "std",
+       vers = "0.7-pre",
+       uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
+       url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
+
+#[comment = "The Rust standard library"];
+#[license = "MIT/ASL2"];
+#[crate_type = "lib"];
+
+// Don't link to std. We are std.
+#[no_std];
+
+#[deny(non_camel_case_types)];
+#[deny(missing_doc)];
+
+// Make std testable by not duplicating lang items. See #2912
+#[cfg(test)] extern mod realstd(name = "std");
+#[cfg(test)] pub use kinds = realstd::kinds;
+#[cfg(test)] pub use ops = realstd::ops;
+#[cfg(test)] pub use cmp = realstd::cmp;
+
+// On Linux, link to the runtime with -lrt.
+#[cfg(target_os = "linux")]
+#[doc(hidden)]
+pub mod linkhack {
+    #[link_args="-lrustrt -lrt"]
+    #[link_args = "-lpthread"]
+    extern {
+    }
+}
+
+// Internal macros
+mod macros;
+
+/* The Prelude. */
+
+pub mod prelude;
+
+/* Primitive types */
+
+#[path = "num/int_macros.rs"]   mod int_macros;
+#[path = "num/uint_macros.rs"]  mod uint_macros;
+
+#[path = "num/int.rs"]  pub mod int;
+#[path = "num/i8.rs"]   pub mod i8;
+#[path = "num/i16.rs"]  pub mod i16;
+#[path = "num/i32.rs"]  pub mod i32;
+#[path = "num/i64.rs"]  pub mod i64;
+
+#[path = "num/uint.rs"] pub mod uint;
+#[path = "num/u8.rs"]   pub mod u8;
+#[path = "num/u16.rs"]  pub mod u16;
+#[path = "num/u32.rs"]  pub mod u32;
+#[path = "num/u64.rs"]  pub mod u64;
+
+#[path = "num/float.rs"] pub mod float;
+#[path = "num/f32.rs"]   pub mod f32;
+#[path = "num/f64.rs"]   pub mod f64;
+
+pub mod nil;
+pub mod bool;
+pub mod char;
+pub mod tuple;
+
+pub mod vec;
+pub mod at_vec;
+pub mod str;
+
+#[path = "str/ascii.rs"]
+pub mod ascii;
+
+pub mod ptr;
+pub mod owned;
+pub mod managed;
+pub mod borrow;
+
+
+/* Core language traits */
+
+#[cfg(not(test))] pub mod kinds;
+#[cfg(not(test))] pub mod ops;
+#[cfg(not(test))] pub mod cmp;
+
+
+/* Common traits */
+
+pub mod from_str;
+#[path = "num/num.rs"]
+pub mod num;
+pub mod iter;
+pub mod iterator;
+pub mod to_str;
+pub mod to_bytes;
+pub mod clone;
+pub mod io;
+pub mod hash;
+pub mod container;
+
+
+/* Common data structures */
+
+pub mod option;
+pub mod result;
+pub mod either;
+pub mod hashmap;
+pub mod cell;
+pub mod trie;
+
+
+/* Tasks and communication */
+
+#[path = "task/mod.rs"]
+pub mod task;
+pub mod comm;
+pub mod pipes;
+pub mod local_data;
+
+
+/* Runtime and platform support */
+
+pub mod gc;
+pub mod libc;
+pub mod os;
+pub mod path;
+pub mod rand;
+pub mod run;
+pub mod sys;
+pub mod cast;
+pub mod repr;
+pub mod cleanup;
+pub mod reflect;
+pub mod condition;
+pub mod logging;
+pub mod util;
+
+
+/* Unsupported interfaces */
+
+// Private APIs
+#[path = "unstable/mod.rs"]
+pub mod unstable;
+
+/* For internal use, not exported */
+
+mod unicode;
+#[path = "num/cmath.rs"]
+mod cmath;
+mod stackwalk;
+
+// XXX: This shouldn't be pub, and it should be reexported under 'unstable'
+// but name resolution doesn't work without it being pub.
+#[path = "rt/mod.rs"]
+pub mod rt;
+
+// A curious inner-module that's not exported that contains the binding
+// 'std' so that macro-expanded references to std::error and such
+// can be resolved within libstd.
+#[doc(hidden)]
+mod core {
+    pub use clone;
+    pub use cmp;
+    pub use condition;
+    pub use option;
+    pub use kinds;
+    pub use sys;
+    pub use pipes;
+}
+#[doc(hidden)]
+mod std {
+    pub use clone;
+    pub use cmp;
+    pub use condition;
+    pub use option;
+    pub use kinds;
+    pub use sys;
+    pub use pipes;
+    pub use unstable;
+    pub use str;
+    pub use os;
+}
diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc
deleted file mode 100644 (file)
index 278600b..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*! This module contains the Rust parser. It maps source text
- *  to token trees and to ASTs. It contains code for expanding
- *  macros.
- */
-
-#[link(name = "syntax",
-       vers = "0.7-pre",
-       uuid = "9311401b-d6ea-4cd9-a1d9-61f89499c645")];
-
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-#[allow(non_camel_case_types)];
-#[deny(deprecated_pattern)];
-
-#[no_core];
-#[no_std];
-
-extern mod core(name = "std");
-extern mod extra(name = "extra");
-
-// For deriving(Encodable) purposes...
-extern mod std(name = "std");
-
-use core::prelude::*;
-
-pub mod util {
-    pub mod interner;
-    #[cfg(test)]
-    pub mod parser_testing;
-}
-
-pub mod syntax {
-    pub use ext;
-    pub use parse;
-}
-
-pub mod opt_vec;
-pub mod attr;
-pub mod diagnostic;
-pub mod codemap;
-pub mod abi;
-pub mod ast;
-pub mod ast_util;
-pub mod ast_map;
-pub mod visit;
-pub mod fold;
-
-
-#[path = "parse/mod.rs"]
-pub mod parse;
-
-pub mod print {
-    pub mod pp;
-    pub mod pprust;
-}
-
-pub mod ext {
-    pub mod asm;
-    pub mod base;
-    pub mod expand;
-
-    pub mod quote;
-
-    #[path = "deriving/mod.rs"]
-    pub mod deriving;
-
-    pub mod build;
-
-    pub mod tt {
-        pub mod transcribe;
-        pub mod macro_parser;
-        pub mod macro_rules;
-    }
-
-
-    pub mod fmt;
-    pub mod env;
-    pub mod bytes;
-    pub mod concat_idents;
-    pub mod log_syntax;
-    pub mod auto_encode;
-    pub mod source_util;
-
-    #[path = "pipes/mod.rs"]
-    pub mod pipes;
-
-    pub mod trace_macros;
-}
diff --git a/src/libsyntax/syntax.rs b/src/libsyntax/syntax.rs
new file mode 100644 (file)
index 0000000..278600b
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*! This module contains the Rust parser. It maps source text
+ *  to token trees and to ASTs. It contains code for expanding
+ *  macros.
+ */
+
+#[link(name = "syntax",
+       vers = "0.7-pre",
+       uuid = "9311401b-d6ea-4cd9-a1d9-61f89499c645")];
+
+#[license = "MIT/ASL2"];
+#[crate_type = "lib"];
+
+#[allow(non_camel_case_types)];
+#[deny(deprecated_pattern)];
+
+#[no_core];
+#[no_std];
+
+extern mod core(name = "std");
+extern mod extra(name = "extra");
+
+// For deriving(Encodable) purposes...
+extern mod std(name = "std");
+
+use core::prelude::*;
+
+pub mod util {
+    pub mod interner;
+    #[cfg(test)]
+    pub mod parser_testing;
+}
+
+pub mod syntax {
+    pub use ext;
+    pub use parse;
+}
+
+pub mod opt_vec;
+pub mod attr;
+pub mod diagnostic;
+pub mod codemap;
+pub mod abi;
+pub mod ast;
+pub mod ast_util;
+pub mod ast_map;
+pub mod visit;
+pub mod fold;
+
+
+#[path = "parse/mod.rs"]
+pub mod parse;
+
+pub mod print {
+    pub mod pp;
+    pub mod pprust;
+}
+
+pub mod ext {
+    pub mod asm;
+    pub mod base;
+    pub mod expand;
+
+    pub mod quote;
+
+    #[path = "deriving/mod.rs"]
+    pub mod deriving;
+
+    pub mod build;
+
+    pub mod tt {
+        pub mod transcribe;
+        pub mod macro_parser;
+        pub mod macro_rules;
+    }
+
+
+    pub mod fmt;
+    pub mod env;
+    pub mod bytes;
+    pub mod concat_idents;
+    pub mod log_syntax;
+    pub mod auto_encode;
+    pub mod source_util;
+
+    #[path = "pipes/mod.rs"]
+    pub mod pipes;
+
+    pub mod trace_macros;
+}