about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPietro Albini <pietro.albini@ferrous-systems.com>2023-03-10 12:32:02 +0100
committerPietro Albini <pietro.albini@ferrous-systems.com>2023-04-03 09:30:28 +0200
commit9cb4373a8458e38c1ed8b1d8e768e11f305e551f (patch)
tree2423c1ebe6328e88c938ef956f777beb4cf082aa
parent8eb3def446b7026b2ff2a981791e5fc6fe031944 (diff)
downloadrust-9cb4373a8458e38c1ed8b1d8e768e11f305e551f.tar.gz
rust-9cb4373a8458e38c1ed8b1d8e768e11f305e551f.zip
move cfg handling into its own module
-rw-r--r--src/tools/compiletest/src/header.rs237
-rw-r--r--src/tools/compiletest/src/header/cfg.rs233
2 files changed, 239 insertions, 231 deletions
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index b0b66e23201..50b99b80572 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -8,41 +8,16 @@ use std::process::Command;
 
 use tracing::*;
 
-use crate::common::CompareMode;
 use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
+use crate::header::cfg::parse_cfg_name_directive;
+use crate::header::cfg::MatchOutcome;
 use crate::util;
 use crate::{extract_cdb_version, extract_gdb_version};
 
+mod cfg;
 #[cfg(test)]
 mod tests;
 
-/// The result of parse_cfg_name_directive.
-#[derive(Clone, PartialEq, Debug)]
-struct ParsedNameDirective<'a> {
-    name: Option<&'a str>,
-    pretty_reason: Option<String>,
-    comment: Option<&'a str>,
-    outcome: MatchOutcome,
-}
-
-impl ParsedNameDirective<'_> {
-    fn invalid() -> Self {
-        Self { name: None, pretty_reason: None, comment: None, outcome: MatchOutcome::NoMatch }
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Debug)]
-enum MatchOutcome {
-    /// No match.
-    NoMatch,
-    /// Match.
-    Match,
-    /// The directive was invalid.
-    Invalid,
-    /// The directive is handled by other parts of our tooling.
-    External,
-}
-
 /// Properties which must be known very early, before actually running
 /// the test.
 #[derive(Default)]
