2011-08-11 21:14:38 -05:00
|
|
|
import std::io;
|
2011-07-30 23:11:14 -05:00
|
|
|
import std::str;
|
2011-08-24 18:00:26 -05:00
|
|
|
import std::istr;
|
2011-07-30 23:11:14 -05:00
|
|
|
import std::option;
|
|
|
|
import std::fs;
|
|
|
|
import std::os;
|
2011-08-15 18:38:23 -05:00
|
|
|
import std::vec;
|
2011-07-30 23:11:14 -05:00
|
|
|
import std::test;
|
|
|
|
|
|
|
|
import common::mode_run_pass;
|
|
|
|
import common::mode_run_fail;
|
|
|
|
import common::mode_compile_fail;
|
2011-07-30 23:44:30 -05:00
|
|
|
import common::mode_pretty;
|
2011-07-30 23:11:14 -05:00
|
|
|
import common::cx;
|
|
|
|
import common::config;
|
|
|
|
import header::load_props;
|
|
|
|
import header::test_props;
|
|
|
|
import util::logv;
|
|
|
|
|
|
|
|
export run;
|
|
|
|
|
2011-08-13 17:20:11 -05:00
|
|
|
fn run(cx: &cx, _testfile: -[u8]) {
|
|
|
|
let testfile = str::unsafe_from_bytes(_testfile);
|
2011-08-19 17:16:48 -05:00
|
|
|
if cx.config.verbose {
|
2011-07-30 23:11:14 -05:00
|
|
|
// We're going to be dumping a lot of info. Start on a new line.
|
2011-08-24 23:26:19 -05:00
|
|
|
io::stdout().write_str(~"\n\n");
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
log #fmt["running %s", testfile];
|
2011-07-30 23:11:14 -05:00
|
|
|
let props = load_props(testfile);
|
|
|
|
alt cx.config.mode {
|
|
|
|
mode_compile_fail. { run_cfail_test(cx, props, testfile); }
|
|
|
|
mode_run_fail. { run_rfail_test(cx, props, testfile); }
|
|
|
|
mode_run_pass. { run_rpass_test(cx, props, testfile); }
|
2011-07-30 23:44:30 -05:00
|
|
|
mode_pretty. { run_pretty_test(cx, props, testfile); }
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run_cfail_test(cx: &cx, props: &test_props, testfile: &str) {
|
|
|
|
let procres = compile_test(cx, props, testfile);
|
|
|
|
|
|
|
|
if procres.status == 0 {
|
2011-08-19 17:16:48 -05:00
|
|
|
fatal_procres("compile-fail test compiled successfully!", procres);
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
check_error_patterns(props, testfile, procres);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run_rfail_test(cx: &cx, props: &test_props, testfile: &str) {
|
|
|
|
let procres = compile_test(cx, props, testfile);
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
if procres.status != 0 { fatal_procres("compilation failed!", procres); }
|
2011-07-30 23:11:14 -05:00
|
|
|
|
2011-08-10 15:36:57 -05:00
|
|
|
procres = exec_compiled_test(cx, props, testfile);
|
2011-07-30 23:11:14 -05:00
|
|
|
|
|
|
|
if procres.status == 0 {
|
2011-08-19 17:16:48 -05:00
|
|
|
fatal_procres("run-fail test didn't produce an error!", procres);
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-10 15:36:57 -05:00
|
|
|
// This is the value valgrind returns on failure
|
|
|
|
// FIXME: Why is this value neither the value we pass to
|
|
|
|
// valgrind as --error-exitcode (1), nor the value we see as the
|
|
|
|
// exit code on the command-line (137)?
|
|
|
|
const valgrind_err: int = 9;
|
|
|
|
if procres.status == valgrind_err {
|
|
|
|
fatal_procres("run-fail test isn't valgrind-clean!", procres);
|
|
|
|
}
|
|
|
|
|
2011-07-30 23:11:14 -05:00
|
|
|
check_error_patterns(props, testfile, procres);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run_rpass_test(cx: &cx, props: &test_props, testfile: &str) {
|
|
|
|
let procres = compile_test(cx, props, testfile);
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
if procres.status != 0 { fatal_procres("compilation failed!", procres); }
|
2011-07-30 23:11:14 -05:00
|
|
|
|
2011-08-10 15:36:57 -05:00
|
|
|
procres = exec_compiled_test(cx, props, testfile);
|
2011-07-30 23:11:14 -05:00
|
|
|
|
|
|
|
|
|
|
|
if procres.status != 0 { fatal_procres("test run failed!", procres); }
|
|
|
|
}
|
|
|
|
|
2011-07-30 23:44:30 -05:00
|
|
|
fn run_pretty_test(cx: &cx, props: &test_props, testfile: &str) {
|
2011-08-01 16:10:59 -05:00
|
|
|
if option::is_some(props.pp_exact) {
|
|
|
|
logv(cx.config, "testing for exact pretty-printing");
|
2011-08-19 17:16:48 -05:00
|
|
|
} else { logv(cx.config, "testing for converging pretty-printing"); }
|
2011-08-01 16:10:59 -05:00
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
let rounds =
|
|
|
|
alt props.pp_exact { option::some(_) { 1 } option::none. { 2 } };
|
2011-07-31 17:33:40 -05:00
|
|
|
|
2011-08-24 23:26:19 -05:00
|
|
|
let srcs = [istr::to_estr(io::read_whole_file_str(
|
|
|
|
istr::from_estr(testfile)))];
|
2011-07-31 17:33:40 -05:00
|
|
|
|
|
|
|
let round = 0;
|
|
|
|
while round < rounds {
|
2011-08-19 17:16:48 -05:00
|
|
|
logv(cx.config, #fmt["pretty-printing round %d", round]);
|
|
|
|
let procres = print_source(cx, testfile, srcs[round]);
|
2011-07-31 17:33:40 -05:00
|
|
|
|
|
|
|
if procres.status != 0 {
|
2011-08-19 17:16:48 -05:00
|
|
|
fatal_procres(#fmt["pretty-printing failed in round %d", round],
|
2011-07-31 17:33:40 -05:00
|
|
|
procres);
|
|
|
|
}
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
srcs += [procres.stdout];
|
2011-07-31 17:33:40 -05:00
|
|
|
round += 1;
|
|
|
|
}
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
let expected =
|
|
|
|
alt props.pp_exact {
|
|
|
|
option::some(file) {
|
2011-08-24 18:00:26 -05:00
|
|
|
let filepath = fs::connect(fs::dirname(
|
|
|
|
istr::from_estr(testfile)), istr::from_estr(file));
|
2011-08-24 23:26:19 -05:00
|
|
|
istr::to_estr(io::read_whole_file_str(filepath))
|
2011-08-19 17:16:48 -05:00
|
|
|
}
|
|
|
|
option::none. { srcs[vec::len(srcs) - 2u] }
|
|
|
|
};
|
|
|
|
let actual = srcs[vec::len(srcs) - 1u];
|
2011-08-03 18:25:38 -05:00
|
|
|
|
2011-08-03 17:36:45 -05:00
|
|
|
if option::is_some(props.pp_exact) {
|
|
|
|
// Now we have to care about line endings
|
|
|
|
let cr = "\r";
|
2011-08-19 17:16:48 -05:00
|
|
|
check (str::is_not_empty(cr));
|
2011-08-03 17:36:45 -05:00
|
|
|
actual = str::replace(actual, cr, "");
|
|
|
|
expected = str::replace(expected, cr, "");
|
|
|
|
}
|
2011-07-31 17:33:40 -05:00
|
|
|
|
|
|
|
compare_source(expected, actual);
|
|
|
|
|
|
|
|
// Finally, let's make sure it actually appears to remain valid code
|
2011-07-31 21:12:33 -05:00
|
|
|
let procres = typecheck_source(cx, testfile, actual);
|
2011-07-31 17:33:40 -05:00
|
|
|
|
|
|
|
if procres.status != 0 {
|
2011-08-19 17:16:48 -05:00
|
|
|
fatal_procres("pretty-printed source does not typecheck", procres);
|
2011-07-31 17:33:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
ret;
|
|
|
|
|
|
|
|
fn print_source(cx: &cx, testfile: &str, src: &str) -> procres {
|
|
|
|
compose_and_run(cx, testfile, make_pp_args,
|
|
|
|
cx.config.compile_lib_path, option::some(src))
|
|
|
|
}
|
|
|
|
|
2011-08-22 13:00:43 -05:00
|
|
|
fn make_pp_args(config: &config, _testfile: &str) -> procargs {
|
2011-08-24 20:01:10 -05:00
|
|
|
let prog = istr::to_estr(config.rustc_path);
|
2011-08-19 17:16:48 -05:00
|
|
|
let args = ["-", "--pretty", "normal"];
|
2011-07-31 17:33:40 -05:00
|
|
|
ret {prog: prog, args: args};
|
|
|
|
}
|
|
|
|
|
|
|
|
fn compare_source(expected: &str, actual: &str) {
|
|
|
|
if expected != actual {
|
2011-08-01 16:10:59 -05:00
|
|
|
error("pretty-printed source does match expected source");
|
2011-08-19 17:16:48 -05:00
|
|
|
let msg =
|
|
|
|
#fmt["\n\
|
2011-07-31 17:33:40 -05:00
|
|
|
expected:\n\
|
|
|
|
------------------------------------------\n\
|
|
|
|
%s\n\
|
|
|
|
------------------------------------------\n\
|
|
|
|
actual:\n\
|
|
|
|
------------------------------------------\n\
|
|
|
|
%s\n\
|
|
|
|
------------------------------------------\n\
|
|
|
|
\n",
|
2011-08-19 17:16:48 -05:00
|
|
|
expected, actual];
|
2011-08-24 23:26:19 -05:00
|
|
|
io::stdout().write_str(istr::from_estr(msg));
|
2011-07-31 17:33:40 -05:00
|
|
|
fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-31 21:12:33 -05:00
|
|
|
fn typecheck_source(cx: &cx, testfile: &str, src: &str) -> procres {
|
|
|
|
compose_and_run(cx, testfile, make_typecheck_args,
|
|
|
|
cx.config.compile_lib_path, option::some(src))
|
|
|
|
}
|
|
|
|
|
2011-08-22 13:00:43 -05:00
|
|
|
fn make_typecheck_args(config: &config, _testfile: &str) -> procargs {
|
2011-08-24 20:01:10 -05:00
|
|
|
let prog = istr::to_estr(config.rustc_path);
|
2011-08-19 17:16:48 -05:00
|
|
|
let args = ["-", "--no-trans", "--lib"];
|
2011-07-31 21:12:33 -05:00
|
|
|
ret {prog: prog, args: args};
|
2011-07-31 17:33:40 -05:00
|
|
|
}
|
2011-07-30 23:44:30 -05:00
|
|
|
}
|
|
|
|
|
2011-07-30 23:11:14 -05:00
|
|
|
fn check_error_patterns(props: &test_props, testfile: &str,
|
|
|
|
procres: &procres) {
|
2011-08-15 18:38:23 -05:00
|
|
|
if vec::is_empty(props.error_patterns) {
|
2011-07-30 23:11:14 -05:00
|
|
|
fatal("no error pattern specified in " + testfile);
|
|
|
|
}
|
|
|
|
|
2011-08-24 15:24:03 -05:00
|
|
|
if procres.status == 0 {
|
|
|
|
fatal("process did not return an error status");
|
|
|
|
}
|
|
|
|
|
2011-07-30 23:11:14 -05:00
|
|
|
let next_err_idx = 0u;
|
2011-08-19 17:16:48 -05:00
|
|
|
let next_err_pat = props.error_patterns[next_err_idx];
|
2011-08-15 23:54:52 -05:00
|
|
|
for line: str in str::split(procres.stdout, '\n' as u8) {
|
2011-07-30 23:11:14 -05:00
|
|
|
if str::find(line, next_err_pat) > 0 {
|
2011-08-19 17:16:48 -05:00
|
|
|
log #fmt["found error pattern %s", next_err_pat];
|
2011-07-30 23:11:14 -05:00
|
|
|
next_err_idx += 1u;
|
2011-08-15 18:38:23 -05:00
|
|
|
if next_err_idx == vec::len(props.error_patterns) {
|
2011-07-30 23:11:14 -05:00
|
|
|
log "found all error patterns";
|
|
|
|
ret;
|
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
next_err_pat = props.error_patterns[next_err_idx];
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let missing_patterns =
|
2011-08-15 18:38:23 -05:00
|
|
|
vec::slice(props.error_patterns, next_err_idx,
|
2011-08-19 17:16:48 -05:00
|
|
|
vec::len(props.error_patterns));
|
2011-08-15 18:38:23 -05:00
|
|
|
if vec::len(missing_patterns) == 1u {
|
2011-08-19 17:16:48 -05:00
|
|
|
fatal_procres(#fmt["error pattern '%s' not found!",
|
|
|
|
missing_patterns[0]], procres);
|
2011-07-30 23:11:14 -05:00
|
|
|
} else {
|
2011-08-15 23:54:52 -05:00
|
|
|
for pattern: str in missing_patterns {
|
2011-08-19 17:16:48 -05:00
|
|
|
error(#fmt["error pattern '%s' not found!", pattern]);
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
fatal_procres("multiple error patterns not found", procres);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-11 17:57:30 -05:00
|
|
|
type procargs = {prog: str, args: [str]};
|
2011-07-30 23:11:14 -05:00
|
|
|
|
|
|
|
type procres = {status: int, stdout: str, stderr: str, cmdline: str};
|
|
|
|
|
|
|
|
fn compile_test(cx: &cx, props: &test_props, testfile: &str) -> procres {
|
|
|
|
compose_and_run(cx, testfile, bind make_compile_args(_, props, _),
|
2011-07-31 17:33:40 -05:00
|
|
|
cx.config.compile_lib_path, option::none)
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
fn exec_compiled_test(cx: &cx, props: &test_props, testfile: &str) ->
|
|
|
|
procres {
|
2011-08-10 15:36:57 -05:00
|
|
|
compose_and_run(cx, testfile, bind make_run_args(_, props, _),
|
2011-07-31 17:33:40 -05:00
|
|
|
cx.config.run_lib_path, option::none)
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn compose_and_run(cx: &cx, testfile: &str,
|
2011-08-24 20:01:10 -05:00
|
|
|
make_args: fn(&config, &str) -> procargs, lib_path: &istr,
|
2011-08-10 11:27:22 -05:00
|
|
|
input: option::t<str>) -> procres {
|
2011-07-30 23:11:14 -05:00
|
|
|
let procargs = make_args(cx.config, testfile);
|
2011-08-19 17:16:48 -05:00
|
|
|
ret program_output(cx, testfile, lib_path, procargs.prog, procargs.args,
|
2011-07-31 17:33:40 -05:00
|
|
|
input);
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
fn make_compile_args(config: &config, props: &test_props, testfile: &str) ->
|
|
|
|
procargs {
|
2011-08-24 20:01:10 -05:00
|
|
|
let prog = istr::to_estr(config.rustc_path);
|
2011-08-19 17:16:48 -05:00
|
|
|
let args = [testfile, "-o", make_exe_name(config, testfile)];
|
2011-08-24 20:01:10 -05:00
|
|
|
let rustcflags = alt config.rustcflags {
|
|
|
|
option::some(s) { option::some(istr::to_estr(s)) }
|
|
|
|
option::none. { option::none }
|
|
|
|
};
|
|
|
|
args += split_maybe_args(rustcflags);
|
2011-07-30 23:11:14 -05:00
|
|
|
args += split_maybe_args(props.compile_flags);
|
|
|
|
ret {prog: prog, args: args};
|
|
|
|
}
|
|
|
|
|
|
|
|
fn make_exe_name(config: &config, testfile: &str) -> str {
|
2011-08-25 13:11:21 -05:00
|
|
|
output_base_name(config, testfile) + istr::to_estr(os::exec_suffix())
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
fn make_run_args(config: &config, props: &test_props, testfile: &str) ->
|
|
|
|
procargs {
|
2011-08-24 20:01:10 -05:00
|
|
|
let toolargs = if !props.no_valgrind {
|
|
|
|
// If we've got another tool to run under (valgrind),
|
|
|
|
// then split apart its command
|
|
|
|
let runtool = alt config.runtool {
|
|
|
|
option::some(s) { option::some(istr::to_estr(s)) }
|
|
|
|
option::none. { option::none }
|
|
|
|
};
|
|
|
|
split_maybe_args(runtool)
|
|
|
|
} else { [] };
|
2011-08-19 17:16:48 -05:00
|
|
|
|
|
|
|
let args = toolargs + [make_exe_name(config, testfile)];
|
|
|
|
ret {prog: args[0], args: vec::slice(args, 1u, vec::len(args))};
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-10 11:27:22 -05:00
|
|
|
fn split_maybe_args(argstr: &option::t<str>) -> [str] {
|
2011-08-11 17:57:30 -05:00
|
|
|
fn rm_whitespace(v: &[str]) -> [str] {
|
2011-08-10 11:27:22 -05:00
|
|
|
fn flt(s: &str) -> option::t<str> {
|
2011-08-19 17:16:48 -05:00
|
|
|
if !is_whitespace(s) { option::some(s) } else { option::none }
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: This should be in std
|
|
|
|
fn is_whitespace(s: str) -> bool {
|
2011-08-19 17:16:48 -05:00
|
|
|
for c: u8 in s { if c != ' ' as u8 { ret false; } }
|
2011-07-30 23:11:14 -05:00
|
|
|
ret true;
|
|
|
|
}
|
2011-08-15 18:38:23 -05:00
|
|
|
vec::filter_map(flt, v)
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
alt argstr {
|
2011-08-11 19:33:13 -05:00
|
|
|
option::some(s) { rm_whitespace(str::split(s, ' ' as u8)) }
|
2011-08-19 17:16:48 -05:00
|
|
|
option::none. { [] }
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-24 20:01:10 -05:00
|
|
|
fn program_output(cx: &cx, testfile: &str, lib_path: &istr, prog: &str,
|
2011-08-10 11:27:22 -05:00
|
|
|
args: &[str], input: option::t<str>) -> procres {
|
2011-08-24 20:01:10 -05:00
|
|
|
let lib_path = istr::to_estr(lib_path);
|
2011-07-30 23:11:14 -05:00
|
|
|
let cmdline =
|
2011-08-19 17:16:48 -05:00
|
|
|
{
|
|
|
|
let cmdline = make_cmdline(lib_path, prog, args);
|
|
|
|
logv(cx.config, #fmt["executing %s", cmdline]);
|
|
|
|
cmdline
|
|
|
|
};
|
|
|
|
let res = procsrv::run(cx.procsrv, lib_path, prog, args, input);
|
2011-07-30 23:11:14 -05:00
|
|
|
dump_output(cx.config, testfile, res.out, res.err);
|
2011-08-19 17:16:48 -05:00
|
|
|
ret {status: res.status,
|
|
|
|
stdout: res.out,
|
|
|
|
stderr: res.err,
|
|
|
|
cmdline: cmdline};
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-11 17:57:30 -05:00
|
|
|
fn make_cmdline(libpath: &str, prog: &str, args: &[str]) -> str {
|
2011-08-19 17:16:48 -05:00
|
|
|
#fmt["%s %s %s", lib_path_cmd_prefix(libpath), prog,
|
|
|
|
str::connect(args, " ")]
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Build the LD_LIBRARY_PATH variable as it would be seen on the command line
|
|
|
|
// for diagnostic purposes
|
|
|
|
fn lib_path_cmd_prefix(path: &str) -> str {
|
2011-08-19 17:16:48 -05:00
|
|
|
#fmt["%s=\"%s\"", util::lib_path_env_var(), util::make_new_path(path)]
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
fn dump_output(config: &config, testfile: &str, out: &str, err: &str) {
|
2011-07-30 23:11:14 -05:00
|
|
|
dump_output_file(config, testfile, out, "out");
|
|
|
|
dump_output_file(config, testfile, err, "err");
|
|
|
|
maybe_dump_to_stdout(config, out, err);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_os = "win32")]
|
|
|
|
#[cfg(target_os = "linux")]
|
2011-08-19 17:16:48 -05:00
|
|
|
fn dump_output_file(config: &config, testfile: &str, out: &str,
|
|
|
|
extension: &str) {
|
2011-07-30 23:11:14 -05:00
|
|
|
let outfile = make_out_name(config, testfile, extension);
|
2011-08-24 23:26:19 -05:00
|
|
|
let writer = io::file_writer(istr::from_estr(outfile),
|
|
|
|
[io::create, io::truncate]);
|
|
|
|
writer.write_str(istr::from_estr(out));
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME (726): Can't use file_writer on mac
|
|
|
|
#[cfg(target_os = "macos")]
|
2011-08-19 17:16:48 -05:00
|
|
|
fn dump_output_file(config: &config, testfile: &str, out: &str,
|
|
|
|
extension: &str) {
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
fn make_out_name(config: &config, testfile: &str, extension: &str) -> str {
|
2011-07-30 23:11:14 -05:00
|
|
|
output_base_name(config, testfile) + "." + extension
|
|
|
|
}
|
|
|
|
|
|
|
|
fn output_base_name(config: &config, testfile: &str) -> str {
|
2011-08-24 20:01:10 -05:00
|
|
|
let base = istr::to_estr(config.build_base);
|
2011-07-30 23:11:14 -05:00
|
|
|
let filename =
|
|
|
|
{
|
2011-08-24 18:00:26 -05:00
|
|
|
let parts = istr::split(fs::basename(istr::from_estr(testfile)),
|
|
|
|
'.' as u8);
|
2011-08-15 18:38:23 -05:00
|
|
|
parts = vec::slice(parts, 0u, vec::len(parts) - 1u);
|
2011-08-24 18:00:26 -05:00
|
|
|
istr::connect(parts, ~".")
|
2011-07-30 23:11:14 -05:00
|
|
|
};
|
2011-08-24 20:01:10 -05:00
|
|
|
#fmt["%s%s.%s", base, istr::to_estr(filename),
|
|
|
|
istr::to_estr(config.stage_id)]
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
fn maybe_dump_to_stdout(config: &config, out: &str, err: &str) {
|
2011-07-30 23:11:14 -05:00
|
|
|
if config.verbose {
|
2011-08-19 17:16:48 -05:00
|
|
|
let sep1 = #fmt["------%s------------------------------", "stdout"];
|
|
|
|
let sep2 = #fmt["------%s------------------------------", "stderr"];
|
2011-07-30 23:11:14 -05:00
|
|
|
let sep3 = "------------------------------------------";
|
2011-08-24 23:26:19 -05:00
|
|
|
io::stdout().write_line(istr::from_estr(sep1));
|
|
|
|
io::stdout().write_line(istr::from_estr(out));
|
|
|
|
io::stdout().write_line(istr::from_estr(sep2));
|
|
|
|
io::stdout().write_line(istr::from_estr(err));
|
|
|
|
io::stdout().write_line(istr::from_estr(sep3));
|
2011-07-30 23:11:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-24 23:26:19 -05:00
|
|
|
fn error(err: &str) {
|
|
|
|
io::stdout().write_line(istr::from_estr(#fmt["\nerror: %s", err]));
|
|
|
|
}
|
2011-07-30 23:11:14 -05:00
|
|
|
|
|
|
|
fn fatal(err: &str) -> ! { error(err); fail; }
|
|
|
|
|
|
|
|
fn fatal_procres(err: &str, procres: procres) -> ! {
|
|
|
|
let msg =
|
2011-08-24 23:26:19 -05:00
|
|
|
istr::from_estr(#fmt["\n\
|
2011-07-30 23:11:14 -05:00
|
|
|
error: %s\n\
|
|
|
|
command: %s\n\
|
|
|
|
stdout:\n\
|
|
|
|
------------------------------------------\n\
|
|
|
|
%s\n\
|
|
|
|
------------------------------------------\n\
|
|
|
|
stderr:\n\
|
|
|
|
------------------------------------------\n\
|
|
|
|
%s\n\
|
|
|
|
------------------------------------------\n\
|
|
|
|
\n",
|
2011-08-24 23:26:19 -05:00
|
|
|
err, procres.cmdline, procres.stdout, procres.stderr]);
|
2011-08-11 21:14:38 -05:00
|
|
|
io::stdout().write_str(msg);
|
2011-07-30 23:11:14 -05:00
|
|
|
fail;
|
|
|
|
}
|