Skip to content

Commit f15a56d

Browse files
committed
Implement a proper command parser...
... that grabs things from the front instead of splitting at spaces and colons and hoping for the best
1 parent 63916d6 commit f15a56d

File tree

2 files changed

+34
-31
lines changed

2 files changed

+34
-31
lines changed

ui_test/src/comments.rs

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,7 @@ impl Comments {
9898
line: &str,
9999
) -> Result<()> {
100100
if let Some((_, command)) = line.split_once("//@") {
101-
let command = command.trim();
102-
if let Some((command, args)) = command.split_once(':') {
103-
self.parse_command_with_args(command, args, l)
104-
} else if let Some((command, _comments)) = command.split_once(' ') {
105-
self.parse_command(command)
106-
} else {
107-
self.parse_command(command)
108-
}
101+
self.parse_command(command.trim(), l)
109102
} else if let Some((_, pattern)) = line.split_once("//~") {
110103
self.parse_pattern(pattern, fallthrough_to, l)
111104
} else if let Some((_, pattern)) = line.split_once("//[") {
@@ -189,7 +182,22 @@ impl Comments {
189182
Ok(this)
190183
}
191184

192-
fn parse_command_with_args(&mut self, command: &str, args: &str, l: usize) -> Result<()> {
185+
fn parse_command(&mut self, command: &str, l: usize) -> Result<()> {
186+
// Commands are letters or dashes, grab everything until the first character that is neither of those.
187+
let (command, args) = match command.chars().position(|c: char| !c.is_alphabetic() && c != '-') {
188+
None => (command, ""),
189+
Some(i) => {
190+
let (command, args) = command.split_at(i);
191+
let mut args = args.chars();
192+
let next = args.next().expect("the `position` above guarantees that there is at least one char");
193+
let args = match next {
194+
':' | ' ' => args.as_str(),
195+
_ => bail!("expected space or `:`, got `{next}`"),
196+
};
197+
(command, args)
198+
}
199+
};
200+
193201
match command {
194202
"revisions" => {
195203
ensure!(self.revisions.is_none(), "cannot specifiy revisions twice");
@@ -222,30 +230,25 @@ impl Comments {
222230
);
223231
self.error_pattern = Some((args.trim().to_string(), l));
224232
}
225-
// Maybe the user just left a comment explaining a command without arguments
226-
_ => self.parse_command(command)?,
227-
}
228-
Ok(())
229-
}
230-
231-
fn parse_command(&mut self, command: &str) -> Result<()> {
232-
if let Some(s) = command.strip_prefix("ignore-") {
233-
self.ignore.push(Condition::parse(s));
234-
return Ok(());
235-
}
236-
237-
if let Some(s) = command.strip_prefix("only-") {
238-
self.only.push(Condition::parse(s));
239-
return Ok(());
240-
}
233+
"stderr-per-bitwidth" => {
234+
ensure!(!self.stderr_per_bitwidth, "cannot specifiy stderr-per-bitwidth twice");
235+
self.stderr_per_bitwidth = true;
236+
}
237+
command => {
238+
if let Some(s) = command.strip_prefix("ignore-") {
239+
self.ignore.push(Condition::parse(s));
240+
return Ok(());
241+
}
241242

242-
if command.starts_with("stderr-per-bitwidth") {
243-
ensure!(!self.stderr_per_bitwidth, "cannot specifiy stderr-per-bitwidth twice");
244-
self.stderr_per_bitwidth = true;
245-
return Ok(());
243+
if let Some(s) = command.strip_prefix("only-") {
244+
self.only.push(Condition::parse(s));
245+
return Ok(());
246+
}
247+
bail!("unknown command {command}");
248+
}
246249
}
247250

248-
bail!("unknown command {command}");
251+
Ok(())
249252
}
250253

251254
fn parse_pattern(

ui_test/src/comments/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use std::mem;
4444
fn parse_slash_slash_at_fail() -> Result<()> {
4545
init();
4646
let s = r"
47-
//@ error-pattern foomp
47+
//@ error-patttern foomp
4848
use std::mem;
4949
5050
";

0 commit comments

Comments
 (0)