use log::*;
-use crate::common::{self, CompareMode, Config, FailMode, Mode, PassMode};
+use crate::common::{CompareMode, Config, Debugger, FailMode, Mode, PassMode};
use crate::extract_gdb_version;
use crate::util;
#[cfg(test)]
mod tests;
-/// Whether to ignore the test.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub enum Ignore {
- /// Runs it.
- Run,
- /// Ignore it totally.
- Ignore,
- /// Ignore only the gdb test, but run the lldb test.
- IgnoreGdb,
- /// Ignore only the lldb test, but run the gdb test.
- IgnoreLldb,
-}
-
-impl Ignore {
- pub fn can_run_gdb(&self) -> bool {
- *self == Ignore::Run || *self == Ignore::IgnoreLldb
- }
-
- pub fn can_run_lldb(&self) -> bool {
- *self == Ignore::Run || *self == Ignore::IgnoreGdb
- }
-
- pub fn no_gdb(&self) -> Ignore {
- match *self {
- Ignore::Run => Ignore::IgnoreGdb,
- Ignore::IgnoreGdb => Ignore::IgnoreGdb,
- _ => Ignore::Ignore,
- }
- }
-
- pub fn no_lldb(&self) -> Ignore {
- match *self {
- Ignore::Run => Ignore::IgnoreLldb,
- Ignore::IgnoreLldb => Ignore::IgnoreLldb,
- _ => Ignore::Ignore,
- }
- }
-}
-
/// The result of parse_cfg_name_directive.
#[derive(Clone, Copy, PartialEq, Debug)]
enum ParsedNameDirective {
NoMatch,
/// Match.
Match,
- /// Mode was DebugInfoGdbLldb and this matched gdb.
- MatchGdb,
- /// Mode was DebugInfoGdbLldb and this matched lldb.
- MatchLldb,
}
/// Properties which must be known very early, before actually running
/// the test.
+#[derive(Default)]
pub struct EarlyProps {
- pub ignore: Ignore,
+ pub ignore: bool,
pub should_fail: bool,
pub aux: Vec<String>,
pub aux_crate: Vec<(String, String)>,
impl EarlyProps {
pub fn from_file(config: &Config, testfile: &Path) -> Self {
- let mut props = EarlyProps {
- ignore: Ignore::Run,
- should_fail: false,
- aux: Vec::new(),
- aux_crate: Vec::new(),
- revisions: vec![],
- };
-
- if config.mode == common::DebugInfoGdbLldb {
- if config.lldb_python_dir.is_none() {
- props.ignore = props.ignore.no_lldb();
- }
- if config.gdb_version.is_none() {
- props.ignore = props.ignore.no_gdb();
- }
- } else if config.mode == common::DebugInfoCdb {
- if config.cdb.is_none() {
- props.ignore = Ignore::Ignore;
- }
- }
+ let file = File::open(testfile).unwrap();
+ Self::from_reader(config, testfile, file)
+ }
+ pub fn from_reader<R: Read>(config: &Config, testfile: &Path, rdr: R) -> Self {
+ let mut props = EarlyProps::default();
let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some();
- iter_header(testfile, None, &mut |ln| {
+ iter_header(testfile, None, rdr, &mut |ln| {
// we should check if any only-<platform> exists and if it exists
// and does not matches the current platform, skip the test
- if props.ignore != Ignore::Ignore {
+ if !props.ignore {
props.ignore = match config.parse_cfg_name_directive(ln, "ignore") {
- ParsedNameDirective::Match => Ignore::Ignore,
+ ParsedNameDirective::Match => true,
ParsedNameDirective::NoMatch => props.ignore,
- ParsedNameDirective::MatchGdb => props.ignore.no_gdb(),
- ParsedNameDirective::MatchLldb => props.ignore.no_lldb(),
};
if config.has_cfg_prefix(ln, "only") {
props.ignore = match config.parse_cfg_name_directive(ln, "only") {
ParsedNameDirective::Match => props.ignore,
- ParsedNameDirective::NoMatch => Ignore::Ignore,
- ParsedNameDirective::MatchLldb => props.ignore.no_gdb(),
- ParsedNameDirective::MatchGdb => props.ignore.no_lldb(),
+ ParsedNameDirective::NoMatch => true,
};
}
if ignore_llvm(config, ln) {
- props.ignore = Ignore::Ignore;
+ props.ignore = true;
}
if config.run_clang_based_tests_with.is_none()
&& config.parse_needs_matching_clang(ln)
{
- props.ignore = Ignore::Ignore;
+ props.ignore = true;
}
if !rustc_has_profiler_support && config.parse_needs_profiler_support(ln) {
- props.ignore = Ignore::Ignore;
+ props.ignore = true;
}
if !rustc_has_sanitizer_support && config.parse_needs_sanitizer_support(ln) {
- props.ignore = Ignore::Ignore;
+ props.ignore = true;
}
if config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln) {
- props.ignore = Ignore::Ignore;
+ props.ignore = true;
}
- }
- if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoGdbLldb)
- && props.ignore.can_run_gdb()
- && ignore_gdb(config, ln)
- {
- props.ignore = props.ignore.no_gdb();
- }
+ if config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln) {
+ props.ignore = true;
+ }
- if (config.mode == common::DebugInfoLldb || config.mode == common::DebugInfoGdbLldb)
- && props.ignore.can_run_lldb()
- && ignore_lldb(config, ln)
- {
- props.ignore = props.ignore.no_lldb();
+ if config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln) {
+ props.ignore = true;
+ }
}
if let Some(s) = config.parse_aux_build(ln) {
/// `//[foo]`), then the property is ignored unless `cfg` is
/// `Some("foo")`.
fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
- iter_header(testfile, cfg, &mut |ln| {
+ let file = File::open(testfile).unwrap();
+ iter_header(testfile, cfg, file, &mut |ln| {
if let Some(ep) = config.parse_error_pattern(ln) {
self.error_patterns.push(ep);
}
}
}
-fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
+fn iter_header<R: Read>(testfile: &Path, cfg: Option<&str>, rdr: R, it: &mut dyn FnMut(&str)) {
if testfile.is_dir() {
return;
}
// It took me like 2 days to debug why compile-flags weren’t taken into account for my test :)
let comment_with_brace = comment.to_string() + "[";
- let rdr = BufReader::new(File::open(testfile).unwrap());
- for ln in rdr.lines() {
+ let mut rdr = BufReader::new(rdr);
+ let mut ln = String::new();
+
+ loop {
+ ln.clear();
+ if rdr.read_line(&mut ln).unwrap() == 0 {
+ break;
+ }
+
// Assume that any directives will be found before the first
// module or function. This doesn't seem to be an optimization
// with a warm page cache. Maybe with a cold one.
- let ln = ln.unwrap();
let ln = ln.trim();
if ln.starts_with("fn") || ln.starts_with("mod") {
return;
/// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
/// or `normalize-stderr-32bit`.
fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
- if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') {
- let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap();
-
- if name == "test" ||
- &self.target == name || // triple
- util::matches_os(&self.target, name) || // target
- util::matches_env(&self.target, name) || // env
- name == util::get_arch(&self.target) || // architecture
- name == util::get_pointer_width(&self.target) || // pointer width
- name == self.stage_id.split('-').next().unwrap() || // stage
- (self.target != self.host && name == "cross-compile") ||
- match self.compare_mode {
- Some(CompareMode::Nll) => name == "compare-mode-nll",
- Some(CompareMode::Polonius) => name == "compare-mode-polonius",
- None => false,
- } ||
- (cfg!(debug_assertions) && name == "debug")
- {
- ParsedNameDirective::Match
- } else {
- match self.mode {
- common::DebugInfoGdbLldb => {
- if name == "gdb" {
- ParsedNameDirective::MatchGdb
- } else if name == "lldb" {
- ParsedNameDirective::MatchLldb
- } else {
- ParsedNameDirective::NoMatch
- }
- }
- common::DebugInfoCdb => {
- if name == "cdb" {
- ParsedNameDirective::Match
- } else {
- ParsedNameDirective::NoMatch
- }
- }
- common::DebugInfoGdb => {
- if name == "gdb" {
- ParsedNameDirective::Match
- } else {
- ParsedNameDirective::NoMatch
- }
- }
- common::DebugInfoLldb => {
- if name == "lldb" {
- ParsedNameDirective::Match
- } else {
- ParsedNameDirective::NoMatch
- }
- }
- common::Pretty => {
- if name == "pretty" {
- ParsedNameDirective::Match
- } else {
- ParsedNameDirective::NoMatch
- }
- }
- _ => ParsedNameDirective::NoMatch,
- }
- }
- } else {
- ParsedNameDirective::NoMatch
+ if !line.as_bytes().starts_with(prefix.as_bytes()) {
+ return ParsedNameDirective::NoMatch;
+ }
+ if line.as_bytes().get(prefix.len()) != Some(&b'-') {
+ return ParsedNameDirective::NoMatch;
}
+
+ let name = line[prefix.len() + 1..].split(&[':', ' '][..]).next().unwrap();
+
+ let is_match = name == "test" ||
+ &self.target == name || // triple
+ util::matches_os(&self.target, name) || // target
+ util::matches_env(&self.target, name) || // env
+ name == util::get_arch(&self.target) || // architecture
+ name == util::get_pointer_width(&self.target) || // pointer width
+ name == self.stage_id.split('-').next().unwrap() || // stage
+ (self.target != self.host && name == "cross-compile") ||
+ match self.compare_mode {
+ Some(CompareMode::Nll) => name == "compare-mode-nll",
+ Some(CompareMode::Polonius) => name == "compare-mode-polonius",
+ None => false,
+ } ||
+ (cfg!(debug_assertions) && name == "debug") ||
+ match self.debugger {
+ Some(Debugger::Cdb) => name == "cdb",
+ Some(Debugger::Gdb) => name == "gdb",
+ Some(Debugger::Lldb) => name == "lldb",
+ None => false,
+ };
+
+ if is_match { ParsedNameDirective::Match } else { ParsedNameDirective::NoMatch }
}
fn has_cfg_prefix(&self, line: &str, prefix: &str) -> bool {