mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
196 lines
4.2 KiB
Go
196 lines
4.2 KiB
Go
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build ignore
|
|
|
|
// This program generates internet protocol constants by reading IANA
|
|
// protocol registries.
|
|
//
|
|
// Usage:
|
|
// go run gentest.go > iana_test.go
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/xml"
|
|
"fmt"
|
|
"go/format"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var registries = []struct {
|
|
url string
|
|
parse func(io.Writer, io.Reader) error
|
|
}{
|
|
{
|
|
"http://www.iana.org/assignments/dscp-registry/dscp-registry.xml",
|
|
parseDSCPRegistry,
|
|
},
|
|
{
|
|
"http://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
|
|
parseTOSTCByte,
|
|
},
|
|
}
|
|
|
|
func main() {
|
|
var bb bytes.Buffer
|
|
fmt.Fprintf(&bb, "// go run gentest.go\n")
|
|
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
|
|
fmt.Fprintf(&bb, "package ipv4_test\n\n")
|
|
for _, r := range registries {
|
|
resp, err := http.Get(r.url)
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
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)
|
|
}
|
|
if err := r.parse(&bb, resp.Body); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Fprintf(&bb, "\n")
|
|
}
|
|
b, err := format.Source(bb.Bytes())
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
os.Stdout.Write(b)
|
|
}
|
|
|
|
func parseDSCPRegistry(w io.Writer, r io.Reader) error {
|
|
dec := xml.NewDecoder(r)
|
|
var dr dscpRegistry
|
|
if err := dec.Decode(&dr); err != nil {
|
|
return err
|
|
}
|
|
drs := dr.escape()
|
|
fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
|
|
fmt.Fprintf(w, "const (\n")
|
|
for _, dr := range drs {
|
|
fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value)
|
|
fmt.Fprintf(w, "// %s\n", dr.OrigName)
|
|
}
|
|
fmt.Fprintf(w, ")\n")
|
|
return nil
|
|
}
|
|
|
|
type dscpRegistry struct {
|
|
XMLName xml.Name `xml:"registry"`
|
|
Title string `xml:"title"`
|
|
Updated string `xml:"updated"`
|
|
Note string `xml:"note"`
|
|
RegTitle string `xml:"registry>title"`
|
|
PoolRecords []struct {
|
|
Name string `xml:"name"`
|
|
Space string `xml:"space"`
|
|
} `xml:"registry>record"`
|
|
Records []struct {
|
|
Name string `xml:"name"`
|
|
Space string `xml:"space"`
|
|
} `xml:"registry>registry>record"`
|
|
}
|
|
|
|
type canonDSCPRecord struct {
|
|
OrigName string
|
|
Name string
|
|
Value int
|
|
}
|
|
|
|
func (drr *dscpRegistry) escape() []canonDSCPRecord {
|
|
drs := make([]canonDSCPRecord, len(drr.Records))
|
|
sr := strings.NewReplacer(
|
|
"+", "",
|
|
"-", "",
|
|
"/", "",
|
|
".", "",
|
|
" ", "",
|
|
)
|
|
for i, dr := range drr.Records {
|
|
s := strings.TrimSpace(dr.Name)
|
|
drs[i].OrigName = s
|
|
drs[i].Name = sr.Replace(s)
|
|
n, err := strconv.ParseUint(dr.Space, 2, 8)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
drs[i].Value = int(n) << 2
|
|
}
|
|
return drs
|
|
}
|
|
|
|
func parseTOSTCByte(w io.Writer, r io.Reader) error {
|
|
dec := xml.NewDecoder(r)
|
|
var ttb tosTCByte
|
|
if err := dec.Decode(&ttb); err != nil {
|
|
return err
|
|
}
|
|
trs := ttb.escape()
|
|
fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated)
|
|
fmt.Fprintf(w, "const (\n")
|
|
for _, tr := range trs {
|
|
fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value)
|
|
fmt.Fprintf(w, "// %s\n", tr.OrigKeyword)
|
|
}
|
|
fmt.Fprintf(w, ")\n")
|
|
return nil
|
|
}
|
|
|
|
type tosTCByte struct {
|
|
XMLName xml.Name `xml:"registry"`
|
|
Title string `xml:"title"`
|
|
Updated string `xml:"updated"`
|
|
Note string `xml:"note"`
|
|
RegTitle string `xml:"registry>title"`
|
|
Records []struct {
|
|
Binary string `xml:"binary"`
|
|
Keyword string `xml:"keyword"`
|
|
} `xml:"registry>record"`
|
|
}
|
|
|
|
type canonTOSTCByteRecord struct {
|
|
OrigKeyword string
|
|
Keyword string
|
|
Value int
|
|
}
|
|
|
|
func (ttb *tosTCByte) escape() []canonTOSTCByteRecord {
|
|
trs := make([]canonTOSTCByteRecord, len(ttb.Records))
|
|
sr := strings.NewReplacer(
|
|
"Capable", "",
|
|
"(", "",
|
|
")", "",
|
|
"+", "",
|
|
"-", "",
|
|
"/", "",
|
|
".", "",
|
|
" ", "",
|
|
)
|
|
for i, tr := range ttb.Records {
|
|
s := strings.TrimSpace(tr.Keyword)
|
|
trs[i].OrigKeyword = s
|
|
ss := strings.Split(s, " ")
|
|
if len(ss) > 1 {
|
|
trs[i].Keyword = strings.Join(ss[1:], " ")
|
|
} else {
|
|
trs[i].Keyword = ss[0]
|
|
}
|
|
trs[i].Keyword = sr.Replace(trs[i].Keyword)
|
|
n, err := strconv.ParseUint(tr.Binary, 2, 8)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
trs[i].Value = int(n)
|
|
}
|
|
return trs
|
|
}
|