##// END OF EJS Templates
rust: simplify pattern file parsing...
Spencer Baugh -
r51750:796b5d66 default
parent child Browse files
Show More
@@ -335,17 +335,22 b' pub fn build_single_regex('
335 335 }
336 336
337 337 lazy_static! {
338 static ref SYNTAXES: FastHashMap<&'static [u8], &'static [u8]> = {
338 static ref SYNTAXES: FastHashMap<&'static [u8], PatternSyntax> = {
339 339 let mut m = FastHashMap::default();
340 340
341 m.insert(b"re".as_ref(), b"relre:".as_ref());
342 m.insert(b"regexp".as_ref(), b"relre:".as_ref());
343 m.insert(b"glob".as_ref(), b"relglob:".as_ref());
344 m.insert(b"rootglob".as_ref(), b"rootglob:".as_ref());
345 m.insert(b"include".as_ref(), b"include:".as_ref());
346 m.insert(b"subinclude".as_ref(), b"subinclude:".as_ref());
347 m.insert(b"path".as_ref(), b"path:".as_ref());
348 m.insert(b"rootfilesin".as_ref(), b"rootfilesin:".as_ref());
341 m.insert(b"re:".as_ref(), PatternSyntax::Regexp);
342 m.insert(b"regexp:".as_ref(), PatternSyntax::Regexp);
343 m.insert(b"path:".as_ref(), PatternSyntax::Path);
344 m.insert(b"filepath:".as_ref(), PatternSyntax::FilePath);
345 m.insert(b"relpath:".as_ref(), PatternSyntax::RelPath);
346 m.insert(b"rootfilesin:".as_ref(), PatternSyntax::RootFiles);
347 m.insert(b"relglob:".as_ref(), PatternSyntax::RelGlob);
348 m.insert(b"relre:".as_ref(), PatternSyntax::RelRegexp);
349 m.insert(b"glob:".as_ref(), PatternSyntax::Glob);
350 m.insert(b"rootglob:".as_ref(), PatternSyntax::RootGlob);
351 m.insert(b"include:".as_ref(), PatternSyntax::Include);
352 m.insert(b"subinclude:".as_ref(), PatternSyntax::SubInclude);
353
349 354 m
350 355 };
351 356 }
@@ -358,11 +363,37 b' pub enum PatternFileWarning {'
358 363 NoSuchFile(PathBuf),
359 364 }
360 365
366 pub fn parse_one_pattern(
367 pattern: &[u8],
368 source: &Path,
369 default: PatternSyntax,
370 ) -> IgnorePattern {
371 let mut pattern_bytes: &[u8] = pattern;
372 let mut syntax = default;
373
374 for (s, val) in SYNTAXES.iter() {
375 if let Some(rest) = pattern_bytes.drop_prefix(s) {
376 syntax = val.clone();
377 pattern_bytes = rest;
378 break;
379 }
380 }
381
382 let pattern = pattern_bytes.to_vec();
383
384 IgnorePattern {
385 syntax,
386 pattern,
387 source: source.to_owned(),
388 }
389 }
390
361 391 pub fn parse_pattern_file_contents(
362 392 lines: &[u8],
363 393 file_path: &Path,
364 default_syntax_override: Option<&[u8]>,
394 default_syntax_override: Option<PatternSyntax>,
365 395 warn: bool,
396 relativize: bool,
366 397 ) -> Result<(Vec<IgnorePattern>, Vec<PatternFileWarning>), PatternError> {
367 398 let comment_regex = Regex::new(r"((?:^|[^\\])(?:\\\\)*)#.*").unwrap();
368 399
@@ -372,11 +403,9 b' pub fn parse_pattern_file_contents('
372 403 let mut warnings: Vec<PatternFileWarning> = vec![];
373 404
374 405 let mut current_syntax =
375 default_syntax_override.unwrap_or_else(|| b"relre:".as_ref());
406 default_syntax_override.unwrap_or(PatternSyntax::RelRegexp);
376 407
377 for (line_number, mut line) in lines.split(|c| *c == b'\n').enumerate() {
378 let line_number = line_number + 1;
379
408 for mut line in lines.split(|c| *c == b'\n') {
380 409 let line_buf;
381 410 if line.contains(&b'#') {
382 411 if let Some(cap) = comment_regex.captures(line) {
@@ -386,7 +415,7 b' pub fn parse_pattern_file_contents('
386 415 line = &line_buf;
387 416 }
388 417
389 let mut line = line.trim_end();
418 let line = line.trim_end();
390 419
391 420 if line.is_empty() {
392 421 continue;
@@ -395,46 +424,28 b' pub fn parse_pattern_file_contents('
395 424 if let Some(syntax) = line.drop_prefix(b"syntax:") {
396 425 let syntax = syntax.trim();
397 426
398 if let Some(rel_syntax) = SYNTAXES.get(syntax) {
399 current_syntax = rel_syntax;
427 if let Some(parsed) =
428 SYNTAXES.get([syntax, &b":"[..]].concat().as_slice())
429 {
430 current_syntax = parsed.clone();
400 431 } else if warn {
401 432 warnings.push(PatternFileWarning::InvalidSyntax(
402 433 file_path.to_owned(),
403 434 syntax.to_owned(),
404 435 ));
405 436 }
406 continue;
437 } else {
438 let pattern = parse_one_pattern(
439 line,
440 file_path,
441 current_syntax.clone(),
442 );
443 inputs.push(if relativize {
444 pattern.to_relative()
445 } else {
446 pattern
447 })
407 448 }
408
409 let mut line_syntax: &[u8] = current_syntax;
410
411 for (s, rels) in SYNTAXES.iter() {
412 if let Some(rest) = line.drop_prefix(rels) {
413 line_syntax = rels;
414 line = rest;
415 break;
416 }
417 if let Some(rest) = line.drop_prefix(&[s, &b":"[..]].concat()) {
418 line_syntax = rels;
419 line = rest;
420 break;
421 }
422 }
423
424 inputs.push(IgnorePattern::new(
425 parse_pattern_syntax(line_syntax).map_err(|e| match e {
426 PatternError::UnsupportedSyntax(syntax) => {
427 PatternError::UnsupportedSyntaxInFile(
428 syntax,
429 file_path.to_string_lossy().into(),
430 line_number,
431 )
432 }
433 _ => e,
434 })?,
435 line,
436 file_path,
437 ));
438 449 }
439 450 Ok((inputs, warnings))
440 451 }
@@ -447,7 +458,7 b' pub fn read_pattern_file('
447 458 match std::fs::read(file_path) {
448 459 Ok(contents) => {
449 460 inspect_pattern_bytes(file_path, &contents);
450 parse_pattern_file_contents(&contents, file_path, None, warn)
461 parse_pattern_file_contents(&contents, file_path, None, warn, true)
451 462 }
452 463 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok((
453 464 vec![],
@@ -473,6 +484,23 b' impl IgnorePattern {'
473 484 source: source.to_owned(),
474 485 }
475 486 }
487
488 pub fn to_relative(self) -> Self {
489 let Self {
490 syntax,
491 pattern,
492 source,
493 } = self;
494 Self {
495 syntax: match syntax {
496 PatternSyntax::Regexp => PatternSyntax::RelRegexp,
497 PatternSyntax::Glob => PatternSyntax::RelGlob,
498 x => x,
499 },
500 pattern,
501 source,
502 }
503 }
476 504 }
477 505
478 506 pub type PatternResult<T> = Result<T, PatternError>;
@@ -639,7 +667,8 b' mod tests {'
639 667 lines,
640 668 Path::new("file_path"),
641 669 None,
642 false
670 false,
671 true,
643 672 )
644 673 .unwrap()
645 674 .0,
@@ -657,7 +686,8 b' mod tests {'
657 686 lines,
658 687 Path::new("file_path"),
659 688 None,
660 false
689 false,
690 true,
661 691 )
662 692 .unwrap()
663 693 .0,
@@ -669,7 +699,8 b' mod tests {'
669 699 lines,
670 700 Path::new("file_path"),
671 701 None,
672 false
702 false,
703 true,
673 704 )
674 705 .unwrap()
675 706 .0,
@@ -74,6 +74,7 b' pub fn matcher('
74 74 Path::new(""),
75 75 None,
76 76 false,
77 true,
77 78 )?;
78 79 warnings.extend(subwarnings.into_iter().map(From::from));
79 80
@@ -85,6 +86,7 b' pub fn matcher('
85 86 Path::new(""),
86 87 None,
87 88 false,
89 true,
88 90 )?;
89 91 if !patterns.is_empty() {
90 92 warnings.extend(subwarnings.into_iter().map(From::from));
@@ -282,7 +282,8 b' pub fn matcher('
282 282 let (patterns, subwarnings) = parse_pattern_file_contents(
283 283 &config.includes,
284 284 Path::new(""),
285 Some(b"glob:".as_ref()),
285 Some(PatternSyntax::Glob),
286 false,
286 287 false,
287 288 )?;
288 289 warnings.extend(subwarnings.into_iter().map(From::from));
@@ -292,7 +293,8 b' pub fn matcher('
292 293 let (patterns, subwarnings) = parse_pattern_file_contents(
293 294 &config.excludes,
294 295 Path::new(""),
295 Some(b"glob:".as_ref()),
296 Some(PatternSyntax::Glob),
297 false,
296 298 false,
297 299 )?;
298 300 warnings.extend(subwarnings.into_iter().map(From::from));
General Comments 0
You need to be logged in to leave comments. Login now