]> git.lizzy.rs Git - rust.git/commitdiff
Implement a proper command parser...
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Wed, 6 Jul 2022 10:17:21 +0000 (10:17 +0000)
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Fri, 8 Jul 2022 15:55:37 +0000 (15:55 +0000)
... that grabs things from the front instead of splitting at spaces and colons and hoping for the best

ui_test/src/comments.rs
ui_test/src/comments/tests.rs

index dd6ca9581ab2d09c3f9ec3cbf96ada1c8a097b9d..fa46b54970009abe1e45d2a60bc1ba278e235758 100644 (file)
@@ -98,14 +98,7 @@ fn parse_checked_line(
         line: &str,
     ) -> Result<()> {
         if let Some((_, command)) = line.split_once("//@") {
-            let command = command.trim();
-            if let Some((command, args)) = command.split_once(':') {
-                self.parse_command_with_args(command, args, l)
-            } else if let Some((command, _comments)) = command.split_once(' ') {
-                self.parse_command(command)
-            } else {
-                self.parse_command(command)
-            }
+            self.parse_command(command.trim(), l)
         } else if let Some((_, pattern)) = line.split_once("//~") {
             self.parse_pattern(pattern, fallthrough_to, l)
         } else if let Some((_, pattern)) = line.split_once("//[") {
@@ -189,7 +182,22 @@ pub(crate) fn parse(path: &Path, content: &str) -> Result<Self> {
         Ok(this)
     }
 
-    fn parse_command_with_args(&mut self, command: &str, args: &str, l: usize) -> Result<()> {
+    fn parse_command(&mut self, command: &str, l: usize) -> Result<()> {
+        // Commands are letters or dashes, grab everything until the first character that is neither of those.
+        let (command, args) = match command.chars().position(|c: char| !c.is_alphabetic() && c != '-') {
+            None => (command, ""),
+            Some(i) => {
+                let (command, args) = command.split_at(i);
+                let mut args = args.chars();
+                let next = args.next().expect("the `position` above guarantees that there is at least one char");
+                let args = match next {
+                    ':' | ' ' => args.as_str(),
+                    _ => bail!("expected space or `:`, got `{next}`"),
+                };
+                (command, args)
+            }
+        };
+
         match command {
             "revisions" => {
                 ensure!(self.revisions.is_none(), "cannot specifiy revisions twice");
@@ -222,30 +230,25 @@ fn parse_command_with_args(&mut self, command: &str, args: &str, l: usize) -> Re
                 );
                 self.error_pattern = Some((args.trim().to_string(), l));
             }
-            // Maybe the user just left a comment explaining a command without arguments
-            _ => self.parse_command(command)?,
-        }
-        Ok(())
-    }
-
-    fn parse_command(&mut self, command: &str) -> Result<()> {
-        if let Some(s) = command.strip_prefix("ignore-") {
-            self.ignore.push(Condition::parse(s));
-            return Ok(());
-        }
-
-        if let Some(s) = command.strip_prefix("only-") {
-            self.only.push(Condition::parse(s));
-            return Ok(());
-        }
+            "stderr-per-bitwidth" => {
+                ensure!(!self.stderr_per_bitwidth, "cannot specifiy stderr-per-bitwidth twice");
+                self.stderr_per_bitwidth = true;
+            }
+            command => {
+                if let Some(s) = command.strip_prefix("ignore-") {
+                    self.ignore.push(Condition::parse(s));
+                    return Ok(());
+                }
 
-        if command.starts_with("stderr-per-bitwidth") {
-            ensure!(!self.stderr_per_bitwidth, "cannot specifiy stderr-per-bitwidth twice");
-            self.stderr_per_bitwidth = true;
-            return Ok(());
+                if let Some(s) = command.strip_prefix("only-") {
+                    self.only.push(Condition::parse(s));
+                    return Ok(());
+                }
+                bail!("unknown command {command}");
+            }
         }
 
-        bail!("unknown command {command}");
+        Ok(())
     }
 
     fn parse_pattern(
index cdd81aa990538d7f3c0b46c07b1e0f2dc6002f98..15a0aae247b1d08b66da7d6cec7e0ff3a06d64f9 100644 (file)
@@ -44,7 +44,7 @@ fn parse_slash_slash_at() -> Result<()> {
 fn parse_slash_slash_at_fail() -> Result<()> {
     init();
     let s = r"
-//@  error-pattern  foomp
+//@  error-patttern  foomp
 use std::mem;
 
     ";