about summary refs log tree commit diff
path: root/library/stdarch/crates/intrinsic-test/src/common/cli.rs
blob: baa21961e169bb1a90a434c21cfbc06ecdcf216e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use itertools::Itertools;
use std::path::PathBuf;

/// Intrinsic test tool
#[derive(clap::Parser)]
#[command(
    name = "Intrinsic test tool",
    about = "Generates Rust and C programs for intrinsics and compares the output"
)]
pub struct Cli {
    /// The input file containing the intrinsics
    pub input: PathBuf,

    /// The rust toolchain to use for building the rust code
    #[arg(long)]
    pub toolchain: Option<String>,

    /// The C++ compiler to use for compiling the c++ code
    #[arg(long, default_value_t = String::from("clang++"))]
    pub cppcompiler: String,

    /// Run the C programs under emulation with this command
    #[arg(long)]
    pub runner: Option<String>,

    /// Filename for a list of intrinsics to skip (one per line)
    #[arg(long)]
    pub skip: Option<PathBuf>,

    /// Regenerate test programs, but don't build or run them
    #[arg(long)]
    pub generate_only: bool,

    /// Pass a target the test suite
    #[arg(long, default_value_t = String::from("aarch64-unknown-linux-gnu"))]
    pub target: String,

    /// Set the linker
    #[arg(long)]
    pub linker: Option<String>,

    /// Set the sysroot for the C++ compiler
    #[arg(long)]
    pub cxx_toolchain_dir: Option<String>,
}

pub struct ProcessedCli {
    pub filename: PathBuf,
    pub toolchain: Option<String>,
    pub cpp_compiler: Option<String>,
    pub c_runner: String,
    pub target: String,
    pub linker: Option<String>,
    pub cxx_toolchain_dir: Option<String>,
    pub skip: Vec<String>,
}

impl ProcessedCli {
    pub fn new(cli_options: Cli) -> Self {
        let filename = cli_options.input;
        let c_runner = cli_options.runner.unwrap_or_default();
        let target = cli_options.target;
        let linker = cli_options.linker;
        let cxx_toolchain_dir = cli_options.cxx_toolchain_dir;

        let skip = if let Some(filename) = cli_options.skip {
            let data = std::fs::read_to_string(&filename).expect("Failed to open file");
            data.lines()
                .map(str::trim)
                .filter(|s| !s.contains('#'))
                .map(String::from)
                .collect_vec()
        } else {
            Default::default()
        };

        let (toolchain, cpp_compiler) = if cli_options.generate_only {
            (None, None)
        } else {
            (
                Some(
                    cli_options
                        .toolchain
                        .map_or_else(String::new, |t| format!("+{t}")),
                ),
                Some(cli_options.cppcompiler),
            )
        };

        Self {
            toolchain: toolchain,
            cpp_compiler: cpp_compiler,
            c_runner: c_runner,
            target: target,
            linker: linker,
            cxx_toolchain_dir: cxx_toolchain_dir,
            skip: skip,
            filename: filename,
        }
    }
}