go.net/ipv4: make use of go generate to create system adaptation files
LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/160800043
diff --git a/ipv4/gen.go b/ipv4/gen.go
index f2721a5..a1d65ef 100644
--- a/ipv4/gen.go
+++ b/ipv4/gen.go
@@ -6,8 +6,9 @@
//go:generate go run gen.go
-// This program generates internet protocol constants and tables by
-// reading IANA protocol registries.
+// This program generates system adaptation constants and types,
+// internet protocol constants and tables by reading template files
+// and IANA protocol registries.
package main
import (
@@ -19,10 +20,55 @@
"io/ioutil"
"net/http"
"os"
+ "os/exec"
+ "runtime"
"strconv"
"strings"
)
+func main() {
+ if err := genzsys(); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ if err := geniana(); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+}
+
+func genzsys() error {
+ defs := "defs_" + runtime.GOOS + ".go"
+ f, err := os.Open(defs)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
+ }
+ f.Close()
+ cmd := exec.Command("go", "tool", "cgo", "-godefs", defs)
+ b, err := cmd.Output()
+ if err != nil {
+ return err
+ }
+ switch runtime.GOOS {
+ case "dragonfly", "solaris":
+ // The ipv4 pacakge still supports go1.2, and so we
+ // need to take care of additional platforms in go1.3
+ // and above for working with go1.2.
+ b = bytes.Replace(b, []byte("package ipv4\n"), []byte("// +build "+runtime.GOOS+"\n\npackage ipv4\n"), 1)
+ }
+ b, err = format.Source(b)
+ if err != nil {
+ return err
+ }
+ if err := ioutil.WriteFile("zsys_"+runtime.GOOS+".go", b, 0644); err != nil {
+ return err
+ }
+ return nil
+}
+
var registries = []struct {
url string
parse func(io.Writer, io.Reader) error
@@ -33,7 +79,7 @@
},
}
-func main() {
+func geniana() error {
var bb bytes.Buffer
fmt.Fprintf(&bb, "// go generate gen.go\n")
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
@@ -41,29 +87,25 @@
for _, r := range registries {
resp, err := http.Get(r.url)
if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
+ return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url)
- os.Exit(1)
+ return fmt.Errorf("got HTTP status code %v for %v\n", resp.StatusCode, r.url)
}
if err := r.parse(&bb, resp.Body); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
+ return err
}
fmt.Fprintf(&bb, "\n")
}
b, err := format.Source(bb.Bytes())
if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
+ return err
}
if err := ioutil.WriteFile("iana.go", b, 0644); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
+ return err
}
+ return nil
}
func parseICMPv4Parameters(w io.Writer, r io.Reader) error {