fix(commands): make flags not match if param was in quotes

This commit is contained in:
dusk 2025-01-12 19:30:21 +09:00
parent a21210f3ce
commit 413b8c1915
No known key found for this signature in database
3 changed files with 38 additions and 17 deletions

View file

@ -42,17 +42,24 @@ lazy_static::lazy_static! {
};
}
#[derive(Debug)]
pub(super) struct MatchedParam<'a> {
pub(super) value: &'a str,
pub(super) next_pos: usize,
pub(super) in_quotes: bool,
}
// very very simple quote matching
// quotes need to be at start/end of words, and are ignored if a closing quote is not present
// WTB POSIX quoting: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html
pub(super) fn next_param(input: SmolStr, current_pos: usize) -> Option<(SmolStr, usize)> {
pub(super) fn next_param<'a>(input: &'a str, current_pos: usize) -> Option<MatchedParam<'a>> {
if input.len() == current_pos {
return None;
}
let leading_whitespace_count =
input[..current_pos].len() - input[..current_pos].trim_start().len();
let substr_to_match: SmolStr = input[current_pos + leading_whitespace_count..].into();
let substr_to_match = &input[current_pos + leading_whitespace_count..];
println!("stuff: {input} {current_pos} {leading_whitespace_count}");
println!("to match: {substr_to_match}");
@ -68,20 +75,32 @@ pub(super) fn next_param(input: SmolStr, current_pos: usize) -> Option<(SmolStr,
.is_whitespace()
{
// return quoted string, without quotes
return Some((substr_to_match[1..pos - 1].into(), current_pos + pos + 1));
return Some(MatchedParam {
value: &substr_to_match[1..pos - 1],
next_pos: current_pos + pos + 1,
in_quotes: true,
});
}
}
}
}
// find next whitespace character
for (pos, char) in substr_to_match.clone().char_indices() {
for (pos, char) in substr_to_match.char_indices() {
if char.is_whitespace() {
return Some((substr_to_match[..pos].into(), current_pos + pos + 1));
return Some(MatchedParam {
value: &substr_to_match[..pos],
next_pos: current_pos + pos + 1,
in_quotes: false,
});
}
}
// if we're here, we went to EOF and didn't match any whitespace
// so we return the whole string
Some((substr_to_match.clone(), current_pos + substr_to_match.len()))
Some(MatchedParam {
value: substr_to_match,
next_pos: current_pos + substr_to_match.len(),
in_quotes: false,
})
}