diff --git a/usbid/load.go b/usbid/load.go index b9733cd..df410c6 100644 --- a/usbid/load.go +++ b/usbid/load.go @@ -60,6 +60,8 @@ func LoadFromURL(url string) error { return nil } +//go:generate go run regen/regen.go --template regen/load_data.go.tpl -o load_data.go + func init() { ids, cls, err := ParseIDs(strings.NewReader(usbIdListData)) if err != nil { diff --git a/usbid/load_data.go b/usbid/load_data.go index 5d6877c..a3614fe 100644 --- a/usbid/load_data.go +++ b/usbid/load_data.go @@ -19,8 +19,8 @@ import "time" // LastUpdate stores the latest time that the library was updated. // // The baked-in data was last generated: -// 2016-04-03 11:25:26.920427461 -0700 PDT -var LastUpdate = time.Unix(0, 1459707926920427461) +// 2016-04-03 20:03:19.628811942 -0700 PDT +var LastUpdate = time.Unix(0, 1459738999628811942) const usbIdListData = `# # List of USB ID's diff --git a/usbid/regen/load_data.go.tpl b/usbid/regen/load_data.go.tpl new file mode 100644 index 0000000..1a0c4d1 --- /dev/null +++ b/usbid/regen/load_data.go.tpl @@ -0,0 +1,25 @@ +// Copyright 2013 Google Inc. All rights reserved. +// +// 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. + +package usbid + +import "time" + +// LastUpdate stores the latest time that the library was updated. +// +// The baked-in data was last generated: +// {{.Generated}} +var LastUpdate = time.Unix(0, {{.Generated.UnixNano}}) + +const usbIdListData = `{{printf "%s" .Data}}` diff --git a/usbid/regen/regen.go b/usbid/regen/regen.go new file mode 100644 index 0000000..261820b --- /dev/null +++ b/usbid/regen/regen.go @@ -0,0 +1,102 @@ +// Copyright 2013 Google Inc. All rights reserved. +// +// 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. + +package main + +import ( + "bytes" + "flag" + "io/ioutil" + "log" + "net/http" + "os" + "text/template" + "time" + + "github.com/kylelemons/gousb/usbid" +) + +var ( + remote = flag.String("url", usbid.LinuxUsbDotOrg, "URL from which to download new vendor data") + dataFile = flag.String("template", "load_data.go.tpl", "Template filename") + outFile = flag.String("o", "load_data.go", "Output filename") +) + +func main() { + flag.Parse() + + log.Printf("Fetching %q...", *remote) + resp, err := http.Get(*remote) + if err != nil { + log.Fatalf("failed to download from %q: %s", *remote, err) + } + defer resp.Body.Close() + + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Fatalf("failed to read %q: %s", *remote, err) + } + + ids, cls, err := usbid.ParseIDs(bytes.NewReader(data)) + if err != nil { + log.Fatalf("failed to parse %q: %s", *remote, err) + } + + log.Printf("Successfully fetched %q:", *remote) + log.Printf(" Loaded %d Vendor IDs", len(ids)) + log.Printf(" Loaded %d Class IDs", len(cls)) + + rawTemplate, err := ioutil.ReadFile(*dataFile) + if err != nil { + log.Fatalf("failed to read template %q: %s", *dataFile) + } + + template, err := template.New("").Parse(string(rawTemplate)) + if err != nil { + log.Fatalf("failed to parse template %q: %s", *dataFile, err) + } + + out, err := os.Create(*outFile) + if err != nil { + log.Fatalf("failed to open output file %q: %s", *outFile, err) + } + defer out.Close() + + templateData := struct { + Data []byte + Generated time.Time + RFC3339 string + }{ + Data: bytes.Map(sanitize, data), + Generated: time.Now(), + } + if err := template.Execute(out, templateData); err != nil { + log.Fatalf("failed to execute template: %s", err) + } + + log.Printf("Successfully wrote %q", *outFile) +} + +// sanitize strips characters that can't be `-quoted +func sanitize(r rune) rune { + switch { + case r == '`': + return -1 + case r == '\t', r == '\n': + return r + case r >= ' ' && r <= '~': + return r + } + return -1 +}