mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
godoc/static: use a stable quote function
Printf(%q) aka strconv.AppendQuote depends on the Unicode tables du jour, which means gen_test breaks after a Go release in which Unicode evolves. This change uses a very dumb quotation function that emits only ASCII and is independent of the Go release. Perhaps an even better fix would have been to parse the generated file. Change-Id: I197942f1c36a8b53d6a37be4bb2b1e63a208f7e2 Reviewed-on: https://go-review.googlesource.com/119157 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
c06a8d8ed1
commit
e10d6c9a84
@ -12,7 +12,7 @@ import (
|
||||
"go/format"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var files = []string{
|
||||
@ -80,35 +80,28 @@ func Generate() ([]byte, error) {
|
||||
return b, err
|
||||
}
|
||||
fmt.Fprintf(buf, "\t%q: ", fn)
|
||||
if utf8.Valid(b) {
|
||||
fmt.Fprintf(buf, "`%s`", sanitize(b))
|
||||
} else {
|
||||
fmt.Fprintf(buf, "%q", b)
|
||||
}
|
||||
appendQuote(buf, b)
|
||||
fmt.Fprintf(buf, ",\n\n")
|
||||
}
|
||||
fmt.Fprintln(buf, "}")
|
||||
|
||||
b := buf.Bytes()
|
||||
|
||||
// The 鿥 U+9FE5 character became printable in go 1.10,
|
||||
// causing it to appear literally in newer output.
|
||||
// Force the old behavior.
|
||||
b = bytes.Replace(b, []byte("\u9fe5"), []byte(`\u9fe5`), -1)
|
||||
|
||||
return format.Source(b)
|
||||
return format.Source(buf.Bytes())
|
||||
}
|
||||
|
||||
// sanitize prepares a valid UTF-8 string as a raw string constant.
|
||||
func sanitize(b []byte) []byte {
|
||||
// Replace ` with `+"`"+`
|
||||
b = bytes.Replace(b, []byte("`"), []byte("`+\"`\"+`"), -1)
|
||||
|
||||
// Replace BOM with `+"\xEF\xBB\xBF"+`
|
||||
// (A BOM is valid UTF-8 but not permitted in Go source files.
|
||||
// I wouldn't bother handling this, but for some insane reason
|
||||
// jquery.js has a BOM somewhere in the middle.)
|
||||
return bytes.Replace(b, []byte("\xEF\xBB\xBF"), []byte("`+\"\\xEF\\xBB\\xBF\"+`"), -1)
|
||||
// appendQuote is like strconv.AppendQuote, but we avoid the latter
|
||||
// because it changes when Unicode evolves, breaking gen_test.go.
|
||||
func appendQuote(out *bytes.Buffer, data []byte) {
|
||||
out.WriteByte('"')
|
||||
for _, b := range data {
|
||||
if b == '\\' || b == '"' {
|
||||
out.WriteByte('\\')
|
||||
out.WriteByte(b)
|
||||
} else if b <= unicode.MaxASCII && unicode.IsPrint(rune(b)) && !unicode.IsSpace(rune(b)) {
|
||||
out.WriteByte(b)
|
||||
} else {
|
||||
fmt.Fprintf(out, "\\x%02x", b)
|
||||
}
|
||||
}
|
||||
out.WriteByte('"')
|
||||
}
|
||||
|
||||
const warning = `// Code generated by "makestatic"; DO NOT EDIT.`
|
||||
|
@ -7,7 +7,9 @@ package static
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"testing"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func TestStaticIsUpToDate(t *testing.T) {
|
||||
@ -29,3 +31,19 @@ to see the differences.`)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TestAppendQuote ensures that AppendQuote produces a valid literal.
|
||||
func TestAppendQuote(t *testing.T) {
|
||||
var in, out bytes.Buffer
|
||||
for r := rune(0); r < unicode.MaxRune; r++ {
|
||||
in.WriteRune(r)
|
||||
}
|
||||
appendQuote(&out, in.Bytes())
|
||||
in2, err := strconv.Unquote(out.String())
|
||||
if err != nil {
|
||||
t.Fatalf("AppendQuote produced invalid string literal: %v", err)
|
||||
}
|
||||
if got, want := in2, in.String(); got != want {
|
||||
t.Fatal("AppendQuote modified string") // no point printing got/want: huge
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user