fnmatch.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
  2. //
  3. // This program is free software: you can redistribute it and/or modify it
  4. // under the terms of the GNU General Public License as published by the Free
  5. // Software Foundation, either version 3 of the License, or (at your option)
  6. // any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful, but WITHOUT
  9. // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. // more details.
  12. //
  13. // You should have received a copy of the GNU General Public License along
  14. // with this program. If not, see <http://www.gnu.org/licenses/>.
  15. package fnmatch
  16. import (
  17. "path/filepath"
  18. "regexp"
  19. "runtime"
  20. "strings"
  21. )
  22. const (
  23. FNM_NOESCAPE = (1 << iota)
  24. FNM_PATHNAME
  25. FNM_CASEFOLD
  26. )
  27. func Convert(pattern string, flags int) (*regexp.Regexp, error) {
  28. any := "."
  29. switch runtime.GOOS {
  30. case "windows":
  31. flags |= FNM_NOESCAPE | FNM_CASEFOLD
  32. pattern = filepath.FromSlash(pattern)
  33. if flags&FNM_PATHNAME != 0 {
  34. any = "[^\\\\]"
  35. }
  36. case "darwin":
  37. flags |= FNM_CASEFOLD
  38. fallthrough
  39. default:
  40. if flags&FNM_PATHNAME != 0 {
  41. any = "[^/]"
  42. }
  43. }
  44. if flags&FNM_NOESCAPE != 0 {
  45. pattern = strings.Replace(pattern, "\\", "\\\\", -1)
  46. } else {
  47. pattern = strings.Replace(pattern, "\\*", "[:escapedstar:]", -1)
  48. pattern = strings.Replace(pattern, "\\?", "[:escapedques:]", -1)
  49. pattern = strings.Replace(pattern, "\\.", "[:escapeddot:]", -1)
  50. }
  51. pattern = strings.Replace(pattern, ".", "\\.", -1)
  52. pattern = strings.Replace(pattern, "**", "[:doublestar:]", -1)
  53. pattern = strings.Replace(pattern, "*", any+"*", -1)
  54. pattern = strings.Replace(pattern, "[:doublestar:]", ".*", -1)
  55. pattern = strings.Replace(pattern, "?", any, -1)
  56. pattern = strings.Replace(pattern, "[:escapedstar:]", "\\*", -1)
  57. pattern = strings.Replace(pattern, "[:escapedques:]", "\\?", -1)
  58. pattern = strings.Replace(pattern, "[:escapeddot:]", "\\.", -1)
  59. pattern = "^" + pattern + "$"
  60. if flags&FNM_CASEFOLD != 0 {
  61. pattern = "(?i)" + pattern
  62. }
  63. return regexp.Compile(pattern)
  64. }
  65. // Matches the pattern against the string, with the given flags,
  66. // and returns true if the match is successful.
  67. func Match(pattern, s string, flags int) (bool, error) {
  68. exp, err := Convert(pattern, flags)
  69. if err != nil {
  70. return false, err
  71. }
  72. return exp.MatchString(s), nil
  73. }