OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv6 / gen.go
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.
4
5 // +build ignore
6
7 //go:generate go run gen.go
8
9 // This program generates system adaptation constants and types,
10 // internet protocol constants and tables by reading template files
11 // and IANA protocol registries.
12 package main
13
14 import (
15         "bytes"
16         "encoding/xml"
17         "fmt"
18         "go/format"
19         "io"
20         "io/ioutil"
21         "net/http"
22         "os"
23         "os/exec"
24         "runtime"
25         "strconv"
26         "strings"
27 )
28
29 func main() {
30         if err := genzsys(); err != nil {
31                 fmt.Fprintln(os.Stderr, err)
32                 os.Exit(1)
33         }
34         if err := geniana(); err != nil {
35                 fmt.Fprintln(os.Stderr, err)
36                 os.Exit(1)
37         }
38 }
39
40 func genzsys() error {
41         defs := "defs_" + runtime.GOOS + ".go"
42         f, err := os.Open(defs)
43         if err != nil {
44                 if os.IsNotExist(err) {
45                         return nil
46                 }
47                 return err
48         }
49         f.Close()
50         cmd := exec.Command("go", "tool", "cgo", "-godefs", defs)
51         b, err := cmd.Output()
52         if err != nil {
53                 return err
54         }
55         b, err = format.Source(b)
56         if err != nil {
57                 return err
58         }
59         zsys := "zsys_" + runtime.GOOS + ".go"
60         switch runtime.GOOS {
61         case "freebsd", "linux":
62                 zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go"
63         }
64         if err := ioutil.WriteFile(zsys, b, 0644); err != nil {
65                 return err
66         }
67         return nil
68 }
69
70 var registries = []struct {
71         url   string
72         parse func(io.Writer, io.Reader) error
73 }{
74         {
75                 "http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml",
76                 parseICMPv6Parameters,
77         },
78 }
79
80 func geniana() error {
81         var bb bytes.Buffer
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)
87                 if err != nil {
88                         return err
89                 }
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)
93                 }
94                 if err := r.parse(&bb, resp.Body); err != nil {
95                         return err
96                 }
97                 fmt.Fprintf(&bb, "\n")
98         }
99         b, err := format.Source(bb.Bytes())
100         if err != nil {
101                 return err
102         }
103         if err := ioutil.WriteFile("iana.go", b, 0644); err != nil {
104                 return err
105         }
106         return nil
107 }
108
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 {
113                 return err
114         }
115         prs := icp.escape()
116         fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
117         fmt.Fprintf(w, "const (\n")
118         for _, pr := range prs {
119                 if pr.Name == "" {
120                         continue
121                 }
122                 fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Name, pr.Value)
123                 fmt.Fprintf(w, "// %s\n", pr.OrigName)
124         }
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 {
129                 if pr.Name == "" {
130                         continue
131                 }
132                 fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigName))
133         }
134         fmt.Fprintf(w, "}\n")
135         return nil
136 }
137
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"`
144                 Records []struct {
145                         Value string `xml:"value"`
146                         Name  string `xml:"name"`
147                 } `xml:"record"`
148         } `xml:"registry"`
149 }
150
151 type canonICMPv6ParamRecord struct {
152         OrigName string
153         Name     string
154         Value    int
155 }
156
157 func (icp *icmpv6Parameters) escape() []canonICMPv6ParamRecord {
158         id := -1
159         for i, r := range icp.Registries {
160                 if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") {
161                         id = i
162                         break
163                 }
164         }
165         if id < 0 {
166                 return nil
167         }
168         prs := make([]canonICMPv6ParamRecord, len(icp.Registries[id].Records))
169         sr := strings.NewReplacer(
170                 "Messages", "",
171                 "Message", "",
172                 "ICMP", "",
173                 "+", "P",
174                 "-", "",
175                 "/", "",
176                 ".", "",
177                 " ", "",
178         )
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") {
185                         continue
186                 }
187                 ss := strings.Split(pr.Name, "\n")
188                 if len(ss) > 1 {
189                         prs[i].Name = strings.Join(ss, " ")
190                 } else {
191                         prs[i].Name = ss[0]
192                 }
193                 s := strings.TrimSpace(prs[i].Name)
194                 prs[i].OrigName = s
195                 prs[i].Name = sr.Replace(s)
196                 prs[i].Value, _ = strconv.Atoi(pr.Value)
197         }
198         return prs
199 }