-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
path_linux.go
110 lines (92 loc) · 2.11 KB
/
path_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.
package utils
// PathPatternMatchOpts PathPatternMatch options
type PathPatternMatchOpts struct {
WildcardLimit int // max number of wildcard in the pattern
PrefixNodeRequired int // number of prefix nodes required
SuffixNodeRequired int // number of suffix nodes required
NodeSizeLimit int // min size required to substitute with a wildcard
}
// PathPatternMatch pattern builder for files
func PathPatternMatch(pattern string, path string, opts PathPatternMatchOpts) bool {
var (
i, j, offsetPath = 0, 0, 0
wildcardCount, nodeCount, suffixNode = 0, 0, 0
patternLen, pathLen = len(pattern), len(path)
wildcard bool
computeNode = func() bool {
if wildcard {
wildcardCount++
if wildcardCount > opts.WildcardLimit {
return false
}
if nodeCount < opts.PrefixNodeRequired {
return false
}
if opts.NodeSizeLimit != 0 && j-offsetPath < opts.NodeSizeLimit {
return false
}
suffixNode = 0
} else {
suffixNode++
}
offsetPath = j
if i > 0 {
nodeCount++
}
return true
}
)
if patternLen > 0 && pattern[0] != '/' {
return false
}
if pathLen > 0 && path[0] != '/' {
return false
}
for i < len(pattern) && j < len(path) {
pn, ph := pattern[i], path[j]
if pn == '/' && ph == '/' {
if !computeNode() {
return false
}
wildcard = false
i++
j++
continue
}
if pn != ph {
wildcard = true
}
if pn != '/' {
i++
}
if ph != '/' {
j++
}
}
if patternLen != i || pathLen != j {
wildcard = true
}
for i < patternLen {
if pattern[i] == '/' {
return false
}
i++
}
for j < pathLen {
if path[j] == '/' {
return false
}
j++
}
if !computeNode() {
return false
}
if opts.SuffixNodeRequired == 0 || suffixNode >= opts.SuffixNodeRequired {
return true
}
return false
}