-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathglob.go
More file actions
89 lines (76 loc) · 1.99 KB
/
glob.go
File metadata and controls
89 lines (76 loc) · 1.99 KB
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
/* ipp-usb - HTTP reverse proxy, backed by IPP-over-USB connection to device
*
* Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com)
* 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 exactly one character
// * - matches any sequence of characters
// \C - matches character C
// C - matches character C (C is not *, ? or \)
//
// This function is used to match quirks, applicable to devices,
// by model name.
//
// It returns the "matching weight" which allows to prioritize
// quirks, if there are multiple matches, as more or less specific
// (the more the weight, the more specific the quirk is).
//
// For the glob-style model name matching, the match weight is defined
// as a counter of matched non-wildcard characters.
//
// If there is no match, it returns -1.
//
// Se also [HWIDPattern.Match] documentation for comparison with
// the similar function, used for match-by-HWID purpose.
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
}