73 lines
1.9 KiB
Go
73 lines
1.9 KiB
Go
package editorconfig
|
|
|
|
/*
|
|
* Converts a string from a .editorconfig file to a Go-compatible regex. Refer to the documentation
|
|
* in `docs/file-pattern-matchers.md`
|
|
*/
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var metaCharsRegexp = []*regexp.Regexp{
|
|
// Characters .+$^!()
|
|
regexp.MustCompile(`([\.\+\$\^\!\(\)])`),
|
|
// [ not followed by a ]
|
|
regexp.MustCompile(`(\[[^\]]*)$`),
|
|
// ] not preceded by a [
|
|
regexp.MustCompile(`^([^\[]*\])`),
|
|
}
|
|
|
|
func ConvertWildcardPatternToGoRegexp(pattern string) *regexp.Regexp {
|
|
if pattern == "*" {
|
|
// As documented in `docs/file-pattern-matchers.md`, we deviate from the official
|
|
// documentation here and make * match every file.
|
|
return regexp.MustCompile(".")
|
|
}
|
|
|
|
originalPattern := pattern
|
|
|
|
for _, r := range metaCharsRegexp {
|
|
pattern = r.ReplaceAllString(pattern, "\\$1")
|
|
}
|
|
|
|
// Handle **
|
|
pattern = strings.Replace(pattern, `**`, `.+`, -1)
|
|
|
|
// Handle *
|
|
pattern = strings.Replace(pattern, `*`, `[^/\\]+`, -1)
|
|
|
|
// Handle ?
|
|
pattern = strings.Replace(pattern, `?`, `.`, -1)
|
|
|
|
// [seq] should work already.
|
|
|
|
// Handle [!seq]
|
|
pattern = strings.Replace(pattern, `[\!`, `[^`, -1)
|
|
|
|
// Handle {s1,s2,s3}
|
|
for i := 1; i < 7; i++ {
|
|
find := `\{([^,}]+)` + strings.Repeat(`,([^,}]+)`, i) + `\}`
|
|
replace := "($1"
|
|
for ii := 1; ii <= i; ii++ {
|
|
replace += "|$" + strconv.Itoa(ii+1)
|
|
}
|
|
replace += ")"
|
|
pattern = regexp.MustCompile(find).ReplaceAllString(pattern, replace)
|
|
}
|
|
|
|
// Handle {num1..num2}
|
|
// @todo - This is currently not fully supported. If there is a numeric range, we only check
|
|
// that numbers are present; we don't check if the numbers present are within the correct range.
|
|
pattern = regexp.MustCompile(`\{-?\d+\\.\\.-?\d+\}`).ReplaceAllString(pattern, `[-0-9]+`)
|
|
|
|
r, err := regexp.Compile(pattern)
|
|
if err != nil {
|
|
ExitBecauseOfInternalError("A file pattern could not be parsed: " + originalPattern)
|
|
}
|
|
|
|
return r
|
|
}
|