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 5//go:build ignore 6// +build ignore 7 8package main 9 10// This code is shared between the main code generator and the test code. 11 12import ( 13 "flag" 14 "log" 15 "strconv" 16 "strings" 17 18 "golang.org/x/text/internal/gen" 19 "golang.org/x/text/internal/ucd" 20) 21 22var ( 23 outputFile = flag.String("out", "tables.go", "output file") 24) 25 26var typeMap = map[string]elem{ 27 "A": tagAmbiguous, 28 "N": tagNeutral, 29 "Na": tagNarrow, 30 "W": tagWide, 31 "F": tagFullwidth, 32 "H": tagHalfwidth, 33} 34 35// getWidthData calls f for every entry for which it is defined. 36// 37// f may be called multiple times for the same rune. The last call to f is the 38// correct value. f is not called for all runes. The default tag type is 39// Neutral. 40func getWidthData(f func(r rune, tag elem, alt rune)) { 41 // Set the default values for Unified Ideographs. In line with Annex 11, 42 // we encode full ranges instead of the defined runes in Unified_Ideograph. 43 for _, b := range []struct{ lo, hi rune }{ 44 {0x4E00, 0x9FFF}, // the CJK Unified Ideographs block, 45 {0x3400, 0x4DBF}, // the CJK Unified Ideographs Externsion A block, 46 {0xF900, 0xFAFF}, // the CJK Compatibility Ideographs block, 47 {0x20000, 0x2FFFF}, // the Supplementary Ideographic Plane, 48 {0x30000, 0x3FFFF}, // the Tertiary Ideographic Plane, 49 } { 50 for r := b.lo; r <= b.hi; r++ { 51 f(r, tagWide, 0) 52 } 53 } 54 55 inverse := map[rune]rune{} 56 maps := map[string]bool{ 57 "<wide>": true, 58 "<narrow>": true, 59 } 60 61 // We cannot reuse package norm's decomposition, as we need an unexpanded 62 // decomposition. We make use of the opportunity to verify that the 63 // decomposition type is as expected. 64 ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) { 65 r := p.Rune(0) 66 s := strings.SplitN(p.String(ucd.DecompMapping), " ", 2) 67 if !maps[s[0]] { 68 return 69 } 70 x, err := strconv.ParseUint(s[1], 16, 32) 71 if err != nil { 72 log.Fatalf("Error parsing rune %q", s[1]) 73 } 74 if inverse[r] != 0 || inverse[rune(x)] != 0 { 75 log.Fatalf("Circular dependency in mapping between %U and %U", r, x) 76 } 77 inverse[r] = rune(x) 78 inverse[rune(x)] = r 79 }) 80 81 // <rune range>;<type> 82 ucd.Parse(gen.OpenUCDFile("EastAsianWidth.txt"), func(p *ucd.Parser) { 83 tag, ok := typeMap[p.String(1)] 84 if !ok { 85 log.Fatalf("Unknown width type %q", p.String(1)) 86 } 87 r := p.Rune(0) 88 alt, ok := inverse[r] 89 if tag == tagFullwidth || tag == tagHalfwidth && r != wonSign { 90 tag |= tagNeedsFold 91 if !ok { 92 log.Fatalf("Narrow or wide rune %U has no decomposition", r) 93 } 94 } 95 f(r, tag, alt) 96 }) 97} 98