Skip to content

Commit

Permalink
globset: add 'escape' routine
Browse files Browse the repository at this point in the history
Fixes #2060, Closes #2061
  • Loading branch information
piegamesde authored and BurntSushi committed Jul 8, 2023
1 parent 23adbd6 commit 4993d29
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
20 changes: 14 additions & 6 deletions crates/globset/src/glob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,9 @@ impl<'a> GlobBuilder<'a> {
}

/// Toggle whether an empty pattern in a list of alternates is accepted.
///
///
/// For example, if this is set then the glob `foo{,.txt}` will match both `foo` and `foo.txt`.
///
///
/// By default this is false.
pub fn empty_alternates(&mut self, yes: bool) -> &mut GlobBuilder<'a> {
self.opts.empty_alternates = yes;
Expand Down Expand Up @@ -1222,12 +1222,20 @@ mod tests {
Options { casei: Some(true), litsep: None, bsesc: None, ealtre: None };
const SLASHLIT: Options =
Options { casei: None, litsep: Some(true), bsesc: None, ealtre: None };
const NOBSESC: Options =
Options { casei: None, litsep: None, bsesc: Some(false), ealtre: None };
const NOBSESC: Options = Options {
casei: None,
litsep: None,
bsesc: Some(false),
ealtre: None,
};
const BSESC: Options =
Options { casei: None, litsep: None, bsesc: Some(true), ealtre: None };
const EALTRE: Options =
Options { casei: None, litsep: None, bsesc: Some(true), ealtre: Some(true) };
const EALTRE: Options = Options {
casei: None,
litsep: None,
bsesc: Some(true),
ealtre: Some(true),
};

toregex!(re_casei, "a", "(?i)^a$", &CASEI);

Expand Down
35 changes: 35 additions & 0 deletions crates/globset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,29 @@ impl RequiredExtensionStrategyBuilder {
}
}

/// Escape meta-characters within the given glob pattern.
///
/// The escaping works by surrounding meta-characters with brackets. For
/// example, `*` becomes `[*]`.
pub fn escape(s: &str) -> String {
let mut escaped = String::with_capacity(s.len());
for c in s.chars() {
match c {
// note that ! does not need escaping because it is only special
// inside brackets
'?' | '*' | '[' | ']' => {
escaped.push('[');
escaped.push(c);
escaped.push(']');
}
c => {
escaped.push(c);
}
}
}
escaped
}

#[cfg(test)]
mod tests {
use super::{GlobSet, GlobSetBuilder};
Expand Down Expand Up @@ -919,4 +942,16 @@ mod tests {
assert!(!set.is_match(""));
assert!(!set.is_match("a"));
}

#[test]
fn escape() {
use super::escape;
assert_eq!("foo", escape("foo"));
assert_eq!("foo[*]", escape("foo*"));
assert_eq!("[[][]]", escape("[]"));
assert_eq!("[*][?]", escape("*?"));
assert_eq!("src/[*][*]/[*].rs", escape("src/**/*.rs"));
assert_eq!("bar[[]ab[]]baz", escape("bar[ab]baz"));
assert_eq!("bar[[]!![]]!baz", escape("bar[!!]!baz"));
}
}

0 comments on commit 4993d29

Please sign in to comment.