cranelift_reader/
isaspec.rs1use crate::error::{Location, ParseError};
10use crate::testcommand::TestOption;
11use cranelift_codegen::isa::{OwnedTargetIsa, TargetIsa};
12use cranelift_codegen::settings::{Configurable, Flags, SetError};
13
14pub enum IsaSpec {
16 None(Flags),
19
20 Some(Vec<OwnedTargetIsa>),
23}
24
25impl IsaSpec {
26 pub fn unique_isa(&self) -> Option<&dyn TargetIsa> {
28 if let Self::Some(ref isa_vec) = *self {
29 if isa_vec.len() == 1 {
30 return Some(&*isa_vec[0]);
31 }
32 }
33 None
34 }
35}
36
37pub enum ParseOptionError {
39 Generic(ParseError),
41
42 UnknownFlag {
44 loc: Location,
46 name: String,
48 },
49
50 UnknownValue {
52 loc: Location,
54 name: String,
56 value: String,
58 },
59}
60
61impl From<ParseOptionError> for ParseError {
62 fn from(err: ParseOptionError) -> Self {
63 match err {
64 ParseOptionError::Generic(err) => err,
65 ParseOptionError::UnknownFlag { loc, name } => Self {
66 location: loc,
67 message: format!("unknown setting '{name}'"),
68 is_warning: false,
69 },
70 ParseOptionError::UnknownValue { loc, name, value } => Self {
71 location: loc,
72 message: format!("unknown setting '{name}={value}'"),
73 is_warning: false,
74 },
75 }
76 }
77}
78
79macro_rules! option_err {
80 ( $loc:expr, $fmt:expr, $( $arg:expr ),+ ) => {
81 Err($crate::ParseOptionError::Generic($crate::ParseError {
82 location: $loc.clone(),
83 message: format!( $fmt, $( $arg ),+ ),
84 is_warning: false,
85 }))
86 };
87}
88
89pub fn parse_options<'a, I>(
93 iter: I,
94 config: &mut dyn Configurable,
95 loc: Location,
96) -> Result<(), ParseOptionError>
97where
98 I: Iterator<Item = &'a str>,
99{
100 for opt in iter {
101 parse_option(opt, config, loc)?;
102 }
103 Ok(())
104}
105
106pub fn parse_option(
108 opt: &str,
109 config: &mut dyn Configurable,
110 loc: Location,
111) -> Result<(), ParseOptionError> {
112 match TestOption::new(opt) {
113 TestOption::Flag(name) => match config.enable(name) {
114 Ok(_) => Ok(()),
115 Err(SetError::BadName(name)) => Err(ParseOptionError::UnknownFlag { loc, name }),
116 Err(_) => option_err!(loc, "not a boolean flag: '{}'", opt),
117 },
118 TestOption::Value(name, value) => match config.set(name, value) {
119 Ok(_) => Ok(()),
120 Err(SetError::BadName(name)) => Err(ParseOptionError::UnknownValue {
121 loc,
122 name,
123 value: value.to_string(),
124 }),
125 Err(SetError::BadType) => option_err!(loc, "invalid setting type: '{}'", opt),
126 Err(SetError::BadValue(expected)) => {
127 option_err!(
128 loc,
129 "invalid setting value for '{}', expected {}",
130 opt,
131 expected
132 )
133 }
134 },
135 }
136}