diff --git a/wfassoc/src/extra/windows.rs b/wfassoc/src/extra/windows.rs index 2175e05..0de5b6b 100644 --- a/wfassoc/src/extra/windows.rs +++ b/wfassoc/src/extra/windows.rs @@ -251,26 +251,33 @@ impl> Iterator for CmdLexer { // Handle backslash '\\' => { - if let Some(pc) = self.chars.peek().copied() { - match pc { - '\\' => { - // Double backslash are treated as single backslash - self.chars.next(); - token.push(pc); - } - '"' => { - // Backslash with an quote is interpreted as an literal quote - self.chars.next(); - token.push(pc); - } - _ => { - // Treated as normal backslash - token.push(c); - } + // Eat backslash as much as possible and count it. + let mut backslashes: usize = 1; + while self.chars.peek().copied() == Some('\\') { + self.chars.next(); + backslashes += 1; + } + + if self.chars.peek().copied() == Some('"') { + // Rule: backslashes before a double quote are special + + // consume the " + let quote = self.chars.next().unwrap(); + + // Even number: backslashes become half, quote is delimiter + // Odd number: backslashes become half, quote is literal + let num_slashes = backslashes / 2; + let is_literal_quote = backslashes % 2 != 0; + + token.push_str(&"\\".repeat(num_slashes)); + if is_literal_quote { + token.push(quote); + } else { + in_quotes = !in_quotes; } } else { - // There is no more chars, treat it as normal. - token.push(c); + // Not followed by quote: treat all backslashes literally + token.push_str(&"\\".repeat(backslashes)); } }