Fix bootstrap/PR63632
[official-gcc.git] / libgo / go / strconv / makeisprint.go
blob216159cc020fdc5e27c5e3aa7c106dced48c0c1d
1 // Copyright 2012 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.
5 // +build ignore
7 // makeisprint generates the tables for strconv's compact isPrint.
8 package main
10 import (
11 "fmt"
12 "os"
13 "unicode"
16 var (
17 range16 []uint16
18 except16 []uint16
19 range32 []uint32
20 except32 []uint32
23 // bsearch16 returns the smallest i such that a[i] >= x.
24 // If there is no such i, bsearch16 returns len(a).
25 func bsearch16(a []uint16, x uint16) int {
26 i, j := 0, len(a)
27 for i < j {
28 h := i + (j-i)/2
29 if a[h] < x {
30 i = h + 1
31 } else {
32 j = h
35 return i
38 // bsearch32 returns the smallest i such that a[i] >= x.
39 // If there is no such i, bsearch32 returns len(a).
40 func bsearch32(a []uint32, x uint32) int {
41 i, j := 0, len(a)
42 for i < j {
43 h := i + (j-i)/2
44 if a[h] < x {
45 i = h + 1
46 } else {
47 j = h
50 return i
53 func isPrint(r rune) bool {
54 // Same algorithm, either on uint16 or uint32 value.
55 // First, find first i such that rang[i] >= x.
56 // This is the index of either the start or end of a pair that might span x.
57 // The start is even (rang[i&^1]) and the end is odd (rang[i|1]).
58 // If we find x in a range, make sure x is not in exception list.
60 if 0 <= r && r < 1<<16 {
61 rr, rang, except := uint16(r), range16, except16
62 i := bsearch16(rang, rr)
63 if i >= len(rang) || rr < rang[i&^1] || rang[i|1] < rr {
64 return false
66 j := bsearch16(except, rr)
67 return j >= len(except) || except[j] != rr
70 rr, rang, except := uint32(r), range32, except32
71 i := bsearch32(rang, rr)
72 if i >= len(rang) || rr < rang[i&^1] || rang[i|1] < rr {
73 return false
75 j := bsearch32(except, rr)
76 return j >= len(except) || except[j] != rr
79 func scan(min, max rune) (rang, except []uint32) {
80 lo := rune(-1)
81 for i := min; ; i++ {
82 if (i > max || !unicode.IsPrint(i)) && lo >= 0 {
83 // End range, but avoid flip flop.
84 if i+1 <= max && unicode.IsPrint(i+1) {
85 except = append(except, uint32(i))
86 continue
88 rang = append(rang, uint32(lo), uint32(i-1))
89 lo = -1
91 if i > max {
92 break
94 if lo < 0 && unicode.IsPrint(i) {
95 lo = i
98 return
101 func to16(x []uint32) []uint16 {
102 var y []uint16
103 for _, v := range x {
104 if uint32(uint16(v)) != v {
105 panic("bad 32->16 conversion")
107 y = append(y, uint16(v))
109 return y
112 func main() {
113 rang, except := scan(0, 0xFFFF)
114 range16 = to16(rang)
115 except16 = to16(except)
116 range32, except32 = scan(0x10000, unicode.MaxRune)
118 for i := rune(0); i <= unicode.MaxRune; i++ {
119 if isPrint(i) != unicode.IsPrint(i) {
120 fmt.Fprintf(os.Stderr, "%U: isPrint=%v, want %v\n", i, isPrint(i), unicode.IsPrint(i))
121 return
125 fmt.Printf(`// Copyright 2013 The Go Authors. All rights reserved.
126 // Use of this source code is governed by a BSD-style
127 // license that can be found in the LICENSE file.` + "\n\n")
128 fmt.Printf("// DO NOT EDIT. GENERATED BY\n")
129 fmt.Printf("// go run makeisprint.go >x && mv x isprint.go\n\n")
130 fmt.Printf("package strconv\n\n")
132 fmt.Printf("// (%d+%d+%d)*2 + (%d)*4 = %d bytes\n\n",
133 len(range16), len(except16), len(except32),
134 len(range32),
135 (len(range16)+len(except16)+len(except32))*2+
136 (len(range32))*4)
138 fmt.Printf("var isPrint16 = []uint16{\n")
139 for i := 0; i < len(range16); i += 2 {
140 fmt.Printf("\t%#04x, %#04x,\n", range16[i], range16[i+1])
142 fmt.Printf("}\n\n")
144 fmt.Printf("var isNotPrint16 = []uint16{\n")
145 for _, r := range except16 {
146 fmt.Printf("\t%#04x,\n", r)
148 fmt.Printf("}\n\n")
150 fmt.Printf("var isPrint32 = []uint32{\n")
151 for i := 0; i < len(range32); i += 2 {
152 fmt.Printf("\t%#06x, %#06x,\n", range32[i], range32[i+1])
154 fmt.Printf("}\n\n")
156 fmt.Printf("var isNotPrint32 = []uint16{ // add 0x10000 to each entry\n")
157 for _, r := range except32 {
158 if r >= 0x20000 {
159 fmt.Fprintf(os.Stderr, "%U too big for isNotPrint32\n", r)
160 return
162 fmt.Printf("\t%#04x,\n", r-0x10000)
164 fmt.Printf("}\n")