diff --git a/README.md b/README.md index f44d171..0609c47 100644 --- a/README.md +++ b/README.md @@ -61,5 +61,6 @@ A few notes about the flags to `generate`: - `version`: The API version to generate. The `all` pseudo-version includes all functions and enumerations for the specified API. - `profile`: For `gl` packages with version 3.2 or higher, `core` or `compatibility` ([explanation](http://www.opengl.org/wiki/Core_And_Compatibility_in_Contexts)). - `addext`: A regular expression describing which extensions to include. `.*` by default, including everything. +- `restrict`: A JSON file that explicitly lists what enumerations / functions that Glow should generate (see example.json). - `remext`: A regular expression describing which extensions to exclude. Empty by default, excluding nothing. Takes precedence over explicitly added regular expressions. - `lenientInit`: Flag to disable strict function availability checks at `Init` time. By default if any non-extension function pointer cannot be loaded then initialization fails; when this flag is set initialization will succeed with missing functions. Note that on some platforms unavailable functions will load successfully even but fail upon invocation so check against the OpenGL context what is supported. diff --git a/example.json b/example.json new file mode 100644 index 0000000..109e67b --- /dev/null +++ b/example.json @@ -0,0 +1,11 @@ +{ + "Enums": [ + "GL_CCW", + "GL_COLOR_ATTACHMENT0", + "GL_COMPRESSED_RGB" + ], + "Functions": [ + "glBindTextures", + "glBindVertexArray" + ] +} diff --git a/main.go b/main.go index 6f60ddd..cb83b3d 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( + "encoding/json" "flag" "fmt" "io/ioutil" @@ -61,6 +62,7 @@ func generate(name string, args []string) { profile := flags.String("profile", "", "API profile to generate (e.g., core)") addext := flags.String("addext", ".*", "Regular expression of extensions to include (e.g., .*)") remext := flags.String("remext", "$^", "Regular expression of extensions to exclude (e.g., .*)") + restrict := flags.String("restrict", "", "JSON file of symbols to restrict symbol generation") lenientInit := flags.Bool("lenientInit", false, "When true missing functions do not fail Init") flags.Parse(args) @@ -97,6 +99,9 @@ func generate(name string, args []string) { pkg = spec.ToPackage(packageSpec) pkg.SpecRev = rev docs.AddDocs(pkg) + if len(*restrict) > 0 { + performRestriction(pkg, *restrict) + } if err := pkg.GeneratePackage(); err != nil { log.Fatal("error generating package:", err) } @@ -109,6 +114,34 @@ func generate(name string, args []string) { log.Println("generated package in", pkg.Dir()) } +// Converts a slice string into a simple lookup map. +func lookupMap(s []string) map[string]bool { + lookup := make(map[string]bool, len(s)) + for _, str := range s { + lookup[str] = true + } + return lookup +} + +type jsonRestriction struct { + Enums []string + Functions []string +} + +// Reads the given JSON file path into jsonRestriction and filters the package +// accordingly. +func performRestriction(pkg *Package, jsonPath string) { + data, err := ioutil.ReadFile(jsonPath) + if err != nil { + log.Fatal("error reading JSON restriction file:", err) + } + var r jsonRestriction + if err = json.Unmarshal(data, &r); err != nil { + log.Fatal("error parsing JSON restriction file:", err) + } + pkg.Filter(lookupMap(r.Enums), lookupMap(r.Functions)) +} + func parseSpecifications(xmlDir string) ([]*Specification, string) { specDir := filepath.Join(xmlDir, "spec") specFiles, err := ioutil.ReadDir(specDir) diff --git a/package.go b/package.go index f0076bc..b725fcf 100644 --- a/package.go +++ b/package.go @@ -109,6 +109,31 @@ func (pkg *Package) HasRequiredFunctions() bool { return false } +// Filter removes any enums, or functions found in this package that are not +// listed in the given lookup maps. If either of the maps has a length of zero, +// filtering does not occur for that type (e.g. all functions are left intact). +func (pkg *Package) Filter(enums, functions map[string]bool) { + if len(enums) > 0 { + // Remove any enum not listed in the enums lookup map. + for name := range pkg.Enums { + _, valid := enums[name] + if !valid { + delete(pkg.Enums, name) + } + } + } + + if len(functions) > 0 { + // Remove any function not listed in the functions lookup map. + for name := range pkg.Functions { + _, valid := functions[name] + if !valid { + delete(pkg.Functions, name) + } + } + } +} + // This package's directory (relative to $GOPATH). const pkgDir = "src/github.com/go-gl/glow"