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,
}
}
}
|