// Copyright 2016 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. //go:build ignore // +build ignore package main import ( "bytes" "log" "sort" "strings" "golang.org/x/text/internal/gen" "golang.org/x/text/internal/gen/bitfield" "golang.org/x/text/internal/ucd" ) var ( // computed by computeDirectOffsets directOffsets = map[string]int{} directData bytes.Buffer // computed by computeEntries entries []entry singleData bytes.Buffer index []uint16 ) type entry struct { start rune `bitfield:"21,startRune"` numRunes int `bitfield:"16"` end rune index int `bitfield:"16"` base int `bitfield:"6"` direct bool `bitfield:""` name string } func main() { gen.Init() w := gen.NewCodeWriter() defer w.WriteVersionedGoFile("tables.go", "runenames") gen.WriteUnicodeVersion(w) computeDirectOffsets() computeEntries() if err := bitfield.Gen(w, entry{}, nil); err != nil { log.Fatal(err) } type entry uint64 // trick the generation code to use the entry type packed := []entry{} for _, e := range entries { e.numRunes = int(e.end - e.start + 1) v, err := bitfield.Pack(e, nil) if err != nil { log.Fatal(err) } packed = append(packed, entry(v)) } index = append(index, uint16(singleData.Len())) w.WriteVar("entries", packed) w.WriteVar("index", index) w.WriteConst("directData", directData.String()) w.WriteConst("singleData", singleData.String()) } func computeDirectOffsets() { counts := map[string]int{} p := ucd.New(gen.OpenUCDFile("UnicodeData.txt"), ucd.KeepRanges) for p.Next() { start, end := p.Range(0) counts[getName(p)] += int(end-start) + 1 } direct := []string{} for k, v := range counts { if v > 1 { direct = append(direct, k) } } sort.Strings(direct) for _, s := range direct { directOffsets[s] = directData.Len() directData.WriteString(s) } } func computeEntries() { p := ucd.New(gen.OpenUCDFile("UnicodeData.txt"), ucd.KeepRanges) for p.Next() { start, end := p.Range(0) last := entry{} if len(entries) > 0 { last = entries[len(entries)-1] } name := getName(p) if index, ok := directOffsets[name]; ok { if last.name == name && last.end+1 == start { entries[len(entries)-1].end = end continue } entries = append(entries, entry{ start: start, end: end, index: index, base: len(name), direct: true, name: name, }) continue } if start != end { log.Fatalf("Expected start == end, found %x != %x", start, end) } offset := singleData.Len() base := offset >> 16 index = append(index, uint16(offset)) singleData.WriteString(name) if last.base == base && last.end+1 == start { entries[len(entries)-1].end = start continue } entries = append(entries, entry{ start: start, end: end, index: len(index) - 1, base: base, name: name, }) } } func getName(p *ucd.Parser) string { s := p.String(ucd.Name) if s == "" { return "" } if s[0] == '<' { const first = ", First>" if i := strings.Index(s, first); i >= 0 { s = s[:i] + ">" } } return s }