Show More
@@ -214,10 +214,33 lazy_static! { | |||||
214 | static ref FLAG_RE: Regex = Regex::new(r"^\(\?[aiLmsux]+\)").unwrap(); |
|
214 | static ref FLAG_RE: Regex = Regex::new(r"^\(\?[aiLmsux]+\)").unwrap(); | |
215 | } |
|
215 | } | |
216 |
|
216 | |||
|
217 | /// Extra path components to match at the end of the pattern | |||
|
218 | #[derive(Clone, Copy)] | |||
|
219 | pub enum GlobSuffix { | |||
|
220 | /// `Empty` means the pattern only matches files, not directories, | |||
|
221 | /// so the path needs to match exactly. | |||
|
222 | Empty, | |||
|
223 | /// `MoreComponents` means the pattern matches directories as well, | |||
|
224 | /// so any path that has the pattern as a prefix, should match. | |||
|
225 | MoreComponents, | |||
|
226 | } | |||
|
227 | ||||
|
228 | impl GlobSuffix { | |||
|
229 | fn to_re(self) -> &'static [u8] { | |||
|
230 | match self { | |||
|
231 | Self::Empty => b"$", | |||
|
232 | Self::MoreComponents => b"(?:/|$)", | |||
|
233 | } | |||
|
234 | } | |||
|
235 | } | |||
|
236 | ||||
217 | /// Builds the regex that corresponds to the given pattern. |
|
237 | /// Builds the regex that corresponds to the given pattern. | |
218 | /// If within a `syntax: regexp` context, returns the pattern, |
|
238 | /// If within a `syntax: regexp` context, returns the pattern, | |
219 | /// otherwise, returns the corresponding regex. |
|
239 | /// otherwise, returns the corresponding regex. | |
220 | fn _build_single_regex(entry: &IgnorePattern, glob_suffix: &[u8]) -> Vec<u8> { |
|
240 | fn _build_single_regex( | |
|
241 | entry: &IgnorePattern, | |||
|
242 | glob_suffix: GlobSuffix, | |||
|
243 | ) -> Vec<u8> { | |||
221 | let IgnorePattern { |
|
244 | let IgnorePattern { | |
222 | syntax, pattern, .. |
|
245 | syntax, pattern, .. | |
223 | } = entry; |
|
246 | } = entry; | |
@@ -264,7 +287,11 fn _build_single_regex(entry: &IgnorePat | |||||
264 | if pattern == b"." { |
|
287 | if pattern == b"." { | |
265 | return vec![]; |
|
288 | return vec![]; | |
266 | } |
|
289 | } | |
267 | [escape_pattern(pattern).as_slice(), b"(?:/|$)"].concat() |
|
290 | [ | |
|
291 | escape_pattern(pattern).as_slice(), | |||
|
292 | GlobSuffix::MoreComponents.to_re(), | |||
|
293 | ] | |||
|
294 | .concat() | |||
268 | } |
|
295 | } | |
269 | PatternSyntax::RootFilesIn => { |
|
296 | PatternSyntax::RootFilesIn => { | |
270 | let mut res = if pattern == b"." { |
|
297 | let mut res = if pattern == b"." { | |
@@ -281,13 +308,13 fn _build_single_regex(entry: &IgnorePat | |||||
281 | PatternSyntax::RelGlob => { |
|
308 | PatternSyntax::RelGlob => { | |
282 | let glob_re = glob_to_re(pattern); |
|
309 | let glob_re = glob_to_re(pattern); | |
283 | if let Some(rest) = glob_re.drop_prefix(b"[^/]*") { |
|
310 | if let Some(rest) = glob_re.drop_prefix(b"[^/]*") { | |
284 | [b".*", rest, glob_suffix].concat() |
|
311 | [b".*", rest, glob_suffix.to_re()].concat() | |
285 | } else { |
|
312 | } else { | |
286 | [b"(?:.*/)?", glob_re.as_slice(), glob_suffix].concat() |
|
313 | [b"(?:.*/)?", glob_re.as_slice(), glob_suffix.to_re()].concat() | |
287 | } |
|
314 | } | |
288 | } |
|
315 | } | |
289 | PatternSyntax::Glob | PatternSyntax::RootGlob => { |
|
316 | PatternSyntax::Glob | PatternSyntax::RootGlob => { | |
290 | [glob_to_re(pattern).as_slice(), glob_suffix].concat() |
|
317 | [glob_to_re(pattern).as_slice(), glob_suffix.to_re()].concat() | |
291 | } |
|
318 | } | |
292 | PatternSyntax::Include |
|
319 | PatternSyntax::Include | |
293 | | PatternSyntax::SubInclude |
|
320 | | PatternSyntax::SubInclude | |
@@ -345,7 +372,7 pub fn normalize_path_bytes(bytes: &[u8] | |||||
345 | /// that don't need to be transformed into a regex. |
|
372 | /// that don't need to be transformed into a regex. | |
346 | pub fn build_single_regex( |
|
373 | pub fn build_single_regex( | |
347 | entry: &IgnorePattern, |
|
374 | entry: &IgnorePattern, | |
348 |
glob_suffix: |
|
375 | glob_suffix: GlobSuffix, | |
349 | ) -> Result<Option<Vec<u8>>, PatternError> { |
|
376 | ) -> Result<Option<Vec<u8>>, PatternError> { | |
350 | let IgnorePattern { |
|
377 | let IgnorePattern { | |
351 | pattern, syntax, .. |
|
378 | pattern, syntax, .. | |
@@ -800,7 +827,7 mod tests { | |||||
800 | b"rust/target/", |
|
827 | b"rust/target/", | |
801 | Path::new("") |
|
828 | Path::new("") | |
802 | ), |
|
829 | ), | |
803 | b"(?:/|$)" |
|
830 | GlobSuffix::MoreComponents | |
804 | ) |
|
831 | ) | |
805 | .unwrap(), |
|
832 | .unwrap(), | |
806 | Some(br"(?:.*/)?rust/target(?:/|$)".to_vec()), |
|
833 | Some(br"(?:.*/)?rust/target(?:/|$)".to_vec()), | |
@@ -812,7 +839,7 mod tests { | |||||
812 | br"rust/target/\d+", |
|
839 | br"rust/target/\d+", | |
813 | Path::new("") |
|
840 | Path::new("") | |
814 | ), |
|
841 | ), | |
815 | b"(?:/|$)" |
|
842 | GlobSuffix::MoreComponents | |
816 | ) |
|
843 | ) | |
817 | .unwrap(), |
|
844 | .unwrap(), | |
818 | Some(br"rust/target/\d+".to_vec()), |
|
845 | Some(br"rust/target/\d+".to_vec()), | |
@@ -828,7 +855,7 mod tests { | |||||
828 | b"", |
|
855 | b"", | |
829 | Path::new("") |
|
856 | Path::new("") | |
830 | ), |
|
857 | ), | |
831 | b"(?:/|$)" |
|
858 | GlobSuffix::MoreComponents | |
832 | ) |
|
859 | ) | |
833 | .unwrap(), |
|
860 | .unwrap(), | |
834 | None, |
|
861 | None, | |
@@ -840,7 +867,7 mod tests { | |||||
840 | b"whatever", |
|
867 | b"whatever", | |
841 | Path::new("") |
|
868 | Path::new("") | |
842 | ), |
|
869 | ), | |
843 | b"(?:/|$)" |
|
870 | GlobSuffix::MoreComponents | |
844 | ) |
|
871 | ) | |
845 | .unwrap(), |
|
872 | .unwrap(), | |
846 | None, |
|
873 | None, | |
@@ -852,7 +879,7 mod tests { | |||||
852 | b"*.o", |
|
879 | b"*.o", | |
853 | Path::new("") |
|
880 | Path::new("") | |
854 | ), |
|
881 | ), | |
855 | b"(?:/|$)" |
|
882 | GlobSuffix::MoreComponents | |
856 | ) |
|
883 | ) | |
857 | .unwrap(), |
|
884 | .unwrap(), | |
858 | Some(br"[^/]*\.o(?:/|$)".to_vec()), |
|
885 | Some(br"[^/]*\.o(?:/|$)".to_vec()), | |
@@ -868,7 +895,7 mod tests { | |||||
868 | b"^ba{2}r", |
|
895 | b"^ba{2}r", | |
869 | Path::new("") |
|
896 | Path::new("") | |
870 | ), |
|
897 | ), | |
871 | b"(?:/|$)" |
|
898 | GlobSuffix::MoreComponents | |
872 | ) |
|
899 | ) | |
873 | .unwrap(), |
|
900 | .unwrap(), | |
874 | Some(b"^ba{2}r".to_vec()), |
|
901 | Some(b"^ba{2}r".to_vec()), | |
@@ -880,7 +907,7 mod tests { | |||||
880 | b"ba{2}r", |
|
907 | b"ba{2}r", | |
881 | Path::new("") |
|
908 | Path::new("") | |
882 | ), |
|
909 | ), | |
883 | b"(?:/|$)" |
|
910 | GlobSuffix::MoreComponents | |
884 | ) |
|
911 | ) | |
885 | .unwrap(), |
|
912 | .unwrap(), | |
886 | Some(b".*ba{2}r".to_vec()), |
|
913 | Some(b".*ba{2}r".to_vec()), | |
@@ -892,7 +919,7 mod tests { | |||||
892 | b"(?ia)ba{2}r", |
|
919 | b"(?ia)ba{2}r", | |
893 | Path::new("") |
|
920 | Path::new("") | |
894 | ), |
|
921 | ), | |
895 | b"(?:/|$)" |
|
922 | GlobSuffix::MoreComponents | |
896 | ) |
|
923 | ) | |
897 | .unwrap(), |
|
924 | .unwrap(), | |
898 | Some(b"(?ia:.*ba{2}r)".to_vec()), |
|
925 | Some(b"(?ia:.*ba{2}r)".to_vec()), | |
@@ -904,7 +931,7 mod tests { | |||||
904 | b"(?ia)^ba{2}r", |
|
931 | b"(?ia)^ba{2}r", | |
905 | Path::new("") |
|
932 | Path::new("") | |
906 | ), |
|
933 | ), | |
907 | b"(?:/|$)" |
|
934 | GlobSuffix::MoreComponents | |
908 | ) |
|
935 | ) | |
909 | .unwrap(), |
|
936 | .unwrap(), | |
910 | Some(b"(?ia:^ba{2}r)".to_vec()), |
|
937 | Some(b"(?ia:^ba{2}r)".to_vec()), |
@@ -14,8 +14,8 use crate::{ | |||||
14 | dirstate::dirs_multiset::{DirsChildrenMultiset, DirsMultiset}, |
|
14 | dirstate::dirs_multiset::{DirsChildrenMultiset, DirsMultiset}, | |
15 | filepatterns::{ |
|
15 | filepatterns::{ | |
16 | build_single_regex, filter_subincludes, get_patterns_from_file, |
|
16 | build_single_regex, filter_subincludes, get_patterns_from_file, | |
17 |
IgnorePattern, PatternError, PatternFileWarning, |
|
17 | GlobSuffix, IgnorePattern, PatternError, PatternFileWarning, | |
18 | PatternSyntax, |
|
18 | PatternResult, PatternSyntax, | |
19 | }, |
|
19 | }, | |
20 | utils::{ |
|
20 | utils::{ | |
21 | files::{dir_ancestors, find_dirs}, |
|
21 | files::{dir_ancestors, find_dirs}, | |
@@ -328,7 +328,8 impl<'a> PatternMatcher<'a> { | |||||
328 | let prefix = ignore_patterns.iter().all(|k| { |
|
328 | let prefix = ignore_patterns.iter().all(|k| { | |
329 | matches!(k.syntax, PatternSyntax::Path | PatternSyntax::RelPath) |
|
329 | matches!(k.syntax, PatternSyntax::Path | PatternSyntax::RelPath) | |
330 | }); |
|
330 | }); | |
331 |
let (patterns, match_fn) = |
|
331 | let (patterns, match_fn) = | |
|
332 | build_match(ignore_patterns, GlobSuffix::Empty)?; | |||
332 |
|
333 | |||
333 | Ok(Self { |
|
334 | Ok(Self { | |
334 | patterns, |
|
335 | patterns, | |
@@ -807,7 +808,7 fn re_matcher(pattern: &[u8]) -> Pattern | |||||
807 | /// said regex formed by the given ignore patterns. |
|
808 | /// said regex formed by the given ignore patterns. | |
808 | fn build_regex_match<'a>( |
|
809 | fn build_regex_match<'a>( | |
809 | ignore_patterns: &[IgnorePattern], |
|
810 | ignore_patterns: &[IgnorePattern], | |
810 |
glob_suffix: |
|
811 | glob_suffix: GlobSuffix, | |
811 | ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> { |
|
812 | ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> { | |
812 | let mut regexps = vec![]; |
|
813 | let mut regexps = vec![]; | |
813 | let mut exact_set = HashSet::new(); |
|
814 | let mut exact_set = HashSet::new(); | |
@@ -927,7 +928,7 fn roots_dirs_and_parents( | |||||
927 | /// should be matched. |
|
928 | /// should be matched. | |
928 | fn build_match<'a>( |
|
929 | fn build_match<'a>( | |
929 | ignore_patterns: Vec<IgnorePattern>, |
|
930 | ignore_patterns: Vec<IgnorePattern>, | |
930 |
glob_suffix: |
|
931 | glob_suffix: GlobSuffix, | |
931 | ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> { |
|
932 | ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> { | |
932 | let mut match_funcs: Vec<IgnoreFnType<'a>> = vec![]; |
|
933 | let mut match_funcs: Vec<IgnoreFnType<'a>> = vec![]; | |
933 | // For debugging and printing |
|
934 | // For debugging and printing | |
@@ -1067,7 +1068,8 impl<'a> IncludeMatcher<'a> { | |||||
1067 | let prefix = ignore_patterns.iter().all(|k| { |
|
1068 | let prefix = ignore_patterns.iter().all(|k| { | |
1068 | matches!(k.syntax, PatternSyntax::Path | PatternSyntax::RelPath) |
|
1069 | matches!(k.syntax, PatternSyntax::Path | PatternSyntax::RelPath) | |
1069 | }); |
|
1070 | }); | |
1070 |
let (patterns, match_fn) = |
|
1071 | let (patterns, match_fn) = | |
|
1072 | build_match(ignore_patterns, GlobSuffix::MoreComponents)?; | |||
1071 |
|
1073 | |||
1072 | Ok(Self { |
|
1074 | Ok(Self { | |
1073 | patterns, |
|
1075 | patterns, |
General Comments 0
You need to be logged in to leave comments.
Login now