OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [exp/] [norm/] [normregtest.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 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
package main
6
 
7
import (
8
        "bufio"
9
        "bytes"
10
        "exp/norm"
11
        "flag"
12
        "fmt"
13
        "io"
14
        "log"
15
        "net/http"
16
        "os"
17
        "path"
18
        "regexp"
19
        "runtime"
20
        "strconv"
21
        "strings"
22
        "time"
23
        "unicode/utf8"
24
)
25
 
26
func main() {
27
        flag.Parse()
28
        loadTestData()
29
        CharacterByCharacterTests()
30
        StandardTests()
31
        PerformanceTest()
32
        if errorCount == 0 {
33
                fmt.Println("PASS")
34
        }
35
}
36
 
37
const file = "NormalizationTest.txt"
38
 
39
var url = flag.String("url",
40
        "http://www.unicode.org/Public/6.0.0/ucd/"+file,
41
        "URL of Unicode database directory")
42
var localFiles = flag.Bool("local",
43
        false,
44
        "data files have been copied to the current directory; for debugging only")
45
 
46
var logger = log.New(os.Stderr, "", log.Lshortfile)
47
 
48
// This regression test runs the test set in NormalizationTest.txt
49
// (taken from http://www.unicode.org/Public/6.0.0/ucd/).
50
//
51
// NormalizationTest.txt has form:
52
// @Part0 # Specific cases
53
// #
54
// 1E0A;1E0A;0044 0307;1E0A;0044 0307; # (Ḋ; Ḋ; D◌̇; Ḋ; D◌̇; ) LATIN CAPITAL LETTER D WITH DOT ABOVE
55
// 1E0C;1E0C;0044 0323;1E0C;0044 0323; # (Ḍ; Ḍ; D◌̣; Ḍ; D◌̣; ) LATIN CAPITAL LETTER D WITH DOT BELOW
56
//
57
// Each test has 5 columns (c1, c2, c3, c4, c5), where
58
// (c1, c2, c3, c4, c5) == (c1, NFC(c1), NFD(c1), NFKC(c1), NFKD(c1))
59
//
60
// CONFORMANCE:
61
// 1. The following invariants must be true for all conformant implementations
62
//
63
//    NFC
64
//      c2 ==  NFC(c1) ==  NFC(c2) ==  NFC(c3)
65
//      c4 ==  NFC(c4) ==  NFC(c5)
66
//
67
//    NFD
68
//      c3 ==  NFD(c1) ==  NFD(c2) ==  NFD(c3)
69
//      c5 ==  NFD(c4) ==  NFD(c5)
70
//
71
//    NFKC
72
//      c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(c4) == NFKC(c5)
73
//
74
//    NFKD
75
//      c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(c4) == NFKD(c5)
76
//
77
// 2. For every code point X assigned in this version of Unicode that is not
78
//    specifically listed in Part 1, the following invariants must be true
79
//    for all conformant implementations:
80
//
81
//      X == NFC(X) == NFD(X) == NFKC(X) == NFKD(X)
82
//
83
 
84
// Column types.
85
const (
86
        cRaw = iota
87
        cNFC
88
        cNFD
89
        cNFKC
90
        cNFKD
91
        cMaxColumns
92
)
93
 
94
// Holds data from NormalizationTest.txt
95
var part []Part
96
 
97
type Part struct {
98
        name   string
99
        number int
100
        tests  []Test
101
}
102
 
103
type Test struct {
104
        name   string
105
        partnr int
106
        number int
107
        r      rune                // used for character by character test
108
        cols   [cMaxColumns]string // Each has 5 entries, see below.
109
}
110
 
111
func (t Test) Name() string {
112
        if t.number < 0 {
113
                return part[t.partnr].name
114
        }
115
        return fmt.Sprintf("%s:%d", part[t.partnr].name, t.number)
116
}
117
 
118
var partRe = regexp.MustCompile(`@Part(\d) # (.*)\n$`)
119
var testRe = regexp.MustCompile(`^` + strings.Repeat(`([\dA-F ]+);`, 5) + ` # (.*)\n?$`)
120
 
121
var counter int
122
 
123
// Load the data form NormalizationTest.txt
124
func loadTestData() {
125
        if *localFiles {
126
                pwd, _ := os.Getwd()
127
                *url = "file://" + path.Join(pwd, file)
128
        }
129
        t := &http.Transport{}
130
        t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
131
        c := &http.Client{Transport: t}
132
        resp, err := c.Get(*url)
133
        if err != nil {
134
                logger.Fatal(err)
135
        }
136
        if resp.StatusCode != 200 {
137
                logger.Fatal("bad GET status for "+file, resp.Status)
138
        }
139
        f := resp.Body
140
        defer f.Close()
141
        input := bufio.NewReader(f)
142
        for {
143
                line, err := input.ReadString('\n')
144
                if err != nil {
145
                        if err == io.EOF {
146
                                break
147
                        }
148
                        logger.Fatal(err)
149
                }
150
                if len(line) == 0 || line[0] == '#' {
151
                        continue
152
                }
153
                m := partRe.FindStringSubmatch(line)
154
                if m != nil {
155
                        if len(m) < 3 {
156
                                logger.Fatal("Failed to parse Part: ", line)
157
                        }
158
                        i, err := strconv.Atoi(m[1])
159
                        if err != nil {
160
                                logger.Fatal(err)
161
                        }
162
                        name := m[2]
163
                        part = append(part, Part{name: name[:len(name)-1], number: i})
164
                        continue
165
                }
166
                m = testRe.FindStringSubmatch(line)
167
                if m == nil || len(m) < 7 {
168
                        logger.Fatalf(`Failed to parse: "%s" result: %#v`, line, m)
169
                }
170
                test := Test{name: m[6], partnr: len(part) - 1, number: counter}
171
                counter++
172
                for j := 1; j < len(m)-1; j++ {
173
                        for _, split := range strings.Split(m[j], " ") {
174
                                r, err := strconv.ParseUint(split, 16, 64)
175
                                if err != nil {
176
                                        logger.Fatal(err)
177
                                }
178
                                if test.r == 0 {
179
                                        // save for CharacterByCharacterTests
180
                                        test.r = rune(r)
181
                                }
182
                                var buf [utf8.UTFMax]byte
183
                                sz := utf8.EncodeRune(buf[:], rune(r))
184
                                test.cols[j-1] += string(buf[:sz])
185
                        }
186
                }
187
                part := &part[len(part)-1]
188
                part.tests = append(part.tests, test)
189
        }
190
}
191
 
192
var fstr = []string{"NFC", "NFD", "NFKC", "NFKD"}
193
 
194
var errorCount int
195
 
196
func cmpResult(t *Test, name string, f norm.Form, gold, test, result string) {
197
        if gold != result {
198
                errorCount++
199
                if errorCount > 20 {
200
                        return
201
                }
202
                st, sr, sg := []rune(test), []rune(result), []rune(gold)
203
                logger.Printf("%s:%s: %s(%X)=%X; want:%X: %s",
204
                        t.Name(), name, fstr[f], st, sr, sg, t.name)
205
        }
206
}
207
 
208
func cmpIsNormal(t *Test, name string, f norm.Form, test string, result, want bool) {
209
        if result != want {
210
                errorCount++
211
                if errorCount > 20 {
212
                        return
213
                }
214
                logger.Printf("%s:%s: %s(%X)=%v; want: %v", t.Name(), name, fstr[f], []rune(test), result, want)
215
        }
216
}
217
 
218
func doTest(t *Test, f norm.Form, gold, test string) {
219
        result := f.Bytes([]byte(test))
220
        cmpResult(t, "Bytes", f, gold, test, string(result))
221
        for i := range test {
222
                out := f.Append(f.Bytes([]byte(test[:i])), []byte(test[i:])...)
223
                cmpResult(t, fmt.Sprintf(":Append:%d", i), f, gold, test, string(out))
224
        }
225
        cmpIsNormal(t, "IsNormal", f, test, f.IsNormal([]byte(test)), test == gold)
226
}
227
 
228
func doConformanceTests(t *Test, partn int) {
229
        for i := 0; i <= 2; i++ {
230
                doTest(t, norm.NFC, t.cols[1], t.cols[i])
231
                doTest(t, norm.NFD, t.cols[2], t.cols[i])
232
                doTest(t, norm.NFKC, t.cols[3], t.cols[i])
233
                doTest(t, norm.NFKD, t.cols[4], t.cols[i])
234
        }
235
        for i := 3; i <= 4; i++ {
236
                doTest(t, norm.NFC, t.cols[3], t.cols[i])
237
                doTest(t, norm.NFD, t.cols[4], t.cols[i])
238
                doTest(t, norm.NFKC, t.cols[3], t.cols[i])
239
                doTest(t, norm.NFKD, t.cols[4], t.cols[i])
240
        }
241
}
242
 
243
func CharacterByCharacterTests() {
244
        tests := part[1].tests
245
        var last rune = 0
246
        for i := 0; i <= len(tests); i++ { // last one is special case
247
                var r rune
248
                if i == len(tests) {
249
                        r = 0x2FA1E // Don't have to go to 0x10FFFF
250
                } else {
251
                        r = tests[i].r
252
                }
253
                for last++; last < r; last++ {
254
                        // Check all characters that were not explicitly listed in the test.
255
                        t := &Test{partnr: 1, number: -1}
256
                        char := string(last)
257
                        doTest(t, norm.NFC, char, char)
258
                        doTest(t, norm.NFD, char, char)
259
                        doTest(t, norm.NFKC, char, char)
260
                        doTest(t, norm.NFKD, char, char)
261
                }
262
                if i < len(tests) {
263
                        doConformanceTests(&tests[i], 1)
264
                }
265
        }
266
}
267
 
268
func StandardTests() {
269
        for _, j := range []int{0, 2, 3} {
270
                for _, test := range part[j].tests {
271
                        doConformanceTests(&test, j)
272
                }
273
        }
274
}
275
 
276
// PerformanceTest verifies that normalization is O(n). If any of the
277
// code does not properly check for maxCombiningChars, normalization
278
// may exhibit O(n**2) behavior.
279
func PerformanceTest() {
280
        runtime.GOMAXPROCS(2)
281
        success := make(chan bool, 1)
282
        go func() {
283
                buf := bytes.Repeat([]byte("\u035D"), 1024*1024)
284
                buf = append(buf, "\u035B"...)
285
                norm.NFC.Append(nil, buf...)
286
                success <- true
287
        }()
288
        timeout := time.After(1 * time.Second)
289
        select {
290
        case <-success:
291
                // test completed before the timeout
292
        case <-timeout:
293
                errorCount++
294
                logger.Printf(`unexpectedly long time to complete PerformanceTest`)
295
        }
296
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.