gen.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright 2015 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. // +build ignore
  5. package main
  6. import (
  7. "bytes"
  8. "encoding/xml"
  9. "fmt"
  10. "io"
  11. "log"
  12. "strings"
  13. "golang.org/x/text/internal/gen"
  14. )
  15. type registry struct {
  16. XMLName xml.Name `xml:"registry"`
  17. Updated string `xml:"updated"`
  18. Registry []struct {
  19. ID string `xml:"id,attr"`
  20. Record []struct {
  21. Name string `xml:"name"`
  22. Xref []struct {
  23. Type string `xml:"type,attr"`
  24. Data string `xml:"data,attr"`
  25. } `xml:"xref"`
  26. Desc struct {
  27. Data string `xml:",innerxml"`
  28. // Any []struct {
  29. // Data string `xml:",chardata"`
  30. // } `xml:",any"`
  31. // Data string `xml:",chardata"`
  32. } `xml:"description,"`
  33. MIB string `xml:"value"`
  34. Alias []string `xml:"alias"`
  35. MIME string `xml:"preferred_alias"`
  36. } `xml:"record"`
  37. } `xml:"registry"`
  38. }
  39. func main() {
  40. r := gen.OpenIANAFile("assignments/character-sets/character-sets.xml")
  41. reg := &registry{}
  42. if err := xml.NewDecoder(r).Decode(&reg); err != nil && err != io.EOF {
  43. log.Fatalf("Error decoding charset registry: %v", err)
  44. }
  45. if len(reg.Registry) == 0 || reg.Registry[0].ID != "character-sets-1" {
  46. log.Fatalf("Unexpected ID %s", reg.Registry[0].ID)
  47. }
  48. w := &bytes.Buffer{}
  49. fmt.Fprintf(w, "const (\n")
  50. for _, rec := range reg.Registry[0].Record {
  51. constName := ""
  52. for _, a := range rec.Alias {
  53. if strings.HasPrefix(a, "cs") && strings.IndexByte(a, '-') == -1 {
  54. // Some of the constant definitions have comments in them. Strip those.
  55. constName = strings.Title(strings.SplitN(a[2:], "\n", 2)[0])
  56. }
  57. }
  58. if constName == "" {
  59. switch rec.MIB {
  60. case "2085":
  61. constName = "HZGB2312" // Not listed as alias for some reason.
  62. default:
  63. log.Fatalf("No cs alias defined for %s.", rec.MIB)
  64. }
  65. }
  66. if rec.MIME != "" {
  67. rec.MIME = fmt.Sprintf(" (MIME: %s)", rec.MIME)
  68. }
  69. fmt.Fprintf(w, "// %s is the MIB identifier with IANA name %s%s.\n//\n", constName, rec.Name, rec.MIME)
  70. if len(rec.Desc.Data) > 0 {
  71. fmt.Fprint(w, "// ")
  72. d := xml.NewDecoder(strings.NewReader(rec.Desc.Data))
  73. inElem := true
  74. attr := ""
  75. for {
  76. t, err := d.Token()
  77. if err != nil {
  78. if err != io.EOF {
  79. log.Fatal(err)
  80. }
  81. break
  82. }
  83. switch x := t.(type) {
  84. case xml.CharData:
  85. attr = "" // Don't need attribute info.
  86. a := bytes.Split([]byte(x), []byte("\n"))
  87. for i, b := range a {
  88. if b = bytes.TrimSpace(b); len(b) != 0 {
  89. if !inElem && i > 0 {
  90. fmt.Fprint(w, "\n// ")
  91. }
  92. inElem = false
  93. fmt.Fprintf(w, "%s ", string(b))
  94. }
  95. }
  96. case xml.StartElement:
  97. if x.Name.Local == "xref" {
  98. inElem = true
  99. use := false
  100. for _, a := range x.Attr {
  101. if a.Name.Local == "type" {
  102. use = use || a.Value != "person"
  103. }
  104. if a.Name.Local == "data" && use {
  105. attr = a.Value + " "
  106. }
  107. }
  108. }
  109. case xml.EndElement:
  110. inElem = false
  111. fmt.Fprint(w, attr)
  112. }
  113. }
  114. fmt.Fprint(w, "\n")
  115. }
  116. for _, x := range rec.Xref {
  117. switch x.Type {
  118. case "rfc":
  119. fmt.Fprintf(w, "// Reference: %s\n", strings.ToUpper(x.Data))
  120. case "uri":
  121. fmt.Fprintf(w, "// Reference: %s\n", x.Data)
  122. }
  123. }
  124. fmt.Fprintf(w, "%s MIB = %s\n", constName, rec.MIB)
  125. fmt.Fprintln(w)
  126. }
  127. fmt.Fprintln(w, ")")
  128. gen.WriteGoFile("mib.go", "identifier", w.Bytes())
  129. }