Skip to content

Commit

Permalink
optimize building patterns with strings.Builder
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed Sep 1, 2024
1 parent ab0e2e3 commit b5c3682
Showing 1 changed file with 41 additions and 33 deletions.
74 changes: 41 additions & 33 deletions zglob.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,111 +92,119 @@ func New(pattern string) (*zenv, error) {
globmask = toSlash(path.Clean(globmask))

cc := []rune(globmask)
dirmask := ""
filemask := ""
var dirmask strings.Builder
var filemask strings.Builder
staticDir := true
for i := 0; i < len(cc); i++ {
if i < len(cc)-2 && cc[i] == '\\' {
i++
filemask += fmt.Sprintf("[\\x%02X]", cc[i])
fmt.Fprintf(&filemask, "[\\x%02X]", cc[i])
if staticDir {
dirmask += string(cc[i])
dirmask.WriteRune(cc[i])
}
} else if cc[i] == '*' {
staticDir = false
if i < len(cc)-2 && cc[i+1] == '*' && cc[i+2] == '/' {
filemask += "(.*/)?"
filemask.WriteString("(.*/)?")
i += 2
} else {
filemask += "[^/]*"
filemask.WriteString("[^/]*")
}
} else if cc[i] == '[' { // range
staticDir = false
pattern := ""
var b strings.Builder
for j := i + 1; j < len(cc); j++ {
if cc[j] == ']' {
i = j
break
} else {
pattern += string(cc[j])
b.WriteRune(cc[j])
}
}
if pattern != "" {
filemask += "[" + pattern + "]"
if pattern := b.String(); pattern != "" {
filemask.WriteByte('[')
filemask.WriteString(pattern)
filemask.WriteByte(']')
continue
}
} else {
if cc[i] == '{' {
staticDir = false
pattern := ""
var b strings.Builder
for j := i + 1; j < len(cc); j++ {
if cc[j] == ',' {
pattern += "|"
b.WriteByte('|')
} else if cc[j] == '}' {
i = j
break
} else {
c := cc[j]
if c == '/' {
pattern += string(c)
b.WriteRune(c)
} else if ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 255 < c {
pattern += string(c)
b.WriteRune(c)
} else {
pattern += fmt.Sprintf("[\\x%02X]", c)
fmt.Fprintf(&b, "[\\x%02X]", c)
}
}
}
if pattern != "" {
filemask += "(" + pattern + ")"
if pattern := b.String(); pattern != "" {
filemask.WriteByte('(')
filemask.WriteString(pattern)
filemask.WriteByte(')')
continue
}
} else if i < len(cc)-1 && cc[i] == '!' && cc[i+1] == '(' {
i++
pattern := ""
var b strings.Builder
for j := i + 1; j < len(cc); j++ {
if cc[j] == ')' {
i = j
break
} else {
c := cc[j]
pattern += fmt.Sprintf("[^\\x%02X/]*", c)
fmt.Fprintf(&b, "[^\\x%02X/]*", c)
}
}
if pattern != "" {
if dirmask == "" {
dirmask = filemask
root = filemask
if pattern := b.String(); pattern != "" {
if dirmask.Len() == 0 {
m := filemask.String()
dirmask.WriteString(m)
root = m
}
filemask += pattern
filemask.WriteString(pattern)
continue
}
}
c := cc[i]
if c == '/' || ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || 255 < c {
filemask += string(c)
filemask.WriteRune(c)
} else {
filemask += fmt.Sprintf("[\\x%02X]", c)
fmt.Fprintf(&filemask, "[\\x%02X]", c)
}
if staticDir {
dirmask += string(c)
dirmask.WriteRune(c)
}
}
}
if len(filemask) > 0 && filemask[len(filemask)-1] == '/' {
if m := filemask.String(); len(m) > 0 && m[len(m)-1] == '/' {
if root == "" {
root = filemask
root = m
}
filemask += "[^/]*"
filemask.WriteString("[^/]*")
}
var pat string
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
filemask = "(?i:" + filemask + ")"
pat = "^(?i:" + filemask.String() + ")$"
} else {
pat = "^" + filemask.String() + "$"
}
fre, err := regexp.Compile("^" + filemask + "$")
fre, err := regexp.Compile(pat)
if err != nil {
return nil, err
}
return &zenv{
dirmask: path.Dir(dirmask) + "/",
dirmask: path.Dir(dirmask.String()) + "/",
fre: fre,
pattern: pattern,
root: filepath.Clean(root),
Expand Down

0 comments on commit b5c3682

Please sign in to comment.