summaryrefslogtreecommitdiffstats
path: root/globset/src/glob.rs
diff options
context:
space:
mode:
Diffstat (limited to 'globset/src/glob.rs')
-rw-r--r--globset/src/glob.rs231
1 files changed, 121 insertions, 110 deletions
diff --git a/globset/src/glob.rs b/globset/src/glob.rs
index c8dedba2..50502b96 100644
--- a/globset/src/glob.rs
+++ b/globset/src/glob.rs
@@ -2,13 +2,13 @@ use std::fmt;
use std::hash;
use std::iter;
use std::ops::{Deref, DerefMut};
-use std::path::{Path, is_separator};
+use std::path::{is_separator, Path};
use std::str;
use regex;
use regex::bytes::Regex;
-use {Candidate, Error, ErrorKind, new_regex};
+use {new_regex, Candidate, Error, ErrorKind};
/// Describes a matching strategy for a particular pattern.
///
@@ -85,16 +85,16 @@ pub struct Glob {
}
impl PartialEq for Glob {
- fn eq(&self, other: &Glob) -> bool {
- self.glob == other.glob && self.opts == other.opts
- }
+ fn eq(&self, other: &Glob) -> bool {
+ self.glob == other.glob && self.opts == other.opts
+ }
}
impl hash::Hash for Glob {
- fn hash<H: hash::Hasher>(&self, state: &mut H) {
- self.glob.hash(state);
- self.opts.hash(state);
- }
+ fn hash<H: hash::Hasher>(&self, state: &mut H) {
+ self.glob.hash(state);
+ self.opts.hash(state);
+ }
}
impl fmt::Display for Glob {
@@ -227,11 +227,15 @@ struct Tokens(Vec<Token>);
impl Deref for Tokens {
type Target = Vec<Token>;
- fn deref(&self) -> &Vec<Token> { &self.0 }
+ fn deref(&self) -> &Vec<Token> {
+ &self.0
+ }
}
impl DerefMut for Tokens {
- fn deref_mut(&mut self) -> &mut Vec<Token> { &mut self.0 }
+ fn deref_mut(&mut self) -> &mut Vec<Token> {
+ &mut self.0
+ }
}
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -242,10 +246,7 @@ enum Token {
RecursivePrefix,
RecursiveSuffix,
RecursiveZeroOrMore,
- Class {
- negated: bool,
- ranges: Vec<(char, char)>,
- },
+ Class { negated: bool, ranges: Vec<(char, char)> },
Alternates(Vec<Tokens>),
}
@@ -257,12 +258,9 @@ impl Glob {
/// Returns a matcher for this pattern.
pub fn compile_matcher(&self) -> GlobMatcher {
- let re = new_regex(&self.re)
- .expect("regex compilation shouldn't fail");
- GlobMatcher {
- pat: self.clone(),
- re: re,
- }
+ let re =
+ new_regex(&self.re).expect("regex compilation shouldn't fail");
+ GlobMatcher { pat: self.clone(), re: re }
}
/// Returns a strategic matcher.
@@ -273,13 +271,9 @@ impl Glob {
#[cfg(test)]
fn compile_strategic_matcher(&self) -> GlobStrategic {
let strategy = MatchStrategy::new(self);
- let re = new_regex(&self.re)
- .expect("regex compilation shouldn't fail");
- GlobStrategic {
- strategy: strategy,
- pat: self.clone(),
- re: re,
- }
+ let re =
+ new_regex(&self.re).expect("regex compilation shouldn't fail");
+ GlobStrategic { strategy: strategy, pat: self.clone(), re: re }
}
/// Returns the original glob pattern used to build this pattern.
@@ -537,7 +531,7 @@ impl Glob {
| Token::RecursiveZeroOrMore => {
return None;
}
- Token::Class{..} | Token::Alternates(..) => {
+ Token::Class { .. } | Token::Alternates(..) => {
// We *could* be a little smarter here, but either one
// of these is going to prevent our literal optimizations
// anyway, so give up.
@@ -574,10 +568,7 @@ impl<'a> GlobBuilder<'a> {
///
/// The pattern is not compiled until `build` is called.
pub fn new(glob: &'a str) -> GlobBuilder<'a> {
- GlobBuilder {
- glob: glob,
- opts: GlobOptions::default(),
- }
+ GlobBuilder { glob: glob, opts: GlobOptions::default() }
}
/// Parses and builds the pattern.
@@ -875,25 +866,22 @@ impl<'a> Parser<'a> {
return Ok(());
}
}
- let is_suffix =
- match self.peek() {
- None => {
- assert!(self.bump().is_none());
- true
- }
- Some(',') | Some('}') if self.stack.len() >= 2 => {
- true
- }
- Some(c) if is_separator(c) => {
- assert!(self.bump().map(is_separator).unwrap_or(false));
- false
- }
- _ => {
- self.push_token(Token::ZeroOrMore)?;
- self.push_token(Token::ZeroOrMore)?;
- return Ok(());
- }
- };
+ let is_suffix = match self.peek() {
+ None => {
+ assert!(self.bump().is_none());
+ true
+ }
+ Some(',') | Some('}') if self.stack.len() >= 2 => true,
+ Some(c) if is_separator(c) => {
+ assert!(self.bump().map(is_separator).unwrap_or(false));
+ false
+ }
+ _ => {
+ self.push_token(Token::ZeroOrMore)?;
+ self.push_token(Token::ZeroOrMore)?;
+ return Ok(());
+ }
+ };
match self.pop_token()? {
Token::RecursivePrefix => {
self.push_token(Token::RecursivePrefix)?;
@@ -973,7 +961,10 @@ impl<'a> Parser<'a> {
// invariant: in_range is only set when there is
// already at least one character seen.
add_to_last_range(
- &self.glob, ranges.last_mut().unwrap(), c)?;
+ &self.glob,
+ ranges.last_mut().unwrap(),
+ c,
+ )?;
} else {
ranges.push((c, c));
}
@@ -987,10 +978,7 @@ impl<'a> Parser<'a> {
// it as a literal.
ranges.push(('-', '-'));
}
- self.push_token(Token::Class {
- negated: negated,
- ranges: ranges,
- })
+ self.push_token(Token::Class { negated: negated, ranges: ranges })
}
fn bump(&mut self) -> Option<char> {
@@ -1019,9 +1007,9 @@ fn ends_with(needle: &[u8], haystack: &[u8]) -> bool {
#[cfg(test)]
mod tests {
- use {GlobSetBuilder, ErrorKind};
- use super::{Glob, GlobBuilder, Token};
use super::Token::*;
+ use super::{Glob, GlobBuilder, Token};
+ use {ErrorKind, GlobSetBuilder};
#[derive(Clone, Copy, Debug, Default)]
struct Options {
@@ -1037,7 +1025,7 @@ mod tests {
let pat = Glob::new($pat).unwrap();
assert_eq!($tokens, pat.tokens.0);
}
- }
+ };
}
macro_rules! syntaxerr {
@@ -1047,7 +1035,7 @@ mod tests {
let err = Glob::new($pat).unwrap_err();
assert_eq!(&$err, err.kind());
}
- }
+ };
}
macro_rules! toregex {
@@ -1129,7 +1117,9 @@ mod tests {
};
}
- fn s(string: &str) -> String { string.to_string() }
+ fn s(string: &str) -> String {
+ string.to_string()
+ }
fn class(s: char, e: char) -> Token {
Class { negated: false, ranges: vec![(s, e)] }
@@ -1153,16 +1143,20 @@ mod tests {
syntax!(any2, "a?b", vec![Literal('a'), Any, Literal('b')]);
syntax!(seq1, "*", vec![ZeroOrMore]);
syntax!(seq2, "a*b", vec![Literal('a'), ZeroOrMore, Literal('b')]);
- syntax!(seq3, "*a*b*", vec![
- ZeroOrMore, Literal('a'), ZeroOrMore, Literal('b'), ZeroOrMore,
- ]);
+ syntax!(
+ seq3,
+ "*a*b*",
+ vec![ZeroOrMore, Literal('a'), ZeroOrMore, Literal('b'), ZeroOrMore,]
+ );
syntax!(rseq1, "**", vec![RecursivePrefix]);
syntax!(rseq2, "**/", vec![RecursivePrefix]);
syntax!(rseq3, "/**", vec![RecursiveSuffix]);
syntax!(rseq4, "/**/", vec![RecursiveZeroOrMore]);
- syntax!(rseq5, "a/**/b", vec![
- Literal('a'), RecursiveZeroOrMore, Literal('b'),
- ]);
+ syntax!(
+ rseq5,
+ "a/**/b",
+ vec![Literal('a'), RecursiveZeroOrMore, Literal('b'),]
+ );
syntax!(cls1, "[a]", vec![class('a', 'a')]);
syntax!(cls2, "[!a]", vec![classn('a', 'a')]);
syntax!(cls3, "[a-z]", vec![class('a', 'z')]);
@@ -1174,9 +1168,11 @@ mod tests {
syntax!(cls9, "[a-]", vec![rclass(&[('a', 'a'), ('-', '-')])]);
syntax!(cls10, "[-a-z]", vec![rclass(&[('-', '-'), ('a', 'z')])]);
syntax!(cls11, "[a-z-]", vec![rclass(&[('a', 'z'), ('-', '-')])]);
- syntax!(cls12, "[-a-z-]", vec![
- rclass(&[('-', '-'), ('a', 'z'), ('-', '-')]),
- ]);
+ syntax!(
+ cls12,
+ "[-a-z-]",
+ vec![rclass(&[('-', '-'), ('a', 'z'), ('-', '-')]),]
+ );
syntax!(cls13, "[]-z]", vec![class(']', 'z')]);
syntax!(cls14, "[--z]", vec![class('-', 'z')]);
syntax!(cls15, "[ --]", vec![class(' ', '-')]);
@@ -1194,26 +1190,14 @@ mod tests {
syntaxerr!(err_range1, "[z-a]", ErrorKind::InvalidRange('z', 'a'));
syntaxerr!(err_range2, "[z--]", ErrorKind::InvalidRange('z', '-'));
- const CASEI: Options = Options {
- casei: Some(true),
- litsep: None,
- bsesc: None,
- };
- const SLASHLIT: Options = Options {
- casei: None,
- litsep: Some(true),
- bsesc: None,
- };
- const NOBSESC: Options = Options {
- casei: None,
- litsep: None,
- bsesc: Some(false),
- };
- const BSESC: Options = Options {
- casei: None,
- litsep: None,
- bsesc: Some(true),
- };
+ const CASEI: Options =
+ Options { casei: Some(true), litsep: None, bsesc: None };
+ const SLASHLIT: Options =
+ Options { casei: None, litsep: Some(true), bsesc: None };
+ const NOBSESC: Options =
+ Options { casei: None, litsep: None, bsesc: Some(false) };
+ const BSESC: Options =
+ Options { casei: None, litsep: None, bsesc: Some(true) };
toregex!(re_casei, "a", "(?i)^a$", &CASEI);
@@ -1311,8 +1295,11 @@ mod tests {
matches!(matchpat4, "*hello.txt", "some\\path\\to\\hello.txt");
matches!(matchpat5, "*hello.txt", "/an/absolute/path/to/hello.txt");
matches!(matchpat6, "*some/path/to/hello.txt", "some/path/to/hello.txt");
- matches!(matchpat7, "*some/path/to/hello.txt",
- "a/bigger/some/path/to/hello.txt");
+ matches!(
+ matchpat7,
+ "*some/path/to/hello.txt",
+ "a/bigger/some/path/to/hello.txt"
+ );
matches!(matchescape, "_[[]_[]]_[?]_[*]_!_", "_[_]_?_*_!_");
@@ -1375,28 +1362,44 @@ mod tests {
nmatches!(matchnot15, "[!-]", "-");
nmatches!(matchnot16, "*hello.txt", "hello.txt-and-then-some");
nmatches!(matchnot17, "*hello.txt", "goodbye.txt");
- nmatches!(matchnot18, "*some/path/to/hello.txt",
- "some/path/to/hello.txt-and-then-some");
- nmatches!(matchnot19, "*some/path/to/hello.txt",
- "some/other/path/to/hello.txt");
+ nmatches!(
+ matchnot18,
+ "*some/path/to/hello.txt",
+ "some/path/to/hello.txt-and-then-some"
+ );
+ nmatches!(
+ matchnot19,
+ "*some/path/to/hello.txt",
+ "some/other/path/to/hello.txt"
+ );
nmatches!(matchnot20, "a", "foo/a");
nmatches!(matchnot21, "./foo", "foo");
nmatches!(matchnot22, "**/foo", "foofoo");
nmatches!(matchnot23, "**/foo/bar", "foofoo/bar");
nmatches!(matchnot24, "/*.c", "mozilla-sha1/sha1.c");
nmatches!(matchnot25, "*.c", "mozilla-sha1/sha1.c", SLASHLIT);
- nmatches!(matchnot26, "**/m4/ltoptions.m4",
- "csharp/src/packages/repositories.config", SLASHLIT);
+ nmatches!(
+ matchnot26,
+ "**/m4/ltoptions.m4",
+ "csharp/src/packages/repositories.config",
+ SLASHLIT
+ );
nmatches!(matchnot27, "a[^0-9]b", "a0b");
nmatches!(matchnot28, "a[^0-9]b", "a9b");
nmatches!(matchnot29, "[^-]", "-");
nmatches!(matchnot30, "some/*/needle.txt", "some/needle.txt");
nmatches!(
matchrec31,
- "some/*/needle.txt", "some/one/two/needle.txt", SLASHLIT);
+ "some/*/needle.txt",
+ "some/one/two/needle.txt",
+ SLASHLIT
+ );
nmatches!(
matchrec32,
- "some/*/needle.txt", "some/one/two/three/needle.txt", SLASHLIT);
+ "some/*/needle.txt",
+ "some/one/two/three/needle.txt",
+ SLASHLIT
+ );
macro_rules! extract {
($which:ident, $name:ident, $pat:expr, $expect:expr) => {
@@ -1458,19 +1461,27 @@ mod tests {
literal!(extract_lit7, "foo/bar", Some(s("foo/bar")));
literal!(extract_lit8, "**/foo/bar", None);
- basetokens!(extract_basetoks1, "**/foo", Some(&*vec![
- Literal('f'), Literal('o'), Literal('o'),
- ]));
+ basetokens!(
+ extract_basetoks1,
+ "**/foo",
+ Some(&*vec![Literal('f'), Literal('o'), Literal('o'),])
+ );
basetokens!(extract_basetoks2, "**/foo", None, CASEI);
- basetokens!(extract_basetoks3, "**/foo", Some(&*vec![
- Literal('f'), Literal('o'), Literal('o'),
- ]), SLASHLIT);
+ basetokens!(
+ extract_basetoks3,
+ "**/foo",
+ Some(&*vec![Literal('f'), Literal('o'), Literal('o'),]),
+ SLASHLIT
+ );
basetokens!(extract_basetoks4, "*foo", None, SLASHLIT);
basetokens!(extract_basetoks5, "*foo", None);
basetokens!(extract_basetoks6, "**/fo*o", None);
- basetokens!(extract_basetoks7, "**/fo*o", Some(&*vec![
- Literal('f'), Literal('o'), ZeroOrMore, Literal('o'),
- ]), SLASHLIT);
+ basetokens!(
+ extract_basetoks7,
+ "**/fo*o",
+ Some(&*vec![Literal('f'), Literal('o'), ZeroOrMore, Literal('o'),]),
+ SLASHLIT
+ );
ext!(extract_ext1, "**/*.rs", Some(s(".rs")));
ext!(extract_ext2, "**/*.rs.bak", None);