mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-16 08:27:05 +00:00
Add tools/trim-includes: Script to clean up includes
Change-Id: I37e98f7bf6cc4f6a10eaae6b87b2c8e46dcdee18 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/43885 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
fe2ceb9b5d
commit
b78251fdcd
76
tools/trim-includes/match/match.go
Normal file
76
tools/trim-includes/match/match.go
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package match provides functions for performing filepath [?,*,**] wildcard
|
||||
// matching.
|
||||
package match
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Test is the match predicate returned by New.
|
||||
type Test func(path string) bool
|
||||
|
||||
// New returns a Test function that returns true iff the path matches the
|
||||
// provided pattern.
|
||||
//
|
||||
// pattern uses forward-slashes for directory separators '/', and may use the
|
||||
// following wildcards:
|
||||
// ? - matches any single non-separator character
|
||||
// * - matches any sequence of non-separator characters
|
||||
// ** - matches any sequence of characters including separators
|
||||
func New(pattern string) (Test, error) {
|
||||
// Transform pattern into a regex by replacing the uses of `?`, `*`, `**`
|
||||
// with corresponding regex patterns.
|
||||
// As the pattern may contain other regex sequences, the string has to be
|
||||
// escaped. So:
|
||||
// a) Replace the patterns of `?`, `*`, `**` with unique placeholder tokens.
|
||||
// b) Escape the expression so that other sequences don't confuse the regex
|
||||
// parser.
|
||||
// c) Replace the placeholder tokens with the corresponding regex tokens.
|
||||
|
||||
// Temporary placeholder tokens
|
||||
const (
|
||||
starstar = "••"
|
||||
star = "•"
|
||||
questionmark = "¿"
|
||||
)
|
||||
// Check pattern doesn't contain any of our placeholder tokens
|
||||
for _, r := range []rune{'•', '¿'} {
|
||||
if strings.ContainsRune(pattern, r) {
|
||||
return nil, fmt.Errorf("Pattern must not contain '%c'", r)
|
||||
}
|
||||
}
|
||||
// Replace **, * and ? with placeholder tokens
|
||||
subbed := pattern
|
||||
subbed = strings.ReplaceAll(subbed, "**", starstar)
|
||||
subbed = strings.ReplaceAll(subbed, "*", star)
|
||||
subbed = strings.ReplaceAll(subbed, "?", questionmark)
|
||||
// Escape any remaining regex characters
|
||||
escaped := regexp.QuoteMeta(subbed)
|
||||
// Insert regex matchers for the substituted tokens
|
||||
regex := "^" + escaped + "$"
|
||||
regex = strings.ReplaceAll(regex, starstar, ".*")
|
||||
regex = strings.ReplaceAll(regex, star, "[^/]*")
|
||||
regex = strings.ReplaceAll(regex, questionmark, "[^/]")
|
||||
|
||||
re, err := regexp.Compile(regex)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`Failed to compile regex "%v" for pattern "%v": %w`, regex, pattern, err)
|
||||
}
|
||||
return re.MatchString, nil
|
||||
}
|
||||
106
tools/trim-includes/match/match_test.go
Normal file
106
tools/trim-includes/match/match_test.go
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package match_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
match "."
|
||||
)
|
||||
|
||||
func TestMatch(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
pattern string
|
||||
path string
|
||||
expect bool
|
||||
}{
|
||||
{"a", "a", true},
|
||||
{"b", "a", false},
|
||||
|
||||
{"?", "a", true},
|
||||
{"a/?/c", "a/x/c", true},
|
||||
{"a/??/c", "a/x/c", false},
|
||||
{"a/??/c", "a/xx/c", true},
|
||||
{"a/???/c", "a/x z/c", true},
|
||||
{"a/?/c", "a/xx/c", false},
|
||||
{"a/?/?/c", "a/x/y/c", true},
|
||||
{"a/?/?/?/c", "a/x/y/z/c", true},
|
||||
{"a/???/c", "a/x/y/c", false},
|
||||
{"a/?????", "a/x/y/c", false},
|
||||
|
||||
{"*", "a", true},
|
||||
{"*", "abc", true},
|
||||
{"*", "abc 123", true},
|
||||
{"*", "xxx/yyy", false},
|
||||
{"*/*", "xxx/yyy", true},
|
||||
{"*/*", "xxx/yyy/zzz", false},
|
||||
{"*/*/c", "xxx/yyy/c", true},
|
||||
{"a/*/*", "a/xxx/yyy", true},
|
||||
{"a/*/c", "a/xxx/c", true},
|
||||
{"a/*/c", "a/xxx/c", true},
|
||||
{"a/*/*/c", "a/b/c", false},
|
||||
|
||||
{"**", "a", true},
|
||||
{"**", "abc", true},
|
||||
{"**", "abc 123", true},
|
||||
{"**", "xxx/yyy", true},
|
||||
{"**", "xxx/yyy/zzz", true},
|
||||
{"**/**", "xxx", false},
|
||||
{"**/**", "xxx/yyy", true},
|
||||
{"**/**", "xxx/yyy/zzz", true},
|
||||
{"**/**/**", "xxx/yyy/zzz", true},
|
||||
{"**/**/c", "xxx/yyy/c", true},
|
||||
{"**/**/c", "xxx/yyy/c/d", false},
|
||||
{"a/**/**", "a/xxx/yyy", true},
|
||||
{"a/**/c", "a/xxx/c", true},
|
||||
{"a/**/c", "a/xxx/yyy/c", true},
|
||||
{"a/**/c", "a/xxx/y y/zzz/c", true},
|
||||
|
||||
{"a/**/c", "a/c", false},
|
||||
{"a/**c", "a/c", true},
|
||||
|
||||
{"xxx/**.foo", "xxx/aaa.foo", true},
|
||||
{"xxx/**.foo", "xxx/yyy/zzz/.foo", true},
|
||||
{"xxx/**.foo", "xxx/yyy/zzz/bar.foo", true},
|
||||
} {
|
||||
f, err := match.New(test.pattern)
|
||||
if err != nil {
|
||||
t.Errorf(`match.New("%v")`, test.pattern)
|
||||
continue
|
||||
}
|
||||
matched := f(test.path)
|
||||
switch {
|
||||
case matched && !test.expect:
|
||||
t.Errorf(`Path "%v" matched against pattern "%v"`, test.path, test.pattern)
|
||||
case !matched && test.expect:
|
||||
t.Errorf(`Path "%v" did not match against pattern "%v"`, test.path, test.pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrOnPlaceholder(t *testing.T) {
|
||||
for _, pattern := range []string{"a/b••c", "a/b•c", "a/b/¿c"} {
|
||||
_, err := match.New(pattern)
|
||||
if err == nil {
|
||||
t.Errorf(`match.New("%v") did not return an expected error`, pattern)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(err.Error(), "Pattern must not contain") {
|
||||
t.Errorf(`match.New("%v") returned unrecognised error: %v`, pattern, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user