diff options
Diffstat (limited to '3rdparty/bgfx/3rdparty/spirv-tools/utils/vscode/src/tools/gen-grammar.go')
-rw-r--r-- | 3rdparty/bgfx/3rdparty/spirv-tools/utils/vscode/src/tools/gen-grammar.go | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/utils/vscode/src/tools/gen-grammar.go b/3rdparty/bgfx/3rdparty/spirv-tools/utils/vscode/src/tools/gen-grammar.go new file mode 100644 index 00000000000..f07dde0d636 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/spirv-tools/utils/vscode/src/tools/gen-grammar.go @@ -0,0 +1,167 @@ +// Copyright (C) 2019 Google Inc. +// +// 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 +// +// http://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. + +// gen-grammar generates the spirv.json grammar file from the official SPIR-V +// grammar JSON file. +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "runtime" + "strings" + "text/template" + + "github.com/pkg/errors" + + "../grammar" +) + +const ( + spirvGrammarURL = "https://raw.githubusercontent.com/KhronosGroup/SPIRV-Headers/master/include/spirv/unified1/spirv.core.grammar.json" + spirvGrammarName = "spirv.core.grammar.json" +) + +var ( + templatePath = flag.String("template", "", "Path to input template file (required)") + outputPath = flag.String("out", "", "Path to output generated file (required)") + cachePath = flag.String("cache", "", "Cache directory for downloaded files (optional)") + + thisDir = func() string { + _, file, _, _ := runtime.Caller(1) + return filepath.Dir(file) + }() +) + +func main() { + flag.Parse() + if *templatePath == "" || *outputPath == "" { + flag.Usage() + os.Exit(1) + } + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func run() error { + tf, err := ioutil.ReadFile(*templatePath) + if err != nil { + return errors.Wrap(err, "Could not open template file") + } + t, err := template.New("tmpl"). + Funcs(template.FuncMap{ + "GenerateArguments": func() string { + relPath := func(path string) string { + rel, err := filepath.Rel(thisDir, path) + if err != nil { + return path + } + return rel + } + args := []string{ + "--template=" + relPath(*templatePath), + "--out=" + relPath(*outputPath), + } + return "gen-grammar.go " + strings.Join(args, " ") + }, + "OperandKindsMatch": func(k grammar.OperandKind) string { + sb := strings.Builder{} + for i, e := range k.Enumerants { + if i > 0 { + sb.WriteString("|") + } + sb.WriteString(e.Enumerant) + } + return sb.String() + }, + }).Parse(string(tf)) + if err != nil { + return errors.Wrap(err, "Failed to parse template") + } + + file, err := getOrDownload(spirvGrammarName, spirvGrammarURL) + if err != nil { + return errors.Wrap(err, "Failed to load grammar file") + } + + g := grammar.Root{} + if err := json.NewDecoder(bytes.NewReader(file)).Decode(&g); err != nil { + return errors.Wrap(err, "Failed to parse grammar file") + } + + buf := bytes.Buffer{} + if err := t.Execute(&buf, g); err != nil { + return errors.Wrap(err, "Failed to execute template") + } + + out := buf.String() + out = strings.ReplaceAll(out, "•", "") + + if err := ioutil.WriteFile(*outputPath, []byte(out), 0777); err != nil { + return errors.Wrap(err, "Failed to write output file") + } + + return nil +} + +// getOrDownload loads the specific file from the cache, or downloads the file +// from the given url. +func getOrDownload(name, url string) ([]byte, error) { + if *cachePath != "" { + if err := os.MkdirAll(*cachePath, 0777); err == nil { + path := filepath.Join(*cachePath, name) + if isFile(path) { + return ioutil.ReadFile(path) + } + } + } + resp, err := http.Get(url) + if err != nil { + return nil, err + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if *cachePath != "" { + ioutil.WriteFile(filepath.Join(*cachePath, name), data, 0777) + } + return data, nil +} + +// isFile returns true if path is a file. +func isFile(path string) bool { + s, err := os.Stat(path) + if err != nil { + return false + } + return !s.IsDir() +} + +// isDir returns true if path is a directory. +func isDir(path string) bool { + s, err := os.Stat(path) + if err != nil { + return false + } + return s.IsDir() +} |