Commit 815ca4d3 by Ian Lance Taylor

libgo: Update to current Go library.

From-SVN: r205426
parent 40a373f1
7ebbddd21330 65bf677ab8d8
The first line of this file holds the Mercurial revision number of the The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources. last merge done from the master library sources.
...@@ -140,8 +140,8 @@ type Stmt interface { ...@@ -140,8 +140,8 @@ type Stmt interface {
} }
// ColumnConverter may be optionally implemented by Stmt if the // ColumnConverter may be optionally implemented by Stmt if the
// the statement is aware of its own columns' types and can // statement is aware of its own columns' types and can convert from
// convert from any type to a driver Value. // any type to a driver Value.
type ColumnConverter interface { type ColumnConverter interface {
// ColumnConverter returns a ValueConverter for the provided // ColumnConverter returns a ValueConverter for the provided
// column index. If the type of a specific column isn't known // column index. If the type of a specific column isn't known
......
...@@ -201,7 +201,7 @@ type DB struct { ...@@ -201,7 +201,7 @@ type DB struct {
connRequests *list.List // of connRequest connRequests *list.List // of connRequest
numOpen int numOpen int
pendingOpens int pendingOpens int
// Used to sygnal the need for new connections // Used to signal the need for new connections
// a goroutine running connectionOpener() reads on this chan and // a goroutine running connectionOpener() reads on this chan and
// maybeOpenNewConnections sends on the chan (one send per needed connection) // maybeOpenNewConnections sends on the chan (one send per needed connection)
// It is closed during db.Close(). The close tells the connectionOpener // It is closed during db.Close(). The close tells the connectionOpener
...@@ -1637,7 +1637,16 @@ func (r *Row) Scan(dest ...interface{}) error { ...@@ -1637,7 +1637,16 @@ func (r *Row) Scan(dest ...interface{}) error {
// A Result summarizes an executed SQL command. // A Result summarizes an executed SQL command.
type Result interface { type Result interface {
// LastInsertId returns the integer generated by the database
// in response to a command. Typically this will be from an
// "auto increment" column when inserting a new row. Not all
// databases support this feature, and the syntax of such
// statements varies.
LastInsertId() (int64, error) LastInsertId() (int64, error)
// RowsAffected returns the number of rows affected by an
// update, insert, or delete. Not every database or database
// driver may support this.
RowsAffected() (int64, error) RowsAffected() (int64, error)
} }
......
...@@ -207,9 +207,8 @@ const ( ...@@ -207,9 +207,8 @@ const (
formRef8 format = 0x14 formRef8 format = 0x14
formRefUdata format = 0x15 formRefUdata format = 0x15
formIndirect format = 0x16 formIndirect format = 0x16
// following are defined in DWARF 4
formSecOffset format = 0x17 formSecOffset format = 0x17
formExprLoc format = 0x18 formExprloc format = 0x18
formFlagPresent format = 0x19 formFlagPresent format = 0x19
formRefSig8 format = 0x20 formRefSig8 format = 0x20
) )
......
...@@ -185,29 +185,15 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { ...@@ -185,29 +185,15 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
case formUdata: case formUdata:
val = int64(b.uint()) val = int64(b.uint())
// exprloc
case formExprLoc:
val = b.bytes(int(b.uint()))
// flag // flag
case formFlag: case formFlag:
val = b.uint8() == 1 val = b.uint8() == 1
// New in DWARF 4.
case formFlagPresent: case formFlagPresent:
// The attribute is implicitly indicated as present, and no value is // The attribute is implicitly indicated as present, and no value is
// encoded in the debugging information entry itself. // encoded in the debugging information entry itself.
val = true val = true
// lineptr, loclistptr, macptr, rangelistptr
case formSecOffset:
is64, known := b.format.dwarf64()
if !known {
b.error("unknown size for DW_FORM_sec_offset")
} else if is64 {
val = Offset(b.uint64())
} else {
val = Offset(b.uint32())
}
// reference to other entry // reference to other entry
case formRefAddr: case formRefAddr:
vers := b.format.version() vers := b.format.version()
...@@ -235,8 +221,6 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { ...@@ -235,8 +221,6 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
val = Offset(b.uint64()) + ubase val = Offset(b.uint64()) + ubase
case formRefUdata: case formRefUdata:
val = Offset(b.uint()) + ubase val = Offset(b.uint()) + ubase
case formRefSig8:
val = b.uint64()
// string // string
case formString: case formString:
...@@ -253,6 +237,30 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { ...@@ -253,6 +237,30 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
b.err = b1.err b.err = b1.err
return nil return nil
} }
// lineptr, loclistptr, macptr, rangelistptr
// New in DWARF 4, but clang can generate them with -gdwarf-2.
// Section reference, replacing use of formData4 and formData8.
case formSecOffset:
is64, known := b.format.dwarf64()
if !known {
b.error("unknown size for DW_FORM_sec_offset")
} else if is64 {
val = int64(b.uint64())
} else {
val = int64(b.uint32())
}
// exprloc
// New in DWARF 4.
case formExprloc:
val = b.bytes(int(b.uint()))
// reference
// New in DWARF 4.
case formRefSig8:
// 64-bit type signature.
val = b.uint64()
} }
e.Field[i].Val = val e.Field[i].Val = val
} }
......
...@@ -86,13 +86,13 @@ Functions and channels will not be sent in a gob. Attempting to encode such a va ...@@ -86,13 +86,13 @@ Functions and channels will not be sent in a gob. Attempting to encode such a va
at top the level will fail. A struct field of chan or func type is treated exactly at top the level will fail. A struct field of chan or func type is treated exactly
like an unexported field and is ignored. like an unexported field and is ignored.
Gob can encode a value of any type implementing the GobEncoder, Gob can encode a value of any type implementing the GobEncoder or
encoding.BinaryMarshaler, or encoding.TextMarshaler interfaces by calling the encoding.BinaryMarshaler interfaces by calling the corresponding method,
corresponding method, in that order of preference. in that order of preference.
Gob can decode a value of any type implementing the GobDecoder, Gob can decode a value of any type implementing the GobDecoder or
encoding.BinaryUnmarshaler, or encoding.TextUnmarshaler interfaces by calling encoding.BinaryUnmarshaler interfaces by calling the corresponding method,
the corresponding method, again in that order of preference. again in that order of preference.
Encoding Details Encoding Details
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"net"
"strings" "strings"
"testing" "testing"
"time" "time"
...@@ -767,3 +768,17 @@ func TestGobEncodePtrError(t *testing.T) { ...@@ -767,3 +768,17 @@ func TestGobEncodePtrError(t *testing.T) {
t.Fatalf("expected nil, got %v", err2) t.Fatalf("expected nil, got %v", err2)
} }
} }
func TestNetIP(t *testing.T) {
// Encoding of net.IP{1,2,3,4} in Go 1.1.
enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
var ip net.IP
err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
if err != nil {
t.Fatalf("decode: %v", err)
}
if ip.String() != "1.2.3.4" {
t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
}
}
...@@ -88,18 +88,25 @@ func validUserType(rt reflect.Type) (ut *userTypeInfo, err error) { ...@@ -88,18 +88,25 @@ func validUserType(rt reflect.Type) (ut *userTypeInfo, err error) {
ut.externalEnc, ut.encIndir = xGob, indir ut.externalEnc, ut.encIndir = xGob, indir
} else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok { } else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
ut.externalEnc, ut.encIndir = xBinary, indir ut.externalEnc, ut.encIndir = xBinary, indir
} else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
ut.externalEnc, ut.encIndir = xText, indir
} }
// NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
// with older encodings for net.IP. See golang.org/issue/6760.
// } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
// ut.externalEnc, ut.encIndir = xText, indir
// }
if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok { if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
ut.externalDec, ut.decIndir = xGob, indir ut.externalDec, ut.decIndir = xGob, indir
} else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok { } else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
ut.externalDec, ut.decIndir = xBinary, indir ut.externalDec, ut.decIndir = xBinary, indir
} else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
ut.externalDec, ut.decIndir = xText, indir
} }
// See note above.
// } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
// ut.externalDec, ut.decIndir = xText, indir
// }
userTypeCache[rt] = ut userTypeCache[rt] = ut
return return
} }
......
...@@ -53,7 +53,7 @@ import ( ...@@ -53,7 +53,7 @@ import (
// Unmarshal records the attribute value in that field. // Unmarshal records the attribute value in that field.
// //
// * If the XML element contains character data, that data is // * If the XML element contains character data, that data is
// accumulated in the first struct field that has tag "chardata". // accumulated in the first struct field that has tag ",chardata".
// The struct field may have type []byte or string. // The struct field may have type []byte or string.
// If there is no such field, the character data is discarded. // If there is no such field, the character data is discarded.
// //
......
...@@ -22,6 +22,9 @@ func firstSentenceLen(s string) int { ...@@ -22,6 +22,9 @@ func firstSentenceLen(s string) int {
if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) { if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) {
return i return i
} }
if p == '。' || p == '.' {
return i
}
ppp, pp, p = pp, p, q ppp, pp, p = pp, p, q
} }
return len(s) return len(s)
......
...@@ -28,6 +28,8 @@ var tests = []struct { ...@@ -28,6 +28,8 @@ var tests = []struct {
{"P. Q. ", 8, "P. Q."}, {"P. Q. ", 8, "P. Q."},
{"Package Καλημέρα κόσμε.", 36, "Package Καλημέρα κόσμε."}, {"Package Καλημέρα κόσμε.", 36, "Package Καλημέρα κόσμε."},
{"Package こんにちは 世界\n", 31, "Package こんにちは 世界"}, {"Package こんにちは 世界\n", 31, "Package こんにちは 世界"},
{"Package こんにちは。世界", 26, "Package こんにちは。"},
{"Package 안녕.世界", 17, "Package 안녕."},
{"Package foo does bar.", 21, "Package foo does bar."}, {"Package foo does bar.", 21, "Package foo does bar."},
{"Copyright 2012 Google, Inc. Package foo does bar.", 27, ""}, {"Copyright 2012 Google, Inc. Package foo does bar.", 27, ""},
{"All Rights reserved. Package foo does bar.", 20, ""}, {"All Rights reserved. Package foo does bar.", 20, ""},
......
...@@ -53,6 +53,19 @@ func TestLookupStaticHost(t *testing.T) { ...@@ -53,6 +53,19 @@ func TestLookupStaticHost(t *testing.T) {
hostsPath = p hostsPath = p
} }
// https://code.google.com/p/go/issues/detail?id=6646
func TestSingleLineHostsFile(t *testing.T) {
p := hostsPath
hostsPath = "testdata/hosts_singleline"
ips := lookupStaticHost("odin")
if len(ips) != 1 || ips[0] != "127.0.0.2" {
t.Errorf("lookupStaticHost = %v, want %v", ips, []string{"127.0.0.2"})
}
hostsPath = p
}
func TestLookupHost(t *testing.T) { func TestLookupHost(t *testing.T) {
// Can't depend on this to return anything in particular, // Can't depend on this to return anything in particular,
// but if it does return something, make sure it doesn't // but if it does return something, make sure it doesn't
......
...@@ -45,13 +45,27 @@ func (c *dumpConn) SetDeadline(t time.Time) error { return nil } ...@@ -45,13 +45,27 @@ func (c *dumpConn) SetDeadline(t time.Time) error { return nil }
func (c *dumpConn) SetReadDeadline(t time.Time) error { return nil } func (c *dumpConn) SetReadDeadline(t time.Time) error { return nil }
func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil } func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil }
type neverEnding byte
func (b neverEnding) Read(p []byte) (n int, err error) {
for i := range p {
p[i] = byte(b)
}
return len(p), nil
}
// DumpRequestOut is like DumpRequest but includes // DumpRequestOut is like DumpRequest but includes
// headers that the standard http.Transport adds, // headers that the standard http.Transport adds,
// such as User-Agent. // such as User-Agent.
func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
save := req.Body save := req.Body
dummyBody := false
if !body || req.Body == nil { if !body || req.Body == nil {
req.Body = nil req.Body = nil
if req.ContentLength != 0 {
req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), req.ContentLength))
dummyBody = true
}
} else { } else {
var err error var err error
save, req.Body, err = drainBody(req.Body) save, req.Body, err = drainBody(req.Body)
...@@ -99,7 +113,19 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { ...@@ -99,7 +113,19 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return buf.Bytes(), nil dump := buf.Bytes()
// If we used a dummy body above, remove it now.
// TODO: if the req.ContentLength is large, we allocate memory
// unnecessarily just to slice it off here. But this is just
// a debug function, so this is acceptable for now. We could
// discard the body earlier if this matters.
if dummyBody {
if i := bytes.Index(dump, []byte("\r\n\r\n")); i >= 0 {
dump = dump[:i+4]
}
}
return dump, nil
} }
// delegateReader is a reader that delegates to another reader, // delegateReader is a reader that delegates to another reader,
......
...@@ -20,6 +20,7 @@ type dumpTest struct { ...@@ -20,6 +20,7 @@ type dumpTest struct {
WantDump string WantDump string
WantDumpOut string WantDumpOut string
NoBody bool // if true, set DumpRequest{,Out} body to false
} }
var dumpTests = []dumpTest{ var dumpTests = []dumpTest{
...@@ -83,6 +84,31 @@ var dumpTests = []dumpTest{ ...@@ -83,6 +84,31 @@ var dumpTests = []dumpTest{
"User-Agent: Go 1.1 package http\r\n" + "User-Agent: Go 1.1 package http\r\n" +
"Accept-Encoding: gzip\r\n\r\n", "Accept-Encoding: gzip\r\n\r\n",
}, },
// Request with Body, but Dump requested without it.
{
Req: http.Request{
Method: "POST",
URL: &url.URL{
Scheme: "http",
Host: "post.tld",
Path: "/",
},
ContentLength: 6,
ProtoMajor: 1,
ProtoMinor: 1,
},
Body: []byte("abcdef"),
WantDumpOut: "POST / HTTP/1.1\r\n" +
"Host: post.tld\r\n" +
"User-Agent: Go 1.1 package http\r\n" +
"Content-Length: 6\r\n" +
"Accept-Encoding: gzip\r\n\r\n",
NoBody: true,
},
} }
func TestDumpRequest(t *testing.T) { func TestDumpRequest(t *testing.T) {
...@@ -105,7 +131,7 @@ func TestDumpRequest(t *testing.T) { ...@@ -105,7 +131,7 @@ func TestDumpRequest(t *testing.T) {
if tt.WantDump != "" { if tt.WantDump != "" {
setBody() setBody()
dump, err := DumpRequest(&tt.Req, true) dump, err := DumpRequest(&tt.Req, !tt.NoBody)
if err != nil { if err != nil {
t.Errorf("DumpRequest #%d: %s", i, err) t.Errorf("DumpRequest #%d: %s", i, err)
continue continue
...@@ -118,7 +144,7 @@ func TestDumpRequest(t *testing.T) { ...@@ -118,7 +144,7 @@ func TestDumpRequest(t *testing.T) {
if tt.WantDumpOut != "" { if tt.WantDumpOut != "" {
setBody() setBody()
dump, err := DumpRequestOut(&tt.Req, true) dump, err := DumpRequestOut(&tt.Req, !tt.NoBody)
if err != nil { if err != nil {
t.Errorf("DumpRequestOut #%d: %s", i, err) t.Errorf("DumpRequestOut #%d: %s", i, err)
continue continue
......
...@@ -54,7 +54,7 @@ func (f *file) readLine() (s string, ok bool) { ...@@ -54,7 +54,7 @@ func (f *file) readLine() (s string, ok bool) {
if n >= 0 { if n >= 0 {
f.data = f.data[0 : ln+n] f.data = f.data[0 : ln+n]
} }
if err == io.EOF { if err == io.EOF || err == io.ErrUnexpectedEOF {
f.atEOF = true f.atEOF = true
} }
} }
......
127.0.0.2 odin
\ No newline at end of file
...@@ -574,13 +574,10 @@ func canonicalMIMEHeaderKey(a []byte) string { ...@@ -574,13 +574,10 @@ func canonicalMIMEHeaderKey(a []byte) string {
// and upper case after each dash. // and upper case after each dash.
// (Host, User-Agent, If-Modified-Since). // (Host, User-Agent, If-Modified-Since).
// MIME headers are ASCII only, so no Unicode issues. // MIME headers are ASCII only, so no Unicode issues.
if a[i] == ' ' {
a[i] = '-'
upper = true
continue
}
c := a[i] c := a[i]
if upper && 'a' <= c && c <= 'z' { if c == ' ' {
c = '-'
} else if upper && 'a' <= c && c <= 'z' {
c -= toLower c -= toLower
} else if !upper && 'A' <= c && c <= 'Z' { } else if !upper && 'A' <= c && c <= 'Z' {
c += toLower c += toLower
......
...@@ -25,6 +25,10 @@ var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{ ...@@ -25,6 +25,10 @@ var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{
{"user-agent", "User-Agent"}, {"user-agent", "User-Agent"},
{"USER-AGENT", "User-Agent"}, {"USER-AGENT", "User-Agent"},
{"üser-agenT", "üser-Agent"}, // non-ASCII unchanged {"üser-agenT", "üser-Agent"}, // non-ASCII unchanged
// This caused a panic due to mishandling of a space:
{"C Ontent-Transfer-Encoding", "C-Ontent-Transfer-Encoding"},
{"foo bar", "Foo-Bar"},
} }
func TestCanonicalMIMEHeaderKey(t *testing.T) { func TestCanonicalMIMEHeaderKey(t *testing.T) {
......
...@@ -558,8 +558,8 @@ func parseQuery(m Values, query string) (err error) { ...@@ -558,8 +558,8 @@ func parseQuery(m Values, query string) (err error) {
return err return err
} }
// Encode encodes the values into ``URL encoded'' form. // Encode encodes the values into ``URL encoded'' form
// e.g. "foo=bar&bar=baz" // ("bar=baz&foo=quux") sorted by key.
func (v Values) Encode() string { func (v Values) Encode() string {
if v == nil { if v == nil {
return "" return ""
......
...@@ -176,14 +176,11 @@ func (f *File) readdir(n int) (fi []FileInfo, err error) { ...@@ -176,14 +176,11 @@ func (f *File) readdir(n int) (fi []FileInfo, err error) {
fi = make([]FileInfo, len(names)) fi = make([]FileInfo, len(names))
for i, filename := range names { for i, filename := range names {
fip, lerr := lstat(dirname + filename) fip, lerr := lstat(dirname + filename)
if lerr == nil { if lerr != nil {
fi[i] = fip
} else {
fi[i] = &fileStat{name: filename} fi[i] = &fileStat{name: filename}
if err == nil { continue
err = lerr
}
} }
fi[i] = fip
} }
return fi, err return fi, err
} }
......
...@@ -92,8 +92,8 @@ func TestReaddirWithBadLstat(t *testing.T) { ...@@ -92,8 +92,8 @@ func TestReaddirWithBadLstat(t *testing.T) {
defer func() { *LstatP = Lstat }() defer func() { *LstatP = Lstat }()
dirs, err := handle.Readdir(-1) dirs, err := handle.Readdir(-1)
if err != ErrInvalid { if err != nil {
t.Fatalf("Expected Readdir to return ErrInvalid, got %v", err) t.Fatalf("Expected Readdir to return no error, got %v", err)
} }
foundfail := false foundfail := false
for _, dir := range dirs { for _, dir := range dirs {
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"hash/crc32" "hash/crc32"
"math/big"
"os/exec" "os/exec"
"regexp" "regexp"
"runtime" "runtime"
...@@ -123,6 +124,10 @@ func testCPUProfile(t *testing.T, need []string, f func()) { ...@@ -123,6 +124,10 @@ func testCPUProfile(t *testing.T, need []string, f func()) {
} }
}) })
if len(need) == 0 {
return
}
var total uintptr var total uintptr
for i, name := range need { for i, name := range need {
total += have[i] total += have[i]
...@@ -237,6 +242,26 @@ func TestGoroutineSwitch(t *testing.T) { ...@@ -237,6 +242,26 @@ func TestGoroutineSwitch(t *testing.T) {
} }
} }
// Test that profiling of division operations is okay, especially on ARM. See issue 6681.
func TestMathBigDivide(t *testing.T) {
testCPUProfile(t, nil, func() {
t := time.After(5 * time.Second)
pi := new(big.Int)
for {
for i := 0; i < 100; i++ {
n := big.NewInt(2646693125139304345)
d := big.NewInt(842468587426513207)
pi.Div(n, d)
}
select {
case <-t:
return
default:
}
}
})
}
// Operating systems that are expected to fail the tests. See issue 6047. // Operating systems that are expected to fail the tests. See issue 6047.
var badOS = map[string]bool{ var badOS = map[string]bool{
"darwin": true, "darwin": true,
......
...@@ -364,17 +364,18 @@ func makeSingleStringReplacer(pattern string, value string) *singleStringReplace ...@@ -364,17 +364,18 @@ func makeSingleStringReplacer(pattern string, value string) *singleStringReplace
func (r *singleStringReplacer) Replace(s string) string { func (r *singleStringReplacer) Replace(s string) string {
var buf []byte var buf []byte
i := 0 i, matched := 0, false
for { for {
match := r.finder.next(s[i:]) match := r.finder.next(s[i:])
if match == -1 { if match == -1 {
break break
} }
matched = true
buf = append(buf, s[i:i+match]...) buf = append(buf, s[i:i+match]...)
buf = append(buf, r.value...) buf = append(buf, r.value...)
i += match + len(r.finder.pattern) i += match + len(r.finder.pattern)
} }
if buf == nil { if !matched {
return s return s
} }
buf = append(buf, s[i:]...) buf = append(buf, s[i:]...)
......
...@@ -261,10 +261,21 @@ func TestReplacer(t *testing.T) { ...@@ -261,10 +261,21 @@ func TestReplacer(t *testing.T) {
testCases = append(testCases, testCases = append(testCases,
testCase{abcMatcher, "", ""}, testCase{abcMatcher, "", ""},
testCase{abcMatcher, "ab", "ab"}, testCase{abcMatcher, "ab", "ab"},
testCase{abcMatcher, "abc", "[match]"},
testCase{abcMatcher, "abcd", "[match]d"}, testCase{abcMatcher, "abcd", "[match]d"},
testCase{abcMatcher, "cabcabcdabca", "c[match][match]d[match]a"}, testCase{abcMatcher, "cabcabcdabca", "c[match][match]d[match]a"},
) )
// Issue 6659 cases (more single string replacer)
noHello := NewReplacer("Hello", "")
testCases = append(testCases,
testCase{noHello, "Hello", ""},
testCase{noHello, "Hellox", "x"},
testCase{noHello, "xHello", "x"},
testCase{noHello, "xHellox", "xx"},
)
// No-arg test cases. // No-arg test cases.
nop := NewReplacer() nop := NewReplacer()
......
...@@ -73,17 +73,19 @@ ...@@ -73,17 +73,19 @@
// //
// Example functions without output comments are compiled but not executed. // Example functions without output comments are compiled but not executed.
// //
// The naming convention to declare examples for a function F, a type T and // The naming convention to declare examples for the package, a function F, a type T and
// method M on type T are: // method M on type T are:
// //
// func Example() { ... }
// func ExampleF() { ... } // func ExampleF() { ... }
// func ExampleT() { ... } // func ExampleT() { ... }
// func ExampleT_M() { ... } // func ExampleT_M() { ... }
// //
// Multiple example functions for a type/function/method may be provided by // Multiple example functions for a package/type/function/method may be provided by
// appending a distinct suffix to the name. The suffix must start with a // appending a distinct suffix to the name. The suffix must start with a
// lower-case letter. // lower-case letter.
// //
// func Example_suffix() { ... }
// func ExampleF_suffix() { ... } // func ExampleF_suffix() { ... }
// func ExampleT_suffix() { ... } // func ExampleT_suffix() { ... }
// func ExampleT_M_suffix() { ... } // func ExampleT_M_suffix() { ... }
......
...@@ -18,4 +18,7 @@ func ForceUSPacificForTesting() { ...@@ -18,4 +18,7 @@ func ForceUSPacificForTesting() {
localOnce.Do(initTestingZone) localOnce.Do(initTestingZone)
} }
var ParseTimeZone = parseTimeZone var (
ForceZipFileForTesting = forceZipFileForTesting
ParseTimeZone = parseTimeZone
)
...@@ -578,6 +578,18 @@ func TestParseInSydney(t *testing.T) { ...@@ -578,6 +578,18 @@ func TestParseInSydney(t *testing.T) {
} }
} }
func TestLoadLocationZipFile(t *testing.T) {
t.Skip("gccgo does not use the zip file")
ForceZipFileForTesting(true)
defer ForceZipFileForTesting(false)
_, err := LoadLocation("Australia/Sydney")
if err != nil {
t.Fatal(err)
}
}
var rubyTests = []ParseTest{ var rubyTests = []ParseTest{
{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0}, {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
// Ignore the time zone in the test. If it parses, it'll be OK. // Ignore the time zone in the test. If it parses, it'll be OK.
......
...@@ -154,3 +154,7 @@ func loadLocation(name string) (*Location, error) { ...@@ -154,3 +154,7 @@ func loadLocation(name string) (*Location, error) {
} }
return nil, errors.New("unknown time zone " + name) return nil, errors.New("unknown time zone " + name)
} }
func forceZipFileForTesting(zipOnly bool) {
// We only use the zip file anyway.
}
...@@ -28,7 +28,19 @@ var zoneDirs = []string{ ...@@ -28,7 +28,19 @@ var zoneDirs = []string{
"/usr/share/zoneinfo/", "/usr/share/zoneinfo/",
"/usr/share/lib/zoneinfo/", "/usr/share/lib/zoneinfo/",
"/usr/lib/locale/TZ/", "/usr/lib/locale/TZ/",
runtime.GOROOT() + "/lib/time/zoneinfo/", runtime.GOROOT() + "/lib/time/zoneinfo.zip",
}
var origZoneDirs = zoneDirs
func forceZipFileForTesting(zipOnly bool) {
zoneDirs = make([]string, len(origZoneDirs))
copy(zoneDirs, origZoneDirs)
if zipOnly {
for i := 0; i < len(zoneDirs)-1; i++ {
zoneDirs[i] = "/XXXNOEXIST"
}
}
} }
func initLocal() { func initLocal() {
......
...@@ -264,3 +264,7 @@ func loadLocation(name string) (*Location, error) { ...@@ -264,3 +264,7 @@ func loadLocation(name string) (*Location, error) {
} }
return nil, errors.New("unknown time zone " + name) return nil, errors.New("unknown time zone " + name)
} }
func forceZipFileForTesting(zipOnly bool) {
// We only use the zip file anyway.
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment