lib/ignores: Use bitmask for result
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3030
This commit is contained in:
parent
29fa05ae05
commit
abb96802cb
@ -21,8 +21,8 @@ func TestCache(t *testing.T) {
|
|||||||
|
|
||||||
// Set and check some items
|
// Set and check some items
|
||||||
|
|
||||||
c.set("true", Result{true, true})
|
c.set("true", resultInclude|resultDeletable)
|
||||||
c.set("false", Result{false, false})
|
c.set("false", 0)
|
||||||
|
|
||||||
res, ok = c.get("true")
|
res, ok = c.get("true")
|
||||||
if !res.IsIgnored() || !res.IsDeletable() || ok != true {
|
if !res.IsIgnored() || !res.IsDeletable() || ok != true {
|
||||||
|
|||||||
@ -22,44 +22,46 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var notMatched = Result{
|
const (
|
||||||
include: false,
|
resultInclude Result = 1 << iota
|
||||||
deletable: false,
|
resultDeletable = 1 << iota
|
||||||
}
|
resultFoldCase = 1 << iota
|
||||||
|
)
|
||||||
|
|
||||||
|
var notMatched Result = 0
|
||||||
|
|
||||||
type Pattern struct {
|
type Pattern struct {
|
||||||
pattern string
|
pattern string
|
||||||
match glob.Glob
|
match glob.Glob
|
||||||
include bool
|
result Result
|
||||||
foldCase bool
|
|
||||||
deletable bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Pattern) String() string {
|
func (p Pattern) String() string {
|
||||||
ret := p.pattern
|
ret := p.pattern
|
||||||
if !p.include {
|
if p.result&resultInclude != resultInclude {
|
||||||
ret = "!" + ret
|
ret = "!" + ret
|
||||||
}
|
}
|
||||||
if p.foldCase {
|
if p.result&resultFoldCase == resultFoldCase {
|
||||||
ret = "(?i)" + ret
|
ret = "(?i)" + ret
|
||||||
}
|
}
|
||||||
if p.deletable {
|
if p.result&resultDeletable == resultDeletable {
|
||||||
ret = "(?d)" + ret
|
ret = "(?d)" + ret
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result struct {
|
type Result uint8
|
||||||
include bool
|
|
||||||
deletable bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r Result) IsIgnored() bool {
|
func (r Result) IsIgnored() bool {
|
||||||
return r.include
|
return r&resultInclude == resultInclude
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Result) IsDeletable() bool {
|
func (r Result) IsDeletable() bool {
|
||||||
return r.include && r.deletable
|
return r.IsIgnored() && r&resultDeletable == resultDeletable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Result) IsCaseFolded() bool {
|
||||||
|
return r&resultFoldCase == resultFoldCase
|
||||||
}
|
}
|
||||||
|
|
||||||
type Matcher struct {
|
type Matcher struct {
|
||||||
@ -150,22 +152,16 @@ func (m *Matcher) Match(file string) (result Result) {
|
|||||||
file = filepath.ToSlash(file)
|
file = filepath.ToSlash(file)
|
||||||
var lowercaseFile string
|
var lowercaseFile string
|
||||||
for _, pattern := range m.patterns {
|
for _, pattern := range m.patterns {
|
||||||
if pattern.foldCase {
|
if pattern.result.IsCaseFolded() {
|
||||||
if lowercaseFile == "" {
|
if lowercaseFile == "" {
|
||||||
lowercaseFile = strings.ToLower(file)
|
lowercaseFile = strings.ToLower(file)
|
||||||
}
|
}
|
||||||
if pattern.match.Match(lowercaseFile) {
|
if pattern.match.Match(lowercaseFile) {
|
||||||
return Result{
|
return pattern.result
|
||||||
pattern.include,
|
|
||||||
pattern.deletable,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if pattern.match.Match(file) {
|
if pattern.match.Match(file) {
|
||||||
return Result{
|
return pattern.result
|
||||||
pattern.include,
|
|
||||||
pattern.deletable,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,11 +240,15 @@ func loadIgnoreFile(file string, seen map[string]bool) ([]Pattern, error) {
|
|||||||
func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) ([]Pattern, error) {
|
func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) ([]Pattern, error) {
|
||||||
var patterns []Pattern
|
var patterns []Pattern
|
||||||
|
|
||||||
|
defaultResult := resultInclude
|
||||||
|
if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
|
||||||
|
defaultResult |= resultFoldCase
|
||||||
|
}
|
||||||
|
|
||||||
addPattern := func(line string) error {
|
addPattern := func(line string) error {
|
||||||
pattern := Pattern{
|
pattern := Pattern{
|
||||||
pattern: line,
|
pattern: line,
|
||||||
include: true,
|
result: defaultResult,
|
||||||
foldCase: runtime.GOOS == "darwin" || runtime.GOOS == "windows",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow prefixes to be specified in any order, but only once.
|
// Allow prefixes to be specified in any order, but only once.
|
||||||
@ -258,21 +258,21 @@ func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) ([]
|
|||||||
if strings.HasPrefix(line, "!") && !seenPrefix[0] {
|
if strings.HasPrefix(line, "!") && !seenPrefix[0] {
|
||||||
seenPrefix[0] = true
|
seenPrefix[0] = true
|
||||||
line = line[1:]
|
line = line[1:]
|
||||||
pattern.include = false
|
pattern.result ^= resultInclude
|
||||||
} else if strings.HasPrefix(line, "(?i)") && !seenPrefix[1] {
|
} else if strings.HasPrefix(line, "(?i)") && !seenPrefix[1] {
|
||||||
seenPrefix[1] = true
|
seenPrefix[1] = true
|
||||||
pattern.foldCase = true
|
pattern.result |= resultFoldCase
|
||||||
line = line[4:]
|
line = line[4:]
|
||||||
} else if strings.HasPrefix(line, "(?d)") && !seenPrefix[2] {
|
} else if strings.HasPrefix(line, "(?d)") && !seenPrefix[2] {
|
||||||
seenPrefix[2] = true
|
seenPrefix[2] = true
|
||||||
pattern.deletable = true
|
pattern.result |= resultDeletable
|
||||||
line = line[4:]
|
line = line[4:]
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pattern.foldCase {
|
if pattern.result.IsCaseFolded() {
|
||||||
line = strings.ToLower(line)
|
line = strings.ToLower(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user