-
Notifications
You must be signed in to change notification settings - Fork 15
/
glob.go
75 lines (62 loc) · 1.51 KB
/
glob.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
/* ipp-usb - HTTP reverse proxy, backed by IPP-over-USB connection to device
*
* Copyright (C) 2020 and up by Alexander Pevzner ([email protected])
* See LICENSE for license terms and conditions
*
* Glob-style pattern matching
*/
package main
// GlobMatch matches string against glob-style pattern.
// Pattern may contain wildcards and has a following syntax:
// * - matches any sequence of characters
// ? - matches exactly one character
// \ C - matches character C
// C - matches character C (C is not *, ? or \)
//
// It return a counter of matched non-wildcard characters, -1 if no match
func GlobMatch(str, pattern string) int {
return globMatchInternal(str, pattern, 0)
}
// globMatchInternal does the actual work of GlobMatch() function
func globMatchInternal(str, pattern string, count int) int {
for str != "" && pattern != "" {
p := pattern[0]
pattern = pattern[1:]
switch p {
case '*':
for pattern != "" && pattern[0] == '*' {
pattern = pattern[1:]
}
if pattern == "" {
return count
}
for i := 0; i < len(str); i++ {
c2 := globMatchInternal(str[i:], pattern, count)
if c2 >= 0 {
return c2
}
}
case '?':
str = str[1:]
case '\\':
if pattern == "" {
return -1
}
p, pattern = pattern[0], pattern[1:]
fallthrough
default:
if str[0] != p {
return -1
}
str = str[1:]
count++
}
}
for pattern != "" && pattern[0] == '*' {
pattern = pattern[1:]
}
if str == "" && pattern == "" {
return count
}
return -1
}