lib/ignores: Use bitmask for result

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3030
This commit is contained in:
Audrius Butkevicius 2016-05-01 15:58:23 +00:00 committed by Jakob Borg
parent 29fa05ae05
commit abb96802cb
2 changed files with 36 additions and 36 deletions

View File

@ -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 {

View File

@ -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)
} }