1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 //go:generate go run gen.go
9 // This program generates system adaptation constants and types,
10 // internet protocol constants and tables by reading template files
11 // and IANA protocol registries.
30 if err := genzsys(); err != nil {
31 fmt.Fprintln(os.Stderr, err)
34 if err := geniana(); err != nil {
35 fmt.Fprintln(os.Stderr, err)
40 func genzsys() error {
41 defs := "defs_" + runtime.GOOS + ".go"
42 f, err := os.Open(defs)
44 if os.IsNotExist(err) {
50 cmd := exec.Command("go", "tool", "cgo", "-godefs", defs)
51 b, err := cmd.Output()
55 b, err = format.Source(b)
59 zsys := "zsys_" + runtime.GOOS + ".go"
61 case "freebsd", "linux":
62 zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go"
64 if err := ioutil.WriteFile(zsys, b, 0644); err != nil {
70 var registries = []struct {
72 parse func(io.Writer, io.Reader) error
75 "http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml",
76 parseICMPv6Parameters,
80 func geniana() error {
82 fmt.Fprintf(&bb, "// go generate gen.go\n")
83 fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
84 fmt.Fprintf(&bb, "package ipv6\n\n")
85 for _, r := range registries {
86 resp, err := http.Get(r.url)
90 defer resp.Body.Close()
91 if resp.StatusCode != http.StatusOK {
92 return fmt.Errorf("got HTTP status code %v for %v\n", resp.StatusCode, r.url)
94 if err := r.parse(&bb, resp.Body); err != nil {
97 fmt.Fprintf(&bb, "\n")
99 b, err := format.Source(bb.Bytes())
103 if err := ioutil.WriteFile("iana.go", b, 0644); err != nil {
109 func parseICMPv6Parameters(w io.Writer, r io.Reader) error {
110 dec := xml.NewDecoder(r)
111 var icp icmpv6Parameters
112 if err := dec.Decode(&icp); err != nil {
116 fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
117 fmt.Fprintf(w, "const (\n")
118 for _, pr := range prs {
122 fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Name, pr.Value)
123 fmt.Fprintf(w, "// %s\n", pr.OrigName)
125 fmt.Fprintf(w, ")\n\n")
126 fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
127 fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n")
128 for _, pr := range prs {
132 fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigName))
134 fmt.Fprintf(w, "}\n")
138 type icmpv6Parameters struct {
139 XMLName xml.Name `xml:"registry"`
140 Title string `xml:"title"`
141 Updated string `xml:"updated"`
142 Registries []struct {
143 Title string `xml:"title"`
145 Value string `xml:"value"`
146 Name string `xml:"name"`
151 type canonICMPv6ParamRecord struct {
157 func (icp *icmpv6Parameters) escape() []canonICMPv6ParamRecord {
159 for i, r := range icp.Registries {
160 if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") {
168 prs := make([]canonICMPv6ParamRecord, len(icp.Registries[id].Records))
169 sr := strings.NewReplacer(
179 for i, pr := range icp.Registries[id].Records {
180 if strings.Contains(pr.Name, "Reserved") ||
181 strings.Contains(pr.Name, "Unassigned") ||
182 strings.Contains(pr.Name, "Deprecated") ||
183 strings.Contains(pr.Name, "Experiment") ||
184 strings.Contains(pr.Name, "experiment") {
187 ss := strings.Split(pr.Name, "\n")
189 prs[i].Name = strings.Join(ss, " ")
193 s := strings.TrimSpace(prs[i].Name)
195 prs[i].Name = sr.Replace(s)
196 prs[i].Value, _ = strconv.Atoi(pr.Value)