From 6918357031df3a7e3373fcb0b28657ead4afc1bb Mon Sep 17 00:00:00 2001 From: Marcel van Lohuizen Date: Mon, 20 Aug 2012 10:55:40 +0200 Subject: [PATCH] exp/locale/collate: Added test flag to maketables tool for comparing newly against previously generated tables. R=r CC=golang-dev https://golang.org/cl/6441098 --- src/pkg/exp/locale/collate/maketables.go | 89 ++++++++++++++++++++---- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/src/pkg/exp/locale/collate/maketables.go b/src/pkg/exp/locale/collate/maketables.go index a76e2d0f93..a42ce9b67b 100644 --- a/src/pkg/exp/locale/collate/maketables.go +++ b/src/pkg/exp/locale/collate/maketables.go @@ -11,6 +11,7 @@ package main import ( "bufio" + "bytes" "exp/locale/collate" "exp/locale/collate/build" "flag" @@ -21,6 +22,7 @@ import ( "os" "path" "regexp" + "sort" "strconv" "strings" "unicode" @@ -29,6 +31,9 @@ import ( var ducet = flag.String("ducet", "http://unicode.org/Public/UCA/"+unicode.Version+"/allkeys.txt", "URL of the Default Unicode Collation Element Table (DUCET).") +var test = flag.Bool("test", + false, + "test existing tables; can be used to compare web data with package data") var localFiles = flag.Bool("local", false, "data files have been copied to the current directory; for debugging only") @@ -124,6 +129,9 @@ func parseUCA(builder *build.Builder) { if len(part[1]) < n+3 || part[1][n+1] != '#' { log.Fatalf("%d: expected comment; found %s", i, part[1][n:]) } + if *test { + testInput.add(string(lhs)) + } failOnError(builder.Add(lhs, rhs, vars)) } } @@ -137,6 +145,59 @@ func convHex(line int, s string) int { return int(r) } +var testInput = stringSet{} + +type stringSet struct { + set []string +} + +func (ss *stringSet) add(s string) { + ss.set = append(ss.set, s) +} + +func (ss *stringSet) values() []string { + ss.compact() + return ss.set +} + +func (ss *stringSet) compact() { + a := ss.set + sort.Strings(a) + k := 0 + for i := 1; i < len(a); i++ { + if a[k] != a[i] { + a[k+1] = a[i] + k++ + } + } + ss.set = a[:k+1] +} + +func testCollator(c *collate.Collator) { + c0 := collate.Root + + // iterator over all characters for all locales and check + // whether Key is equal. + buf := collate.Buffer{} + + // Add all common and not too uncommon runes to the test set. + for i := rune(0); i < 0x30000; i++ { + testInput.add(string(i)) + } + for i := rune(0xE0000); i < 0xF0000; i++ { + testInput.add(string(i)) + } + for _, str := range testInput.values() { + k0 := c0.KeyFromString(&buf, str) + k := c.KeyFromString(&buf, str) + if bytes.Compare(k0, k) != 0 { + failOnError(fmt.Errorf("test:%U: keys differ (%x vs %x)", []rune(str), k0, k)) + } + buf.ResetKeys() + } + fmt.Println("PASS") +} + // TODO: move this functionality to exp/locale/collate/build. func printCollators(c *collate.Collator) { const name = "Root" @@ -157,18 +218,22 @@ func main() { c, err := b.Build() failOnError(err) - fmt.Println("// Generated by running") - fmt.Printf("// maketables --ducet=%s\n", *ducet) - fmt.Println("// DO NOT EDIT") - fmt.Println("// TODO: implement more compact representation for sparse blocks.") - fmt.Println("") - fmt.Println("package collate") - fmt.Println("") - fmt.Println(`import "exp/norm"`) - fmt.Println("") + if *test { + testCollator(c) + } else { + fmt.Println("// Generated by running") + fmt.Printf("// maketables --ducet=%s\n", *ducet) + fmt.Println("// DO NOT EDIT") + fmt.Println("// TODO: implement more compact representation for sparse blocks.") + fmt.Println("") + fmt.Println("package collate") + fmt.Println("") + fmt.Println(`import "exp/norm"`) + fmt.Println("") - printCollators(c) + printCollators(c) - _, err = b.Print(os.Stdout) - failOnError(err) + _, err = b.Print(os.Stdout) + failOnError(err) + } }