| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- // Copyright (C) 2014 The Syncthing Authors.
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this file,
- // You can obtain one at http://mozilla.org/MPL/2.0/.
- package fnmatch
- import (
- "path/filepath"
- "regexp"
- "runtime"
- "strings"
- )
- const (
- NoEscape = (1 << iota)
- PathName
- CaseFold
- )
- func Convert(pattern string, flags int) (*regexp.Regexp, error) {
- any := "."
- switch runtime.GOOS {
- case "windows":
- flags |= NoEscape | CaseFold
- pattern = filepath.FromSlash(pattern)
- if flags&PathName != 0 {
- any = `[^\\]`
- }
- case "darwin":
- flags |= CaseFold
- fallthrough
- default:
- if flags&PathName != 0 {
- any = `[^/]`
- }
- }
- if flags&NoEscape != 0 {
- pattern = strings.Replace(pattern, `\`, `\\`, -1)
- } else {
- pattern = strings.Replace(pattern, `\*`, "[:escapedstar:]", -1)
- pattern = strings.Replace(pattern, `\?`, "[:escapedques:]", -1)
- pattern = strings.Replace(pattern, `\.`, "[:escapeddot:]", -1)
- }
- // Characters that are special in regexps but not in glob, must be
- // escaped.
- for _, char := range []string{`.`, `+`, `$`, `^`, `(`, `)`, `|`} {
- pattern = strings.Replace(pattern, char, `\`+char, -1)
- }
- pattern = strings.Replace(pattern, `**`, `[:doublestar:]`, -1)
- pattern = strings.Replace(pattern, `*`, any+`*`, -1)
- pattern = strings.Replace(pattern, `[:doublestar:]`, `.*`, -1)
- pattern = strings.Replace(pattern, `?`, any, -1)
- pattern = strings.Replace(pattern, `[:escapedstar:]`, `\*`, -1)
- pattern = strings.Replace(pattern, `[:escapedques:]`, `\?`, -1)
- pattern = strings.Replace(pattern, `[:escapeddot:]`, `\.`, -1)
- pattern = `^` + pattern + `$`
- if flags&CaseFold != 0 {
- pattern = `(?i)` + pattern
- }
- return regexp.Compile(pattern)
- }
- // Match matches the pattern against the string, with the given flags, and
- // returns true if the match is successful.
- func Match(pattern, s string, flags int) (bool, error) {
- exp, err := Convert(pattern, flags)
- if err != nil {
- return false, err
- }
- return exp.MatchString(s), nil
- }
|