133 lines
3.2 KiB
Go
133 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"text/template"
|
|
)
|
|
|
|
var usage = `%[1]s generates Go code to support CLDR plural rules.
|
|
|
|
Usage: %[1]s [options]
|
|
|
|
Options:
|
|
|
|
`
|
|
|
|
func main() {
|
|
flag.Usage = func() {
|
|
fmt.Fprintf(os.Stderr, usage, os.Args[0])
|
|
flag.PrintDefaults()
|
|
}
|
|
var in, cout, tout string
|
|
flag.StringVar(&in, "i", "plurals.xml", "the input XML file containing CLDR plural rules")
|
|
flag.StringVar(&cout, "cout", "", "the code output file")
|
|
flag.StringVar(&tout, "tout", "", "the test output file")
|
|
flag.BoolVar(&verbose, "v", false, "verbose output")
|
|
flag.Parse()
|
|
|
|
buf, err := ioutil.ReadFile(in)
|
|
if err != nil {
|
|
fatalf("failed to read file: %s", err)
|
|
}
|
|
|
|
var data SupplementalData
|
|
if err := xml.Unmarshal(buf, &data); err != nil {
|
|
fatalf("failed to unmarshal xml: %s", err)
|
|
}
|
|
|
|
count := 0
|
|
for _, pg := range data.PluralGroups {
|
|
count += len(pg.SplitLocales())
|
|
}
|
|
infof("parsed %d locales", count)
|
|
|
|
if cout != "" {
|
|
file := openWritableFile(cout)
|
|
if err := codeTemplate.Execute(file, data); err != nil {
|
|
fatalf("unable to execute code template because %s", err)
|
|
} else {
|
|
infof("generated %s", cout)
|
|
}
|
|
} else {
|
|
infof("not generating code file (use -cout)")
|
|
}
|
|
|
|
if tout != "" {
|
|
file := openWritableFile(tout)
|
|
if err := testTemplate.Execute(file, data); err != nil {
|
|
fatalf("unable to execute test template because %s", err)
|
|
} else {
|
|
infof("generated %s", tout)
|
|
}
|
|
} else {
|
|
infof("not generating test file (use -tout)")
|
|
}
|
|
}
|
|
|
|
func openWritableFile(name string) *os.File {
|
|
file, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
|
if err != nil {
|
|
fatalf("failed to write file %s because %s", name, err)
|
|
}
|
|
return file
|
|
}
|
|
|
|
var codeTemplate = template.Must(template.New("spec").Parse(`package language
|
|
// This file is generated by i18n/language/codegen/generate.sh
|
|
|
|
func init() {
|
|
{{range .PluralGroups}}
|
|
registerPluralSpec({{printf "%#v" .SplitLocales}}, &PluralSpec{
|
|
Plurals: newPluralSet({{range $i, $e := .PluralRules}}{{if $i}}, {{end}}{{$e.CountTitle}}{{end}}),
|
|
PluralFunc: func(ops *operands) Plural { {{range .PluralRules}}{{if .GoCondition}}
|
|
// {{.Condition}}
|
|
if {{.GoCondition}} {
|
|
return {{.CountTitle}}
|
|
}{{end}}{{end}}
|
|
return Other
|
|
},
|
|
}){{end}}
|
|
}
|
|
`))
|
|
|
|
var testTemplate = template.Must(template.New("spec").Parse(`package language
|
|
// This file is generated by i18n/language/codegen/generate.sh
|
|
|
|
import "testing"
|
|
|
|
{{range .PluralGroups}}
|
|
func Test{{.Name}}(t *testing.T) {
|
|
var tests []pluralTest
|
|
{{range .PluralRules}}
|
|
{{if .IntegerExamples}}tests = appendIntegerTests(tests, {{.CountTitle}}, {{printf "%#v" .IntegerExamples}}){{end}}
|
|
{{if .DecimalExamples}}tests = appendDecimalTests(tests, {{.CountTitle}}, {{printf "%#v" .DecimalExamples}}){{end}}
|
|
{{end}}
|
|
locales := {{printf "%#v" .SplitLocales}}
|
|
for _, locale := range locales {
|
|
runTests(t, locale, tests)
|
|
}
|
|
}
|
|
{{end}}
|
|
`))
|
|
|
|
func infof(format string, args ...interface{}) {
|
|
fmt.Fprintf(os.Stderr, format+"\n", args...)
|
|
}
|
|
|
|
var verbose bool
|
|
|
|
func verbosef(format string, args ...interface{}) {
|
|
if verbose {
|
|
infof(format, args...)
|
|
}
|
|
}
|
|
|
|
func fatalf(format string, args ...interface{}) {
|
|
infof("fatal: "+format+"\n", args...)
|
|
os.Exit(1)
|
|
}
|