Show More
@@ -271,7 +271,7 b' pub fn normalize_path_bytes(bytes: &[u8]' | |||
|
271 | 271 | /// that don't need to be transformed into a regex. |
|
272 | 272 | pub fn build_single_regex( |
|
273 | 273 | entry: &IgnorePattern, |
|
274 | ) -> Result<Vec<u8>, PatternError> { | |
|
274 | ) -> Result<Option<Vec<u8>>, PatternError> { | |
|
275 | 275 | let IgnorePattern { |
|
276 | 276 | pattern, syntax, .. |
|
277 | 277 | } = entry; |
@@ -288,16 +288,11 b' pub fn build_single_regex(' | |||
|
288 | 288 | if *syntax == PatternSyntax::RootGlob |
|
289 | 289 | && !pattern.iter().any(|b| GLOB_SPECIAL_CHARACTERS.contains(b)) |
|
290 | 290 | { |
|
291 | // The `regex` crate adds `.*` to the start and end of expressions | |
|
292 | // if there are no anchors, so add the start anchor. | |
|
293 | let mut escaped = vec![b'^']; | |
|
294 | escaped.extend(escape_pattern(&pattern)); | |
|
295 | escaped.extend(GLOB_SUFFIX); | |
|
296 | Ok(escaped) | |
|
291 | Ok(None) | |
|
297 | 292 | } else { |
|
298 | 293 | let mut entry = entry.clone(); |
|
299 | 294 | entry.pattern = pattern; |
|
300 | Ok(_build_single_regex(&entry)) | |
|
295 | Ok(Some(_build_single_regex(&entry))) | |
|
301 | 296 | } |
|
302 | 297 | } |
|
303 | 298 | |
@@ -628,7 +623,7 b' mod tests {' | |||
|
628 | 623 | Path::new("") |
|
629 | 624 | )) |
|
630 | 625 | .unwrap(), |
|
631 | br"(?:.*/)?rust/target(?:/|$)".to_vec(), | |
|
626 | Some(br"(?:.*/)?rust/target(?:/|$)".to_vec()), | |
|
632 | 627 | ); |
|
633 | 628 | } |
|
634 | 629 | |
@@ -641,7 +636,7 b' mod tests {' | |||
|
641 | 636 | Path::new("") |
|
642 | 637 | )) |
|
643 | 638 | .unwrap(), |
|
644 | br"^\.(?:/|$)".to_vec(), | |
|
639 | None, | |
|
645 | 640 | ); |
|
646 | 641 | assert_eq!( |
|
647 | 642 | build_single_regex(&IgnorePattern::new( |
@@ -650,7 +645,7 b' mod tests {' | |||
|
650 | 645 | Path::new("") |
|
651 | 646 | )) |
|
652 | 647 | .unwrap(), |
|
653 | br"^whatever(?:/|$)".to_vec(), | |
|
648 | None, | |
|
654 | 649 | ); |
|
655 | 650 | assert_eq!( |
|
656 | 651 | build_single_regex(&IgnorePattern::new( |
@@ -659,7 +654,7 b' mod tests {' | |||
|
659 | 654 | Path::new("") |
|
660 | 655 | )) |
|
661 | 656 | .unwrap(), |
|
662 | br"^[^/]*\.o(?:/|$)".to_vec(), | |
|
657 | Some(br"^[^/]*\.o(?:/|$)".to_vec()), | |
|
663 | 658 | ); |
|
664 | 659 | } |
|
665 | 660 | } |
@@ -24,6 +24,7 b' use crate::{' | |||
|
24 | 24 | PatternSyntax, |
|
25 | 25 | }; |
|
26 | 26 | |
|
27 | use crate::filepatterns::normalize_path_bytes; | |
|
27 | 28 | use std::borrow::ToOwned; |
|
28 | 29 | use std::collections::HashSet; |
|
29 | 30 | use std::fmt::{Display, Error, Formatter}; |
@@ -373,15 +374,32 b' fn re_matcher(' | |||
|
373 | 374 | fn build_regex_match<'a>( |
|
374 | 375 | ignore_patterns: &'a [&'a IgnorePattern], |
|
375 | 376 | ) -> PatternResult<(Vec<u8>, Box<dyn Fn(&HgPath) -> bool + Sync>)> { |
|
376 | let regexps: Result<Vec<_>, PatternError> = ignore_patterns | |
|
377 | .into_iter() | |
|
378 | .map(|k| build_single_regex(*k)) | |
|
379 | .collect(); | |
|
380 | let regexps = regexps?; | |
|
377 | let mut regexps = vec![]; | |
|
378 | let mut exact_set = HashSet::new(); | |
|
379 | ||
|
380 | for pattern in ignore_patterns { | |
|
381 | if let Some(re) = build_single_regex(pattern)? { | |
|
382 | regexps.push(re); | |
|
383 | } else { | |
|
384 | let exact = normalize_path_bytes(&pattern.pattern); | |
|
385 | exact_set.insert(HgPathBuf::from_bytes(&exact)); | |
|
386 | } | |
|
387 | } | |
|
388 | ||
|
381 | 389 | let full_regex = regexps.join(&b'|'); |
|
382 | 390 | |
|
391 | // An empty pattern would cause the regex engine to incorrectly match the | |
|
392 | // (empty) root directory | |
|
393 | let func = if !(regexps.is_empty()) { | |
|
383 | 394 | let matcher = re_matcher(&full_regex)?; |
|
384 |
let func = |
|
|
395 | let func = move |filename: &HgPath| { | |
|
396 | exact_set.contains(filename) || matcher(filename) | |
|
397 | }; | |
|
398 | Box::new(func) as Box<dyn Fn(&HgPath) -> bool + Sync> | |
|
399 | } else { | |
|
400 | let func = move |filename: &HgPath| exact_set.contains(filename); | |
|
401 | Box::new(func) as Box<dyn Fn(&HgPath) -> bool + Sync> | |
|
402 | }; | |
|
385 | 403 | |
|
386 | 404 | Ok((full_regex, func)) |
|
387 | 405 | } |
General Comments 0
You need to be logged in to leave comments.
Login now