auto merge of #9480 : brson/rust/noexit, r=thestinger

This can cause unexpected errors in the runtime when done while
scheduler threads are still initializing. Required some restructuring
of the main_args functions in our libraries.
This commit is contained in:
bors 2013-09-24 23:40:54 -07:00
commit dad32f703d
6 changed files with 45 additions and 45 deletions

View File

@ -30,7 +30,6 @@ use treemap::TreeMap;
use std::clone::Clone;
use std::comm::{stream, SharedChan, GenericPort, GenericChan};
use std::libc;
use std::io;
use std::result;
use std::task;
@ -125,8 +124,9 @@ pub type MetricDiff = TreeMap<~str,MetricChange>;
pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) {
let opts =
match parse_opts(args) {
Ok(o) => o,
Err(msg) => fail!(msg)
Some(Ok(o)) => o,
Some(Err(msg)) => fail!(msg),
None => return
};
if !run_tests_console(&opts, tests) { fail!("Some tests failed"); }
}
@ -189,7 +189,7 @@ fn optgroups() -> ~[getopts::groups::OptGroup] {
"A.B")]
}
fn usage(binary: &str, helpstr: &str) -> ! {
fn usage(binary: &str, helpstr: &str) {
#[fixed_stack_segment]; #[inline(never)];
let message = fmt!("Usage: %s [OPTIONS] [FILTER]", binary);
@ -217,20 +217,19 @@ Test Attributes:
tests. This may also be written as #[ignore(cfg(...))] to
ignore the test on certain configurations.");
}
unsafe { libc::exit(0) }
}
// Parses command line arguments into test options
pub fn parse_opts(args: &[~str]) -> OptRes {
pub fn parse_opts(args: &[~str]) -> Option<OptRes> {
let args_ = args.tail();
let matches =
match groups::getopts(args_, optgroups()) {
Ok(m) => m,
Err(f) => return Err(f.to_err_msg())
Err(f) => return Some(Err(f.to_err_msg()))
};
if matches.opt_present("h") { usage(args[0], "h"); }
if matches.opt_present("help") { usage(args[0], "help"); }
if matches.opt_present("h") { usage(args[0], "h"); return None; }
if matches.opt_present("help") { usage(args[0], "help"); return None; }
let filter =
if matches.free.len() > 0 {
@ -272,7 +271,7 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
logfile: logfile
};
Ok(test_opts)
Some(Ok(test_opts))
}
pub fn opt_shard(maybestr: Option<~str>) -> Option<(uint,uint)> {
@ -1228,7 +1227,7 @@ mod tests {
fn first_free_arg_should_be_a_filter() {
let args = ~[~"progname", ~"filter"];
let opts = match parse_opts(args) {
Ok(o) => o,
Some(Ok(o)) => o,
_ => fail!("Malformed arg in first_free_arg_should_be_a_filter")
};
assert!("filter" == opts.filter.clone().unwrap());
@ -1238,7 +1237,7 @@ mod tests {
fn parse_ignored_flag() {
let args = ~[~"progname", ~"filter", ~"--ignored"];
let opts = match parse_opts(args) {
Ok(o) => o,
Some(Ok(o)) => o,
_ => fail!("Malformed arg in parse_ignored_flag")
};
assert!((opts.run_ignored));

View File

@ -44,7 +44,7 @@ impl ValidUsage {
enum Action {
Call(extern "Rust" fn(args: &[~str]) -> ValidUsage),
CallMain(&'static str, extern "Rust" fn(&[~str])),
CallMain(&'static str, extern "Rust" fn(&[~str]) -> int),
}
enum UsageSource<'self> {
@ -185,18 +185,17 @@ fn cmd_run(args: &[~str]) -> ValidUsage {
}
}
fn invoke(prog: &str, args: &[~str], f: &fn(&[~str])) {
fn invoke(prog: &str, args: &[~str], f: &fn(&[~str]) -> int) -> int {
let mut osargs = ~[prog.to_owned()];
osargs.push_all_move(args.to_owned());
f(osargs);
f(osargs)
}
fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
match command.action {
Call(f) => f(args),
CallMain(prog, f) => {
invoke(prog, args, f);
Valid(0)
Valid(invoke(prog, args, f))
}
}
}

View File

@ -394,13 +394,14 @@ pub fn monitor(f: ~fn(@diagnostic::Emitter)) {
}
pub fn main() {
let args = os::args();
main_args(args);
std::os::set_exit_status(main_args(std::os::args()));
}
pub fn main_args(args: &[~str]) {
pub fn main_args(args: &[~str]) -> int {
let owned_args = args.to_owned();
do monitor |demitter| {
run_compiler(owned_args, demitter);
}
return 0;
}

View File

@ -52,7 +52,7 @@ enum OutputFormat {
}
pub fn main() {
main_args(std::os::args());
std::os::set_exit_status(main_args(std::os::args()));
}
pub fn opts() -> ~[groups::OptGroup] {
@ -76,14 +76,14 @@ pub fn usage(argv0: &str) {
argv0), opts()));
}
pub fn main_args(args: &[~str]) {
pub fn main_args(args: &[~str]) -> int {
//use extra::getopts::groups::*;
let matches = groups::getopts(args.tail(), opts()).unwrap();
if matches.opt_present("h") || matches.opt_present("help") {
usage(args[0]);
return;
return 0;
}
let (format, cratefile) = match matches.free.clone() {
@ -92,17 +92,17 @@ pub fn main_args(args: &[~str]) {
[s, _] => {
println!("Unknown output format: `{}`", s);
usage(args[0]);
exit(1);
return 1;
}
[_, .._] => {
println!("Expected exactly one crate to process");
usage(args[0]);
exit(1);
return 1;
}
_ => {
println!("Expected an output format and then one crate");
usage(args[0]);
exit(1);
return 1;
}
};
@ -179,6 +179,8 @@ pub fn main_args(args: &[~str]) {
}
let ended = time::precise_time_ns();
info2!("Took {:.03f}s", (ended as f64 - started as f64) / 1000000000f64);
return 0;
}
fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
@ -208,9 +210,3 @@ fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
let output = extra::json::Object(json).to_str();
file.write(output.as_bytes());
}
fn exit(status: int) -> ! {
#[fixed_stack_segment]; #[inline(never)];
use std::libc;
unsafe { libc::exit(status as libc::c_int) }
}

View File

@ -517,8 +517,7 @@ pub fn run_line(repl: &mut Repl, input: @io::Reader, out: @io::Writer, line: ~st
}
pub fn main() {
let args = os::args();
main_args(args);
os::set_exit_status(main_args(os::args()));
}
struct Completer;
@ -534,7 +533,7 @@ impl CompletionCb for Completer {
}
}
pub fn main_args(args: &[~str]) {
pub fn main_args(args: &[~str]) -> int {
#[fixed_stack_segment]; #[inline(never)];
let input = io::stdin();
@ -576,6 +575,8 @@ pub fn main_args(args: &[~str]) {
}
}
}
return 0;
}
#[cfg(test)]

View File

@ -615,11 +615,10 @@ impl CtxMethods for BuildContext {
pub fn main() {
io::println("WARNING: The Rust package manager is experimental and may be unstable");
let args = os::args();
main_args(args);
os::set_exit_status(main_args(os::args()));
}
pub fn main_args(args: &[~str]) {
pub fn main_args(args: &[~str]) -> int {
let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
getopts::optflag("no-link"),
getopts::optflag("no-trans"),
@ -645,7 +644,7 @@ pub fn main_args(args: &[~str]) {
result::Err(f) => {
error(fmt!("%s", f.to_err_msg()));
return;
return 1;
}
};
let mut help = matches.opt_present("h") ||
@ -662,7 +661,7 @@ pub fn main_args(args: &[~str]) {
if matches.opt_present("v") ||
matches.opt_present("version") {
rustc::version(args[0]);
return;
return 0;
}
let use_rust_path_hack = matches.opt_present("r") ||
@ -701,7 +700,8 @@ pub fn main_args(args: &[~str]) {
args.shift();
if (args.len() < 1) {
return usage::general();
usage::general();
return 1;
}
let rustc_flags = RustcFlags {
@ -739,11 +739,14 @@ pub fn main_args(args: &[~str]) {
}
}
let cmd = match cmd_opt {
None => return usage::general(),
None => {
usage::general();
return 0;
}
Some(cmd) => {
help |= context::flags_ok_for_cmd(&rustc_flags, cfgs, *cmd, user_supplied_opt_level);
if help {
return match *cmd {
match *cmd {
~"build" => usage::build(),
~"clean" => usage::clean(),
~"do" => usage::do_cmd(),
@ -757,6 +760,7 @@ pub fn main_args(args: &[~str]) {
~"unprefer" => usage::unprefer(),
_ => usage::general()
};
return 0;
} else {
cmd
}
@ -794,8 +798,8 @@ pub fn main_args(args: &[~str]) {
// and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE,
// when actually, it might set the exit code for that even if a different
// unhandled condition got raised.
if result.is_err() { os::set_exit_status(COPY_FAILED_CODE); }
if result.is_err() { return COPY_FAILED_CODE; }
return 0;
}
/**