github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/ipv6/gen.go (about) 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 // The ipv6 pacakge still supports go1.2, and so we need to 56 // take care of additional platforms in go1.3 and above for 57 // working with go1.2. 58 switch { 59 case runtime.GOOS == "dragonfly" || runtime.GOOS == "solaris": 60 b = bytes.Replace(b, []byte("package ipv6\n"), []byte("// +build "+runtime.GOOS+"\n\npackage ipv6\n"), 1) 61 case runtime.GOOS == "linux" && (runtime.GOARCH == "arm64" || runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"): 62 b = bytes.Replace(b, []byte("package ipv6\n"), []byte("// +build "+runtime.GOOS+","+runtime.GOARCH+"\n\npackage ipv6\n"), 1) 63 } 64 b, err = format.Source(b) 65 if err != nil { 66 return err 67 } 68 zsys := "zsys_" + runtime.GOOS + ".go" 69 switch runtime.GOOS { 70 case "freebsd", "linux": 71 zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go" 72 } 73 if err := ioutil.WriteFile(zsys, b, 0644); err != nil { 74 return err 75 } 76 return nil 77 } 78 79 var registries = []struct { 80 url string 81 parse func(io.Writer, io.Reader) error 82 }{ 83 { 84 "http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml", 85 parseICMPv6Parameters, 86 }, 87 } 88 89 func geniana() error { 90 var bb bytes.Buffer 91 fmt.Fprintf(&bb, "// go generate gen.go\n") 92 fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n") 93 fmt.Fprintf(&bb, "package ipv6\n\n") 94 for _, r := range registries { 95 resp, err := http.Get(r.url) 96 if err != nil { 97 return err 98 } 99 defer resp.Body.Close() 100 if resp.StatusCode != http.StatusOK { 101 return fmt.Errorf("got HTTP status code %v for %v\n", resp.StatusCode, r.url) 102 } 103 if err := r.parse(&bb, resp.Body); err != nil { 104 return err 105 } 106 fmt.Fprintf(&bb, "\n") 107 } 108 b, err := format.Source(bb.Bytes()) 109 if err != nil { 110 return err 111 } 112 if err := ioutil.WriteFile("iana.go", b, 0644); err != nil { 113 return err 114 } 115 return nil 116 } 117 118 func parseICMPv6Parameters(w io.Writer, r io.Reader) error { 119 dec := xml.NewDecoder(r) 120 var icp icmpv6Parameters 121 if err := dec.Decode(&icp); err != nil { 122 return err 123 } 124 prs := icp.escape() 125 fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated) 126 fmt.Fprintf(w, "const (\n") 127 for _, pr := range prs { 128 if pr.Name == "" { 129 continue 130 } 131 fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Name, pr.Value) 132 fmt.Fprintf(w, "// %s\n", pr.OrigName) 133 } 134 fmt.Fprintf(w, ")\n\n") 135 fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated) 136 fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n") 137 for _, pr := range prs { 138 if pr.Name == "" { 139 continue 140 } 141 fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigName)) 142 } 143 fmt.Fprintf(w, "}\n") 144 return nil 145 } 146 147 type icmpv6Parameters struct { 148 XMLName xml.Name `xml:"registry"` 149 Title string `xml:"title"` 150 Updated string `xml:"updated"` 151 Registries []struct { 152 Title string `xml:"title"` 153 Records []struct { 154 Value string `xml:"value"` 155 Name string `xml:"name"` 156 } `xml:"record"` 157 } `xml:"registry"` 158 } 159 160 type canonICMPv6ParamRecord struct { 161 OrigName string 162 Name string 163 Value int 164 } 165 166 func (icp *icmpv6Parameters) escape() []canonICMPv6ParamRecord { 167 id := -1 168 for i, r := range icp.Registries { 169 if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") { 170 id = i 171 break 172 } 173 } 174 if id < 0 { 175 return nil 176 } 177 prs := make([]canonICMPv6ParamRecord, len(icp.Registries[id].Records)) 178 sr := strings.NewReplacer( 179 "Messages", "", 180 "Message", "", 181 "ICMP", "", 182 "+", "P", 183 "-", "", 184 "/", "", 185 ".", "", 186 " ", "", 187 ) 188 for i, pr := range icp.Registries[id].Records { 189 if strings.Contains(pr.Name, "Reserved") || 190 strings.Contains(pr.Name, "Unassigned") || 191 strings.Contains(pr.Name, "Deprecated") || 192 strings.Contains(pr.Name, "Experiment") || 193 strings.Contains(pr.Name, "experiment") { 194 continue 195 } 196 ss := strings.Split(pr.Name, "\n") 197 if len(ss) > 1 { 198 prs[i].Name = strings.Join(ss, " ") 199 } else { 200 prs[i].Name = ss[0] 201 } 202 s := strings.TrimSpace(prs[i].Name) 203 prs[i].OrigName = s 204 prs[i].Name = sr.Replace(s) 205 prs[i].Value, _ = strconv.Atoi(pr.Value) 206 } 207 return prs 208 }