github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/net/ipv4/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 //go:build ignore 6 // +build ignore 7 8 //go:generate go run gen.go 9 10 // This program generates system adaptation constants and types, 11 // internet protocol constants and tables by reading template files 12 // and IANA protocol registries. 13 package main 14 15 import ( 16 "bytes" 17 "encoding/xml" 18 "fmt" 19 http "github.com/hxx258456/ccgo/gmhttp" 20 "go/format" 21 "io" 22 "io/ioutil" 23 "os" 24 "os/exec" 25 "runtime" 26 "strconv" 27 "strings" 28 ) 29 30 func main() { 31 if err := genzsys(); err != nil { 32 fmt.Fprintln(os.Stderr, err) 33 os.Exit(1) 34 } 35 if err := geniana(); err != nil { 36 fmt.Fprintln(os.Stderr, err) 37 os.Exit(1) 38 } 39 } 40 41 func genzsys() error { 42 defs := "defs_" + runtime.GOOS + ".go" 43 f, err := os.Open(defs) 44 if err != nil { 45 if os.IsNotExist(err) { 46 return nil 47 } 48 return err 49 } 50 f.Close() 51 cmd := exec.Command("go", "tool", "cgo", "-godefs", defs) 52 b, err := cmd.Output() 53 if err != nil { 54 return err 55 } 56 b, err = format.Source(b) 57 if err != nil { 58 return err 59 } 60 zsys := "zsys_" + runtime.GOOS + ".go" 61 switch runtime.GOOS { 62 case "freebsd", "linux": 63 zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go" 64 } 65 if err := ioutil.WriteFile(zsys, b, 0644); err != nil { 66 return err 67 } 68 return nil 69 } 70 71 var registries = []struct { 72 url string 73 parse func(io.Writer, io.Reader) error 74 }{ 75 { 76 "https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml", 77 parseICMPv4Parameters, 78 }, 79 } 80 81 func geniana() error { 82 var bb bytes.Buffer 83 fmt.Fprintf(&bb, "// go generate gen.go\n") 84 fmt.Fprintf(&bb, "// Code generated by the command above; DO NOT EDIT.\n\n") 85 fmt.Fprintf(&bb, "package ipv4\n\n") 86 for _, r := range registries { 87 resp, err := http.Get(r.url) 88 if err != nil { 89 return err 90 } 91 defer resp.Body.Close() 92 if resp.StatusCode != http.StatusOK { 93 return fmt.Errorf("got HTTP status code %v for %v\n", resp.StatusCode, r.url) 94 } 95 if err := r.parse(&bb, resp.Body); err != nil { 96 return err 97 } 98 fmt.Fprintf(&bb, "\n") 99 } 100 b, err := format.Source(bb.Bytes()) 101 if err != nil { 102 return err 103 } 104 if err := ioutil.WriteFile("iana.go", b, 0644); err != nil { 105 return err 106 } 107 return nil 108 } 109 110 func parseICMPv4Parameters(w io.Writer, r io.Reader) error { 111 dec := xml.NewDecoder(r) 112 var icp icmpv4Parameters 113 if err := dec.Decode(&icp); err != nil { 114 return err 115 } 116 prs := icp.escape() 117 fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated) 118 fmt.Fprintf(w, "const (\n") 119 for _, pr := range prs { 120 if pr.Descr == "" { 121 continue 122 } 123 fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Descr, pr.Value) 124 fmt.Fprintf(w, "// %s\n", pr.OrigDescr) 125 } 126 fmt.Fprintf(w, ")\n\n") 127 fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated) 128 fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n") 129 for _, pr := range prs { 130 if pr.Descr == "" { 131 continue 132 } 133 fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigDescr)) 134 } 135 fmt.Fprintf(w, "}\n") 136 return nil 137 } 138 139 type icmpv4Parameters struct { 140 XMLName xml.Name `xml:"registry"` 141 Title string `xml:"title"` 142 Updated string `xml:"updated"` 143 Registries []struct { 144 Title string `xml:"title"` 145 Records []struct { 146 Value string `xml:"value"` 147 Descr string `xml:"description"` 148 } `xml:"record"` 149 } `xml:"registry"` 150 } 151 152 type canonICMPv4ParamRecord struct { 153 OrigDescr string 154 Descr string 155 Value int 156 } 157 158 func (icp *icmpv4Parameters) escape() []canonICMPv4ParamRecord { 159 id := -1 160 for i, r := range icp.Registries { 161 if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") { 162 id = i 163 break 164 } 165 } 166 if id < 0 { 167 return nil 168 } 169 prs := make([]canonICMPv4ParamRecord, len(icp.Registries[id].Records)) 170 sr := strings.NewReplacer( 171 "Messages", "", 172 "Message", "", 173 "ICMP", "", 174 "+", "P", 175 "-", "", 176 "/", "", 177 ".", "", 178 " ", "", 179 ) 180 for i, pr := range icp.Registries[id].Records { 181 if strings.Contains(pr.Descr, "Reserved") || 182 strings.Contains(pr.Descr, "Unassigned") || 183 strings.Contains(pr.Descr, "Deprecated") || 184 strings.Contains(pr.Descr, "Experiment") || 185 strings.Contains(pr.Descr, "experiment") { 186 continue 187 } 188 ss := strings.Split(pr.Descr, "\n") 189 if len(ss) > 1 { 190 prs[i].Descr = strings.Join(ss, " ") 191 } else { 192 prs[i].Descr = ss[0] 193 } 194 s := strings.TrimSpace(prs[i].Descr) 195 prs[i].OrigDescr = s 196 prs[i].Descr = sr.Replace(s) 197 prs[i].Value, _ = strconv.Atoi(pr.Value) 198 } 199 return prs 200 }