diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index a7f693da6cc..1c629e5a5fd 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -91,6 +91,9 @@ pub struct Config { // Only run tests that match this filter pub filter: Option, + // Precompiled regex for finding expected errors in cfail + pub cfail_regex: Regex, + // Write out a parseable log of tests that were run pub logfile: Option, @@ -144,5 +147,4 @@ pub struct Config { // Explain what's going on pub verbose: bool - } diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 3fb354a7867..db9cf358a9b 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -33,6 +33,7 @@ use getopts::{optopt, optflag, reqopt}; use common::Config; use common::{Pretty, DebugInfoGdb, Codegen}; use util::logv; +use regex::Regex; pub mod procsrv; pub mod util; @@ -147,6 +148,7 @@ pub fn parse_config(args: Vec ) -> Config { .as_slice()).expect("invalid mode"), run_ignored: matches.opt_present("ignored"), filter: filter, + cfail_regex: Regex::new(errors::EXPECTED_PATTERN).unwrap(), logfile: matches.opt_str("logfile").map(|s| Path::new(s)), save_metrics: matches.opt_str("save-metrics").map(|s| Path::new(s)), ratchet_metrics: diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 4e65115caa2..408206b16e9 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -9,6 +9,7 @@ // except according to those terms. use std::io::{BufferedReader, File}; +use regex::Regex; pub struct ExpectedError { pub line: uint, @@ -16,61 +17,28 @@ pub struct ExpectedError { pub msg: StrBuf, } +pub static EXPECTED_PATTERN : &'static str = r"//~(?P\^*)\s*(?P\S*)\s*(?P.*)"; + // Load any test directives embedded in the file -pub fn load_errors(testfile: &Path) -> Vec { - - let mut error_patterns = Vec::new(); +pub fn load_errors(re: &Regex, testfile: &Path) -> Vec { let mut rdr = BufferedReader::new(File::open(testfile).unwrap()); - let mut line_num = 1u; - for ln in rdr.lines() { - error_patterns.push_all_move(parse_expected(line_num, - ln.unwrap().to_strbuf())); - line_num += 1u; - } - return error_patterns; + + rdr.lines().enumerate().filter_map(|(line_no, ln)| { + parse_expected(line_no + 1, ln.unwrap(), re) + }).collect() } -fn parse_expected(line_num: uint, line: StrBuf) -> Vec { - let line = line.as_slice().trim().to_strbuf(); - let error_tag = "//~".to_strbuf(); - let mut idx; - match line.as_slice().find_str(error_tag.as_slice()) { - None => return Vec::new(), - Some(nn) => { idx = (nn as uint) + error_tag.len(); } - } +fn parse_expected(line_num: uint, line: &str, re: &Regex) -> Option { + re.captures(line).and_then(|caps| { + let adjusts = caps.name("adjusts").len(); + let kind = caps.name("kind").to_ascii().to_lower().into_str().to_strbuf(); + let msg = caps.name("msg").trim().to_strbuf(); - // "//~^^^ kind msg" denotes a message expected - // three lines above current line: - let mut adjust_line = 0u; - let len = line.len(); - while idx < len && line.as_slice()[idx] == ('^' as u8) { - adjust_line += 1u; - idx += 1u; - } - - // Extract kind: - while idx < len && line.as_slice()[idx] == (' ' as u8) { - idx += 1u; - } - let start_kind = idx; - while idx < len && line.as_slice()[idx] != (' ' as u8) { - idx += 1u; - } - - let kind = line.as_slice().slice(start_kind, idx); - let kind = kind.to_ascii().to_lower().into_str().to_strbuf(); - - // Extract msg: - while idx < len && line.as_slice()[idx] == (' ' as u8) { - idx += 1u; - } - let msg = line.as_slice().slice(idx, len).to_strbuf(); - - debug!("line={} kind={} msg={}", line_num - adjust_line, kind, msg); - - return vec!(ExpectedError{ - line: line_num - adjust_line, - kind: kind, - msg: msg, - }); + debug!("line={} kind={} msg={}", line_num, kind, msg); + Some(ExpectedError { + line: line_num - adjusts, + kind: kind, + msg: msg, + }) + }) } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index cd00a949bf8..8c2b34ff35d 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -79,7 +79,7 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) { check_correct_failure_status(&proc_res); - let expected_errors = errors::load_errors(testfile); + let expected_errors = errors::load_errors(&config.cfail_regex, testfile); if !expected_errors.is_empty() { if !props.error_patterns.is_empty() { fatal("both error pattern and expected errors \