gen.go 3.6 KB

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