...
1 package gitignore
2
3 import "strings"
4
5 const (
6 asc = iota
7 desc
8 )
9
10 type depthPatternHolder struct {
11 patterns depthPatterns
12 order int
13 }
14
15 func newDepthPatternHolder(order int) depthPatternHolder {
16 return depthPatternHolder{
17 patterns: depthPatterns{m: map[int]initialPatternHolder{}},
18 order: order,
19 }
20 }
21
22 func (h *depthPatternHolder) add(pattern string) {
23 count := strings.Count(strings.Trim(pattern, "/"), "/")
24 h.patterns.set(count+1, pattern)
25 }
26
27 func (h depthPatternHolder) match(path string, isDir bool) bool {
28 if h.patterns.size() == 0 {
29 return false
30 }
31
32 for depth := 1; ; depth++ {
33 var part string
34 var isLast, isDirCurrent bool
35 if h.order == asc {
36 part, isLast = cutN(path, depth)
37 if isLast {
38 isDirCurrent = isDir
39 } else {
40 isDirCurrent = false
41 }
42 } else {
43 part, isLast = cutLastN(path, depth)
44 isDirCurrent = isDir
45 }
46 if patterns, ok := h.patterns.get(depth); ok {
47 if patterns.match(part, isDirCurrent) {
48 return true
49 }
50 }
51 if isLast {
52 break
53 }
54 }
55 return false
56 }
57
58 type depthPatterns struct {
59 m map[int]initialPatternHolder
60 }
61
62 func (p *depthPatterns) set(depth int, pattern string) {
63 if ps, ok := p.m[depth]; ok {
64 ps.add(pattern)
65 } else {
66 holder := newInitialPatternHolder()
67 holder.add(pattern)
68 p.m[depth] = holder
69 }
70 }
71
72 func (p depthPatterns) get(depth int) (initialPatternHolder, bool) {
73 patterns, ok := p.m[depth]
74 return patterns, ok
75 }
76
77 func (p depthPatterns) size() int {
78 return len(p.m)
79 }
80
View as plain text