@@ -666,7 +641,7 @@ impl Config {
     }
 
     fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> {
-        if self.parse_cfg_name_directive(line, prefix).outcome == MatchOutcome::Match {
+        if parse_cfg_name_directive(self, line, prefix).outcome == MatchOutcome::Match {
             let from = parse_normalization_string(&mut line)?;
             let to = parse_normalization_string(&mut line)?;
             Some((from, to))
@@ -683,206 +658,6 @@ impl Config {
         self.parse_name_directive(line, "needs-profiler-support")
     }
 
-    /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
-    /// or `normalize-stderr-32bit`.
-    fn parse_cfg_name_directive<'a>(&self, line: &'a str, prefix: &str) -> ParsedNameDirective<'a> {
-        if !line.as_bytes().starts_with(prefix.as_bytes()) {
-            return ParsedNameDirective::invalid();
-        }
-        if line.as_bytes().get(prefix.len()) != Some(&b'-') {
-            return ParsedNameDirective::invalid();
-        }
-        let line = &line[prefix.len() + 1..];
-
-        let (name, comment) =
-            line.split_once(&[':', ' ']).map(|(l, c)| (l, Some(c))).unwrap_or((line, None));
-
-        // Some of the matchers might be "" depending on what the target information is. To avoid
-        // problems we outright reject empty directives.
-        if name == "" {
-            return ParsedNameDirective::invalid();
-        }
-
-        let mut outcome = MatchOutcome::Invalid;
-        let mut message = None;
-
-        macro_rules! maybe_condition {
-            (
-                name: $name:expr,
-                $(allowed_names: $allowed_names:expr,)?
-                $(condition: $condition:expr,)?
-                message: $($message:tt)*
-            ) => {{
-                // This is not inlined to avoid problems with macro repetitions.
-                let format_message = || format!($($message)*);
-
-                if outcome != MatchOutcome::Invalid {
-                    // Ignore all other matches if we already found one
-                } else if $name.as_ref().map(|n| n == &name).unwrap_or(false) {
-                    message = Some(format_message());
-                    if true $(&& $condition)? {
-                        outcome = MatchOutcome::Match;
-                    } else {
-                        outcome = MatchOutcome::NoMatch;
-                    }
-                }
-                $(else if $allowed_names.contains(name) {
-                    message = Some(format_message());
-                    outcome = MatchOutcome::NoMatch;
-                })?
-            }};
-        }
-        macro_rules! condition {
-            (
-                name: $name:expr,
-                $(allowed_names: $allowed_names:expr,)?
-                $(condition: $condition:expr,)?
-                message: $($message:tt)*
-            ) => {
-                maybe_condition! {
-                    name: Some($name),
-                    $(allowed_names: $allowed_names,)*
-                    $(condition: $condition,)*
-                    message: $($message)*
-                }
-            };
-        }
-        macro_rules! hashset {
-            ($($value:expr),* $(,)?) => {{
-                let mut set = HashSet::new();
-                $(set.insert($value);)*
-                set
-            }}
-        }
-
-        let target_cfgs = self.target_cfgs();
-        let target_cfg = self.target_cfg();
-
-        condition! {
-            name: "test",
-            message: "always"
-        }
-        condition! {
-            name: &self.target,
-            allowed_names: &target_cfgs.all_targets,
-            message: "when the target is {name}"
-        }
-        condition! {
-            name: &target_cfg.os,
-            allowed_names: &target_cfgs.all_oses,
-            message: "when the operative system is {name}"
-        }
-        condition! {
-            name: &target_cfg.env,
-            allowed_names: &target_cfgs.all_envs,
-            message: "when the target environment is {name}"
-        }
-        condition! {
-            name: &target_cfg.abi,
-            allowed_names: &target_cfgs.all_abis,
-            message: "when the ABI is {name}"
-        }
-        condition! {
-            name: &target_cfg.arch,
-            allowed_names: &target_cfgs.all_archs,
-            message: "when the architecture is {name}"
-        }
-        condition! {
-            name: format!("{}bit", target_cfg.pointer_width),
-            allowed_names: &target_cfgs.all_pointer_widths,
-            message: "when the pointer width is {name}"
-        }
-        for family in &target_cfg.families {
-            condition! {
-                name: family,
-                allowed_names: &target_cfgs.all_families,
-                message: "when the target family is {name}"
-            }
-        }
-
-        // If something is ignored for emscripten, it likely also needs to be
-        // ignored for wasm32-unknown-unknown.
-        // `wasm32-bare` is an alias to refer to just wasm32-unknown-unknown
-        // (in contrast to `wasm32` which also matches non-bare targets like
-        // asmjs-unknown-emscripten).
-        condition! {
-            name: "emscripten",
-            condition: self.target == "wasm32-unknown-unknown",
-            message: "when the target is WASM",
-        }
-        condition! {
-            name: "wasm32-bare",
-            condition: self.target == "wasm32-unknown-unknown",
-            message: "when the target is WASM"
-        }
-
-        condition! {
-            name: &self.channel,
-            allowed_names: hashset!["stable", "beta", "nightly"],
-            message: "when the release channel is {name}",
-        }
-        condition! {
-            name: "cross-compile",
-            condition: self.target != self.host,
-            message: "when cross-compiling"
-        }
-        condition! {
-            name: "endian-big",
-            condition: self.is_big_endian(),
-            message: "on big-endian targets",
-        }
-        condition! {
-            name: self.stage_id.split('-').next().unwrap(),
-            allowed_names: hashset!["stable", "beta", "nightly"],
-            message: "when the bootstrapping stage is {name}",
-        }
-        condition! {
-            name: "remote",
-            condition: self.remote_test_client.is_some(),
-            message: "when running tests remotely",
-        }
-        condition! {
-            name: "debug",
-            condition: cfg!(debug_assertions),
-            message: "when building with debug assertions",
-        }
-        maybe_condition! {
-            name: self.debugger.as_ref().map(|d| d.to_str()),
-            allowed_names: Debugger::VARIANTS
-                .iter()
-                .map(|v| v.to_str())
-                .collect::<HashSet<_>>(),
-            message: "when the debugger is {name}",
-        }
-        maybe_condition! {
-            name: self.compare_mode
-                .as_ref()
-                .map(|d| format!("compare-mode-{}", d.to_str())),
-            allowed_names: CompareMode::VARIANTS
-                .iter()
-                .map(|cm| format!("compare-mode-{}", cm.to_str()))
-                .collect::<HashSet<_>>(),
-            message: "when comparing with {name}",
-        }
-
-        // Don't error out for ignore-tidy-* diretives, as those are not handled by compiletest.
-        if prefix == "ignore" && name.starts_with("tidy-") && outcome == MatchOutcome::Invalid {
-            outcome = MatchOutcome::External;
-        }
-
-        // Don't error out for ignore-pass, as that is handled elsewhere.
-        if prefix == "ignore" && name == "pass" && outcome == MatchOutcome::Invalid {
-            outcome = MatchOutcome::External;
-        }
-
-        ParsedNameDirective {
-            name: Some(name),
-            comment: comment.map(|c| c.trim().trim_start_matches('-').trim()),
-            outcome,
-            pretty_reason: message,
-        }
-    }
-
     fn has_cfg_prefix(&self, line: &str, prefix: &str) -> bool {
         // returns whether this line contains this prefix or not. For prefix
         // "ignore", returns true if line says "ignore-x86_64", "ignore-arch",
@@ -1151,7 +926,7 @@ pub fn make_test_description<R: Read>(
         }
 
         {
-            let parsed = config.parse_cfg_name_directive(ln, "ignore");
+            let parsed = parse_cfg_name_directive(config, ln, "ignore");
             ignore = match parsed.outcome {
                 MatchOutcome::Match => {
                     let reason = parsed.pretty_reason.unwrap();
@@ -1171,7 +946,7 @@ pub fn make_test_description<R: Read>(
         }
 
         if config.has_cfg_prefix(ln, "only") {
-            let parsed = config.parse_cfg_name_directive(ln, "only");
+            let parsed = parse_cfg_name_directive(config, ln, "only");
             ignore = match parsed.outcome {
                 MatchOutcome::Match => ignore,
                 MatchOutcome::NoMatch => {
diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs
new file mode 100644
index 00000000000..a6812792c27
--- /dev/null
+++ b/src/tools/compiletest/src/header/cfg.rs
@@ -0,0 +1,233 @@
+use crate::common::{Config, CompareMode, Debugger};
+use std::collections::HashSet;
+
+/// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
+/// or `normalize-stderr-32bit`.
+pub(super) fn parse_cfg_name_directive<'a>(
+    config: &Config,
+    line: &'a str,
+    prefix: &str,
+) -> ParsedNameDirective<'a> {
+    if !line.as_bytes().starts_with(prefix.as_bytes()) {
+        return ParsedNameDirective::invalid();
+    }
+    if line.as_bytes().get(prefix.len()) != Some(&b'-') {
+        return ParsedNameDirective::invalid();
+    }
+    let line = &line[prefix.len() + 1..];
+
+    let (name, comment) =
+        line.split_once(&[':', ' ']).map(|(l, c)| (l, Some(c))).unwrap_or((line, None));
+
+    // Some of the matchers might be "" depending on what the target information is. To avoid
+    // problems we outright reject empty directives.
+    if name == "" {
+        return ParsedNameDirective::invalid();
+    }
+
+    let mut outcome = MatchOutcome::Invalid;
+    let mut message = None;
+
+    macro_rules! maybe_condition {
+        (
+            name: $name:expr,
+            $(allowed_names: $allowed_names:expr,)?
+            $(condition: $condition:expr,)?
+            message: $($message:tt)*
+        ) => {{
+            // This is not inlined to avoid problems with macro repetitions.
+            let format_message = || format!($($message)*);
+
+            if outcome != MatchOutcome::Invalid {
+                // Ignore all other matches if we already found one
+            } else if $name.as_ref().map(|n| n == &name).unwrap_or(false) {
+                message = Some(format_message());
+                if true $(&& $condition)? {
+                    outcome = MatchOutcome::Match;
+                } else {
+                    outcome = MatchOutcome::NoMatch;
+                }
+            }
+            $(else if $allowed_names.contains(name) {
+                message = Some(format_message());
+                outcome = MatchOutcome::NoMatch;
+            })?
+        }};
+    }
+    macro_rules! condition {
+        (
+            name: $name:expr,
+            $(allowed_names: $allowed_names:expr,)?
+            $(condition: $condition:expr,)?
+            message: $($message:tt)*
+        ) => {
+            maybe_condition! {
+                name: Some($name),
+                $(allowed_names: $allowed_names,)*
+                $(condition: $condition,)*
+                message: $($message)*
+            }
+        };
+    }
+    macro_rules! hashset {
+        ($($value:expr),* $(,)?) => {{
+            let mut set = HashSet::new();
+            $(set.insert($value);)*
+            set
+        }}
+    }
+
+    let target_cfgs = config.target_cfgs();
+    let target_cfg = config.target_cfg();
+
+    condition! {
+        name: "test",
+        message: "always"
+    }
+    condition! {
+        name: &config.target,
+        allowed_names: &target_cfgs.all_targets,
+        message: "when the target is {name}"
+    }
+    condition! {
+        name: &target_cfg.os,
+        allowed_names: &target_cfgs.all_oses,
+        message: "when the operative system is {name}"
+    }
+    condition! {
+        name: &target_cfg.env,
+        allowed_names: &target_cfgs.all_envs,
+        message: "when the target environment is {name}"
+    }
+    condition! {
+        name: &target_cfg.abi,
+        allowed_names: &target_cfgs.all_abis,
+        message: "when the ABI is {name}"
+    }
+    condition! {
+        name: &target_cfg.arch,
+        allowed_names: &target_cfgs.all_archs,
+        message: "when the architecture is {name}"
+    }
+    condition! {
+        name: format!("{}bit", target_cfg.pointer_width),
+        allowed_names: &target_cfgs.all_pointer_widths,
+        message: "when the pointer width is {name}"
+    }
+    for family in &target_cfg.families {
+        condition! {
+            name: family,
+            allowed_names: &target_cfgs.all_families,
+            message: "when the target family is {name}"
+        }
+    }
+
+    // If something is ignored for emscripten, it likely also needs to be
+    // ignored for wasm32-unknown-unknown.
+    // `wasm32-bare` is an alias to refer to just wasm32-unknown-unknown
+    // (in contrast to `wasm32` which also matches non-bare targets like
+    // asmjs-unknown-emscripten).
+    condition! {
+        name: "emscripten",
+        condition: config.target == "wasm32-unknown-unknown",
+        message: "when the target is WASM",
+    }
+    condition! {
+        name: "wasm32-bare",
+        condition: config.target == "wasm32-unknown-unknown",
+        message: "when the target is WASM"
+    }
+
+    condition! {
+        name: &config.channel,
+        allowed_names: hashset!["stable", "beta", "nightly"],
+        message: "when the release channel is {name}",
+    }
+    condition! {
+        name: "cross-compile",
+        condition: config.target != config.host,
+        message: "when cross-compiling"
+    }
+    condition! {
+        name: "endian-big",
+        condition: config.is_big_endian(),
+        message: "on big-endian targets",
+    }
+    condition! {
+        name: config.stage_id.split('-').next().unwrap(),
+        allowed_names: hashset!["stable", "beta", "nightly"],
+        message: "when the bootstrapping stage is {name}",
+    }
+    condition! {
+        name: "remote",
+        condition: config.remote_test_client.is_some(),
+        message: "when running tests remotely",
+    }
+    condition! {
+        name: "debug",
+        condition: cfg!(debug_assertions),
+        message: "when building with debug assertions",
+    }
+    maybe_condition! {
+        name: config.debugger.as_ref().map(|d| d.to_str()),
+        allowed_names: Debugger::VARIANTS
+            .iter()
+            .map(|v| v.to_str())
+            .collect::<HashSet<_>>(),
+        message: "when the debugger is {name}",
+    }
+    maybe_condition! {
+        name: config.compare_mode
+            .as_ref()
+            .map(|d| format!("compare-mode-{}", d.to_str())),
+        allowed_names: CompareMode::VARIANTS
+            .iter()
+            .map(|cm| format!("compare-mode-{}", cm.to_str()))
+            .collect::<HashSet<_>>(),
+        message: "when comparing with {name}",
+    }
+
+    // Don't error out for ignore-tidy-* diretives, as those are not handled by compiletest.
+    if prefix == "ignore" && name.starts_with("tidy-") && outcome == MatchOutcome::Invalid {
+        outcome = MatchOutcome::External;
+    }
+
+    // Don't error out for ignore-pass, as that is handled elsewhere.
+    if prefix == "ignore" && name == "pass" && outcome == MatchOutcome::Invalid {
+        outcome = MatchOutcome::External;
+    }
+
+    ParsedNameDirective {
+        name: Some(name),
+        comment: comment.map(|c| c.trim().trim_start_matches('-').trim()),
+        outcome,
+        pretty_reason: message,
+    }
+}
+
+/// The result of parse_cfg_name_directive.
+#[derive(Clone, PartialEq, Debug)]
+pub(super) struct ParsedNameDirective<'a> {
+    pub(super) name: Option<&'a str>,
+    pub(super) pretty_reason: Option<String>,
+    pub(super) comment: Option<&'a str>,
+    pub(super) outcome: MatchOutcome,
+}
+
+impl ParsedNameDirective<'_> {
+    fn invalid() -> Self {
+        Self { name: None, pretty_reason: None, comment: None, outcome: MatchOutcome::NoMatch }
+    }
+}
+
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub(super) enum MatchOutcome {
+    /// No match.
+    NoMatch,
+    /// Match.
+    Match,
+    /// The directive was invalid.
+    Invalid,
+    /// The directive is handled by other parts of our tooling.
+    External,
+}