From 5a72fb28fb69a476437141a4eb898d6d001dd281 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Wed, 14 Apr 2021 20:17:42 -0600 Subject: implement potentially-mixed-quoted conditional args --- src/makefile/conditional.rs | 41 +++++++++++++++++++++++++++++++++++++---- src/makefile/input.rs | 10 +++++----- src/makefile/token.rs | 2 +- 3 files changed, 43 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/makefile/conditional.rs b/src/makefile/conditional.rs index 95cab9e..98400e6 100644 --- a/src/makefile/conditional.rs +++ b/src/makefile/conditional.rs @@ -2,7 +2,7 @@ use eyre::{bail, Result}; use super::token::TokenString; -#[derive(Debug)] +#[derive(Debug, Eq, PartialEq)] pub enum Line { /// spelled "ifeq" IfEqual(TokenString, TokenString), @@ -73,10 +73,23 @@ fn decode_condition_args(line_body: &str) -> Option<(TokenString, TokenString)> let mut tokens = tokens; tokens.strip_prefix("("); tokens.strip_suffix(")"); - tokens.split_once(',')? + tokens.split_once(",")? } else { - // TODO see if i really need to implement potentially-mixed-quoted args - return None; + let quotes = &["\"", "'"]; + let mut split_pair = None; + for (left_quote, right_quote) in quotes + .iter() + .flat_map(|left| quotes.iter().map(move |right| (left, right))) + { + if tokens.starts_with(left_quote) && tokens.ends_with(right_quote) { + let mut tokens = tokens; + tokens.strip_prefix(left_quote); + tokens.strip_suffix(right_quote); + split_pair = Some(tokens.split_once(&format!("{} {}", left_quote, right_quote))?); + break; + } + } + split_pair? }; arg1.trim_end(); arg2.trim_start(); @@ -182,3 +195,23 @@ impl Line { }) } } + +#[cfg(test)] +mod test { + use super::*; + + type R = Result<()>; + + #[test] + fn quotes() -> R { + let line = r#"ifeq 'x' "3""#; + assert_eq!( + Line::from(line, |_| panic!())?, + Some(Line::IfEqual( + TokenString::text("x"), + TokenString::text("3") + )) + ); + Ok(()) + } +} diff --git a/src/makefile/input.rs b/src/makefile/input.rs index 5a1259f..4a0f086 100644 --- a/src/makefile/input.rs +++ b/src/makefile/input.rs @@ -569,13 +569,13 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { fn read_rule(&mut self, line_tokens: TokenString, line_number: usize) -> Result<()> { let (targets, not_targets) = line_tokens - .split_once(':') + .split_once(":") .ok_or_else(|| eyre!("read_rule couldn't find a ':' on line {}", line_number))?; #[cfg(feature = "full")] let (static_targets, targets, not_targets) = if not_targets.contains_text(":") { // ugh, this is probably a Static Pattern Rule let (pattern, not_targets) = not_targets - .split_once(':') + .split_once(":") .ok_or_else(|| eyre!("bro hold the fuck up it literally just had that"))?; (Some(targets), pattern, not_targets) } else { @@ -583,7 +583,7 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { }; let targets = self.expand_macros(&targets)?; let targets = targets.split_whitespace().collect::>(); - let (prerequisites, mut commands) = match not_targets.split_once(';') { + let (prerequisites, mut commands) = match not_targets.split_once(";") { Some((prerequisites, command)) => { // TODO make sure escaped newlines get retroactively treated correctly here (prerequisites, vec![command]) @@ -801,8 +801,8 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> { (line_tokens, value) } else { line_tokens - .split_once('=') - .ok_or_else(|| eyre!("read_rule couldn't find a ':' on line {}", line_number))? + .split_once("=") + .ok_or_else(|| eyre!("read_macro couldn't find a '=' on line {}", line_number))? }; let name = self.expand_macros(&name)?; // GNUisms are annoying, but popular diff --git a/src/makefile/token.rs b/src/makefile/token.rs index 05ad98c..2721387 100644 --- a/src/makefile/token.rs +++ b/src/makefile/token.rs @@ -53,7 +53,7 @@ impl TokenString { &mut self.0[0] } - pub fn split_once(&self, delimiter: char) -> Option<(Self, Self)> { + pub fn split_once(&self, delimiter: &str) -> Option<(Self, Self)> { let mut result0 = vec![]; let mut iter = self.0.iter(); while let Some(t) = iter.next() { -- cgit v1.2.3