# 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
# 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
+++ /dev/null
-// 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()) })
-}
--- /dev/null
+// 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()) })
+}
--- /dev/null
+// 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;
+}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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();
-}
--- /dev/null
+// 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();
+}
+++ /dev/null
-// 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);
- }
-}
--- /dev/null
+// 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);
+ }
+}
+++ /dev/null
-// 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
-}
--- /dev/null
+// 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
+}
+++ /dev/null
-// 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);
- }
-}
--- /dev/null
+// 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);
+ }
+}
+++ /dev/null
-// 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()
-}
--- /dev/null
+// 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()
+}
+++ /dev/null
-// 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;
-}
--- /dev/null
+// 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;
+}
+++ /dev/null
-// 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;
-}
--- /dev/null
+// 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;
+}